Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
ExtForceConfig.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
19
21#include "shambackends/math.hpp"
23#include "shambackends/vec.hpp"
25#include <nlohmann/json.hpp>
26#include <type_traits>
27#include <string>
28#include <variant>
29
30namespace shammodels {
31
32 template<class Tvec>
34 using Tscal = shambase::VecComponent<Tvec>;
35 static constexpr u32 dim = shambase::VectorProperties<Tvec>::dimension;
36 struct PointMass {
37 Tscal central_mass;
38 Tscal Racc;
39 Tvec central_pos{};
40 };
41
42 struct PN_PW {
43 Tscal central_mass;
44 Tvec central_pos;
45 Tscal Racc;
46 };
47
49 Tscal central_mass;
50 Tscal Racc;
51 Tscal a_spin;
52 Tvec dir_spin;
53 Tvec central_pos{};
54 Tvec central_vel{};
55 };
56
64 struct ShearingBoxForce {
65 i32_3 shear_base = {1, 0, 0};
66 i32_3 shear_dir = {0, 1, 0};
67
68 Tscal Omega_0;
69 Tscal eta;
70 Tscal q;
71
72 inline Tscal shear_speed(Tscal box_length) { return q * Omega_0 * box_length; }
73
74 ShearingBoxForce() = default;
75 ShearingBoxForce(Tscal Omega_0, Tscal eta, Tscal q)
76 : Omega_0(Omega_0), eta(eta), q(q) {};
77 ShearingBoxForce(i32_3 shear_base, i32_3 shear_dir, Tscal Omega_0, Tscal eta, Tscal q)
78 : shear_base(shear_base), shear_dir(shear_dir), Omega_0(Omega_0), eta(eta), q(q) {};
79 };
80
83 Tscal central_mass;
84 Tscal R0;
85 };
86
89 Tscal eta;
90 };
91
92 using VariantForce = std::variant<
94 PN_PW,
99 VariantForce val;
100 };
101
102 template<class Tvec>
104
105 using Tscal = shambase::VecComponent<Tvec>;
106 static constexpr u32 dim = shambase::VectorProperties<Tvec>::dimension;
107
108 using PointMass = typename ExtForceVariant<Tvec>::PointMass;
109 using PN_PW = typename ExtForceVariant<Tvec>::PN_PW;
110 using LenseThirring = typename ExtForceVariant<Tvec>::LenseThirring;
111 using ShearingBoxForce = typename ExtForceVariant<Tvec>::ShearingBoxForce;
112 using VerticalDiscPotential = typename ExtForceVariant<Tvec>::VerticalDiscPotential;
113 using VelocityDissipation = typename ExtForceVariant<Tvec>::VelocityDissipation;
114
115 std::vector<ExtForceVariant<Tvec>> ext_forces;
116
117 inline void add_point_mass(Tscal central_mass, Tscal Racc, Tvec central_pos = Tvec{}) {
118 ext_forces.push_back(ExtForceVariant<Tvec>{PointMass{central_mass, Racc, central_pos}});
119 }
120
121 inline void add_paczynski_wiita(Tscal central_mass, Tvec central_pos, Tscal Racc) {
122 ext_forces.push_back(ExtForceVariant<Tvec>{PN_PW{central_mass, central_pos, Racc}});
123 }
124
125 inline void add_lense_thirring(
126 Tscal central_mass,
127 Tscal Racc,
128 Tscal a_spin,
129 Tvec dir_spin,
130 Tvec central_pos = Tvec{},
131 Tvec central_vel = Tvec{}) {
132 if (sham::abs(sycl::length(dir_spin) - 1) > 1e-8) {
134 "the sping direction should be a unit vector");
135 }
136 ext_forces.push_back(
138 LenseThirring{central_mass, Racc, a_spin, dir_spin, central_pos, central_vel}});
139 }
140
145 inline void add_shearing_box(Tscal Omega_0, Tscal eta, Tscal q) {
146
147 ext_forces.push_back(ExtForceVariant<Tvec>{ShearingBoxForce{Omega_0, eta, q}});
148 }
149
150 inline void add_vertical_disc_potential(Tscal central_mass, Tscal R0) {
151 ext_forces.push_back(ExtForceVariant<Tvec>{VerticalDiscPotential{central_mass, R0}});
152 }
153
154 inline void add_velocity_dissipation(Tscal eta) {
155 ext_forces.push_back(ExtForceVariant<Tvec>{VelocityDissipation{eta}});
156 }
157 };
158
159} // namespace shammodels
160
161namespace shammodels {
162 template<class Tvec>
163 inline void to_json(nlohmann::json &j, const ExtForceVariant<Tvec> &p) {
164 using T = ExtForceVariant<Tvec>;
165
166 using PointMass = typename T::PointMass;
167 using PN_PW = typename T::PN_PW;
168 using LenseThirring = typename T::LenseThirring;
169 using ShearingBoxForce = typename T::ShearingBoxForce;
170 using VerticalDiscPotential = typename T::VerticalDiscPotential;
171 using VelocityDissipation = typename T::VelocityDissipation;
172
173 if (const PointMass *v = std::get_if<PointMass>(&p.val)) {
174 j
175 = {{"force_type", "point_mass"},
176 {"central_mass", v->central_mass},
177 {"Racc", v->Racc},
178 {"central_pos", v->central_pos}};
179
180 } else if (const PN_PW *v = std::get_if<PN_PW>(&p.val)) {
181 j
182 = {{"force_type", "paczynski_wiita"},
183 {"central_mass", v->central_mass},
184 {"central_pos", v->central_pos},
185 {"Racc", v->Racc}};
186 } else if (const LenseThirring *v = std::get_if<LenseThirring>(&p.val)) {
187 j = {
188 {"force_type", "lense_thirring"},
189 {"central_mass", v->central_mass},
190 {"Racc", v->Racc},
191 {"a_spin", v->a_spin},
192 {"dir_spin", v->dir_spin},
193 {"central_pos", v->central_pos},
194 {"central_vel", v->central_vel},
195 };
196 } else if (const ShearingBoxForce *v = std::get_if<ShearingBoxForce>(&p.val)) {
197 j = {
198 {"force_type", "shearing_box_force"},
199 {"shear_base", v->shear_base},
200 {"shear_dir", v->shear_dir},
201 {"Omega_0", v->Omega_0},
202 {"eta", v->eta},
203 {"q", v->q},
204 };
205 } else if (const VerticalDiscPotential *v = std::get_if<VerticalDiscPotential>(&p.val)) {
206 j
207 = {{"force_type", "vertical_disc_potential"},
208 {"central_mass", v->central_mass},
209 {"R0", v->R0}};
210 } else if (const VelocityDissipation *v = std::get_if<VelocityDissipation>(&p.val)) {
211 j = {{"force_type", "velocity_dissipation"}, {"eta", v->eta}};
212 } else {
214 }
215 }
216
217 template<class Tvec>
218 inline void from_json(const nlohmann::json &j, ExtForceVariant<Tvec> &p) {
219 using Tscal = shambase::VecComponent<Tvec>;
220 using T = ExtForceVariant<Tvec>;
221
222 if (!j.contains("force_type")) {
223 shambase::throw_with_loc<std::runtime_error>("no field eos_type is found in this json");
224 }
225
226 std::string force_type;
227 j.at("force_type").get_to(force_type);
228
229 using PointMass = typename T::PointMass;
230 using PN_PW = typename T::PN_PW;
231 using LenseThirring = typename T::LenseThirring;
232 using ShearingBoxForce = typename T::ShearingBoxForce;
233 using VerticalDiscPotential = typename T::VerticalDiscPotential;
234 using VelocityDissipation = typename T::VelocityDissipation;
235
236 if (force_type == "point_mass") {
237 p.val = PointMass{
238 j.at("central_mass").get<Tscal>(),
239 j.at("Racc").get<Tscal>(),
240 j.value("central_pos", Tvec{}),
241 };
242 } else if (force_type == "paczynski_wiita") {
243 p.val = PN_PW{
244 j.at("central_mass").get<Tscal>(),
245 j.at("central_pos").get<Tvec>(),
246 j.at("Racc").get<Tscal>(),
247 };
248 } else if (force_type == "lense_thirring") {
249 p.val = LenseThirring{
250 j.at("central_mass").get<Tscal>(),
251 j.at("Racc").get<Tscal>(),
252 j.at("a_spin").get<Tscal>(),
253 j.at("dir_spin").get<Tvec>(),
254 j.value("central_pos", Tvec{}),
255 j.value("central_vel", Tvec{}),
256 };
257 } else if (force_type == "shearing_box_force") {
258 p.val = ShearingBoxForce{
259 j.at("shear_base").get<i32_3>(),
260 j.at("shear_dir").get<i32_3>(),
261 j.at("Omega_0").get<Tscal>(),
262 j.at("eta").get<Tscal>(),
263 j.at("q").get<Tscal>(),
264 };
265 } else if (force_type == "vertical_disc_potential") {
266 p.val = VerticalDiscPotential{
267 j.at("central_mass").get<Tscal>(),
268 j.at("R0").get<Tscal>(),
269 };
270 } else if (force_type == "velocity_dissipation") {
271 p.val = VelocityDissipation{j.at("eta").get<Tscal>()};
272 } else {
274 }
275 }
276
277 template<class Tvec>
278 inline void to_json(nlohmann::json &j, const ExtForceConfig<Tvec> &p) {
279 using T = ExtForceConfig<Tvec>;
280
281 j = {{"force_list", p.ext_forces}};
282 }
283
284 template<class Tvec>
285 inline void from_json(const nlohmann::json &j, ExtForceConfig<Tvec> &p) {
286 using T = ExtForceConfig<Tvec>;
287
288 j.at("force_list").get_to(p.ext_forces);
289 }
290} // namespace shammodels
std::uint32_t u32
32 bit unsigned integer
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.
void throw_unimplemented(SourceLocation loc=SourceLocation{})
Throw a std::runtime_error saying that the function is unimplemented.
namespace for models
Definition AMRBlock.hpp:26
void add_shearing_box(Tscal Omega_0, Tscal eta, Tscal q)
Shearing box forces as in athena stone2010_shear_box.
Contains functions for converting between SYCL vector types and C++ standard library array types.