12#ifndef MFEM_LIBCEED_MIXED_INTEGRATOR
13#define MFEM_LIBCEED_MIXED_INTEGRATOR
17#include <unordered_map>
27template <
typename CeedInteg>
31 using ElementKey = std::pair<int, int>;
34 std::size_t operator()(
const ElementKey& k)
const
36 return k.first + 2 * k.second;
39 using ElementsMap = std::unordered_map<const ElementKey, int*, key_hash>;
40 std::vector<CeedInteg*> sub_ops;
43 template <
typename Integrator,
typename CeedOperatorInfo,
typename CoeffType>
45 CeedOperatorInfo &info,
50 ElementsMap element_indices;
54 for (
int i = 0; i < fes.
GetNE(); i++)
57 auto value = count.find(key);
58 if (value == count.end())
60 count[key] =
new int(1);
69 for (
const auto& value : count )
71 element_indices[value.first] =
new int[*value.second];
72 offsets[value.first] =
new int(0);
76 for (
int i = 0; i < fes.
GetNE(); i++)
79 int &offset = *(offsets[key]);
80 int* indices_array = element_indices[key];
81 indices_array[offset] = i;
86 CeedCompositeOperatorCreate(internal::ceed, &
oper);
89 sub_ops.reserve(element_indices.size());
90 for (
const auto& value : element_indices)
92 const int* indices = value.second;
93 const int first_index = indices[0];
97 "Mixed mesh integrators should not have an"
100 auto sub_op =
new CeedInteg();
101 int nelem = *count[value.first];
102 sub_op->Assemble(info, fes, ir, nelem, indices, Q);
103 sub_ops.push_back(sub_op);
104 CeedCompositeOperatorAddSub(
oper, sub_op->GetCeedOperator());
108 CeedVectorCreate(internal::ceed, ndofs, &
u);
109 CeedVectorCreate(internal::ceed, ndofs, &
v);
114 for (
auto sub_op : sub_ops)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
int GetElementType(int i) const
Returns the type of element i.
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
int GetNE() const
Returns number of elements in the mesh.
int GetElementOrder(int i) const
Returns the order of the i'th finite element.
Mesh * GetMesh() const
Returns the mesh.
int GetVDim() const
Returns the vector dimension of the finite element space.
Abstract class for all finite elements.
Class for an integration rule - an Array of IntegrationPoint.
This base class implements some shared functionality between linear and nonlinear form integrators.
const IntegrationRule * GetIntRule() const
Directly return the IntRule pointer (possibly null) without checking for NURBS patch rules or falling...
void GetElementTransformation(int i, IsoparametricTransformation *ElTr) const
Builds the transformation defining the i-th element in ElTr. ElTr must be allocated in advance and wi...
This class wraps a ceed::PAIntegrator or ceed::MFIntegrator to support mixed finite element spaces.
virtual ~MixedIntegrator()
void Assemble(const Integrator &integ, CeedOperatorInfo &info, const mfem::FiniteElementSpace &fes, CoeffType *Q)
const IntegrationRule & GetRule(const Integrator &integ, const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans)