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!");
140 MFEM_ABORT(
"BilinearForm: unknown assembly level");
150 MFEM_WARNING(
"Static condensation not supported for this assembly level");
156 bool symmetric =
false;
157 bool block_diagonal =
false;
176 MFEM_WARNING(
"Hybridization not supported for this assembly level");
203 "invalid matrix A dimensions: " 205 MFEM_ASSERT(A.
Finalized(),
"matrix A must be Finalized");
294 domain_integs[0]->AssembleElementMatrix(fe, *eltrans, elmat);
404 #ifdef MFEM_USE_LEGACY_OPENMP 405 int free_element_matrices = 0;
409 free_element_matrices = 1;
421 "invalid element marker for domain integrator #" 422 << k <<
", counting from zero");
426 for (
int i = 0; i <
fes -> GetNE(); i++)
432 elmat_p = &(*element_matrices)(i);
445 if (elmat.
Size() == 0)
455 if (elmat.
Size() == 0)
498 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
499 "invalid boundary marker for boundary integrator #" 500 << k <<
", counting from zero");
501 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
503 bdr_attr_marker[i] |= bdr_marker[i];
507 for (
int i = 0; i <
fes -> GetNBE(); i++)
510 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
513 doftrans =
fes -> GetBdrElementVDofs (i,
vdofs);
514 eltrans =
fes -> GetBdrElementTransformation (i);
559 for (
int i = 0; i < nfaces; i++)
561 tr = mesh -> GetInteriorFaceTransformations (i);
564 fes -> GetElementVDofs (tr -> Elem1No,
vdofs);
565 fes -> GetElementVDofs (tr -> Elem2No, vdofs2);
596 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
597 "invalid boundary marker for boundary face integrator #" 598 << k <<
", counting from zero");
599 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
601 bdr_attr_marker[i] |= bdr_marker[i];
605 for (
int i = 0; i <
fes -> GetNBE(); i++)
608 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
610 tr = mesh -> GetBdrFaceTransformations (i);
613 fes -> GetElementVDofs (tr -> Elem1No,
vdofs);
614 fe1 =
fes -> GetFE (tr -> Elem1No);
633 #ifdef MFEM_USE_LEGACY_OPENMP 634 if (free_element_matrices)
648 MFEM_ASSERT(
mat,
"the BilinearForm is not assembled");
679 "Vector for holding diagonal has wrong size!");
683 MFEM_ASSERT(
mat,
"the BilinearForm is not assembled!");
684 MFEM_ASSERT(cP ==
nullptr ||
mat->
Height() == cP->Width(),
685 "BilinearForm::ConformingAssemble() is not called!");
700 Vector local_diag(cP->Height());
702 cP->AbsMultTranspose(local_diag, diag);
707 Vector &B,
int copy_interior)
803 const int remove_zeros = 0;
891 #ifdef MFEM_USE_LEGACY_OPENMP 892 #pragma omp parallel for private(tmp,eltrans) 894 for (
int i = 0; i < num_elements; i++)
897 num_dofs_per_el, num_dofs_per_el);
900 if (num_dofs_per_el != fe.GetDof()*
fes->
GetVDim())
901 mfem_error(
"BilinearForm::ComputeElementMatrices:" 902 " all elements must have same number of dofs");
974 for (
int i = 0; i < vdofs_.
Size(); i++)
976 int vdof = vdofs_[i];
979 mat -> EliminateRowCol (vdof, sol(vdof), rhs, dpolicy);
983 mat -> EliminateRowCol (-1-vdof, sol(-1-vdof), rhs, dpolicy);
997 for (
int i = 0; i < vdofs_.
Size(); i++)
999 int vdof = vdofs_[i];
1002 mat -> EliminateRowCol (vdof, *
mat_e, dpolicy);
1006 mat -> EliminateRowCol (-1-vdof, *
mat_e, dpolicy);
1015 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
1016 MFEM_ASSERT(sol.
Size() ==
height,
"incorrect sol Vector size");
1017 MFEM_ASSERT(rhs.
Size() ==
height,
"incorrect rhs Vector size");
1019 for (
int i = 0; i < ess_dofs.
Size(); i++)
1020 if (ess_dofs[i] < 0)
1022 mat -> EliminateRowCol (i, sol(i), rhs, dpolicy);
1029 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
1031 for (
int i = 0; i < ess_dofs.
Size(); i++)
1032 if (ess_dofs[i] < 0)
1034 mat -> EliminateRowCol (i, dpolicy);
1041 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
1043 for (
int i = 0; i < ess_dofs.
Size(); i++)
1044 if (ess_dofs[i] < 0)
1046 mat -> EliminateRowColDiag (i, value);
1086 if (nfes && nfes !=
fes)
1154 :
Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
1168 :
Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
1194 MFEM_ABORT(
"the assembly level has already been set!");
1206 mfem_error(
"Element assembly not supported yet... stay tuned!");
1213 mfem_error(
"Matrix-free action not supported yet... stay tuned!");
1223 return (*
mat)(i, j);
1228 return (*
mat)(i, j);
1238 const double a)
const 1257 const double a)
const 1273 MFEM_WARNING(
"MixedBilinearForm::Inverse not possible with this " 1295 "MixedBilinearForm::GetBlocks: both trial and test spaces " 1296 "must use Ordering::byNODES!");
1362 for (
int i = 0; i <
test_fes -> GetNE(); i++)
1366 eltrans =
test_fes -> GetElementTransformation (i);
1377 if (ran_dof_trans || dom_dof_trans)
1390 bdr_attr_marker = 0;
1395 bdr_attr_marker = 1;
1399 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1400 "invalid boundary marker for boundary integrator #" 1401 << k <<
", counting from zero");
1402 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1404 bdr_attr_marker[i] |= bdr_marker[i];
1408 for (
int i = 0; i <
test_fes -> GetNBE(); i++)
1411 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1415 eltrans =
test_fes -> GetBdrElementTransformation (i);
1429 if (ran_dof_trans || dom_dof_trans)
1444 for (
int i = 0; i < nfaces; i++)
1462 test_fe2 = test_fe1;
1482 bdr_attr_marker = 0;
1487 bdr_attr_marker = 1;
1491 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1492 "invalid boundary marker for boundary trace face" 1493 "integrator #" << k <<
", counting from zero");
1494 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1496 bdr_attr_marker[i] |= bdr_marker[i];
1500 for (
int i = 0; i <
trial_fes -> GetNBE(); i++)
1503 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1515 test_fe2 = test_fe1;
1539 "Vector for holding diagonal has wrong size!");
1541 "Vector for holding diagonal has wrong size!");
1546 Vector local_D(P_trial->Height());
1547 P_trial->Mult(D, local_D);
1576 MFEM_ABORT(
"Not implemented. Maybe assemble your bilinear form into a " 1577 "matrix and use SparseMatrix functions?");
1585 MFEM_WARNING(
"Conforming assemble not supported for this assembly level!");
1621 domain_integs[0]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
1625 domain_integs[k]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
1646 boundary_integs[0]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
1650 boundary_integs[k]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
1709 for (i = 0; i <
trial_fes -> GetNBE(); i++)
1710 if (bdr_attr_is_ess[
trial_fes -> GetBdrAttribute (i)-1])
1712 trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
1713 for (j = 0; j < tr_vdofs.
Size(); j++)
1715 if ( (k = tr_vdofs[j]) < 0 )
1722 mat -> EliminateCols (cols_marker, &sol, &rhs);
1728 mat -> EliminateCols (marked_vdofs, &sol, &rhs);
1736 for (i = 0; i <
test_fes -> GetNBE(); i++)
1737 if (bdr_attr_is_ess[
test_fes -> GetBdrAttribute (i)-1])
1739 test_fes -> GetBdrElementVDofs (i, te_vdofs);
1740 for (j = 0; j < te_vdofs.
Size(); j++)
1742 if ( (k = te_vdofs[j]) < 0 )
1746 mat -> EliminateRow (k);
1768 if (test_P && trial_P)
1787 Array<int> ess_trial_tdof_marker, ess_test_tdof_marker;
1789 ess_trial_tdof_marker);
1791 ess_test_tdof_marker);
1796 for (
int i=0; i<test_tdof_list.
Size(); ++i)
1867 MFEM_ABORT(
"the assembly level has already been set!");
1877 mfem_error(
"Element assembly not supported yet... stay tuned!");
1883 mfem_error(
"Matrix-free action not supported yet... stay tuned!");
1920 domain_integs[0]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T,
1924 domain_integs[j]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T,
1928 if (ran_dof_trans || dom_dof_trans)
1939 for (
int i = 0; i < nfaces; i++)
Abstract class for all finite elements.
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 ...
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
AssemblyLevel
Enumeration defining the assembly level for bilinear and nonlinear form classes derived from Operator...
virtual void AddMultTranspose(const Vector &x, Vector &y, const double a=1.0) const
Operator transpose application: y+=A^t(x) (default) or y+=a*A^t(x).
void SetConstraintIntegrator(BilinearFormIntegrator *c_integ)
void GetDiag(Vector &d) const
Returns the Diagonal of A.
void ComputeSolution(const Vector &b, const Vector &sc_sol, Vector &sol) const
virtual void Finalize(int skip_zeros=1)
Finalize the matrix initialization, switching the storage format from LIL to CSR. ...
void SyncMemory(const Vector &v) const
Update the memory location of the vector to match v.
void SortRows()
Sort the column (TYPE II) indices in each row.
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
void SetSize(int s)
Resize the vector to size s.
virtual void AddMult(const Vector &x, Vector &y, const double a=1.0) const
Operator application: y+=A(x) (default) or y+=a*A(x).
const SparseMatrix * GetConformingRestriction() const
The returned SparseMatrix is owned by the FiniteElementSpace.
void GetFaceVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i'th face element (2D and 3D).
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Pointer to an Operator of a specified type.
int * GetJ()
Return the array J.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
int Size() const
Returns the size of the vector.
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.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
Data type dense matrix using column-major storage.
bool HasEliminatedBC() const
Return true if essential boundary conditions have been eliminated from the Schur complement matrix...
bool ReducesTrueVSize() const
int * GetI()
Return the array I.
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).
virtual void AddMult(const Vector &x, Vector &y, const double a=1.0) const
y += A * x (default) or y += a * A * x
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 ...
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
const FiniteElement * GetFaceElement(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th face in the ...
void ReduceRHS(const Vector &b, Vector &b_r) const
int GetAttribute(int i) const
Return the attribute of element i.
void SetSize(int m, int n)
void Finalize()
Finalize the construction of the hybridized matrix.
void GetBlocks(Array2D< SparseMatrix *> &blocks) const
void AssembleBdrMatrix(int bdr_el, const DenseMatrix &A)
Assemble the boundary element matrix A into the hybridized system matrix.
double f(const Vector &xvec)
SparseMatrix & GetMatrix()
Return the serial hybridized matrix.
void TransformPrimal(const DofTransformation *ran_dof_trans, const DofTransformation *dom_dof_trans, DenseMatrix &elmat)
int Size() const
For backward compatibility define Size to be synonym of Width()
int Append(const T &el)
Append element 'el' to array, resize if necessary.
ElementTransformation * GetBdrElementTransformation(int i) const
Returns ElementTransformation for the i-th boundary element.
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)
virtual const SparseMatrix * GetRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Abstract data type matrix.
const SparseMatrix * GetConformingProlongation() const
The returned SparseMatrix is owned by the FiniteElementSpace.
Table * GetFaceToElementTable() const
Set the diagonal value to one.
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
FaceElementTransformations * GetBdrFaceTransformations(int BdrElemNo)
int GetNE() const
Returns number of elements in the mesh.
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
bool Finalized() const
Returns whether or not CSR format has been finalized.
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)
int GetVDim() const
Returns vector dimension.
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...
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
bool IsIdentityProlongation(const Operator *P)
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
virtual void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
Mesh * GetMesh() const
Returns the mesh.
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...
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 Finalize()
Finalize the construction of the Schur complement matrix.
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
int GetDof() const
Returns the number of degrees of freedom in the finite element.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
void AssembleBdrMatrix(int el, const DenseMatrix &elmat)
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
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.
virtual const Operator * GetProlongationMatrix() const
The returned Operator is owned by the FiniteElementSpace.
SparseMatrix * TransposeMult(const SparseMatrix &A, const SparseMatrix &B)
C = A^T B.
void AssembleMatrix(int el, const DenseMatrix &elmat)
Ordering::Type GetOrdering() const
Return the ordering method.
DofTransformation * GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i'th boundary element.
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
void EliminateCols(const Array< int > &cols, const Vector *x=NULL, Vector *b=NULL)
Eliminate all columns i for which cols[i] != 0.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
bool ColumnsAreSorted() const
Returns whether or not the columns are sorted.
int Size() const
Return the logical size of the array.
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 Init(const Array< int > &ess_tdof_list)
Prepare the Hybridization object for assembly.
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.
void ComputeSolution(const Vector &b, const Vector &sol_r, Vector &sol) const
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)
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...
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.
virtual void AddMultTranspose(const Vector &x, Vector &y, const double a=1.0) const
y += At * x (default) or y += a * At * x
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
Partial assembly extension for DiscreteLinearOperator.
ElementTransformation * GetElementTransformation(int i) const
Returns ElementTransformation for the i-th element.