18 void LORBase::AddIntegrators(BilinearForm &a_from,
20 GetIntegratorsFn get_integrators,
21 AddIntegratorFn add_integrator,
22 const IntegrationRule *ir)
24 Array<BilinearFormIntegrator*> *integrators = (a_from.*get_integrators)();
25 for (
int i=0; i<integrators->Size(); ++i)
27 (a_to.*add_integrator)((*integrators)[i]);
28 ir_map[(*integrators)[i]] = ((*integrators)[i])->GetIntegrationRule();
29 if (ir) { ((*integrators)[i])->SetIntegrationRule(*ir); }
33 void LORBase::AddIntegratorsAndMarkers(BilinearForm &a_from,
35 GetIntegratorsFn get_integrators,
36 GetMarkersFn get_markers,
37 AddIntegratorMarkersFn add_integrator,
38 const IntegrationRule *ir)
40 Array<BilinearFormIntegrator*> *integrators = (a_from.*get_integrators)();
41 Array<Array<int>*> *markers = (a_from.*get_markers)();
43 for (
int i=0; i<integrators->Size(); ++i)
45 (a_to.*add_integrator)((*integrators)[i], *(*markers[i]));
46 ir_map[(*integrators)[i]] = ((*integrators)[i])->GetIntegrationRule();
47 if (ir) { ((*integrators)[i])->SetIntegrationRule(*ir); }
51 void LORBase::ResetIntegrationRules(GetIntegratorsFn get_integrators)
53 Array<BilinearFormIntegrator*> *integrators = (
a->*get_integrators)();
54 for (
int i=0; i<integrators->Size(); ++i)
56 ((*integrators)[i])->SetIntegrationRule(*ir_map[(*integrators)[i]]);
63 if (dynamic_cast<const H1_FECollection*>(fec)) {
return H1; }
64 else if (dynamic_cast<const ND_FECollection*>(fec)) {
return ND; }
65 else if (dynamic_cast<const RT_FECollection*>(fec)) {
return RT; }
66 else if (dynamic_cast<const L2_FECollection*>(fec)) {
return L2; }
67 else { MFEM_ABORT(
"Bad LOR space type."); }
74 return (type ==
L2 || type ==
RT) ? 0 : 1;
80 MFEM_VERIFY(type !=
H1 && type !=
L2,
"");
86 MFEM_ASSERT(tfe != NULL,
"");
87 return tfe->GetDofMap();
98 for (
int ilor=0; ilor<mesh_lor.
GetNE(); ++ilor)
101 int lor_index = cf_tr.
embeddings[ilor].matrix;
108 perm_[vdof_lor[0]] = vdof_ho[lor_index];
114 int ndof_per_dim = (dim == 2) ? p*p1 : type ==
ND ? p*p1*p1 : p*p*p1;
117 const Array<int> &dofmap_lor = get_dof_map(fes_lor, ilor);
119 int off_x = lor_index %
p;
120 int off_y = (lor_index /
p) % p;
121 int off_z = (lor_index /
p) / p;
123 auto set_perm = [&](
int off_lor,
int off_ho,
int n1,
int n2)
125 for (
int i1=0; i1<2; ++i1)
127 int m = (dim == 2 || type ==
RT) ? 1 : 2;
128 for (
int i2=0; i2<m; ++i2)
131 i = dofmap_lor[off_lor + i1 + i2*2];
132 int s1 = i < 0 ? -1 : 1;
133 int idof_lor = vdof_lor[absdof(i)];
134 i = dofmap_ho[off_ho + i1*n1 + i2*n2];
135 int s2 = i < 0 ? -1 : 1;
136 int idof_ho = vdof_ho[absdof(i)];
137 int s3 = idof_lor < 0 ? -1 : 1;
138 int s4 = idof_ho < 0 ? -1 : 1;
141 perm_[absdof(idof_lor)] = s < 0 ? -1-absdof(i) : absdof(i);
151 offset = off_x + off_y*p + off_z*p*p1;
152 set_perm(0, offset, p, p*p1);
154 offset = ndof_per_dim + off_x + off_y*(p1) + off_z*p1*p;
155 set_perm(dim == 2 ? 2 : 4, offset, 1, p*p1);
159 offset = 2*ndof_per_dim + off_x + off_y*p1 + off_z*p1*p1;
160 set_perm(8, offset, 1, p+1);
166 offset = off_x + off_y*p1 + off_z*p*p1;
167 set_perm(0, offset, 1, 0);
169 offset = ndof_per_dim + off_x + off_y*p + off_z*p1*
p;
170 set_perm(2, offset, p, 0);
174 offset = 2*ndof_per_dim + off_x + off_y*p + off_z*p*
p;
175 set_perm(4, offset, p*p, 0);
196 if (pfes_ho && pfes_lor)
201 for (
int i=0; i<l_perm.
Size(); ++i)
204 int s = j < 0 ? -1 : 1;
208 if ((t_i < 0 && t_j >=0) || (t_j < 0 && t_i >= 0))
210 MFEM_ABORT(
"Inconsistent DOF numbering");
212 if (t_i < 0) {
continue; }
213 perm[t_i] = s < 0 ? -1 - t_j : t_j;
237 MFEM_VERIFY(
a != NULL &&
A.
Ptr() != NULL,
"No LOR system assembled");
260 for (
int i=0; i<p.
Size(); ++i)
262 pi[absdof(p[i])] = i;
265 for (
int i=0; i<ess_dofs.
Size(); ++i)
267 ess_dofs_perm[i] = pi[ess_dofs[i]];
296 template <
typename FEC>
299 const FEC *fec =
dynamic_cast<const FEC*
>(fes.
FEColl());
302 int btype = fec->GetBasisType();
305 mfem::err <<
"\nWARNING: Constructing low-order refined "
306 <<
"discretization with basis type\n"
308 <<
"The LOR discretization is only spectrally equivalent\n"
309 <<
"with Gauss-Lobatto basis.\n" << std::endl;
314 template <
typename FEC>
317 const FEC *fec =
dynamic_cast<const FEC*
>(fes.
FEColl());
320 int cbtype = fec->GetClosedBasisType();
321 int obtype = fec->GetOpenBasisType();
324 mfem::err <<
"\nWARNING: Constructing vector low-order refined "
325 <<
"discretization with basis type \npair ("
328 <<
"The LOR discretization is only spectrally\nequivalent "
329 <<
"with basis types (Gauss-Lobatto, IntegratedGLL).\n"
337 CheckScalarBasisType<H1_FECollection>(fes);
338 CheckVectorBasisType<ND_FECollection>(fes);
339 CheckVectorBasisType<RT_FECollection>(fes);
352 ir_el = &irs.
Get(geoms[0], 1);
381 int ref_type) :
LORBase(fes_ho)
387 "Cannot construct LOR operators on variable-order spaces");
404 MFEM_VERIFY(
a != NULL &&
A.
Ptr() != NULL,
"No LOR system assembled");
420 int ref_type) :
LORBase(fes_ho)
425 "Cannot construct LOR operators on variable-order spaces");
444 MFEM_VERIFY(
a != NULL &&
A.
Ptr() != NULL,
"No LOR system assembled");
Abstract class for all finite elements.
int Size() const
Return the logical size of the array.
Abstract base class for LORDiscretization and ParLORDiscretization classes, which construct low-order...
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
LORDiscretization(BilinearForm &a_ho, const Array< int > &ess_tdof_list, int ref_type=BasisType::GaussLobatto)
Construct the low-order refined version of a_ho using the given list of essential DOFs...
const OperatorHandle & GetAssembledSystem() const
Returns the assembled LOR system.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
Create and assemble a low-order refined version of a ParBilinearForm.
static Type TensorProductGeometry(int dim)
FESpaceType GetFESpaceType() const
Returns the type of finite element space: H1, ND, RT or L2.
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
ParMesh * GetParMesh() const
static ParMesh MakeRefined(ParMesh &orig_mesh, int ref_factor, int ref_type)
Create a uniformly refined (by any factor) version of orig_mesh.
int GetLOROrder() const
Returns the order of the LOR space. 1 for H1 or ND, 0 for L2 or RT.
Integrated GLL indicator functions.
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
Pointer to an Operator of a specified type.
FiniteElementSpace & fes_ho
static Mesh MakeRefined(Mesh &orig_mesh, int ref_factor, int ref_type)
Create a refined (by any factor) version of orig_mesh.
void GetGeometries(int dim, Array< Geometry::Type > &el_geoms) const
Return all element geometries of the given dimension present in the mesh.
const Array< int > & GetDofPermutation() const
Returns the permutation that maps LOR DOFs to high-order DOFs.
int GetNE() const
Returns number of elements.
Abstract parallel finite element space.
A class container for 1D quadrature type constants.
int GetLocalTDofNumber(int ldof) const
static const char * Name(int b_type)
Check and convert a BasisType constant to a string identifier.
virtual void CopyProlongationAndRestriction(const FiniteElementSpace &fes, const Array< int > *perm)
Copies the prolongation and restriction matrices from fes.
HypreParMatrix & GetAssembledMatrix() const
Return the assembled LOR operator as a HypreParMatrix.
void CheckScalarBasisType(const FiniteElementSpace &fes)
Create and assemble a low-order refined version of a BilinearForm.
virtual int GetTrueVSize() const
Return the number of local vector true dofs.
ID for class SparseMatrix.
Mesh * GetMesh() const
Returns the mesh.
void CheckBasisType(const FiniteElementSpace &fes)
int GetMaxElementOrder() const
Return the maximum polynomial order.
void SetupNonconforming()
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Operator * Ptr() const
Access the underlying Operator pointer.
double p(const Vector &x, double t)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int GetOrder(int i) const
Returns the polynomial degree of the i'th finite element.
void ConstructDofPermutation() const
const CoarseFineTransformations & GetRefinementTransforms()
bool Nonconforming() const
bool Nonconforming() const
virtual FiniteElementCollection * Clone(int p) const
Instantiate a new collection of the same type with a different order.
static bool IsTensorProduct(Type geom)
ParFiniteElementSpace & GetParFESpace() const
Return the LOR ParFiniteElementSpace.
FiniteElementCollection * fec
ParLORDiscretization(ParBilinearForm &a_ho, const Array< int > &ess_tdof_list, int ref_type=BasisType::GaussLobatto)
Construct the low-order refined version of a_ho using the given list of essential DOFs...
void AssembleSystem(BilinearForm &a_ho, const Array< int > &ess_dofs)
Assembles the LOR system.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
void ConstructLocalDofPermutation(Array< int > &perm_) const
LORBase(FiniteElementSpace &fes_ho_)
void CheckVectorBasisType(const FiniteElementSpace &fes)
bool RequiresDofPermutation() const
SparseMatrix & GetAssembledMatrix() const
Return the assembled LOR operator as a SparseMatrix.
const FiniteElementCollection * FEColl() const
ID for class HypreParMatrix.
Wrapper for hypre's ParCSR matrix class.
Class for parallel meshes.
void SetType(Operator::Type tid)
Invoke Clear() and set a new type id.