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;
75 "Only elements with MapType VALUE and H_DIV are supported!");
92 "Only elements with MapType VALUE and H_DIV are supported!");
98namespace quadrature_interpolator
105static void Eval1D(
const int NE,
114 const int eval_flags)
118 const int nd = maps.
ndof;
119 const int nq = maps.
nqpt;
122 MFEM_VERIFY(vdim == 1 || !(eval_flags & QI::DETERMINANTS),
"");
123 MFEM_VERIFY(
bool(geom) ==
bool(eval_flags & QI::PHYSICAL_DERIVATIVES),
124 "'geom' must be given (non-null) only when evaluating physical"
128 const auto J =
Reshape(geom ? geom->
J.
Read() : nullptr, nq, NE);
129 const auto E =
Reshape(e_vec.
Read(), nd, vdim, NE);
139 for (
int q = 0; q < nq; ++q)
141 if (eval_flags & QI::VALUES)
143 for (
int c = 0; c < vdim; c++)
146 for (
int d = 0; d < nd; ++d)
148 q_val += B(q,d)*E(d,c,e);
154 if ((eval_flags & QI::DERIVATIVES) ||
155 (eval_flags & QI::PHYSICAL_DERIVATIVES) ||
156 (eval_flags & QI::DETERMINANTS))
158 for (
int c = 0; c < vdim; c++)
161 for (
int d = 0; d < nd; ++d)
163 q_d += G(q,d)*E(d,c,e);
165 if (eval_flags & QI::PHYSICAL_DERIVATIVES)
169 if (eval_flags & QI::DERIVATIVES || eval_flags & QI::PHYSICAL_DERIVATIVES)
174 if (vdim == 1 && (eval_flags & QI::DETERMINANTS))
188template<const
int T_VDIM, const
int T_ND, const
int T_NQ>
189static void Eval2D(
const int NE,
192 const GeometricFactors *geom,
193 const DofToQuad &maps,
198 const int eval_flags)
200 using QI = QuadratureInterpolator;
202 const int nd = maps.ndof;
203 const int nq = maps.nqpt;
204 const int ND = T_ND ? T_ND : nd;
205 const int NQ = T_NQ ? T_NQ : nq;
206 const int NMAX = NQ > ND ? NQ : ND;
207 const int VDIM = T_VDIM ? T_VDIM : vdim;
209 MFEM_ASSERT(!geom || geom->mesh->SpaceDimension() == 2,
"");
210 MFEM_VERIFY(ND <= QI::MAX_ND2D,
"");
211 MFEM_VERIFY(NQ <= QI::MAX_NQ2D,
"");
212 MFEM_VERIFY(
bool(geom) ==
bool(eval_flags & QI::PHYSICAL_DERIVATIVES),
213 "'geom' must be given (non-null) only when evaluating physical"
215 const auto B =
Reshape(maps.B.Read(), NQ, ND);
216 const auto G =
Reshape(maps.G.Read(), NQ, 2, ND);
217 const auto J =
Reshape(geom ? geom->J.Read() : nullptr, NQ, 2, 2, NE);
218 const auto E =
Reshape(e_vec.Read(), ND, VDIM, NE);
220 Reshape(q_val.Write(), NQ, VDIM, NE):
223 Reshape(q_der.Write(), NQ, VDIM, 2, NE):
225 auto det =
Reshape(q_det.Write(), NQ, NE);
228 const int ND = T_ND ? T_ND : nd;
229 const int NQ = T_NQ ? T_NQ : nq;
230 const int VDIM = T_VDIM ? T_VDIM : vdim;
231 constexpr int max_ND = T_ND ? T_ND : QI::MAX_ND2D;
232 constexpr int max_VDIM = T_VDIM ? T_VDIM : QI::MAX_VDIM2D;
233 MFEM_SHARED
real_t s_E[max_VDIM*max_ND];
234 MFEM_FOREACH_THREAD(d, x, ND)
236 for (
int c = 0; c < VDIM; c++)
238 s_E[c+d*VDIM] = E(d,c,e);
243 MFEM_FOREACH_THREAD(q, x, NQ)
245 if (eval_flags & QI::VALUES)
248 for (
int c = 0; c < VDIM; c++) { ed[c] = 0.0; }
249 for (
int d = 0; d < ND; ++d)
252 for (
int c = 0; c < VDIM; c++) { ed[c] +=
b*s_E[c+d*VDIM]; }
254 for (
int c = 0; c < VDIM; c++)
260 if ((eval_flags & QI::DERIVATIVES) ||
261 (eval_flags & QI::PHYSICAL_DERIVATIVES) ||
262 (eval_flags & QI::DETERMINANTS))
265 real_t D[QI::MAX_VDIM2D*2];
266 for (
int i = 0; i < 2*VDIM; i++) { D[i] = 0.0; }
267 for (
int d = 0; d < ND; ++d)
269 const real_t wx = G(q,0,d);
270 const real_t wy = G(q,1,d);
271 for (
int c = 0; c < VDIM; c++)
273 real_t s_e = s_E[c+d*VDIM];
274 D[c+VDIM*0] += s_e * wx;
275 D[c+VDIM*1] += s_e * wy;
278 if (eval_flags & QI::DERIVATIVES)
280 for (
int c = 0; c < VDIM; c++)
284 der(c,0,q,e) = D[c+VDIM*0];
285 der(c,1,q,e) = D[c+VDIM*1];
289 der(q,c,0,e) = D[c+VDIM*0];
290 der(q,c,1,e) = D[c+VDIM*1];
294 if (eval_flags & QI::PHYSICAL_DERIVATIVES)
297 Jloc[0] = J(q,0,0,e);
298 Jloc[1] = J(q,1,0,e);
299 Jloc[2] = J(q,0,1,e);
300 Jloc[3] = J(q,1,1,e);
302 for (
int c = 0; c < VDIM; c++)
305 const real_t v = D[c+VDIM*1];
306 const real_t JiU = Jinv[0]*
u + Jinv[1]*v;
307 const real_t JiV = Jinv[2]*
u + Jinv[3]*v;
320 if (eval_flags & QI::DETERMINANTS)
325 DeviceTensor<2> j(D, 3, 2);
326 const double E = j(0,0)*j(0,0) + j(1,0)*j(1,0) + j(2,0)*j(2,0);
327 const double F = j(0,0)*j(0,1) + j(1,0)*j(1,1) + j(2,0)*j(2,1);
328 const double G = j(0,1)*j(0,1) + j(1,1)*j(1,1) + j(2,1)*j(2,1);
329 det(q,e) = sqrt(E*G - F*F);
341template<const
int T_VDIM, const
int T_ND, const
int T_NQ>
342static void Eval3D(
const int NE,
345 const GeometricFactors *geom,
346 const DofToQuad &maps,
351 const int eval_flags)
353 using QI = QuadratureInterpolator;
355 const int nd = maps.ndof;
356 const int nq = maps.nqpt;
357 const int ND = T_ND ? T_ND : nd;
358 const int NQ = T_NQ ? T_NQ : nq;
359 const int NMAX = NQ > ND ? NQ : ND;
360 const int VDIM = T_VDIM ? T_VDIM : vdim;
362 MFEM_ASSERT(!geom || geom->mesh->SpaceDimension() == 3,
"");
363 MFEM_VERIFY(ND <= QI::MAX_ND3D,
"");
364 MFEM_VERIFY(NQ <= QI::MAX_NQ3D,
"");
365 MFEM_VERIFY(VDIM == 3 || !(eval_flags & QI::DETERMINANTS),
"");
366 MFEM_VERIFY(
bool(geom) ==
bool(eval_flags & QI::PHYSICAL_DERIVATIVES),
367 "'geom' must be given (non-null) only when evaluating physical"
369 const auto B =
Reshape(maps.B.Read(), NQ, ND);
370 const auto G =
Reshape(maps.G.Read(), NQ, 3, ND);
371 const auto J =
Reshape(geom ? geom->J.Read() : nullptr, NQ, 3, 3, NE);
372 const auto E =
Reshape(e_vec.Read(), ND, VDIM, NE);
374 Reshape(q_val.Write(), NQ, VDIM, NE):
377 Reshape(q_der.Write(), NQ, VDIM, 3, NE):
379 auto det =
Reshape(q_det.Write(), NQ, NE);
382 const int ND = T_ND ? T_ND : nd;
383 const int NQ = T_NQ ? T_NQ : nq;
384 const int VDIM = T_VDIM ? T_VDIM : vdim;
385 constexpr int max_ND = T_ND ? T_ND : QI::MAX_ND3D;
386 constexpr int max_VDIM = T_VDIM ? T_VDIM : QI::MAX_VDIM3D;
387 MFEM_SHARED
real_t s_E[max_VDIM*max_ND];
388 MFEM_FOREACH_THREAD(d, x, ND)
390 for (
int c = 0; c < VDIM; c++)
392 s_E[c+d*VDIM] = E(d,c,e);
397 MFEM_FOREACH_THREAD(q, x, NQ)
399 if (eval_flags & QI::VALUES)
402 for (
int c = 0; c < VDIM; c++) { ed[c] = 0.0; }
403 for (
int d = 0; d < ND; ++d)
406 for (
int c = 0; c < VDIM; c++) { ed[c] +=
b*s_E[c+d*VDIM]; }
408 for (
int c = 0; c < VDIM; c++)
414 if ((eval_flags & QI::DERIVATIVES) ||
415 (eval_flags & QI::PHYSICAL_DERIVATIVES) ||
416 (eval_flags & QI::DETERMINANTS))
419 real_t D[QI::MAX_VDIM3D*3];
420 for (
int i = 0; i < 3*VDIM; i++) { D[i] = 0.0; }
421 for (
int d = 0; d < ND; ++d)
423 const real_t wx = G(q,0,d);
424 const real_t wy = G(q,1,d);
425 const real_t wz = G(q,2,d);
426 for (
int c = 0; c < VDIM; c++)
428 real_t s_e = s_E[c+d*VDIM];
429 D[c+VDIM*0] += s_e * wx;
430 D[c+VDIM*1] += s_e * wy;
431 D[c+VDIM*2] += s_e * wz;
434 if (eval_flags & QI::DERIVATIVES)
436 for (
int c = 0; c < VDIM; c++)
440 der(c,0,q,e) = D[c+VDIM*0];
441 der(c,1,q,e) = D[c+VDIM*1];
442 der(c,2,q,e) = D[c+VDIM*2];
446 der(q,c,0,e) = D[c+VDIM*0];
447 der(q,c,1,e) = D[c+VDIM*1];
448 der(q,c,2,e) = D[c+VDIM*2];
452 if (eval_flags & QI::PHYSICAL_DERIVATIVES)
455 for (
int col = 0; col < 3; col++)
457 for (
int row = 0; row < 3; row++)
459 Jloc[row+3*col] = J(q,row,col,e);
463 for (
int c = 0; c < VDIM; c++)
466 const real_t v = D[c+VDIM*1];
467 const real_t w = D[c+VDIM*2];
468 const real_t JiU = Jinv[0]*
u + Jinv[1]*v + Jinv[2]*w;
469 const real_t JiV = Jinv[3]*
u + Jinv[4]*v + Jinv[5]*w;
470 const real_t JiW = Jinv[6]*
u + Jinv[7]*v + Jinv[8]*w;
485 if (VDIM == 3 && (eval_flags & QI::DETERMINANTS))
506 using namespace internal::quadrature_interpolator;
509 if (ne == 0) {
return; }
515 return MultHDiv(e_vec, eval_flags, q_val, q_der);
520 const bool use_tensor_eval =
529 const int nd = maps.
ndof;
530 const int nq = maps.
nqpt;
539 (
dim == 2 && vdim == 3),
"Invalid dimensions for determinants.");
542 "mixed meshes are not supported");
549 e_vec.
Read(), q_val.
Write(), vdim, nd, nq);
555 const int s_dim = phys ? sdim :
dim;
556 GradKernels::Run(
dim,
q_layout, phys, vdim, nd, nq, ne,
558 q_der.
Write(), s_dim, vdim, nd, nq);
562 DetKernels::Run(
dim, vdim, nd, nq, ne, maps.
B.
Read(),
570 geom, maps,e_vec, q_val,q_der,q_det,eval_flags);
580 if (ne == 0) {
return; }
582 "variable order spaces are not supported yet!");
585 "this method can be used only for H(div) spaces");
586 MFEM_VERIFY((eval_flags &
588 "only VALUES, PHYSICAL_VALUES, and PHYSICAL_MAGNITUDES"
589 " evaluations are implemented!");
592 MFEM_VERIFY((
dim == 2 ||
dim == 3) &&
dim == sdim,
593 "dim = " <<
dim <<
", sdim = " << sdim
594 <<
" is not supported yet!");
596 "mixed meshes are not supported yet!");
598 MFEM_VERIFY(vdim == 1,
"vdim != 1 is not supported yet!");
600 MFEM_VERIFY(tfe !=
nullptr,
"only quad and hex elements are supported!");
602 "non-tensor-product evaluation are not supported yet!");
608 const DofToQuad &maps_c = tfe->GetDofToQuad(*ir, mode);
609 const DofToQuad &maps_o = tfe->GetDofToQuadOpen(*ir, mode);
610 const int nd = maps_c.
ndof;
611 const int nq = maps_c.
nqpt;
622 "only one of VALUES, PHYSICAL_VALUES, and PHYSICAL_MAGNITUDES"
623 " can be requested at a time!");
624 const unsigned value_eval_mode =
632 TensorEvalHDivKernels::Run(
634 dim, q_l, value_eval_mode, nd, nq,
639 MFEM_CONTRACT_VAR(q_div);
647 MFEM_CONTRACT_VAR(eval_flags);
648 MFEM_CONTRACT_VAR(q_val);
649 MFEM_CONTRACT_VAR(q_der);
650 MFEM_CONTRACT_VAR(e_vec);
651 MFEM_ABORT(
"this method is not implemented yet");
687using namespace internal::quadrature_interpolator;
694template <QVectorLayout Q_LAYOUT>
695TensorEvalKernel FallbackTensorEvalKernel(
int DIM)
697 if (
DIM == 1) {
return Values1D<Q_LAYOUT>; }
698 else if (
DIM == 2) {
return Values2D<Q_LAYOUT>; }
699 else if (
DIM == 3) {
return Values3D<Q_LAYOUT>; }
700 else { MFEM_ABORT(
""); }
703template<QVectorLayout Q_LAYOUT,
bool GRAD_PHYS>
704GradKernel GetGradKernel(
int DIM)
706 if (
DIM == 1) {
return Derivatives1D<Q_LAYOUT, GRAD_PHYS>; }
707 else if (
DIM == 2) {
return Derivatives2D<Q_LAYOUT, GRAD_PHYS>; }
708 else if (
DIM == 3) {
return Derivatives3D<Q_LAYOUT, GRAD_PHYS>; }
709 else { MFEM_ABORT(
""); }
713template<QVectorLayout Q_LAYOUT>
714GradKernel GetGradKernel(
int DIM,
bool GRAD_PHYS)
716 if (GRAD_PHYS) {
return GetGradKernel<Q_LAYOUT, true>(
DIM); }
717 else {
return GetGradKernel<Q_LAYOUT, false>(
DIM); }
720template<QVectorLayout Q_LAYOUT,
bool GRAD_PHYS>
721CollocatedGradKernel GetCollocatedGradKernel(
int DIM)
723 if (
DIM == 1) {
return CollocatedDerivatives1D<Q_LAYOUT, GRAD_PHYS>; }
724 else if (
DIM == 2) {
return CollocatedDerivatives2D<Q_LAYOUT, GRAD_PHYS>; }
725 else if (
DIM == 3) {
return CollocatedDerivatives3D<Q_LAYOUT, GRAD_PHYS>; }
726 else { MFEM_ABORT(
""); }
729template<QVectorLayout Q_LAYOUT>
730CollocatedGradKernel GetCollocatedGradKernel(
int DIM,
bool GRAD_PHYS)
732 if (GRAD_PHYS) {
return GetCollocatedGradKernel<Q_LAYOUT, true>(
DIM); }
733 else {
return GetCollocatedGradKernel<Q_LAYOUT, false>(
DIM); }
737template <
int DIM,
int VDIM,
int ND,
int NQ>
738EvalKernel QuadratureInterpolator::EvalKernels::Kernel()
740 using namespace internal::quadrature_interpolator;
741 if (
DIM == 1) {
return Eval1D; }
742 else if (
DIM == 2) {
return Eval2D<VDIM,ND,NQ>; }
743 else if (
DIM == 3) {
return Eval3D<VDIM,ND,NQ>; }
744 else { MFEM_ABORT(
""); }
748EvalKernel GetEvalKernelVDimFallback(
int VDIM)
750 using EvalKernels = QuadratureInterpolator::EvalKernels;
751 if (VDIM == 1) {
return EvalKernels::Kernel<DIM,1,0,0>(); }
752 else if (VDIM == 2) {
return EvalKernels::Kernel<DIM,2,0,0>(); }
753 else if (VDIM == 3) {
return EvalKernels::Kernel<DIM,3,0,0>(); }
754 else { MFEM_ABORT(
""); }
757EvalKernel QuadratureInterpolator::EvalKernels::Fallback(
758 int DIM,
int VDIM,
int ND,
int NQ)
760 if (
DIM == 1) {
return GetEvalKernelVDimFallback<1>(VDIM); }
761 else if (
DIM == 2) {
return GetEvalKernelVDimFallback<2>(VDIM); }
762 else if (
DIM == 3) {
return GetEvalKernelVDimFallback<3>(VDIM); }
763 else { MFEM_ABORT(
""); }
766TensorEvalKernel QuadratureInterpolator::TensorEvalKernels::Fallback(
770 else {
return FallbackTensorEvalKernel<QVectorLayout::byVDIM>(
DIM); }
773GradKernel QuadratureInterpolator::GradKernels::Fallback(
777 else {
return GetGradKernel<QVectorLayout::byVDIM>(
DIM, GRAD_PHYS); }
780CollocatedGradKernel QuadratureInterpolator::CollocatedGradKernels::Fallback(
784 else {
return GetCollocatedGradKernel<QVectorLayout::byVDIM>(
DIM, GRAD_PHYS); }
791namespace quadrature_interpolator
793void InitEvalKernels()
795 using k = QuadratureInterpolator::EvalKernels;
797 k::Specialization<2,1,1,1>::Add();
798 k::Specialization<2,1,1,4>::Add();
800 k::Specialization<2,1,4,4>::Add();
801 k::Specialization<2,1,4,9>::Add();
803 k::Specialization<2,1,9,9>::Add();
804 k::Specialization<2,1,9,16>::Add();
806 k::Specialization<2,1,16,16>::Add();
807 k::Specialization<2,1,16,25>::Add();
808 k::Specialization<2,1,16,36>::Add();
810 k::Specialization<2,1,25,25>::Add();
811 k::Specialization<2,1,25,36>::Add();
812 k::Specialization<2,1,25,49>::Add();
813 k::Specialization<2,1,25,64>::Add();
817 k::Specialization<3,1,1,1>::Add();
818 k::Specialization<3,1,1,8>::Add();
820 k::Specialization<3,1,8,8>::Add();
821 k::Specialization<3,1,8,27>::Add();
823 k::Specialization<3,1,27,27>::Add();
824 k::Specialization<3,1,27,64>::Add();
826 k::Specialization<3,1,64,64>::Add();
827 k::Specialization<3,1,64,125>::Add();
828 k::Specialization<3,1,64,216>::Add();
830 k::Specialization<3,1,125,125>::Add();
831 k::Specialization<3,1,125,216>::Add();
835 k::Specialization<2,3,1,1>::Add();
836 k::Specialization<2,3,1,4>::Add();
838 k::Specialization<2,3,4,4>::Add();
839 k::Specialization<2,3,4,9>::Add();
841 k::Specialization<2,3,9,4>::Add();
842 k::Specialization<2,3,9,9>::Add();
843 k::Specialization<2,3,9,16>::Add();
844 k::Specialization<2,3,9,25>::Add();
846 k::Specialization<2,3,16,16>::Add();
847 k::Specialization<2,3,16,25>::Add();
848 k::Specialization<2,3,16,36>::Add();
850 k::Specialization<2,3,25,25>::Add();
851 k::Specialization<2,3,25,36>::Add();
852 k::Specialization<2,3,25,49>::Add();
853 k::Specialization<2,3,25,64>::Add();
857 k::Specialization<2,2,4,4>::Add();
858 k::Specialization<2,2,4,9>::Add();
860 k::Specialization<2,2,9,9>::Add();
861 k::Specialization<2,2,9,16>::Add();
863 k::Specialization<2,2,16,16>::Add();
864 k::Specialization<2,2,16,25>::Add();
865 k::Specialization<2,2,16,36>::Add();
867 k::Specialization<2,2,25,25>::Add();
868 k::Specialization<2,2,25,36>::Add();
869 k::Specialization<2,2,25,49>::Add();
870 k::Specialization<2,2,25,64>::Add();
874 k::Specialization<3,3,8,8>::Add();
875 k::Specialization<3,3,8,27>::Add();
877 k::Specialization<3,3,27,27>::Add();
878 k::Specialization<3,3,27,64>::Add();
879 k::Specialization<3,3,27,125>::Add();
881 k::Specialization<3,3,64,64>::Add();
882 k::Specialization<3,3,64,125>::Add();
883 k::Specialization<3,3,64,216>::Add();
885 k::Specialization<3,3,125,125>::Add();
886 k::Specialization<3,3,125,216>::Add();
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 J
Jacobians of the element transformations at all quadrature points.
Class for an integration rule - an Array of IntegrationPoint.
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...
void(*)(const int, const real_t *, const real_t *, const real_t *, real_t *, const int, const int, const int) CollocatedGradKernelType
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...
void(*)(const int, const int, const QVectorLayout, const GeometricFactors *, const DofToQuad &, const Vector &, Vector &, Vector &, Vector &, const int) EvalKernelType
QuadratureInterpolator(const FiniteElementSpace &fes, const IntegrationRule &ir)
void(*)(const int, const real_t *, const real_t *, const real_t *, const real_t *, real_t *, const int, const int, const int, const int) GradKernelType
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 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 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, const real_t *, const real_t *, real_t *, const int, const int, const int) TensorEvalKernelType
void Values(const Vector &e_vec, Vector &q_val) const
Interpolate the 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.
const IntegrationRule * IntRule
Not owned.
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.
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 void CalcInverse(const T *data, T *inv_data)
Return the inverse of a matrix with given size and data into the matrix with data inv_data.
MFEM_HOST_DEVICE T Det(const T *data)
Compute the determinant of a square matrix of size dim with given data.
real_t u(const Vector &xvec)
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.
void forall_2D(int N, int X, int Y, lambda &&body)
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)