include/pops/numerics/spatial/primitives/state_access.hpp Source FileΒΆ

adc_cpp: include/pops/numerics/spatial/primitives/state_access.hpp Source File
adc_cpp 0.3.0
Model-free C++23 core for coupled hyperbolic-elliptic systems on adaptive (AMR) meshes, with MPI and GPU (Kokkos) backends
state_access.hpp
Go to the documentation of this file.
1
14
15#pragma once
16
17#include <pops/core/model/physical_model.hpp> // aux_comps, HasPrimitiveVars: optional primitive reconstruction
20#include <pops/core/state/variables.hpp> // VariableSet: SourceFreeModel::conservative_vars forwarding
21#include <pops/mesh/storage/fab2d.hpp> // ConstArray4: load_state / load_aux read path
22
23#include <concepts>
24
25namespace pops {
26
27// aux_comps<Model>() (aux channel width of a model) now lives in the contract header
28// pops/core/physical_model.hpp (included above) so that CompositeModel can propagate it.
29
37template <class M>
38concept DiffusiveModel = requires(const M m) {
39 { m.diffusivity() } -> std::convertible_to<Real>;
40};
41
49template <class M>
51 using State = typename M::State;
52 using Aux = typename M::Aux;
53 static constexpr int n_vars = M::n_vars;
54 static constexpr int n_aux = aux_comps<M>(); // transparent to the wrapped model's aux width
55 M m;
56 POPS_HD State flux(const State& u, const Aux& a, int dir) const { return m.flux(u, a, dir); }
57 POPS_HD Real max_wave_speed(const State& u, const Aux& a, int dir) const {
58 return m.max_wave_speed(u, a, dir);
59 }
60 POPS_HD State source(const State&, const Aux&) const { return State{}; }
61 POPS_HD Real elliptic_rhs(const State& u) const { return m.elliptic_rhs(u); }
62 // SourceFreeModel does not expose the primitive variables: the explicit IMEX half-step that
63 // uses it therefore reconstructs in conservative variables (the direct explicit path itself
64 // has the composite model's conversions and can reconstruct in primitive variables).
65 // Transparent to the HLL/HLLC contract: forwards pressure and signed wave speeds ONLY if M
66 // exposes them (requires clause), so an IMEX half-step can stay on the HLLC flux.
67 POPS_HD Real pressure(const State& u) const
68 requires requires(const M& mm, const State& s) { mm.pressure(s); }
69 {
70 return m.pressure(u);
71 }
72 POPS_HD void wave_speeds(const State& u, const Aux& a, int dir, Real& smin, Real& smax) const
73 requires requires(const M& mm, const State& s, const Aux& aa, int d, Real& lo, Real& hi) {
74 mm.wave_speeds(s, aa, d, lo, hi);
75 }
76 {
77 m.wave_speeds(u, a, dir, smin, smax);
78 }
79 // Roe / HLLC CAPABILITIES (HasRoeDissipation / HasHLLCStructure): forwarded ONLY if M exposes
80 // them (requires clause), exactly like pressure / wave_speeds above and like composite.hpp.
81 // WITHOUT these, an IMEX explicit half-step on riemann='roe' / 'hllc' loses the model's GENERIC
82 // hooks, so RoeFlux / HLLCFlux silently fall back to the canonical Euler-4var path -- which fails
83 // to even COMPILE for a non-Euler model (e.g. a moment hierarchy: n_vars != 4, no pressure). The
84 // 4-var Euler models compiled before only because that fallback happens to fit them.
85 POPS_HD Real contact_speed(const State& ul, const State& ur, Real pl, Real pr, Real sl, Real sr,
86 int dir) const
87 requires requires(const M& mm, const State a_, const State b_, Real p, Real q, Real x, Real y,
88 int d) { mm.contact_speed(a_, b_, p, q, x, y, d); }
89 {
90 return m.contact_speed(ul, ur, pl, pr, sl, sr, dir);
91 }
92 POPS_HD State hllc_star_state(const State& u, Real p, Real s, Real sStar, int dir) const
93 requires requires(const M& mm, const State a_, Real p_, Real s_, Real ss_, int d) {
94 mm.hllc_star_state(a_, p_, s_, ss_, d);
95 }
96 {
97 return m.hllc_star_state(u, p, s, sStar, dir);
98 }
99 POPS_HD State roe_dissipation(const State& ul, const Aux& al, const State& ur, const Aux& ar,
100 int dir) const
101 requires requires(const M& mm, const State a_, const Aux x_, const State b_, const Aux y_,
102 int d) { mm.roe_dissipation(a_, x_, b_, y_, d); }
103 {
104 return m.roe_dissipation(ul, al, ur, ar, dir);
105 }
106 // Forward the VariableSet introspection (HOST): lets positivity_comp resolve the Density role
107 // through the explicit IMEX half-step. Conditional (requires), like pressure / wave_speeds.
109 requires requires { M::conservative_vars(); }
110 {
111 return M::conservative_vars();
112 }
113};
114
119template <class Model>
120POPS_HD inline typename Model::State load_state(const ConstArray4& a, int i, int j) {
121 typename Model::State u;
122 for (int c = 0; c < Model::n_vars; ++c)
123 u[c] = a(i, j, c);
124 return u;
125}
126
134//
135// The extra fields are loaded from the SINGLE SOURCE POPS_AUX_FIELDS (state.hpp): each
136// X(name, idx) generates `if constexpr (NComp > idx) x.name = a(i,j,idx);`, exactly the
137// sequence written by hand before. Adding an extra field => 1 line in POPS_AUX_FIELDS is
138// enough for this device read path to cover it (and the host marshaling, generated from the
139// same table). NComp = kAuxBaseComps: all guards are false -> bit-identical.
140template <int NComp = kAuxBaseComps>
141POPS_HD inline Aux load_aux(const ConstArray4& a, int i, int j) {
142 Aux x{a(i, j, 0), a(i, j, 1), a(i, j, 2)};
143#define POPS_AUX_LOAD(name, idx) \
144 if constexpr (NComp > (idx)) \
145 x.name = a(i, j, idx);
147#undef POPS_AUX_LOAD
148 // NAMED aux fields (ADC-70 phase 1): components from kAuxNamedBase (= 5). Loaded
149 // ONLY if the model declares n_aux > kAuxNamedBase (otherwise if constexpr false -> no codegen,
150 // NComp = kAuxBaseComps stays strictly bit-identical). The bound n_extra is known at
151 // compile time (NComp template): the loop is unrolled and clamped to kAuxMaxExtra (size of
152 // x.extra) -- never an out-of-bounds access on the C array, device-clean.
153 if constexpr (NComp > kAuxNamedBase) {
154 constexpr int n_extra =
155 (NComp - kAuxNamedBase) < kAuxMaxExtra ? (NComp - kAuxNamedBase) : kAuxMaxExtra;
156 for (int k = 0; k < n_extra; ++k)
157 x.extra[k] = a(i, j, kAuxNamedBase + k);
158 }
159 return x;
160}
161
162} // namespace pops
DiffusiveModel: optional concept for models with isotropic scalar diffusion.
Definition state_access.hpp:38
Fab2D: single-grid data on a Box2D (in-house equivalent of AMReX's FArrayBox); Array4 / ConstArray4: ...
Definition amr_hierarchy.hpp:29
double Real
Definition types.hpp:30
POPS_HD Aux load_aux(const ConstArray4 &a, int i, int j)
load_aux<NComp>: reads NComp components of the auxiliary from an Array4 at (i,j).
Definition state_access.hpp:141
constexpr int kAuxMaxExtra
Definition state.hpp:100
constexpr int kAuxNamedBase
Definition state.hpp:154
POPS_HD Model::State load_state(const ConstArray4 &a, int i, int j)
load_state<Model>: reads Model::n_vars scalars at (i,j) from an Array4.
Definition state_access.hpp:120
C++20 concepts defining the contract of the physics layer.
Pointwise types of the physics layer: StateVec<N> (conserved state) and Aux (auxiliary fields from th...
#define POPS_AUX_FIELDS(X)
SINGLE SOURCE of the layout of the EXTRA aux fields (X-macro).
Definition state.hpp:92
#define POPS_AUX_LOAD(name, idx)
POINTWISE auxiliary fields shared with the physics: single coupling channel.
Definition state.hpp:123
READ-only handle (const counterpart of Array4): same layout and same contract (POD device-copyable,...
Definition fab2d.hpp:44
SourceFreeModel<M>: adapter that cancels the source of M (explicit IMEX half-step).
Definition state_access.hpp:50
POPS_HD State hllc_star_state(const State &u, Real p, Real s, Real sStar, int dir) const
Definition state_access.hpp:92
POPS_HD Real pressure(const State &u) const
Definition state_access.hpp:67
static constexpr int n_aux
Definition state_access.hpp:54
M m
Definition state_access.hpp:55
POPS_HD void wave_speeds(const State &u, const Aux &a, int dir, Real &smin, Real &smax) const
Definition state_access.hpp:72
POPS_HD Real elliptic_rhs(const State &u) const
Definition state_access.hpp:61
static VariableSet conservative_vars()
Definition state_access.hpp:108
POPS_HD State source(const State &, const Aux &) const
Definition state_access.hpp:60
typename M::Aux Aux
Definition state_access.hpp:52
POPS_HD State roe_dissipation(const State &ul, const Aux &al, const State &ur, const Aux &ar, int dir) const
Definition state_access.hpp:99
POPS_HD State flux(const State &u, const Aux &a, int dir) const
Definition state_access.hpp:56
POPS_HD Real contact_speed(const State &ul, const State &ur, Real pl, Real pr, Real sl, Real sr, int dir) const
Definition state_access.hpp:85
typename M::State State
Definition state_access.hpp:51
static constexpr int n_vars
Definition state_access.hpp:53
POPS_HD Real max_wave_speed(const State &u, const Aux &a, int dir) const
Definition state_access.hpp:57
A model's variable set: kind (cons/prim), names, size, canonical roles (optional, parallel to names; ...
Definition variables.hpp:58
Base scalar types and the POPS_HD macro (host+device portability).
#define POPS_HD
Definition types.hpp:25
Descriptor of a model's variables (Vars).