14 #include "../restriction.hpp" 15 #include "../pbilinearform.hpp" 16 #include "../../general/forall.hpp" 21 void 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->GetIntegrationRule();
33 if (ir) { integrator->SetIntegrationRule(*ir); }
37 void 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];
53 (a_to.*add_integrator_marker)(integrator, *(*markers[i]));
57 (a_to.*add_integrator)(integrator);
59 ir_map[integrator] = integrator->GetIntegrationRule();
60 if (ir) { integrator->SetIntegrationRule(*ir); }
64 void 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]]);
76 if (dynamic_cast<const H1_FECollection*>(fec_ho)) {
return H1; }
77 else if (dynamic_cast<const ND_FECollection*>(fec_ho)) {
return ND; }
78 else if (dynamic_cast<const RT_FECollection*>(fec_ho)) {
return RT; }
79 else if (dynamic_cast<const L2_FECollection*>(fec_ho)) {
return L2; }
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;
161 int idof_lor = vdof_lor[absdof(i)];
162 i = dofmap_ho[off_ho + i1*n1 + i2*n2];
163 int s2 = i < 0 ? -1 : 1;
164 int idof_ho = vdof_ho[absdof(i)];
165 int s3 = idof_lor < 0 ? -1 : 1;
166 int s4 = idof_ho < 0 ? -1 : 1;
169 perm_[absdof(idof_lor)] =
s < 0 ? -1-absdof(i) : absdof(i);
179 offset = off_x + off_y*
p + off_z*
p*p1;
180 set_perm(0, offset,
p,
p*p1);
182 offset = ndof_per_dim + off_x + off_y*(p1) + off_z*p1*
p;
183 set_perm(
dim == 2 ? 2 : 4, offset, 1,
p*p1);
187 offset = 2*ndof_per_dim + off_x + off_y*p1 + off_z*p1*p1;
188 set_perm(8, offset, 1,
p+1);
194 offset = off_x + off_y*p1 + off_z*
p*p1;
195 set_perm(0, offset, 1, 0);
197 offset = ndof_per_dim + off_x + off_y*
p + off_z*p1*
p;
198 set_perm(2, offset,
p, 0);
202 offset = 2*ndof_per_dim + off_x + off_y*
p + off_z*
p*
p;
203 set_perm(4, offset,
p*
p, 0);
212 if (type ==
H1 || type ==
L2)
225 if (pfes_ho && pfes_lor)
230 for (
int i=0; i<l_perm.
Size(); ++i)
233 int s = j < 0 ? -1 : 1;
237 if ((t_i < 0 && t_j >=0) || (t_j < 0 && t_i >= 0))
239 MFEM_ABORT(
"Inconsistent DOF numbering");
241 if (t_i < 0) {
continue; }
242 perm[t_i] =
s < 0 ? -1 - t_j : t_j;
261 return type ==
H1 || type ==
L2;
266 MFEM_VERIFY(
A.
Ptr() != NULL,
"No LOR system assembled");
272 MFEM_VERIFY(
A.
Ptr() != NULL,
"No LOR system assembled");
290 template <
typename FEC>
293 const FEC *fec =
dynamic_cast<const FEC*
>(fes.
FEColl());
296 int btype = fec->GetBasisType();
299 mfem::err <<
"\nWARNING: Constructing low-order refined " 300 <<
"discretization with basis type\n" 302 <<
"The LOR discretization is only spectrally equivalent\n" 303 <<
"with Gauss-Lobatto basis.\n" << std::endl;
308 template <
typename FEC>
311 const FEC *fec =
dynamic_cast<const FEC*
>(fes.
FEColl());
314 int cbtype = fec->GetClosedBasisType();
315 int obtype = fec->GetOpenBasisType();
318 mfem::err <<
"\nWARNING: Constructing vector low-order refined " 319 <<
"discretization with basis type \npair (" 322 <<
"The LOR discretization is only spectrally\nequivalent " 323 <<
"with basis types (Gauss-Lobatto, IntegratedGLL).\n" 331 CheckScalarBasisType<H1_FECollection>(fes);
332 CheckVectorBasisType<ND_FECollection>(fes);
333 CheckVectorBasisType<RT_FECollection>(fes);
338 : irs(0,
Quadrature1D::GaussLobatto), ref_type(ref_type_), fes_ho(fes_ho_)
346 ir_el = &irs.
Get(geoms[0], 1);
397 if (
auto *pfes = dynamic_cast<ParFiniteElementSpace*>(&fes_lor))
442 :
LORBase(*a_ho_.FESpace(), ref_type_)
450 int ref_type_) :
LORBase(fes_ho, ref_type_)
463 for (
int i=0; i<refinements.Size(); ++i)
478 MFEM_VERIFY(
A.
Ptr() !=
nullptr,
"No LOR system assembled");
486 int ref_type_) :
LORBase(*a_ho_.ParFESpace(), ref_type_)
506 "Cannot construct LOR operators on variable-order spaces");
524 MFEM_VERIFY(
A.
Ptr() !=
nullptr,
"No LOR system assembled");
533 #endif // MFEM_USE_MPI Abstract class for all finite elements.
class BatchedLORAssembly * batched_lor
Abstract base class for LORDiscretization and ParLORDiscretization classes, which construct low-order...
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...
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
static Type TensorProductGeometry(int dim)
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
Geometry::Type GetElementBaseGeometry(int i) const
static ParMesh MakeRefined(ParMesh &orig_mesh, int ref_factor, int ref_type)
Create a uniformly refined (by any factor) version of orig_mesh.
ParFiniteElementSpace & GetParFESpace() const
Return the LOR ParFiniteElementSpace.
void LegacyAssembleSystem(BilinearForm &a_ho, const Array< int > &ess_dofs)
Assembles the LOR system corresponding to a_ho using the legacy method.
int GetLOROrder() const
Returns the order of the LOR space. 1 for H1 or ND, 0 for L2 or RT.
Efficient batched assembly of LOR discretizations on device.
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.
Abstract parallel finite element space.
A class container for 1D quadrature type constants.
void FormLORSpace() override
Construct the LOR space (overridden for serial and parallel versions).
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.
static bool FormIsSupported(BilinearForm &a)
Returns true if the form a supports batched assembly, false otherwise.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
const Array< int > & GetDofPermutation() const
Returns the permutation that maps LOR DOFs to high-order DOFs.
void CheckScalarBasisType(const FiniteElementSpace &fes)
virtual FiniteElementCollection * Clone(int p) const
Instantiate a new collection of the same type with a different order.
ID for class SparseMatrix.
const OperatorHandle & GetAssembledSystem() const
Returns the assembled LOR system (const version).
int GetMaxElementOrder() const
Return the maximum polynomial order.
const FiniteElementCollection * FEColl() const
LORBase(FiniteElementSpace &fes_ho_, int ref_type_)
Construct the LORBase object for the given FE space and refinement type.
ParMesh * GetParMesh() const
void SetupProlongationAndRestriction()
void CheckBasisType(const FiniteElementSpace &fes)
virtual void FormLORSpace()=0
Construct the LOR space (overridden for serial and parallel versions).
bool HasSameDofNumbering() const
int GetVDim() const
Returns vector dimension.
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
HypreParMatrix & GetAssembledMatrix() const
Return the assembled LOR operator as a HypreParMatrix.
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Mesh * GetMesh() const
Returns the mesh.
double p(const Vector &x, double t)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
int GetOrder(int i) const
Returns the polynomial degree of the i'th finite element.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void Assemble(BilinearForm &a, const Array< int > ess_dofs, OperatorHandle &A)
Assemble the given form as a matrix and place the result in A.
int GetLocalTDofNumber(int ldof) const
void Clear()
Clear the OperatorHandle, deleting the held Operator (if owned), while leaving the type id unchanged...
void ConstructDofPermutation() const
const CoarseFineTransformations & GetRefinementTransforms()
void GetGeometries(int dim, Array< Geometry::Type > &el_geoms) const
Return all element geometries of the given dimension present in the mesh.
SparseMatrix & GetAssembledMatrix() const
Return the assembled LOR operator as a SparseMatrix.
Integrated GLL indicator functions.
int GetNE() const
Returns number of elements.
virtual int GetTrueVSize() const
Return the number of local vector true dofs.
static bool IsTensorProduct(Type geom)
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get()...
Ordering::Type GetOrdering() const
Return the ordering method.
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 corresponding to a_ho.
FESpaceType GetFESpaceType() const
Returns the type of finite element space: H1, ND, RT or L2.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
Operator * Ptr() const
Access the underlying Operator pointer.
void CheckVectorBasisType(const FiniteElementSpace &fes)
int Size() const
Return the logical size of the array.
ID for class HypreParMatrix.
FiniteElementSpace & GetFESpace() const
Returns the low-order refined finite element space.
void FormLORSpace() override
Construct the LOR space (overridden for serial and parallel versions).
void ConstructLocalDofPermutation(Array< int > &perm_) const
Wrapper for hypre's ParCSR matrix class.
Class for parallel meshes.
void SetType(Operator::Type tid)
Invoke Clear() and set a new type id.