15 #include "../general/device.hpp" 16 #include "../mesh/nurbs.hpp" 38 Table face_dof, dof_face;
57 int *I = dof_dof.
GetI();
58 int *J = dof_dof.
GetJ();
120 MFEM_ABORT(
"the assembly level has already been set!");
141 MFEM_ABORT(
"BilinearForm: unknown assembly level");
151 MFEM_WARNING(
"Static condensation not supported for this assembly level");
157 bool symmetric =
false;
158 bool block_diagonal =
false;
177 MFEM_WARNING(
"Hybridization not supported for this assembly level");
204 "invalid matrix A dimensions: " 206 MFEM_ASSERT(A.
Finalized(),
"matrix A must be Finalized");
295 domain_integs[0]->AssembleElementMatrix(fe, *eltrans, elmat);
405 #ifdef MFEM_USE_LEGACY_OPENMP 406 int free_element_matrices = 0;
410 free_element_matrices = 1;
422 "invalid element marker for domain integrator #" 423 << k <<
", counting from zero");
428 MFEM_VERIFY(
fes->
GetNURBSext(),
"Patchwise integration requires a " 429 <<
"NURBS FE space");
434 for (
int i = 0; i <
fes -> GetNE(); i++)
439 elmat_p = &(*element_matrices)(i);
454 if (elmat.
Size() == 0)
464 if (elmat.
Size() == 0)
497 bool vdofsSet =
false;
513 for (
int r=0; r<spmat->
Height(); ++r)
515 spmat->
GetRow(r, cols, srow);
516 for (
int i=0; i<cols.
Size(); ++i)
518 cols[i] =
vdofs[cols[i]];
544 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
545 "invalid boundary marker for boundary integrator #" 546 << k <<
", counting from zero");
547 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
549 bdr_attr_marker[i] |= bdr_marker[i];
553 for (
int i = 0; i <
fes -> GetNBE(); i++)
556 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
559 doftrans =
fes -> GetBdrElementVDofs (i,
vdofs);
560 eltrans =
fes -> GetBdrElementTransformation (i);
605 for (
int i = 0; i < nfaces; i++)
607 tr = mesh -> GetInteriorFaceTransformations (i);
610 fes -> GetElementVDofs (tr -> Elem1No,
vdofs);
611 fes -> GetElementVDofs (tr -> Elem2No, vdofs2);
642 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
643 "invalid boundary marker for boundary face integrator #" 644 << k <<
", counting from zero");
645 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
647 bdr_attr_marker[i] |= bdr_marker[i];
651 for (
int i = 0; i <
fes -> GetNBE(); i++)
654 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
656 tr = mesh -> GetBdrFaceTransformations (i);
659 fes -> GetElementVDofs (tr -> Elem1No,
vdofs);
660 fe1 =
fes -> GetFE (tr -> Elem1No);
679 #ifdef MFEM_USE_LEGACY_OPENMP 680 if (free_element_matrices)
694 MFEM_ASSERT(
mat,
"the BilinearForm is not assembled");
725 "Vector for holding diagonal has wrong size!");
729 MFEM_ASSERT(
mat,
"the BilinearForm is not assembled!");
730 MFEM_ASSERT(cP ==
nullptr ||
mat->
Height() == cP->Width(),
731 "BilinearForm::ConformingAssemble() is not called!");
746 Vector local_diag(cP->Height());
748 cP->AbsMultTranspose(local_diag, diag);
753 Vector &B,
int copy_interior)
849 const int remove_zeros = 0;
937 #ifdef MFEM_USE_LEGACY_OPENMP 938 #pragma omp parallel for private(tmp,eltrans) 940 for (
int i = 0; i < num_elements; i++)
943 num_dofs_per_el, num_dofs_per_el);
946 if (num_dofs_per_el != fe.GetDof()*
fes->
GetVDim())
947 mfem_error(
"BilinearForm::ComputeElementMatrices:" 948 " all elements must have same number of dofs");
1020 for (
int i = 0; i < vdofs_.
Size(); i++)
1022 int vdof = vdofs_[i];
1025 mat -> EliminateRowCol (vdof, sol(vdof), rhs, dpolicy);
1029 mat -> EliminateRowCol (-1-vdof, sol(-1-vdof), rhs, dpolicy);
1043 for (
int i = 0; i < vdofs_.
Size(); i++)
1045 int vdof = vdofs_[i];
1048 mat -> EliminateRowCol (vdof, *
mat_e, dpolicy);
1052 mat -> EliminateRowCol (-1-vdof, *
mat_e, dpolicy);
1061 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
1062 MFEM_ASSERT(sol.
Size() ==
height,
"incorrect sol Vector size");
1063 MFEM_ASSERT(rhs.
Size() ==
height,
"incorrect rhs Vector size");
1065 for (
int i = 0; i < ess_dofs.
Size(); i++)
1066 if (ess_dofs[i] < 0)
1068 mat -> EliminateRowCol (i, sol(i), rhs, dpolicy);
1075 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
1077 for (
int i = 0; i < ess_dofs.
Size(); i++)
1078 if (ess_dofs[i] < 0)
1080 mat -> EliminateRowCol (i, dpolicy);
1087 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
1089 for (
int i = 0; i < ess_dofs.
Size(); i++)
1090 if (ess_dofs[i] < 0)
1092 mat -> EliminateRowColDiag (i, value);
1132 if (nfes && nfes !=
fes)
1200 :
Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
1214 :
Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
1240 MFEM_ABORT(
"the assembly level has already been set!");
1252 mfem_error(
"Element assembly not supported yet... stay tuned!");
1259 mfem_error(
"Matrix-free action not supported yet... stay tuned!");
1269 return (*
mat)(i, j);
1274 return (*
mat)(i, j);
1284 const double a)
const 1303 const double a)
const 1319 MFEM_WARNING(
"MixedBilinearForm::Inverse not possible with this " 1341 "MixedBilinearForm::GetBlocks: both trial and test spaces " 1342 "must use Ordering::byNODES!");
1408 for (
int i = 0; i <
test_fes -> GetNE(); i++)
1412 eltrans =
test_fes -> GetElementTransformation (i);
1423 if (ran_dof_trans || dom_dof_trans)
1436 bdr_attr_marker = 0;
1441 bdr_attr_marker = 1;
1445 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1446 "invalid boundary marker for boundary integrator #" 1447 << k <<
", counting from zero");
1448 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1450 bdr_attr_marker[i] |= bdr_marker[i];
1454 for (
int i = 0; i <
test_fes -> GetNBE(); i++)
1457 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1461 eltrans =
test_fes -> GetBdrElementTransformation (i);
1475 if (ran_dof_trans || dom_dof_trans)
1490 for (
int i = 0; i < nfaces; i++)
1508 test_fe2 = test_fe1;
1528 bdr_attr_marker = 0;
1533 bdr_attr_marker = 1;
1537 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1538 "invalid boundary marker for boundary trace face" 1539 "integrator #" << k <<
", counting from zero");
1540 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1542 bdr_attr_marker[i] |= bdr_marker[i];
1546 for (
int i = 0; i <
trial_fes -> GetNBE(); i++)
1549 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1561 test_fe2 = test_fe1;
1585 "Vector for holding diagonal has wrong size!");
1587 "Vector for holding diagonal has wrong size!");
1592 Vector local_D(P_trial->Height());
1593 P_trial->Mult(D, local_D);
1622 MFEM_ABORT(
"Not implemented. Maybe assemble your bilinear form into a " 1623 "matrix and use SparseMatrix functions?");
1631 MFEM_WARNING(
"Conforming assemble not supported for this assembly level!");
1667 domain_integs[0]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
1671 domain_integs[k]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
1692 boundary_integs[0]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
1696 boundary_integs[k]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
1755 for (i = 0; i <
trial_fes -> GetNBE(); i++)
1756 if (bdr_attr_is_ess[
trial_fes -> GetBdrAttribute (i)-1])
1758 trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
1759 for (j = 0; j < tr_vdofs.
Size(); j++)
1761 if ( (k = tr_vdofs[j]) < 0 )
1768 mat -> EliminateCols (cols_marker, &sol, &rhs);
1774 mat -> EliminateCols (marked_vdofs, &sol, &rhs);
1782 for (i = 0; i <
test_fes -> GetNBE(); i++)
1783 if (bdr_attr_is_ess[
test_fes -> GetBdrAttribute (i)-1])
1785 test_fes -> GetBdrElementVDofs (i, te_vdofs);
1786 for (j = 0; j < te_vdofs.
Size(); j++)
1788 if ( (k = te_vdofs[j]) < 0 )
1792 mat -> EliminateRow (k);
1814 if (test_P && trial_P)
1833 Array<int> ess_trial_tdof_marker, ess_test_tdof_marker;
1835 ess_trial_tdof_marker);
1837 ess_test_tdof_marker);
1842 for (
int i=0; i<test_tdof_list.
Size(); ++i)
1913 MFEM_ABORT(
"the assembly level has already been set!");
1923 mfem_error(
"Element assembly not supported yet... stay tuned!");
1929 mfem_error(
"Matrix-free action not supported yet... stay tuned!");
1966 domain_integs[0]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T,
1970 domain_integs[j]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T,
1974 if (ran_dof_trans || dom_dof_trans)
1985 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 the indices of the degrees of freedom for the specified face, including the DOFs for the edge...
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.
const NURBSExtension * GetNURBSext() const
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 int GetRow(const int row, Array< int > &cols, Vector &srow) const
Extract all column indices and values from a given row.
void AddRow(const int row, const Array< int > &cols, const Vector &srow)
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
std::function< double(const Vector &)> f(double mass_coeff)
void GetPatchVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom in vdofs for NURBS patch i.
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.
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 indices of degrees of freedom for the i'th element. The returned indices are offsets into an ...
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.
double p(const Vector &x, double t)
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.
NURBSExtension * NURBSext
Optional NURBS mesh extension.
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 indices of degrees of freedom for i'th boundary element. The returned indices are offsets int...
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.