31#ifndef MFEM_BILININTEG_ELASTICITY_KERNELS_HPP 
   32#define MFEM_BILININTEG_ELASTICITY_KERNELS_HPP 
   66void ElasticityAddMultPA(
const int dim, 
const int nDofs,
 
   67                         const FiniteElementSpace &fespace, 
const CoefficientVector &lambda,
 
   68                         const CoefficientVector &
mu, 
const GeometricFactors &geom,
 
   69                         const DofToQuad &maps, 
const Vector &x, QuadratureFunction &QVec, Vector &y);
 
   94void ElasticityComponentAddMultPA(
 
   95   const int dim, 
const int nDofs, 
const FiniteElementSpace &fespace,
 
   96   const CoefficientVector &lambda, 
const CoefficientVector &
mu,
 
   97   const GeometricFactors &geom, 
const DofToQuad &maps, 
const Vector &x,
 
   98   QuadratureFunction &QVec, Vector &y, 
const int i_block, 
const int j_block);
 
  122void ElasticityAssembleEA(
const int dim, 
const int i_block, 
const int j_block,
 
  123                          const int nDofs, 
const IntegrationRule &ir,
 
  124                          const CoefficientVector &lambda,
 
  125                          const CoefficientVector &
mu, 
const GeometricFactors &geom,
 
  126                          const DofToQuad &maps, Vector &emat);
 
  138void ElasticityAssembleDiagonalPA(
const int dim, 
const int nDofs,
 
  139                                  const CoefficientVector &lambda,
 
  140                                  const CoefficientVector &
mu, 
const GeometricFactors &geom,
 
  141                                  const DofToQuad &maps, QuadratureFunction &QVec, Vector &diag);
 
  144template<
int dim, 
int i_block = -1, 
int j_block = -1>
 
  145void ElasticityAddMultPA_(
const int nDofs, 
const FiniteElementSpace &fespace,
 
  146                          const CoefficientVector &lambda, 
const CoefficientVector &
mu,
 
  147                          const GeometricFactors &geom, 
const DofToQuad &maps, 
const Vector &x,
 
  148                          QuadratureFunction &QVec, Vector &y)
 
  150   static_assert((i_block < 0) == (j_block < 0),
 
  151                 "i_block and j_block must both be non-negative or strictly negative.");
 
  152   static constexpr int d = 
