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");
284 dbfi[0]->AssembleElementMatrix(fe, *eltrans, elmat);
285 for (
int k = 1; k <
dbfi.Size(); k++)
287 dbfi[k]->AssembleElementMatrix(fe, *eltrans,
elemmat);
305 bbfi[0]->AssembleElementMatrix(be, *eltrans, elmat);
306 for (
int k = 1; k <
bbfi.Size(); k++)
308 bbfi[k]->AssembleElementMatrix(be, *eltrans,
elemmat);
393 #ifdef MFEM_USE_LEGACY_OPENMP
394 int free_element_matrices = 0;
398 free_element_matrices = 1;
404 for (
int i = 0; i <
fes -> GetNE(); i++)
409 elmat_p = &(*element_matrices)(i);
415 dbfi[0]->AssembleElementMatrix(fe, *eltrans, elmat);
416 for (
int k = 1; k <
dbfi.Size(); k++)
418 dbfi[k]->AssembleElementMatrix(fe, *eltrans,
elemmat);
444 for (
int k = 0; k <
bbfi.Size(); k++)
452 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
453 "invalid boundary marker for boundary integrator #"
454 << k <<
", counting from zero");
455 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
457 bdr_attr_marker[i] |= bdr_marker[i];
461 for (
int i = 0; i <
fes -> GetNBE(); i++)
464 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
467 fes -> GetBdrElementVDofs (i,
vdofs);
468 eltrans =
fes -> GetBdrElementTransformation (i);
470 for (; k <
bbfi.Size(); k++)
475 bbfi[k]->AssembleElementMatrix(be, *eltrans, elmat);
479 for (; k <
bbfi.Size(); k++)
484 bbfi[k]->AssembleElementMatrix(be, *eltrans,
elemmat);
508 for (
int i = 0; i < nfaces; i++)
510 tr = mesh -> GetInteriorFaceTransformations (i);
513 fes -> GetElementVDofs (tr -> Elem1No,
vdofs);
514 fes -> GetElementVDofs (tr -> Elem2No, vdofs2);
516 for (
int k = 0; k <
fbfi.Size(); k++)
518 fbfi[k] -> AssembleFaceMatrix (*
fes -> GetFE (tr -> Elem1No),
519 *
fes -> GetFE (tr -> Elem2No),
536 for (
int k = 0; k <
bfbfi.Size(); k++)
544 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
545 "invalid boundary marker for boundary face 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; }
558 tr = mesh -> GetBdrFaceTransformations (i);
561 fes -> GetElementVDofs (tr -> Elem1No,
vdofs);
562 fe1 =
fes -> GetFE (tr -> Elem1No);
567 for (
int k = 0; k <
bfbfi.Size(); k++)
572 bfbfi[k] -> AssembleFaceMatrix (*fe1, *fe2, *tr,
elemmat);
579 #ifdef MFEM_USE_LEGACY_OPENMP
580 if (free_element_matrices)
594 MFEM_ASSERT(
mat,
"the BilinearForm is not assembled");
627 "Vector for holding diagonal has wrong size!");
634 Vector local_diag(P->Height());
652 MFEM_ABORT(
"Prolongation matrix has unexpected type.");
658 Vector local_diag(P->Height());
660 P->MultTranspose(local_diag, diag);
675 Vector &B,
int copy_interior)
771 const int remove_zeros = 0;
859 #ifdef MFEM_USE_LEGACY_OPENMP
860 #pragma omp parallel for private(tmp,eltrans)
862 for (
int i = 0; i < num_elements; i++)
865 num_dofs_per_el, num_dofs_per_el);
868 if (num_dofs_per_el != fe.GetDof()*
fes->
GetVDim())
869 mfem_error(
"BilinearForm::ComputeElementMatrices:"
870 " all elements must have same number of dofs");
874 dbfi[0]->AssembleElementMatrix(fe, eltrans, elmat);
875 for (
int k = 1; k <
dbfi.Size(); k++)
878 dbfi[k]->AssembleElementMatrix(fe, eltrans, tmp);
941 for (
int i = 0; i < vdofs.
Size(); i++)
946 mat -> EliminateRowCol (vdof, sol(vdof), rhs, dpolicy);
950 mat -> EliminateRowCol (-1-vdof, sol(-1-vdof), rhs, dpolicy);
963 for (
int i = 0; i < vdofs.
Size(); i++)
968 mat -> EliminateRowCol (vdof, *
mat_e, dpolicy);
972 mat -> EliminateRowCol (-1-vdof, *
mat_e, dpolicy);
981 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
982 MFEM_ASSERT(sol.
Size() ==
height,
"incorrect sol Vector size");
983 MFEM_ASSERT(rhs.
Size() ==
height,
"incorrect rhs Vector size");
985 for (
int i = 0; i < ess_dofs.
Size(); i++)
988 mat -> EliminateRowCol (i, sol(i), rhs, dpolicy);
995 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
997 for (
int i = 0; i < ess_dofs.
Size(); i++)
1000 mat -> EliminateRowCol (i, dpolicy);
1007 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
1009 for (
int i = 0; i < ess_dofs.
Size(); i++)
1010 if (ess_dofs[i] < 0)
1012 mat -> EliminateRowColDiag (i, value);
1039 if (nfes && nfes !=
fes)
1093 for (k=0; k <
dbfi.Size(); k++) {
delete dbfi[k]; }
1094 for (k=0; k <
bbfi.Size(); k++) {
delete bbfi[k]; }
1095 for (k=0; k <
fbfi.Size(); k++) {
delete fbfi[k]; }
1096 for (k=0; k <
bfbfi.Size(); k++) {
delete bfbfi[k]; }
1105 :
Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
1119 :
Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
1145 MFEM_ABORT(
"the assembly level has already been set!");
1157 mfem_error(
"Element assembly not supported yet... stay tuned!");
1164 mfem_error(
"Matrix-free action not supported yet... stay tuned!");
1174 return (*
mat)(i, j);
1179 return (*
mat)(i, j);
1189 const double a)
const
1208 const double a)
const
1224 MFEM_WARNING(
"MixedBilinearForm::Inverse not possible with this assembly level!");
1245 "MixedBilinearForm::GetBlocks: both trial and test spaces "
1246 "must use Ordering::byNODES!");
1310 for (
int i = 0; i <
test_fes -> GetNE(); i++)
1312 trial_fes -> GetElementVDofs (i, tr_vdofs);
1313 test_fes -> GetElementVDofs (i, te_vdofs);
1314 eltrans =
test_fes -> GetElementTransformation (i);
1315 for (
int k = 0; k <
dbfi.Size(); k++)
1320 mat -> AddSubMatrix (te_vdofs, tr_vdofs, elemmat, skip_zeros);
1330 bdr_attr_marker = 0;
1331 for (
int k = 0; k <
bbfi.Size(); k++)
1335 bdr_attr_marker = 1;
1339 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1340 "invalid boundary marker for boundary integrator #"
1341 << k <<
", counting from zero");
1342 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1344 bdr_attr_marker[i] |= bdr_marker[i];
1348 for (
int i = 0; i <
test_fes -> GetNBE(); i++)
1351 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1353 trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
1354 test_fes -> GetBdrElementVDofs (i, te_vdofs);
1355 eltrans =
test_fes -> GetBdrElementTransformation (i);
1356 for (
int k = 0; k <
bbfi.Size(); k++)
1364 mat -> AddSubMatrix (te_vdofs, tr_vdofs, elemmat, skip_zeros);
1376 for (
int i = 0; i < nfaces; i++)
1386 te_vdofs.
Append(te_vdofs2);
1394 test_fe2 = test_fe1;
1396 for (
int k = 0; k <
tfbfi.Size(); k++)
1398 tfbfi[k]->AssembleFaceMatrix(*trial_face_fe, *test_fe1, *test_fe2,
1414 bdr_attr_marker = 0;
1415 for (
int k = 0; k <
btfbfi.Size(); k++)
1419 bdr_attr_marker = 1;
1423 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1424 "invalid boundary marker for boundary trace face integrator #"
1425 << k <<
", counting from zero");
1426 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1428 bdr_attr_marker[i] |= bdr_marker[i];
1432 for (
int i = 0; i <
trial_fes -> GetNBE(); i++)
1435 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1447 test_fe2 = test_fe1;
1448 for (
int k = 0; k <
btfbfi.Size(); k++)
1453 btfbfi[k]->AssembleFaceMatrix(*trial_face_fe, *test_fe1, *test_fe2,
1468 "Vector for holding diagonal has wrong size!");
1470 "Vector for holding diagonal has wrong size!");
1475 Vector local_D(P_trial->Height());
1476 P_trial->Mult(D, local_D);
1505 MFEM_ABORT(
"Not implemented. Maybe assemble your bilinear form into a "
1506 "matrix and use SparseMatrix functions?");
1514 MFEM_WARNING(
"Conforming assemble not supported for this assembly level!");
1550 dbfi[0]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans, elmat);
1551 for (
int k = 1; k <
dbfi.Size(); k++)
1553 dbfi[k]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
elemmat);
1573 bbfi[0]->AssembleElementMatrix2(trial_be, test_be, *eltrans, elmat);
1574 for (
int k = 1; k <
bbfi.Size(); k++)
1576 bbfi[k]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
elemmat);
1634 for (i = 0; i <
trial_fes -> GetNBE(); i++)
1635 if (bdr_attr_is_ess[
trial_fes -> GetBdrAttribute (i)-1])
1637 trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
1638 for (j = 0; j < tr_vdofs.
Size(); j++)
1640 if ( (k = tr_vdofs[j]) < 0 )
1647 mat -> EliminateCols (cols_marker, &sol, &rhs);
1653 mat -> EliminateCols (marked_vdofs, &sol, &rhs);
1661 for (i = 0; i <
test_fes -> GetNBE(); i++)
1662 if (bdr_attr_is_ess[
test_fes -> GetBdrAttribute (i)-1])
1664 test_fes -> GetBdrElementVDofs (i, te_vdofs);
1665 for (j = 0; j < te_vdofs.
Size(); j++)
1667 if ( (k = te_vdofs[j]) < 0 )
1671 mat -> EliminateRow (k);
1700 Array<int> ess_trial_tdof_marker, ess_test_tdof_marker;
1702 ess_trial_tdof_marker);
1704 ess_test_tdof_marker);
1709 for (
int i=0; i<test_tdof_list.
Size(); ++i)
1765 for (i = 0; i <
dbfi.Size(); i++) {
delete dbfi[i]; }
1766 for (i = 0; i <
bbfi.Size(); i++) {
delete bbfi[i]; }
1767 for (i = 0; i <
tfbfi.Size(); i++) {
delete tfbfi[i]; }
1768 for (i = 0; i <
btfbfi.Size(); i++) {
delete btfbfi[i]; }
1786 if (
dbfi.Size() > 0)
1796 dbfi[0]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, totelmat);
1797 for (
int j = 1; j <
dbfi.Size(); j++)
1799 dbfi[j]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, elmat);
1809 for (
int i = 0; i < nfaces; i++)
1817 tfbfi[0]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, totelmat);
1818 for (
int j = 1; j <
tfbfi.Size(); j++)
1820 tfbfi[j]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, elmat);
Abstract class for all finite elements.
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.
void SyncMemory(const Vector &v)
Update the memory location of the vector to match v.
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.
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
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
FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31)
Memory< double > & GetMemory()
Return a reference to the Memory object used by the Vector.
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 ...
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
void AbsMultTranspose(double a, const Vector &x, double b, Vector &y) const
Computes y = a * |At| * x + b * y, using entry-wise absolute values of the transpose of matrix A...
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.
void AssembleBdrMatrix(int bdr_el, const DenseMatrix &A)
Assemble the boundary element matrix A into the hybridized system matrix.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
SparseMatrix & GetMatrix()
Return the serial hybridized matrix.
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.
void Transpose(const Table &A, Table &At, int _ncols_A)
Transpose a Table.
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 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 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...
void AbsMultTranspose(const Vector &x, Vector &y) const
y = |At| * x, using entry-wise absolute values of the transpose of matrix A
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
void NewMemoryAndSize(const Memory< double > &mem, int s, bool own_mem)
Reset the Vector to use the given external Memory mem and size s.
void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
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...
SparseMatrix & GetMatrix()
Return the serial Schur complement matrix.
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 GetBdrElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom for i'th boundary element.
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.
Wrapper for hypre's ParCSR matrix class.
virtual const SparseMatrix * GetRestrictionMatrix() const
The returned SparseMatrix is owned by the FiniteElementSpace.
long GetSequence() const
Return update counter (see Mesh::sequence)
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 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
double f(const Vector &p)