Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
PatchDataLayerLayout.cpp
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
16
17#include "shambase/string.hpp"
21#include <nlohmann/json.hpp>
22
23namespace shamrock::patch {
25 std::stringstream ss;
26
27 if (fields.empty()) {
28 ss << "empty table\n";
29 } else {
30
31 u32 index = 0;
32 for (const var_t &v : fields) {
33 v.visit([&](auto &field) {
34 using f_t = typename std::remove_reference<decltype(field)>::type;
35 using base_t = typename f_t::field_T;
36
37 ss << index << " : " << field.name << " : nvar=" << field.nvar << " type : ";
38
39 if (std::is_same<base_t, f32>::value) {
40 ss << "f32 ";
41 } else if (std::is_same<base_t, f32_2>::value) {
42 ss << "f32_2 ";
43 } else if (std::is_same<base_t, f32_3>::value) {
44 ss << "f32_3 ";
45 } else if (std::is_same<base_t, f32_4>::value) {
46 ss << "f32_4 ";
47 } else if (std::is_same<base_t, f32_8>::value) {
48 ss << "f32_8 ";
49 } else if (std::is_same<base_t, f32_16>::value) {
50 ss << "f32_16";
51 } else if (std::is_same<base_t, f64>::value) {
52 ss << "f64 ";
53 } else if (std::is_same<base_t, f64_2>::value) {
54 ss << "f64_2 ";
55 } else if (std::is_same<base_t, f64_3>::value) {
56 ss << "f64_3 ";
57 } else if (std::is_same<base_t, f64_4>::value) {
58 ss << "f64_4 ";
59 } else if (std::is_same<base_t, f64_8>::value) {
60 ss << "f64_8 ";
61 } else if (std::is_same<base_t, f64_16>::value) {
62 ss << "f64_16";
63 } else if (std::is_same<base_t, u32>::value) {
64 ss << "u32 ";
65 } else if (std::is_same<base_t, u64>::value) {
66 ss << "u64 ";
67 } else if (std::is_same<base_t, u32_3>::value) {
68 ss << "u32_3 ";
69 } else if (std::is_same<base_t, u64_3>::value) {
70 ss << "u64_3 ";
71 } else if (std::is_same<base_t, i64_3>::value) {
72 ss << "i64_3 ";
73 } else {
74 ss << "unknown";
75 }
76
77 ss << "\n";
78
79 index++;
80 });
81 }
82 }
83
84 return ss.str();
85 }
86
87 std::vector<std::string> PatchDataLayerLayout::get_field_names() {
88 std::vector<std::string> ret;
89
90 for (var_t &v : fields) {
91 v.visit([&](auto &field) {
92 ret.push_back(field.name);
93 });
94 }
95
96 return ret;
97 }
98
99 bool PatchDataLayerLayout::has_field_name(const std::string &field_name) const {
100 for (const var_t &fvar : fields) {
101 if (fvar.visit_return([&](const auto &arg) {
102 return field_name == arg.name;
103 })) {
104 return true;
105 }
106 }
107 return false;
108 }
109
110 template<class T>
112 const std::string &field_name, u32 nvar, SourceLocation loc) {
113 if (has_field_name(field_name)) {
115 "add_field -> the name already exists");
116 }
117
118 shamlog_debug_ln(
119 "PatchDataLayerLayout",
120 "adding field :",
121 field_name,
122 nvar,
123 "loc :",
124 loc.format_one_line());
125
126 fields.push_back(var_t{FieldDescriptor<T>(field_name, nvar)});
127 }
128
129 template<class T>
130 u32 PatchDataLayerLayout::get_field_idx(const std::string &field_name) const {
131 for (u32 i = 0; i < fields.size(); i++) {
132 if (const FieldDescriptor<T> *pval
133 = std::get_if<FieldDescriptor<T>>(&fields[i].value)) {
134 if (pval->name == field_name) {
135 return i;
136 }
137 }
138 }
139
141 "the requested field does not exists\n the function : {}\n the field name : {}\n "
142 " current table : \n{}",
143 __PRETTY_FUNCTION__,
144 field_name,
146 }
147
148 template<class T>
149 u32 PatchDataLayerLayout::get_field_idx(const std::string &field_name, u32 nvar) const {
150 for (u32 i = 0; i < fields.size(); i++) {
151 if (const FieldDescriptor<T> *pval
152 = std::get_if<FieldDescriptor<T>>(&fields[i].value)) {
153 if ((pval->name == field_name) && (pval->nvar == nvar)) {
154 return i;
155 }
156 }
157 }
158
160 "the requested field does not exists\n current table : " + get_description_str());
161 }
162
163 void to_json(nlohmann::json &j, const PatchDataLayerLayout &p) {
164
165 using json = nlohmann::json;
166
167 std::vector<json> entries;
168
169 p.for_each_field_any([&](auto &field) {
170 using f_t = typename std::remove_reference<decltype(field)>::type;
171 using base_t = typename f_t::field_T;
172
173 auto get_tname = []() {
174 if (std::is_same<base_t, f32>::value) {
175 return "f32";
176 } else if (std::is_same<base_t, f32_2>::value) {
177 return "f32_2";
178 } else if (std::is_same<base_t, f32_3>::value) {
179 return "f32_3";
180 } else if (std::is_same<base_t, f32_4>::value) {
181 return "f32_4";
182 } else if (std::is_same<base_t, f32_8>::value) {
183 return "f32_8";
184 } else if (std::is_same<base_t, f32_16>::value) {
185 return "f32_16";
186 } else if (std::is_same<base_t, f64>::value) {
187 return "f64";
188 } else if (std::is_same<base_t, f64_2>::value) {
189 return "f64_2";
190 } else if (std::is_same<base_t, f64_3>::value) {
191 return "f64_3";
192 } else if (std::is_same<base_t, f64_4>::value) {
193 return "f64_4";
194 } else if (std::is_same<base_t, f64_8>::value) {
195 return "f64_8";
196 } else if (std::is_same<base_t, f64_16>::value) {
197 return "f64_16";
198 } else if (std::is_same<base_t, u32>::value) {
199 return "u32";
200 } else if (std::is_same<base_t, u64>::value) {
201 return "u64";
202 } else if (std::is_same<base_t, u32_3>::value) {
203 return "u32_3";
204 } else if (std::is_same<base_t, u64_3>::value) {
205 return "u64_3";
206 } else if (std::is_same<base_t, i64_3>::value) {
207 return "i64_3";
208 } else {
210 return "";
211 }
212 };
213
214 entries.push_back(
215 json{
216 {"type", get_tname()},
217 {"nvar", field.nvar},
218 {"field_name", field.name},
219 });
220 });
221
222 j = entries;
223 }
224
225 void from_json(const nlohmann::json &j, PatchDataLayerLayout &p) {
226 for (auto &entry : j) {
227 p.add_field_t(entry["field_name"], entry["nvar"].get<u32>(), entry["type"]);
228 }
229 }
230
232
233 bool ret = true;
234 ret = ret && (lhs.fields.size() == rhs.fields.size());
235
236 for (u32 i = 0; i < lhs.fields.size(); i++) {
237 const PatchDataLayerLayout::var_t &var_lhs = lhs.fields[i];
238 const PatchDataLayerLayout::var_t &var_rhs = rhs.fields[i];
239
240 std::visit(
241 [&](auto &flhs, auto &frhs) {
242 using t1 = typename std::remove_reference<decltype(flhs)>::type;
243 using t2 = typename std::remove_reference<decltype(frhs)>::type;
244
245 ret = ret && std::is_same_v<t1, t2>;
246 ret = ret && (flhs.nvar == frhs.nvar);
247 ret = ret && (flhs.name == frhs.name);
248 },
249 var_lhs.value,
250 var_rhs.value);
251 }
252
253 return ret;
254 }
255
256} // namespace shamrock::patch
257
259// Explicitly instantiate add_field/get_field_idx for all classes in
260// XMAC_LIST_ENABLED_FIELD
262
263#ifndef DOXYGEN
264 #define X(a) \
265 template void shamrock::patch::PatchDataLayerLayout::add_field<a>( \
266 const std::string &field_name, u32 nvar, SourceLocation loc); \
267 template u32 shamrock::patch::PatchDataLayerLayout::get_field_idx<a>( \
268 const std::string &field_name) const; \
269 template u32 shamrock::patch::PatchDataLayerLayout::get_field_idx<a>( \
270 const std::string &field_name, u32 nvar) const;
271XMAC_LIST_ENABLED_FIELD
272 #undef X
273#endif
void from_json(const nlohmann::json &j, PatchDataLayerLayout &p)
Deserialize a PatchDataLayerLayout object from a JSON object.
void to_json(nlohmann::json &j, const PatchDataLayerLayout &p)
Serialize a PatchDataLayerLayout object to a JSON object.
std::uint32_t u32
32 bit unsigned integer
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
std::vector< std::string > get_field_names()
Get the list of field names.
bool has_field_name(const std::string &field_name) const
Check whether a field with the given name already exists.
std::string get_description_str() const
Get the description of the layout.
ExcptTypes make_except_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Create an exception with a message and a location.
void throw_unimplemented(SourceLocation loc=SourceLocation{})
Throw a std::runtime_error saying that the function is unimplemented.
provide information about the source location
std::string format_one_line() const
format the location in a one liner