22static void GetSigns(
const FiniteElementSpace &fes,
const FaceType type,
25 const Mesh &mesh = *fes.GetMesh();
26 const int dim = mesh.SpaceDimension();
29 for (
int f = 0;
f < mesh.GetNumFacesWithGhost(); ++
f)
31 Mesh::FaceInformation face = mesh.GetFaceInformation(
f);
32 face_id = face.element[0].local_face_id;
33 if (face.IsNonconformingCoarse())
39 else if ( face.IsOfFaceType(type) )
43 if (face_id==2 || face_id==3)
54 if (face_id==0 || face_id==3 || face_id==4)
71 : type(type_), nf(fes.GetNFbyType(type)), signs(nf),
79 GetSigns(*
fespace, type, signs);
88 return sfe !=
nullptr && tfe !=
nullptr && (
93template<const
int T_VDIM, const
int T_ND1D, const
int T_NQ1D>
105 const int eval_flags)
107 const int nd1d = maps.
ndof;
108 const int nq1d = maps.
nqpt;
109 const int ND1D = T_ND1D ? T_ND1D : nd1d;
110 const int NQ1D = T_NQ1D ? T_NQ1D : nq1d;
111 const int VDIM = T_VDIM ? T_VDIM : vdim;
114 MFEM_VERIFY(VDIM == 2 || !(eval_flags &
DETERMINANTS),
"");
118 auto sign = signs.
Read();
132 const int ND1D = T_ND1D ? T_ND1D : nd1d;
133 const int NQ1D = T_NQ1D ? T_NQ1D : nq1d;
134 const int VDIM = T_VDIM ? T_VDIM : vdim;
135 constexpr int max_ND1D = T_ND1D ? T_ND1D :
MAX_ND1D;
136 constexpr int max_VDIM = T_VDIM ? T_VDIM :
MAX_VDIM2D;
137 real_t r_F[max_ND1D][max_VDIM];
138 for (
int d = 0; d < ND1D; d++)
140 for (
int c = 0; c < VDIM; c++)
142 r_F[d][c] = F(d,c,
f);
145 for (
int q = 0; q < NQ1D; ++q)
150 for (
int c = 0; c < VDIM; c++) { ed[c] = 0.0; }
151 for (
int d = 0; d < ND1D; ++d)
154 for (
int c = 0; c < VDIM; c++) { ed[c] +=
b*r_F[d][c]; }
156 for (
int c = 0; c < VDIM; c++)
167 for (
int i = 0; i < VDIM; i++) { D[i] = 0.0; }
168 for (
int d = 0; d < ND1D; ++d)
171 for (
int c = 0; c < VDIM; c++)
179 for (
int c = 0; c < VDIM; c++)
195 const real_t norm = sqrt(D[0]*D[0]+D[1]*D[1]);
202 const real_t s = sign[
f] ? -1.0 : 1.0;
205 n(0,q,
f) = s*D[1]/
norm;
206 n(1,q,
f) = -s*D[0]/
norm;
210 n(q,0,
f) = s*D[1]/
norm;
211 n(q,1,
f) = -s*D[0]/
norm;
220template<const
int T_VDIM, const
int T_ND1D, const
int T_NQ1D>
232 const int eval_flags)
234 const int nd1d = maps.
ndof;
235 const int nq1d = maps.
nqpt;
236 const int ND1D = T_ND1D ? T_ND1D : nd1d;
237 const int NQ1D = T_NQ1D ? T_NQ1D : nq1d;
238 const int VDIM = T_VDIM ? T_VDIM : vdim;
241 MFEM_VERIFY(VDIM == 3 || !(eval_flags &
DETERMINANTS),
"");
244 auto F =
Reshape(e_vec.
Read(), ND1D, ND1D, VDIM, NF);
245 auto sign = signs.
Read();
258 constexpr int max_ND1D = T_ND1D ? T_ND1D :
MAX_ND1D;
259 constexpr int max_NQ1D = T_NQ1D ? T_NQ1D :
MAX_NQ1D;
260 constexpr int max_VDIM = T_VDIM ? T_VDIM :
MAX_VDIM3D;
261 real_t r_F[max_ND1D][max_ND1D][max_VDIM];
262 for (
int d1 = 0; d1 < ND1D; d1++)
264 for (
int d2 = 0; d2 < ND1D; d2++)
266 for (
int c = 0; c < VDIM; c++)
268 r_F[d1][d2][c] = F(d1,d2,c,
f);
274 real_t Bu[max_NQ1D][max_ND1D][max_VDIM];
275 for (
int d2 = 0; d2 < ND1D; ++d2)
277 for (
int q = 0; q < NQ1D; ++q)
279 for (
int c = 0; c < VDIM; c++) { Bu[q][d2][c] = 0.0; }
280 for (
int d1 = 0; d1 < ND1D; ++d1)
283 for (
int c = 0; c < VDIM; c++)
285 Bu[q][d2][c] +=
b*r_F[d1][d2][c];
290 real_t BBu[max_NQ1D][max_NQ1D][max_VDIM];
291 for (
int q2 = 0; q2 < NQ1D; ++q2)
293 for (
int q1 = 0; q1 < NQ1D; ++q1)
295 for (
int c = 0; c < VDIM; c++) { BBu[q2][q1][c] = 0.0; }
296 for (
int d2 = 0; d2 < ND1D; ++d2)
299 for (
int c = 0; c < VDIM; c++)
301 BBu[q2][q1][c] +=
b*Bu[q1][d2][c];
304 for (
int c = 0; c < VDIM; c++)
306 const real_t v = BBu[q2][q1][c];
318 real_t Gu[max_NQ1D][max_ND1D][max_VDIM];
319 real_t Bu[max_NQ1D][max_ND1D][max_VDIM];
320 for (
int d2 = 0; d2 < ND1D; ++d2)
322 for (
int q = 0; q < NQ1D; ++q)
324 for (
int c = 0; c < VDIM; c++)
329 for (
int d1 = 0; d1 < ND1D; ++d1)
333 for (
int c = 0; c < VDIM; c++)
335 const real_t u = r_F[d1][d2][c];
342 real_t BGu[max_NQ1D][max_NQ1D][max_VDIM];
343 real_t GBu[max_NQ1D][max_NQ1D][max_VDIM];
344 for (
int q2 = 0; q2 < NQ1D; ++q2)
346 for (
int q1 = 0; q1 < NQ1D; ++q1)
348 for (
int c = 0; c < VDIM; c++)
350 BGu[q2][q1][c] = 0.0;
351 GBu[q2][q1][c] = 0.0;
353 for (
int d2 = 0; d2 < ND1D; ++d2)
356 const real_t g = G(q2,d2);
357 for (
int c = 0; c < VDIM; c++)
359 BGu[q2][q1][c] +=
b*Gu[q1][d2][c];
360 GBu[q2][q1][c] += g*Bu[q1][d2][c];
367 for (
int c = 0; c < VDIM; c++)
369 for (
int q2 = 0; q2 < NQ1D; ++q2)
371 for (
int q1 = 0; q1 < NQ1D; ++q1)
375 der(c,0,q1,q2,
f) = BGu[q2][q1][c];
376 der(c,1,q1,q2,
f) = GBu[q2][q1][c];
380 der(q1,q2,c,0,
f) = BGu[q2][q1][c];
381 der(q1,q2,c,1,
f) = GBu[q2][q1][c];
387 if (VDIM == 3 && ((eval_flags &
NORMALS) ||
391 for (
int q2 = 0; q2 < NQ1D; ++q2)
393 for (
int q1 = 0; q1 < NQ1D; ++q1)
395 const real_t s = sign[
f] ? -1.0 : 1.0;
396 n[0] = s*( BGu[q2][q1][1]*GBu[q2][q1][2]-GBu[q2][q1][1]*
398 n[1] = s*(-BGu[q2][q1][0]*GBu[q2][q1][2]+GBu[q2][q1][0]*
400 n[2] = s*( BGu[q2][q1][0]*GBu[q2][q1][1]-GBu[q2][q1][0]*
402 const real_t norm = sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);
408 nor(0,q1,q2,
f) = n[0]/
norm;
409 nor(1,q1,q2,
f) = n[1]/
norm;
410 nor(2,q1,q2,
f) = n[2]/
norm;
414 nor(q1,q2,0,
f) = n[0]/
norm;
415 nor(q1,q2,1,
f) = n[1]/
norm;
416 nor(q1,q2,2,
f) = n[2]/
norm;
426template<const
int T_VDIM, const
int T_ND1D, const
int T_NQ1D>
438 const int eval_flags)
440 MFEM_PERF_SCOPE(
"FaceQuadInterpolator::SmemEval3D");
441 const int nd1d = maps.
ndof;
442 const int nq1d = maps.
nqpt;
443 const int ND1D = T_ND1D ? T_ND1D : nd1d;
444 const int NQ1D = T_NQ1D ? T_NQ1D : nq1d;
445 const int VDIM = T_VDIM ? T_VDIM : vdim;
448 MFEM_VERIFY(VDIM == 3 || !(eval_flags &
DETERMINANTS),
"");
451 auto F =
Reshape(e_vec.
Read(), ND1D, ND1D, VDIM, NF);
452 auto sign = signs.
Read();
466 constexpr int max_ND1D = T_ND1D ? T_ND1D :
MAX_ND1D;
467 constexpr int max_NQ1D = T_NQ1D ? T_NQ1D :
MAX_NQ1D;
468 constexpr int max_VDIM = T_VDIM ? T_VDIM :
MAX_VDIM3D;
470 MFEM_SHARED
real_t sm1[max_NQ1D*max_NQ1D*max_VDIM];
471 MFEM_SHARED
real_t sm2[max_NQ1D*max_ND1D*max_VDIM];
473 auto s_F = (
real_t(*)[max_ND1D][max_VDIM])sm1;
474 MFEM_FOREACH_THREAD(d1,x,ND1D)
476 MFEM_FOREACH_THREAD(d2,y,ND1D)
478 MFEM_FOREACH_THREAD(c,z,VDIM)
480 s_F[d1][d2][c] = F(d1,d2,c,
f);
488 auto Bu = (
real_t (*)[max_ND1D][max_VDIM])sm2;
489 MFEM_FOREACH_THREAD(d2,x,ND1D)
491 MFEM_FOREACH_THREAD(q1,y,NQ1D)
493 MFEM_FOREACH_THREAD(c,z,VDIM)
496 for (
int d1 = 0; d1 < ND1D; ++d1)
498 thrdBu += B(q1,d1)*s_F[d1][d2][c];
500 Bu[q1][d2][c] = thrdBu;
506 MFEM_FOREACH_THREAD(q2,x,NQ1D)
508 MFEM_FOREACH_THREAD(q1,y,NQ1D)
510 MFEM_FOREACH_THREAD(c,z,VDIM)
513 for (
int d2 = 0; d2 < ND1D; ++d2)
515 v += B(q2,d2)*Bu[q1][d2][c];
529 auto Gu = (
real_t (*)[max_ND1D][max_VDIM])sm2;
530 MFEM_SHARED
real_t Bu[max_NQ1D][max_ND1D][max_VDIM];
531 MFEM_FOREACH_THREAD(d2,x,ND1D)
533 MFEM_FOREACH_THREAD(q1,y,NQ1D)
535 MFEM_FOREACH_THREAD(c,z,VDIM)
539 for (
int d1 = 0; d1 < ND1D; ++d1)
541 const real_t u = s_F[d1][d2][c];
542 thrdBu += B(q1,d1)*
u;
543 thrdGu += G(q1,d1)*
u;
545 Gu[q1][d2][c] = thrdGu;
546 Bu[q1][d2][c] = thrdBu;
552 auto BGu = (
real_t (*)[max_NQ1D][max_VDIM])sm1;
553 MFEM_SHARED
real_t GBu[max_NQ1D][max_NQ1D][max_VDIM];
554 MFEM_FOREACH_THREAD(q2,x,NQ1D)
556 MFEM_FOREACH_THREAD(q1,y,NQ1D)
558 MFEM_FOREACH_THREAD(c,z,VDIM)
562 for (
int d2 = 0; d2 < ND1D; ++d2)
564 thrdBGu += B(q2,d2)*Gu[q1][d2][c];
565 thrdGBu += G(q2,d2)*Bu[q1][d2][c];
567 BGu[q2][q1][c] = thrdBGu;
568 GBu[q2][q1][c] = thrdGBu;
576 MFEM_FOREACH_THREAD(q2,x,NQ1D)
578 MFEM_FOREACH_THREAD(q1,y,NQ1D)
580 MFEM_FOREACH_THREAD(c,z,VDIM)
584 der(c,0,q1,q2,
f) = BGu[q2][q1][c];
585 der(c,1,q1,q2,
f) = GBu[q2][q1][c];
589 der(q1,q2,c,0,
f) = BGu[q2][q1][c];
590 der(q1,q2,c,1,
f) = GBu[q2][q1][c];
597 if (VDIM == 3 && ((eval_flags &
NORMALS) ||
601 MFEM_FOREACH_THREAD(q2,x,NQ1D)
603 MFEM_FOREACH_THREAD(q1,y,NQ1D)
605 if (MFEM_THREAD_ID(z) == 0)
607 const real_t s = sign[
f] ? -1.0 : 1.0;
608 n[0] = s*( BGu[q2][q1][1]*GBu[q2][q1][2]-GBu[q2][q1][1]*
610 n[1] = s*(-BGu[q2][q1][0]*GBu[q2][q1][2]+GBu[q2][q1][0]*
612 n[2] = s*( BGu[q2][q1][0]*GBu[q2][q1][1]-GBu[q2][q1][0]*
615 const real_t norm = sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);
623 nor(0,q1,q2,
f) = n[0]/
norm;
624 nor(1,q1,q2,
f) = n[1]/
norm;
625 nor(2,q1,q2,
f) = n[2]/
norm;
629 nor(q1,q2,0,
f) = n[0]/
norm;
630 nor(q1,q2,1,
f) = n[1]/
norm;
631 nor(q1,q2,2,
f) = n[2]/
norm;
643 const Vector &e_vec,
unsigned eval_flags,
646 if (nf == 0) {
return; }
652 const int nd1d = maps.
ndof;
653 const int nq1d = maps.
nqpt;
665 const int eval_flags) = NULL;
670 switch (10*nd1d + nq1d)
691 if (nq1d >= 10 || !eval_func)
698 switch (10*nd1d + nq1d)
718 if (nq1d >= 10 || !eval_func)
724 else if (vdim ==
dim)
728 switch (10*nd1d + nq1d)
746 if (nq1d >= 10 || !eval_func)
753 switch (10*nd1d + nq1d)
770 if (nq1d >= 10 || !eval_func)
778 eval_func(nf, vdim,
q_layout, maps, signs, e_vec,
779 q_val, q_der, q_det, q_nor, eval_flags);
783 MFEM_ABORT(
"case not supported yet");
790 Vector q_der, q_det, q_nor;
791 Mult(e_vec,
VALUES, q_val, q_der, q_det, q_nor);
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
@ GaussLobatto
Closed type.
@ Positive
Bernstein polynomials.
Structure representing the matrices/tensors needed to evaluate (in reference space) the values,...
Array< real_t > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
@ 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.
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
@ DERIVATIVES
Evaluate the derivatives at quadrature points.
@ DETERMINANTS
Assuming the derivative at quadrature points form a matrix, this flag can be used to compute and stor...
@ VALUES
Evaluate the values at quadrature points.
void Values(const Vector &e_vec, Vector &q_val) const
Interpolate the values of the E-vector e_vec at quadrature points.
static const int MAX_VDIM2D
const FiniteElementSpace * fespace
Not owned.
static const int MAX_NQ1D
static void Eval3D(const int NF, const int vdim, const QVectorLayout q_layout, const DofToQuad &maps, const Array< bool > &signs, const Vector &e_vec, Vector &q_val, Vector &q_der, Vector &q_det, Vector &q_nor, const int eval_flags)
Template compute kernel for 3D.
FaceQuadratureInterpolator(const FiniteElementSpace &fes, const IntegrationRule &ir, FaceType type)
QVectorLayout q_layout
Output Q-vector layout.
static const int MAX_VDIM3D
void Mult(const Vector &e_vec, unsigned eval_flags, Vector &q_val, Vector &q_der, Vector &q_det, Vector &q_nor) const
Interpolate the E-vector e_vec to quadrature points.
const IntegrationRule * IntRule
Not owned.
static bool SupportsFESpace(const FiniteElementSpace &fes)
Returns true if the given finite element space is supported by FaceQuadratureInterpolator.
static void SmemEval3D(const int NF, const int vdim, const QVectorLayout q_layout, const DofToQuad &maps, const Array< bool > &signs, const Vector &e_vec, Vector &q_val, Vector &q_der, Vector &q_det, Vector &q_nor, const int eval_flags)
static void Eval2D(const int NF, const int vdim, const QVectorLayout q_layout, const DofToQuad &maps, const Array< bool > &signs, const Vector &e_vec, Vector &q_val, Vector &q_der, Vector &q_det, Vector &q_nor, const int eval_flags)
Template compute kernel for 2D.
static const int MAX_ND1D
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
int GetNE() const
Returns number of elements in the mesh.
const FiniteElement * GetTypicalTraceElement() const
Return a "typical" trace element.
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...
Class for an integration rule - an Array of IntegrationPoint.
int Dimension() const
Dimension of the reference space used within the elements.
Class for finite elements with basis functions that return scalar values.
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
real_t u(const Vector &xvec)
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
std::function< void(const Vector &, Vector &)> f_vec(bool grad_div_problem)
void forall_3D(int N, int X, int Y, int Z, lambda &&body)
QVectorLayout
Type describing possible layouts for Q-vectors.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
void forall(int N, lambda &&body)
MFEM_HOST_DEVICE real_t norm(const Complex &z)