MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
nonlininteg_vecconvection_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 "./nonlininteg_vecconvection_pa.hpp" // IWYU pragma: keep
14#include "./nonlininteg_vecconvection_pa_grad.hpp" // IWYU pragma: keep
15#include "./nonlininteg_vecconvection_pa_diag.hpp" // IWYU pragma: keep
16
17namespace mfem
18{
19
47
49{
50 MFEM_ASSERT(fes.GetOrdering() == Ordering::byNODES,
51 "PA Only supports Ordering::byNODES!");
52 Mesh *mesh = fes.GetMesh();
53 const FiniteElement &el = *fes.GetTypicalFE();
55 const IntegrationRule *ir = IntRule ? IntRule : &GetRule(el, Tr);
56
57 if (DeviceCanUseCeed())
58 {
59 delete ceedOp;
60 const bool mixed = mesh->GetNumGeometries(mesh->Dimension()) > 1 ||
61 fes.IsVariableOrder();
62 if (mixed)
63 {
65 }
66 else
67 {
69 }
70 return;
71 }
72
73 ne = mesh->GetNE();
74 nq = ir->GetNPoints();
75 dim = mesh->Dimension();
76 MFEM_VERIFY(dim == 2 || dim == 3, "Dimension not supported");
77
80 : pa_mt;
81 pa_adj.SetSize(ne * nq * dim * dim, mt);
83 maps = &el.GetDofToQuad(*ir, DofToQuad::TENSOR);
84 d1d = maps->ndof;
85 q1d = maps->nqpt;
86
87 QuadratureSpace qs(*mesh, *ir);
89
90 const int nq1d = q1d * q1d * (dim==3 ? q1d : 1);
91 MFEM_VERIFY(coeff.Size() == 1 || coeff.Size() == nq1d*ne, "Invalid coeff");
92 MFEM_VERIFY(ir->GetWeights().Size() == nq1d, "Invalid weights size");
93
94 const auto w_r = ir->GetWeights().Read();
95 const bool const_coeff = coeff.Size() == 1;
96
97 if (dim == 2)
98 {
99 const int Q1D = q1d;
100 constexpr int VDIM = 2, DIM = 2;
101 const auto W = Reshape(w_r, Q1D, Q1D);
102 const auto C = const_coeff ?
103 Reshape(coeff.Read(), 1, 1, 1) :
104 Reshape(coeff.Read(), Q1D, Q1D, ne);
105 const auto J = Reshape(geom->J.Read(), Q1D, Q1D, VDIM, DIM, ne);
106 auto A = Reshape(pa_adj.Write(), VDIM, DIM, Q1D, Q1D, ne);
107
108 mfem::forall_2D(ne, Q1D, Q1D, [=] MFEM_HOST_DEVICE(int e)
109 {
110 MFEM_FOREACH_THREAD_DIRECT(qy, y, Q1D)
111 {
112 MFEM_FOREACH_THREAD_DIRECT(qx, x, Q1D)
113 {
114 const real_t J11 = J(qx, qy, 0, 0, e), J12 = J(qx, qy, 0, 1, e);
115 const real_t J21 = J(qx, qy, 1, 0, e), J22 = J(qx, qy, 1, 1, e);
116 // adj(J)
117 const real_t A11 = +J22, A12 = -J12;
118 const real_t A21 = -J21, A22 = +J11;
119 // Store w * coeff * adj(J)
120 const real_t w = W(qx, qy);
121 const real_t c = const_coeff ? C(0, 0, 0) : C(qx, qy, e);
122 A(0, 0, qx, qy, e) = w * c * A11;
123 A(1, 0, qx, qy, e) = w * c * A12;
124 A(0, 1, qx, qy, e) = w * c * A21;
125 A(1, 1, qx, qy, e) = w * c * A22;
126 }
127 }
128 });
129 }
130 else if (dim == 3)
131 {
132 const int Q1D = q1d;
133 constexpr int VDIM = 3, DIM = 3;
134 const auto W = Reshape(w_r, Q1D, Q1D, Q1D);
135 const auto C = const_coeff ?
136 Reshape(coeff.Read(), 1, 1, 1, 1) :
137 Reshape(coeff.Read(), Q1D, Q1D, Q1D, ne);
138 const auto J = Reshape(geom->J.Read(), Q1D, Q1D, Q1D, VDIM, DIM, ne);
139 auto A = Reshape(pa_adj.Write(), VDIM, DIM, Q1D, Q1D, Q1D, ne);
140
141 mfem::forall_3D(ne, Q1D, Q1D, Q1D, [=] MFEM_HOST_DEVICE(int e)
142 {
143 MFEM_FOREACH_THREAD_DIRECT(qz, z, Q1D)
144 {
145 MFEM_FOREACH_THREAD_DIRECT(qy, y, Q1D)
146 {
147 MFEM_FOREACH_THREAD_DIRECT(qx, x, Q1D)
148 {
149 const real_t J11 = J(qx, qy, qz, 0, 0, e),
150 J12 = J(qx, qy, qz, 0, 1, e),
151 J13 = J(qx, qy, qz, 0, 2, e);
152 const real_t J21 = J(qx, qy, qz, 1, 0, e),
153 J22 = J(qx, qy, qz, 1, 1, e),
154 J23 = J(qx, qy, qz, 1, 2, e);
155 const real_t J31 = J(qx, qy, qz, 2, 0, e),
156 J32 = J(qx, qy, qz, 2, 1, e),
157 J33 = J(qx, qy, qz, 2, 2, e);
158 const real_t c =
159 const_coeff ? C(0, 0, 0, 0) : C(qx, qy, qz, e);
160 const real_t cw = W(qx, qy, qz) * c;
161 // adj(J)
162 const real_t A11 = (J22 * J33) - (J23 * J32);
163 const real_t A12 = (J32 * J13) - (J12 * J33);
164 const real_t A13 = (J12 * J23) - (J22 * J13);
165 const real_t A21 = (J31 * J23) - (J21 * J33);
166 const real_t A22 = (J11 * J33) - (J13 * J31);
167 const real_t A23 = (J21 * J13) - (J11 * J23);
168 const real_t A31 = (J21 * J32) - (J31 * J22);
169 const real_t A32 = (J31 * J12) - (J11 * J32);
170 const real_t A33 = (J11 * J22) - (J12 * J21);
171 // Store wq * coeff * adj(J)
172 A(0, 0, qx, qy, qz, e) = cw * A11;
173 A(1, 0, qx, qy, qz, e) = cw * A12;
174 A(2, 0, qx, qy, qz, e) = cw * A13;
175 A(0, 1, qx, qy, qz, e) = cw * A21;
176 A(1, 1, qx, qy, qz, e) = cw * A22;
177 A(2, 1, qx, qy, qz, e) = cw * A23;
178 A(0, 2, qx, qy, qz, e) = cw * A31;
179 A(1, 2, qx, qy, qz, e) = cw * A32;
180 A(2, 2, qx, qy, qz, e) = cw * A33;
181 }
182 }
183 }
184 });
185 }
186 else
187 {
188 MFEM_ABORT("dim " << dim << " not supported!");
189 }
190}
191
193{
194 if (DeviceCanUseCeed())
195 {
196 ceedOp->AddMult(x, y);
197 }
198 else
199 {
200 AddMultPAKernels::Run(dim, d1d, q1d, ne,
201 maps->B.Read(),
202 maps->G.Read(),
203 pa_adj.Read(),
204 x.Read(),
205 y.ReadWrite(),
206 d1d, q1d);
207 }
208}
209
210} // namespace mfem
int Size() const
Return the logical size of the array.
Definition array.hpp:192
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:410
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
Array< real_t > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
Definition fe_base.hpp:222
@ 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
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
Ordering::Type GetOrdering() const
Return the ordering method.
Definition fespace.hpp:852
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
Vector J
Jacobians of the element transformations at all quadrature points.
Definition mesh.hpp:3158
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
Mesh data type.
Definition mesh.hpp:67
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
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
void AddMultPA(const Vector &x, Vector &y) const override
Method for partially assembled action.
void AssemblePA(const FiniteElementSpace &fes) override
Method defining partial assembly.
static const IntegrationRule & GetRule(const FiniteElement &fe, const ElementTransformation &T)
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
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:536
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
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 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
int dim
Definition ex24.cpp:53
constexpr int DIM
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.
void forall_2D(int N, int X, int Y, lambda &&body)
Definition forall.hpp:1220
void forall_3D(int N, int X, int Y, int Z, lambda &&body)
Definition forall.hpp:1244
float real_t
Definition config.hpp:46
MemoryType
Memory types supported by MFEM.