Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
PhantomDumpEOSUtils.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
17
19#include "shambase/string.hpp"
20#include "shambackends/sycl.hpp"
21#include "shamcomm/logs.hpp"
24#include <stdexcept>
25#include <string>
26
27namespace {
28
30 struct EOSPhConfig {
31 i32 isink;
32 f64 gamma = 1;
33 f64 polyk;
34 f64 polyk2;
35 f64 qfacdisc = 0.75;
36 f64 qfacdisc2 = 0.75;
37
38 // if (ieos == 7) {
39 int istrat;
40 f64 alpha_z;
41 f64 beta_z;
42 f64 z0;
43 //}
44 };
45
47 void write_headeropts_eos(int ieos, shammodels::sph::PhantomDump &hdr, EOSPhConfig &eos) {
48 hdr.table_header_i32.add("isink", eos.isink);
49 hdr.table_header_fort_real.add("gamma", eos.gamma);
50 hdr.table_header_fort_real.add("RK2", 1.5 * eos.polyk);
51 hdr.table_header_fort_real.add("polyk2", eos.polyk2);
52 hdr.table_header_fort_real.add("qfacdisc", eos.qfacdisc);
53 hdr.table_header_fort_real.add("qfacdisc2", eos.qfacdisc2);
54
55 if (ieos == 7) {
56 hdr.table_header_i32.add("istrat", eos.istrat);
57 hdr.table_header_fort_real.add("alpha_z", eos.alpha_z);
58 hdr.table_header_fort_real.add("beta_z", eos.beta_z);
59 hdr.table_header_fort_real.add("z0", eos.z0);
60 }
61 }
62
64 EOSPhConfig read_headeropts_eos(const shammodels::sph::PhantomDump &hdr, int ieos) {
65 EOSPhConfig eos;
66
67 f64 RK2;
68
69 eos.gamma = hdr.read_header_float<f64>("gamma");
70 RK2 = hdr.read_header_float<f64>("RK2");
71 eos.polyk = 2.0 / 3.0 * RK2;
72
73 bool use_krome = false; // How do i get this one from a dump Daniel ...
74 int maxvxyzu = (eos.gamma != 1.) ? 4 : 3;
75
76 if (shamcomm::world_rank() == 0) {
77 if (maxvxyzu >= 4) {
78 if (use_krome) {
79 logger::raw_ln("KROME eos: initial gamma = 1.666667");
80 } else {
81 logger::raw_ln(sham::format("adiabatic eos: gamma = {}", eos.gamma));
82 }
83 } else {
85 sham::format(
86 "setting isothermal sound speed^2 (polyk) = {}, gamma = {}",
87 eos.polyk,
88 eos.gamma));
89 if (eos.polyk <= std::numeric_limits<f64>::epsilon()) {
91 sham::format("WARNING! sound speed zero in dump!, polyk = {}", eos.polyk));
92 }
93 }
94 }
95
96 eos.polyk2 = hdr.read_header_float<f64>("polyk2");
97 eos.qfacdisc = hdr.read_header_float<f64>("qfacdisc");
98 eos.qfacdisc2 = hdr.read_header_float<f64>("qfacdisc2");
99 eos.isink = hdr.read_header_int<int>("isink");
100
101 if (std::abs(eos.gamma - 1.0) > std::numeric_limits<f64>::epsilon() && maxvxyzu < 4) {
103 sham::format(
104 "WARNING! compiled for isothermal equation of state but gamma /= 1, gamma={}",
105 eos.gamma));
106 }
107
108 if (ieos == 3 || ieos == 6 || ieos == 7) {
109 if (eos.qfacdisc <= std::numeric_limits<f64>::epsilon()) {
110 if (shamcomm::world_rank() == 0)
111 logger::raw_ln(sham::format("ERROR: qfacdisc <= 0"));
112 } else {
113 if (shamcomm::world_rank() == 0)
114 logger::raw_ln(sham::format("qfacdisc = {}", eos.qfacdisc));
115 }
116 }
117
118 if (ieos == 7) {
119 eos.istrat = hdr.read_header_int<int>("istrat");
120 eos.alpha_z = hdr.read_header_float<f64>("alpha_z");
121 eos.beta_z = hdr.read_header_float<f64>("beta_z");
122 eos.z0 = hdr.read_header_float<f64>("z0");
123 if (std::abs(eos.qfacdisc2) <= std::numeric_limits<f64>::epsilon()) {
124 if (shamcomm::world_rank() == 0)
125 logger::raw_ln(sham::format("ERROR: qfacdisc2 == 0"));
126 } else {
127 if (shamcomm::world_rank() == 0)
128 logger::raw_ln(sham::format("qfacdisc2 = {}", eos.qfacdisc2));
129 }
130 }
131
132 return eos;
133 }
134
135} // namespace
136
137namespace shammodels::sph::phdump {
138
139 bool is_maxvxyzu_at_least_4(const PhantomDump &dump) { return dump.has_header_entry("alphau"); }
140
142 inline void assert_ieos_val(const PhantomDump &dump, int ieos) {
143 i64 ieos_dump = dump.read_header_int<i64>("ieos");
144 if (ieos_dump != ieos) {
146 "You are querying phantom dump eos {} parameters, even though ieos is {}",
147 ieos,
148 ieos_dump));
149 }
150 }
151
152 /*
153 * EOS 1
154 !
155 !--Isothermal eos
156 !
157 ! :math:`P = c_s^2 \rho`
158 !
159 ! where :math:`c_s^2 \equiv K` is a constant stored in the dump file header
160 !
161 */
162
163 void eos1_load(const PhantomDump &dump, f64 &cs) {
164 assert_ieos_val(dump, 1);
165 EOSPhConfig eos = read_headeropts_eos(dump, 1);
166
167 cs = sycl::sqrt(eos.polyk);
168 }
169
170 void eos1_write(PhantomDump &dump, const f64 &cs) {
171 EOSPhConfig eos;
172
173 eos.polyk = cs * cs;
174
175 dump.table_header_i32.add("ieos", 1);
176 write_headeropts_eos(1, dump, eos);
177 }
178
179 /*
180 case(2,5,17)
181 !
182 !--Adiabatic equation of state (code default)
183 !
184 ! :math:`P = (\gamma - 1) \rho u`
185 !
186 ! if the code is compiled with ISOTHERMAL=yes, ieos=2 gives a polytropic eos:
187 !
188 ! :math:`P = K \rho^\gamma`
189 !
190 ! where K is a global constant specified in the dump header
191 !
192
193 For now I will support only 2
194 */
195 void eos2_load(const PhantomDump &dump, f64 &gamma) {
196 assert_ieos_val(dump, 2);
197 EOSPhConfig eos = read_headeropts_eos(dump, 2);
198
199 gamma = eos.gamma;
200 }
201
202 void eos2_write(PhantomDump &dump, const f64 &gamma) {
203 EOSPhConfig eos;
204
205 eos.gamma = gamma;
206
207 dump.table_header_i32.add("ieos", 2);
208 write_headeropts_eos(2, dump, eos);
209 }
210
211 /*
212 case(3)
213 !
214 !--Locally isothermal disc as in Lodato & Pringle (2007) where
215 !
216 ! :math:`P = c_s^2 (r) \rho`
217 !
218 ! sound speed (temperature) is prescribed as a function of radius using:
219 !
220 ! :math:`c_s = c_{s,0} r^{-q}` where :math:`r = \sqrt{x^2 + y^2 + z^2}`
221 !
222
223 ponrhoi = polyk*(xi**2 + yi**2 + zi**2)**(-qfacdisc) ! polyk is cs^2, so this is (R^2)^(-q)
224 spsoundi = sqrt(ponrhoi)
225 tempi = temperature_coef*mui*ponrhoi
226 */
227
228 void eos3_load(const PhantomDump &dump, f64 &cs0, f64 &q, f64 &r0) {
229 assert_ieos_val(dump, 3);
230 EOSPhConfig eos = read_headeropts_eos(dump, 3);
231
232 cs0 = sycl::sqrt(eos.polyk);
233 q = eos.qfacdisc;
234 r0 = 1; // the polyk in phantom include the 1/r0^2 ?
235 }
236
237 void eos3_write(PhantomDump &dump, const f64 &cs0, const f64 &q, const f64 &r0) {
238 EOSPhConfig eos;
239
240 eos.polyk = cs0 * cs0 / (r0 * r0);
241 eos.qfacdisc = q;
242
243 dump.table_header_i32.add("ieos", 3);
244 write_headeropts_eos(3, dump, eos);
245 }
246
247 /*
248 case(13)
249 !
250 !--Locally isothermal eos for generic hierarchical system
251 !
252 ! Assuming all sink particles are stars.
253 ! Generalisation of Farris et al. (2014; for binaries) to N stars.
254 ! For two sink particles this is identical to ieos=14
255 !
256 */
257
258 void eos13_load(const PhantomDump &dump, f64 &cs0, f64 &q, f64 &r0) {
259 assert_ieos_val(dump, 13);
260 EOSPhConfig eos = read_headeropts_eos(dump, 13);
261
262 cs0 = sycl::sqrt(eos.polyk);
263 q = eos.qfacdisc;
264 r0 = 1; // the polyk in phantom include the 1/r0^2 ?
265 }
266
267 void eos13_write(PhantomDump &dump, const f64 &cs0, const f64 &q, const f64 &r0) {
268 EOSPhConfig eos;
269
270 eos.polyk = cs0 * cs0 / (r0 * r0);
271 eos.qfacdisc = q;
272
273 dump.table_header_i32.add("ieos", 13);
274 write_headeropts_eos(13, dump, eos);
275 }
276
277 /*
278 case(14)
279 !
280 !--Locally isothermal eos from Farris et al. (2014) for binary system
281 !
282 ! uses the locations of the first two sink particles
283 !
284 */
285
286 void eos14_load(const PhantomDump &dump, f64 &cs0, f64 &q, f64 &r0) {
287 assert_ieos_val(dump, 14);
288 EOSPhConfig eos = read_headeropts_eos(dump, 14);
289
290 cs0 = sycl::sqrt(eos.polyk);
291 q = eos.qfacdisc;
292 r0 = 1; // the polyk in phantom include the 1/r0^2 ?
293 }
294
295 void eos14_write(PhantomDump &dump, const f64 &cs0, const f64 &q, const f64 &r0) {
296 EOSPhConfig eos;
297
298 eos.polyk = cs0 * cs0 / (r0 * r0);
299 eos.qfacdisc = q;
300
301 dump.table_header_i32.add("ieos", 14);
302 write_headeropts_eos(14, dump, eos);
303 }
304} // namespace shammodels::sph::phdump
void assert_ieos_val(const PhantomDump &dump, int ieos)
Check that the eos in the dump is the expected one.
void eos2_write(PhantomDump &dump, const f64 &gamma)
Write the EOS2 to the phantom dump.
void eos1_write(PhantomDump &dump, const f64 &cs)
Write the EOS1 to the phantom dump.
void eos2_load(const PhantomDump &dump, f64 &gamma)
Load the EOS2 from the phantom dump.
void eos13_write(PhantomDump &dump, const f64 &cs0, const f64 &q, const f64 &r0)
Write the EOS13 to the phantom dump.
void eos3_load(const PhantomDump &dump, f64 &cs0, f64 &q, f64 &r0)
Load the EOS3 from the phantom dump.
bool is_maxvxyzu_at_least_4(const PhantomDump &dump)
check if alphau is set in the header, which is the case for (maxvxyzu >= 4)
void eos13_load(const PhantomDump &dump, f64 &cs0, f64 &q, f64 &r0)
Load the EOS13 from the phantom dump.
void eos14_write(PhantomDump &dump, const f64 &cs0, const f64 &q, const f64 &r0)
Write the EOS14 to the phantom dump.
void eos14_load(const PhantomDump &dump, f64 &cs0, f64 &q, f64 &r0)
Load the EOS14 from the phantom dump.
void eos3_write(PhantomDump &dump, const f64 &cs0, const f64 &q, const f64 &r0)
Write the EOS3 to the phantom dump.
void eos1_load(const PhantomDump &dump, f64 &cs)
Load the EOS1 from the phantom dump.
double f64
Alias for double.
std::int64_t i64
64 bit integer
std::int32_t i32
32 bit 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.
i32 world_rank()
Gives the rank of the current process in the MPI communicator.
Definition worldInfo.cpp:41
void raw_ln(Types... var2)
Prints a log message with multiple arguments followed by a newline.
Definition logs.hpp:89
void add(std::string s, T val)
Adds an entry to the header.
Class representing a Phantom dump file.
T read_header_float(std::string s) const
Retrieves a floating-point value from the table headers.
bool has_header_entry(std::string s) const
Checks if a given string is present in any of the table headers.
PhantomDumpTableHeader< i32 > table_header_i32
Table header for signed 32-bit integer data.
T read_header_int(std::string s) const
Retrieves an integer value from the table headers.
PhantomDumpTableHeader< fort_real > table_header_fort_real
Table header for floating-point data.
Functions related to the MPI communicator.