12 #include "../general/forall.hpp"
19 static void EADGTraceAssemble1DInt(
const int NF,
20 const Array<double> &basis,
26 auto D =
Reshape(padata.Read(), 2, 2, NF);
27 auto A_int =
Reshape(eadata_int.ReadWrite(), 2, NF);
28 auto A_ext =
Reshape(eadata_ext.ReadWrite(), 2, NF);
31 double val_int0, val_int1, val_ext01, val_ext10;
32 val_int0 = D(0, 0,
f);
33 val_ext10 = D(1, 0,
f);
34 val_ext01 = D(0, 1,
f);
35 val_int1 = D(1, 1,
f);
38 A_int(0,
f) += val_int0;
39 A_int(1,
f) += val_int1;
40 A_ext(0,
f) += val_ext01;
41 A_ext(1,
f) += val_ext10;
45 A_int(0,
f) = val_int0;
46 A_int(1,
f) = val_int1;
47 A_ext(0,
f) = val_ext01;
48 A_ext(1,
f) = val_ext10;
53 static void EADGTraceAssemble1DBdr(
const int NF,
54 const Array<double> &basis,
59 auto D =
Reshape(padata.Read(), 2, 2, NF);
60 auto A_bdr =
Reshape(eadata_bdr.ReadWrite(), NF);
65 A_bdr(
f) += D(0, 0,
f);
69 A_bdr(
f) = D(0, 0,
f);
74 template<
int T_D1D = 0,
int T_Q1D = 0>
75 static void EADGTraceAssemble2DInt(
const int NF,
76 const Array<double> &basis,
84 const int D1D = T_D1D ? T_D1D : d1d;
85 const int Q1D = T_Q1D ? T_Q1D : q1d;
86 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
87 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
88 auto B =
Reshape(basis.Read(), Q1D, D1D);
89 auto D =
Reshape(padata.Read(), Q1D, 2, 2, NF);
90 auto A_int =
Reshape(eadata_int.ReadWrite(), D1D, D1D, 2, NF);
91 auto A_ext =
Reshape(eadata_ext.ReadWrite(), D1D, D1D, 2, NF);
92 MFEM_FORALL_3D(
f, NF, D1D, D1D, 1,
94 const int D1D = T_D1D ? T_D1D : d1d;
95 const int Q1D = T_Q1D ? T_Q1D : q1d;
96 MFEM_FOREACH_THREAD(i1,x,D1D)
98 MFEM_FOREACH_THREAD(j1,y,D1D)
100 double val_int0 = 0.0;
101 double val_int1 = 0.0;
102 double val_ext01 = 0.0;
103 double val_ext10 = 0.0;
104 for (
int k1 = 0; k1 < Q1D; ++k1)
106 val_int0 += B(k1,i1) * B(k1,j1) * D(k1, 0, 0,
f);
107 val_ext01 += B(k1,i1) * B(k1,j1) * D(k1, 0, 1,
f);
108 val_ext10 += B(k1,i1) * B(k1,j1) * D(k1, 1, 0,
f);
109 val_int1 += B(k1,i1) * B(k1,j1) * D(k1, 1, 1,
f);
113 A_int(i1, j1, 0,
f) += val_int0;
114 A_int(i1, j1, 1,
f) += val_int1;
115 A_ext(i1, j1, 0,
f) += val_ext01;
116 A_ext(i1, j1, 1,
f) += val_ext10;
120 A_int(i1, j1, 0,
f) = val_int0;
121 A_int(i1, j1, 1,
f) = val_int1;
122 A_ext(i1, j1, 0,
f) = val_ext01;
123 A_ext(i1, j1, 1,
f) = val_ext10;
130 template<
int T_D1D = 0,
int T_Q1D = 0>
131 static void EADGTraceAssemble2DBdr(
const int NF,
132 const Array<double> &basis,
133 const Vector &padata,
139 const int D1D = T_D1D ? T_D1D : d1d;
140 const int Q1D = T_Q1D ? T_Q1D : q1d;
141 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
142 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
143 auto B =
Reshape(basis.Read(), Q1D, D1D);
144 auto D =
Reshape(padata.Read(), Q1D, 2, 2, NF);
145 auto A_bdr =
Reshape(eadata_bdr.ReadWrite(), D1D, D1D, NF);
146 MFEM_FORALL_3D(
f, NF, D1D, D1D, 1,
148 const int D1D = T_D1D ? T_D1D : d1d;
149 const int Q1D = T_Q1D ? T_Q1D : q1d;
150 MFEM_FOREACH_THREAD(i1,x,D1D)
152 MFEM_FOREACH_THREAD(j1,y,D1D)
154 double val_bdr = 0.0;
155 for (
int k1 = 0; k1 < Q1D; ++k1)
157 val_bdr += B(k1,i1) * B(k1,j1) * D(k1, 0, 0,
f);
161 A_bdr(i1, j1,
f) += val_bdr;
165 A_bdr(i1, j1,
f) = val_bdr;
172 template<
int T_D1D = 0,
int T_Q1D = 0>
173 static void EADGTraceAssemble3DInt(
const int NF,
174 const Array<double> &basis,
175 const Vector &padata,
182 const int D1D = T_D1D ? T_D1D : d1d;
183 const int Q1D = T_Q1D ? T_Q1D : q1d;
184 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
185 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
186 auto B =
Reshape(basis.Read(), Q1D, D1D);
187 auto D =
Reshape(padata.Read(), Q1D, Q1D, 2, 2, NF);
188 auto A_int =
Reshape(eadata_int.ReadWrite(), D1D, D1D, D1D, D1D, 2, NF);
189 auto A_ext =
Reshape(eadata_ext.ReadWrite(), D1D, D1D, D1D, D1D, 2, NF);
190 MFEM_FORALL_3D(
f, NF, D1D, D1D, 1,
192 const int D1D = T_D1D ? T_D1D : d1d;
193 const int Q1D = T_Q1D ? T_Q1D : q1d;
194 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
195 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
196 double r_B[MQ1][MD1];
197 for (
int d = 0; d < D1D; d++)
199 for (
int q = 0; q < Q1D; q++)
204 MFEM_SHARED
double s_D[MQ1][MQ1][2][2];
205 for (
int i=0; i < 2; i++)
207 for (
int j=0; j < 2; j++)
209 MFEM_FOREACH_THREAD(k1,x,Q1D)
211 MFEM_FOREACH_THREAD(k2,y,Q1D)
213 s_D[k1][k2][i][j] = D(k1,k2,i,j,
f);
219 MFEM_FOREACH_THREAD(i1,x,D1D)
221 MFEM_FOREACH_THREAD(i2,y,D1D)
223 for (
int j1 = 0; j1 < D1D; ++j1)
225 for (
int j2 = 0; j2 < D1D; ++j2)
227 double val_int0 = 0.0;
228 double val_int1 = 0.0;
229 double val_ext01 = 0.0;
230 double val_ext10 = 0.0;
231 for (
int k1 = 0; k1 < Q1D; ++k1)
233 for (
int k2 = 0; k2 < Q1D; ++k2)
235 val_int0 += r_B[k1][i1] * r_B[k1][j1]
236 * r_B[k2][i2] * r_B[k2][j2]
238 val_int1 += r_B[k1][i1] * r_B[k1][j1]
239 * r_B[k2][i2] * r_B[k2][j2]
241 val_ext01+= r_B[k1][i1] * r_B[k1][j1]
242 * r_B[k2][i2] * r_B[k2][j2]
244 val_ext10+= r_B[k1][i1] * r_B[k1][j1]
245 * r_B[k2][i2] * r_B[k2][j2]
251 A_int(i1, i2, j1, j2, 0,
f) += val_int0;
252 A_int(i1, i2, j1, j2, 1,
f) += val_int1;
253 A_ext(i1, i2, j1, j2, 0,
f) += val_ext01;
254 A_ext(i1, i2, j1, j2, 1,
f) += val_ext10;
258 A_int(i1, i2, j1, j2, 0,
f) = val_int0;
259 A_int(i1, i2, j1, j2, 1,
f) = val_int1;
260 A_ext(i1, i2, j1, j2, 0,
f) = val_ext01;
261 A_ext(i1, i2, j1, j2, 1,
f) = val_ext10;
270 template<
int T_D1D = 0,
int T_Q1D = 0>
271 static void EADGTraceAssemble3DBdr(
const int NF,
272 const Array<double> &basis,
273 const Vector &padata,
279 const int D1D = T_D1D ? T_D1D : d1d;
280 const int Q1D = T_Q1D ? T_Q1D : q1d;
281 MFEM_VERIFY(D1D <=
MAX_D1D,
"");
282 MFEM_VERIFY(Q1D <=
MAX_Q1D,
"");
283 auto B =
Reshape(basis.Read(), Q1D, D1D);
284 auto D =
Reshape(padata.Read(), Q1D, Q1D, 2, 2, NF);
285 auto A_bdr =
Reshape(eadata_bdr.ReadWrite(), D1D, D1D, D1D, D1D, NF);
286 MFEM_FORALL_3D(
f, NF, D1D, D1D, 1,
288 const int D1D = T_D1D ? T_D1D : d1d;
289 const int Q1D = T_Q1D ? T_Q1D : q1d;
290 constexpr
int MD1 = T_D1D ? T_D1D :
MAX_D1D;
291 constexpr
int MQ1 = T_Q1D ? T_Q1D :
MAX_Q1D;
292 double r_B[MQ1][MD1];
293 for (
int d = 0; d < D1D; d++)
295 for (
int q = 0; q < Q1D; q++)
300 MFEM_SHARED
double s_D[MQ1][MQ1][2][2];
301 for (
int i=0; i < 2; i++)
303 for (
int j=0; j < 2; j++)
305 MFEM_FOREACH_THREAD(k1,x,Q1D)
307 MFEM_FOREACH_THREAD(k2,y,Q1D)
309 s_D[k1][k2][i][j] = D(k1,k2,i,j,
f);
315 MFEM_FOREACH_THREAD(i1,x,D1D)
317 MFEM_FOREACH_THREAD(i2,y,D1D)
319 for (
int j1 = 0; j1 < D1D; ++j1)
321 for (
int j2 = 0; j2 < D1D; ++j2)
323 double val_bdr = 0.0;
324 for (
int k1 = 0; k1 < Q1D; ++k1)
326 for (
int k2 = 0; k2 < Q1D; ++k2)
328 val_bdr += r_B[k1][i1] * r_B[k1][j1]
329 * r_B[k2][i2] * r_B[k2][j2]
335 A_bdr(i1, i2, j1, j2,
f) += val_bdr;
339 A_bdr(i1, i2, j1, j2,
f) = val_bdr;
355 if (
nf==0) {
return; }
359 return EADGTraceAssemble1DInt(
nf,B,
pa_data,ea_data_int,ea_data_ext,add);
366 return EADGTraceAssemble2DInt<2,2>(
nf,B,
pa_data,ea_data_int,
369 return EADGTraceAssemble2DInt<3,3>(
nf,B,
pa_data,ea_data_int,
372 return EADGTraceAssemble2DInt<4,4>(
nf,B,
pa_data,ea_data_int,
375 return EADGTraceAssemble2DInt<5,5>(
nf,B,
pa_data,ea_data_int,
378 return EADGTraceAssemble2DInt<6,6>(
nf,B,
pa_data,ea_data_int,
381 return EADGTraceAssemble2DInt<7,7>(
nf,B,
pa_data,ea_data_int,
384 return EADGTraceAssemble2DInt<8,8>(
nf,B,
pa_data,ea_data_int,
387 return EADGTraceAssemble2DInt<9,9>(
nf,B,
pa_data,ea_data_int,
390 return EADGTraceAssemble2DInt(nf,B,pa_data,ea_data_int,
399 return EADGTraceAssemble3DInt<2,3>(
nf,B,
pa_data,ea_data_int,
402 return EADGTraceAssemble3DInt<3,4>(
nf,B,
pa_data,ea_data_int,
405 return EADGTraceAssemble3DInt<4,5>(
nf,B,
pa_data,ea_data_int,
408 return EADGTraceAssemble3DInt<5,6>(
nf,B,
pa_data,ea_data_int,
411 return EADGTraceAssemble3DInt<6,7>(
nf,B,
pa_data,ea_data_int,
414 return EADGTraceAssemble3DInt<7,8>(
nf,B,
pa_data,ea_data_int,
417 return EADGTraceAssemble3DInt<8,9>(
nf,B,
pa_data,ea_data_int,
420 return EADGTraceAssemble3DInt(nf,B,pa_data,ea_data_int,
424 MFEM_ABORT(
"Unknown kernel.");
433 if (
nf==0) {
return; }
437 return EADGTraceAssemble1DBdr(
nf,B,
pa_data,ea_data_bdr,add);
443 case 0x22:
return EADGTraceAssemble2DBdr<2,2>(
nf,B,
pa_data,ea_data_bdr,
add);
444 case 0x33:
return EADGTraceAssemble2DBdr<3,3>(
nf,B,
pa_data,ea_data_bdr,
add);
445 case 0x44:
return EADGTraceAssemble2DBdr<4,4>(
nf,B,
pa_data,ea_data_bdr,
add);
446 case 0x55:
return EADGTraceAssemble2DBdr<5,5>(
nf,B,
pa_data,ea_data_bdr,
add);
447 case 0x66:
return EADGTraceAssemble2DBdr<6,6>(
nf,B,
pa_data,ea_data_bdr,
add);
448 case 0x77:
return EADGTraceAssemble2DBdr<7,7>(
nf,B,
pa_data,ea_data_bdr,
add);
449 case 0x88:
return EADGTraceAssemble2DBdr<8,8>(
nf,B,
pa_data,ea_data_bdr,
add);
450 case 0x99:
return EADGTraceAssemble2DBdr<9,9>(
nf,B,
pa_data,ea_data_bdr,
add);
452 return EADGTraceAssemble2DBdr(nf,B,pa_data,ea_data_bdr,add,
dofs1D,
quad1D);
459 case 0x23:
return EADGTraceAssemble3DBdr<2,3>(
nf,B,
pa_data,ea_data_bdr,
add);
460 case 0x34:
return EADGTraceAssemble3DBdr<3,4>(
nf,B,
pa_data,ea_data_bdr,
add);
461 case 0x45:
return EADGTraceAssemble3DBdr<4,5>(
nf,B,
pa_data,ea_data_bdr,
add);
462 case 0x56:
return EADGTraceAssemble3DBdr<5,6>(
nf,B,
pa_data,ea_data_bdr,
add);
463 case 0x67:
return EADGTraceAssemble3DBdr<6,7>(
nf,B,
pa_data,ea_data_bdr,
add);
464 case 0x78:
return EADGTraceAssemble3DBdr<7,8>(
nf,B,
pa_data,ea_data_bdr,
add);
465 case 0x89:
return EADGTraceAssemble3DBdr<8,9>(
nf,B,
pa_data,ea_data_bdr,
add);
467 return EADGTraceAssemble3DBdr(nf,B,pa_data,ea_data_bdr,add,
dofs1D,
quad1D);
470 MFEM_ABORT(
"Unknown kernel.");
int GetNFbyType(FaceType type) const
Returns the number of faces according to the requested type.
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.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
virtual void AssembleEAInteriorFaces(const FiniteElementSpace &fes, Vector &ea_data_int, Vector &ea_data_ext, const bool add)
virtual void AssembleEABoundaryFaces(const FiniteElementSpace &fes, Vector &ea_data_bdr, const bool add)
Array< double > B
Basis functions evaluated at quadrature points.
const DofToQuad * maps
Not owned.
double f(const Vector &p)