MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
bilininteg_dgtrace_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"
16#include "../restriction.hpp"
17
19
20namespace mfem
21{
22
23// PA DG Trace Integrator
24static void PADGTraceSetup2D(const int Q1D, const int NF,
25 const Array<real_t> &w, const Vector &det,
26 const Vector &nor, const Vector &rho,
27 const Vector &vel, const real_t alpha,
28 const real_t beta, Vector &op)
29{
30 const int VDIM = 2;
31
32 auto d = Reshape(det.Read(), Q1D, NF);
33 auto n = Reshape(nor.Read(), Q1D, VDIM, NF);
34 const bool const_r = rho.Size() == 1;
35 auto R = const_r ? Reshape(rho.Read(), 1, 1) : Reshape(rho.Read(), Q1D, NF);
36 const bool const_v = vel.Size() == 2;
37 auto V =
38 const_v ? Reshape(vel.Read(), 2, 1, 1) : Reshape(vel.Read(), 2, Q1D, NF);
39 auto W = w.Read();
40 auto qd = Reshape(op.Write(), Q1D, 2, 2, NF);
41
42 mfem::forall(Q1D * NF, [=] MFEM_HOST_DEVICE(int tid)
43 {
44 const int f = tid / Q1D;
45 const int q = tid % Q1D;
46 {
47 const real_t r = const_r ? R(0, 0) : R(q, f);
48 const real_t v0 = const_v ? V(0, 0, 0) : V(0, q, f);
49 const real_t v1 = const_v ? V(1, 0, 0) : V(1, q, f);
50 const real_t dot = n(q, 0, f) * v0 + n(q, 1, f) * v1;
51 const real_t abs = dot > 0_r ? dot : -dot;
52 const real_t w = W[q] * r * d(q, f);
53 qd(q, 0, 0, f) = w * (alpha / 2 * dot + beta * abs);
54 qd(q, 1, 0, f) = w * (alpha / 2 * dot - beta * abs);
55 qd(q, 0, 1, f) = w * (-alpha / 2 * dot - beta * abs);
56 qd(q, 1, 1, f) = w * (-alpha / 2 * dot + beta * abs);
57 }
58 });
59}
60
61static void PADGTraceSetup3D(const int Q1D, const int NF,
62 const Array<real_t> &w, const Vector &det,
63 const Vector &nor, const Vector &rho,
64 const Vector &vel, const real_t alpha,
65 const real_t beta, Vector &op)
66{
67 const int VDIM = 3;
68
69 auto d = Reshape(det.Read(), Q1D, Q1D, NF);
70 auto n = Reshape(nor.Read(), Q1D, Q1D, VDIM, NF);
71 const bool const_r = rho.Size() == 1;
72 auto R = const_r ? Reshape(rho.Read(), 1, 1, 1)
73 : Reshape(rho.Read(), Q1D, Q1D, NF);
74 const bool const_v = vel.Size() == 3;
75 auto V = const_v ? Reshape(vel.Read(), 3, 1, 1, 1)
76 : Reshape(vel.Read(), 3, Q1D, Q1D, NF);
77 auto W = w.Read();
78 auto qd = Reshape(op.Write(), Q1D, Q1D, 2, 2, NF);
79
80 mfem::forall(Q1D * Q1D * NF, [=] MFEM_HOST_DEVICE(int tid)
81 {
82 int f = tid / (Q1D * Q1D);
83 int q2 = (tid / Q1D) % Q1D;
84 int q1 = tid % Q1D;
85 {
86 {
87 const real_t r = const_r ? R(0, 0, 0) : R(q1, q2, f);
88 const real_t v0 = const_v ? V(0, 0, 0, 0) : V(0, q1, q2, f);
89 const real_t v1 = const_v ? V(1, 0, 0, 0) : V(1, q1, q2, f);
90 const real_t v2 = const_v ? V(2, 0, 0, 0) : V(2, q1, q2, f);
91 const real_t dot = n(q1, q2, 0, f) * v0 + n(q1, q2, 1, f) * v1 +
92 n(q1, q2, 2, f) * v2;
93 const real_t abs = dot > 0.0 ? dot : -dot;
94 const real_t w = W[q1 + q2 * Q1D] * r * d(q1, q2, f);
95 qd(q1, q2, 0, 0, f) = w * (alpha / 2 * dot + beta * abs);
96 qd(q1, q2, 1, 0, f) = w * (alpha / 2 * dot - beta * abs);
97 qd(q1, q2, 0, 1, f) = w * (-alpha / 2 * dot - beta * abs);
98 qd(q1, q2, 1, 1, f) = w * (-alpha / 2 * dot + beta * abs);
99 }
100 }
101 });
102}
103
104static void PADGTraceSetup(const int dim, const int D1D, const int Q1D,
105 const int NF, const Array<real_t> &W,
106 const Vector &det, const Vector &nor,
107 const Vector &rho, const Vector &u,
108 const real_t alpha, const real_t beta, Vector &op)
109{
110 if (dim == 1)
111 {
112 MFEM_ABORT("dim==1 not supported in PADGTraceSetup");
113 }
114 if (dim == 2)
115 {
116 PADGTraceSetup2D(Q1D, NF, W, det, nor, rho, u, alpha, beta, op);
117 }
118 if (dim == 3)
119 {
120 PADGTraceSetup3D(Q1D, NF, W, det, nor, rho, u, alpha, beta, op);
121 }
122}
123
124void DGTraceIntegrator::SetupPA(const FiniteElementSpace &fes, FaceType type)
125{
126 const MemoryType mt =
128
129 // Assumes tensor-product elements
130 Mesh *mesh = fes.GetMesh();
131 const FiniteElement &el = *fes.GetTypicalTraceElement();
132 const IntegrationRule *ir = IntRule?
133 IntRule:
134 &GetRule(el.GetGeomType(), el.GetOrder(),
135 *mesh->GetTypicalElementTransformation());
136
137
138 FaceQuadratureSpace qs(*mesh, *ir, type);
139 nf = qs.GetNumFaces();
140 if (nf==0) { return; }
141 const int symmDims = 4;
142 nq = ir->GetNPoints();
143 dim = mesh->Dimension();
144 geom = mesh->GetFaceGeometricFactors(
146 type, mt);
147 maps = &el.GetDofToQuad(*ir, DofToQuad::TENSOR);
148 dofs1D = maps->ndof;
149 quad1D = maps->nqpt;
150 pa_data.SetSize(symmDims * nq * nf, Device::GetMemoryType());
151 CoefficientVector vel(*u, qs, CoefficientStorage::COMPRESSED);
152
153 CoefficientVector r(qs, CoefficientStorage::COMPRESSED);
154 if (rho == nullptr)
155 {
156 r.SetConstant(1.0);
157 }
158 else if (ConstantCoefficient *const_rho =
159 dynamic_cast<ConstantCoefficient *>(rho))
160 {
161 r.SetConstant(const_rho->constant);
162 }
163 else if (QuadratureFunctionCoefficient *qf_rho =
164 dynamic_cast<QuadratureFunctionCoefficient *>(rho))
165 {
166 r.MakeRef(qf_rho->GetQuadFunction());
167 }
168 else
169 {
170 r.SetSize(nq * nf);
171 auto C_vel = Reshape(vel.HostRead(), dim, nq, nf);
172 auto n = Reshape(geom->normal.HostRead(), nq, dim, nf);
173 auto C = Reshape(r.HostWrite(), nq, nf);
174 int f_ind = 0;
175 for (int f = 0; f < mesh->GetNumFacesWithGhost(); ++f)
176 {
177 Mesh::FaceInformation face = mesh->GetFaceInformation(f);
178 if (face.IsNonconformingCoarse() || !face.IsOfFaceType(type))
179 {
180 // We skip nonconforming coarse faces as they are treated
181 // by the corresponding nonconforming fine faces.
182 continue;
183 }
184 FaceElementTransformations &T =
185 *fes.GetMesh()->GetFaceElementTransformations(f);
186 for (int q = 0; q < nq; ++q)
187 {
188 // Convert to lexicographic ordering
189 int iq =
190 ToLexOrdering(dim, face.element[0].local_face_id, quad1D, q);
191
192 T.SetAllIntPoints(&ir->IntPoint(q));
193 const IntegrationPoint &eip1 = T.GetElement1IntPoint();
194 const IntegrationPoint &eip2 = T.GetElement2IntPoint();
195 real_t rq;
196
197 if (face.IsBoundary())
198 {
199 rq = rho->Eval(*T.Elem1, eip1);
200 }
201 else
202 {
203 real_t udotn = 0.0;
204 for (int d = 0; d < dim; ++d)
205 {
206 udotn += C_vel(d, iq, f_ind) * n(iq, d, f_ind);
207 }
208 if (udotn >= 0.0)
209 {
210 rq = rho->Eval(*T.Elem2, eip2);
211 }
212 else
213 {
214 rq = rho->Eval(*T.Elem1, eip1);
215 }
216 }
217 C(iq, f_ind) = rq;
218 }
219 f_ind++;
220 }
221 MFEM_VERIFY(f_ind == nf, "Incorrect number of faces.");
222 }
223 PADGTraceSetup(dim, dofs1D, quad1D, nf, ir->GetWeights(), geom->detJ,
224 geom->normal, r, vel, alpha, beta, pa_data);
225}
226
231
236
237// PA DGTraceIntegrator Apply kernel
239{
240 ApplyPAKernels::Run(dim, dofs1D, quad1D, nf, maps->B, maps->Bt, pa_data, x,
241 y, dofs1D, quad1D);
242}
243
245{
246 ApplyPATKernels::Run(dim, dofs1D, quad1D, nf, maps->B, maps->Bt, pa_data, x,
247 y, dofs1D, quad1D);
248}
249
251{
252 static Kernels kernels;
253}
254
260
266
268 real_t a, real_t b)
270{
271 rho = &rho_;
272 u = &u_;
273}
274
275/// \cond DO_NOT_DOCUMENT
276
277DGTraceIntegrator::Kernels::Kernels()
278{
279 // 2D
288 // 3D
296}
297
299DGTraceIntegrator::ApplyPAKernels::Fallback(int dim, int, int)
300{
301 if (dim == 2)
302 {
303 return internal::PADGTraceApply2D;
304 }
305 else if (dim == 3)
306 {
307 return internal::PADGTraceApply3D;
308 }
309 else
310 {
311 MFEM_ABORT("");
312 }
313}
314
316DGTraceIntegrator::ApplyPATKernels::Fallback(int dim, int, int)
317{
318 if (dim == 2)
319 {
320 return internal::PADGTraceApplyTranspose2D;
321 }
322 else if (dim == 3)
323 {
324 return internal::PADGTraceApplyTranspose3D;
325 }
326 else
327 {
328 MFEM_ABORT("");
329 }
330}
331
332/// \endcond DO_NOT_DOCUMENT
333
334} // namespace mfem
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the coefficient in the element described by T at the point ip.
void AddMultPA(const Vector &, Vector &) const override
Method for partially assembled action.
void AssemblePABoundaryFaces(const FiniteElementSpace &fes) override
void AddMultTransposePA(const Vector &x, Vector &y) const override
Method for partially assembled transposed action.
DGTraceIntegrator(real_t a, real_t b)
VectorCoefficient * u
void AssemblePAInteriorFaces(const FiniteElementSpace &fes) override
void(*)(const int, const Array< real_t > &, const Array< real_t > &, const Vector &, const Vector &, Vector &, const int, const int) ApplyKernelType
arguments: nf, B, Bt, pa_data, x, y, dofs1D, quad1D
static const IntegrationRule & GetRule(Geometry::Type geom, int order, const FaceElementTransformations &T)
const FaceGeometricFactors * geom
Not owned.
const DofToQuad * maps
Not owned.
static void AddSpecialization()
static MemoryType GetMemoryType()
(DEPRECATED) Equivalent to GetDeviceMemoryType().
Definition device.hpp:281
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
Definition device.hpp:277
@ 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 normal
Normals at all quadrature points.
Definition mesh.hpp:3176
Vector detJ
Determinants of the Jacobians at all quadrature points.
Definition mesh.hpp:3169
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:208
const IntegrationRule * IntRule
Base class for vector Coefficients that optionally depend on time and space.
Vector data type.
Definition vector.hpp:82
virtual const real_t * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
Definition vector.hpp:524
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:584
const real_t alpha
Definition ex15.cpp:369
int dim
Definition ex24.cpp:53
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
mfem::real_t real_t
MFEM_HOST_DEVICE T det(const tensor< T, 1, 1 > &A)
Returns the determinant of a matrix.
Definition tensor.hpp:1406
MFEM_HOST_DEVICE zero dot(const T &, zero)
the dot product of anything with zero is zero
Definition tensor.hpp:288
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
Definition device.hpp:348
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
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
int ToLexOrdering(const int dim, const int face_id, const int size1d, const int index)
Convert a dof face index from Native ordering to lexicographic ordering for quads and hexes.
@ COMPRESSED
Enable all above compressions.
float real_t
Definition config.hpp:46
MemoryType
Memory types supported by MFEM.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30
void forall(int N, lambda &&body)
Definition forall.hpp:839
FaceType
Definition mesh.hpp:49
void vel(const Vector &x, real_t t, Vector &u)
MFEM_HOST_DEVICE real_t abs(const Complex &z)