27 mfem_error(
"ParametricBNLFormIntegrator::GetElementEnergy"
28 " is not overloaded!");
42 mfem_error(
"ParametricBNLFormIntegrator::AssembleFaceGrad"
43 " is not overloaded!");
54 mfem_error(
"ParametricBNLFormIntegrator::AssembleElementGrad"
55 " is not overloaded!");
66 mfem_error(
"ParametricBNLFormIntegrator::AssembleElementVector"
67 " is not overloaded!");
80 mfem_error(
"ParametricBNLFormIntegrator::AssembleFaceVector"
81 " is not overloaded!");
94 mfem_error(
"ParametricBNLFormIntegrator::AssemblePrmElementVector"
95 " is not overloaded!");
109 mfem_error(
"ParametricBNLFormIntegrator::AssemblePrmFaceVector"
110 " is not overloaded!");
125 fes(0),paramfes(0), BlockGrad(nullptr)
135 for (
int i=0; i<
Grads.NumRows(); ++i)
137 for (
int j=0; j<
Grads.NumCols(); ++j)
143 for (
int i = 0; i <
ess_tdofs.Size(); ++i)
161 for (
int i=0; i<
fes.
Size(); ++i)
200 P[
s] =
fes[
s]->GetProlongationMatrix();
273 for (
int i=0; i<
fes.
Size(); ++i)
275 el_x_const[i] = el_x[i] =
new Vector();
281 prmel_x_const[i] = prmel_x[i] =
new Vector();
288 for (
int i = 0; i <
fes[0]->GetNE(); ++i)
290 T =
fes[0]->GetElementTransformation(i);
293 fe[
s] =
fes[
s]->GetFE(i);
294 fes[
s]->GetElementVDofs(i, *vdofs[
s]);
301 paramfes[
s]->GetElementVDofs(i, *prmvdofs[
s]);
307 for (
int k = 0; k <
dnfi.Size(); ++k)
309 energy +=
dnfi[k]->GetElementEnergy(fe, prmfe, *T, el_x_const, prmel_x_const);
315 for (
int i = 0; i <
fes.
Size(); ++i)
329 MFEM_ABORT(
"TODO: add energy contribution from interior face terms");
334 MFEM_ABORT(
"TODO: add energy contribution from boundary face terms");
461 el_x_const[
s] = el_x[
s] =
new Vector();
465 ael_x_const[
s] = ael_x[
s] =
new Vector();
470 prmel_x_const[
s] = prmel_x[
s] =
new Vector();
478 for (
int i = 0; i <
fes[0]->GetNE(); ++i)
480 T =
fes[0]->GetElementTransformation(i);
483 fes[
s]->GetElementVDofs(i, *(vdofs[
s]));
484 fe[
s] =
fes[
s]->GetFE(i);
491 paramfes[
s]->GetElementVDofs(i, *(prmvdofs[
s]));
497 for (
int k = 0; k <
dnfi.Size(); ++k)
499 dnfi[k]->AssemblePrmElementVector(fe,prmfe, *T,
500 el_x_const, ael_x_const, prmel_x_const,
505 if (prmel_y[
s]->Size() == 0) {
continue; }
506 dy.GetBlock(
s).AddElementVector(*(prmvdofs[
s]), *prmel_y[s]);
514 Mesh *mesh =
fes[0]->GetMesh();
528 fes[
s]->GetElementVDofs(tr->
Elem2No, *(vdofs2[s]));
530 vdofs[
s]->
Append(*(vdofs2[s]));
544 prmvdofs[
s]->
Append(*(prmvdofs2[s]));
549 for (
int k = 0; k <
fnfi.Size(); ++k)
552 fnfi[k]->AssemblePrmFaceVector(fe, fe2, prmfe, prmfe2, *tr,
553 el_x_const, ael_x_const, prmel_x_const, prmel_y);
557 if (prmel_y[
s]->Size() == 0) {
continue; }
558 dy.GetBlock(
s).AddElementVector(*(prmvdofs[
s]), *prmel_y[s]);
567 Mesh *mesh =
fes[0]->GetMesh();
573 for (
int k = 0; k <
bfnfi.Size(); ++k)
581 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
582 "invalid boundary marker for boundary face integrator #"
583 << k <<
", counting from zero");
584 for (
int i = 0; i < bdr_attr_marker.
Size(); ++i)
586 bdr_attr_marker[i] |= bdr_marker[i];
590 for (
int i = 0; i < mesh->
GetNBE(); ++i)
593 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
618 for (
int k = 0; k <
bfnfi.Size(); ++k)
623 bfnfi[k]->AssemblePrmFaceVector(fe, fe2, prmfe, prmfe2, *tr,
624 el_x_const, ael_x_const, prmel_x_const, prmel_y);
628 if (prmel_y[
s]->Size() == 0) {
continue; }
629 dy.GetBlock(
s).AddElementVector(*(prmvdofs[
s]), *prmel_y[s]);
679 el_x_const[
s] = el_x[
s] =
new Vector();
687 prmel_x_const[
s] = prmel_x[
s] =
new Vector();
694 for (
int i = 0; i <
fes[0]->GetNE(); ++i)
696 T =
fes[0]->GetElementTransformation(i);
699 fes[
s]->GetElementVDofs(i, *(vdofs[
s]));
700 fe[
s] =
fes[
s]->GetFE(i);
706 paramfes[
s]->GetElementVDofs(i, *(prmvdofs[
s]));
712 for (
int k = 0; k <
dnfi.Size(); ++k)
714 dnfi[k]->AssembleElementVector(fe,prmfe, *T,
715 el_x_const, prmel_x_const, el_y);
719 if (el_y[
s]->Size() == 0) {
continue; }
720 by.GetBlock(
s).AddElementVector(*(vdofs[
s]), *el_y[s]);
728 Mesh *mesh =
fes[0]->GetMesh();
742 fes[
s]->GetElementVDofs(tr->
Elem2No, *(vdofs2[s]));
744 vdofs[
s]->
Append(*(vdofs2[s]));
757 prmvdofs[
s]->
Append(*(prmvdofs2[s]));
762 for (
int k = 0; k <
fnfi.Size(); ++k)
765 fnfi[k]->AssembleFaceVector(fe, fe2, prmfe, prmfe2, *tr, el_x_const,
766 prmel_x_const, el_y);
770 if (el_y[
s]->Size() == 0) {
continue; }
771 by.GetBlock(
s).AddElementVector(*(vdofs[
s]), *el_y[s]);
780 Mesh *mesh =
fes[0]->GetMesh();
786 for (
int k = 0; k <
bfnfi.Size(); ++k)
794 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
795 "invalid boundary marker for boundary face integrator #"
796 << k <<
", counting from zero");
797 for (
int i = 0; i < bdr_attr_marker.
Size(); ++i)
799 bdr_attr_marker[i] |= bdr_marker[i];
803 for (
int i = 0; i < mesh->
GetNBE(); ++i)
806 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
830 for (
int k = 0; k <
bfnfi.Size(); ++k)
835 bfnfi[k]->AssembleFaceVector(fe, fe2, prmfe, prmfe2, *tr, el_x_const,
836 prmel_x_const, el_y);
840 if (el_y[
s]->Size() == 0) {
continue; }
841 by.GetBlock(
s).AddElementVector(*(vdofs[
s]), *el_y[s]);
867 MFEM_VERIFY(bx.
Size() ==
Width(),
"invalid input BlockVector size");
884 MFEM_VERIFY(bx.
Size() ==
paramwidth,
"invalid input BlockVector size");
959 const int skip_zeros = 0;
977 for (
int i=0; i<
fes.
Size(); ++i)
979 el_x_const[i] = el_x[i] =
new Vector();
982 for (
int j=0; j<
fes.
Size(); ++j)
988 for (
int i=0; i<
fes.
Size(); ++i)
990 for (
int j=0; j<
fes.
Size(); ++j)
992 if (
Grads(i,j) != NULL)
1006 prmel_x_const[i] = prmel_x[i] =
new Vector();
1013 for (
int i = 0; i <
fes[0]->GetNE(); ++i)
1015 T =
fes[0]->GetElementTransformation(i);
1019 fe[
s] =
fes[
s]->GetFE(i);
1020 fes[
s]->GetElementVDofs(i, *vdofs[
s]);
1027 paramfes[
s]->GetElementVDofs(i, *prmvdofs[
s]);
1031 for (
int k = 0; k <
dnfi.Size(); ++k)
1033 dnfi[k]->AssembleElementGrad(fe,prmfe,*T, el_x_const, prmel_x_const, elmats);
1035 for (
int j=0; j<
fes.
Size(); ++j)
1037 for (
int l=0; l<
fes.
Size(); ++l)
1039 if (elmats(j,l)->Height() == 0) {
continue; }
1040 Grads(j,l)->AddSubMatrix(*vdofs[j], *vdofs[l],
1041 *elmats(j,l), skip_zeros);
1051 Mesh *mesh =
fes[0]->GetMesh();
1064 vdofs[
s]->
Append(*(vdofs2[s]));
1076 prmvdofs[
s]->
Append(*(prmvdofs2[s]));
1081 for (
int k = 0; k <
fnfi.Size(); ++k)
1083 fnfi[k]->AssembleFaceGrad(fe, fe2, prmfe, prmfe2, *tr, el_x_const,
1084 prmel_x_const, elmats);
1085 for (
int j=0; j<
fes.
Size(); ++j)
1087 for (
int l=0; l<
fes.
Size(); ++l)
1089 if (elmats(j,l)->Height() == 0) {
continue; }
1090 Grads(j,l)->AddSubMatrix(*vdofs[j], *vdofs[l],
1091 *elmats(j,l), skip_zeros);
1101 Mesh *mesh =
fes[0]->GetMesh();
1106 bdr_attr_marker = 0;
1107 for (
int k = 0; k <
bfnfi.Size(); ++k)
1111 bdr_attr_marker = 1;
1115 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1116 "invalid boundary marker for boundary face integrator #"
1117 << k <<
", counting from zero");
1118 for (
int i = 0; i < bdr_attr_marker.
Size(); ++i)
1120 bdr_attr_marker[i] |= bdr_marker[i];
1124 for (
int i = 0; i < mesh->
GetNBE(); ++i)
1127 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1137 fes[
s]->GetElementVDofs(i, *vdofs[
s]);
1144 prmfe2[
s] = prmfe[
s];
1146 paramfes[
s]->GetElementVDofs(i, *prmvdofs[
s]);
1151 for (
int k = 0; k <
bfnfi.Size(); ++k)
1153 bfnfi[k]->AssembleFaceGrad(fe, fe2, prmfe, prmfe2, *tr, el_x_const,
1154 prmel_x_const, elmats);
1155 for (
int l=0; l<
fes.
Size(); ++l)
1157 for (
int j=0; j<
fes.
Size(); ++j)
1159 if (elmats(j,l)->Height() == 0) {
continue; }
1160 Grads(j,l)->AddSubMatrix(*vdofs[j], *vdofs[l],
1161 *elmats(j,l), skip_zeros);
1169 if (!
Grads(0,0)->Finalized())
1171 for (
int i=0; i<
fes.
Size(); ++i)
1173 for (
int j=0; j<
fes.
Size(); ++j)
1175 Grads(i,j)->Finalize(skip_zeros);
1180 for (
int i=0; i<
fes.
Size(); ++i)
1182 for (
int j=0; j<
fes.
Size(); ++j)
1193 delete prmvdofs2[i];
1210 for (
int s1 = 0; s1 <
fes.
Size(); ++s1)
1212 for (
int s2 = 0; s2 <
fes.
Size(); ++s2)
1216 mGrads(s1, s2) =
cGrads(s1, s2);
1223 for (
int i = 0; i <
ess_tdofs[
s]->Size(); ++i)
1225 for (
int j = 0; j <
fes.
Size(); ++j)
1235 mGrads(j, s)->EliminateCol((*
ess_tdofs[s])[i]);
1243 for (
int i = 0; i <
fes.
Size(); ++i)
1245 for (
int j = 0; j <
fes.
Size(); ++j)
1257 for (
int i=0; i<
fes.
Size(); ++i)
1259 for (
int j=0; j<
fes.
Size(); ++j)
1272 for (
int i = 0; i <
dnfi.Size(); ++i)
1277 for (
int i = 0; i <
fnfi.Size(); ++i)
1282 for (
int i = 0; i <
bfnfi.Size(); ++i)
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 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.
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 Update(double *data, const Array< int > &bOffsets)
Update method.
FaceElementTransformations * GetInteriorFaceTransformations(int FaceNo)
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
int Append(const T &el)
Append element 'el' to array, resize if necessary.
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Set the diagonal value to one.
FaceElementTransformations * GetBdrFaceTransformations(int BdrElemNo)
Dynamic 2D array using row-major layout.
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 PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
int height
Dimension of the output / number of rows in the matrix.
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).
Vector & GetBlock(int i)
Get the i-th vector in the block.