38 Table face_dof, dof_face;
57 int *I = dof_dof.
GetI();
58 int *J = dof_dof.
GetJ();
113 MFEM_ABORT(
"the assembly level has already been set!");
134 MFEM_ABORT(
"BilinearForm: unknown assembly level");
143 MFEM_WARNING(
"Static condensation not supported for this assembly level");
149 bool symmetric =
false;
150 bool block_diagonal =
false;
167 MFEM_WARNING(
"Hybridization not supported for this assembly level");
198 "invalid matrix A dimensions: "
200 MFEM_ASSERT(A.
Finalized(),
"matrix A must be Finalized");
290 domain_integs[0]->AssembleElementMatrix(fe, *eltrans, elmat);
331 tr = mesh -> GetFaceElementTransformations (i);
335 if (tr->Elem2No >= 0)
359 if (tr->Elem2No >= 0)
373 tr = mesh -> GetBdrFaceTransformations (i);
377 fe1 =
fes -> GetFE (tr -> Elem1No);
477#ifdef MFEM_USE_LEGACY_OPENMP
478 int free_element_matrices = 0;
482 free_element_matrices = 1;
494 "invalid element marker for domain integrator #"
495 << k <<
", counting from zero");
500 MFEM_VERIFY(
fes->
GetNURBSext(),
"Patchwise integration requires a "
501 <<
"NURBS FE space");
507 for (
int i = 0; i <
fes -> GetNE(); i++)
515 elmat_p = &(*element_matrices)(i);
532 if (elmat.
Size() == 0)
542 if (elmat.
Size() == 0)
572 bool vdofsSet =
false;
588 for (
int r=0; r<spmat->
Height(); ++r)
590 spmat->
GetRow(r, cols, srow);
591 for (
int i=0; i<cols.
Size(); ++i)
593 cols[i] =
vdofs[cols[i]];
619 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
620 "invalid boundary marker for boundary integrator #"
621 << k <<
", counting from zero");
622 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
624 bdr_attr_marker[i] |= bdr_marker[i];
629 for (
int i = 0; i <
fes -> GetNBE(); i++)
632 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
635 fes -> GetBdrElementVDofs (i,
vdofs, doftrans);
636 eltrans =
fes -> GetBdrElementTransformation (i);
678 for (
int i = 0; i < nfaces; i++)
680 tr = mesh -> GetInteriorFaceTransformations (i);
683 fes -> GetElementVDofs (tr -> Elem1No,
vdofs);
684 fes -> GetElementVDofs (tr -> Elem2No, vdofs2);
689 AssembleFaceMatrix(*
fes->
GetFE(tr->Elem1No),
715 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
716 "invalid boundary marker for boundary face integrator #"
717 << k <<
", counting from zero");
718 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
720 bdr_attr_marker[i] |= bdr_marker[i];
724 for (
int i = 0; i <
fes -> GetNBE(); i++)
727 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
729 tr = mesh -> GetBdrFaceTransformations (i);
732 fes -> GetElementVDofs (tr -> Elem1No,
vdofs);
733 fe1 =
fes -> GetFE (tr -> Elem1No);
752#ifdef MFEM_USE_LEGACY_OPENMP
753 if (free_element_matrices)
767 MFEM_ASSERT(
mat,
"the BilinearForm is not assembled");
798 "Vector for holding diagonal has wrong size!");
802 MFEM_ASSERT(
mat,
"the BilinearForm is not assembled!");
804 "BilinearForm::ConformingAssemble() is not called!");
811 ext->AssembleDiagonal(diag);
820 ext->AssembleDiagonal(local_diag);
826 Vector &B,
int copy_interior)
841 ext->FormLinearSystem(ess_tdof_list, x,
b, A, X, B, copy_interior);
912 const int remove_zeros = 0;
918 ext->FormSystemMatrix(ess_tdof_list, A);
943 const int remove_zeros = 0;
962 ext->RecoverFEMSolution(X,
b, x);
1041#ifdef MFEM_USE_LEGACY_OPENMP
1042 #pragma omp parallel for private(tmp,eltrans)
1044 for (
int i = 0; i < num_elements; i++)
1047 num_dofs_per_el, num_dofs_per_el);
1051 mfem_error(
"BilinearForm::ComputeElementMatrices:"
1052 " all elements must have same number of dofs");
1056 domain_integs[0]->AssembleElementMatrix(fe, eltrans, elmat);
1130 for (
int i = 0; i < vdofs_.
Size(); i++)
1132 int vdof = vdofs_[i];
1135 mat -> EliminateRowCol (vdof, sol(vdof), rhs, dpolicy);
1139 mat -> EliminateRowCol (-1-vdof, sol(-1-vdof), rhs, dpolicy);
1153 for (
int i = 0; i < vdofs_.
Size(); i++)
1155 int vdof = vdofs_[i];
1158 mat -> EliminateRowCol (vdof, *
mat_e, dpolicy);
1162 mat -> EliminateRowCol (-1-vdof, *
mat_e, dpolicy);
1171 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
1172 MFEM_ASSERT(sol.
Size() ==
height,
"incorrect sol Vector size");
1173 MFEM_ASSERT(rhs.
Size() ==
height,
"incorrect rhs Vector size");
1175 for (
int i = 0; i < ess_dofs.
Size(); i++)
1176 if (ess_dofs[i] < 0)
1178 mat -> EliminateRowCol (i, sol(i), rhs, dpolicy);
1186 "incorrect dof Array size: " << ess_dofs.
Size() <<
' ' <<
height);
1188 for (
int i = 0; i < ess_dofs.
Size(); i++)
1189 if (ess_dofs[i] < 0)
1191 mat -> EliminateRowCol (i, dpolicy);
1199 "incorrect dof Array size: " << ess_dofs.
Size() <<
' ' <<
height);
1201 for (
int i = 0; i < ess_dofs.
Size(); i++)
1202 if (ess_dofs[i] < 0)
1204 mat -> EliminateRowColDiag (i, value);
1231 ext->MultTranspose(x, y);
1244 if (nfes && nfes !=
fes)
1277 if (
ext) {
ext->Update(); }
1305 :
Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
1319 :
Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
1347 MFEM_ABORT(
"the assembly level has already been set!");
1359 MFEM_ABORT(
"Element assembly not supported yet... stay tuned!");
1366 MFEM_ABORT(
"Matrix-free action not supported yet... stay tuned!");
1370 MFEM_ABORT(
"Unknown assembly level");
1376 return (*
mat)(i, j);
1381 return (*
mat)(i, j);
1395 ext->AddMult(x, y,
a);
1414 ext->AddMultTranspose(x, y,
a);
1426 MFEM_WARNING(
"MixedBilinearForm::Inverse not possible with this "
1448 "MixedBilinearForm::GetBlocks: both trial and test spaces "
1449 "must use Ordering::byNODES!");
1545 "invalid element marker for domain integrator #"
1546 << k <<
", counting from zero");
1551 for (
int i = 0; i <
test_fes -> GetNE(); i++)
1556 eltrans =
test_fes -> GetElementTransformation (i);
1581 bdr_attr_marker = 0;
1586 bdr_attr_marker = 1;
1590 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1591 "invalid boundary marker for boundary integrator #"
1592 << k <<
", counting from zero");
1593 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1595 bdr_attr_marker[i] |= bdr_marker[i];
1600 for (
int i = 0; i <
test_fes -> GetNBE(); i++)
1603 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1607 eltrans =
test_fes -> GetBdrElementTransformation (i);
1630 const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
1633 for (
int i = 0; i < nfaces; i++)
1656 trial_fe2 = trial_fe1;
1657 test_fe2 = test_fe1;
1674 const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
1679 bdr_attr_marker = 0;
1684 bdr_attr_marker = 1;
1688 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1689 "invalid boundary marker for boundary face integrator #"
1690 << k <<
", counting from zero");
1691 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1693 bdr_attr_marker[i] |= bdr_marker[i];
1697 for (
int i = 0; i <
trial_fes -> GetNBE(); i++)
1700 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1702 ftr = mesh -> GetBdrFaceTransformations (i);
1712 trial_fe2 = trial_fe1;
1713 test_fe2 = test_fe1;
1735 for (
int i = 0; i < nfaces; i++)
1753 test_fe2 = test_fe1;
1773 bdr_attr_marker = 0;
1778 bdr_attr_marker = 1;
1782 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1783 "invalid boundary marker for boundary trace face"
1784 "integrator #" << k <<
", counting from zero");
1785 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1787 bdr_attr_marker[i] |= bdr_marker[i];
1791 for (
int i = 0; i <
trial_fes -> GetNBE(); i++)
1794 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1807 test_fe2 = test_fe1;
1831 "Vector for holding diagonal has wrong size!");
1833 "Vector for holding diagonal has wrong size!");
1839 P_trial->
Mult(D, local_D);
1844 ext->AssembleDiagonal_ADAt(local_D, local_diag);
1849 ext->AssembleDiagonal_ADAt(local_D, diag);
1857 ext->AssembleDiagonal_ADAt(D, local_diag);
1862 ext->AssembleDiagonal_ADAt(D, diag);
1868 MFEM_ABORT(
"Not implemented. Maybe assemble your bilinear form into a "
1869 "matrix and use SparseMatrix functions?");
1877 MFEM_WARNING(
"Conforming assemble not supported for this assembly level!");
1914 domain_integs[0]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
1918 domain_integs[k]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
1928 elmat.
SetSize(te_dofs, tr_dofs);
1941 boundary_integs[0]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
1945 boundary_integs[k]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
1955 elmat.
SetSize(te_dofs, tr_dofs);
1965 MFEM_ASSERT(ftr,
"No associated face transformations.");
1967 const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
1981 trial_fe2 = trial_fe1;
1982 test_fe2 = test_fe1;
2008 elmat.
SetSize(te_dofs, tr_dofs);
2018 MFEM_ASSERT(ftr,
"No associated boundary face.");
2020 const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
2027 trial_fe2 = trial_fe1;
2028 test_fe2 = test_fe1;
2048 elmat.
SetSize(te_dofs, tr_dofs);
2058 MFEM_ASSERT(ftr,
"No associated face transformation.");
2073 test_fe2 = test_fe1;
2096 elmat.
SetSize(te_dofs, tr_face_dofs);
2107 MFEM_ASSERT(ftr,
"No associated boundary face.");
2116 test_fe2 = test_fe1;
2136 elmat.
SetSize(te_dofs, tr_face_dofs);
2200 trial_vdofs_marker);
2213 trial_vdofs_marker);
2236 for (i = 0; i <
test_fes -> GetNBE(); i++)
2237 if (bdr_attr_is_ess[
test_fes -> GetBdrAttribute (i)-1])
2239 test_fes -> GetBdrElementVDofs (i, te_vdofs);
2240 for (j = 0; j < te_vdofs.
Size(); j++)
2242 if ( (k = te_vdofs[j]) < 0 )
2246 mat -> EliminateRow (k);
2253 for (
int i=0; i<test_vdofs_.
Size(); ++i)
2267 ext->FormRectangularSystemOperator(trial_tdof_list, test_tdof_list, A);
2276 if (test_P && trial_P)
2310 ext->FormRectangularLinearSystem(trial_tdof_list, test_tdof_list,
2339 if (
ext) {
ext->Update(); }
2367 MFEM_ABORT(
"the assembly level has already been set!");
2377 MFEM_ABORT(
"Element assembly not supported yet... stay tuned!");
2383 MFEM_ABORT(
"Matrix-free action not supported yet... stay tuned!");
2386 MFEM_ABORT(
"Unknown assembly level");
2416 "invalid element marker for domain integrator #"
2417 << k <<
", counting from zero");
2451 for (
int i = 0; i < nfaces; i++)
Dynamic 2D array using row-major layout.
void SetSize(int m, int n)
Set the 2D array size to m x n.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
int Size() const
Return the logical size of the array.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Square Operator for imposing essential boundary conditions using only the action, Mult(),...
void EliminateRHS(const Vector &x, Vector &b) const
Eliminate "essential boundary condition" values specified in x from the given right-hand side b.
Data type dense matrix using column-major storage.
real_t * GetData() const
Returns the matrix data array. Warning: this method casts away constness.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
int Size() const
For backward compatibility define Size to be synonym of Width()
Rank 3 tensor (array of matrices)
virtual void Assemble(int skip_zeros=1)
Construct the internal matrix representation of the discrete linear operator.
void SetAssemblyLevel(AssemblyLevel assembly_level)
Set the desired assembly level. The default is AssemblyLevel::FULL.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
const SparseMatrix * GetConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
const Table & GetElementToDofTable() const
Return a reference to the internal Table that stores the lists of scalar dofs, for each mesh element,...
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th boundary fac...
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
ElementTransformation * GetElementTransformation(int i) const
virtual const SparseMatrix * GetRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
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...
const NURBSExtension * GetNURBSext() const
virtual const Operator * GetProlongationMatrix() const
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for the i'th element. The returned indices are offsets into an ...
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
Ordering::Type GetOrdering() const
Return the ordering method.
ElementTransformation * GetBdrElementTransformation(int i) const
Returns ElementTransformation for the i-th boundary element.
int GetNE() const
Returns number of elements in the mesh.
void GetFaceVDofs(int i, Array< int > &vdofs) const
Returns the indices of the degrees of freedom for the specified face, including the DOFs for the edge...
const FiniteElement * GetFaceElement(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th face in the ...
const SparseMatrix * GetConformingProlongation() const
Mesh * GetMesh() const
Returns the mesh.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
int GetVDim() const
Returns the vector dimension of the finite element space.
const FiniteElement * GetTypicalFE() const
Return GetFE(0) if the local mesh is not empty; otherwise return a typical FE based on the Geometry t...
DofTransformation * GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for i'th boundary element. The returned indices are offsets int...
virtual void GetEssentialVDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_vdofs, int component=-1) const
Mark degrees of freedom associated with boundary elements with the specified boundary attributes (mar...
void GetPatchVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom in vdofs for NURBS patch i.
Abstract class for all finite elements.
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Auxiliary class Hybridization, used to implement BilinearForm hybridization.
Abstract data type for matrix inverse.
Abstract data type matrix.
Class used by MFEM to store pointers to host and/or device memory.
virtual FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31)
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
NURBSExtension * NURBSext
Optional NURBS mesh extension.
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
int GetAttribute(int i) const
Return the attribute of element i.
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
int GetBdrElementFaceIndex(int be_idx) const
Return the local face (codimension-1) index for the given boundary element index.
ElementTransformation * GetFaceTransformation(int FaceNo)
Returns a pointer to the transformation defining the given face element.
FaceElementTransformations * GetBdrFaceTransformations(int BdrElemNo)
Builds the transformation defining the given boundary face.
FaceElementTransformations * GetInteriorFaceTransformations(int FaceNo)
See GetFaceElementTransformations().
Table * GetFaceToElementTable() const
Array< int > attributes
A list of all unique element attributes used by the Mesh.
int GetNP() const
Return the number of patches.
Pointer to an Operator of a specified type.
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
int width
Dimension of the input / number of columns in the matrix.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int height
Dimension of the output / number of rows in the matrix.
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
@ DIAG_ONE
Set the diagonal value to one.
@ DIAG_KEEP
Keep the diagonal value.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void InitTVectors(const Operator *Po, const Operator *Ri, const Operator *Pi, Vector &x, Vector &b, Vector &X, Vector &B) const
Initializes memory for true vectors of linear system.
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 ...
Partial assembly extension for DiscreteLinearOperator.
int GetRow(const int row, Array< int > &cols, Vector &srow) const override
Extract all column indices and values from a given row.
void GetDiag(Vector &d) const
Returns the Diagonal of A.
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
bool ColumnsAreSorted() const
Returns whether or not the columns are sorted.
void MultTranspose(const Vector &x, Vector &y) const override
Multiply a vector with the transposed matrix. y = At * x.
bool Finalized() const
Returns whether or not CSR format has been finalized.
void SetSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
void AddMultTranspose(const Vector &x, Vector &y, const real_t a=1.0) const override
y += At * x (default) or y += a * At * x
void AddMult(const Vector &x, Vector &y, const real_t a=1.0) const override
y += A * x (default) or y += a * A * x
void Mult(const Vector &x, Vector &y) const override
Matrix vector multiplication.
void EliminateRow(int row, const real_t sol, Vector &rhs)
Eliminates a column from the transpose matrix.
void GetBlocks(Array2D< SparseMatrix * > &blocks) const
void AbsMultTranspose(const Vector &x, Vector &y) const override
y = |At| * x, using entry-wise absolute values of the transpose of matrix A
void Finalize(int skip_zeros=1) override
Finalize the matrix initialization, switching the storage format from LIL to CSR.
void EliminateCols(const Array< int > &cols, const Vector *x=NULL, Vector *b=NULL)
Eliminate all columns i for which cols[i] != 0.
int * GetJ()
Return the array J.
void AddRow(const int row, const Array< int > &cols, const Vector &srow)
int * GetI()
Return the array I.
Table stores the connectivity of elements of TYPE I to elements of TYPE II. For example,...
void LoseData()
Releases ownership of and null-ifies the data.
void SortRows()
Sort the column (TYPE II) indices in each row.
void SetSubVector(const Array< int > &dofs, const real_t value)
Set the entries listed in dofs to the given value.
void SyncMemory(const Vector &v) const
Update the memory location of the vector to match v.
int Size() const
Returns the size of the vector.
void SetSize(int s)
Resize the vector to size s.
void SetSubVectorComplement(const Array< int > &dofs, const real_t val)
Set all vector entries NOT in the dofs Array to the given val.
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
void mfem_error(const char *msg)
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void TransformDual(const DofTransformation &ran_dof_trans, const DofTransformation &dom_dof_trans, DenseMatrix &elmat)
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
AssemblyLevel
Enumeration defining the assembly level for bilinear and nonlinear form classes derived from Operator...
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
bool IsIdentityProlongation(const Operator *P)
void TransformPrimal(const DofTransformation &ran_dof_trans, const DofTransformation &dom_dof_trans, DenseMatrix &elmat)
@ NATIVE
Native ordering as defined by the FiniteElement.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
SparseMatrix * TransposeMult(const SparseMatrix &A, const SparseMatrix &B)
C = A^T B.
real_t p(const Vector &x, real_t t)