15 #include "../general/forall.hpp"
19 #include "ceed/util.hpp"
43 trialFes(
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 trialFes(
a->FESpace()),
245 testFes(
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(form->FESpace()->IsDGSpace())
516 const int integratorCount = integrators.
Size();
517 for (
int i = 0; i < integratorCount; ++i)
526 MFEM_VERIFY(
a->
GetBBFI()->Size() == 0,
527 "Element assembly does not support AddBoundaryIntegrator yet.");
530 const int intFaceIntegratorCount = intFaceIntegrators.Size();
531 if (intFaceIntegratorCount>0)
537 for (
int i = 0; i < intFaceIntegratorCount; ++i)
539 intFaceIntegrators[i]->AssembleEAInteriorFaces(*
a->
FESpace(),
546 const int boundFaceIntegratorCount = bdrFaceIntegrators.
Size();
547 if (boundFaceIntegratorCount>0)
553 for (
int i = 0; i < boundFaceIntegratorCount; ++i)
573 const bool useRestrict = !DeviceCanUseCeed() &&
elem_restrict;
589 MFEM_FORALL(glob_j,
ne*NDOFS,
591 const int e = glob_j/NDOFS;
592 const int j = glob_j%NDOFS;
594 for (
int i = 0; i < NDOFS; i++)
596 res += A(i, j, e)*X(i, e);
608 const int iFISz = intFaceIntegrators.
Size();
623 MFEM_FORALL(glob_j,
nf_int*NDOFS,
625 const int f = glob_j/NDOFS;
626 const int j = glob_j%NDOFS;
628 for (
int i = 0; i < NDOFS; i++)
630 res += A_int(i, j, 0, f)*X(i, 0, f);
634 for (
int i = 0; i < NDOFS; i++)
636 res += A_int(i, j, 1, f)*X(i, 1, f);
642 MFEM_FORALL(glob_j,
nf_int*NDOFS,
644 const int f = glob_j/NDOFS;
645 const int j = glob_j%NDOFS;
647 for (
int i = 0; i < NDOFS; i++)
649 res += A_ext(i, j, 0, f)*X(i, 0, f);
653 for (
int i = 0; i < NDOFS; i++)
655 res += A_ext(i, j, 1, f)*X(i, 1, f);
666 const int bFISz = bdrFaceIntegrators.
Size();
679 MFEM_FORALL(glob_j,
nf_bdr*NDOFS,
681 const int f = glob_j/NDOFS;
682 const int j = glob_j%NDOFS;
684 for (
int i = 0; i < NDOFS; i++)
686 res += A(i, j, f)*X(i, f);
699 const bool useRestrict = DeviceCanUseCeed() || !
elem_restrict;
715 MFEM_FORALL(glob_j,
ne*NDOFS,
717 const int e = glob_j/NDOFS;
718 const int j = glob_j%NDOFS;
720 for (
int i = 0; i < NDOFS; i++)
722 res += A(j, i, e)*X(i, e);
734 const int iFISz = intFaceIntegrators.
Size();
749 MFEM_FORALL(glob_j,
nf_int*NDOFS,
751 const int f = glob_j/NDOFS;
752 const int j = glob_j%NDOFS;
754 for (
int i = 0; i < NDOFS; i++)
756 res += A_int(j, i, 0, f)*X(i, 0, f);
760 for (
int i = 0; i < NDOFS; i++)
762 res += A_int(j, i, 1, f)*X(i, 1, f);
768 MFEM_FORALL(glob_j,
nf_int*NDOFS,
770 const int f = glob_j/NDOFS;
771 const int j = glob_j%NDOFS;
773 for (
int i = 0; i < NDOFS; i++)
775 res += A_ext(j, i, 0, f)*X(i, 0, f);
779 for (
int i = 0; i < NDOFS; i++)
781 res += A_ext(j, i, 1, f)*X(i, 1, f);
792 const int bFISz = bdrFaceIntegrators.
Size();
805 MFEM_FORALL(glob_j,
nf_bdr*NDOFS,
807 const int f = glob_j/NDOFS;
808 const int j = glob_j%NDOFS;
810 for (
int i = 0; i < NDOFS; i++)
812 res += A(j, i, f)*X(i, f);
843 bool keep_nbr_block =
false;
857 keep_nbr_block =
true;
876 for (
int i = height; i > 0; i--)
903 if (restF) { restF->
FillI(*mat, keep_nbr_block); }
907 for (
int i = 0; i <
height; i++)
909 const int nnz = h_I[i];
924 for (
int i = height; i > 0; i--)
944 if ( (pfes = dynamic_cast<const ParFiniteElementSpace*>(
testFes)) )
948 x_gf.
MakeRef(const_cast<ParFiniteElementSpace*>(pfes),
949 const_cast<Vector&>(x),0);
953 auto dg_x_ptr = dg_x.
Write();
954 auto x_ptr = x.
Read();
955 MFEM_FORALL(i,local_size,
957 dg_x_ptr[i] = x_ptr[i];
959 const int shared_size = shared_x.
Size();
960 auto shared_x_ptr = shared_x.
Read();
961 MFEM_FORALL(i,shared_size,
963 dg_x_ptr[local_size+i] = shared_x_ptr[i];
966 if ((pform = dynamic_cast<ParBilinearForm*>(
a)) && (pform->keep_nbr_block))
968 mat->
Mult(dg_x, dg_y);
970 auto dg_y_ptr = dg_y.
Read();
972 MFEM_FORALL(i,local_size,
974 y_ptr[i] += dg_y_ptr[i];
1005 if ( (pfes = dynamic_cast<const ParFiniteElementSpace*>(
testFes)) )
1009 x_gf.
MakeRef(const_cast<ParFiniteElementSpace*>(pfes),
1010 const_cast<Vector&>(x),0);
1014 auto dg_x_ptr = dg_x.
Write();
1015 auto x_ptr = x.
Read();
1016 MFEM_FORALL(i,local_size,
1018 dg_x_ptr[i] = x_ptr[i];
1020 const int shared_size = shared_x.
Size();
1021 auto shared_x_ptr = shared_x.
Read();
1022 MFEM_FORALL(i,shared_size,
1024 dg_x_ptr[local_size+i] = shared_x_ptr[i];
1027 if ((pb = dynamic_cast<ParBilinearForm*>(
a)) && (pb->keep_nbr_block))
1031 auto dg_y_ptr = dg_y.
Read();
1033 MFEM_FORALL(i,local_size,
1035 y_ptr[i] += dg_y_ptr[i];
1064 :
Operator(form->Height(), form->Width()),
a(form)
1094 trialFes(form->TrialFESpace()),
1095 testFes(form->TestFESpace()),
1096 elem_restrict_trial(NULL),
1097 elem_restrict_test(NULL)
1105 const int integratorCount = integrators.
Size();
1106 for (
int i = 0; i < integratorCount; ++i)
1110 MFEM_VERIFY(
a->
GetBBFI()->Size() == 0,
1111 "Partial assembly does not support AddBoundaryIntegrator yet.");
1113 "Partial assembly does not support AddTraceFaceIntegrator yet.");
1115 "Partial assembly does not support AddBdrTraceFaceIntegrator yet.");
1172 const double c)
const
1175 if (elem_restrict_x)
1177 elem_restrict_x->
Mult(x, localX);
1194 if (elem_restrict_y)
1212 const double c)
const
1215 const int iSz = integrators.
Size();
1222 for (
int i = 0; i < iSz; ++i)
1244 const double c)
const
1247 const int iSz = integrators.
Size();
1254 for (
int i = 0; i < iSz; ++i)
1273 const int iSz = integrators.
Size();
1279 if (H1elem_restrict_trial)
1292 for (
int i = 0; i < iSz; ++i)
1300 integrators[i]->AssembleDiagonalPA_ADAt(D,
localTest);
1305 if (H1elem_restrict_test)
1318 for (
int i = 0; i < iSz; ++i)
1322 integrators[i]->AssembleDiagonalPA_ADAt(
localTrial, diag);
1326 integrators[i]->AssembleDiagonalPA_ADAt(D, diag);
1348 const int integratorCount = integrators.
Size();
1349 for (
int i = 0; i < integratorCount; ++i)
1367 mfem_error(
"A real ElementRestriction is required in this setting!");
1370 auto tm = test_multiplicity.
ReadWrite();
1371 MFEM_FORALL(i, test_multiplicity.
Size(),
1373 tm[i] = 1.0 / tm[i];
1381 const int iSz = integrators.
Size();
1388 for (
int i = 0; i < iSz; ++i)
1406 mfem_error(
"In this setting you need a real ElementRestriction!");
1414 const int iSz = integrators.
Size();
1420 MFEM_VERIFY(x.
Size() == test_multiplicity.
Size(),
"Input vector of wrong size");
1422 auto tm = test_multiplicity.
Read();
1423 MFEM_FORALL(i, x.
Size(),
1431 for (
int i = 0; i < iSz; ++i)
1445 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()
virtual void FillJAndData(const Vector &ea_data, SparseMatrix &mat, const bool keep_nbr_block=false) const
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.
void AddFaceMatricesToElementMatrices(Vector &fea_data, Vector &ea_data) const
This methods adds the DG face matrices to the element matrices.
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 on L2 FiniteElementSpaces.
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
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
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