13 #include "../general/forall.hpp"
22 MFEM_ABORT(
"the assembly level has already been set!");
37 mfem_error(
"Unknown assembly level for this form.");
79 MFEM_ABORT(
"internal MFEM error");
90 MFEM_VERIFY(!
fnfi.Size(),
"Interior faces terms not yet implemented!");
91 MFEM_VERIFY(!
bfnfi.Size(),
"Boundary face terms not yet implemented!");
103 for (
int i = 0; i <
fes->
GetNE(); i++)
109 for (
int k = 0; k <
dnfi.Size(); k++)
111 energy +=
dnfi[k]->GetElementEnergy(*fe, *T, el_x);
118 MFEM_ABORT(
"TODO: add energy contribution from interior face terms");
123 MFEM_ABORT(
"TODO: add energy contribution from boundary face terms");
131 MFEM_VERIFY(x.
Size() ==
Width(),
"invalid input Vector size");
159 MFEM_FORALL(i, N, Y[tdof[i]] = 0.0; );
175 for (
int i = 0; i <
fes->
GetNE(); i++)
181 for (
int k = 0; k <
dnfi.Size(); k++)
183 dnfi[k]->AssembleElementVector(*fe, *T, el_x, el_y);
209 for (
int k = 0; k <
fnfi.Size(); k++)
211 fnfi[k]->AssembleFaceVector(*fe1, *fe2, *tr, el_x, el_y);
227 for (
int k = 0; k <
bfnfi.Size(); k++)
235 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
236 "invalid boundary marker for boundary face integrator #"
237 << k <<
", counting from zero");
238 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
240 bdr_attr_marker[i] |= bdr_marker[i];
244 for (
int i = 0; i <
fes -> GetNBE(); i++)
247 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
260 for (
int k = 0; k <
bfnfi.Size(); k++)
265 bfnfi[k]->AssembleFaceVector(*fe1, *fe2, *tr, el_x, el_y);
299 const int skip_zeros = 0;
319 for (
int i = 0; i <
fes->
GetNE(); i++)
325 for (
int k = 0; k <
dnfi.Size(); k++)
327 dnfi[k]->AssembleElementGrad(*fe, *T, el_x, elmat);
354 for (
int k = 0; k <
fnfi.Size(); k++)
356 fnfi[k]->AssembleFaceGrad(*fe1, *fe2, *tr, el_x, elmat);
372 for (
int k = 0; k <
bfnfi.Size(); k++)
380 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
381 "invalid boundary marker for boundary face integrator #"
382 << k <<
", counting from zero");
383 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
385 bdr_attr_marker[i] |= bdr_marker[i];
389 for (
int i = 0; i <
fes -> GetNBE(); i++)
392 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
405 for (
int k = 0; k <
bfnfi.Size(); k++)
410 bfnfi[k]->AssembleFaceGrad(*fe1, *fe2, *tr, el_x, elmat);
466 for (
int i = 0; i <
dnfi.Size(); i++) {
delete dnfi[i]; }
467 for (
int i = 0; i <
fnfi.Size(); i++) {
delete fnfi[i]; }
468 for (
int i = 0; i <
bfnfi.Size(); i++) {
delete bfnfi[i]; }
474 fes(0), BlockGrad(NULL)
484 for (
int i=0; i<
Grads.NumRows(); ++i)
486 for (
int j=0; j<
Grads.NumCols(); ++j)
492 for (
int i = 0; i <
ess_tdofs.Size(); ++i)
505 for (
int i=0; i<
fes.
Size(); ++i)
529 P[
s] =
fes[
s]->GetProlongationMatrix();
551 fes(0), BlockGrad(NULL)
588 for (
int i=0; i<
fes.
Size(); ++i)
590 el_x_const[i] = el_x[i] =
new Vector();
595 for (
int i = 0; i <
fes[0]->GetNE(); ++i)
597 T =
fes[0]->GetElementTransformation(i);
600 fe[
s] =
fes[
s]->GetFE(i);
601 fes[
s]->GetElementVDofs(i, *vdofs[
s]);
605 for (
int k = 0; k <
dnfi.Size(); ++k)
607 energy +=
dnfi[k]->GetElementEnergy(fe, *T, el_x_const);
612 for (
int i = 0; i <
fes.
Size(); ++i)
620 MFEM_ABORT(
"TODO: add energy contribution from interior face terms");
625 MFEM_ABORT(
"TODO: add energy contribution from boundary face terms");
654 el_x_const[
s] = el_x[
s] =
new Vector();
662 for (
int i = 0; i <
fes[0]->GetNE(); ++i)
664 T =
fes[0]->GetElementTransformation(i);
667 fes[
s]->GetElementVDofs(i, *(vdofs[
s]));
668 fe[
s] =
fes[
s]->GetFE(i);
672 for (
int k = 0; k <
dnfi.Size(); ++k)
674 dnfi[k]->AssembleElementVector(fe, *T,
679 if (el_y[
s]->Size() == 0) {
continue; }
688 Mesh *mesh =
fes[0]->GetMesh();
702 fes[
s]->GetElementVDofs(tr->
Elem2No, *(vdofs2[s]));
704 vdofs[
s]->
Append(*(vdofs2[s]));
709 for (
int k = 0; k <
fnfi.Size(); ++k)
712 fnfi[k]->AssembleFaceVector(fe, fe2, *tr, el_x_const, el_y);
716 if (el_y[
s]->Size() == 0) {
continue; }
726 Mesh *mesh =
fes[0]->GetMesh();
732 for (
int k = 0; k <
bfnfi.Size(); ++k)
740 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
741 "invalid boundary marker for boundary face integrator #"
742 << k <<
", counting from zero");
743 for (
int i = 0; i < bdr_attr_marker.
Size(); ++i)
745 bdr_attr_marker[i] |= bdr_marker[i];
749 for (
int i = 0; i < mesh->
GetNBE(); ++i)
752 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
766 for (
int k = 0; k <
bfnfi.Size(); ++k)
771 bfnfi[k]->AssembleFaceVector(fe, fe2, *tr, el_x_const, el_y);
775 if (el_y[
s]->Size() == 0) {
continue; }
796 MFEM_VERIFY(bx.
Size() ==
Width(),
"invalid input BlockVector size");
838 const int skip_zeros = 0;
848 for (
int i=0; i<
fes.
Size(); ++i)
850 el_x_const[i] = el_x[i] =
new Vector();
853 for (
int j=0; j<
fes.
Size(); ++j)
859 for (
int i=0; i<
fes.
Size(); ++i)
861 for (
int j=0; j<
fes.
Size(); ++j)
863 if (
Grads(i,j) != NULL)
877 for (
int i = 0; i <
fes[0]->GetNE(); ++i)
879 T =
fes[0]->GetElementTransformation(i);
882 fe[
s] =
fes[
s]->GetFE(i);
883 fes[
s]->GetElementVDofs(i, *vdofs[
s]);
887 for (
int k = 0; k <
dnfi.Size(); ++k)
889 dnfi[k]->AssembleElementGrad(fe, *T, el_x_const, elmats);
891 for (
int j=0; j<
fes.
Size(); ++j)
893 for (
int l=0; l<
fes.
Size(); ++l)
895 if (elmats(j,l)->Height() == 0) {
continue; }
896 Grads(j,l)->AddSubMatrix(*vdofs[j], *vdofs[l],
897 *elmats(j,l), skip_zeros);
907 Mesh *mesh =
fes[0]->GetMesh();
920 vdofs[
s]->
Append(*(vdofs2[s]));
925 for (
int k = 0; k <
fnfi.Size(); ++k)
927 fnfi[k]->AssembleFaceGrad(fe, fe2, *tr, el_x_const, elmats);
928 for (
int j=0; j<
fes.
Size(); ++j)
930 for (
int l=0; l<
fes.
Size(); ++l)
932 if (elmats(j,l)->Height() == 0) {
continue; }
933 Grads(j,l)->AddSubMatrix(*vdofs[j], *vdofs[l],
934 *elmats(j,l), skip_zeros);
944 Mesh *mesh =
fes[0]->GetMesh();
950 for (
int k = 0; k <
bfnfi.Size(); ++k)
958 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
959 "invalid boundary marker for boundary face integrator #"
960 << k <<
", counting from zero");
961 for (
int i = 0; i < bdr_attr_marker.
Size(); ++i)
963 bdr_attr_marker[i] |= bdr_marker[i];
967 for (
int i = 0; i < mesh->
GetNBE(); ++i)
970 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
984 for (
int k = 0; k <
bfnfi.Size(); ++k)
988 bfnfi[k]->AssembleFaceGrad(fe, fe2, *tr, el_x_const, elmats);
989 for (
int l=0; l<
fes.
Size(); ++l)
991 for (
int j=0; j<
fes.
Size(); ++j)
993 if (elmats(j,l)->Height() == 0) {
continue; }
994 Grads(j,l)->AddSubMatrix(*vdofs[j], *vdofs[l],
995 *elmats(j,l), skip_zeros);
1003 if (!
Grads(0,0)->Finalized())
1005 for (
int i=0; i<
fes.
Size(); ++i)
1007 for (
int j=0; j<
fes.
Size(); ++j)
1009 Grads(i,j)->Finalize(skip_zeros);
1014 for (
int i=0; i<
fes.
Size(); ++i)
1016 for (
int j=0; j<
fes.
Size(); ++j)
1037 for (
int s1 = 0; s1 <
fes.
Size(); ++s1)
1039 for (
int s2 = 0; s2 <
fes.
Size(); ++s2)
1043 mGrads(s1, s2) =
cGrads(s1, s2);
1050 for (
int i = 0; i <
ess_tdofs[
s]->Size(); ++i)
1052 for (
int j = 0; j <
fes.
Size(); ++j)
1062 mGrads(j, s)->EliminateCol((*
ess_tdofs[s])[i]);
1070 for (
int i = 0; i <
fes.
Size(); ++i)
1072 for (
int j = 0; j <
fes.
Size(); ++j)
1083 for (
int i=0; i<
fes.
Size(); ++i)
1085 for (
int j=0; j<
fes.
Size(); ++j)
1093 for (
int i = 0; i <
dnfi.Size(); ++i)
1098 for (
int i = 0; i <
fnfi.Size(); ++i)
1103 for (
int i = 0; i <
bfnfi.Size(); ++i)
Abstract class for all finite elements.
int Size() const
Return the logical size of the array.
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
AssemblyLevel
Enumeration defining the assembly level for bilinear and nonlinear form classes derived from Operator...
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
A class to handle Vectors in a block fashion.
HypreParMatrix * RAP(const HypreParMatrix *A, const HypreParMatrix *P)
Returns the matrix P^t * A * P.
virtual void Finalize(int skip_zeros=1)
Finalize the matrix initialization, switching the storage format from LIL to CSR. ...
void SetSize(int s)
Resize the vector to size s.
int GetNBE() const
Returns number of boundary elements.
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
Data type dense matrix using column-major storage.
int Size() const
Returns the size of the vector.
void SyncToBlocks() const
Synchronize the memory location flags (i.e. the memory validity flags) of the big/monolithic block-ve...
void Update(double *data, const Array< int > &bOffsets)
Update method.
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
Get a list of essential true dofs, ess_tdof_list, corresponding to the boundary attributes marked in ...
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
Abstract parallel finite element space.
FaceElementTransformations * GetInteriorFaceTransformations(int FaceNo)
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
static void MarkerToList(const Array< int > &marker, Array< int > &list)
Convert a Boolean marker array to a list containing all marked indices.
void BooleanMultTranspose(int alpha, const int *x, int beta, int *y)
The "Boolean" analog of y = alpha * A^T * x + beta * y, where elements in the sparsity pattern of the...
virtual int GetTrueVSize() const
Return the number of local vector true dofs.
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
int GetNE() const
Returns number of elements in the mesh.
double f(const Vector &xvec)
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Mesh * GetMesh() const
Returns the mesh.
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
HypreParMatrix * Dof_TrueDof_Matrix() const
The true dof-to-dof interpolation matrix.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
virtual const Operator * GetProlongationMatrix() const
The returned Operator is owned by the FiniteElementSpace.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Set the diagonal value to one.
FaceElementTransformations * GetBdrFaceTransformations(int BdrElemNo)
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add elements of the elemvect Vector to the entries listed in dofs. Negative dof values cause the -dof...
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
Dynamic 2D array using row-major layout.
bool Finalized() const
Returns whether or not CSR format has been finalized.
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void EliminateRowCol(int rc, const double sol, Vector &rhs, DiagonalPolicy dpolicy=DIAG_ONE)
Eliminate row rc and column rc and modify the rhs using sol.
void PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged...
int height
Dimension of the output / number of rows in the matrix.
void ConvertToConformingVDofs(const Array< int > &dofs, Array< int > &cdofs)
For a partially conforming FE space, convert a marker array (nonzero entries are true) on the partial...
virtual double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
void FormSystemOperator(const Array< int > &ess_tdof_list, Operator *&A)
Return in A a parallel (on truedofs) version of this square operator.
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...
void SyncFromBlocks() const
Synchronize the memory location flags (i.e. the memory validity flags) of the big/monolithic block-ve...
static void ListToMarker(const Array< int > &list, int marker_size, Array< int > &marker, int mark_val=-1)
Convert an array of indices (list) to a Boolean marker array where all indices in the list are marked...
A class to handle Block systems in a matrix-free implementation.
int width
Dimension of the input / number of columns in the matrix.
void SetBlock(int iRow, int iCol, Operator *op, double c=1.0)
Add a block op in the block-entry (iblock, jblock).
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
Vector & GetBlock(int i)
Get the i-th vector in the block.