MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
bilininteg_mass_pa.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
13#include "../bilininteg.hpp"
14#include "../gridfunc.hpp"
15#include "../qfunction.hpp"
19
20namespace mfem
21{
22
23// PA Mass Integrator
24
26{
27 const MemoryType mt = (pa_mt == MemoryType::DEFAULT) ?
29
30 // Assuming the same element type
31 fespace = &fes;
32 Mesh *mesh = fes.GetMesh();
33 dim = mesh->Dimension();
34 const FiniteElement &el = *fes.GetTypicalFE();
36 const bool stroud = fes.UsesRaggedTensorBasis();
37 const IntegrationRule *ir = IntRule ? IntRule : &GetRule(el, el, *T0, stroud);
38 if (DeviceCanUseCeed())
39 {
40 delete ceedOp;
41 const bool mixed = mesh->GetNumGeometries(mesh->Dimension()) > 1 ||
42 fes.IsVariableOrder();
43 if (mixed)
44 {
45 ceedOp = new ceed::MixedPAMassIntegrator(*this, fes, Q);
46 }
47 else
48 {
49 ceedOp = new ceed::PAMassIntegrator(fes, *ir, Q);
50 }
51 return;
52 }
53 int map_type = el.GetMapType();
54 ne = fes.GetMesh()->GetNE();
55 nq = ir->GetNPoints();
57 if (stroud)
58 {
60 }
61 else
62 {
64 }
65 dofs1D = maps->ndof;
66 quad1D = maps->nqpt;
67 pa_data.SetSize(ne*nq, mt);
68
69 QuadratureSpace qs(*mesh, *ir);
71 // QuadratureSpace expects ir defined in reference simplex for Bernstein
72 // elements with partial assembly
73 {
74 const int NE = ne;
75 const int NQ = nq;
76 const bool const_c = coeff.Size() == 1;
77 const bool by_val = map_type == FiniteElement::VALUE;
78 const auto W = Reshape(ir->GetWeights().Read(), NQ);
79 const auto J = Reshape(geom->detJ.Read(), NQ, NE);
80 const auto C =
81 const_c ? Reshape(coeff.Read(), 1, 1) : Reshape(coeff.Read(), NQ, NE);
82 auto v = Reshape(pa_data.Write(), NQ, NE);
83 mfem::forall(NQ, NE, [=] MFEM_HOST_DEVICE(int q, int e)
84 {
85 const real_t detJ = J(q, e);
86 const real_t coeff = const_c ? C(0, 0) : C(q, e);
87 v(q, e) = W(q) * coeff * (by_val ? detJ : 1.0 / detJ);
88 });
89 }
90}
91
93{
94 const MemoryType mt = (pa_mt == MemoryType::DEFAULT) ?
96
97 // Assuming the same element type
98 fespace = &fes;
99 Mesh *mesh = fes.GetMesh();
101 if (ne == 0) { return; }
102 const FiniteElement &el = *fes.GetBE(0);
104 const IntegrationRule *ir = IntRule ? IntRule : &GetRule(el, el, *T0);
105
106 int map_type = el.GetMapType();
107 dim = el.GetDim(); // Dimension of the boundary element, *not* the mesh
108 nq = ir->GetNPoints();
112 dofs1D = maps->ndof;
113 quad1D = maps->nqpt;
114 pa_data.SetSize(ne*nq, mt);
115
118
119 const int NE = ne;
120 const int NQ = nq;
121 const bool const_c = coeff.Size() == 1;
122 const bool by_val = map_type == FiniteElement::VALUE;
123 {
124 const auto W = Reshape(ir->GetWeights().Read(), NQ);
125 const auto J = Reshape(face_geom->detJ.Read(), NQ, NE);
126 const auto C = const_c ? Reshape(coeff.Read(), 1, 1)
127 : Reshape(coeff.Read(), NQ, NE);
128 auto v = Reshape(pa_data.Write(), NQ, NE);
129 mfem::forall(NQ, NE, [=] MFEM_HOST_DEVICE(int q, int e)
130 {
131 const real_t detJ = J(q, e);
132 const real_t coeff = const_c ? C(0, 0) : C(q, e);
133 v(q, e) = W(q) * coeff * (by_val ? detJ : 1.0 / detJ);
134 });
135 }
136}
137
139{
140 if (DeviceCanUseCeed())
141 {
142 ceedOp->GetDiagonal(diag);
143 }
144 else
145 {
146 MFEM_VERIFY(maps && maps->mode != DofToQuad::RAGGED_TENSOR,
147 "AssembleDiagonalPA requires AssemblePA to be called first,"
148 " and is not implemented for ragged tensor bases");
149 DiagonalPAKernels::Run(dim, dofs1D, quad1D, ne, maps->B, pa_data,
150 diag, dofs1D, quad1D);
151 }
152}
153
155{
156 if (DeviceCanUseCeed())
157 {
158 ceedOp->AddMult(x, y);
159 }
160 else
161 {
162 const int D1D = dofs1D;
163 const int Q1D = quad1D;
164 const Vector &D = pa_data;
165 const Array<real_t> &B = maps->B;
166 const Array<real_t> &Bt = maps->Bt;
167
168#ifdef MFEM_USE_OCCA
169 if (DeviceCanUseOcca())
170 {
171 if (dim == 2)
172 {
173 return internal::OccaPAMassApply2D(D1D,Q1D,ne,B,Bt,D,x,y);
174 }
175 if (dim == 3)
176 {
177 return internal::OccaPAMassApply3D(D1D,Q1D,ne,B,Bt,D,x,y);
178 }
179 MFEM_ABORT("OCCA PA Mass Apply unknown kernel!");
180 }
181#endif // MFEM_USE_OCCA
182
184 {
185 const auto *rmaps = static_cast<const RaggedDofToQuad*>(maps);
186
187 const Array<real_t> &Ba1 = rmaps->Ba1;
188 const Array<real_t> &Ba2 = rmaps->Ba2;
189 const Array<real_t> &Ba3 = rmaps->Ba3;
190 const Array<real_t> &Ba1t = rmaps->Ba1t;
191 const Array<real_t> &Ba2t = rmaps->Ba2t;
192 const Array<real_t> &Ba3t = rmaps->Ba3t;
193 const Array<int> &lex_map = rmaps->lex_map;
194 const Array<int> &forward_map2d = rmaps->forward_map2d_mass;
195 const Array<int> &inverse_map2d = rmaps->inverse_map2d_mass;
196 const Array<int> &forward_map3d = rmaps->forward_map3d_mass;
197 const Array<int> &inverse_map3d = rmaps->inverse_map3d_mass;
198 ApplySimplexPAKernels::Run(dim, D1D, Q1D, ne, lex_map, forward_map2d,
199 inverse_map2d,
200 forward_map3d, inverse_map3d, Ba1, Ba2, Ba3, Ba1t, Ba2t, Ba3t,
201 D, x, y, D1D, Q1D);
202 }
203 else
204 {
205 ApplyPAKernels::Run(dim, D1D, Q1D, ne, B, Bt, D, x, y, D1D, Q1D);
206 }
207 }
208}
209
211{
212 if (DeviceCanUseCeed())
213 {
214 MFEM_ABORT("AddAbsMultPA not implemented with CEED!");
215 ceedOp->AddMult(x, y);
216 }
217 else
218 {
219 MFEM_VERIFY(!fespace->UsesRaggedTensorBasis(),
220 "AbsMultPA not implemented for ragged tensor basis");
221 Vector abs_pa_data(pa_data);
222 abs_pa_data.Abs();
223 Array<real_t> absB(maps->B);
224 Array<real_t> absBt(maps->Bt);
225 absB.Abs();
226 absBt.Abs();
227
228 ApplyPAKernels::Run(dim, dofs1D, quad1D, ne, absB, absBt, abs_pa_data,
229 x, y, dofs1D, quad1D);
230 }
231}
232
234{
235 // Mass integrator is symmetric
236 AddMultPA(x, y);
237}
238
240{
241 // Mass integrator is symmetric
242 AddAbsMultPA(x, y);
243}
244
245} // namespace mfem
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:410
void Abs()
Replace each entry of the array with its absolute value.
Definition array.cpp:134
Class to represent a coefficient evaluated at quadrature points.
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
Definition device.hpp:298
Mode mode
Describes the contents of the B, Bt, G, and Gt arrays, see Mode.
Definition fe_base.hpp:182
@ RAGGED_TENSOR
Ragged tensor product representation using 1D matrices/tensors with dimensions using 1D number of qua...
Definition fe_base.hpp:178
@ TENSOR
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Definition fe_base.hpp:165
Array< real_t > B
Basis functions evaluated at quadrature points.
Definition fe_base.hpp:201
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number.
Definition fe_base.hpp:186
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Definition fe_base.hpp:190
Array< real_t > Bt
Transpose of B.
Definition fe_base.hpp:207
Vector detJ
Determinants of the Jacobians at all quadrature points.
Definition mesh.hpp:3212
Class representing the storage layout of a FaceQuadratureFunction.
Definition qspace.hpp:214
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:210
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
Definition fespace.hpp:673
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th boundary fac...
Definition fespace.cpp:3906
bool UsesRaggedTensorBasis() const
Return true if the mesh contains only one topology, the elements are all triangles or tetrahedrons,...
Definition fespace.hpp:1595
Mesh * GetMesh() const
Returns the mesh.
Definition fespace.hpp:639
const FiniteElement * GetTypicalFE() const
Return GetFE(0) if the local mesh is not empty; otherwise return a typical FE based on the Geometry t...
Definition fespace.cpp:3896
Abstract class for all finite elements.
Definition fe_base.hpp:294
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...
Definition fe_base.cpp:373
int GetDim() const
Returns the reference space dimension for the finite element.
Definition fe_base.hpp:381
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
Definition fe_base.hpp:436
Vector detJ
Determinants of the Jacobians at all quadrature points.
Definition mesh.hpp:3164
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:96
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition intrules.hpp:255
const Array< real_t > & GetWeights() const
Return the quadrature weights in a contiguous array.
Definition intrules.cpp:98
const IntegrationRule * IntRule
const FiniteElementSpace * fespace
const FaceGeometricFactors * face_geom
Not owned.
void AddAbsMultPA(const Vector &, Vector &) const override
const DofToQuad * maps
Not owned.
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
void AssemblePABoundary(const FiniteElementSpace &fes) override
static const IntegrationRule & GetRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &Trans, const bool stroud=false)
void AssembleDiagonalPA(Vector &diag) override
Assemble diagonal and add it to Vector diag.
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
const GeometricFactors * geom
Not owned.
void AddMultTransposePA(const Vector &, Vector &) const override
Method for partially assembled transposed action.
void AddAbsMultTransposePA(const Vector &, Vector &) const override
Mesh data type.
Definition mesh.hpp:67
virtual int GetNFbyType(FaceType type) const
Returns the number of faces according to the requested type, does not count master nonconforming face...
Definition mesh.cpp:7318
const FaceGeometricFactors * GetFaceGeometricFactors(const IntegrationRule &ir, const int flags, FaceType type, MemoryType d_mt=MemoryType::DEFAULT)
Return the mesh geometric factors for the faces corresponding to the given integration rule.
Definition mesh.cpp:978
int GetNE() const
Returns number of elements.
Definition mesh.hpp:1390
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1314
ElementTransformation * GetTypicalElementTransformation()
If the local mesh is not empty return GetElementTransformation(0); otherwise, return the identity tra...
Definition mesh.cpp:394
ElementTransformation * GetBdrElementTransformation(int i)
Returns a pointer to the transformation defining the i-th boundary element.
Definition mesh.cpp:533
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.
Definition mesh.cpp:958
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
Definition mesh.cpp:8014
Class representing the storage layout of a QuadratureFunction.
Definition qspace.hpp:164
Structure representing the matrices/tensors needed to evaluate (in reference space) the values,...
Definition fe_base.hpp:247
Vector data type.
Definition vector.hpp:82
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:520
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
void Abs()
(*this)(i) = abs((*this)(i))
Definition vector.cpp:392
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:633
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:528
void GetDiagonal(mfem::Vector &diag) const
Definition operator.cpp:104
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).
Definition operator.cpp:72
Represent a MassIntegrator with AssemblyLevel::Partial using libCEED.
Definition mass.hpp:27
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
Definition dtensor.hpp:138
bool DeviceCanUseCeed()
Function that determines if a CEED kernel should be used, based on the current mfem::Device configura...
Definition util.cpp:33
@ COMPRESSED
Enable all above compressions.
bool DeviceCanUseOcca()
Function that determines if an OCCA kernel should be used, based on the current mfem::Device configur...
Definition occa.hpp:69
float real_t
Definition config.hpp:46
MemoryType
Memory types supported by MFEM.
void forall(int N, lambda &&body)
Definition forall.hpp:1134