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!");
104 for (
int i = 0; i <
fes->
GetNE(); i++)
111 for (
int k = 0; k <
dnfi.Size(); k++)
113 energy +=
dnfi[k]->GetElementEnergy(*fe, *T, el_x);
120 MFEM_ABORT(
"TODO: add energy contribution from interior face terms");
125 MFEM_ABORT(
"TODO: add energy contribution from boundary face terms");
133 MFEM_VERIFY(x.
Size() ==
Width(),
"invalid input Vector size");
161 MFEM_FORALL(i, N, Y[tdof[i]] = 0.0; );
178 for (
int i = 0; i <
fes->
GetNE(); i++)
185 for (
int k = 0; k <
dnfi.Size(); k++)
187 dnfi[k]->AssembleElementVector(*fe, *T, el_x, el_y);
214 for (
int k = 0; k <
fnfi.Size(); k++)
216 fnfi[k]->AssembleFaceVector(*fe1, *fe2, *tr, el_x, el_y);
232 for (
int k = 0; k <
bfnfi.Size(); k++)
240 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
241 "invalid boundary marker for boundary face integrator #"
242 << k <<
", counting from zero");
243 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
245 bdr_attr_marker[i] |= bdr_marker[i];
249 for (
int i = 0; i <
fes -> GetNBE(); i++)
252 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
265 for (
int k = 0; k <
bfnfi.Size(); k++)
270 bfnfi[k]->AssembleFaceVector(*fe1, *fe2, *tr, el_x, el_y);
304 const int skip_zeros = 0;
325 for (
int i = 0; i <
fes->
GetNE(); i++)
332 for (
int k = 0; k <
dnfi.Size(); k++)
334 dnfi[k]->AssembleElementGrad(*fe, *T, el_x, elmat);
362 for (
int k = 0; k <
fnfi.Size(); k++)
364 fnfi[k]->AssembleFaceGrad(*fe1, *fe2, *tr, el_x, elmat);
380 for (
int k = 0; k <
bfnfi.Size(); k++)
388 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
389 "invalid boundary marker for boundary face integrator #"
390 << k <<
", counting from zero");
391 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
393 bdr_attr_marker[i] |= bdr_marker[i];
397 for (
int i = 0; i <
fes -> GetNBE(); i++)
400 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
413 for (
int k = 0; k <
bfnfi.Size(); k++)
418 bfnfi[k]->AssembleFaceGrad(*fe1, *fe2, *tr, el_x, elmat);
474 for (
int i = 0; i <
dnfi.Size(); i++) {
delete dnfi[i]; }
475 for (
int i = 0; i <
fnfi.Size(); i++) {
delete fnfi[i]; }
476 for (
int i = 0; i <
bfnfi.Size(); i++) {
delete bfnfi[i]; }
482 fes(0), BlockGrad(NULL)
492 for (
int i=0; i<
Grads.NumRows(); ++i)
494 for (
int j=0; j<
Grads.NumCols(); ++j)
500 for (
int i = 0; i <
ess_tdofs.Size(); ++i)
513 for (
int i=0; i<
fes.
Size(); ++i)
537 P[
s] =
fes[
s]->GetProlongationMatrix();
559 fes(0), BlockGrad(NULL)
597 for (
int i=0; i<
fes.
Size(); ++i)
599 el_x_const[i] = el_x[i] =
new Vector();
604 for (
int i = 0; i <
fes[0]->GetNE(); ++i)
606 T =
fes[0]->GetElementTransformation(i);
609 fe[
s] =
fes[
s]->GetFE(i);
610 doftrans =
fes[
s]->GetElementVDofs(i, *vdofs[
s]);
615 for (
int k = 0; k <
dnfi.Size(); ++k)
617 energy +=
dnfi[k]->GetElementEnergy(fe, *T, el_x_const);
622 for (
int i = 0; i <
fes.
Size(); ++i)
630 MFEM_ABORT(
"TODO: add energy contribution from interior face terms");
635 MFEM_ABORT(
"TODO: add energy contribution from boundary face terms");
665 el_x_const[
s] = el_x[
s] =
new Vector();
673 for (
int i = 0; i <
fes[0]->GetNE(); ++i)
675 T =
fes[0]->GetElementTransformation(i);
678 doftrans[
s] =
fes[
s]->GetElementVDofs(i, *(vdofs[
s]));
679 fe[
s] =
fes[
s]->GetFE(i);
681 if (doftrans[s]) {doftrans[
s]->InvTransformPrimal(*el_x[s]); }
684 for (
int k = 0; k <
dnfi.Size(); ++k)
686 dnfi[k]->AssembleElementVector(fe, *T,
691 if (el_y[
s]->Size() == 0) {
continue; }
692 if (doftrans[
s]) {doftrans[
s]->TransformDual(*el_y[s]); }
701 Mesh *mesh =
fes[0]->GetMesh();
715 fes[
s]->GetElementVDofs(tr->
Elem2No, *(vdofs2[s]));
717 vdofs[
s]->
Append(*(vdofs2[s]));
722 for (
int k = 0; k <
fnfi.Size(); ++k)
725 fnfi[k]->AssembleFaceVector(fe, fe2, *tr, el_x_const, el_y);
729 if (el_y[
s]->Size() == 0) {
continue; }
739 Mesh *mesh =
fes[0]->GetMesh();
745 for (
int k = 0; k <
bfnfi.Size(); ++k)
753 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
754 "invalid boundary marker for boundary face integrator #"
755 << k <<
", counting from zero");
756 for (
int i = 0; i < bdr_attr_marker.
Size(); ++i)
758 bdr_attr_marker[i] |= bdr_marker[i];
762 for (
int i = 0; i < mesh->
GetNBE(); ++i)
765 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
779 for (
int k = 0; k <
bfnfi.Size(); ++k)
784 bfnfi[k]->AssembleFaceVector(fe, fe2, *tr, el_x_const, el_y);
788 if (el_y[
s]->Size() == 0) {
continue; }
809 MFEM_VERIFY(bx.
Size() ==
Width(),
"invalid input BlockVector size");
851 const int skip_zeros = 0;
862 for (
int i=0; i<
fes.
Size(); ++i)
864 el_x_const[i] = el_x[i] =
new Vector();
867 for (
int j=0; j<
fes.
Size(); ++j)
873 for (
int i=0; i<
fes.
Size(); ++i)
875 for (
int j=0; j<
fes.
Size(); ++j)
877 if (
Grads(i,j) != NULL)
891 for (
int i = 0; i <
fes[0]->GetNE(); ++i)
893 T =
fes[0]->GetElementTransformation(i);
896 fe[
s] =
fes[
s]->GetFE(i);
897 doftrans[
s] =
fes[
s]->GetElementVDofs(i, *vdofs[
s]);
899 if (doftrans[s]) {doftrans[
s]->InvTransformPrimal(*el_x[s]); }
902 for (
int k = 0; k <
dnfi.Size(); ++k)
904 dnfi[k]->AssembleElementGrad(fe, *T, el_x_const, elmats);
906 for (
int j=0; j<
fes.
Size(); ++j)
908 for (
int l=0; l<
fes.
Size(); ++l)
910 if (elmats(j,l)->Height() == 0) {
continue; }
911 if (doftrans[j] || doftrans[l])
915 Grads(j,l)->AddSubMatrix(*vdofs[j], *vdofs[l],
916 *elmats(j,l), skip_zeros);
926 Mesh *mesh =
fes[0]->GetMesh();
939 vdofs[
s]->
Append(*(vdofs2[s]));
944 for (
int k = 0; k <
fnfi.Size(); ++k)
946 fnfi[k]->AssembleFaceGrad(fe, fe2, *tr, el_x_const, elmats);
947 for (
int j=0; j<
fes.
Size(); ++j)
949 for (
int l=0; l<
fes.
Size(); ++l)
951 if (elmats(j,l)->Height() == 0) {
continue; }
952 Grads(j,l)->AddSubMatrix(*vdofs[j], *vdofs[l],
953 *elmats(j,l), skip_zeros);
963 Mesh *mesh =
fes[0]->GetMesh();
969 for (
int k = 0; k <
bfnfi.Size(); ++k)
977 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
978 "invalid boundary marker for boundary face integrator #"
979 << k <<
", counting from zero");
980 for (
int i = 0; i < bdr_attr_marker.
Size(); ++i)
982 bdr_attr_marker[i] |= bdr_marker[i];
986 for (
int i = 0; i < mesh->
GetNBE(); ++i)
989 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1003 for (
int k = 0; k <
bfnfi.Size(); ++k)
1007 bfnfi[k]->AssembleFaceGrad(fe, fe2, *tr, el_x_const, elmats);
1008 for (
int l=0; l<
fes.
Size(); ++l)
1010 for (
int j=0; j<
fes.
Size(); ++j)
1012 if (elmats(j,l)->Height() == 0) {
continue; }
1013 Grads(j,l)->AddSubMatrix(*vdofs[j], *vdofs[l],
1014 *elmats(j,l), skip_zeros);
1022 if (!
Grads(0,0)->Finalized())
1024 for (
int i=0; i<
fes.
Size(); ++i)
1026 for (
int j=0; j<
fes.
Size(); ++j)
1028 Grads(i,j)->Finalize(skip_zeros);
1033 for (
int i=0; i<
fes.
Size(); ++i)
1035 for (
int j=0; j<
fes.
Size(); ++j)
1056 for (
int s1 = 0; s1 <
fes.
Size(); ++s1)
1058 for (
int s2 = 0; s2 <
fes.
Size(); ++s2)
1062 mGrads(s1, s2) =
cGrads(s1, s2);
1069 for (
int i = 0; i <
ess_tdofs[
s]->Size(); ++i)
1071 for (
int j = 0; j <
fes.
Size(); ++j)
1081 mGrads(j, s)->EliminateCol((*
ess_tdofs[s])[i]);
1089 for (
int i = 0; i <
fes.
Size(); ++i)
1091 for (
int j = 0; j <
fes.
Size(); ++j)
1102 for (
int i=0; i<
fes.
Size(); ++i)
1104 for (
int j=0; j<
fes.
Size(); ++j)
1112 for (
int i = 0; i <
dnfi.Size(); ++i)
1117 for (
int i = 0; i <
fnfi.Size(); ++i)
1122 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.
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.
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
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...
void TransformDual(const DofTransformation *ran_dof_trans, const DofTransformation *dom_dof_trans, DenseMatrix &elmat)
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.