21void LORBase::AddIntegrators(BilinearForm &a_from,
23 GetIntegratorsFn get_integrators,
24 AddIntegratorFn add_integrator,
25 const IntegrationRule *ir)
27 Array<BilinearFormIntegrator*> *integrators = (a_from.*get_integrators)();
28 for (
int i=0; i<integrators->Size(); ++i)
30 BilinearFormIntegrator *integrator = (*integrators)[i];
31 (a_to.*add_integrator)(integrator);
32 ir_map[integrator] = integrator->GetIntRule();
33 if (ir) { integrator->SetIntegrationRule(*ir); }
37void LORBase::AddIntegratorsAndMarkers(BilinearForm &a_from,
39 GetIntegratorsFn get_integrators,
40 GetMarkersFn get_markers,
41 AddIntegratorMarkersFn add_integrator_marker,
42 AddIntegratorFn add_integrator,
43 const IntegrationRule *ir)
45 Array<BilinearFormIntegrator*> *integrators = (a_from.*get_integrators)();
46 Array<Array<int>*> &markers = *(a_from.*get_markers)();
48 for (
int i=0; i<integrators->Size(); ++i)
50 BilinearFormIntegrator *integrator = (*integrators)[i];
51 if (markers[i] !=
nullptr)
53 (a_to.*add_integrator_marker)(integrator, *markers[i]);
57 (a_to.*add_integrator)(integrator);
59 ir_map[integrator] = integrator->GetIntRule();
60 if (ir) { integrator->SetIntegrationRule(*ir); }
64void LORBase::ResetIntegrationRules(GetIntegratorsFn get_integrators)
66 Array<BilinearFormIntegrator*> *integrators = (
a->*get_integrators)();
67 for (
int i=0; i<integrators->Size(); ++i)
69 ((*integrators)[i])->SetIntRule(ir_map[(*integrators)[i]]);
80 else { MFEM_ABORT(
"Bad LOR space type."); }
87 return (type ==
L2 || type ==
RT) ? 0 : 1;
93 MFEM_VERIFY(type !=
H1 && type !=
L2,
"");
99 MFEM_ASSERT(tfe != NULL,
"");
100 return tfe->GetDofMap();
108 using GeomRef = std::pair<Geometry::Type, int>;
109 std::map<GeomRef, int> point_matrices_offsets;
113 for (
int ilor=0; ilor<mesh_lor.
GetNE(); ++ilor)
117 int lor_index = cf_tr.
embeddings[ilor].matrix;
126 if (point_matrices_offsets.find(
id) == point_matrices_offsets.end())
128 point_matrices_offsets[id] = lor_index;
130 lor_index -= point_matrices_offsets[id];
137 perm_[vdof_lor[0]] = vdof_ho[lor_index];
142 int ndof_per_dim = (
dim == 2) ?
p*p1 : type ==
ND ?
p*p1*p1 :
p*
p*p1;
145 const Array<int> &dofmap_lor = get_dof_map(fes_lor, ilor);
147 int off_x = lor_index %
p;
148 int off_y = (lor_index /
p) %
p;
149 int off_z = (lor_index /
p) /
p;
151 auto set_perm = [&](
int off_lor,
int off_ho,
int n1,
int n2)
153 for (
int i1=0; i1<2; ++i1)
155 int m = (
dim == 2 || type ==
RT) ? 1 : 2;
156 for (
int i2=0; i2<m; ++i2)
159 i = dofmap_lor[off_lor + i1 + i2*2];
160 int s1 = i < 0 ? -1 : 1;
162 i = dofmap_ho[off_ho + i1*n1 + i2*n2];
163 int s2 = i < 0 ? -1 : 1;
165 int s3 = idof_lor < 0 ? -1 : 1;
166 int s4 = idof_ho < 0 ? -1 : 1;
180 offset = off_x + off_y*
p + off_z*
p*p1;
181 set_perm(0, offset,
p,
p*p1);
183 offset = ndof_per_dim + off_x + off_y*(p1) + off_z*p1*
p;
184 set_perm(
dim == 2 ? 2 : 4, offset, 1,
p*p1);
188 offset = 2*ndof_per_dim + off_x + off_y*p1 + off_z*p1*p1;
189 set_perm(8, offset, 1,
p+1);
195 offset = off_x + off_y*p1 + off_z*
p*p1;
196 set_perm(0, offset, 1, 0);
198 offset = ndof_per_dim + off_x + off_y*
p + off_z*p1*
p;
199 set_perm(2, offset,
p, 0);
203 offset = 2*ndof_per_dim + off_x + off_y*
p + off_z*
p*
p;
204 set_perm(4, offset,
p*
p, 0);
213 if (type ==
H1 || type ==
L2)
226 if (pfes_ho && pfes_lor)
231 for (
int i=0; i<l_perm.
Size(); ++i)
234 int s = j < 0 ? -1 : 1;
238 if ((t_i < 0 && t_j >=0) || (t_j < 0 && t_i >= 0))
240 MFEM_ABORT(
"Inconsistent DOF numbering");
242 if (t_i < 0) {
continue; }
243 perm[t_i] = s < 0 ? -1 - t_j : t_j;
262 return type ==
H1 || type ==
L2;
267 MFEM_VERIFY(
A.
Ptr() != NULL,
"No LOR system assembled");
273 MFEM_VERIFY(
A.
Ptr() != NULL,
"No LOR system assembled");
291template <
typename FEC>
294 const FEC *fec =
dynamic_cast<const FEC*
>(fes.
FEColl());
297 int btype = fec->GetBasisType();
300 mfem::err <<
"\nWARNING: Constructing low-order refined "
301 <<
"discretization with basis type\n"
303 <<
"The LOR discretization is only spectrally equivalent\n"
304 <<
"with Gauss-Lobatto basis.\n" << std::endl;
309template <
typename FEC>
312 const FEC *fec =
dynamic_cast<const FEC*
>(fes.
FEColl());
315 int cbtype = fec->GetClosedBasisType();
316 int obtype = fec->GetOpenBasisType();
319 mfem::err <<
"\nWARNING: Constructing vector low-order refined "
320 <<
"discretization with basis type \npair ("
323 <<
"The LOR discretization is only spectrally\nequivalent "
324 <<
"with basis types (Gauss-Lobatto, IntegratedGLL).\n"
339 : irs(0,
Quadrature1D::GaussLobatto), ref_type(ref_type_), fes_ho(fes_ho_)
347 ir_el = &irs.
Get(geoms[0], 1);
443 :
LORBase(*a_ho_.FESpace(), ref_type_)
451 int ref_type_) :
LORBase(fes_ho, ref_type_)
464 for (
int i=0; i<refinements.
Size(); ++i)
479 MFEM_VERIFY(
A.
Ptr() !=
nullptr,
"No LOR system assembled");
487 int ref_type_) :
LORBase(*a_ho_.ParFESpace(), ref_type_)
507 "Cannot construct LOR operators on variable-order spaces");
525 MFEM_VERIFY(
A.
Ptr() !=
nullptr,
"No LOR system assembled");
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
static const char * Name(int b_type)
Check and convert a BasisType constant to a string identifier.
@ GaussLobatto
Closed type.
@ IntegratedGLL
Integrated GLL indicator functions.
Efficient batched assembly of LOR discretizations on device.
static bool FormIsSupported(BilinearForm &a)
Returns true if the form a supports batched assembly, false otherwise.
void Assemble(BilinearForm &a, const Array< int > ess_dofs, OperatorHandle &A)
Assemble the given form as a matrix and place the result in A.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
virtual FiniteElementCollection * Clone(int p) const
Instantiate a new collection of the same type with a different order.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
virtual void CopyProlongationAndRestriction(const FiniteElementSpace &fes, const Array< int > *perm)
Copies the prolongation and restriction matrices from fes.
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 ...
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
Ordering::Type GetOrdering() const
Return the ordering method.
int GetOrder(int i) const
Returns the polynomial degree of the i'th finite element.
const FiniteElementCollection * FEColl() const
Mesh * GetMesh() const
Returns the mesh.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
int GetVDim() const
Returns the vector dimension of the finite element space.
Abstract class for all finite elements.
static bool IsTensorProduct(Type geom)
static Type TensorProductGeometry(int dim)
Arbitrary order H1-conforming (continuous) finite elements.
Wrapper for hypre's ParCSR matrix class.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Arbitrary order "L2-conforming" discontinuous finite elements.
Abstract base class for LORDiscretization and ParLORDiscretization classes, which construct low-order...
LORBase(FiniteElementSpace &fes_ho_, int ref_type_)
Construct the LORBase object for the given FE space and refinement type.
int GetLOROrder() const
Returns the order of the LOR space. 1 for H1 or ND, 0 for L2 or RT.
void ConstructLocalDofPermutation(Array< int > &perm_) const
bool HasSameDofNumbering() const
void ConstructDofPermutation() const
void AssembleSystem(BilinearForm &a_ho, const Array< int > &ess_dofs)
Assembles the LOR system corresponding to a_ho.
FESpaceType GetFESpaceType() const
Returns the type of finite element space: H1, ND, RT or L2.
FiniteElementCollection * fec
void SetupProlongationAndRestriction()
class BatchedLORAssembly * batched_lor
FiniteElementSpace & fes_ho
virtual void FormLORSpace()=0
Construct the LOR space (overridden for serial and parallel versions).
const Array< int > & GetDofPermutation() const
Returns the permutation that maps LOR DOFs to high-order DOFs.
FiniteElementSpace & GetFESpace() const
Returns the low-order refined finite element space.
const OperatorHandle & GetAssembledSystem() const
Returns the assembled LOR system (const version).
void LegacyAssembleSystem(BilinearForm &a_ho, const Array< int > &ess_dofs)
Assembles the LOR system corresponding to a_ho using the legacy method.
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.
void FormLORSpace() override
Construct the LOR space (overridden for serial and parallel versions).
SparseMatrix & GetAssembledMatrix() const
Return the assembled LOR operator as a SparseMatrix.
void GetGeometries(int dim, Array< Geometry::Type > &el_geoms) const
Return all element geometries of the given dimension present in the mesh.
const CoarseFineTransformations & GetRefinementTransforms() const
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
static Mesh MakeRefined(Mesh &orig_mesh, int ref_factor, int ref_type)
Create a refined (by any factor) version of orig_mesh.
Geometry::Type GetElementBaseGeometry(int i) const
Arbitrary order H(curl)-conforming Nedelec finite elements.
Pointer to an Operator of a specified type.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get().
void SetType(Operator::Type tid)
Invoke Clear() and set a new type id.
Operator * Ptr() const
Access the underlying Operator pointer.
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged.
@ MFEM_SPARSEMAT
ID for class SparseMatrix.
@ Hypre_ParCSR
ID for class HypreParMatrix.
Abstract parallel finite element space.
int GetMaxElementOrder() const override
Returns the maximum polynomial order over all elements globally.
int GetLocalTDofNumber(int ldof) const
int GetTrueVSize() const override
Return the number of local vector true dofs.
ParMesh * GetParMesh() const
ParFiniteElementSpace & GetParFESpace() const
Return the LOR ParFiniteElementSpace.
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.
HypreParMatrix & GetAssembledMatrix() const
Return the assembled LOR operator as a HypreParMatrix.
void FormLORSpace() override
Construct the LOR space (overridden for serial and parallel versions).
Class for parallel meshes.
static ParMesh MakeRefined(ParMesh &orig_mesh, int ref_factor, int ref_type)
Create a uniformly refined (by any factor) version of orig_mesh.
A class container for 1D quadrature type constants.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
const int * ess_tdof_list
void CheckScalarBasisType(const FiniteElementSpace &fes)
MFEM_HOST_DEVICE int UnsignIndex(int i)
void CheckBasisType(const FiniteElementSpace &fes)
void CheckVectorBasisType(const FiniteElementSpace &fes)
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
real_t p(const Vector &x, real_t t)