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));