12 #include "../general/forall.hpp"
19 template<
int T_D1D = 0,
int T_Q1D = 0>
20 static void EAConvectionAssemble1D(
const int NE,
21 const Array<double> &
b,
22 const Array<double> &g,
29 const int D1D = T_D1D ? T_D1D : d1d;
30 const int Q1D = T_Q1D ? T_Q1D : q1d;
31 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
32 MFEM_VERIFY(Q1D <=
MAX_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);
37 MFEM_FORALL_3D(e, NE, D1D, D1D, 1,
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 :
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];
71 template<
int T_D1D = 0,
int T_Q1D = 0>
72 static void EAConvectionAssemble2D(
const int NE,
73 const Array<double> &b,
74 const Array<double> &g,
81 const int D1D = T_D1D ? T_D1D : d1d;
82 const int Q1D = T_Q1D ? T_Q1D : q1d;
83 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
84 MFEM_VERIFY(Q1D <=
MAX_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);
89 MFEM_FORALL_3D(e, NE, D1D, D1D, 1,
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 :
MAX_D1D;
94 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
97 for (
int d = 0; d < D1D; d++)
99 for (
int q = 0; q < Q1D; q++)
105 MFEM_SHARED
double 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;
148 template<
int T_D1D = 0,
int T_Q1D = 0>
149 static void EAConvectionAssemble3D(
const int NE,
150 const Array<double> &b,
151 const Array<double> &g,
152 const Vector &padata,
158 const int D1D = T_D1D ? T_D1D : d1d;
159 const int Q1D = T_Q1D ? T_Q1D : q1d;
160 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
161 MFEM_VERIFY(Q1D <=
MAX_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);
166 MFEM_FORALL_3D(e, NE, D1D, D1D, D1D,
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 :
MAX_D1D;
171 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
172 double r_B[MQ1][MD1];
173 double r_G[MQ1][MD1];
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 double D0 = D(k1,k2,k3,0,e);
202 double D1 = D(k1,k2,k3,1,e);
203 double 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.");
int GetNE() const
Returns number of elements.
void add(const Vector &v1, const Vector &v2, Vector &v)
DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims...dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
virtual void AssembleEA(const FiniteElementSpace &fes, Vector &emat, const bool add)
Method defining element assembly.
Mesh * GetMesh() const
Returns the mesh.
virtual void AssemblePA(const FiniteElementSpace &)
Method defining partial assembly.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Array< double > B
Basis functions evaluated at quadrature points.
Array< double > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
const DofToQuad * maps
Not owned.