dim;
 
  153   static constexpr int qLower = (i_block < 0) ? 0 : i_block;
 
  154   static constexpr int qUpper = (i_block < 0) ? d : i_block+1;
 
  155   static constexpr int qSize = qUpper-qLower;
 
  156   static constexpr int aLower = (j_block < 0) ? 0 : j_block;
 
  157   static constexpr int aUpper = (j_block < 0) ? d : j_block+1;
 
  158   static constexpr int aSize = aUpper-aLower;
 
  159   static constexpr bool isComponent = (i_block >= 0);
 
  162   const auto &ir = QVec.GetIntRule(0);
 
  163   const QuadratureInterpolator *E_To_Q_Map = fespace.GetQuadratureInterpolator(
 
  167   E_To_Q_Map->PhysDerivatives(x, QVec);
 
  169   const int numPoints = ir.GetNPoints();
 
  170   const int numEls = fespace.GetNE();
 
  171   const auto lamDev = 
Reshape(lambda.Read(), numPoints, numEls);
 
  172   const auto muDev = 
Reshape(
mu.Read(), numPoints, numEls);
 
  173   const auto J = 
Reshape(geom.J.Read(), numPoints, d, d, numEls);
 
  174   auto Q = 
Reshape(QVec.ReadWrite(), numPoints, d, qSize, numEls);
 
  175   const real_t *ipWeights = ir.GetWeights().Read();
 
  179      MFEM_FOREACH_THREAD(
p, x,numPoints)
 
  181         auto invJ = inv(make_tensor<d, d>(
 
  182         [&](
int i, 
int j) { 
return J(
p, i, j, e); }));
 
  183         tensor<real_t, aSize, d> gradx;
 
  187            for (
int i = 0; i < d; i++)
 
  189               gradx(0,i) = Q(
p, i, 0, e);
 
  194            for (
int j = 0; j < d; j++)
 
  196               for (
int i = 0; i < d; i++)
 
  198                  gradx(i,j) = Q(
p, i, j, e);
 
  204         for (
int i = aLower; i < aUpper; i++)
 
  207            const int iIndex = isComponent ? 0 : i;
 
  208            div += gradx(iIndex,i);
 
  210         const real_t w = ipWeights[
p] /det(invJ);
 
  211         for (
int m = 0; m < d; m++)
 
  213            for (
int q = qLower; q < qUpper; q++)
 
  222                  for (
int a = 0; 
a < d; 
a++)
 
  224                     contraction += 2*((
a == q)*invJ(m,j_block) + (j_block==q)*invJ(m,
a))*(gradx(0,
 
  230                  for (
int a = 0; 
a < d; 
a++)
 
  232                     for (
int b = 0; 
b < d; 
b++)
 
  234                        contraction += ((
a == q)*invJ(m,
b) + (
b==q)*invJ(m,
a))
 
  235                                       *(gradx(
a,
b) + gradx(
b, 
a));
 
  241               const int qIndex = isComponent ? 0 : q;
 
  242               Q(
p,m,qIndex,e) = w*(lamDev(
p, e)*invJ(m,q)*div + 0.5*muDev(
p, e)*contraction);
 
  249   const auto QRead = 
Reshape(QVec.Read(), numPoints, d, qSize, numEls);
 
  250   const auto G = 
Reshape(maps.G.Read(), numPoints, d, nDofs);
 
  251   auto yDev = 
Reshape(y.ReadWrite(), nDofs, qSize, numEls);
 
  254      MFEM_FOREACH_THREAD(i, y, nDofs)
 
  256         MFEM_FOREACH_THREAD(q, x, qSize)
 
  258            const int qIndex = isComponent ? 0 : q;
 
  260            for (
int m = 0; m < d; m++ )
 
  262               for (
int p = 0; 
p < numPoints; 
p++ )
 
  264                  sum += QRead(
p,m,qIndex,e)*G(
p,m,i);
 
  267            yDev(i, qIndex, e) += sum;
 
  275void ElasticityAssembleDiagonalPA_(
const int nDofs,
 
  276                                   const CoefficientVector &lambda,
 
  277                                   const CoefficientVector &
mu, 
const GeometricFactors &geom,
 
  278                                   const DofToQuad &maps, QuadratureFunction &QVec, Vector &diag)
 
  281   const auto &ir = QVec.GetIntRule(0);
 
  282   static constexpr int d = 
dim;
 
  283   const int numPoints = ir.GetNPoints();
 
  284   const int numEls = lambda.Size()/numPoints;
 
  285   const auto lamDev = 
Reshape(lambda.Read(), numPoints, numEls);
 
  286   const auto muDev = 
Reshape(
mu.Read(), numPoints, numEls);
 
  287   const auto J = 
Reshape(geom.J.Read(), numPoints, d, d, numEls);
 
  288   auto Q = 
Reshape(QVec.ReadWrite(), numPoints, d,d, d, numEls);
 
  289   const real_t *ipWeights = ir.GetWeights().Read();
 
  292      MFEM_FOREACH_THREAD(
p, x,numPoints)
 
  294         auto invJ = inv(make_tensor<d, d>(
 
  295         [&](
int i, 
int j) { 
return J(
p, i, j, e); }));
 
  296         const real_t w = ipWeights[
p] /det(invJ);
 
  297         for (
int n = 0; n < d; n++)
 
  299            for (
int m = 0; m < d; m++)
 
  301               for (
int q = 0; q < d; q++)
 
  307                  for (
int a = 0; 
a < d; 
a++)
 
  309                     for (
int b = 0; 
b < d; 
b++)
 
  311                        contraction += ((
a == q)*invJ(m,
b) + (
b==q)*invJ(m,
a))*((
a == q)
 
  312                                                                                *invJ(n, 
b) + (
b==q)*invJ(n,
a));
 
  317                  Q(
p,m,n,q,e) = w*(lamDev(
p, e)*invJ(m,q)*invJ(n,q)
 
  318                                    + 0.5*muDev(
p, e)*contraction);
 
  326   const auto QRead = 
Reshape(QVec.Read(), numPoints, d, d, d, numEls);
 
  327   auto diagDev = 
Reshape(diag.Write(), nDofs, d, numEls);
 
  328   const auto G = 
Reshape(maps.G.Read(), numPoints, d, nDofs);
 
  331      MFEM_FOREACH_THREAD(i, y, nDofs)
 
  333         MFEM_FOREACH_THREAD(q, x, d)
 
  336            for (
int n = 0; n < d; n++)
 
  338               for (
int m = 0; m < d; m++)
 
  340                  for (
int p = 0; 
p < numPoints; 
p++ )
 
  342                     sum += QRead(
p,m,n,q,e)*G(
p,m,i)*G(
p,n,i);
 
  346            diagDev(i, q, e) = sum;
 
  354void ElasticityAssembleEA_(
const int i_block,
 
  357                           const IntegrationRule &ir,
 
  358                           const CoefficientVector &lambda,
 
  359                           const CoefficientVector &
mu,
 
  360                           const GeometricFactors &geom,
 
  361                           const DofToQuad &maps,
 
  365   static constexpr int d = 
dim;
 
  366   const int numPoints = ir.GetNPoints();
 
  367   const int numEls = lambda.Size()/numPoints;
 
  368   const auto lamDev = 
Reshape(lambda.Read(), numPoints, numEls);
 
  369   const auto muDev = 
Reshape(
mu.Read(), numPoints, numEls);
 
  370   const auto J = 
Reshape(geom.J.Read(), numPoints, d, d, numEls);
 
  371   const auto G = 
Reshape(maps.G.Read(), numPoints, d, nDofs);
 
  372   auto ematDev = 
Reshape(emat.Write(), nDofs, nDofs, numEls);
 
  373   const real_t *ipWeights = ir.GetWeights().Read();
 
  376      MFEM_FOREACH_THREAD(JDof, y, nDofs)
 
  378         MFEM_FOREACH_THREAD(IDof, x, nDofs)
 
  381            for (
int p = 0 ; 
p < numPoints; 
p++)
 
  383               auto invJ = inv(make_tensor<d, d>(
 
  384               [&](
int i, 
int j) { 
return J(
p, i, j, e); }));
 
  385               const real_t w = ipWeights[
p] /det(invJ);
 
  386               for (
int n = 0; n < d; n++)
 
  388                  for (
int m = 0; m < d; m++)
 
  392                     for (
int a = 0; 
a < d; 
a++)
 
  394                        for (
int b = 0; 
b < d; 
b++)
 
  396                           contraction += ((
a == i_block)*invJ(m,
b) + (
b==i_block)*invJ(m,
 
  397                                                                                        a))*((
a == j_block)*invJ(n,
 
  398                                                                                              b) + (
b==j_block)*invJ(n,
a));
 
  403                     sum += w*(lamDev(
p, e)*invJ(m,i_block)*invJ(n,j_block)
 
  404                               + 0.5*muDev(
p, e)*contraction)*G(
p,m,IDof)*G(
p,n,JDof);
 
  408            ematDev(IDof, JDof, e) = sum;
 
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
void forall_2D(int N, int X, int Y, lambda &&body)
real_t p(const Vector &x, real_t t)
Implementation of the tensor class.