15 #include "../general/device.hpp"
37 Table face_dof, dof_face;
56 int *I = dof_dof.
GetI();
57 int *J = dof_dof.
GetJ();
119 MFEM_ABORT(
"the assembly level has already been set!");
149 MFEM_WARNING(
"Static condensation not supported for this assembly level");
155 bool symmetric =
false;
156 bool block_diagonal =
false;
175 MFEM_WARNING(
"Hybridization not supported for this assembly level");
202 "invalid matrix A dimensions: "
204 MFEM_ASSERT(A.
Finalized(),
"matrix A must be Finalized");
293 domain_integs[0]->AssembleElementMatrix(fe, *eltrans, elmat);
403 #ifdef MFEM_USE_LEGACY_OPENMP
404 int free_element_matrices = 0;
408 free_element_matrices = 1;
420 "invalid element marker for domain integrator #"
421 << k <<
", counting from zero");
425 for (
int i = 0; i <
fes -> GetNE(); i++)
431 elmat_p = &(*element_matrices)(i);
444 if (elmat.
Size() == 0)
454 if (elmat.
Size() == 0)
497 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
498 "invalid boundary marker for boundary integrator #"
499 << k <<
", counting from zero");
500 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
502 bdr_attr_marker[i] |= bdr_marker[i];
506 for (
int i = 0; i <
fes -> GetNBE(); i++)
509 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
512 doftrans =
fes -> GetBdrElementVDofs (i,
vdofs);
513 eltrans =
fes -> GetBdrElementTransformation (i);
558 for (
int i = 0; i < nfaces; i++)
560 tr = mesh -> GetInteriorFaceTransformations (i);
563 fes -> GetElementVDofs (tr -> Elem1No,
vdofs);
564 fes -> GetElementVDofs (tr -> Elem2No, vdofs2);
595 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
596 "invalid boundary marker for boundary face integrator #"
597 << k <<
", counting from zero");
598 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
600 bdr_attr_marker[i] |= bdr_marker[i];
604 for (
int i = 0; i <
fes -> GetNBE(); i++)
607 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
609 tr = mesh -> GetBdrFaceTransformations (i);
612 fes -> GetElementVDofs (tr -> Elem1No,
vdofs);
613 fe1 =
fes -> GetFE (tr -> Elem1No);
632 #ifdef MFEM_USE_LEGACY_OPENMP
633 if (free_element_matrices)
647 MFEM_ASSERT(
mat,
"the BilinearForm is not assembled");
678 "Vector for holding diagonal has wrong size!");
682 MFEM_ASSERT(
mat,
"the BilinearForm is not assembled!");
683 MFEM_ASSERT(cP ==
nullptr ||
mat->
Height() == cP->Width(),
684 "BilinearForm::ConformingAssemble() is not called!");
699 Vector local_diag(cP->Height());
701 cP->AbsMultTranspose(local_diag, diag);
706 Vector &B,
int copy_interior)
802 const int remove_zeros = 0;
890 #ifdef MFEM_USE_LEGACY_OPENMP
891 #pragma omp parallel for private(tmp,eltrans)
893 for (
int i = 0; i < num_elements; i++)
896 num_dofs_per_el, num_dofs_per_el);
899 if (num_dofs_per_el != fe.GetDof()*
fes->
GetVDim())
900 mfem_error(
"BilinearForm::ComputeElementMatrices:"
901 " all elements must have same number of dofs");
973 for (
int i = 0; i < vdofs_.
Size(); i++)
975 int vdof = vdofs_[i];
978 mat -> EliminateRowCol (vdof, sol(vdof), rhs, dpolicy);
982 mat -> EliminateRowCol (-1-vdof, sol(-1-vdof), rhs, dpolicy);
995 for (
int i = 0; i < vdofs_.
Size(); i++)
997 int vdof = vdofs_[i];
1000 mat -> EliminateRowCol (vdof, *
mat_e, dpolicy);
1004 mat -> EliminateRowCol (-1-vdof, *
mat_e, dpolicy);
1013 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
1014 MFEM_ASSERT(sol.
Size() ==
height,
"incorrect sol Vector size");
1015 MFEM_ASSERT(rhs.
Size() ==
height,
"incorrect rhs Vector size");
1017 for (
int i = 0; i < ess_dofs.
Size(); i++)
1018 if (ess_dofs[i] < 0)
1020 mat -> EliminateRowCol (i, sol(i), rhs, dpolicy);
1027 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
1029 for (
int i = 0; i < ess_dofs.
Size(); i++)
1030 if (ess_dofs[i] < 0)
1032 mat -> EliminateRowCol (i, dpolicy);
1039 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
1041 for (
int i = 0; i < ess_dofs.
Size(); i++)
1042 if (ess_dofs[i] < 0)
1044 mat -> EliminateRowColDiag (i, value);
1084 if (nfes && nfes !=
fes)
1152 :
Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
1166 :
Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
1192 MFEM_ABORT(
"the assembly level has already been set!");
1204 mfem_error(
"Element assembly not supported yet... stay tuned!");
1211 mfem_error(
"Matrix-free action not supported yet... stay tuned!");
1221 return (*
mat)(i, j);
1226 return (*
mat)(i, j);
1236 const double a)
const
1255 const double a)
const
1271 MFEM_WARNING(
"MixedBilinearForm::Inverse not possible with this "
1293 "MixedBilinearForm::GetBlocks: both trial and test spaces "
1294 "must use Ordering::byNODES!");
1360 for (
int i = 0; i <
test_fes -> GetNE(); i++)
1364 eltrans =
test_fes -> GetElementTransformation (i);
1375 if (ran_dof_trans || dom_dof_trans)
1388 bdr_attr_marker = 0;
1393 bdr_attr_marker = 1;
1397 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1398 "invalid boundary marker for boundary integrator #"
1399 << k <<
", counting from zero");
1400 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1402 bdr_attr_marker[i] |= bdr_marker[i];
1406 for (
int i = 0; i <
test_fes -> GetNBE(); i++)
1409 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1413 eltrans =
test_fes -> GetBdrElementTransformation (i);
1427 if (ran_dof_trans || dom_dof_trans)
1442 for (
int i = 0; i < nfaces; i++)
1460 test_fe2 = test_fe1;
1480 bdr_attr_marker = 0;
1485 bdr_attr_marker = 1;
1489 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1490 "invalid boundary marker for boundary trace face"
1491 "integrator #" << k <<
", counting from zero");
1492 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1494 bdr_attr_marker[i] |= bdr_marker[i];
1498 for (
int i = 0; i <
trial_fes -> GetNBE(); i++)
1501 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1513 test_fe2 = test_fe1;
1537 "Vector for holding diagonal has wrong size!");
1539 "Vector for holding diagonal has wrong size!");
1544 Vector local_D(P_trial->Height());
1545 P_trial->Mult(D, local_D);
1574 MFEM_ABORT(
"Not implemented. Maybe assemble your bilinear form into a "
1575 "matrix and use SparseMatrix functions?");
1583 MFEM_WARNING(
"Conforming assemble not supported for this assembly level!");
1619 domain_integs[0]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
1623 domain_integs[k]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
1644 boundary_integs[0]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
1648 boundary_integs[k]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
1707 for (i = 0; i <
trial_fes -> GetNBE(); i++)
1708 if (bdr_attr_is_ess[
trial_fes -> GetBdrAttribute (i)-1])
1710 trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
1711 for (j = 0; j < tr_vdofs.
Size(); j++)
1713 if ( (k = tr_vdofs[j]) < 0 )
1720 mat -> EliminateCols (cols_marker, &sol, &rhs);
1726 mat -> EliminateCols (marked_vdofs, &sol, &rhs);
1734 for (i = 0; i <
test_fes -> GetNBE(); i++)
1735 if (bdr_attr_is_ess[
test_fes -> GetBdrAttribute (i)-1])
1737 test_fes -> GetBdrElementVDofs (i, te_vdofs);
1738 for (j = 0; j < te_vdofs.
Size(); j++)
1740 if ( (k = te_vdofs[j]) < 0 )
1744 mat -> EliminateRow (k);
1773 Array<int> ess_trial_tdof_marker, ess_test_tdof_marker;
1775 ess_trial_tdof_marker);
1777 ess_test_tdof_marker);
1782 for (
int i=0; i<test_tdof_list.
Size(); ++i)
1853 MFEM_ABORT(
"the assembly level has already been set!");
1863 mfem_error(
"Element assembly not supported yet... stay tuned!");
1869 mfem_error(
"Matrix-free action not supported yet... stay tuned!");
1906 domain_integs[0]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T,
1910 domain_integs[j]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T,
1914 if (ran_dof_trans || dom_dof_trans)
1925 for (
int i = 0; i < nfaces; i++)
Abstract class for all finite elements.
int Size() const
For backward compatibility define Size to be synonym of Width()
Ordering::Type GetOrdering() const
Return the ordering method.
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.
const SparseMatrix * GetConformingProlongation() const
The returned SparseMatrix is owned by the FiniteElementSpace.
void SetConstraintIntegrator(BilinearFormIntegrator *c_integ)
bool ColumnsAreSorted() const
Returns whether or not the columns are sorted.
bool ReducesTrueVSize() const
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 SortRows()
Sort the column (TYPE II) indices in each row.
void SetSize(int s)
Resize the vector to size s.
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Pointer to an Operator of a specified type.
int * GetJ()
Return the array J.
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...
Data type dense matrix using column-major storage.
void AddMult(const Vector &x, Vector &y, const double a=1.0) const
y += A * x (default) or y += a * A * x
int Size() const
Returns the size of the vector.
void ReduceSystem(Vector &x, Vector &b, Vector &X, Vector &B, int copy_interior=0) const
Set the reduced solution X and r.h.s B vectors from the full linear system solution x and r...
int * GetI()
Return the array I.
void AddMultTranspose(const Vector &x, Vector &y, const double a=1.0) const
y += At * x (default) or y += a * At * x
void EliminateReducedTrueDofs(const Array< int > &ess_rtdof_list, Matrix::DiagonalPolicy dpolicy)
Eliminate the given reduced true dofs from the Schur complement matrix S.
Abstract data type for matrix inverse.
void LoseData()
Call this if data has been stolen.
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
const FiniteElement * GetFaceElement(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th face in the ...
void ComputeSolution(const Vector &b, const Vector &sc_sol, Vector &sol) const
virtual FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31)
void SetAssemblyLevel(AssemblyLevel assembly_level)
Set the desired assembly level. The default is AssemblyLevel::FULL.
void Reset()
Destroy the current hybridization matrix while preserving the computed constraint matrix and the set ...
void GetBlocks(Array2D< SparseMatrix * > &blocks) const
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 ...
DofTransformation * GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i'th boundary element.
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
const SparseMatrix * GetConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
int GetNE() const
Returns number of elements in the mesh.
void SetSize(int m, int n)
void Finalize()
Finalize the construction of the hybridized matrix.
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
void AssembleBdrMatrix(int bdr_el, const DenseMatrix &A)
Assemble the boundary element matrix A into the hybridized system matrix.
double f(const Vector &xvec)
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
SparseMatrix & GetMatrix()
Return the serial hybridized matrix.
void TransformPrimal(const DofTransformation *ran_dof_trans, const DofTransformation *dom_dof_trans, DenseMatrix &elmat)
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.
void GetFaceTransformation(int i, IsoparametricTransformation *FTr)
Returns the transformation defining the given face element in a user-defined variable.
void ComputeSolution(const Vector &b, const Vector &sol_r, Vector &sol) const
Abstract data type 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.
ElementTransformation * GetBdrElementTransformation(int i) const
Returns ElementTransformation for the i-th boundary element.
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
int GetVDim() const
Returns vector dimension.
FaceElementTransformations * GetBdrFaceTransformations(int BdrElemNo)
void SyncMemory(const Vector &v) const
Update the memory location of the vector to match v.
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
Dynamic 2D array using row-major layout.
void SetSubVectorComplement(const Array< int > &dofs, const double val)
Set all vector entries NOT in the dofs Array to the given val.
void SetSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
bool Finalized() const
Returns whether or not CSR format has been finalized.
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.
bool IsIdentityProlongation(const Operator *P)
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void AssembleMatrix(int el, const DenseMatrix &A)
Assemble the element matrix A into the hybridized system matrix.
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 Finalize()
Finalize the construction of the Schur complement matrix.
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.
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
void AssembleBdrMatrix(int el, const DenseMatrix &elmat)
virtual void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x)
Reconstruct a solution vector x (e.g. a GridFunction) from the solution X of a constrained linear sys...
int height
Dimension of the output / number of rows in the matrix.
void EliminateRow(int row, const double sol, Vector &rhs)
Eliminates a column from the transpose matrix.
Table * GetFaceToElementTable() const
void GetDiag(Vector &d) const
Returns the Diagonal of A.
void AssembleMatrix(int el, const DenseMatrix &elmat)
bool HasEliminatedBC() const
Return true if essential boundary conditions have been eliminated from the Schur complement matrix...
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
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 EliminateCols(const Array< int > &cols, const Vector *x=NULL, Vector *b=NULL)
Eliminate all columns i for which cols[i] != 0.
void GetFaceVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i'th face element (2D and 3D).
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 MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
SparseMatrix & GetMatrix()
Return the serial Schur complement matrix.
void TransformDual(const DofTransformation *ran_dof_trans, const DofTransformation *dom_dof_trans, DenseMatrix &elmat)
void ReduceRHS(const Vector &b, Vector &b_r) const
const Table & GetElementToDofTable() const
Return a reference to the internal Table that stores the lists of scalar dofs, for each mesh element...
void Init(const Array< int > &ess_tdof_list)
Prepare the Hybridization object for assembly.
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th boundary fac...
void SetEssentialTrueDofs(const Array< int > &ess_tdof_list)
Determine and save internally essential reduced true dofs.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
virtual const SparseMatrix * GetRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
void Init(bool symmetric, bool block_diagonal)
virtual void Assemble(int skip_zeros=1)
Construct the internal matrix representation of the discrete linear operator.
Rank 3 tensor (array of matrices)
int GetAttribute(int i) const
Return the attribute of element i.
Array< int > attributes
A list of all unique element attributes used by the Mesh.
int width
Dimension of the input / number of columns in the matrix.
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
Partial assembly extension for DiscreteLinearOperator.