Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
PatchDataLayerLayout.hpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
10#pragma once
11
21#include "shambase/string.hpp"
24#include <nlohmann/json.hpp>
25#include <sstream>
26#include <variant>
27#include <vector>
28
29namespace shamrock::patch {
30
37 template<class T>
39 public:
41 using field_T = T;
42
44 std::string name;
45
48
55 inline FieldDescriptor() : name(""), nvar(1) {};
56
63 inline FieldDescriptor(std::string name, u32 nvar) : nvar(nvar), name(name) {}
64 };
65
67
68 template<class T>
70
71 // using var_t = var_t_template<FieldDescriptor>;
73
74 std::vector<var_t> fields;
75
76 public:
84 template<class T>
85 void add_field(
86 const std::string &field_name, u32 nvar, SourceLocation loc = SourceLocation{});
87
95 template<class T>
96 FieldDescriptor<T> get_field(const std::string &field_name);
97
105 template<class T>
107
115 template<class T>
116 u32 get_field_idx(const std::string &field_name) const;
117
126 template<class T>
127 u32 get_field_idx(const std::string &field_name, u32 nvar) const;
128
137 template<class T>
138 bool check_field_type(u32 idx);
139
147 template<class T>
148 inline bool check_main_field_type() {
149 return check_field_type<T>(0);
150 }
151
157 [[nodiscard]] inline const var_t &get_main_field_any() const { return fields[0]; }
158
164 std::string get_description_str() const;
165
171 std::vector<std::string> get_field_names();
172
179 template<class Functor>
180 inline void for_each_field_any(Functor &&func) const {
181 for (auto &f : fields) {
182 f.visit([&](auto &arg) {
183 func(arg);
184 });
185 }
186 }
187
195 inline void add_field_t(std::string fname, u32 nvar, std::string type) {
196 if (type == "f32") {
197 add_field<f32>(fname, nvar);
198 } else if (type == "f32_2") {
199 add_field<f32_2>(fname, nvar);
200 } else if (type == "f32_3") {
201 add_field<f32_3>(fname, nvar);
202 } else if (type == "f32_4") {
203 add_field<f32_4>(fname, nvar);
204 } else if (type == "f32_8") {
205 add_field<f32_8>(fname, nvar);
206 } else if (type == "f32_16") {
207 add_field<f32_16>(fname, nvar);
208 } else if (type == "f64") {
209 add_field<f64>(fname, nvar);
210 } else if (type == "f64_2") {
211 add_field<f64_2>(fname, nvar);
212 } else if (type == "f64_3") {
213 add_field<f64_3>(fname, nvar);
214 } else if (type == "f64_4") {
215 add_field<f64_4>(fname, nvar);
216 } else if (type == "f64_8") {
217 add_field<f64_8>(fname, nvar);
218 } else if (type == "f64_16") {
219 add_field<f64_16>(fname, nvar);
220 } else if (type == "u32") {
221 add_field<u32>(fname, nvar);
222 } else if (type == "u64") {
223 add_field<u64>(fname, nvar);
224 } else if (type == "u32_3") {
225 add_field<u32_3>(fname, nvar);
226 } else if (type == "u64_3") {
227 add_field<u64_3>(fname, nvar);
228 } else if (type == "i64_3") {
229 add_field<i64_3>(fname, nvar);
230 } else {
232 "the select type is not recognized");
233 }
234 }
235
248 friend bool operator==(const PatchDataLayerLayout &lhs, const PatchDataLayerLayout &rhs);
249 };
250
260 void to_json(nlohmann::json &j, const PatchDataLayerLayout &p);
261
271 void from_json(const nlohmann::json &j, PatchDataLayerLayout &p);
272
285 bool operator==(const PatchDataLayerLayout &lhs, const PatchDataLayerLayout &rhs);
286
288 // out of line implementation of the PatchDataLayerLayout
290
291 template<class T>
293 const std::string &field_name, u32 nvar, SourceLocation loc) {
294 bool found = false;
295
296 for (var_t &fvar : fields) {
297 fvar.visit([&](auto &arg) {
298 if (field_name == arg.name) {
299 found = true;
300 }
301 });
302 }
303
304 if (found) {
306 "add_field -> the name already exists");
307 }
308
309 shamlog_debug_ln(
310 "PatchDataLayerLayout",
311 "adding field :",
312 field_name,
313 nvar,
314 "loc :",
315 loc.format_one_line());
316
317 fields.push_back(var_t{FieldDescriptor<T>(field_name, nvar)});
318 }
319
320 template<class T>
322 const std::string &field_name) {
323
324 for (var_t &fvar : fields) {
325 if (FieldDescriptor<T> *pval = std::get_if<FieldDescriptor<T>>(&fvar.value)) {
326 if (pval->name == field_name) {
327 return *pval;
328 }
329 }
330 }
331
333 "the requested field does not exists\n current table : " + get_description_str());
334 }
335
336 template<class T>
338
339 if (FieldDescriptor<T> *pval = std::get_if<FieldDescriptor<T>>(&fields[idx].value)) {
340 return *pval;
341 }
342
344 "the required type does no match at index " + std::to_string(idx)
345 + "\n current table : " + get_description_str());
346 }
347
348 template<class T>
349 inline u32 PatchDataLayerLayout::get_field_idx(const std::string &field_name) const {
350 for (u32 i = 0; i < fields.size(); i++) {
351 if (const FieldDescriptor<T> *pval
352 = std::get_if<FieldDescriptor<T>>(&fields[i].value)) {
353 if (pval->name == field_name) {
354 return i;
355 }
356 }
357 }
358
360 "the requested field does not exists\n the function : {}\n the field name : {}\n "
361 " current table : \n{}",
362 __PRETTY_FUNCTION__,
363 field_name,
365 }
366
367 template<class T>
368 inline u32 PatchDataLayerLayout::get_field_idx(const std::string &field_name, u32 nvar) const {
369 for (u32 i = 0; i < fields.size(); i++) {
370 if (const FieldDescriptor<T> *pval
371 = std::get_if<FieldDescriptor<T>>(&fields[i].value)) {
372 if ((pval->name == field_name) && (pval->nvar == nvar)) {
373 return i;
374 }
375 }
376 }
377
379 "the requested field does not exists\n current table : " + get_description_str());
380 }
381
382 template<class T>
384 var_t &tmp = fields[idx];
385
386 FieldDescriptor<T> *pval = std::get_if<FieldDescriptor<T>>(&tmp.value);
387
388 if (pval) {
389 return true;
390 } else {
391 return false;
392 }
393 }
394
395} // namespace shamrock::patch
Field variant object to instanciate a variant on the patch types.
Source location utility.
std::uint32_t u32
32 bit unsigned integer
Structure describing a field in a patch data layout.
T field_T
The type of the field mirrored from the template type.
std::string name
The name of the field.
FieldDescriptor(std::string name, u32 nvar)
Constructor with a given name and number of variables.
u32 nvar
The number of variables of the field per object.
u32 get_field_idx(const std::string &field_name) const
Get the field id if matching name & type.
friend bool operator==(const PatchDataLayerLayout &lhs, const PatchDataLayerLayout &rhs)
Overloaded equality operator for PatchDataLayerLayout class.
void add_field(const std::string &field_name, u32 nvar, SourceLocation loc=SourceLocation{})
add a field of type T to the layout
const var_t & get_main_field_any() const
Get the main field description as a variant object.
bool check_field_type(u32 idx)
check that field of id @idx is of type T
bool check_main_field_type()
check that main field (id=0)is of type T
FieldDescriptor< T > get_field(const std::string &field_name)
Get the field description id if matching name & type.
std::vector< std::string > get_field_names()
Get the list of field names.
void for_each_field_any(Functor &&func) const
for each visit of each field
void add_field_t(std::string fname, u32 nvar, std::string type)
Add a field with type specified as a string.
std::string get_description_str() const
Get the description of the layout.
This header file contains utility functions related to exception handling in the code.
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
provide information about the source location
std::string format_one_line() const
format the location in a one liner