MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
bilininteg_mass_pa.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, 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"
18
19namespace mfem
20{
21
22// PA Mass Integrator
23
25{
26 const MemoryType mt = (pa_mt == MemoryType::DEFAULT) ?
28
29 // Assuming the same element type
30 fespace = &fes;
31 Mesh *mesh = fes.GetMesh();
32 const FiniteElement &el = *fes.GetTypicalFE();
34 const IntegrationRule *ir = IntRule ? IntRule : &GetRule(el, el, *T0);
35 if (DeviceCanUseCeed())
36 {
37 delete ceedOp;
38 const bool mixed = mesh->GetNumGeometries(mesh->Dimension()) > 1 ||
39 fes.IsVariableOrder();
40 if (mixed)
41 {
42 ceedOp = new ceed::MixedPAMassIntegrator(*this, fes, Q);
43 }
44 else
45 {
46 ceedOp = new ceed::PAMassIntegrator(fes, *ir, Q);
47 }
48 return;
49 }
50 int map_type = el.GetMapType();
51 dim = mesh->Dimension();
52 ne = fes.GetMesh()->GetNE();
53 nq = ir->GetNPoints();
56 dofs1D = maps->ndof;
57 quad1D = maps->nqpt;
58 pa_data.SetSize(ne*nq, mt);
59
60 QuadratureSpace qs(*mesh, *ir);
62
63 if (dim==1) { MFEM_ABORT("Not supported yet... stay tuned!"); }
64 if (dim==2)
65 {
66 const int NE = ne;
67 const int Q1D = quad1D;
68 const bool const_c = coeff.Size() == 1;
69 const bool by_val = map_type == FiniteElement::VALUE;
70 const auto W = Reshape(ir->GetWeights().Read(), Q1D,Q1D);
71 const auto J = Reshape(geom->detJ.Read(), Q1D,Q1D,NE);
72 const auto C = const_c ? Reshape(coeff.Read(), 1,1,1) :
73 Reshape(coeff.Read(), Q1D,Q1D,NE);
74 auto v = Reshape(pa_data.Write(), Q1D,Q1D, NE);
75 mfem::forall_2D(NE,Q1D,Q1D, [=] MFEM_HOST_DEVICE (int e)
76 {
77 MFEM_FOREACH_THREAD(qx,x,Q1D)
78 {
79 MFEM_FOREACH_THREAD(qy,y,Q1D)
80 {
81 const real_t detJ = J(qx,qy,e);
82 const real_t coeff = const_c ? C(0,0,0) : C(qx,qy,e);
83 v(qx,qy,e) = W(qx,qy) * coeff * (by_val ? detJ : 1.0/detJ);
84 }
85 }
86 });
87 }
88 if (dim==3)
89 {
90 const int NE = ne;
91 const int Q1D = quad1D;
92 const bool const_c = coeff.Size() == 1;
93 const bool by_val = map_type == FiniteElement::VALUE;
94 const auto W = Reshape(ir->GetWeights().Read(), Q1D,Q1D,Q1D);
95 const auto J = Reshape(geom->detJ.Read(), Q1D,Q1D,Q1D,NE);
96 const auto C = const_c ? Reshape(coeff.Read(), 1,1,1,1) :
97 Reshape(coeff.Read(), Q1D,Q1D,Q1D,NE);
98 auto v = Reshape(pa_data.Write(), Q1D,Q1D,Q1D,NE);
99 mfem::forall_3D(NE, Q1D, Q1D, Q1D, [=] MFEM_HOST_DEVICE (int e)
100 {
101 MFEM_FOREACH_THREAD(qx,x,Q1D)
102 {
103 MFEM_FOREACH_THREAD(qy,y,Q1D)
104 {
105 MFEM_FOREACH_THREAD(qz,z,Q1D)
106 {
107 const real_t detJ = J(qx,qy,qz,e);
108 const real_t coeff = const_c ? C(0,0,0,0) : C(qx,qy,qz,e);
109 v(qx,qy,qz,e) = W(qx,qy,qz) * coeff * (by_val ? detJ : 1.0/detJ);
110 }
111 }
112 }
113 });
114 }
115}
116
118{
119 const MemoryType mt = (pa_mt == MemoryType::DEFAULT) ?
121
122 // Assuming the same element type
123 fespace = &fes;
124 Mesh *mesh = fes.GetMesh();
126 if (ne == 0) { return; }
127 const FiniteElement &el = *fes.GetBE(0);
129 const IntegrationRule *ir = IntRule ? IntRule : &GetRule(el, el, *T0);
130
131 int map_type = el.GetMapType();
132 dim = el.GetDim(); // Dimension of the boundary element, *not* the mesh
133 nq = ir->GetNPoints();
137 dofs1D = maps->ndof;
138 quad1D = maps->nqpt;
139 pa_data.SetSize(ne*nq, mt);
140
143
144 const int NE = ne;
145 const int Q1D = quad1D;
146 const bool const_c = coeff.Size() == 1;
147 const bool by_val = map_type == FiniteElement::VALUE;
148 if (dim==1)
149 {
150 const auto W = Reshape(ir->GetWeights().Read(), Q1D);
151 const auto J = Reshape(face_geom->detJ.Read(), Q1D, NE);
152 const auto C = const_c ? Reshape(coeff.Read(), 1, 1) :
153 Reshape(coeff.Read(), Q1D, NE);
154 auto v = Reshape(pa_data.Write(), Q1D, NE);
155 mfem::forall_2D(NE, Q1D, 1, [=] MFEM_HOST_DEVICE (int e)
156 {
157 MFEM_FOREACH_THREAD(qx,x,Q1D)
158 {
159 const real_t detJ = J(qx,e);
160 const real_t coeff = const_c ? C(0,0) : C(qx,e);
161 v(qx,e) = W(qx) * coeff * (by_val ? detJ : 1.0/detJ);
162 }
163 });
164 }
165 else if (dim==2)
166 {
167 const auto W = Reshape(ir->GetWeights().Read(), Q1D,Q1D);
168 const auto J = Reshape(face_geom->detJ.Read(), Q1D,Q1D,NE);
169 const auto C = const_c ? Reshape(coeff.Read(), 1,1,1) :
170 Reshape(coeff.Read(), Q1D,Q1D,NE);
171 auto v = Reshape(pa_data.Write(), Q1D,Q1D, NE);
172 mfem::forall_2D(NE, Q1D, Q1D, [=] MFEM_HOST_DEVICE (int e)
173 {
174 MFEM_FOREACH_THREAD(qx,x,Q1D)
175 {
176 MFEM_FOREACH_THREAD(qy,y,Q1D)
177 {
178 const real_t detJ = J(qx,qy,e);
179 const real_t coeff = const_c ? C(0,0,0) : C(qx,qy,e);
180 v(qx,qy,e) = W(qx,qy) * coeff * (by_val ? detJ : 1.0/detJ);
181 }
182 }
183 });
184 }
185 else
186 {
187 MFEM_ABORT("Not supported.");
188 }
189}
190
192{
193 if (DeviceCanUseCeed())
194 {
195 ceedOp->GetDiagonal(diag);
196 }
197 else
198 {
199 DiagonalPAKernels::Run(dim, dofs1D, quad1D, ne, maps->B, pa_data,
200 diag, dofs1D, quad1D);
201 }
202}
203
205{
206 if (DeviceCanUseCeed())
207 {
208 ceedOp->AddMult(x, y);
209 }
210 else
211 {
212 const int D1D = dofs1D;
213 const int Q1D = quad1D;
214 const Array<real_t> &B = maps->B;
215 const Array<real_t> &Bt = maps->Bt;
216 const Vector &D = pa_data;
217#ifdef MFEM_USE_OCCA
218 if (DeviceCanUseOcca())
219 {
220 if (dim == 2)
221 {
222 return internal::OccaPAMassApply2D(D1D,Q1D,ne,B,Bt,D,x,y);
223 }
224 if (dim == 3)
225 {
226 return internal::OccaPAMassApply3D(D1D,Q1D,ne,B,Bt,D,x,y);
227 }
228 MFEM_ABORT("OCCA PA Mass Apply unknown kernel!");
229 }
230#endif // MFEM_USE_OCCA
231 ApplyPAKernels::Run(dim, D1D, Q1D, ne, B, Bt, D, x, y, D1D, Q1D);
232 }
233}
234
236{
237 // Mass integrator is symmetric
238 AddMultPA(x, y);
239}
240
241} // namespace mfem
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:337
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:274
@ 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:193
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number.
Definition fe_base.hpp:178
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Definition fe_base.hpp:182
Array< real_t > Bt
Transpose of B.
Definition fe_base.hpp:199
Vector detJ
Determinants of the Jacobians at all quadrature points.
Definition mesh.hpp:3030
Class representing the storage layout of a FaceQuadratureFunction.
Definition qspace.hpp:170
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:244
bool IsVariableOrder() const
Returns true if the space contains elements of varying polynomial orders.
Definition fespace.hpp:709
const FiniteElement * GetBE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th boundary fac...
Definition fespace.cpp:3881
Mesh * GetMesh() const
Returns the mesh.
Definition fespace.hpp:679
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:3871
Abstract class for all finite elements.
Definition fe_base.hpp:244
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:365
int GetDim() const
Returns the reference space dimension for the finite element.
Definition fe_base.hpp:321
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
Definition fe_base.hpp:360
Vector detJ
Determinants of the Jacobians at all quadrature points.
Definition mesh.hpp:2982
Class for an integration rule - an Array of IntegrationPoint.
Definition intrules.hpp:100
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition intrules.hpp:256
const Array< real_t > & GetWeights() const
Return the quadrature weights in a contiguous array.
Definition intrules.cpp:86
const IntegrationRule * IntRule
const FiniteElementSpace * fespace
const FaceGeometricFactors * face_geom
Not owned.
const DofToQuad * maps
Not owned.
static const IntegrationRule & GetRule(const FiniteElement &trial_fe, const FiniteElement &test_fe, const ElementTransformation &Trans)
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
void AssemblePABoundary(const FiniteElementSpace &fes) override
virtual 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.
Mesh data type.
Definition mesh.hpp:64
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:6547
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:900
int GetNE() const
Returns number of elements.
Definition mesh.hpp:1282
int Dimension() const
Dimension of the reference space used within the elements.
Definition mesh.hpp:1216
ElementTransformation * GetTypicalElementTransformation()
If the local mesh is not empty return GetElementTransformation(0); otherwise, return the identity tra...
Definition mesh.cpp:390
ElementTransformation * GetBdrElementTransformation(int i)
Returns a pointer to the transformation defining the i-th boundary element.
Definition mesh.cpp:530
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:880
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
Definition mesh.cpp:7243
Class representing the storage layout of a QuadratureFunction.
Definition qspace.hpp:120
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:494
int Size() const
Returns the size of the vector.
Definition vector.hpp:226
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:558
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:502
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:131
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.
void forall_2D(int N, int X, int Y, lambda &&body)
Definition forall.hpp:762
void forall_3D(int N, int X, int Y, int Z, lambda &&body)
Definition forall.hpp:774
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:43
MemoryType
Memory types supported by MFEM.