15 #include "../general/forall.hpp"
19 #include "ceed/util.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());
65 const int iSz = integrators.
Size();
69 for (
int i = 0; i < iSz; ++i)
71 integrators[i]->AssembleDiagonalMF(
localY);
88 for (
int i = 0; i < iSz; ++i)
90 integrators[i]->AssembleDiagonalMF(y);
130 const int iSz = integrators.
Size();
135 for (
int i = 0; i < iSz; ++i)
137 integrators[i]->AddMultMF(x, y);
144 for (
int i = 0; i < iSz; ++i)
152 const int iFISz = intFaceIntegrators.
Size();
159 for (
int i = 0; i < iFISz; ++i)
168 const int bFISz = bdrFaceIntegrators.
Size();
175 for (
int i = 0; i < bFISz; ++i)
187 const int iSz = integrators.
Size();
192 for (
int i = 0; i < iSz; ++i)
202 for (
int i = 0; i < iSz; ++i)
204 integrators[i]->AddMultTransposeMF(x, y);
209 const int iFISz = intFaceIntegrators.
Size();
216 for (
int i = 0; i < iFISz; ++i)
225 const int bFISz = bdrFaceIntegrators.
Size();
232 for (
int i = 0; i < bFISz; ++i)
244 trial_fes(
a->FESpace()),
245 test_fes(
a->FESpace())
294 const int integratorCount = integrators.
Size();
295 for (
int i = 0; i < integratorCount; ++i)
297 integrators[i]->AssemblePA(*
a->
FESpace());
300 MFEM_VERIFY(
a->
GetBBFI()->Size() == 0,
301 "Partial assembly does not support AddBoundaryIntegrator yet.");
304 const int intFaceIntegratorCount = intFaceIntegrators.Size();
305 for (
int i = 0; i < intFaceIntegratorCount; ++i)
307 intFaceIntegrators[i]->AssemblePAInteriorFaces(*
a->
FESpace());
311 const int boundFaceIntegratorCount = bdrFaceIntegrators.
Size();
312 for (
int i = 0; i < boundFaceIntegratorCount; ++i)
314 bdrFaceIntegrators[i]->AssemblePABoundaryFaces(*
a->
FESpace());
322 const int iSz = integrators.
Size();
326 for (
int i = 0; i < iSz; ++i)
328 integrators[i]->AssembleDiagonalPA(
localY);
345 for (
int i = 0; i < iSz; ++i)
347 integrators[i]->AssembleDiagonalPA(y);
387 const int iSz = integrators.
Size();
392 for (
int i = 0; i < iSz; ++i)
394 integrators[i]->AddMultPA(x, y);
401 for (
int i = 0; i < iSz; ++i)
409 const int iFISz = intFaceIntegrators.
Size();
416 for (
int i = 0; i < iFISz; ++i)
425 const int bFISz = bdrFaceIntegrators.
Size();
432 for (
int i = 0; i < bFISz; ++i)
444 const int iSz = integrators.
Size();
449 for (
int i = 0; i < iSz; ++i)
459 for (
int i = 0; i < iSz; ++i)
461 integrators[i]->AddMultTransposePA(x, y);
466 const int iFISz = intFaceIntegrators.
Size();
473 for (
int i = 0; i < iFISz; ++i)
482 const int bFISz = bdrFaceIntegrators.
Size();
489 for (
int i = 0; i < bFISz; ++i)
501 factorize_face_terms(false)
520 const int integratorCount = integrators.
Size();
521 if ( integratorCount == 0 )
525 for (
int i = 0; i < integratorCount; ++i)
534 MFEM_VERIFY(
a->
GetBBFI()->Size() == 0,
535 "Element assembly does not support AddBoundaryIntegrator yet.");
538 const int intFaceIntegratorCount = intFaceIntegrators.Size();
539 if (intFaceIntegratorCount>0)
545 for (
int i = 0; i < intFaceIntegratorCount; ++i)
547 intFaceIntegrators[i]->AssembleEAInteriorFaces(*
a->
FESpace(),
554 const int boundFaceIntegratorCount = bdrFaceIntegrators.
Size();
555 if (boundFaceIntegratorCount>0)
561 for (
int i = 0; i < boundFaceIntegratorCount; ++i)
581 const bool useRestrict = !DeviceCanUseCeed() &&
elem_restrict;
598 MFEM_FORALL(glob_j,
ne*NDOFS,
600 const int e = glob_j/NDOFS;
601 const int j = glob_j%NDOFS;
603 for (
int i = 0; i < NDOFS; i++)
605 res += A(i, j, e)*X(i, e);
618 const int iFISz = intFaceIntegrators.
Size();
633 MFEM_FORALL(glob_j,
nf_int*NDOFS,
635 const int f = glob_j/NDOFS;
636 const int j = glob_j%NDOFS;
638 for (
int i = 0; i < NDOFS; i++)
640 res += A_int(i, j, 0, f)*X(i, 0, f);
644 for (
int i = 0; i < NDOFS; i++)
646 res += A_int(i, j, 1, f)*X(i, 1, f);
652 MFEM_FORALL(glob_j,
nf_int*NDOFS,
654 const int f = glob_j/NDOFS;
655 const int j = glob_j%NDOFS;
657 for (
int i = 0; i < NDOFS; i++)
659 res += A_ext(i, j, 0, f)*X(i, 0, f);
663 for (
int i = 0; i < NDOFS; i++)
665 res += A_ext(i, j, 1, f)*X(i, 1, f);
676 const int bFISz = bdrFaceIntegrators.
Size();
689 MFEM_FORALL(glob_j,
nf_bdr*NDOFS,
691 const int f = glob_j/NDOFS;
692 const int j = glob_j%NDOFS;
694 for (
int i = 0; i < NDOFS; i++)
696 res += A(i, j, f)*X(i, f);
709 const bool useRestrict = !DeviceCanUseCeed() &&
elem_restrict;
726 MFEM_FORALL(glob_j,
ne*NDOFS,
728 const int e = glob_j/NDOFS;
729 const int j = glob_j%NDOFS;
731 for (
int i = 0; i < NDOFS; i++)
733 res += A(j, i, e)*X(i, e);
746 const int iFISz = intFaceIntegrators.
Size();
761 MFEM_FORALL(glob_j,
nf_int*NDOFS,
763 const int f = glob_j/NDOFS;
764 const int j = glob_j%NDOFS;
766 for (
int i = 0; i < NDOFS; i++)
768 res += A_int(j, i, 0, f)*X(i, 0, f);
772 for (
int i = 0; i < NDOFS; i++)
774 res += A_int(j, i, 1, f)*X(i, 1, f);
780 MFEM_FORALL(glob_j,
nf_int*NDOFS,
782 const int f = glob_j/NDOFS;
783 const int j = glob_j%NDOFS;
785 for (
int i = 0; i < NDOFS; i++)
787 res += A_ext(j, i, 1, f)*X(i, 0, f);
791 for (
int i = 0; i < NDOFS; i++)
793 res += A_ext(j, i, 0, f)*X(i, 1, f);
804 const int bFISz = bdrFaceIntegrators.
Size();
817 MFEM_FORALL(glob_j,
nf_bdr*NDOFS,
819 const int f = glob_j/NDOFS;
820 const int j = glob_j%NDOFS;
822 for (
int i = 0; i < NDOFS; i++)
824 res += A(j, i, f)*X(i, f);
855 bool keep_nbr_block =
false;
869 keep_nbr_block =
true;
883 "Full Assembly not yet supported on NCMesh.");
891 for (
int i = height; i > 0; i--)
915 "Full Assembly not yet supported on NCMesh.");
921 if (restF) { restF->
FillI(*mat, keep_nbr_block); }
925 for (
int i = 0; i <
height; i++)
927 const int nnz = h_I[i];
942 for (
int i = height; i > 0; i--)
962 if ( (pfes = dynamic_cast<const ParFiniteElementSpace*>(
test_fes)) )
966 x_gf.
MakeRef(const_cast<ParFiniteElementSpace*>(pfes),
967 const_cast<Vector&>(x),0);
971 auto dg_x_ptr = dg_x.
Write();
972 auto x_ptr = x.
Read();
973 MFEM_FORALL(i,local_size,
975 dg_x_ptr[i] = x_ptr[i];
977 const int shared_size = shared_x.
Size();
978 auto shared_x_ptr = shared_x.
Read();
979 MFEM_FORALL(i,shared_size,
981 dg_x_ptr[local_size+i] = shared_x_ptr[i];
984 if ((pform = dynamic_cast<ParBilinearForm*>(
a)) && (pform->keep_nbr_block))
986 mat->
Mult(dg_x, dg_y);
988 auto dg_y_ptr = dg_y.
Read();
990 MFEM_FORALL(i,local_size,
992 y_ptr[i] += dg_y_ptr[i];
1023 if ( (pfes = dynamic_cast<const ParFiniteElementSpace*>(
test_fes)) )
1027 x_gf.
MakeRef(const_cast<ParFiniteElementSpace*>(pfes),
1028 const_cast<Vector&>(x),0);
1032 auto dg_x_ptr = dg_x.
Write();
1033 auto x_ptr = x.
Read();
1034 MFEM_FORALL(i,local_size,
1036 dg_x_ptr[i] = x_ptr[i];
1038 const int shared_size = shared_x.
Size();
1039 auto shared_x_ptr = shared_x.
Read();
1040 MFEM_FORALL(i,shared_size,
1042 dg_x_ptr[local_size+i] = shared_x_ptr[i];
1045 if ((pb = dynamic_cast<ParBilinearForm*>(
a)) && (pb->keep_nbr_block))
1049 auto dg_y_ptr = dg_y.
Read();
1051 MFEM_FORALL(i,local_size,
1053 y_ptr[i] += dg_y_ptr[i];
1082 :
Operator(form->Height(), form->Width()),
a(form)
1112 trial_fes(form->TrialFESpace()),
1113 test_fes(form->TestFESpace()),
1114 elem_restrict_trial(NULL),
1115 elem_restrict_test(NULL)
1123 const int integratorCount = integrators.
Size();
1124 for (
int i = 0; i < integratorCount; ++i)
1128 MFEM_VERIFY(
a->
GetBBFI()->Size() == 0,
1129 "Partial assembly does not support AddBoundaryIntegrator yet.");
1131 "Partial assembly does not support AddTraceFaceIntegrator yet.");
1133 "Partial assembly does not support AddBdrTraceFaceIntegrator yet.");
1190 const double c)
const
1193 if (elem_restrict_x)
1195 elem_restrict_x->
Mult(x, localX);
1212 if (elem_restrict_y)
1230 const double c)
const
1233 const int iSz = integrators.
Size();
1240 for (
int i = 0; i < iSz; ++i)
1262 const double c)
const
1265 const int iSz = integrators.
Size();
1272 for (
int i = 0; i < iSz; ++i)
1291 const int iSz = integrators.
Size();
1297 if (H1elem_restrict_trial)
1310 for (
int i = 0; i < iSz; ++i)
1318 integrators[i]->AssembleDiagonalPA_ADAt(D,
localTest);
1323 if (H1elem_restrict_test)
1336 for (
int i = 0; i < iSz; ++i)
1340 integrators[i]->AssembleDiagonalPA_ADAt(
localTrial, diag);
1344 integrators[i]->AssembleDiagonalPA_ADAt(D, diag);
1366 const int integratorCount = integrators.
Size();
1367 for (
int i = 0; i < integratorCount; ++i)
1385 mfem_error(
"A real ElementRestriction is required in this setting!");
1388 auto tm = test_multiplicity.
ReadWrite();
1389 MFEM_FORALL(i, test_multiplicity.
Size(),
1391 tm[i] = 1.0 / tm[i];
1399 const int iSz = integrators.
Size();
1406 for (
int i = 0; i < iSz; ++i)
1424 mfem_error(
"In this setting you need a real ElementRestriction!");
1432 const int iSz = integrators.
Size();
1438 MFEM_VERIFY(x.
Size() == test_multiplicity.
Size(),
"Input vector of wrong size");
1440 auto tm = test_multiplicity.
Read();
1441 MFEM_FORALL(i, x.
Size(),
1449 for (
int i = 0; i < iSz; ++i)
1463 mfem_error(
"Trial ElementRestriction not defined");
int GetNFbyType(FaceType type) const
Returns the number of faces according to the requested type.
int Size() const
Return the logical size of the array.
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)...
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
void MultTransposeUnsigned(const Vector &x, Vector &y) const
Compute MultTranspose without applying signs based on DOF orientations.
void Mult(const Vector &x, Vector &y) const override=0
Extract the face degrees of freedom from x into y.
void ExchangeFaceNbrData()
void SetSize(int s)
Resize the vector to size s.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Pointer to an Operator of a specified type.
void FillJAndData(const Vector &ea_data, SparseMatrix &mat) const
int Size() const
Returns the size of the vector.
int GetNE() const
Returns number of elements.
void MultLeftInverse(const Vector &x, Vector &y) const
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
Geometry::Type GetFaceBaseGeometry(int i) const
Abstract parallel finite element space.
void SyncAliasMemory(const Vector &v) const
Update the alias memory location of the vector to match v.
bool UsesTensorBasis(const FiniteElementSpace &fes)
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
Memory< double > & GetMemoryData()
Memory< int > & GetMemoryI()
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...
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 ...
Memory< int > & GetMemoryJ()
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.
const Operator * GetElementRestriction(ElementDofOrdering e_ordering) const
Return an Operator that converts L-vectors to E-vectors.
DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims...dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
virtual void MakeRef(FiniteElementSpace *f, double *v)
Make the ParGridFunction reference external data on a new FiniteElementSpace.
const Operator * GetOutputRestrictionTranspose() const
Transpose of GetOutputRestriction, directly available in this form to facilitate matrix-free RAP-type...
void ExchangeFaceNbrData()
double f(const Vector &xvec)
PADiscreteLinearOperatorExtension(DiscreteLinearOperator *linop)
Native ordering as defined by the FiniteElement.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
void FillI(SparseMatrix &mat) const
Mesh * GetMesh() const
Returns the mesh.
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().
bool IsDGSpace() const
Return whether or not the space is discontinuous (L2)
void FormRectangularSystemOperator(const Array< int > &, const Array< int > &, OperatorHandle &A)
Setup OperatorHandle A to contain constrained linear operator.
void MultUnsigned(const Vector &x, Vector &y) const
Compute Mult without applying signs based on DOF orientations.
void Assemble()
Partial assembly of all internal integrators.
virtual const FaceRestriction * GetFaceRestriction(ElementDofOrdering e_ordering, FaceType, L2FaceValues mul=L2FaceValues::DoubleValued) const
Return an Operator that converts L-vectors to E-vectors on each face.
virtual const Operator * GetOutputRestrictionTranspose() const
Transpose of GetOutputRestriction, directly available in this form to facilitate matrix-free RAP-type...
virtual void AddMultTranspose(const Vector &x, Vector &y) const =0
Add the face degrees of freedom x to the element degrees of freedom y.
Operator that converts FiniteElementSpace L-vectors to E-vectors.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
void FillJAndData(const Vector &ea_data, SparseMatrix &mat) const
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.
Vector & Set(const double a, const Vector &x)
(*this) = a * x
int height
Dimension of the output / number of rows in the matrix.
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...
void AddMultTranspose(const Vector &x, Vector &y, const double c=1.0) const
y += c*A^T*x
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 MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
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 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...
virtual void AddFaceMatricesToElementMatrices(const Vector &fea_data, Vector &ea_data) const
This methods adds the DG face matrices to the element matrices.
Class for parallel grid function.
virtual const double * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
Operator that converts L2 FiniteElementSpace L-vectors to E-vectors.
int width
Dimension of the input / number of columns in the matrix.
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 FillSparseMatrix(const Vector &mat_ea, SparseMatrix &mat) const
Fill a Sparse Matrix with Element Matrices.
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
void AddMult(const Vector &x, Vector &y, const double c) const
y += c*A*x