25#include <nlohmann/json.hpp>
34 using Tscal = shambase::VecComponent<Tvec>;
35 static constexpr u32 dim = shambase::VectorProperties<Tvec>::dimension;
64 struct ShearingBoxForce {
65 i32_3 shear_base = {1, 0, 0};
66 i32_3 shear_dir = {0, 1, 0};
72 inline Tscal shear_speed(Tscal box_length) {
return q * Omega_0 * box_length; }
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) {};
92 using VariantForce = std::variant<
105 using Tscal = shambase::VecComponent<Tvec>;
106 static constexpr u32 dim = shambase::VectorProperties<Tvec>::dimension;
115 std::vector<ExtForceVariant<Tvec>> ext_forces;
117 inline void add_point_mass(Tscal central_mass, Tscal Racc, Tvec central_pos = Tvec{}) {
121 inline void add_paczynski_wiita(Tscal central_mass, Tvec central_pos, Tscal Racc) {
125 inline void add_lense_thirring(
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");
136 ext_forces.push_back(
138 LenseThirring{central_mass, Racc, a_spin, dir_spin, central_pos, central_vel}});
150 inline void add_vertical_disc_potential(Tscal central_mass, Tscal R0) {
154 inline void add_velocity_dissipation(Tscal eta) {
155 ext_forces.push_back(ExtForceVariant<Tvec>{VelocityDissipation{eta}});
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;
173 if (
const PointMass *v = std::get_if<PointMass>(&p.val)) {
175 = {{
"force_type",
"point_mass"},
176 {
"central_mass", v->central_mass},
178 {
"central_pos", v->central_pos}};
180 }
else if (
const PN_PW *v = std::get_if<PN_PW>(&p.val)) {
182 = {{
"force_type",
"paczynski_wiita"},
183 {
"central_mass", v->central_mass},
184 {
"central_pos", v->central_pos},
186 }
else if (
const LenseThirring *v = std::get_if<LenseThirring>(&p.val)) {
188 {
"force_type",
"lense_thirring"},
189 {
"central_mass", v->central_mass},
191 {
"a_spin", v->a_spin},
192 {
"dir_spin", v->dir_spin},
193 {
"central_pos", v->central_pos},
194 {
"central_vel", v->central_vel},
196 }
else if (
const ShearingBoxForce *v = std::get_if<ShearingBoxForce>(&p.val)) {
198 {
"force_type",
"shearing_box_force"},
199 {
"shear_base", v->shear_base},
200 {
"shear_dir", v->shear_dir},
201 {
"Omega_0", v->Omega_0},
205 }
else if (
const VerticalDiscPotential *v = std::get_if<VerticalDiscPotential>(&p.val)) {
207 = {{
"force_type",
"vertical_disc_potential"},
208 {
"central_mass", v->central_mass},
210 }
else if (
const VelocityDissipation *v = std::get_if<VelocityDissipation>(&p.val)) {
211 j = {{
"force_type",
"velocity_dissipation"}, {
"eta", v->eta}};
219 using Tscal = shambase::VecComponent<Tvec>;
222 if (!j.contains(
"force_type")) {
226 std::string force_type;
227 j.at(
"force_type").get_to(force_type);
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;
236 if (force_type ==
"point_mass") {
238 j.at(
"central_mass").get<Tscal>(),
239 j.at(
"Racc").get<Tscal>(),
240 j.value(
"central_pos", Tvec{}),
242 }
else if (force_type ==
"paczynski_wiita") {
244 j.at(
"central_mass").get<Tscal>(),
245 j.at(
"central_pos").get<Tvec>(),
246 j.at(
"Racc").get<Tscal>(),
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{}),
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>(),
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>(),
270 }
else if (force_type ==
"velocity_dissipation") {
271 p.val = VelocityDissipation{j.at(
"eta").get<Tscal>()};
281 j = {{
"force_list", p.ext_forces}};
288 j.at(
"force_list").get_to(p.ext_forces);
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.
void add_shearing_box(Tscal Omega_0, Tscal eta, Tscal q)
Shearing box forces as in athena stone2010_shear_box.
f = -GMy / sqrt(R0^2 + y^2)
Contains functions for converting between SYCL vector types and C++ standard library array types.