include/pops/core/state/variables.hpp Source FileΒΆ

adc_cpp: include/pops/core/state/variables.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
variables.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <stdexcept>
4#include <string>
5#include <vector>
6
17
18namespace pops {
19
23
27enum class VariableRole {
28 Density,
32 Energy,
38 Scalar,
39 Custom
40};
41
44inline VariableRole role_from_name(const std::string& s);
45
47struct Variable {
48 std::string name;
51};
52
60 std::vector<std::string> names;
61 int size;
62 std::vector<VariableRole> roles{};
63 std::vector<std::string> user_roles{};
65
67 int index_of(VariableRole role) const {
68 for (int i = 0; i < static_cast<int>(roles.size()); ++i)
69 if (roles[i] == role)
70 return i;
71 return -1;
72 }
78 int index_of(const std::string& role) const {
79 if (role.empty())
80 return -1;
81 const VariableRole r = role_from_name(role);
82 if (r != VariableRole::Custom)
83 return index_of(r);
84 for (int i = 0; i < static_cast<int>(user_roles.size()); ++i)
85 if (user_roles[i] == role)
86 return i;
87 return -1;
88 }
90 Variable at(int i) const {
91 return {names[i], i < static_cast<int>(roles.size()) ? roles[i] : VariableRole::Custom, i};
92 }
93};
94
97inline const char* role_name(VariableRole r) {
98 switch (r) {
100 return "density";
102 return "momentum_x";
104 return "momentum_y";
106 return "momentum_z";
108 return "energy";
110 return "velocity_x";
112 return "velocity_y";
114 return "velocity_z";
116 return "pressure";
118 return "temperature";
120 return "scalar";
122 return "custom";
123 }
124 return "custom";
125}
126
130inline VariableRole role_from_name(const std::string& s) {
131 if (s == "density")
133 if (s == "momentum_x")
135 if (s == "momentum_y")
137 if (s == "momentum_z")
139 if (s == "energy")
141 if (s == "velocity_x")
143 if (s == "velocity_y")
145 if (s == "velocity_z")
147 if (s == "pressure")
149 if (s == "temperature")
151 if (s == "scalar")
154}
155
158inline std::string names_csv(const VariableSet& vs) {
159 std::string s;
160 for (std::size_t i = 0; i < vs.names.size(); ++i) {
161 if (i)
162 s += ',';
163 s += vs.names[i];
164 }
165 return s;
166}
167
172inline std::string roles_csv(const VariableSet& vs) {
173 std::string s;
174 for (std::size_t i = 0; i < vs.roles.size(); ++i) {
175 if (i)
176 s += ',';
177 if (i < vs.user_roles.size() && !vs.user_roles[i].empty())
178 s += vs.user_roles[i];
179 else
180 s += role_name(vs.roles[i]);
181 }
182 return s;
183}
184
190inline void parse_roles_into(VariableSet& vs, const std::string& csv) {
191 if (csv.empty())
192 return;
193 std::vector<std::string> labels;
194 bool any_user = false;
195 std::size_t start = 0;
196 for (;;) {
197 const std::size_t comma = csv.find(',', start);
198 const std::string tok =
199 csv.substr(start, comma == std::string::npos ? std::string::npos : comma - start);
200 const VariableRole r = role_from_name(tok);
201 vs.roles.push_back(r);
202 const bool is_user = (r == VariableRole::Custom && tok != role_name(VariableRole::Custom));
203 labels.push_back(is_user ? tok : std::string());
204 any_user = any_user || is_user;
205 if (comma == std::string::npos)
206 break;
207 start = comma + 1;
208 }
209 if (any_user)
210 vs.user_roles = std::move(labels);
211}
212
219inline int coupling_role_index(const VariableSet& vs, VariableRole role, int fallback,
220 const char* origin, const std::string& block) {
221 if (vs.roles.empty())
222 return fallback; // roleless legacy block: keep the canonical fallback
223 const int c = vs.index_of(role);
224 if (c >= 0)
225 return c;
226 throw std::runtime_error(std::string(origin) + " : block '" + block + "' declares roles (" +
227 roles_csv(vs) + ") but not the role '" + role_name(role) +
228 "' this coupling requires (no silent fallback to component " +
229 std::to_string(fallback) + ")");
230}
231
234template <class Model>
235std::string var_names_meta() {
236 return names_csv(Model::conservative_vars()) + "|" + names_csv(Model::primitive_vars());
237}
238
240template <class Model>
241std::string roles_meta() {
242 return roles_csv(Model::conservative_vars()) + "|" + roles_csv(Model::primitive_vars());
243}
244
247
248} // namespace pops
249
256#define POPS_EXPORT_BLOCK_METADATA(MODEL) \
257 extern "C" const char* pops_compiled_var_names() { \
258 static const std::string s = pops::var_names_meta<MODEL>(); \
259 return s.c_str(); \
260 } \
261 extern "C" const char* pops_compiled_roles() { \
262 static const std::string s = pops::roles_meta<MODEL>(); \
263 return s.c_str(); \
264 }
265
269#define POPS_EXPORT_BLOCK_GAMMA(GAMMA) \
270 extern "C" double pops_compiled_gamma() { \
271 return (GAMMA); \
272 }
Definition amr_hierarchy.hpp:29
VariableKind
Kind of a variable set: conserved (U) or primitive (W).
Definition variables.hpp:22
std::string roles_meta()
A model's "roles" metadata: "cons_roles_csv|prim_roles_csv" (empty side = roles not provided).
Definition variables.hpp:241
int coupling_role_index(const VariableSet &vs, VariableRole role, int fallback, const char *origin, const std::string &block)
Resolve a REQUIRED canonical role to its component in vs, for a NAMED coupling (add_collision / add_t...
Definition variables.hpp:219
const char * role_name(VariableRole r)
Human-readable name of a role (introspection, Python binding).
Definition variables.hpp:97
std::string roles_csv(const VariableSet &vs)
CSV of a VariableSet's roles (role_name, separator ',').
Definition variables.hpp:172
VariableRole
PHYSICAL role of a component.
Definition variables.hpp:27
void parse_roles_into(VariableSet &vs, const std::string &csv)
Inverse of roles_csv: fill vs.roles (and vs.user_roles for any NON-canonical token) from a roles CSV.
Definition variables.hpp:190
VariableRole role_from_name(const std::string &s)
Forward declaration: VariableSet::index_of(const std::string&) resolves a canonical role NAME via rol...
Definition variables.hpp:130
std::string names_csv(const VariableSet &vs)
CSV of a VariableSet's names (separator ',').
Definition variables.hpp:158
std::string var_names_meta()
A model's "names" metadata: "cons_csv|prim_csv" (separator '|' between the two sets).
Definition variables.hpp:235
A model's variable set: kind (cons/prim), names, size, canonical roles (optional, parallel to names; ...
Definition variables.hpp:58
Variable at(int i) const
Full descriptor of component i (Custom role if not provided).
Definition variables.hpp:90
std::vector< std::string > user_roles
parallel to names; per-component user-defined role label (Custom role); empty entry = canonical role
Definition variables.hpp:63
VariableKind kind
Definition variables.hpp:59
int index_of(const std::string &role) const
Index of the component carrying role addressed BY NAME: a canonical role name (role_from_name) first,...
Definition variables.hpp:78
std::vector< VariableRole > roles
parallel to names; empty = roles not provided
Definition variables.hpp:62
std::vector< std::string > names
Definition variables.hpp:60
int index_of(VariableRole role) const
Index of the component carrying role (first occurrence), -1 if absent.
Definition variables.hpp:67
int size
Definition variables.hpp:61
A variable: name, physical role, component index in the state.
Definition variables.hpp:47
std::string name
Definition variables.hpp:48
VariableRole role
Definition variables.hpp:49
int component
Definition variables.hpp:50