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!");
129 mfem_error(
"Element assembly not supported yet... stay tuned!");
136 mfem_error(
"Matrix-free action not supported yet... stay tuned!");
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");
285 dbfi[0]->AssembleElementMatrix(fe, *eltrans, elmat);
286 for (
int k = 1; k <
dbfi.Size(); k++)
288 dbfi[k]->AssembleElementMatrix(fe, *eltrans,
elemmat);
306 bbfi[0]->AssembleElementMatrix(be, *eltrans, elmat);
307 for (
int k = 1; k <
bbfi.Size(); k++)
309 bbfi[k]->AssembleElementMatrix(be, *eltrans,
elemmat);
394 #ifdef MFEM_USE_LEGACY_OPENMP
395 int free_element_matrices = 0;
399 free_element_matrices = 1;
405 for (
int i = 0; i <
fes -> GetNE(); i++)
410 elmat_p = &(*element_matrices)(i);
416 dbfi[0]->AssembleElementMatrix(fe, *eltrans, elmat);
417 for (
int k = 1; k <
dbfi.Size(); k++)
419 dbfi[k]->AssembleElementMatrix(fe, *eltrans,
elemmat);
445 for (
int k = 0; k <
bbfi.Size(); k++)
453 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
454 "invalid boundary marker for boundary integrator #"
455 << k <<
", counting from zero");
456 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
458 bdr_attr_marker[i] |= bdr_marker[i];
462 for (
int i = 0; i <
fes -> GetNBE(); i++)
465 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
468 fes -> GetBdrElementVDofs (i,
vdofs);
469 eltrans =
fes -> GetBdrElementTransformation (i);
470 bbfi[0]->AssembleElementMatrix(be, *eltrans, elmat);
471 for (
int k = 1; k <
bbfi.Size(); k++)
476 bbfi[k]->AssembleElementMatrix(be, *eltrans,
elemmat);
500 for (
int i = 0; i < nfaces; i++)
502 tr = mesh -> GetInteriorFaceTransformations (i);
505 fes -> GetElementVDofs (tr -> Elem1No,
vdofs);
506 fes -> GetElementVDofs (tr -> Elem2No, vdofs2);
508 for (
int k = 0; k <
fbfi.Size(); k++)
510 fbfi[k] -> AssembleFaceMatrix (*
fes -> GetFE (tr -> Elem1No),
511 *
fes -> GetFE (tr -> Elem2No),
528 for (
int k = 0; k <
bfbfi.Size(); k++)
536 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
537 "invalid boundary marker for boundary face integrator #"
538 << k <<
", counting from zero");
539 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
541 bdr_attr_marker[i] |= bdr_marker[i];
545 for (
int i = 0; i <
fes -> GetNBE(); i++)
548 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
550 tr = mesh -> GetBdrFaceTransformations (i);
553 fes -> GetElementVDofs (tr -> Elem1No,
vdofs);
554 fe1 =
fes -> GetFE (tr -> Elem1No);
559 for (
int k = 0; k <
bfbfi.Size(); k++)
564 bfbfi[k] -> AssembleFaceMatrix (*fe1, *fe2, *tr,
elemmat);
571 #ifdef MFEM_USE_LEGACY_OPENMP
572 if (free_element_matrices)
586 MFEM_ASSERT(
mat,
"the BilinearForm is not assembled");
619 "Vector for holding diagonal has wrong size!");
623 Vector local_diag(P->Height());
625 P->MultTranspose(local_diag, diag);
634 MFEM_ABORT(
"Not implemented. Maybe assemble your bilinear form into a "
635 "matrix and use SparseMatrix::GetDiag?");
641 Vector &B,
int copy_interior)
737 const int remove_zeros = 0;
825 #ifdef MFEM_USE_LEGACY_OPENMP
826 #pragma omp parallel for private(tmp,eltrans)
828 for (
int i = 0; i < num_elements; i++)
831 num_dofs_per_el, num_dofs_per_el);
834 if (num_dofs_per_el != fe.GetDof()*
fes->
GetVDim())
835 mfem_error(
"BilinearForm::ComputeElementMatrices:"
836 " all elements must have same number of dofs");
840 dbfi[0]->AssembleElementMatrix(fe, eltrans, elmat);
841 for (
int k = 1; k <
dbfi.Size(); k++)
844 dbfi[k]->AssembleElementMatrix(fe, eltrans, tmp);
907 for (
int i = 0; i < vdofs.
Size(); i++)
912 mat -> EliminateRowCol (vdof, sol(vdof), rhs, dpolicy);
916 mat -> EliminateRowCol (-1-vdof, sol(-1-vdof), rhs, dpolicy);
929 for (
int i = 0; i < vdofs.
Size(); i++)
934 mat -> EliminateRowCol (vdof, *
mat_e, dpolicy);
938 mat -> EliminateRowCol (-1-vdof, *
mat_e, dpolicy);
947 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
948 MFEM_ASSERT(sol.
Size() ==
height,
"incorrect sol Vector size");
949 MFEM_ASSERT(rhs.
Size() ==
height,
"incorrect rhs Vector size");
951 for (
int i = 0; i < ess_dofs.
Size(); i++)
954 mat -> EliminateRowCol (i, sol(i), rhs, dpolicy);
961 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
963 for (
int i = 0; i < ess_dofs.
Size(); i++)
966 mat -> EliminateRowCol (i, dpolicy);
973 MFEM_ASSERT(ess_dofs.
Size() ==
height,
"incorrect dof Array size");
975 for (
int i = 0; i < ess_dofs.
Size(); i++)
978 mat -> EliminateRowColDiag (i, value);
1005 if (nfes && nfes !=
fes)
1059 for (k=0; k <
dbfi.Size(); k++) {
delete dbfi[k]; }
1060 for (k=0; k <
bbfi.Size(); k++) {
delete bbfi[k]; }
1061 for (k=0; k <
fbfi.Size(); k++) {
delete fbfi[k]; }
1062 for (k=0; k <
bfbfi.Size(); k++) {
delete bfbfi[k]; }
1071 :
Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
1085 :
Matrix(te_fes->GetVSize(), tr_fes->GetVSize())
1111 MFEM_ABORT(
"the assembly level has already been set!");
1121 mfem_error(
"Element assembly not supported yet... stay tuned!");
1128 mfem_error(
"Matrix-free action not supported yet... stay tuned!");
1138 return (*
mat)(i, j);
1143 return (*
mat)(i, j);
1153 const double a)
const
1172 const double a)
const
1188 MFEM_WARNING(
"MixedBilinearForm::Inverse not possible with this assembly level!");
1209 "MixedBilinearForm::GetBlocks: both trial and test spaces "
1210 "must use Ordering::byNODES!");
1274 for (
int i = 0; i <
test_fes -> GetNE(); i++)
1276 trial_fes -> GetElementVDofs (i, tr_vdofs);
1277 test_fes -> GetElementVDofs (i, te_vdofs);
1278 eltrans =
test_fes -> GetElementTransformation (i);
1279 for (
int k = 0; k <
dbfi.Size(); k++)
1284 mat -> AddSubMatrix (te_vdofs, tr_vdofs, elemmat, skip_zeros);
1294 bdr_attr_marker = 0;
1295 for (
int k = 0; k <
bbfi.Size(); k++)
1299 bdr_attr_marker = 1;
1303 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1304 "invalid boundary marker for boundary integrator #"
1305 << k <<
", counting from zero");
1306 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1308 bdr_attr_marker[i] |= bdr_marker[i];
1312 for (
int i = 0; i <
test_fes -> GetNBE(); i++)
1315 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1317 trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
1318 test_fes -> GetBdrElementVDofs (i, te_vdofs);
1319 eltrans =
test_fes -> GetBdrElementTransformation (i);
1320 for (
int k = 0; k <
bbfi.Size(); k++)
1328 mat -> AddSubMatrix (te_vdofs, tr_vdofs, elemmat, skip_zeros);
1340 for (
int i = 0; i < nfaces; i++)
1350 te_vdofs.
Append(te_vdofs2);
1358 test_fe2 = test_fe1;
1360 for (
int k = 0; k <
tfbfi.Size(); k++)
1362 tfbfi[k]->AssembleFaceMatrix(*trial_face_fe, *test_fe1, *test_fe2,
1378 bdr_attr_marker = 0;
1379 for (
int k = 0; k <
btfbfi.Size(); k++)
1383 bdr_attr_marker = 1;
1387 MFEM_ASSERT(bdr_marker.
Size() == bdr_attr_marker.
Size(),
1388 "invalid boundary marker for boundary trace face integrator #"
1389 << k <<
", counting from zero");
1390 for (
int i = 0; i < bdr_attr_marker.
Size(); i++)
1392 bdr_attr_marker[i] |= bdr_marker[i];
1396 for (
int i = 0; i <
trial_fes -> GetNBE(); i++)
1399 if (bdr_attr_marker[bdr_attr-1] == 0) {
continue; }
1411 test_fe2 = test_fe1;
1412 for (
int k = 0; k <
btfbfi.Size(); k++)
1417 btfbfi[k]->AssembleFaceMatrix(*trial_face_fe, *test_fe1, *test_fe2,
1430 MFEM_WARNING(
"Conforming assemble not supported for this assembly level!");
1466 dbfi[0]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans, elmat);
1467 for (
int k = 1; k <
dbfi.Size(); k++)
1469 dbfi[k]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
elemmat);
1489 bbfi[0]->AssembleElementMatrix2(trial_be, test_be, *eltrans, elmat);
1490 for (
int k = 1; k <
bbfi.Size(); k++)
1492 bbfi[k]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
elemmat);
1550 for (i = 0; i <
trial_fes -> GetNBE(); i++)
1551 if (bdr_attr_is_ess[
trial_fes -> GetBdrAttribute (i)-1])
1553 trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
1554 for (j = 0; j < tr_vdofs.
Size(); j++)
1556 if ( (k = tr_vdofs[j]) < 0 )
1563 mat -> EliminateCols (cols_marker, &sol, &rhs);
1569 mat -> EliminateCols (marked_vdofs, &sol, &rhs);
1577 for (i = 0; i <
test_fes -> GetNBE(); i++)
1578 if (bdr_attr_is_ess[
test_fes -> GetBdrAttribute (i)-1])
1580 test_fes -> GetBdrElementVDofs (i, te_vdofs);
1581 for (j = 0; j < te_vdofs.
Size(); j++)
1583 if ( (k = te_vdofs[j]) < 0 )
1587 mat -> EliminateRow (k);
1616 Array<int> ess_trial_tdof_marker, ess_test_tdof_marker;
1618 ess_trial_tdof_marker);
1620 ess_test_tdof_marker);
1625 for (
int i=0; i<test_tdof_list.
Size(); ++i)
1681 for (i = 0; i <
dbfi.Size(); i++) {
delete dbfi[i]; }
1682 for (i = 0; i <
bbfi.Size(); i++) {
delete bbfi[i]; }
1683 for (i = 0; i <
tfbfi.Size(); i++) {
delete tfbfi[i]; }
1684 for (i = 0; i <
btfbfi.Size(); i++) {
delete btfbfi[i]; }
1702 if (
dbfi.Size() > 0)
1712 dbfi[0]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, totelmat);
1713 for (
int j = 1; j <
dbfi.Size(); j++)
1715 dbfi[j]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, elmat);
1725 for (
int i = 0; i < nfaces; i++)
1733 tfbfi[0]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, totelmat);
1734 for (
int j = 1; j <
tfbfi.Size(); j++)
1736 tfbfi[j]->AssembleElementMatrix2(*dom_fe, *ran_fe, *T, elmat);
Abstract class for Finite Elements.
Ordering::Type GetOrdering() const
Return the ordering method.
int Size() const
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().
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
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
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
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.
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 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 AssembleMatrix(int el, const DenseMatrix &elmat)
bool HasEliminatedBC() const
Return true if essential boundary conditions have been eliminated from the Schur complement matrix...
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 associated with i'th element.
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)
SparseMatrix & GetMatrix()
Return the serial Schur complement matrix.
void ReduceRHS(const Vector &b, Vector &b_r) const
const Table & GetElementToDofTable() const
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 for the i'th boundary element.
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.
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