26static int GetNFacesPerElement(
const Mesh &mesh)
33 default: MFEM_ABORT(
"Invalid dimension.");
40 const int ne = mesh.
GetNE();
44 const int n_faces_per_el = GetNFacesPerElement(mesh);
47 Vector emat(m * n * 2 * nf);
60 const auto d_emat =
Reshape(emat.
Read(), m, n, 2, nf);
61 const int *d_dof_map = dof_map.
Read();
72 const int i_lex = idx % m;
73 const int j = (idx / m) % n;
74 const int ie = (idx / m / n) % 2;
75 const int f = idx / m / n / 2;
77 const int e = d_face_to_el(0, ie,
f);
78 const int fi = d_face_to_el(1, ie,
f);
84 const int i_s = d_dof_map[i_lex];
85 const int i = (i_s >= 0) ? i_s : -1 - i_s;
86 d_Ct_mat(i, j, fi, e) = d_emat(i_lex, j, ie,
f);
93template <
typename T,
int SIZE>
97 MFEM_HOST_DEVICE
inline operator T *()
const {
return (T*)data; }
101struct LocalMemory<T,0>
103 MFEM_HOST_DEVICE
inline operator T *()
const {
return (T*)
nullptr; }
107template <
int MID,
int MBD>
111 const int ne = mesh.
GetNE();
112 const int n_faces_per_el = GetNFacesPerElement(mesh);
117 auto d_AhatInvCt =
Reshape(AhatInvCt_mat.
Write(), m, n, n_faces_per_el, ne);
123 MFEM_VERIFY(nidofs <= MID,
"");
124 MFEM_VERIFY(nbdofs <= MBD,
"");
150 static constexpr bool GLOBAL = (MID == 0 && MBD == 0);
152 using internal::LocalMemory;
156 constexpr int MD1D = DofQuadLimits::HDIV_MAX_D1D;
157 constexpr int MAX_DOFS = 3*MD1D*(MD1D-1)*(MD1D-1);
158 constexpr int MAX_IDOFS = (MID == 0 && MBD == 0) ? MAX_DOFS : MID;
159 constexpr int MAX_BDOFS = (MID == 0 && MBD == 0) ? MAX_DOFS : MBD;
161 LocalMemory<int,MAX_IDOFS> idofs_loc;
162 LocalMemory<int,MAX_BDOFS> bdofs_loc;
163 for (
int i = 0; i < nidofs; i++) { idofs_loc[i] = d_idofs[i]; }
164 for (
int i = 0; i < nbdofs; i++) { bdofs_loc[i] = d_bdofs[i]; }
166 LocalMemory<int,MAX_BDOFS> essdofs_loc;
169 for (
int i = 0; i < nbdofs; i++)
171 const int dof_idx = bdofs_loc[i];
172 if (d_hat_dof_marker(dof_idx, e) ==
ESSENTIAL)
174 essdofs_loc[nessdofs] = dof_idx;
179 bdofs_loc[nbfdofs] = dof_idx;
184 LocalMemory<real_t, MID*MID> A_ii_loc;
185 LocalMemory<real_t, MBD*MID> A_bi_loc;
186 LocalMemory<real_t, MID*MBD> A_ib_loc;
187 LocalMemory<real_t, MBD*MBD> A_bb_loc;
189 DeviceMatrix A_ii(GLOBAL ? &d_A_ii(0,0,e) : A_ii_loc, nidofs, nidofs);
190 DeviceMatrix A_ib(GLOBAL ? &d_A_ib_all(0,e) : A_ib_loc, nidofs, nbfdofs);
191 DeviceMatrix A_bi(GLOBAL ? &d_A_bi_all(0,e) : A_bi_loc, nbfdofs, nidofs);
192 DeviceMatrix A_bb(GLOBAL ? &d_A_bb_all(0,e) : A_bb_loc, nbfdofs, nbfdofs);
194 for (
int j = 0; j < nidofs; j++)
196 const int jj = idofs_loc[j];
197 for (
int i = 0; i < nidofs; i++)
199 A_ii(i,j) = d_Ahat(idofs_loc[i], jj, e);
201 for (
int i = 0; i < nbfdofs; i++)
203 A_bi(i,j) = d_Ahat(bdofs_loc[i], jj, e);
206 for (
int j = 0; j < nbfdofs; j++)
208 const int jj = bdofs_loc[j];
209 for (
int i = 0; i < nidofs; i++)
211 A_ib(i,j) = d_Ahat(idofs_loc[i], jj, e);
213 for (
int i = 0; i < nbfdofs; i++)
215 A_bb(i,j) = d_Ahat(bdofs_loc[i], jj, e);
219 LocalMemory<int,MID> ipiv_ii_loc;
220 LocalMemory<int,MBD> ipiv_bb_loc;
222 auto ipiv_ii = GLOBAL ? &d_ipiv_ii(0,e) : ipiv_ii_loc;
223 auto ipiv_bb = GLOBAL ? &d_ipiv_ii(0,e) : ipiv_bb_loc;
229 for (
int f = 0;
f < n_faces_per_el; ++
f)
231 for (
int j = 0; j < n; ++j)
233 LocalMemory<real_t,MAX_BDOFS> Sb_inv_Cb_t;
234 for (
int i = 0; i < nbfdofs; ++i)
236 Sb_inv_Cb_t[i] = d_Ct_mat(bdofs_loc[i], j,
f, e);
239 for (
int i = 0; i < nbfdofs; ++i)
241 const int b_i = bdofs_loc[i];
242 d_AhatInvCt(b_i, j,
f, e) = Sb_inv_Cb_t[i];
244 for (
int i = 0; i < nidofs; ++i)
246 d_AhatInvCt(idofs_loc[i], j,
f, e) = 0.0;
248 for (
int i = 0; i < nessdofs; ++i)
250 d_AhatInvCt(essdofs_loc[i], j,
f, e) = 0.0;
261 &d_A_bi_all(0,e) :
nullptr,
264 &d_A_ib_all(0,e) :
nullptr,
266 DeviceMatrix d_A_bb((nbfdofs) ? &d_A_bb_all(0,e) :
nullptr,
269 for (
int j = 0; j < nidofs; j++)
271 d_ipiv_ii(j,e) = ipiv_ii[j];
272 for (
int i = 0; i < nidofs; i++)
274 d_A_ii(i,j,e) = A_ii(i,j);
276 for (
int i = 0; i < nbfdofs; i++)
278 d_A_bi(i,j) = A_bi(i,j);
281 for (
int j = 0; j < nbfdofs; j++)
283 d_ipiv_bb(j,e) = ipiv_bb[j];
284 for (
int i = 0; i < nidofs; i++)
286 d_A_ib(i,j) = A_ib(i,j);
288 for (
int i = 0; i < nbfdofs; i++)
290 d_A_bb(i,j) = A_bb(i,j);
301 const int ne = mesh.
GetNE();
302 const int n_faces_per_el = GetNFacesPerElement(mesh);
336 const auto d_AhatInvCt =
337 Reshape(AhatInvCt_mat.
Read(), m, n, n_faces_per_el, ne);
340 const int n_face_connections = 2*n_faces_per_el - 1;
341 Array<int> face_to_face(nf * n_face_connections);
348 auto d_CAhatInvCt =
Reshape(CAhatInvCt.
Write(), n, n, n_face_connections, nf);
349 auto d_face_to_face =
Reshape(face_to_face.
Write(), n_face_connections, nf);
351 mfem::forall(n*n*n_face_connections*nf, [=] MFEM_HOST_DEVICE (
int i)
353 d_CAhatInvCt[i] = 0.0;
359 for (
int ei = 0; ei < 2; ++ei)
361 const int e = d_face_to_el(0, ei, fi);
362 if (e < 0 || e >= ne) {
continue; }
363 for (
int fj_i = 0; fj_i < n_faces_per_el; ++fj_i)
365 const int fj = d_el_to_face(fj_i, e);
367 if (fj < 0) {
continue; }
372 for (
int i = 0; i < idx; ++i)
374 if (d_face_to_face(i, fi) == fj)
383 d_face_to_face(idx, fi) = fj;
389 for (; idx < n_face_connections; ++idx)
391 d_face_to_face(idx, fi) = -1;
395 mfem::forall(nf*n_face_connections, [=] MFEM_HOST_DEVICE (
int idx)
397 const int idx_j = idx % n_face_connections;
398 const int fi = idx / n_face_connections;
400 const int fj = d_face_to_face(idx_j, fi);
401 if (fj < 0) {
return; }
403 for (
int ei = 0; ei < 2; ++ei)
405 const int e = d_face_to_el(0, ei, fi);
406 if (e < 0 || e >= ne) {
continue; }
407 const int fi_i = d_face_to_el(1, ei, fi);
410 for (
int ej = 0; ej < 2; ++ej)
412 if (d_face_to_el(0, ej, fj) == e)
414 fj_i = d_face_to_el(1, ej, fj);
420 const real_t *Ct_i = &d_Ct(0, 0, fi_i, e);
421 const real_t *AhatInvCt_i = &d_AhatInvCt(0, 0, fj_i, e);
422 real_t *CAhatInvCt_i = &d_CAhatInvCt(0, 0, idx_j, fi);
435 h.
H->OverrideSize(ncdofs, ncdofs);
437 h.
H->GetMemoryI().New(ncdofs + 1,
h.
H->GetMemoryI().GetMemoryType());
440 int *I =
h.
H->WriteI();
442 mfem::forall(ncdofs, [=] MFEM_HOST_DEVICE (
int i) { I[i] = 0; });
446 const int i = idx_i % n;
447 const int fi = idx_i / n;
448 const int ii = c_gather_map(i, fi);
450 for (
int idx = 0; idx < n_face_connections; ++idx)
452 const int fj = d_face_to_face(idx, fi);
453 if (fj < 0) {
break; }
454 for (
int j = 0; j < n; ++j)
456 if (d_CAhatInvCt(i, j, idx, fi) != 0)
472 int *I =
h.
H->HostReadWriteI();
473 int empty_row_count = 0;
474 for (
int i = 0; i < ncdofs; i++)
476 if (I[i] == 0) { empty_row_count++; }
478 empty_rows.
SetSize(empty_row_count);
480 int empty_row_idx = 0;
482 for (
int i = 0; i < ncdofs; i++)
487 empty_rows[empty_row_idx] = i;
497 const int nnz =
h.
H->HostReadI()[ncdofs];
498 h.
H->GetMemoryJ().New(nnz,
h.
H->GetMemoryJ().GetMemoryType());
499 h.
H->GetMemoryData().New(nnz,
h.
H->GetMemoryData().GetMemoryType());
502 int *I =
h.
H->ReadWriteI();
503 int *J =
h.
H->WriteJ();
508 const int i = idx_i % n;
509 const int fi = idx_i / n;
510 const int ii = c_gather_map[i + fi*n];
511 for (
int idx = 0; idx < n_face_connections; ++idx)
513 const int fj = d_face_to_face(idx, fi);
514 if (fj < 0) {
break; }
515 for (
int j = 0; j < n; ++j)
517 const real_t val = d_CAhatInvCt(i, j, idx, fi);
521 const int jj = c_gather_map(j, fj);
530 const int *d_empty_rows = empty_rows.
Read();
533 const int i = d_empty_rows[idx];
543 int *I =
h.
H->HostReadWriteI();
544 for (
int i = ncdofs - 1; i > 0; --i)
556 pP.ConvertFrom(c_pfes->Dof_TrueDof_Matrix());
558 c_pfes->GetDofOffsets(),
h.
H.get());
568 const int ne = mesh.
GetNE();
573 const int n_faces_per_el = GetNFacesPerElement(mesh);
580 face_restr->
Mult(x, x_evec);
585 const auto d_x_evec =
Reshape(x_evec.
Read(), n_c_dof_per_face, nf);
588 mfem::forall(ne * n_hat_dof_per_el, [=] MFEM_HOST_DEVICE (
int idx)
590 const int e = idx / n_hat_dof_per_el;
591 const int i = idx % n_hat_dof_per_el;
593 for (
int fi = 0; fi < n_faces_per_el; ++fi)
595 const int f = d_el_to_face[e*n_faces_per_el + fi];
596 if (
f < 0) {
continue; }
597 for (
int j = 0; j < n_c_dof_per_face; ++j)
599 d_y(i, e) += d_Ct(i, j, fi, e)*d_x_evec(j,
f);
608 const int ne = mesh.
GetNE();
613 const int n_faces_per_el = GetNFacesPerElement(mesh);
623 auto d_x =
Reshape(x.
Read(), n_hat_dof_per_el, ne);
624 auto d_y_evec =
Reshape(y_evec.
Write(), n_c_dof_per_face, nf);
626 mfem::forall(nf * n_c_dof_per_face, [=] MFEM_HOST_DEVICE (
int idx)
628 const int f = idx / n_c_dof_per_face;
629 const int j = idx % n_c_dof_per_face;
630 d_y_evec(j,
f) = 0.0;
631 for (
int el_i = 0; el_i < 2; ++el_i)
633 const int e = d_face_to_el(0, el_i,
f);
634 const int fi = d_face_to_el(1, el_i,
f);
637 if (e >= ne) {
continue; }
639 for (
int i = 0; i < n_hat_dof_per_el; ++i)
641 d_y_evec(j,
f) += d_Ct(i, j, fi, e)*d_x(i, e);
652 const int n = elmat.
Width();
655 const int offset = el*n*n;
658 d_Ahat[offset + i] += d_elmat[i];
681 Ordering::DofsToVDofs<Ordering::byNODES>(n/vdim, vdim, lvdofs);
682 MFEM_ASSERT(lvdofs.
Size() == elmat.
Height(),
"internal error");
687 for (
int i = 0; i < lvdofs.
Size(); i++)
693 const int offset = el*n*n;
695 for (
int j = 0; j < n; ++j)
697 const int j_f = e2f[j];
698 if (j_f < 0) {
continue; }
699 for (
int i = 0; i < n; ++i)
701 const int i_f = e2f[i];
702 if (i_f < 0) {
continue; }
703 Ahat[offset + i + j*n] += B(i_f, j_f);
714 d_Ahat[i] += d_elmats[i];
728 MFEM_VERIFY(
dim == 2 ||
dim == 3,
"");
736 MFEM_VERIFY(tbe !=
nullptr,
"");
739 const int n_faces_per_el = GetNFacesPerElement(mesh);
742 for (
int f = 0;
f < n_faces_per_el; ++
f)
746 all_face_dofs.
Append(face_map);
751 for (
int i = 0; i < all_face_dofs.
Size(); ++i)
753 const int j_s = all_face_dofs[i];
754 const int j = (j_s >= 0) ? j_s : -1 - j_s;
755 const int j_nat_s = dof_map[j];
756 const int j_nat = (j_nat_s >= 0) ? j_nat_s : -1 - j_nat_s;
757 b_marker[j_nat] =
true;
760 for (
int i = 0; i < ndof_per_el; ++i)
768 const int n_faces_per_el = GetNFacesPerElement(mesh);
782 el_to_face[el1 * n_faces_per_el + fi1] = face_idx;
788 el_to_face[el2 * n_faces_per_el + fi2] = face_idx;
807 d_hat_offsets[i] = i*ndof_per_el;
829 int *d_free_tdof_marker = free_tdof_marker.
Write();
832 d_free_tdof_marker[i] = 1;
834 const int n_ess_dofs = ess_tdof_list.
Size();
835 const int *d_ess_tdof_list = ess_tdof_list.
Read();
838 d_free_tdof_marker[d_ess_tdof_list[i]] = 0;
855 free_vdofs_marker.
MakeRef(free_tdof_marker);
858 free_vdofs_marker.
MakeRef(free_tdof_marker);
866 const int *gather_map = R->GatherMap().Read();
867 const int *d_free_vdofs_marker = free_vdofs_marker.
Read();
869 ndof_per_face, n_faces_per_el, ne);
878 const int j_s = gather_map[i];
879 const int j = (j_s >= 0) ? j_s : -1 - j_s;
880 if (d_free_vdofs_marker[j])
882 const int i_loc = i % ndof_per_el;
883 const int e = i / ndof_per_el;
885 for (
int f = 0;
f < n_faces_per_el; ++
f)
887 for (
int k = 0; k < ndof_per_face; ++k)
889 if (d_Ct_mat(i_loc, k,
f, e) != 0.0)
910 const int *d_offsets = R->Offsets().Read();
911 const int *d_indices = R->Indices().Read();
915 d_hat_dof_gather_map[i] = -1;
919 const int offset = d_offsets[i];
920 const int j_s = d_indices[offset];
921 const int hat_dof_index = (j_s >= 0) ? j_s : -1 - j_s;
924 d_hat_dof_gather_map[hat_dof_index] = (j_s >= 0) ? i : (-2 - i);
959 if (d_hat_dof_marker[i] ==
ESSENTIAL) {
return; }
961 const int j_s = gather_map[i];
962 const int sgn = (j_s >= 0) ? 1 : -1;
963 const int j = (j_s >= 0) ? j_s : -1 - j_s;
965 d_lvec[j] = sgn*d_evec[i];
993 const int j_s = d_hat_dof_gather_map[i];
1000 const int sgn = (j_s >= 0) ? 1 : -1;
1001 const int j = (j_s >= 0) ? j_s : -2 - j_s;
1002 d_b_hat[i] = sgn*d_b_lvec[j];
1037 constexpr int MD1D = DofQuadLimits::HDIV_MAX_D1D;
1038 constexpr int MAX_DOFS = 3*MD1D*(MD1D-1)*(MD1D-1);
1039 internal::LocalMemory<int,MAX_DOFS> bdofs_loc;
1042 for (
int i = 0; i < nbdofs; i++)
1044 const int dof_idx = d_bdofs[i];
1045 if (d_hat_dof_marker(dof_idx, e) !=
ESSENTIAL)
1047 bdofs_loc[nbfdofs] = dof_idx;
1052 for (
int i = 0; i < nidofs; ++i)
1054 d_ivals(i, e) = d_x(d_idofs[i], e);
1056 for (
int i = 0; i < nbfdofs; ++i)
1058 d_bvals(i, e) = d_x(bdofs_loc[i], e);
1065 kernels::LSolve(&d_A_ii(0,0,e), nidofs, &d_ipiv_ii(0,e), &d_ivals(0,e));
1068 nidofs, nbfdofs, 1, &d_A_bi(0,e), &d_ivals(0,e), &d_bvals(0, e));
1079 nbfdofs, nidofs, 1, &d_A_ib(0,e), &d_bvals(0,e), &d_ivals(0, e));
1084 for (
int i = 0; i < nidofs; ++i)
1086 d_x(d_idofs[i], e) = d_ivals(i, e);
1088 for (
int i = 0; i < nbfdofs; ++i)
1090 d_x(bdofs_loc[i], e) = d_bvals(i, e);
1104 if (d_hat_dof_marker[i] ==
ESSENTIAL) { d_b_hat[i] = 0.0; }
1134 P->
Mult(sol_r, sol_l);
1147 if (d_hat_dof_marker[i] ==
ESSENTIAL) { d_tmp1[i] = 0.0; }
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
void MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
T * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
int Append(const T &el)
Append element 'el' to array, resize if necessary.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
Data type dense matrix using column-major storage.
void AdjustDofDirection(Array< int > &dofs)
const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
Rank 3 tensor (array of matrices)
const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
A basic generic Tensor class, appropriate for use on the GPU.
Operator that converts FiniteElementSpace L-vectors to E-vectors.
const Array< int > & GatherMap() const
virtual MFEM_DEPRECATED int GetNFaces(int &nFaceVertices) const =0
virtual int GetNEdges() const =0
Base class for operators that extracts Face degrees of freedom.
void MultTranspose(const Vector &x, Vector &y) const override
Set the face degrees of freedom in the element degrees of freedom y to the values given in x.
virtual const Array< int > & GatherMap() const
Low-level access to the underlying gather map.
void Mult(const Vector &x, Vector &y) const override=0
Extract the face degrees of freedom from x into y.
void SubDofOrder(Geometry::Type Geom, int SDim, int Info, Array< int > &dofs) const
Get the local dofs for a given sub-manifold.
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
static void AdjustVDofs(Array< int > &vdofs)
Remove the orientation information encoded into an array of dofs Some basis function types have a rel...
virtual const Operator * GetProlongationMatrix() const
virtual const Operator * GetRestrictionOperator() const
An abstract operator that performs the same action as GetRestrictionMatrix.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
int GetNE() const
Returns number of elements in the mesh.
const ElementRestrictionOperator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
const FiniteElement * GetFaceElement(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th face in the ...
int GetNFbyType(FaceType type) const
Returns the number of faces according to the requested type.
const FiniteElementCollection * FEColl() const
Mesh * GetMesh() const
Returns the mesh.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
int GetVDim() const
Returns the vector dimension of the finite element space.
virtual const FaceRestriction * GetFaceRestriction(ElementDofOrdering f_ordering, FaceType, L2FaceValues mul=L2FaceValues::DoubleValued) const
Return an Operator that converts L-vectors to E-vectors on each face.
virtual void GetFaceMap(const int face_id, Array< int > &face_map) const
Return the mapping from lexicographic face DOFs to lexicographic element DOFs for the given local fac...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Vector Ct_mat
Constraint matrix (transposed) stored element-wise.
void ConstructC()
Construct the constraint matrix.
void Init(const Array< int > &ess_tdof_list)
Prepare for assembly; form the constraint matrix.
void FactorElementMatrices(Vector &AhatInvCt_mat)
void ReduceRHS(const Vector &b, Vector &b_r) const
Given a right-hand side on the original space, compute the corresponding right-hand side for the Lagr...
Array< int > hat_dof_gather_map
void ComputeSolution(const Vector &b, const Vector &sol_r, Vector &sol) const
Given Lagrange multipliers sol_r and the original right-hand side b, recover the solution sol on the ...
Array< DofType > hat_dof_marker
HybridizationExtension(class Hybridization &hybridization_)
Constructor.
Vector tmp2
Temporary vectors.
void ConstructH()
Form the Schur complement matrix .
void MultR(const Vector &b, Vector &b_hat) const
Apply the action of R mapping from "hat DOFs" to T-vector.
void MultC(const Vector &x, Vector &y) const
Compute the action of C x.
void MultAhatInv(Vector &x) const
Apply the elementwise A_hat^{-1}.
int num_hat_dofs
Number of Lagrange multipliers.
void AssembleMatrix(int el, const class DenseMatrix &elmat)
Assemble the element matrix A into the hybridized system matrix.
void MultCt(const Vector &x, Vector &y) const
Compute the action of C^t x.
class Hybridization & h
The associated Hybridization object.=.
void MultRt(const Vector &b, Vector &b_hat) const
Apply the action of R^t mapping into the "hat DOF" space.
void AssembleBdrMatrix(int bdr_el, const class DenseMatrix &elmat)
Assemble the boundary element matrix A into the hybridized system matrix.
void AssembleElementMatrices(const class DenseTensor &el_mats)
Invert and store the element matrices Ahat.
Auxiliary class Hybridization, used to implement BilinearForm hybridization.
FiniteElementSpace & c_fes
std::unique_ptr< SparseMatrix > H
The Schur complement system for the Lagrange multiplier.
FiniteElementSpace & fes
The finite element space.
std::unique_ptr< BilinearFormIntegrator > c_bfi
The constraint integrator.
Wrapper for hypre's ParCSR matrix class.
void BooleanMult(int alpha, const int *x, int beta, int *y)
The "Boolean" analog of y = alpha * A * x + beta * y, where elements in the sparsity pattern of the m...
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
Geometry::Type GetElementGeometry(int i) const
virtual int GetNFbyType(FaceType type) const
Returns the number of faces according to the requested type, does not count master nonconforming face...
const Element * GetElement(int i) const
Return pointer to the i'th element object.
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
FaceInformation GetFaceInformation(int f) const
void GetBdrElementAdjacentElement(int bdr_el, int &el, int &info) const
For the given boundary element, bdr_el, return its adjacent element and its info, i....
Pointer to an Operator of a specified type.
void MakePtAP(OperatorHandle &A, OperatorHandle &P)
Reset the OperatorHandle to hold the product P^t A P.
void MakeSquareBlockDiag(MPI_Comm comm, HYPRE_BigInt glob_size, HYPRE_BigInt *row_starts, SparseMatrix *diag)
Reset the OperatorHandle to hold a parallel square block-diagonal matrix using the currently set type...
Operator::Type Type() const
Get the currently set operator type id.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Abstract parallel finite element space.
const Array< int > & GetDofMap() const
Get an Array<int> that maps lexicographically ordered indices to the indices of the respective nodes/...
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
int Size() const
Returns the size of the vector.
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
void SetSize(int s)
Resize the vector to size s.
virtual real_t * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
MFEM_HOST_DEVICE void AddMultAtB(const int Aheight, const int Awidth, const int Bwidth, const TA *Adata, const TB *Bdata, TC *Cdata, const TB alpha, const TA beta)
Compute C = alpha*At*B + beta*C.
MFEM_HOST_DEVICE void LSolve(const real_t *data, const int m, const int *ipiv, real_t *x)
Assuming L.U = P.A factored matrix of size (m x m), compute X <- L^{-1} P X, for a vector X of length...
MFEM_HOST_DEVICE void USolve(const real_t *data, const int m, real_t *x)
Assuming L.U = P.A factored matrix of size (m x m), compute X <- U^{-1} X, for a vector X of length m...
MFEM_HOST_DEVICE void BlockFactor(const real_t *data, int m, const int *ipiv, int n, real_t *A12, real_t *A21, real_t *A22)
MFEM_HOST_DEVICE bool LUFactor(real_t *A, const int m, int *ipiv, const real_t tol=0.0)
Compute the LU factorization of the m x m matrix A.
MFEM_HOST_DEVICE void SubMult(const int m, const int n, const int r, const real_t *A21, const real_t *X1, real_t *X2)
Given an (n x m) matrix A21, compute X2 <- X2 - A21 X1, for matrices X1, and X2 of size (m x r) and (...
MFEM_HOST_DEVICE void LUSolve(const real_t *data, const int m, const int *ipiv, real_t *x)
Assuming L.U = P.A for a factored matrix (m x m),.
void add(const Vector &v1, const Vector &v2, Vector &v)
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
bool UsesTensorBasis(const FiniteElementSpace &fes)
Return true if the mesh contains only one topology and the elements are tensor elements.
@ SIZE
Number of host and device memory types.
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
@ NATIVE
Native ordering as defined by the FiniteElement.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
void forall(int N, lambda &&body)