DNDSR 0.1.0.dev1+gcd065ad
Distributed Numeric Data Structure for CFV
Loading...
Searching...
No Matches
JsonUtil.hpp
Go to the documentation of this file.
1#pragma once
2/// @file JsonUtil.hpp
3/// @brief JSON-to-Eigen conversion utilities and nlohmann_json helper macros.
4
5#include "Defines.hpp"
6#define JSON_ASSERT DNDS_assert
7#include <nlohmann/json.hpp>
8#include "EigenUtil.hpp"
9#include "DeviceStorage.hpp"
10#include "Vector.hpp"
11
12namespace DNDS
13{
14 /// @brief Project-wide JSON type alias: nlohmann/json with ordered keys.
15 /// @details Order preservation makes generated config files diffable across
16 /// re-saves. Use this for all DNDSR-facing configuration objects; reach for
17 /// the unordered `nlohmann::json` only where compatibility with third-party
18 /// producers demands it.
19 using t_jsonconfig = nlohmann::ordered_json;
20}
21
22namespace DNDS
23{
24
25 /// @brief Parse a JSON array into an `Eigen::VectorXd`. Throws a descriptive
26 /// assertion on any JSON error.
27 inline Eigen::VectorXd JsonGetEigenVector(const nlohmann::json &arr)
28 {
29 try
30 {
31 DNDS_assert(arr.is_array());
32 Eigen::VectorXd ret;
33 ret.resize(arr.size());
34 for (int i = 0; i < ret.size(); i++)
35 ret(i) = arr.at(i).get<double>();
36 return ret;
37 }
38 catch (...)
39 {
40 DNDS_assert_info(false, "array parse bad: \n" + arr.dump());
41 return Eigen::VectorXd{0};
42 }
43 }
44
45 /// @brief Parse a JSON array into an `Eigen`::VectorFMTSafe (fixed-point-aware wrapper).
46 /// @details Used by configuration paths that feed values into code paths
47 /// compiled with the fixed-point Eigen shim.
48 inline Eigen::VectorFMTSafe<real, -1> JsonGetEigenVectorFMTSafe(const nlohmann::json &arr)
49 {
50 try
51 {
52 DNDS_assert(arr.is_array());
54 ret.resize(arr.size());
55 for (int i = 0; i < ret.size(); i++)
56 ret(i) = arr.at(i).get<double>();
57 return ret;
58 }
59 catch (...)
60 {
61 DNDS_assert_info(false, "array parse bad");
62 return Eigen::VectorFMTSafe<real, -1>{0};
63 }
64 }
65
66 /// @brief Dump an `Eigen::VectorXd` into a JSON array of doubles.
67 inline auto EigenVectorGetJson(const Eigen::VectorXd &ve)
68 {
69 std::vector<real> v;
70 v.resize(ve.size());
71 for (size_t i = 0; i < ve.size(); i++)
72 v[i] = ve[i];
73 return nlohmann::json(v);
74 }
75
76 /// @brief Dump an `Eigen`::VectorFMTSafe into a JSON array of doubles.
78 {
79 std::vector<real> v;
80 v.resize(ve.size());
81 for (size_t i = 0; i < ve.size(); i++)
82 v[i] = ve[i];
83 return nlohmann::json(v);
84 }
85
86/**
87 * @brief Helper macro: read (`read == true`) or write (`read == false`) a named
88 * member into / out of a `jsonObj`.
89 *
90 * @details Used in the common pattern of mirroring a config struct between
91 * JSON and C++:
92 * ```cpp
93 * #define __F(v) __DNDS__json_to_config(v)
94 * __F(gamma); __F(CFL); __F(maxIter);
95 * ```
96 * Errors during reading are surfaced via @ref DNDS_assert_info with the member name.
97 */
98#define __DNDS__json_to_config(name) \
99 { \
100 if (read) \
101 try \
102 { \
103 ((name) = jsonObj.at(#name).template get<decltype(name)>()); \
104 } \
105 catch (const std::exception &v) \
106 { \
107 std::cerr << v.what() << std::endl; \
108 DNDS_assert_info(false, #name); \
109 } \
110 else \
111 (jsonObj[#name] = (name)); \
112 }
113/**
114 * @brief Like @ref NLOHMANN_DEFINE_TYPE_INTRUSIVE but targets `nlohmann::ordered_json`.
115 * @details DNDSR prefers ordered JSON for configuration; this macro wires up
116 * both `to_json` and `from_json` friend functions against the ordered type.
117 */
118#define DNDS_NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_ORDERED_JSON(Type, ...) \
119 friend void to_json(nlohmann::ordered_json &nlohmann_json_j, const Type &nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
120 friend void from_json(const nlohmann::ordered_json &nlohmann_json_j, Type &nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
121
122/// @brief Like @ref DNDS_NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_ORDERED_JSON but
123/// additionally installs the unordered-JSON overloads for interop with code
124/// that uses `nlohmann::json` directly.
125#define DNDS_NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_ORDERED_AND_UNORDERED_JSON(Type, ...) \
126 friend void to_json(nlohmann::ordered_json &nlohmann_json_j, const Type &nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
127 friend void from_json(const nlohmann::ordered_json &nlohmann_json_j, Type &nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } \
128 friend void to_json(nlohmann::json &nlohmann_json_j, const Type &nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
129 friend void from_json(const nlohmann::json &nlohmann_json_j, Type &nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
130}
131
132namespace Eigen // why doesn't work?
133{
134 inline void to_json(nlohmann::json &j, const VectorXd &v)
135 {
137 }
138
139 inline void from_json(const nlohmann::json &j, VectorXd &v)
140 {
142 }
143
144 inline void to_json(nlohmann::ordered_json &j, const VectorXd &v)
145 {
147 }
148
149 inline void from_json(const nlohmann::ordered_json &j, VectorXd &v)
150 {
152 }
153
154 inline void to_json(nlohmann::ordered_json &j, const VectorFMTSafe<DNDS::real, -1> &v)
155 {
157 }
158
159 inline void from_json(const nlohmann::ordered_json &j, VectorFMTSafe<DNDS::real, -1> &v)
160 {
162 }
163
164 inline void to_json(nlohmann::ordered_json &j, const Vector3d &v)
165 {
167 }
168
169 inline void from_json(const nlohmann::ordered_json &j, Vector3d &v)
170 {
172 }
173}
174
175namespace DNDS
176{
177 inline void to_json(nlohmann::ordered_json &j, const host_device_vector<real> &v)
178 {
179 std::vector<real> v_vec = (std::vector<real>)(v);
180 j = v_vec;
181 }
182
183 inline void from_json(const nlohmann::ordered_json &j, host_device_vector<real> &v)
184 {
185 std::vector<real> v_vec = j;
186 v = v_vec;
187 }
188}
Core type aliases, constants, and metaprogramming utilities for the DNDS framework.
Device memory abstraction layer with backend-specific storage and factory creation.
Eigen extensions: to_string, an fmt-safe wrapper, and fmt formatter specialisations for dense Eigen m...
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
Definition Errors.hpp:113
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
Definition Errors.hpp:108
Host-device vector types with optional GPU storage and device-side views.
Host + optional device vector of trivially copyable T.
Definition Vector.hpp:217
the host side operators are provided as implemented
auto EigenVectorFMTSafeGetJson(const Eigen::VectorFMTSafe< real, -1 > &ve)
Dump an Eigen::VectorFMTSafe into a JSON array of doubles.
Definition JsonUtil.hpp:77
Eigen::VectorXd JsonGetEigenVector(const nlohmann::json &arr)
Parse a JSON array into an Eigen::VectorXd. Throws a descriptive assertion on any JSON error.
Definition JsonUtil.hpp:27
void from_json(const nlohmann::ordered_json &j, host_device_vector< real > &v)
Definition JsonUtil.hpp:183
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
Definition Defines.hpp:105
nlohmann::ordered_json t_jsonconfig
Project-wide JSON type alias: nlohmann/json with ordered keys.
Definition JsonUtil.hpp:19
void to_json(nlohmann::ordered_json &j, const host_device_vector< real > &v)
Definition JsonUtil.hpp:177
Eigen::VectorFMTSafe< real, -1 > JsonGetEigenVectorFMTSafe(const nlohmann::json &arr)
Parse a JSON array into an Eigen::VectorFMTSafe (fixed-point-aware wrapper).
Definition JsonUtil.hpp:48
auto EigenVectorGetJson(const Eigen::VectorXd &ve)
Dump an Eigen::VectorXd into a JSON array of doubles.
Definition JsonUtil.hpp:67
void from_json(const nlohmann::json &j, VectorXd &v)
Definition JsonUtil.hpp:139
void to_json(nlohmann::json &j, const VectorXd &v)
Definition JsonUtil.hpp:134
Eigen::Matrix wrapper that hides begin/end from fmt.
Definition EigenUtil.hpp:62
Eigen::Matrix< real, 5, 1 > v