25namespace quadrature_interpolator
27void InitEvalByNodesKernels();
28void InitEvalByVDimKernels();
29void InitEvalKernels();
31template <
bool P>
void InitGradByNodesKernels();
32template <
bool P>
void InitGradByVDimKernels();
33void InitTensorEvalHDivKernels();
38 using namespace internal::quadrature_interpolator;
40 InitEvalByNodesKernels();
41 InitEvalByVDimKernels();
43 InitGradByNodesKernels<false>();
44 InitGradByVDimKernels<false>();
46 InitGradByNodesKernels<true>();
47 InitGradByVDimKernels<true>();
53 InitTensorEvalHDivKernels();
68 static internal::quadrature_interpolator::Kernels kernels;
74 "Only elements with MapType VALUE, INTEGRAL, or H_DIV are supported!");
90 "Only elements with MapType VALUE, INTEGRAL, or H_DIV are supported!");
106namespace quadrature_interpolator
113template <
bool Integral>
114void ImplEval1D(
const int NE,
const int vdim,
const QVectorLayout q_layout,
121 const int nd = maps.
ndof;
122 const int nq = maps.
nqpt;
125 MFEM_VERIFY(vdim == 1 || !(eval_flags & QI::DETERMINANTS),
"");
126 if constexpr(Integral)
128 MFEM_VERIFY(!(eval_flags & (QI::DERIVATIVES | QI::PHYSICAL_DERIVATIVES |
130 "Integral FE does not support computing derivatives");
132 const auto B_ = maps.
B.
Read();
133 const auto G_ = maps.
G.
Read();
134 const auto J =
Reshape(geom ? geom->
J.
Read() : nullptr, nq, NE);
135 const auto E_ = e_vec.
Read();
145 const auto B =
Reshape(B_, nq, nd);
146 const auto G =
Reshape(G_, nq, nd);
147 const auto E =
Reshape(E_, nd, vdim, NE);
148 const auto detJ =
Reshape(detJ_, nq, NE);
149 for (
int q = 0; q < nq; ++q)
151 if (eval_flags & (QI::VALUES | QI::PHYSICAL_VALUES))
153 for (
int c = 0; c < vdim; c++)
156 for (
int d = 0; d < nd; ++d)
158 q_val += B(q, d) * E(d, c, e);
160 if constexpr (Integral)
166 val(c, q, e) = q_val;
170 val(q, c, e) = q_val;
174 if ((eval_flags & QI::DERIVATIVES) ||
175 (eval_flags & QI::PHYSICAL_DERIVATIVES) ||
176 (eval_flags & QI::DETERMINANTS))
178 for (
int c = 0; c < vdim; c++)
181 for (
int d = 0; d < nd; ++d)
183 q_d += G(q, d) * E(d, c, e);
185 if (eval_flags & QI::PHYSICAL_DERIVATIVES)
189 if (eval_flags & QI::DERIVATIVES || eval_flags & QI::PHYSICAL_DERIVATIVES)
200 if (vdim == 1 && (eval_flags & QI::DETERMINANTS))
211ImplEval1D<true>(
const int NE,
const int vdim,
const QVectorLayout q_layout,
212 const real_t *detJ,
const GeometricFactors *geom,
213 const DofToQuad &maps,
const Vector &e_vec, Vector &q_val,
214 Vector &q_der, Vector &q_det,
const int eval_flags);
217ImplEval1D<false>(
const int NE,
const int vdim,
const QVectorLayout q_layout,
218 const real_t *detJ,
const GeometricFactors *geom,
219 const DofToQuad &maps,
const Vector &e_vec, Vector &q_val,
220 Vector &q_der, Vector &q_det,
const int eval_flags);
232 using namespace internal::quadrature_interpolator;
235 if (ne == 0) {
return; }
241 return MultHDiv(e_vec, eval_flags, q_val, q_der);
246 const bool use_tensor_eval =
255 const int nd = maps.
ndof;
256 const int nq = maps.
nqpt;
275 (
dim == 2 && vdim == 3) || (
dim == 1 && vdim == 2) ||
276 (
dim == 1 && vdim == 3),
"Invalid dimensions for determinants.");
279 "mixed meshes are not supported");
287 IntTensorEvalKernels::Run(
dim,
q_layout, vdim, nd, nq, ne,
289 e_vec.
Read(), q_val.
Write(), vdim, nd, nq);
293 TensorEvalKernels::Run(
dim,
q_layout, vdim, nd, nq, ne,
302 const int s_dim = phys ? sdim :
dim;
309 GradKernels::Run(
dim,
q_layout, phys, vdim, nd, nq, ne,
311 q_der.
Write(), s_dim, vdim, nd, nq);
322 DetKernels::Run(
dim, vdim, nd, nq, ne, maps.
B.
Read(), maps.
G.
Read(),
331 IntEvalKernels::Run(
dim, vdim, maps.
ndof, maps.
nqpt, ne, vdim,
333 q_val, q_der, q_det, eval_flags);
338 geom, maps, e_vec, q_val, q_der, q_det, eval_flags);
349 if (ne == 0) {
return; }
351 "variable order spaces are not supported yet!");
354 "this method can be used only for H(div) spaces");
355 MFEM_VERIFY((eval_flags &
357 "only VALUES, PHYSICAL_VALUES, and PHYSICAL_MAGNITUDES"
358 " evaluations are implemented!");
361 MFEM_VERIFY((
dim == 2 ||
dim == 3) &&
dim == sdim,
362 "dim = " <<
dim <<
", sdim = " << sdim
363 <<
" is not supported yet!");
365 "mixed meshes are not supported yet!");
367 MFEM_VERIFY(vdim == 1,
"vdim != 1 is not supported yet!");
369 MFEM_VERIFY(tfe !=
nullptr,
"only quad and hex elements are supported!");
371 "non-tensor-product evaluation are not supported yet!");
377 const DofToQuad &maps_c = tfe->GetDofToQuad(*ir, mode);
378 const DofToQuad &maps_o = tfe->GetDofToQuadOpen(*ir, mode);
379 const int nd = maps_c.
ndof;
380 const int nq = maps_c.
nqpt;
391 "only one of VALUES, PHYSICAL_VALUES, and PHYSICAL_MAGNITUDES"
392 " can be requested at a time!");
393 const unsigned value_eval_mode =
401 TensorEvalHDivKernels::Run(
403 dim, q_l, value_eval_mode, nd, nq,
408 MFEM_CONTRACT_VAR(q_div);
416 MFEM_CONTRACT_VAR(eval_flags);
417 MFEM_CONTRACT_VAR(q_val);
418 MFEM_CONTRACT_VAR(q_der);
419 MFEM_CONTRACT_VAR(e_vec);
420 MFEM_ABORT(
"this method is not implemented yet");
463using namespace internal::quadrature_interpolator;
465template <QVectorLayout Q_LAYOUT>
auto IntFallbackTensorEvalKernel(
int DIM)
469 return ImplValues1D<Q_LAYOUT, true>;
473 return ImplValues2D<Q_LAYOUT, true>;
477 return ImplValues3D<Q_LAYOUT, true>;
482template <QVectorLayout Q_LAYOUT>
auto FallbackTensorEvalKernel(
int DIM)
486 return Values1D<Q_LAYOUT>;
490 return Values2D<Q_LAYOUT>;
494 return Values3D<Q_LAYOUT>;
499template <QVectorLayout Q_LAYOUT,
bool GRAD_PHYS>
auto GetGradKernel(
int DIM)
501 if (
DIM == 1) {
return Derivatives1D<Q_LAYOUT, GRAD_PHYS>; }
502 else if (
DIM == 2) {
return Derivatives2D<Q_LAYOUT, GRAD_PHYS>; }
503 else if (
DIM == 3) {
return Derivatives3D<Q_LAYOUT, GRAD_PHYS>; }
504 else { MFEM_ABORT(
""); }
507template <QVectorLayout Q_LAYOUT>
auto GetGradKernel(
int DIM,
bool GRAD_PHYS)
509 if (GRAD_PHYS) {
return GetGradKernel<Q_LAYOUT, true>(
DIM); }
510 else {
return GetGradKernel<Q_LAYOUT, false>(
DIM); }
513template<QVectorLayout Q_LAYOUT,
bool GRAD_PHYS>
514auto GetCollocatedGradKernel(
int DIM)
518 return CollocatedDerivatives1D<Q_LAYOUT, GRAD_PHYS>;
522 return CollocatedDerivatives2D<Q_LAYOUT, GRAD_PHYS>;
526 return CollocatedDerivatives3D<Q_LAYOUT, GRAD_PHYS>;
531template <QVectorLayout Q_LAYOUT>
532auto GetCollocatedGradKernel(
int DIM,
bool GRAD_PHYS)
534 if (GRAD_PHYS) {
return GetCollocatedGradKernel<Q_LAYOUT, true>(
DIM); }
535 else {
return GetCollocatedGradKernel<Q_LAYOUT, false>(
DIM); }
538auto GetCollocatedGradKernel(
int DIM,
bool GRAD_PHYS,
QVectorLayout Q_LAYOUT)
542 return GetCollocatedGradKernel<QVectorLayout::byNODES>(
547 return GetCollocatedGradKernel<QVectorLayout::byVDIM>(
553template <
int DIM,
bool Integral>
554auto GetEvalKernelVDimFallback(
int VDIM)
556 if constexpr (Integral)
558 using EvalKernels = QuadratureInterpolator::IntEvalKernels;
561 return EvalKernels::Kernel<DIM, 1, 0, 0>();
565 return EvalKernels::Kernel<DIM, 2, 0, 0>();
569 return EvalKernels::Kernel<DIM, 3, 0, 0>();
572 if constexpr (!Integral)
574 using EvalKernels = QuadratureInterpolator::EvalKernels;
577 return EvalKernels::Kernel<DIM, 1, 0, 0>();
581 return EvalKernels::Kernel<DIM, 2, 0, 0>();
585 return EvalKernels::Kernel<DIM, 3, 0, 0>();
591template auto GetEvalKernelVDimFallback<1, true>(
int VDIM);
592template auto GetEvalKernelVDimFallback<1, false>(
int VDIM);
593template auto GetEvalKernelVDimFallback<2, true>(
int VDIM);
594template auto GetEvalKernelVDimFallback<2, false>(
int VDIM);
595template auto GetEvalKernelVDimFallback<3, true>(
int VDIM);
596template auto GetEvalKernelVDimFallback<3, false>(
int VDIM);
599QuadratureInterpolator::IntEvalKernels::Fallback(
int DIM,
int VDIM,
int ND,
604 return GetEvalKernelVDimFallback<1, true>(VDIM);
608 return GetEvalKernelVDimFallback<2, true>(VDIM);
612 return GetEvalKernelVDimFallback<3, true>(VDIM);
621QuadratureInterpolator::EvalKernels::Fallback(
int DIM,
int VDIM,
int ND,
int NQ)
625 return GetEvalKernelVDimFallback<1, false>(VDIM);
629 return GetEvalKernelVDimFallback<2, false>(VDIM);
633 return GetEvalKernelVDimFallback<3, false>(VDIM);
642QuadratureInterpolator::IntTensorEvalKernels::Fallback(
int DIM,
648 return IntFallbackTensorEvalKernel<QVectorLayout::byNODES>(
DIM);
652 return IntFallbackTensorEvalKernel<QVectorLayout::byVDIM>(
DIM);
657QuadratureInterpolator::TensorEvalKernels::Fallback(
int DIM,
663 return FallbackTensorEvalKernel<QVectorLayout::byNODES>(
DIM);
667 return FallbackTensorEvalKernel<QVectorLayout::byVDIM>(
DIM);
672QuadratureInterpolator::GradKernels::Fallback(
int DIM,
QVectorLayout Q_LAYOUT,
673 bool GRAD_PHYS,
int,
int,
int)
676 else {
return GetGradKernel<QVectorLayout::byVDIM>(
DIM, GRAD_PHYS); }
680QuadratureInterpolator::CollocatedGradKernels::Fallback(
int DIM,
685 return GetCollocatedGradKernel(
DIM, GRAD_PHYS, Q_LAYOUT);
692namespace quadrature_interpolator
694void InitEvalKernels()
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Structure representing the matrices/tensors needed to evaluate (in reference space) the values,...
Mode mode
Describes the contents of the B, Bt, G, and Gt arrays, see Mode.
Array< real_t > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
Mode
Type of data stored in the arrays B, Bt, G, and Gt.
@ FULL
Full multidimensional representation which does not use tensor product structure. The ordering of the...
@ TENSOR
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Array< real_t > B
Basis functions evaluated at quadrature points.
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number.
const class FiniteElement * FE
The FiniteElement that created and owns this object.
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
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 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.
Mesh * GetMesh() const
Returns the mesh.
int GetVDim() const
Returns the vector dimension of the finite element space.
const FiniteElement * GetTypicalFE() const
Return GetFE(0) if the local mesh is not empty; otherwise return a typical FE based on the Geometry t...
Abstract class for all finite elements.
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
int GetDim() const
Returns the reference space dimension for the finite element.
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
Structure for storing mesh geometric factors: coordinates, Jacobians, and determinants of the Jacobia...
Vector detJ
Determinants of the Jacobians at all quadrature points.
Vector J
Jacobians of the element transformations at all quadrature points.
Class for an integration rule - an Array of IntegrationPoint.
bool IsMixedMesh() const
Returns true if the mesh is a mixed mesh, false otherwise.
int Dimension() const
Dimension of the reference space used within the elements.
int SpaceDimension() const
Dimension of the physical space containing the mesh.
const GeometricFactors * GetGeometricFactors(const IntegrationRule &ir, const int flags, MemoryType d_mt=MemoryType::DEFAULT)
Return the mesh geometric factors corresponding to the given integration rule.
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
A class that performs interpolation from an E-vector to quadrature point values and/or derivatives (Q...
bool use_tensor_products
Tensor product evaluation mode.
@ VALUES
Evaluate the values at quadrature points.
@ DERIVATIVES
Evaluate the derivatives at quadrature points.
@ PHYSICAL_DERIVATIVES
Evaluate the physical derivatives.
@ DETERMINANTS
Assuming the derivative at quadrature points form a matrix, this flag can be used to compute and stor...
QuadratureInterpolator(const FiniteElementSpace &fes, const IntegrationRule &ir)
void Mult(const Vector &e_vec, unsigned eval_flags, Vector &q_val, Vector &q_der, Vector &q_det) const
Interpolate the E-vector e_vec to quadrature points.
void(*)(const int ne, const real_t *B, const real_t *e_vec, real_t *q_val, const int vdim, const int nd, const int nq) TensorEvalKernelType
void Determinants(const Vector &e_vec, Vector &q_det) const
Compute the determinants of the derivatives (with respect to reference coordinates) of the E-vector e...
void(*)(const int ne, const real_t *B, const real_t *G, const real_t *J, const real_t *e_vec, real_t *q_der, const int s_dim, const int v_dim, const int nd, const int nq) GradKernelType
void MultTranspose(unsigned eval_flags, const Vector &q_val, const Vector &q_der, Vector &e_vec) const
Perform the transpose operation of Mult(). (TODO)
void(*)(const int NE, const int vdim, const QVectorLayout q_layout, const GeometricFactors *geom, const DofToQuad &maps, const Vector &e_vec, Vector &q_val, Vector &q_der, Vector &q_det, const int eval_flags) EvalKernelType
void(*)(const int NE, const int vdim, const QVectorLayout q_layout, const real_t *detJ, const GeometricFactors *geom, const DofToQuad &maps, const Vector &e_vec, Vector &q_val, Vector &q_der, Vector &q_det, const int eval_flags) IntEvalKernelType
void Values(const Vector &e_vec, Vector &q_val) const
Interpolate the values of the E-vector e_vec at quadrature points.
void PhysValues(const Vector &e_vec, Vector &q_val) const
Interpolate the physical values of the E-vector e_vec at quadrature points.
void Derivatives(const Vector &e_vec, Vector &q_der) const
Interpolate the derivatives (with respect to reference coordinates) of the E-vector e_vec at quadratu...
QVectorLayout q_layout
Output Q-vector layout.
void PhysDerivatives(const Vector &e_vec, Vector &q_der) const
Interpolate the derivatives in physical space of the E-vector e_vec at quadrature points.
static bool SupportsFESpace(const FiniteElementSpace &fespace)
Returns true if the given finite element space is supported by QuadratureInterpolator.
static void AddEvalSpecializations()
Adds specializations for EvalKernels.
const IntegrationRule * IntRule
Not owned.
void(*)(const int ne, const real_t *B, const real_t *detJ, const real_t *e_vec, real_t *q_val, const int vdim, const int nd, const int nq) IntTensorEvalKernelType
Vector d_buffer
Auxiliary device buffer.
const FiniteElementSpace * fespace
Not owned.
const QuadratureSpace * qspace
Not owned.
void MultHDiv(const Vector &e_vec, unsigned eval_flags, Vector &q_val, Vector &q_div) const
Auxiliary method called by Mult() when using H(div)-conforming space.
void(*)(const int ne, const real_t *G, const real_t *J, const real_t *e_vec, real_t *q_der, const int sdim, const int vdim, const int d1d) CollocatedGradKernelType
Class representing the storage layout of a QuadratureFunction.
const IntegrationRule & GetElementIntRule(int idx) const
Get the IntegrationRule associated with mesh element idx.
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
MFEM_HOST_DEVICE T det(const tensor< T, 1, 1 > &A)
Returns the determinant of a matrix.
T * Write(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for write access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
SchrodingerBaseKernels< ParMesh, ParFiniteElementSpace, ParComplexGridFunction, ParGridFunction, ParBilinearForm, ParMixedBilinearForm, ParLinearForm > Kernels
bool UsesTensorBasis(const FiniteElementSpace &fes)
Return true if the mesh contains only one topology and the elements are tensor elements.
QVectorLayout
Type describing possible layouts for Q-vectors.
void forall(int N, lambda &&body)