43 trial_fes(
a->FESpace()),
44 test_fes(
a->FESpace())
54 const int integratorCount = integrators.
Size();
55 for (
int i = 0; i < integratorCount; ++i)
57 integrators[i]->AssembleMF(*
a->
FESpace());
60 MFEM_VERIFY(
a->
GetBBFI()->Size() == 0,
"AddBoundaryIntegrator is not "
61 "currently supported in MFBilinearFormExtension");
68 const int iSz = integrators.
Size();
72 for (
int i = 0; i < iSz; ++i)
74 integrators[i]->AssembleDiagonalMF(
localY);
91 for (
int i = 0; i < iSz; ++i)
93 integrators[i]->AssembleDiagonalMF(y);
133 const int iSz = integrators.
Size();
138 for (
int i = 0; i < iSz; ++i)
140 integrators[i]->AddMultMF(x, y);
147 for (
int i = 0; i < iSz; ++i)
155 const int iFISz = intFaceIntegrators.
Size();
162 for (
int i = 0; i < iFISz; ++i)
171 const int bFISz = bdrFaceIntegrators.
Size();
178 for (
int i = 0; i < bFISz; ++i)
190 const int iSz = integrators.
Size();
195 for (
int i = 0; i < iSz; ++i)
205 for (
int i = 0; i < iSz; ++i)
207 integrators[i]->AddMultTransposeMF(x, y);
212 const int iFISz = intFaceIntegrators.
Size();
219 for (
int i = 0; i < iFISz; ++i)
228 const int bFISz = bdrFaceIntegrators.
Size();
235 for (
int i = 0; i < bFISz; ++i)
247 trial_fes(
a->FESpace()),
248 test_fes(
a->FESpace())
269 for (
int i = 0; i < mesh.
GetNE(); ++i)
286 bool needs_normal_derivs =
false;
288 for (
int i = 0; i < integs.Size(); ++i)
290 if (integs[i]->RequiresFaceNormalDerivatives())
292 needs_normal_derivs =
true;
296 if (needs_normal_derivs)
303 const bool has_bdr_integs = (
a->
GetBFBFI()->Size() > 0 ||
315 bool needs_normal_derivs =
false;
317 for (
int i = 0; i < integs.Size(); ++i)
319 if (integs[i]->RequiresFaceNormalDerivatives())
321 needs_normal_derivs =
true;
325 if (needs_normal_derivs)
333 std::unordered_map<int,int> f_to_be;
334 for (
int i = 0; i < mesh.
GetNBE(); ++i)
342 int missing_bdr_elems = 0;
350 if (f_to_be.find(
f) != f_to_be.end())
352 const int be = f_to_be[
f];
365 if (missing_bdr_elems)
367 MFEM_WARNING(
"Missing " << missing_bdr_elems <<
" boundary elements "
368 "for boundary faces.");
380 if (integ->Patchwise())
383 "Patchwise integration requires a NURBS FE space");
384 integ->AssembleNURBSPA(*
a->
FESpace());
395 integ->AssemblePABoundary(*
a->
FESpace());
401 integ->AssemblePAInteriorFaces(*
a->
FESpace());
407 integ->AssemblePABoundaryFaces(*
a->
FESpace());
423 const int ne = attributes.Size();
424 const int nd = d.Size() / ne;
425 const auto d_attr =
Reshape(attributes.Read(), ne);
426 const auto d_m =
Reshape(markers->Read(), markers->Size());
427 auto d_d =
Reshape(d.ReadWrite(), nd, ne);
430 const int attr = d_attr[e];
431 if (d_m[attr - 1] == 0)
433 for (
int i = 0; i < nd; ++i)
442 const int iSz = integrators.
Size();
449 for (
int i = 0; i < iSz; ++i)
451 assemble_diagonal_with_markers(*integrators[i], elem_markers[i],
475 for (
int i = 0; i < iSz; ++i)
477 assemble_diagonal_with_markers(*integrators[i], elem_markers[i],
483 const int n_bdr_integs = bdr_integs.
Size();
488 for (
int i = 0; i < n_bdr_integs; ++i)
490 assemble_diagonal_with_markers(*bdr_integs[i], bdr_markers[i],
532 const int iSz = integrators.
Size();
534 bool allPatchwise =
true;
535 bool somePatchwise =
false;
537 for (
int i = 0; i < iSz; ++i)
539 if (integrators[i]->Patchwise())
541 somePatchwise =
true;
545 allPatchwise =
false;
549 MFEM_VERIFY(!(somePatchwise && !allPatchwise),
550 "All or none of the integrators should be patchwise");
556 for (
int i = 0; i < iSz; ++i)
558 if (integrators[i]->Patchwise())
560 integrators[i]->AddMultNURBSPA(x, y);
564 integrators[i]->AddMultPA(x, y);
575 for (
int i = 0; i < iSz; ++i)
589 const int iFISz = intFaceIntegrators.
Size();
624 for (
int i = 0; i < iFISz; ++i)
626 if (intFaceIntegrators[i]->RequiresFaceNormalDerivatives())
628 intFaceIntegrators[i]->AddMultPAFaceNormalDerivatives(
648 const int n_bdr_integs = bdr_integs.
Size();
649 const int n_bdr_face_integs = bdr_face_integs.
Size();
650 const bool has_bdr_integs = (n_bdr_face_integs > 0 || n_bdr_integs > 0);
669 for (
int i = 0; i < n_bdr_integs; ++i)
674 for (
int i = 0; i < n_bdr_face_integs; ++i)
676 if (bdr_face_integs[i]->RequiresFaceNormalDerivatives())
700 const int iSz = integrators.
Size();
706 for (
int i = 0; i < iSz; ++i)
717 for (
int i = 0; i < iSz; ++i)
719 integrators[i]->AddMultTransposePA(x, y);
724 const int iFISz = intFaceIntegrators.
Size();
731 for (
int i = 0; i < iFISz; ++i)
741 const int n_bdr_integs = bdr_integs.
Size();
742 const int n_bdr_face_integs = bdr_face_integs.
Size();
743 const bool has_bdr_integs = (n_bdr_face_integs > 0 || n_bdr_integs > 0);
753 for (
int i = 0; i < n_bdr_integs; ++i)
758 for (
int i = 0; i < n_bdr_face_integs; ++i)
770static void AddWithMarkers_(
780 const auto d_attr =
Reshape(attributes.
Read(), ne);
784 const int attr = d_attr[e];
785 if (d_m[attr - 1] == 0) {
return; }
786 for (
int i = 0; i < nd; ++i)
788 d_y(i, e) += d_x(i, e);
811 const int ne = attributes.
Size();
812 const int nd_1 = x.
Size() / ne;
813 const int nd_2 = dxdn.
Size() / ne;
815 AddWithMarkers_(ne, nd_1, tmp_y, *markers, attributes, y);
816 AddWithMarkers_(ne, nd_2, tmp_dydn, *markers, attributes, dydn);
829 const bool transpose,
838 const int ne = attributes.
Size();
839 const int nd = x.
Size() / ne;
840 AddWithMarkers_(ne, nd,
tmp_evec, *markers, attributes, y);
852 factorize_face_terms(false)
871 const int integratorCount = integrators.
Size();
872 if ( integratorCount == 0 )
876 for (
int i = 0; i < integratorCount; ++i)
885 MFEM_VERIFY(
a->
GetBBFI()->Size() == 0,
886 "Element assembly does not support AddBoundaryIntegrator yet.");
889 const int intFaceIntegratorCount = intFaceIntegrators.
Size();
890 if (intFaceIntegratorCount>0)
896 for (
int i = 0; i < intFaceIntegratorCount; ++i)
898 intFaceIntegrators[i]->AssembleEAInteriorFaces(*
a->
FESpace(),
905 const int boundFaceIntegratorCount = bdrFaceIntegrators.
Size();
906 if (boundFaceIntegratorCount>0)
912 for (
int i = 0; i < boundFaceIntegratorCount; ++i)
951 const int e = glob_j/NDOFS;
952 const int j = glob_j%NDOFS;
954 for (
int i = 0; i < NDOFS; i++)
956 res += A(i, j, e)*X(i, e);
969 const int iFISz = intFaceIntegrators.
Size();
986 const int f = glob_j/NDOFS;
987 const int j = glob_j%NDOFS;
989 for (
int i = 0; i < NDOFS; i++)
991 res += A_int(i, j, 0,
f)*X(i, 0,
f);
995 for (
int i = 0; i < NDOFS; i++)
997 res += A_int(i, j, 1,
f)*X(i, 1,
f);
1005 const int f = glob_j/NDOFS;
1006 const int j = glob_j%NDOFS;
1008 for (
int i = 0; i < NDOFS; i++)
1010 res += A_ext(i, j, 0,
f)*X(i, 0,
f);
1014 for (
int i = 0; i < NDOFS; i++)
1016 res += A_ext(i, j, 1,
f)*X(i, 1,
f);
1027 const int bFISz = bdrFaceIntegrators.
Size();
1042 const int f = glob_j/NDOFS;
1043 const int j = glob_j%NDOFS;
1045 for (
int i = 0; i < NDOFS; i++)
1047 res += A(i, j,
f)*X(i,
f);
1079 const int e = glob_j/NDOFS;
1080 const int j = glob_j%NDOFS;
1082 for (
int i = 0; i < NDOFS; i++)
1084 res += A(j, i, e)*X(i, e);
1097 const int iFISz = intFaceIntegrators.
Size();
1114 const int f = glob_j/NDOFS;
1115 const int j = glob_j%NDOFS;
1117 for (
int i = 0; i < NDOFS; i++)
1119 res += A_int(j, i, 0,
f)*X(i, 0,
f);
1123 for (
int i = 0; i < NDOFS; i++)
1125 res += A_int(j, i, 1,
f)*X(i, 1,
f);
1133 const int f = glob_j/NDOFS;
1134 const int j = glob_j%NDOFS;
1136 for (
int i = 0; i < NDOFS; i++)
1138 res += A_ext(j, i, 1,
f)*X(i, 0,
f);
1142 for (
int i = 0; i < NDOFS; i++)
1144 res += A_ext(j, i, 0,
f)*X(i, 1,
f);
1155 const int bFISz = bdrFaceIntegrators.
Size();
1170 const int f = glob_j/NDOFS;
1171 const int j = glob_j%NDOFS;
1173 for (
int i = 0; i < NDOFS; i++)
1175 res += A(j, i,
f)*X(i,
f);
1206 bool keep_nbr_block =
false;
1220 keep_nbr_block =
true;
1234 "Full Assembly not yet supported on NCMesh.");
1242 for (
int i =
height; i > 0; i--)
1270 if (restF) { restF->
FillI(*mat, keep_nbr_block); }
1274 for (
int i = 0; i <
height; i++)
1276 const int nnz = h_I[i];
1280 const int nnz = cpt;
1291 for (
int i =
height; i > 0; i--)
1317 pa->ParallelRAP(*pa->mat, A);
1330 "Only DiagonalPolicy::DIAG_ONE supported with"
1331 " FABilinearFormExtension.");
1374 const_cast<Vector&
>(x),0);
1378 auto dg_x_ptr = dg_x.
Write();
1379 auto x_ptr = x.
Read();
1382 dg_x_ptr[i] = x_ptr[i];
1384 const int shared_size = shared_x.
Size();
1385 auto shared_x_ptr = shared_x.
Read();
1388 dg_x_ptr[local_size+i] = shared_x_ptr[i];
1391 if ((pform =
dynamic_cast<ParBilinearForm*
>(
a)) && (pform->keep_nbr_block))
1393 mat->
Mult(dg_x, dg_y);
1395 auto dg_y_ptr = dg_y.
Read();
1399 y_ptr[i] += dg_y_ptr[i];
1435 const_cast<Vector&
>(x),0);
1439 auto dg_x_ptr = dg_x.
Write();
1440 auto x_ptr = x.
Read();
1443 dg_x_ptr[i] = x_ptr[i];
1445 const int shared_size = shared_x.
Size();
1446 auto shared_x_ptr = shared_x.
Read();
1449 dg_x_ptr[local_size+i] = shared_x_ptr[i];
1456 auto dg_y_ptr = dg_y.
Read();
1460 y_ptr[i] += dg_y_ptr[i];
1489 :
Operator(form->Height(), form->Width()),
a(form)
1519 trial_fes(form->TrialFESpace()),
1520 test_fes(form->TestFESpace()),
1521 elem_restrict_trial(NULL),
1522 elem_restrict_test(NULL)
1530 const int integratorCount = integrators.
Size();
1531 for (
int i = 0; i < integratorCount; ++i)
1535 MFEM_VERIFY(
a->
GetBBFI()->Size() == 0,
1536 "Partial assembly does not support AddBoundaryIntegrator yet.");
1538 "Partial assembly does not support AddTraceFaceIntegrator yet.");
1540 "Partial assembly does not support AddBdrTraceFaceIntegrator yet.");
1600 if (elem_restrict_x)
1602 elem_restrict_x->
Mult(x, localX);
1619 if (elem_restrict_y)
1640 const int iSz = integrators.
Size();
1647 for (
int i = 0; i < iSz; ++i)
1672 const int iSz = integrators.
Size();
1679 for (
int i = 0; i < iSz; ++i)
1698 const int iSz = integrators.
Size();
1704 if (H1elem_restrict_trial)
1717 for (
int i = 0; i < iSz; ++i)
1725 integrators[i]->AssembleDiagonalPA_ADAt(D,
localTest);
1730 if (H1elem_restrict_test)
1743 for (
int i = 0; i < iSz; ++i)
1747 integrators[i]->AssembleDiagonalPA_ADAt(
localTrial, diag);
1751 integrators[i]->AssembleDiagonalPA_ADAt(D, diag);
1773 const int integratorCount = integrators.
Size();
1774 for (
int i = 0; i < integratorCount; ++i)
1792 mfem_error(
"A real ElementRestriction is required in this setting!");
1795 auto tm = test_multiplicity.
ReadWrite();
1798 tm[i] = 1.0 / tm[i];
1806 const int iSz = integrators.
Size();
1813 for (
int i = 0; i < iSz; ++i)
1831 mfem_error(
"In this setting you need a real ElementRestriction!");
1839 const int iSz = integrators.
Size();
1845 MFEM_VERIFY(x.
Size() == test_multiplicity.
Size(),
"Input vector of wrong size");
1847 auto tm = test_multiplicity.
Read();
1856 for (
int i = 0; i < iSz; ++i)
1870 mfem_error(
"Trial ElementRestriction not defined");
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
static MemoryType GetMemoryType()
(DEPRECATED) Equivalent to GetDeviceMemoryType().
static bool Allows(unsigned long b_mask)
Return true if any of the backends in the backend mask, b_mask, are allowed.
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
Operator that converts FiniteElementSpace L-vectors to E-vectors.
void FillSparseMatrix(const Vector &mat_ea, SparseMatrix &mat) const
Fill a Sparse Matrix with Element Matrices.
void FillJAndData(const Vector &ea_data, SparseMatrix &mat) const
void MultTransposeUnsigned(const Vector &x, Vector &y) const
Compute MultTranspose without applying signs based on DOF orientations.
void MultLeftInverse(const Vector &x, Vector &y) const
void MultUnsigned(const Vector &x, Vector &y) const
Compute Mult without applying signs based on DOF orientations.
virtual void AddMultTransposeInPlace(Vector &x, Vector &y) const
Add the face degrees of freedom x to the element degrees of freedom y. Perform the same computation a...
virtual void NormalDerivativeAddMultTranspose(const Vector &x, Vector &y) const
Add the face reference-normal derivative degrees of freedom in x to the element degrees of freedom in...
virtual void AddMultTransposeUnsigned(const Vector &x, Vector &y, const real_t a=1.0) const
Add the face degrees of freedom x to the element degrees of freedom y ignoring the signs from DOF ori...
virtual void NormalDerivativeMult(const Vector &x, Vector &y) const
For each face, sets y to the partial derivative of x with respect to the reference coordinate whose d...
void Mult(const Vector &x, Vector &y) const override=0
Extract the face degrees of freedom from x into y.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
const NURBSExtension * GetNURBSext() const
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
const ElementRestrictionOperator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
int GetNFbyType(FaceType type) const
Returns the number of faces according to the requested type.
Mesh * GetMesh() const
Returns the mesh.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
bool IsDGSpace() const
Return whether or not the space is discontinuous (L2)
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.
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Wrapper for hypre's ParCSR matrix class.
Operator that converts L2 FiniteElementSpace L-vectors to E-vectors.
void FillJAndData(const Vector &ea_data, SparseMatrix &mat) const
void FillI(SparseMatrix &mat) const
Operator that extracts Face degrees of freedom for L2 spaces.
virtual void FillI(SparseMatrix &mat, const bool keep_nbr_block=false) const
Fill the I array of SparseMatrix corresponding to the sparsity pattern given by this L2FaceRestrictio...
virtual void FillJAndData(const Vector &fea_data, SparseMatrix &mat, const bool keep_nbr_block=false) const
Fill the J and Data arrays of the SparseMatrix corresponding to the sparsity pattern given by this L2...
virtual void AddFaceMatricesToElementMatrices(const Vector &fea_data, Vector &ea_data) const
This methods adds the DG face matrices to the element matrices.
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
Geometry::Type GetFaceGeometry(int i) const
Return the Geometry::Type associated with face i.
int GetAttribute(int i) const
Return the attribute of element i.
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
int GetBdrElementFaceIndex(int be_idx) const
Return the local face (codimension-1) index for the given boundary element index.
int GetNE() const
Returns number of elements.
FaceInformation GetFaceInformation(int f) const
int GetNBE() const
Returns number of boundary elements.
Pointer to an Operator of a specified type.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get().
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
void FormRectangularLinearSystem(const Array< int > &trial_tdof_list, const Array< int > &test_tdof_list, Vector &x, Vector &b, Operator *&A, Vector &X, Vector &B)
Form a column-constrained linear system using a matrix-free approach.
void FormLinearSystem(const Array< int > &ess_tdof_list, Vector &x, Vector &b, Operator *&A, Vector &X, Vector &B, int copy_interior=0)
Form a constrained linear system using a matrix-free approach.
int width
Dimension of the input / number of columns in the matrix.
void FormSystemOperator(const Array< int > &ess_tdof_list, Operator *&A)
Return in A a parallel (on truedofs) version of this square operator.
virtual const Operator * GetOutputRestrictionTranspose() const
Transpose of GetOutputRestriction, directly available in this form to facilitate matrix-free RAP-type...
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int height
Dimension of the output / number of rows in the matrix.
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
@ DIAG_ONE
Set the diagonal value to one.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void FormRectangularSystemOperator(const Array< int > &trial_tdof_list, const Array< int > &test_tdof_list, Operator *&A)
Return in A a parallel (on truedofs) version of this rectangular operator (including constraints).
Operator * SetupRAP(const Operator *Pi, const Operator *Po)
Returns RAP Operator of this, using input/output Prolongation matrices Pi corresponds to "P",...
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 ...
PADiscreteLinearOperatorExtension(DiscreteLinearOperator *linop)
const Operator * GetOutputRestrictionTranspose() const
Transpose of GetOutputRestriction, directly available in this form to facilitate matrix-free RAP-type...
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const
Operator application: y+=A(x) (default) or y+=a*A(x).
void FormRectangularSystemOperator(const Array< int > &, const Array< int > &, OperatorHandle &A)
void Assemble()
Partial assembly of all internal integrators.
void AddMultTranspose(const Vector &x, Vector &y, const real_t c=1.0) const
Operator transpose application: y+=A^t(x) (default) or y+=a*A^t(x).
Abstract parallel finite element space.
void ExchangeFaceNbrData()
int GetFaceNbrVSize() const
Class for parallel grid function.
void ExchangeFaceNbrData()
void MakeRef(FiniteElementSpace *f, real_t *v) override
Make the ParGridFunction reference external data on a new FiniteElementSpace.
Rectangular Operator for imposing essential boundary conditions on the input space using only the act...
virtual void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
Memory< int > & GetMemoryI()
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
void OverrideSize(int height_, int width_)
Sets the height and width of the matrix.
void SortColumnIndices()
Sort the column indices corresponding to each row.
Memory< int > & GetMemoryJ()
Memory< real_t > & GetMemoryData()
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).
void SyncAliasMemory(const Vector &v) const
Update the alias memory location of the vector to match v.
Vector & Set(const real_t a, const Vector &x)
(*this) = a * x
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 * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
void mfem_error(const char *msg)
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
bool DeviceCanUseCeed()
Function that determines if a CEED kernel should be used, based on the current mfem::Device configura...
ElementDofOrdering GetEVectorOrdering(const FiniteElementSpace &fes)
Return LEXICOGRAPHIC if mesh contains only one topology and the elements are tensor elements,...
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
@ LEXICOGRAPHIC
Lexicographic ordering for tensor-product FiniteElements.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
void forall(int N, lambda &&body)
@ CEED_MASK
Bitwise-OR of all CEED backends.