56      MFEM_VERIFY(cQ != NULL, 
"Only ConstantCoefficient is supported.");
 
   59   if (!(
dim == 2 || 
dim == 3))
 
   61      MFEM_ABORT(
"Dimension not supported.");
 
   65      const real_t constant = coeff;
 
   73         for (
int q = 0; q < NQ; ++q)
 
   75            const real_t J11 = J(q,0,0,e);
 
   76            const real_t J12 = J(q,1,0,e);
 
   77            const real_t J21 = J(q,0,1,e);
 
   78            const real_t J22 = J(q,1,1,e);
 
   79            const real_t detJ = (J11*J22)-(J21*J12);
 
   80            v(q,e) =  w[q] * constant * detJ;
 
   86      const real_t constant = coeff;
 
   94         for (
int q = 0; q < NQ; ++q)
 
   96            const real_t J11 = J(q,0,0,e), J12 = J(q,0,1,e), J13 = J(q,0,2,e);
 
   97            const real_t J21 = J(q,1,0,e), J22 = J(q,1,1,e), J23 = J(q,1,2,e);
 
   98            const real_t J31 = J(q,2,0,e), J32 = J(q,2,1,e), J33 = J(q,2,2,e);
 
   99            const real_t detJ = J11 * (J22 * J33 - J32 * J23) -
 
  100                                J21 * (J12 * J33 - J32 * J13) +
 
  101                                J31 * (J12 * J23 - J22 * J13);
 
  102            v(q,e) = W[q] * constant * detJ;
 
 
  108template<const 
