202 MFEM_VERIFY(3 == dim,
"Only 3D so far");
207 const std::vector<Array2D<real_t>>& B = pB[patch];
208 const std::vector<Array2D<real_t>>& G = pG[patch];
210 const IntArrayVar2D& minD = pminD[patch];
211 const IntArrayVar2D& maxD = pmaxD[patch];
212 const IntArrayVar2D& minQ = pminQ[patch];
213 const IntArrayVar2D& maxQ = pmaxQ[patch];
215 auto X =
Reshape(x.
Read(), D1D[0], D1D[1], D1D[2]);
218 const auto qd =
Reshape(pa_data.
Read(), Q1D[0]*Q1D[1]*Q1D[2],
219 (symmetric ? 6 : 9));
222 std::vector<Array3D<real_t>> grad(dim);
224 Array3D<real_t> gradXY(3, std::max(Q1D[0], D1D[0]), std::max(Q1D[1], D1D[1]));
227 for (
int d=0; d<dim; ++d)
229 grad[d].SetSize(Q1D[0], Q1D[1], Q1D[2]);
231 for (
int qz = 0; qz < Q1D[2]; ++qz)
233 for (
int qy = 0; qy < Q1D[1]; ++qy)
235 for (
int qx = 0; qx < Q1D[0]; ++qx)
237 grad[d](qx,qy,qz) = 0.0;
243 for (
int dz = 0; dz < D1D[2]; ++dz)
245 for (
int qy = 0; qy < Q1D[1]; ++qy)
247 for (
int qx = 0; qx < Q1D[0]; ++qx)
249 for (
int d=0; d<
dim; ++d)
251 gradXY(d,qx,qy) = 0.0;
255 for (
int dy = 0; dy < D1D[1]; ++dy)
257 for (
int qx = 0; qx < Q1D[0]; ++qx)
262 for (
int dx = 0; dx < D1D[0]; ++dx)
264 const real_t s = X(dx,dy,dz);
265 for (
int qx = minD[0][dx]; qx <= maxD[0][dx]; ++qx)
267 gradX(0,qx) += s * B[0](qx,dx);
268 gradX(1,qx) += s * G[0](qx,dx);
271 for (
int qy = minD[1][dy]; qy <= maxD[1][dy]; ++qy)
273 const real_t wy = B[1](qy,dy);
274 const real_t wDy = G[1](qy,dy);
276 for (
int qx = 0; qx < Q1D[0]; ++qx)
278 const real_t wx = gradX(0,qx);
279 const real_t wDx = gradX(1,qx);
280 gradXY(0,qx,qy) += wDx * wy;
281 gradXY(1,qx,qy) += wx * wDy;
282 gradXY(2,qx,qy) += wx * wy;
286 for (
int qz = minD[2][dz]; qz <= maxD[2][dz]; ++qz)
288 const real_t wz = B[2](qz,dz);
289 const real_t wDz = G[2](qz,dz);
290 for (
int qy = 0; qy < Q1D[1]; ++qy)
292 for (
int qx = 0; qx < Q1D[0]; ++qx)
294 grad[0](qx,qy,qz) += gradXY(0,qx,qy) * wz;
295 grad[1](qx,qy,qz) += gradXY(1,qx,qy) * wz;
296 grad[2](qx,qy,qz) += gradXY(2,qx,qy) * wDz;
302 for (
int qz = 0; qz < Q1D[2]; ++qz)
304 for (
int qy = 0; qy < Q1D[1]; ++qy)
306 for (
int qx = 0; qx < Q1D[0]; ++qx)
308 const int q = qx + ((qy + (qz * Q1D[1])) * Q1D[0]);
309 const real_t O00 = qd(q,0);
310 const real_t O01 = qd(q,1);
311 const real_t O02 = qd(q,2);
312 const real_t O10 = symmetric ? O01 : qd(q,3);
313 const real_t O11 = symmetric ? qd(q,3) : qd(q,4);
314 const real_t O12 = symmetric ? qd(q,4) : qd(q,5);
315 const real_t O20 = symmetric ? O02 : qd(q,6);
316 const real_t O21 = symmetric ? O12 : qd(q,7);
317 const real_t O22 = symmetric ? qd(q,5) : qd(q,8);
319 const real_t grad0 = grad[0](qx,qy,qz);
320 const real_t grad1 = grad[1](qx,qy,qz);
321 const real_t grad2 = grad[2](qx,qy,qz);
323 grad[0](qx,qy,qz) = (O00*grad0)+(O01*grad1)+(O02*grad2);
324 grad[1](qx,qy,qz) = (O10*grad0)+(O11*grad1)+(O12*grad2);
325 grad[2](qx,qy,qz) = (O20*grad0)+(O21*grad1)+(O22*grad2);
330 for (
int qz = 0; qz < Q1D[2]; ++qz)
332 for (
int dy = 0; dy < D1D[1]; ++dy)
334 for (
int dx = 0; dx < D1D[0]; ++dx)
336 for (
int d=0; d<3; ++d)
338 gradXY(d,dx,dy) = 0.0;
342 for (
int qy = 0; qy < Q1D[1]; ++qy)
344 for (
int dx = 0; dx < D1D[0]; ++dx)
346 for (
int d=0; d<3; ++d)
351 for (
int qx = 0; qx < Q1D[0]; ++qx)
353 const real_t gX = grad[0](qx,qy,qz);
354 const real_t gY = grad[1](qx,qy,qz);
355 const real_t gZ = grad[2](qx,qy,qz);
356 for (
int dx = minQ[0][qx]; dx <= maxQ[0][qx]; ++dx)
358 const real_t wx = B[0](qx,dx);
359 const real_t wDx = G[0](qx,dx);
360 gradX(0,dx) += gX * wDx;
361 gradX(1,dx) += gY * wx;
362 gradX(2,dx) += gZ * wx;
365 for (
int dy = minQ[1][qy]; dy <= maxQ[1][qy]; ++dy)
367 const real_t wy = B[1](qy,dy);
368 const real_t wDy = G[1](qy,dy);
369 for (
int dx = 0; dx < D1D[0]; ++dx)
371 gradXY(0,dx,dy) += gradX(0,dx) * wy;
372 gradXY(1,dx,dy) += gradX(1,dx) * wDy;
373 gradXY(2,dx,dy) += gradX(2,dx) * wy;
377 for (
int dz = minQ[2][qz]; dz <= maxQ[2][qz]; ++dz)
379 const real_t wz = B[2](qz,dz);
380 const real_t wDz = G[2](qz,dz);
381 for (
int dy = 0; dy < D1D[1]; ++dy)
383 for (
int dx = 0; dx < D1D[0]; ++dx)
386 ((gradXY(0,dx,dy) * wz) +
387 (gradXY(1,dx,dy) * wz) +
388 (gradXY(2,dx,dy) * wDz));