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.