int T_D1D = 0, const 
int T_Q1D = 0>
 
  109static void PAVectorMassAssembleDiagonal2D(
const int NE,
 
  117   const int D1D = T_D1D ? T_D1D : d1d;
 
  118   const int Q1D = T_Q1D ? T_Q1D : q1d;
 
  119   constexpr int VDIM = 2;
 
  127      const int D1D = T_D1D ? T_D1D : d1d;
 
  128      const int Q1D = T_Q1D ? T_Q1D : q1d;
 
  129      constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
 
  130      constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
 
  132      real_t temp[max_Q1D][max_D1D];
 
  133      for (
int qx = 0; qx < Q1D; ++qx)
 
  135         for (
int dy = 0; dy < D1D; ++dy)
 
  138            for (
int qy = 0; qy < Q1D; ++qy)
 
  140               temp[qx][dy] += B(qy, dy) * B(qy, dy) * op(qx, qy, e);
 
  144      for (
int dy = 0; dy < D1D; ++dy)
 
  146         for (
int dx = 0; dx < D1D; ++dx)
 
  149            for (
int qx = 0; qx < Q1D; ++qx)
 
  151               temp1 += B(qx, dx) * B(qx, dx) * temp[qx][dy];
 
  153            y(dx, dy, 0, e) = temp1;
 
  154            y(dx, dy, 1, e) = temp1;
 
  160template<const 
int T_D1D = 0, const 
int T_Q1D = 0>
 
  161static void PAVectorMassAssembleDiagonal3D(
const int NE,
 
  162                                           const Array<real_t> &B_,
 
  163                                           const Array<real_t> &Bt_,
 
  169   const int D1D = T_D1D ? T_D1D : d1d;
 
  170   const int Q1D = T_Q1D ? T_Q1D : q1d;
 
  171   constexpr int VDIM = 3;
 
  174   auto B = 
Reshape(B_.Read(), Q1D, D1D);
 
  175   auto op = 
Reshape(op_.Read(), Q1D, Q1D, Q1D, NE);
 
  176   auto y = 
Reshape(diag_.ReadWrite(), D1D, D1D, D1D, VDIM, NE);
 
  179      const int D1D = T_D1D ? T_D1D : d1d; 
 
  180      const int Q1D = T_Q1D ? T_Q1D : q1d;
 
  182      constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
 
  183      constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
 
  185      real_t temp[max_Q1D][max_Q1D][max_D1D];
 
  186      for (
int qx = 0; qx < Q1D; ++qx)
 
  188         for (
int qy = 0; qy < Q1D; ++qy)
 
  190            for (
int dz = 0; dz < D1D; ++dz)
 
  192               temp[qx][qy][dz] = 0.0;
 
  193               for (
int qz = 0; qz < Q1D; ++qz)
 
  195                  temp[qx][qy][dz] += B(qz, dz) * B(qz, dz) * op(qx, qy, qz, e);
 
  200      real_t temp2[max_Q1D][max_D1D][max_D1D];
 
  201      for (
int qx = 0; qx < Q1D; ++qx)
 
  203         for (
int dz = 0; dz < D1D; ++dz)
 
  205            for (
int dy = 0; dy < D1D; ++dy)
 
  207               temp2[qx][dy][dz] = 0.0;
 
  208               for (
int qy = 0; qy < Q1D; ++qy)
 
  210                  temp2[qx][dy][dz] += B(qy, dy) * B(qy, dy) * temp[qx][qy][dz];
 
  215      for (
int dz = 0; dz < D1D; ++dz)
 
  217         for (
int dy = 0; dy < D1D; ++dy)
 
  219            for (
int dx = 0; dx < D1D; ++dx)
 
  222               for (
int qx = 0; qx < Q1D; ++qx)
 
  224                  temp3 += B(qx, dx) * B(qx, dx)
 
  227               y(dx, dy, dz, 0, e) = temp3;
 
  228               y(dx, dy, dz, 1, e) = temp3;
 
  229               y(dx, dy, dz, 2, e) = temp3;
 
  236static void PAVectorMassAssembleDiagonal(
const int dim,
 
  240                                         const Array<real_t> &B,
 
  241                                         const Array<real_t> &Bt,
 
  247      return PAVectorMassAssembleDiagonal2D(NE, B, Bt, op, y, D1D, Q1D);
 
  251      return PAVectorMassAssembleDiagonal3D(NE, B, Bt, op, y, D1D, Q1D);
 
  253   MFEM_ABORT(
"Dimension not implemented.");
 
  270template<const 
int T_D1D = 0, const 
int T_Q1D = 0>
 
  271static void PAVectorMassApply2D(
const int NE,
 
  280   const int D1D = T_D1D ? T_D1D : d1d;
 
  281   const int Q1D = T_Q1D ? T_Q1D : q1d;
 
  282   constexpr int VDIM = 2;
 
  292      const int D1D = T_D1D ? T_D1D : d1d; 
 
  293      const int Q1D = T_Q1D ? T_Q1D : q1d;
 
  295      constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
 
  296      constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
 
  297      real_t sol_xy[max_Q1D][max_Q1D];
 
  298      for (
int c = 0; c < VDIM; ++c)
 
  300         for (
int qy = 0; qy < Q1D; ++qy)
 
  302            for (
int qx = 0; qx < Q1D; ++qx)
 
  304               sol_xy[qy][qx] = 0.0;
 
  307         for (
int dy = 0; dy < D1D; ++dy)
 
  310            for (
int qy = 0; qy < Q1D; ++qy)
 
  314            for (
int dx = 0; dx < D1D; ++dx)
 
  316               const real_t s = x(dx,dy,c,e);
 
  317               for (
int qx = 0; qx < Q1D; ++qx)
 
  319                  sol_x[qx] += B(qx,dx)* s;
 
  322            for (
int qy = 0; qy < Q1D; ++qy)
 
  324               const real_t d2q = B(qy,dy);
 
  325               for (
int qx = 0; qx < Q1D; ++qx)
 
  327                  sol_xy[qy][qx] += d2q * sol_x[qx];
 
  331         for (
int qy = 0; qy < Q1D; ++qy)
 
  333            for (
int qx = 0; qx < Q1D; ++qx)
 
  335               sol_xy[qy][qx] *= op(qx,qy,e);
 
  338         for (
int qy = 0; qy < Q1D; ++qy)
 
  341            for (
int dx = 0; dx < D1D; ++dx)
 
  345            for (
int qx = 0; qx < Q1D; ++qx)
 
  347               const real_t s = sol_xy[qy][qx];
 
  348               for (
int dx = 0; dx < D1D; ++dx)
 
  350                  sol_x[dx] += Bt(dx,qx) * s;
 
  353            for (
int dy = 0; dy < D1D; ++dy)
 
  355               const real_t q2d = Bt(dy,qy);
 
  356               for (
int dx = 0; dx < D1D; ++dx)
 
  358                  y(dx,dy,c,e) += q2d * sol_x[dx];
 
  366template<const 
int T_D1D = 0, const 
int T_Q1D = 0>
 
  367static void PAVectorMassApply3D(
const int NE,
 
  368                                const Array<real_t> &B_,
 
  369                                const Array<real_t> &Bt_,
 
  376   const int D1D = T_D1D ? T_D1D : d1d;
 
  377   const int Q1D = T_Q1D ? T_Q1D : q1d;
 
  378   constexpr int VDIM = 3;
 
  381   auto B = 
Reshape(B_.Read(), Q1D, D1D);
 
  382   auto Bt = 
Reshape(Bt_.Read(), D1D, Q1D);
 
  383   auto op = 
Reshape(op_.Read(), Q1D, Q1D, Q1D, NE);
 
  384   auto x = 
Reshape(x_.Read(), D1D, D1D, D1D, VDIM, NE);
 
  385   auto y = 
Reshape(y_.ReadWrite(), D1D, D1D, D1D, VDIM, NE);
 
  388      const int D1D = T_D1D ? T_D1D : d1d;
 
  389      const int Q1D = T_Q1D ? T_Q1D : q1d;
 
  390      constexpr int max_D1D = T_D1D ? T_D1D : DofQuadLimits::MAX_D1D;
 
  391      constexpr int max_Q1D = T_Q1D ? T_Q1D : DofQuadLimits::MAX_Q1D;
 
  392      real_t sol_xyz[max_Q1D][max_Q1D][max_Q1D];
 
  393      for (
int c = 0; c < VDIM; ++ c)
 
  395         for (
int qz = 0; qz < Q1D; ++qz)
 
  397            for (
int qy = 0; qy < Q1D; ++qy)
 
  399               for (
int qx = 0; qx < Q1D; ++qx)
 
  401                  sol_xyz[qz][qy][qx] = 0.0;
 
  405         for (
int dz = 0; dz < D1D; ++dz)
 
  407            real_t sol_xy[max_Q1D][max_Q1D];
 
  408            for (
int qy = 0; qy < Q1D; ++qy)
 
  410               for (
int qx = 0; qx < Q1D; ++qx)
 
  412                  sol_xy[qy][qx] = 0.0;
 
  415            for (
int dy = 0; dy < D1D; ++dy)
 
  418               for (
int qx = 0; qx < Q1D; ++qx)
 
  422               for (
int dx = 0; dx < D1D; ++dx)
 
  424                  const real_t s = x(dx,dy,dz,c,e);
 
  425                  for (
int qx = 0; qx < Q1D; ++qx)
 
  427                     sol_x[qx] += B(qx,dx) * s;
 
  430               for (
int qy = 0; qy < Q1D; ++qy)
 
  432                  const real_t wy = B(qy,dy);
 
  433                  for (
int qx = 0; qx < Q1D; ++qx)
 
  435                     sol_xy[qy][qx] += wy * sol_x[qx];
 
  439            for (
int qz = 0; qz < Q1D; ++qz)
 
  441               const real_t wz = B(qz,dz);
 
  442               for (
int qy = 0; qy < Q1D; ++qy)
 
  444                  for (
int qx = 0; qx < Q1D; ++qx)
 
  446                     sol_xyz[qz][qy][qx] += wz * sol_xy[qy][qx];
 
  451         for (
int qz = 0; qz < Q1D; ++qz)
 
  453            for (
int qy = 0; qy < Q1D; ++qy)
 
  455               for (
int qx = 0; qx < Q1D; ++qx)
 
  457                  sol_xyz[qz][qy][qx] *= op(qx,qy,qz,e);
 
  461         for (
int qz = 0; qz < Q1D; ++qz)
 
  463            real_t sol_xy[max_D1D][max_D1D];
 
  464            for (
int dy = 0; dy < D1D; ++dy)
 
  466               for (
int dx = 0; dx < D1D; ++dx)
 
  471            for (
int qy = 0; qy < Q1D; ++qy)
 
  474               for (
int dx = 0; dx < D1D; ++dx)
 
  478               for (
int qx = 0; qx < Q1D; ++qx)
 
  480                  const real_t s = sol_xyz[qz][qy][qx];
 
  481                  for (
int dx = 0; dx < D1D; ++dx)
 
  483                     sol_x[dx] += Bt(dx,qx) * s;
 
  486               for (
int dy = 0; dy < D1D; ++dy)
 
  488                  const real_t wy = Bt(dy,qy);
 
  489                  for (
int dx = 0; dx < D1D; ++dx)
 
  491                     sol_xy[dy][dx] += wy * sol_x[dx];
 
  495            for (
int dz = 0; dz < D1D; ++dz)
 
  497               const real_t wz = Bt(dz,qz);
 
  498               for (
int dy = 0; dy < D1D; ++dy)
 
  500                  for (
int dx = 0; dx < D1D; ++dx)
 
  502                     y(dx,dy,dz,c,e) += wz * sol_xy[dy][dx];
 
  511static void PAVectorMassApply(
const int dim,
 
  515                              const Array<real_t> &B,
 
  516                              const Array<real_t> &Bt,
 
  523      return PAVectorMassApply2D(NE, B, Bt, op, x, y, D1D, Q1D);
 
  527      return PAVectorMassApply3D(NE, B, Bt, op, x, y, D1D, Q1D);
 
  529   MFEM_ABORT(
"Unknown kernel.");
 
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
A coefficient that is constant across space and time.
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
@ TENSOR
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Array< real_t > B
Basis functions evaluated at quadrature points.
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number.
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Array< real_t > Bt
Transpose of B.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
Mesh * GetMesh() const
Returns the mesh.
const FiniteElement * GetTypicalFE() const
Return GetFE(0) if the local mesh is not empty; otherwise return a typical FE based on the Geometry t...
Abstract class for all finite elements.
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
Vector J
Jacobians of the element transformations at all quadrature points.
Class for an integration rule - an Array of IntegrationPoint.
int GetNPoints() const
Returns the number of the points in the integration rule.
const Array< real_t > & GetWeights() const
Return the quadrature weights in a contiguous array.
const IntegrationRule * IntRule
static const IntegrationRule & GetRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &Trans)
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
ElementTransformation * GetTypicalElementTransformation()
If the local mesh is not empty return GetElementTransformation(0); otherwise, return the identity tra...
const GeometricFactors * GetGeometricFactors(const IntegrationRule &ir, const int flags, MemoryType d_mt=MemoryType::DEFAULT)
Return the mesh geometric factors corresponding to the given integration rule.
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
void AssembleDiagonalPA(Vector &diag) override
Assemble diagonal and add it to Vector diag.
const DofToQuad * maps
Not owned.
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
const GeometricFactors * geom
Not owned.
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
void SetSize(int s)
Resize the vector to size s.
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
void GetDiagonal(mfem::Vector &diag) const
void AddMult(const mfem::Vector &x, mfem::Vector &y, const real_t a=1.0) const override
Operator application: y+=A(x) (default) or y+=a*A(x).
Represent a MassIntegrator with AssemblyLevel::Partial using libCEED.
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
bool DeviceCanUseCeed()
Function that determines if a CEED kernel should be used, based on the current mfem::Device configura...
void forall(int N, lambda &&body)
static const DeviceDofQuadLimits & Get()
Return a const reference to the DeviceDofQuadLimits singleton.