19template<
int T_D1D = 0, 
int T_Q1D = 0>
 
   20static void EAConvectionAssemble1D(
const int NE,
 
   21                                   const Array<real_t> &
b,
 
   22                                   const Array<real_t> &g,
 
   29   const int D1D = T_D1D ? T_D1D : d1d;
 
   30   const int Q1D = T_Q1D ? T_Q1D : q1d;
 
   33   auto B = 
Reshape(
b.Read(), Q1D, D1D);
 
   34   auto G = 
Reshape(g.Read(), Q1D, D1D);
 
   35   auto D = 
Reshape(padata.Read(), Q1D, NE);
 
   36   auto A = 
Reshape(eadata.ReadWrite(), D1D, D1D, NE);
 
   39      const int D1D = T_D1D ? T_D1D : d1d;
 
   40      const int Q1D = T_Q1D ? T_Q1D : q1d;
 
   41      constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
 
   44      for (
int q = 0; q < Q1D; q++)
 
   46         r_Gi[q] = G(q,MFEM_THREAD_ID(x));
 
   47         r_Bj[q] = B(q,MFEM_THREAD_ID(y));
 
   49      MFEM_FOREACH_THREAD(i1,x,D1D)
 
   51         MFEM_FOREACH_THREAD(j1,y,D1D)
 
   54            for (
int k1 = 0; k1 < Q1D; ++k1)
 
   56               val += r_Bj[k1] * D(k1, e) * r_Gi[k1];
 
   71template<
int T_D1D = 0, 
int T_Q1D = 0>
 
   72static void EAConvectionAssemble2D(
const int NE,
 
   73                                   const Array<real_t> &
b,
 
   74                                   const Array<real_t> &g,
 
   81   const int D1D = T_D1D ? T_D1D : d1d;
 
   82   const int Q1D = T_Q1D ? T_Q1D : q1d;
 
   85   auto B = 
Reshape(
b.Read(), Q1D, D1D);
 
   86   auto G = 
Reshape(g.Read(), Q1D, D1D);
 
   87   auto D = 
Reshape(padata.Read(), Q1D, Q1D, 2, NE);
 
   88   auto A = 
Reshape(eadata.ReadWrite(), D1D, D1D, D1D, D1D, NE);
 
   91      const int D1D = T_D1D ? T_D1D : d1d;
 
   92      const int Q1D = T_Q1D ? T_Q1D : q1d;
 
   93      constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
 
   94      constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
 
   97      for (
int d = 0; d < D1D; d++)
 
   99         for (
int q = 0; q < Q1D; q++)
 
  105      MFEM_SHARED 
real_t s_D[MQ1][MQ1][2];
 
  106      MFEM_FOREACH_THREAD(k1,x,Q1D)
 
  108         MFEM_FOREACH_THREAD(k2,y,Q1D)
 
  110            s_D[k1][k2][0] = D(k1,k2,0,e);
 
  111            s_D[k1][k2][1] = D(k1,k2,1,e);
 
  115      MFEM_FOREACH_THREAD(i1,x,D1D)
 
  117         MFEM_FOREACH_THREAD(i2,y,D1D)
 
  119            for (
int j1 = 0; j1 < D1D; ++j1)
 
  121               for (
int j2 = 0; j2 < D1D; ++j2)
 
  124                  for (
int k1 = 0; k1 < Q1D; ++k1)
 
  126                     for (
int k2 = 0; k2 < Q1D; ++k2)
 
  128                        val += (r_G[k1][i1] * r_B[k2][i2] * s_D[k1][k2][0]
 
  129                                + r_B[k1][i1] * r_G[k2][i2] * s_D[k1][k2][1])
 
  130                               * r_B[k1][j1]* r_B[k2][j2];
 
  135                     A(i1, i2, j1, j2, e) += val;
 
  139                     A(i1, i2, j1, j2, e) = val;
 
  148template<
int T_D1D = 0, 
int T_Q1D = 0>
 
  149static void EAConvectionAssemble3D(
const int NE,
 
  150                                   const Array<real_t> &
b,
 
  151                                   const Array<real_t> &g,
 
  152                                   const Vector &padata,
 
  158   const int D1D = T_D1D ? T_D1D : d1d;
 
  159   const int Q1D = T_Q1D ? T_Q1D : q1d;
 
  162   auto B = 
Reshape(
b.Read(), Q1D, D1D);
 
  163   auto G = 
Reshape(g.Read(), Q1D, D1D);
 
  164   auto D = 
Reshape(padata.Read(), Q1D, Q1D, Q1D, 3, NE);
 
  165   auto A = 
Reshape(eadata.ReadWrite(), D1D, D1D, D1D, D1D, D1D, D1D, NE);
 
  168      const int D1D = T_D1D ? T_D1D : d1d;
 
  169      const int Q1D = T_Q1D ? T_Q1D : q1d;
 
  170      constexpr int MD1 = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
 
  171      constexpr int MQ1 = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
 
  174      for (
int d = 0; d < D1D; d++)
 
  176         for (
int q = 0; q < Q1D; q++)
 
  182      MFEM_FOREACH_THREAD(i1,x,D1D)
 
  184         MFEM_FOREACH_THREAD(i2,y,D1D)
 
  186            MFEM_FOREACH_THREAD(i3,z,D1D)
 
  188               for (
int j1 = 0; j1 < D1D; ++j1)
 
  190                  for (
int j2 = 0; j2 < D1D; ++j2)
 
  192                     for (
int j3 = 0; j3 < D1D; ++j3)
 
  195                        for (
int k1 = 0; k1 < Q1D; ++k1)
 
  197                           for (
int k2 = 0; k2 < Q1D; ++k2)
 
  199                              for (
int k3 = 0; k3 < Q1D; ++k3)
 
  201                                 real_t D0 = D(k1,k2,k3,0,e);
 
  202                                 real_t D1 = D(k1,k2,k3,1,e);
 
  203                                 real_t D2 = D(k1,k2,k3,2,e);
 
  204                                 val += (r_G[k1][i1] * r_B[k2][i2] * r_B[k3][i3] * D0
 
  205                                         + r_B[k1][i1] * r_G[k2][i2] * r_B[k3][i3] * D1
 
  206                                         + r_B[k1][i1] * r_B[k2][i2] * r_G[k3][i3] * D2)
 
  207                                        * r_B[k1][j1] * r_B[k2][j2] * r_B[k3][j3];
 
  213                           A(i1, i2, i3, j1, j2, j3, e) += val;
 
  217                           A(i1, i2, i3, j1, j2, j3, e) = val;
 
  240         case 0x22: 
return EAConvectionAssemble1D<2,2>(
ne,B,G,
pa_data,ea_data,
add);
 
  241         case 0x33: 
return EAConvectionAssemble1D<3,3>(
ne,B,G,
pa_data,ea_data,
add);
 
  242         case 0x44: 
return EAConvectionAssemble1D<4,4>(
ne,B,G,
pa_data,ea_data,
add);
 
  243         case 0x55: 
return EAConvectionAssemble1D<5,5>(
ne,B,G,
pa_data,ea_data,
add);
 
  244         case 0x66: 
return EAConvectionAssemble1D<6,6>(
ne,B,G,
pa_data,ea_data,
add);
 
  245         case 0x77: 
return EAConvectionAssemble1D<7,7>(
ne,B,G,
pa_data,ea_data,
add);
 
  246         case 0x88: 
return EAConvectionAssemble1D<8,8>(
ne,B,G,
pa_data,ea_data,
add);
 
  247         case 0x99: 
return EAConvectionAssemble1D<9,9>(
ne,B,G,
pa_data,ea_data,
add);
 
  248         default:   
return EAConvectionAssemble1D(
ne,B,G,
pa_data,ea_data,
add,
 
  256         case 0x22: 
return EAConvectionAssemble2D<2,2>(
ne,B,G,
pa_data,ea_data,
add);
 
  257         case 0x33: 
return EAConvectionAssemble2D<3,3>(
ne,B,G,
pa_data,ea_data,
add);
 
  258         case 0x44: 
return EAConvectionAssemble2D<4,4>(
ne,B,G,
pa_data,ea_data,
add);
 
  259         case 0x55: 
return EAConvectionAssemble2D<5,5>(
ne,B,G,
pa_data,ea_data,
add);
 
  260         case 0x66: 
return EAConvectionAssemble2D<6,6>(
ne,B,G,
pa_data,ea_data,
add);
 
  261         case 0x77: 
return EAConvectionAssemble2D<7,7>(
ne,B,G,
pa_data,ea_data,
add);
 
  262         case 0x88: 
return EAConvectionAssemble2D<8,8>(
ne,B,G,
pa_data,ea_data,
add);
 
  263         case 0x99: 
return EAConvectionAssemble2D<9,9>(
ne,B,G,
pa_data,ea_data,
add);
 
  264         default:   
return EAConvectionAssemble2D(
ne,B,G,
pa_data,ea_data,
add,
 
  272         case 0x23: 
return EAConvectionAssemble3D<2,3>(
ne,B,G,
pa_data,ea_data,
add);
 
  273         case 0x34: 
return EAConvectionAssemble3D<3,4>(
ne,B,G,
pa_data,ea_data,
add);
 
  274         case 0x45: 
return EAConvectionAssemble3D<4,5>(
ne,B,G,
pa_data,ea_data,
add);
 
  275         case 0x56: 
return EAConvectionAssemble3D<5,6>(
ne,B,G,
pa_data,ea_data,
add);
 
  276         case 0x67: 
return EAConvectionAssemble3D<6,7>(
ne,B,G,
pa_data,ea_data,
add);
 
  277         case 0x78: 
return EAConvectionAssemble3D<7,8>(
ne,B,G,
pa_data,ea_data,
add);
 
  278         case 0x89: 
return EAConvectionAssemble3D<8,9>(
ne,B,G,
pa_data,ea_data,
add);
 
  279         default:   
return EAConvectionAssemble3D(
ne,B,G,
pa_data,ea_data,
add,
 
  283   MFEM_ABORT(
"Unknown kernel.");
 
 
const DofToQuad * maps
Not owned.
void AssemblePA(const FiniteElementSpace &) override
Method defining partial assembly.
void AssembleEA(const FiniteElementSpace &fes, Vector &emat, const bool add) override
Method defining element assembly.
Array< real_t > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
Array< real_t > B
Basis functions evaluated at quadrature points.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Mesh * GetMesh() const
Returns the mesh.
int GetNE() const
Returns number of elements.
void add(const Vector &v1, const Vector &v2, Vector &v)
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)
void forall_3D(int N, int X, int Y, int Z, lambda &&body)
static const DeviceDofQuadLimits & Get()
Return a const reference to the DeviceDofQuadLimits singleton.