15 #include "../general/forall.hpp" 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())
271 for (
int i = 0; i < mesh.
GetNE(); ++i)
289 const bool has_bdr_integs = (
a->
GetBFBFI()->Size() > 0 ||
303 std::unordered_map<int,int> f_to_be;
304 for (
int i = 0; i < mesh.
GetNBE(); ++i)
312 int missing_bdr_elems = 0;
320 if (f_to_be.find(
f) != f_to_be.end())
322 const int be = f_to_be[
f];
335 if (missing_bdr_elems)
337 MFEM_WARNING(
"Missing " << missing_bdr_elems <<
" boundary elements " 338 "for boundary faces.");
350 if (integ->Patchwise())
353 "Patchwise integration requires a NURBS FE space");
354 integ->AssembleNURBSPA(*
a->
FESpace());
365 integ->AssemblePABoundary(*
a->
FESpace());
371 integ->AssemblePAInteriorFaces(*
a->
FESpace());
377 integ->AssemblePABoundaryFaces(*
a->
FESpace());
385 const int iSz = integrators.
Size();
391 for (
int i = 0; i < iSz; ++i)
393 integrators[i]->AssembleDiagonalPA(
localY);
415 for (
int i = 0; i < iSz; ++i)
417 integrators[i]->AssembleDiagonalPA(y);
422 const int n_bdr_integs = bdr_integs.
Size();
426 for (
int i = 0; i < n_bdr_integs; ++i)
428 bdr_integs[i]->AssembleDiagonalPA(
bdr_face_Y);
469 const int iSz = integrators.
Size();
471 bool allPatchwise =
true;
472 bool somePatchwise =
false;
474 for (
int i = 0; i < iSz; ++i)
476 if (integrators[i]->Patchwise())
478 somePatchwise =
true;
482 allPatchwise =
false;
486 MFEM_VERIFY(!(somePatchwise && !allPatchwise),
487 "All or none of the integrators should be patchwise");
493 for (
int i = 0; i < iSz; ++i)
495 if (integrators[i]->Patchwise())
497 integrators[i]->AddMultNURBSPA(x, y);
501 integrators[i]->AddMultPA(x, y);
512 for (
int i = 0; i < iSz; ++i)
526 const int iFISz = intFaceIntegrators.
Size();
533 for (
int i = 0; i < iFISz; ++i)
543 const int n_bdr_integs = bdr_integs.
Size();
544 const int n_bdr_face_integs = bdr_face_integs.
Size();
545 const bool has_bdr_integs = (n_bdr_face_integs > 0 || n_bdr_integs > 0);
554 for (
int i = 0; i < n_bdr_integs; ++i)
559 for (
int i = 0; i < n_bdr_face_integs; ++i)
572 const int iSz = integrators.
Size();
578 for (
int i = 0; i < iSz; ++i)
589 for (
int i = 0; i < iSz; ++i)
591 integrators[i]->AddMultTransposePA(x, y);
596 const int iFISz = intFaceIntegrators.
Size();
603 for (
int i = 0; i < iFISz; ++i)
613 const int n_bdr_integs = bdr_integs.
Size();
614 const int n_bdr_face_integs = bdr_face_integs.
Size();
615 const bool has_bdr_integs = (n_bdr_face_integs > 0 || n_bdr_integs > 0);
625 for (
int i = 0; i < n_bdr_integs; ++i)
630 for (
int i = 0; i < n_bdr_face_integs; ++i)
642 static void AddWithMarkers_(
652 const auto d_attr =
Reshape(attributes.
Read(), ne);
656 const int attr = d_attr[e];
657 if (d_m[attr - 1] == 0) {
return; }
658 for (
int i = 0; i < nd; ++i)
660 d_y(i, e) += d_x(i, e);
670 const bool transpose,
679 const int ne = attributes.
Size();
680 const int nd = x.
Size() / ne;
681 AddWithMarkers_(ne, nd,
tmp_evec, *markers, attributes, y);
693 factorize_face_terms(false)
712 const int integratorCount = integrators.
Size();
713 if ( integratorCount == 0 )
717 for (
int i = 0; i < integratorCount; ++i)
726 MFEM_VERIFY(
a->
GetBBFI()->Size() == 0,
727 "Element assembly does not support AddBoundaryIntegrator yet.");
730 const int intFaceIntegratorCount = intFaceIntegrators.Size();
731 if (intFaceIntegratorCount>0)
737 for (
int i = 0; i < intFaceIntegratorCount; ++i)
739 intFaceIntegrators[i]->AssembleEAInteriorFaces(*
a->
FESpace(),
746 const int boundFaceIntegratorCount = bdrFaceIntegrators.
Size();
747 if (boundFaceIntegratorCount>0)
753 for (
int i = 0; i < boundFaceIntegratorCount; ++i)
792 const int e = glob_j/NDOFS;
793 const int j = glob_j%NDOFS;
795 for (
int i = 0; i < NDOFS; i++)
797 res += A(i, j, e)*X(i, e);
810 const int iFISz = intFaceIntegrators.
Size();
827 const int f = glob_j/NDOFS;
828 const int j = glob_j%NDOFS;
830 for (
int i = 0; i < NDOFS; i++)
832 res += A_int(i, j, 0,
f)*X(i, 0,
f);
836 for (
int i = 0; i < NDOFS; i++)
838 res += A_int(i, j, 1,
f)*X(i, 1,
f);
846 const int f = glob_j/NDOFS;
847 const int j = glob_j%NDOFS;
849 for (
int i = 0; i < NDOFS; i++)
851 res += A_ext(i, j, 0,
f)*X(i, 0,
f);
855 for (
int i = 0; i < NDOFS; i++)
857 res += A_ext(i, j, 1,
f)*X(i, 1,
f);
868 const int bFISz = bdrFaceIntegrators.
Size();
883 const int f = glob_j/NDOFS;
884 const int j = glob_j%NDOFS;
886 for (
int i = 0; i < NDOFS; i++)
888 res += A(i, j,
f)*X(i,
f);
920 const int e = glob_j/NDOFS;
921 const int j = glob_j%NDOFS;
923 for (
int i = 0; i < NDOFS; i++)
925 res += A(j, i, e)*X(i, e);
938 const int iFISz = intFaceIntegrators.
Size();
955 const int f = glob_j/NDOFS;
956 const int j = glob_j%NDOFS;
958 for (
int i = 0; i < NDOFS; i++)
960 res += A_int(j, i, 0,
f)*X(i, 0,
f);
964 for (
int i = 0; i < NDOFS; i++)
966 res += A_int(j, i, 1,
f)*X(i, 1,
f);
974 const int f = glob_j/NDOFS;
975 const int j = glob_j%NDOFS;
977 for (
int i = 0; i < NDOFS; i++)
979 res += A_ext(j, i, 1,
f)*X(i, 0,
f);
983 for (
int i = 0; i < NDOFS; i++)
985 res += A_ext(j, i, 0,
f)*X(i, 1,
f);
996 const int bFISz = bdrFaceIntegrators.
Size();
1011 const int f = glob_j/NDOFS;
1012 const int j = glob_j%NDOFS;
1014 for (
int i = 0; i < NDOFS; i++)
1016 res += A(j, i,
f)*X(i,
f);
1047 bool keep_nbr_block =
false;
1061 keep_nbr_block =
true;
1075 "Full Assembly not yet supported on NCMesh.");
1083 for (
int i =
height; i > 0; i--)
1108 "Full Assembly not yet supported on NCMesh.");
1114 if (restF) { restF->
FillI(*mat, keep_nbr_block); }
1118 for (
int i = 0; i <
height; i++)
1120 const int nnz = h_I[i];
1124 const int nnz = cpt;
1135 for (
int i =
height; i > 0; i--)
1159 if (
auto pa = dynamic_cast<ParBilinearForm*>(
a) )
1161 pa->ParallelRAP(*pa->mat, A);
1173 MFEM_VERIFY(
a->
diag_policy == DiagonalPolicy::DIAG_ONE,
1174 "Only DiagonalPolicy::DIAG_ONE supported with" 1175 " FABilinearFormExtension.");
1177 if ( dynamic_cast<ParBilinearForm*>(
a) )
1180 DiagonalPolicy::DIAG_ONE);
1186 DiagonalPolicy::DIAG_ONE);
1213 if ( (pfes = dynamic_cast<const ParFiniteElementSpace*>(
test_fes)) )
1217 x_gf.
MakeRef(const_cast<ParFiniteElementSpace*>(pfes),
1218 const_cast<Vector&>(x),0);
1222 auto dg_x_ptr = dg_x.
Write();
1223 auto x_ptr = x.
Read();
1226 dg_x_ptr[i] = x_ptr[i];
1228 const int shared_size = shared_x.
Size();
1229 auto shared_x_ptr = shared_x.
Read();
1232 dg_x_ptr[local_size+i] = shared_x_ptr[i];
1235 if ((pform = dynamic_cast<ParBilinearForm*>(
a)) && (pform->keep_nbr_block))
1237 mat->
Mult(dg_x, dg_y);
1239 auto dg_y_ptr = dg_y.
Read();
1243 y_ptr[i] += dg_y_ptr[i];
1274 if ( (pfes = dynamic_cast<const ParFiniteElementSpace*>(
test_fes)) )
1278 x_gf.
MakeRef(const_cast<ParFiniteElementSpace*>(pfes),
1279 const_cast<Vector&>(x),0);
1283 auto dg_x_ptr = dg_x.
Write();
1284 auto x_ptr = x.
Read();
1287 dg_x_ptr[i] = x_ptr[i];
1289 const int shared_size = shared_x.
Size();
1290 auto shared_x_ptr = shared_x.
Read();
1293 dg_x_ptr[local_size+i] = shared_x_ptr[i];
1296 if ((pb = dynamic_cast<ParBilinearForm*>(
a)) && (pb->keep_nbr_block))
1300 auto dg_y_ptr = dg_y.
Read();
1304 y_ptr[i] += dg_y_ptr[i];
1333 :
Operator(form->Height(), form->Width()),
a(form)
1363 trial_fes(form->TrialFESpace()),
1364 test_fes(form->TestFESpace()),
1365 elem_restrict_trial(NULL),
1366 elem_restrict_test(NULL)
1374 const int integratorCount = integrators.
Size();
1375 for (
int i = 0; i < integratorCount; ++i)
1379 MFEM_VERIFY(
a->
GetBBFI()->Size() == 0,
1380 "Partial assembly does not support AddBoundaryIntegrator yet.");
1382 "Partial assembly does not support AddTraceFaceIntegrator yet.");
1384 "Partial assembly does not support AddBdrTraceFaceIntegrator yet.");
1441 const double c)
const 1444 if (elem_restrict_x)
1446 elem_restrict_x->
Mult(x, localX);
1463 if (elem_restrict_y)
1481 const double c)
const 1484 const int iSz = integrators.
Size();
1491 for (
int i = 0; i < iSz; ++i)
1513 const double c)
const 1516 const int iSz = integrators.
Size();
1523 for (
int i = 0; i < iSz; ++i)
1542 const int iSz = integrators.
Size();
1548 if (H1elem_restrict_trial)
1561 for (
int i = 0; i < iSz; ++i)
1569 integrators[i]->AssembleDiagonalPA_ADAt(D,
localTest);
1574 if (H1elem_restrict_test)
1587 for (
int i = 0; i < iSz; ++i)
1591 integrators[i]->AssembleDiagonalPA_ADAt(
localTrial, diag);
1595 integrators[i]->AssembleDiagonalPA_ADAt(D, diag);
1617 const int integratorCount = integrators.
Size();
1618 for (
int i = 0; i < integratorCount; ++i)
1636 mfem_error(
"A real ElementRestriction is required in this setting!");
1639 auto tm = test_multiplicity.
ReadWrite();
1642 tm[i] = 1.0 / tm[i];
1650 const int iSz = integrators.
Size();
1657 for (
int i = 0; i < iSz; ++i)
1675 mfem_error(
"In this setting you need a real ElementRestriction!");
1683 const int iSz = integrators.
Size();
1689 MFEM_VERIFY(x.
Size() == test_multiplicity.
Size(),
"Input vector of wrong size");
1691 auto tm = test_multiplicity.
Read();
1700 for (
int i = 0; i < iSz; ++i)
1714 mfem_error(
"Trial ElementRestriction not defined");
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
void FillI(SparseMatrix &mat) const
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 ...
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
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)...
void Mult(const Vector &x, Vector &y) const override=0
Extract the face degrees of freedom from x into y.
void ExchangeFaceNbrData()
void FillJAndData(const Vector &ea_data, SparseMatrix &mat) const
int GetBdrElementEdgeIndex(int i) const
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
void SetSize(int s)
Resize the vector to size s.
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
virtual void AddMultTransposeUnsigned(const Vector &x, Vector &y, const double a=1.0) const
Add the face degrees of freedom x to the element degrees of freedom y ignoring the signs from DOF ori...
Geometry::Type GetFaceGeometry(int i) const
Return the Geometry::Type associated with face i.
Pointer to an Operator of a specified type.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
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 Size() const
Returns the size of the vector.
const NURBSExtension * GetNURBSext() const
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
Abstract parallel finite element space.
int GetFaceNbrVSize() const
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...
bool UsesTensorBasis(const FiniteElementSpace &fes)
Return true if the mesh contains only one topology and the elements are tensor elements.
void SortColumnIndices()
Sort the column indices corresponding to each row.
Memory< double > & GetMemoryData()
int GetNBE() const
Returns number of boundary elements.
Memory< int > & GetMemoryI()
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.
Memory< int > & GetMemoryJ()
std::function< double(const Vector &)> f(double mass_coeff)
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.
virtual void MakeRef(FiniteElementSpace *f, double *v)
Make the ParGridFunction reference external data on a new FiniteElementSpace.
int GetAttribute(int i) const
Return the attribute of element i.
virtual void AddFaceMatricesToElementMatrices(const Vector &fea_data, Vector &ea_data) const
This methods adds the DG face matrices to the element matrices.
void ExchangeFaceNbrData()
PADiscreteLinearOperatorExtension(DiscreteLinearOperator *linop)
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...
Native ordering as defined by the FiniteElement.
Operator that extracts Face degrees of freedom for L2 spaces.
virtual double * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
static MemoryType GetMemoryType()
(DEPRECATED) Equivalent to GetDeviceMemoryType().
void MultLeftInverse(const Vector &x, Vector &y) const
void MultTransposeUnsigned(const Vector &x, Vector &y) const
Compute MultTranspose without applying signs based on DOF orientations.
virtual const Operator * GetOutputRestrictionTranspose() const
Transpose of GetOutputRestriction, directly available in this form to facilitate matrix-free RAP-type...
void FormRectangularSystemOperator(const Array< int > &, const Array< int > &, OperatorHandle &A)
Setup OperatorHandle A to contain constrained linear operator.
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...
void Assemble()
Partial assembly of all internal integrators.
const Operator * GetOutputRestrictionTranspose() const
Transpose of GetOutputRestriction, directly available in this form to facilitate matrix-free RAP-type...
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
virtual void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
Mesh * GetMesh() const
Returns the mesh.
void forall(int N, lambda &&body)
Operator that converts FiniteElementSpace L-vectors to E-vectors.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
bool DeviceCanUseCeed()
Function that determines if a CEED kernel should be used, based on the current mfem::Device configura...
void FillJAndData(const Vector &ea_data, SparseMatrix &mat) const
void MultUnsigned(const Vector &x, Vector &y) const
Compute Mult without applying signs based on DOF orientations.
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 GetDof() const
Returns the number of degrees of freedom in the finite element.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
static bool Allows(unsigned long b_mask)
Return true if any of the backends in the backend mask, b_mask, are allowed.
void FillSparseMatrix(const Vector &mat_ea, SparseMatrix &mat) const
Fill a Sparse Matrix with Element Matrices.
Vector & Set(const double a, const Vector &x)
(*this) = a * x
int height
Dimension of the output / number of rows in the matrix.
int GetNE() const
Returns number of elements.
virtual double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Rectangular Operator for imposing essential boundary conditions on the input space using only the act...
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
void SyncAliasMemory(const Vector &v) const
Update the alias memory location of the vector to match v.
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
void FormSystemOperator(const Array< int > &ess_tdof_list, Operator *&A)
Return in A a parallel (on truedofs) version of this square operator.
ElementDofOrdering
Constants describing the possible orderings of the DOFs in one element.
void AddMult(const Vector &x, Vector &y, const double c=1.0) const
y += c*A*x
void OverrideSize(int height_, int width_)
Sets the height and width of the matrix.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
Lexicographic ordering for tensor-product FiniteElements.
Operator * SetupRAP(const Operator *Pi, const Operator *Po)
Returns RAP Operator of this, using input/output Prolongation matrices Pi corresponds to "P"...
int Size() const
Return the logical size of the array.
FaceInformation GetFaceInformation(int f) const
bool IsDGSpace() const
Return whether or not the space is discontinuous (L2)
Class for parallel grid function.
Wrapper for hypre's ParCSR matrix class.
Bitwise-OR of all CEED backends.
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
Operator that converts L2 FiniteElementSpace L-vectors to E-vectors.
int width
Dimension of the input / number of columns in the matrix.
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...
void AddMultTranspose(const Vector &x, Vector &y, const double c=1.0) const
y += c*A^T*x
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.