172 MFEM_VERIFY(3 == dim,
"Only 3D so far");
177 const std::vector<Array2D<real_t>>& B = pB[patch];
178 const std::vector<Array2D<real_t>>& G = pG[patch];
180 const IntArrayVar2D& minD = pminD[patch];
181 const IntArrayVar2D& maxD = pmaxD[patch];
182 const IntArrayVar2D& minQ = pminQ[patch];
183 const IntArrayVar2D& maxQ = pmaxQ[patch];
185 auto X =
Reshape(x.
Read(), D1D[0], D1D[1], D1D[2]);
188 const auto qd =
Reshape(pa_data.
Read(), Q1D[0]*Q1D[1]*Q1D[2],
189 (symmetric ? 6 : 9));
192 std::vector<Array3D<real_t>> grad(dim);
194 Array3D<real_t> gradXY(3, std::max(Q1D[0], D1D[0]), std::max(Q1D[1], D1D[1]));
197 for (
int d=0; d<dim; ++d)
199 grad[d].SetSize(Q1D[0], Q1D[1], Q1D[2]);
201 for (
int qz = 0; qz < Q1D[2]; ++qz)
203 for (
int qy = 0; qy < Q1D[1]; ++qy)
205 for (
int qx = 0; qx < Q1D[0]; ++qx)
207 grad[d](qx,qy,qz) = 0.0;
213 for (
int dz = 0; dz < D1D[2]; ++dz)
215 for (
int qy = 0; qy < Q1D[1]; ++qy)
217 for (
int qx = 0; qx < Q1D[0]; ++qx)
219 for (
int d=0; d<
dim; ++d)
221 gradXY(d,qx,qy) = 0.0;
225 for (
int dy = 0; dy < D1D[1]; ++dy)
227 for (
int qx = 0; qx < Q1D[0]; ++qx)
232 for (
int dx = 0; dx < D1D[0]; ++dx)
234 const real_t s = X(dx,dy,dz);
235 for (
int qx = minD[0][dx]; qx <= maxD[0][dx]; ++qx)
237 gradX(0,qx) += s * B[0](qx,dx);
238 gradX(1,qx) += s * G[0](qx,dx);
241 for (
int qy = minD[1][dy]; qy <= maxD[1][dy]; ++qy)
243 const real_t wy = B[1](qy,dy);
244 const real_t wDy = G[1](qy,dy);
246 for (
int qx = 0; qx < Q1D[0]; ++qx)
248 const real_t wx = gradX(0,qx);
249 const real_t wDx = gradX(1,qx);
250 gradXY(0,qx,qy) += wDx * wy;
251 gradXY(1,qx,qy) += wx * wDy;
252 gradXY(2,qx,qy) += wx * wy;
256 for (
int qz = minD[2][dz]; qz <= maxD[2][dz]; ++qz)
258 const real_t wz = B[2](qz,dz);
259 const real_t wDz = G[2](qz,dz);
260 for (
int qy = 0; qy < Q1D[1]; ++qy)
262 for (
int qx = 0; qx < Q1D[0]; ++qx)
264 grad[0](qx,qy,qz) += gradXY(0,qx,qy) * wz;
265 grad[1](qx,qy,qz) += gradXY(1,qx,qy) * wz;
266 grad[2](qx,qy,qz) += gradXY(2,qx,qy) * wDz;
272 for (
int qz = 0; qz < Q1D[2]; ++qz)
274 for (
int qy = 0; qy < Q1D[1]; ++qy)
276 for (
int qx = 0; qx < Q1D[0]; ++qx)
278 const int q = qx + ((qy + (qz * Q1D[1])) * Q1D[0]);
279 const real_t O00 = qd(q,0);
280 const real_t O01 = qd(q,1);
281 const real_t O02 = qd(q,2);
282 const real_t O10 = symmetric ? O01 : qd(q,3);
283 const real_t O11 = symmetric ? qd(q,3) : qd(q,4);
284 const real_t O12 = symmetric ? qd(q,4) : qd(q,5);
285 const real_t O20 = symmetric ? O02 : qd(q,6);
286 const real_t O21 = symmetric ? O12 : qd(q,7);
287 const real_t O22 = symmetric ? qd(q,5) : qd(q,8);
289 const real_t grad0 = grad[0](qx,qy,qz);
290 const real_t grad1 = grad[1](qx,qy,qz);
291 const real_t grad2 = grad[2](qx,qy,qz);
293 grad[0](qx,qy,qz) = (O00*grad0)+(O01*grad1)+(O02*grad2);
294 grad[1](qx,qy,qz) = (O10*grad0)+(O11*grad1)+(O12*grad2);
295 grad[2](qx,qy,qz) = (O20*grad0)+(O21*grad1)+(O22*grad2);
300 for (
int qz = 0; qz < Q1D[2]; ++qz)
302 for (
int dy = 0; dy < D1D[1]; ++dy)
304 for (
int dx = 0; dx < D1D[0]; ++dx)
306 for (
int d=0; d<3; ++d)
308 gradXY(d,dx,dy) = 0.0;
312 for (
int qy = 0; qy < Q1D[1]; ++qy)
314 for (
int dx = 0; dx < D1D[0]; ++dx)
316 for (
int d=0; d<3; ++d)
321 for (
int qx = 0; qx < Q1D[0]; ++qx)
323 const real_t gX = grad[0](qx,qy,qz);
324 const real_t gY = grad[1](qx,qy,qz);
325 const real_t gZ = grad[2](qx,qy,qz);
326 for (
int dx = minQ[0][qx]; dx <= maxQ[0][qx]; ++dx)
328 const real_t wx = B[0](qx,dx);
329 const real_t wDx = G[0](qx,dx);
330 gradX(0,dx) += gX * wDx;
331 gradX(1,dx) += gY * wx;
332 gradX(2,dx) += gZ * wx;
335 for (
int dy = minQ[1][qy]; dy <= maxQ[1][qy]; ++dy)
337 const real_t wy = B[1](qy,dy);
338 const real_t wDy = G[1](qy,dy);
339 for (
int dx = 0; dx < D1D[0]; ++dx)
341 gradXY(0,dx,dy) += gradX(0,dx) * wy;
342 gradXY(1,dx,dy) += gradX(1,dx) * wDy;
343 gradXY(2,dx,dy) += gradX(2,dx) * wy;
347 for (
int dz = minQ[2][qz]; dz <= maxQ[2][qz]; ++dz)
349 const real_t wz = B[2](qz,dz);
350 const real_t wDz = G[2](qz,dz);
351 for (
int dy = 0; dy < D1D[1]; ++dy)
353 for (
int dx = 0; dx < D1D[0]; ++dx)
356 ((gradXY(0,dx,dy) * wz) +
357 (gradXY(1,dx,dy) * wz) +
358 (gradXY(2,dx,dy) * wDz));