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;
260 DeviceMatrix d_A_bb(&d_A_bb_all(0,e), nbfdofs, nbfdofs);
262 for (
int j = 0; j < nidofs; j++)
264 d_ipiv_ii(j,e) = ipiv_ii[j];
265 for (
int i = 0; i < nidofs; i++)
267 d_A_ii(i,j,e) = A_ii(i,j);
269 for (
int i = 0; i < nbfdofs; i++)
271 d_A_bi(i,j) = A_bi(i,j);
274 for (
int j = 0; j < nbfdofs; j++)
276 d_ipiv_bb(j,e) = ipiv_bb[j];
277 for (
int i = 0; i < nidofs; i++)
279 d_A_ib(i,j) = A_ib(i,j);
281 for (
int i = 0; i < nbfdofs; i++)
283 d_A_bb(i,j) = A_bb(i,j);
294 const int ne = mesh.
GetNE();
295 const int n_faces_per_el = GetNFacesPerElement(mesh);
317 const auto d_AhatInvCt =
318 Reshape(AhatInvCt_mat.
Read(), m, n, n_faces_per_el, ne);
321 const int n_face_connections = 2*n_faces_per_el - 1;
322 Array<int> face_to_face(nf * n_face_connections);
329 auto d_CAhatInvCt =
Reshape(CAhatInvCt.
Write(), n, n, n_face_connections, nf);
330 auto d_face_to_face =
Reshape(face_to_face.
Write(), n_face_connections, nf);
332 mfem::forall(n*n*n_face_connections*nf, [=] MFEM_HOST_DEVICE (
int i)
334 d_CAhatInvCt[i] = 0.0;
340 for (
int ei = 0; ei < 2; ++ei)
342 const int e = d_face_to_el(0, ei, fi);
343 if (e < 0 || e >= ne) {
continue; }
344 for (
int fj_i = 0; fj_i < n_faces_per_el; ++fj_i)
346 const int fj = d_el_to_face(fj_i, e);
348 if (fj < 0) {
continue; }
353 for (
int i = 0; i < idx; ++i)
355 if (d_face_to_face(i, fi) == fj)
364 d_face_to_face(idx, fi) = fj;
370 for (; idx < n_face_connections; ++idx)
372 d_face_to_face(idx, fi) = -1;
376 mfem::forall(nf*n_face_connections, [=] MFEM_HOST_DEVICE (
int idx)
378 const int idx_j = idx % n_face_connections;
379 const int fi = idx / n_face_connections;
381 const int fj = d_face_to_face(idx_j, fi);
382 if (fj < 0) {
return; }
384 for (
int ei = 0; ei < 2; ++ei)
386 const int e = d_face_to_el(0, ei, fi);
387 if (e < 0 || e >= ne) {
continue; }
388 const int fi_i = d_face_to_el(1, ei, fi);
391 for (
int ej = 0; ej < 2; ++ej)
393 if (d_face_to_el(0, ej, fj) == e)
395 fj_i = d_face_to_el(1, ej, fj);
401 const real_t *Ct_i = &d_Ct(0, 0, fi_i, e);
402 const real_t *AhatInvCt_i = &d_AhatInvCt(0, 0, fj_i, e);
403 real_t *CAhatInvCt_i = &d_CAhatInvCt(0, 0, idx_j, fi);
416 h.
H->OverrideSize(ncdofs, ncdofs);
418 h.
H->GetMemoryI().New(ncdofs + 1,
h.
H->GetMemoryI().GetMemoryType());
421 int *I =
h.
H->WriteI();
423 mfem::forall(ncdofs, [=] MFEM_HOST_DEVICE (
int i) { I[i] = 0; });
427 const int i = idx_i % n;
428 const int fi = idx_i / n;
429 const int ii = c_gather_map(i, fi);
431 for (
int idx = 0; idx < n_face_connections; ++idx)
433 const int fj = d_face_to_face(idx, fi);
434 if (fj < 0) {
break; }
435 for (
int j = 0; j < n; ++j)
437 if (d_CAhatInvCt(i, j, idx, fi) != 0)
453 int *I =
h.
H->HostReadWriteI();
454 int empty_row_count = 0;
455 for (
int i = 0; i < ncdofs; i++)
457 if (I[i] == 0) { empty_row_count++; }
459 empty_rows.
SetSize(empty_row_count);
461 int empty_row_idx = 0;
463 for (
int i = 0; i < ncdofs; i++)
468 empty_rows[empty_row_idx] = i;
478 const int nnz =
h.
H->HostReadI()[ncdofs];
479 h.
H->GetMemoryJ().New(nnz,
h.
H->GetMemoryJ().GetMemoryType());
480 h.
H->GetMemoryData().New(nnz,
h.
H->GetMemoryData().GetMemoryType());
483 int *I =
h.
H->ReadWriteI();
484 int *J =
h.
H->WriteJ();
489 const int i = idx_i % n;
490 const int fi = idx_i / n;
491 const int ii = c_gather_map[i + fi*n];
492 for (
int idx = 0; idx < n_face_connections; ++idx)
494 const int fj = d_face_to_face(idx, fi);
495 if (fj < 0) {
break; }
496 for (
int j = 0; j < n; ++j)
498 const real_t val = d_CAhatInvCt(i, j, idx, fi);
502 const int jj = c_gather_map(j, fj);
511 const int *d_empty_rows = empty_rows.
Read();
514 const int i = d_empty_rows[idx];
524 int *I =
h.
H->HostReadWriteI();
525 for (
int i = ncdofs - 1; i > 0; --i)
537 pP.ConvertFrom(c_pfes->Dof_TrueDof_Matrix());
539 c_pfes->GetDofOffsets(),
h.
H.get());
549 const int ne = mesh.
GetNE();
554 const int n_faces_per_el = GetNFacesPerElement(mesh);
561 face_restr->
Mult(x, x_evec);
566 const auto d_x_evec =
Reshape(x_evec.
Read(), n_c_dof_per_face, nf);
569 mfem::forall(ne * n_hat_dof_per_el, [=] MFEM_HOST_DEVICE (
int idx)
571 const int e = idx / n_hat_dof_per_el;
572 const int i = idx % n_hat_dof_per_el;
574 for (
int fi = 0; fi < n_faces_per_el; ++fi)
576 const int f = d_el_to_face[e*n_faces_per_el + fi];
577 if (
f < 0) {
continue; }
578 for (
int j = 0; j < n_c_dof_per_face; ++j)
580 d_y(i, e) += d_Ct(i, j, fi, e)*d_x_evec(j,
f);
589 const int ne = mesh.
GetNE();
594 const int n_faces_per_el = GetNFacesPerElement(mesh);
604 auto d_x =
Reshape(x.
Read(), n_hat_dof_per_el, ne);
605 auto d_y_evec =
Reshape(y_evec.
Write(), n_c_dof_per_face, nf);
607 mfem::forall(nf * n_c_dof_per_face, [=] MFEM_HOST_DEVICE (
int idx)
609 const int f = idx / n_c_dof_per_face;
610 const int j = idx % n_c_dof_per_face;
611 d_y_evec(j,
f) = 0.0;
612 for (
int el_i = 0; el_i < 2; ++el_i)
614 const int e = d_face_to_el(0, el_i,
f);
615 const int fi = d_face_to_el(1, el_i,
f);
618 if (e >= ne) {
continue; }
620 for (
int i = 0; i < n_hat_dof_per_el; ++i)
622 d_y_evec(j,
f) += d_Ct(i, j, fi, e)*d_x(i, e);
633 const int n = elmat.
Width();
636 const int offset = el*n*n;
639 d_Ahat[offset + i] += d_elmat[i];
662 Ordering::DofsToVDofs<Ordering::byNODES>(n/vdim, vdim, lvdofs);
663 MFEM_ASSERT(lvdofs.
Size() == elmat.
Height(),
"internal error");
668 for (
int i = 0; i < lvdofs.
Size(); i++)
674 const int offset = el*n*n;
676 for (
int j = 0; j < n; ++j)
678 const int j_f = e2f[j];
679 if (j_f < 0) {
continue; }
680 for (
int i = 0; i < n; ++i)
682 const int i_f = e2f[i];
683 if (i_f < 0) {
continue; }
684 Ahat[offset + i + j*n] += B(i_f, j_f);
695 d_Ahat[i] += d_elmats[i];
709 MFEM_VERIFY(
dim == 2 ||
dim == 3,
"");
717 MFEM_VERIFY(tbe !=
nullptr,
"");
720 const int n_faces_per_el = GetNFacesPerElement(mesh);
723 for (
int f = 0;
f < n_faces_per_el; ++
f)
727 all_face_dofs.
Append(face_map);
732 for (
int i = 0; i < all_face_dofs.
Size(); ++i)
734 const int j_s = all_face_dofs[i];
735 const int j = (j_s >= 0) ? j_s : -1 - j_s;
736 const int j_nat_s = dof_map[j];
737 const int j_nat = (j_nat_s >= 0) ? j_nat_s : -1 - j_nat_s;
738 b_marker[j_nat] =
true;
741 for (
int i = 0; i < ndof_per_el; ++i)
749 const int n_faces_per_el = GetNFacesPerElement(mesh);
763 el_to_face[el1 * n_faces_per_el + fi1] = face_idx;
769 el_to_face[el2 * n_faces_per_el + fi2] = face_idx;
788 d_hat_offsets[i] = i*ndof_per_el;
810 int *d_free_tdof_marker = free_tdof_marker.
Write();
813 d_free_tdof_marker[i] = 1;
815 const int n_ess_dofs = ess_tdof_list.
Size();
816 const int *d_ess_tdof_list = ess_tdof_list.
Read();
819 d_free_tdof_marker[d_ess_tdof_list[i]] = 0;
836 free_vdofs_marker.
MakeRef(free_tdof_marker);
839 free_vdofs_marker.
MakeRef(free_tdof_marker);
847 const int *gather_map = R->GatherMap().Read();
848 const int *d_free_vdofs_marker = free_vdofs_marker.
Read();
850 ndof_per_face, n_faces_per_el, ne);
859 const int j_s = gather_map[i];
860 const int j = (j_s >= 0) ? j_s : -1 - j_s;
861 if (d_free_vdofs_marker[j])
863 const int i_loc = i % ndof_per_el;
864 const int e = i / ndof_per_el;
866 for (
int f = 0;
f < n_faces_per_el; ++
f)
868 for (
int k = 0; k < ndof_per_face; ++k)
870 if (d_Ct_mat(i_loc, k,
f, e) != 0.0)
891 const int *d_offsets = R->Offsets().Read();
892 const int *d_indices = R->Indices().Read();
896 d_hat_dof_gather_map[i] = -1;
900 const int offset = d_offsets[i];
901 const int j_s = d_indices[offset];
902 const int hat_dof_index = (j_s >= 0) ? j_s : -1 - j_s;
905 d_hat_dof_gather_map[hat_dof_index] = (j_s >= 0) ? i : (-2 - i);
940 if (d_hat_dof_marker[i] ==
ESSENTIAL) {
return; }
942 const int j_s = gather_map[i];
943 const int sgn = (j_s >= 0) ? 1 : -1;
944 const int j = (j_s >= 0) ? j_s : -1 - j_s;
946 d_lvec[j] = sgn*d_evec[i];
974 const int j_s = d_hat_dof_gather_map[i];
981 const int sgn = (j_s >= 0) ? 1 : -1;
982 const int j = (j_s >= 0) ? j_s : -2 - j_s;
983 d_b_hat[i] = sgn*d_b_lvec[j];
1018 constexpr int MD1D = DofQuadLimits::HDIV_MAX_D1D;
1019 constexpr int MAX_DOFS = 3*MD1D*(MD1D-1)*(MD1D-1);
1020 internal::LocalMemory<int,MAX_DOFS> bdofs_loc;
1023 for (
int i = 0; i < nbdofs; i++)
1025 const int dof_idx = d_bdofs[i];
1026 if (d_hat_dof_marker(dof_idx, e) !=
ESSENTIAL)
1028 bdofs_loc[nbfdofs] = dof_idx;
1033 for (
int i = 0; i < nidofs; ++i)
1035 d_ivals(i, e) = d_x(d_idofs[i], e);
1037 for (
int i = 0; i < nbfdofs; ++i)
1039 d_bvals(i, e) = d_x(bdofs_loc[i], e);
1046 kernels::LSolve(&d_A_ii(0,0,e), nidofs, &d_ipiv_ii(0,e), &d_ivals(0,e));
1049 nidofs, nbfdofs, 1, &d_A_bi(0,e), &d_ivals(0,e), &d_bvals(0, e));
1060 nbfdofs, nidofs, 1, &d_A_ib(0,e), &d_bvals(0,e), &d_ivals(0, e));
1065 for (
int i = 0; i < nidofs; ++i)
1067 d_x(d_idofs[i], e) = d_ivals(i, e);
1069 for (
int i = 0; i < nbfdofs; ++i)
1071 d_x(bdofs_loc[i], e) = d_bvals(i, e);
1085 if (d_hat_dof_marker[i] ==
ESSENTIAL) { d_b_hat[i] = 0.0; }
1115 P->
Mult(sol_r, sol_l);
1128 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...
bool Conforming() const
Return a bool indicating whether this mesh is conforming.
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)