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
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(shambase::format("adiabatic eos: gamma = {}", eos.gamma));
82 }
83 } else {
84 logger::raw_ln(
85 shambase::format(
86 "setting isothermal sound speed^2 (polyk) = {}, gamma = {}",
87 eos.polyk,
88 eos.gamma));
89 if (eos.polyk <= std::numeric_limits<f64>::epsilon()) {
90 logger::raw_ln(
91 shambase::format(
92 "WARNING! sound speed zero in dump!, polyk = {}", eos.polyk));
93 }
94 }
95 }
96
97 eos.polyk2 = hdr.read_header_float<f64>("polyk2");
98 eos.qfacdisc = hdr.read_header_float<f64>("qfacdisc");
99 eos.qfacdisc2 = hdr.read_header_float<f64>("qfacdisc2");
100 eos.isink = hdr.read_header_int<int>("isink");
101
102 if (std::abs(eos.gamma - 1.0) > std::numeric_limits<f64>::epsilon() && maxvxyzu < 4) {
103 logger::raw_ln(
104 shambase::format(
105 "WARNING! compiled for isothermal equation of state but gamma /= 1, gamma={}",
106 eos.gamma));
107 }
108
109 if (ieos == 3 || ieos == 6 || ieos == 7) {
110 if (eos.qfacdisc <= std::numeric_limits<f64>::epsilon()) {
111 if (shamcomm::world_rank() == 0)
112 logger::raw_ln(shambase::format("ERROR: qfacdisc <= 0"));
113 } else {
114 if (shamcomm::world_rank() == 0)
115 logger::raw_ln(shambase::format("qfacdisc = {}", eos.qfacdisc));
116 }
117 }
118
119 if (ieos == 7) {
120 eos.istrat = hdr.read_header_int<int>("istrat");
121 eos.alpha_z = hdr.read_header_float<f64>("alpha_z");
122 eos.beta_z = hdr.read_header_float<f64>("beta_z");
123 eos.z0 = hdr.read_header_float<f64>("z0");
124 if (std::abs(eos.qfacdisc2) <= std::numeric_limits<f64>::epsilon()) {
125 if (shamcomm::world_rank() == 0)
126 logger::raw_ln(shambase::format("ERROR: qfacdisc2 == 0"));
127 } else {
128 if (shamcomm::world_rank() == 0)
129 logger::raw_ln(shambase::format("qfacdisc2 = {}", eos.qfacdisc2));
130 }
131 }
132
133 return eos;
134 }
135
136} // namespace
137
138namespace shammodels::sph::phdump {
139
140 bool is_maxvxyzu_at_least_4(const PhantomDump &dump) { return dump.has_header_entry("alphau"); }
141
143 inline void assert_ieos_val(const PhantomDump &dump, int ieos) {
144 i64 ieos_dump = dump.read_header_int<i64>("ieos");
145 if (ieos_dump != ieos) {
147 "You are querying phantom dump eos {} parameters, even though ieos is {}",
148 ieos,
149 ieos_dump));
150 }
151 }
152
153 /*
154 * EOS 1
155 !
156 !--Isothermal eos
157 !
158 ! :math:`P = c_s^2 \rho`
159 !
160 ! where :math:`c_s^2 \equiv K` is a constant stored in the dump file header
161 !
162 */
163
164 void eos1_load(const PhantomDump &dump, f64 &cs) {
165 assert_ieos_val(dump, 1);
166 EOSPhConfig eos = read_headeropts_eos(dump, 1);
167
168 cs = sycl::sqrt(eos.polyk);
169 }
170
171 void eos1_write(PhantomDump &dump, const f64 &cs) {
172 EOSPhConfig eos;
173
174 eos.polyk = cs * cs;
175
176 dump.table_header_i32.add("ieos", 1);
177 write_headeropts_eos(1, dump, eos);
178 }
179
180 /*
181 case(2,5,17)
182 !
183 !--Adiabatic equation of state (code default)
184 !
185 ! :math:`P = (\gamma - 1) \rho u`
186 !
187 ! if the code is compiled with ISOTHERMAL=yes, ieos=2 gives a polytropic eos:
188 !
189 ! :math:`P = K \rho^\gamma`
190 !
191 ! where K is a global constant specified in the dump header
192 !
193
194 For now I will support only 2
195 */
196 void eos2_load(const PhantomDump &dump, f64 &gamma) {
197 assert_ieos_val(dump, 2);
198 EOSPhConfig eos = read_headeropts_eos(dump, 2);
199
200 gamma = eos.gamma;
201 }
202
203 void eos2_write(PhantomDump &dump, const f64 &gamma) {
204 EOSPhConfig eos;
205
206 eos.gamma = gamma;
207
208 dump.table_header_i32.add("ieos", 2);
209 write_headeropts_eos(2, dump, eos);
210 }
211
212 /*
213 case(3)
214 !
215 !--Locally isothermal disc as in Lodato & Pringle (2007) where
216 !
217 ! :math:`P = c_s^2 (r) \rho`
218 !
219 ! sound speed (temperature) is prescribed as a function of radius using:
220 !
221 ! :math:`c_s = c_{s,0} r^{-q}` where :math:`r = \sqrt{x^2 + y^2 + z^2}`
222 !
223
224 ponrhoi = polyk*(xi**2 + yi**2 + zi**2)**(-qfacdisc) ! polyk is cs^2, so this is (R^2)^(-q)
225 spsoundi = sqrt(ponrhoi)
226 tempi = temperature_coef*mui*ponrhoi
227 */
228
229 void eos3_load(const PhantomDump &dump, f64 &cs0, f64 &q, f64 &r0) {
230 assert_ieos_val(dump, 3);
231 EOSPhConfig eos = read_headeropts_eos(dump, 3);
232
233 cs0 = sycl::sqrt(eos.polyk);
234 q = eos.qfacdisc;
235 r0 = 1; // the polyk in phantom include the 1/r0^2 ?
236 }
237
238 void eos3_write(PhantomDump &dump, const f64 &cs0, const f64 &q, const f64 &r0) {
239 EOSPhConfig eos;
240
241 eos.polyk = cs0 * cs0 / (r0 * r0);
242 eos.qfacdisc = q;
243
244 dump.table_header_i32.add("ieos", 3);
245 write_headeropts_eos(3, dump, eos);
246 }
247
248 /*
249 case(13)
250 !
251 !--Locally isothermal eos for generic hierarchical system
252 !
253 ! Assuming all sink particles are stars.
254 ! Generalisation of Farris et al. (2014; for binaries) to N stars.
255 ! For two sink particles this is identical to ieos=14
256 !
257 */
258
259 void eos13_load(const PhantomDump &dump, f64 &cs0, f64 &q, f64 &r0) {
260 assert_ieos_val(dump, 13);
261 EOSPhConfig eos = read_headeropts_eos(dump, 13);
262
263 cs0 = sycl::sqrt(eos.polyk);
264 q = eos.qfacdisc;
265 r0 = 1; // the polyk in phantom include the 1/r0^2 ?
266 }
267
268 void eos13_write(PhantomDump &dump, const f64 &cs0, const f64 &q, const f64 &r0) {
269 EOSPhConfig eos;
270
271 eos.polyk = cs0 * cs0 / (r0 * r0);
272 eos.qfacdisc = q;
273
274 dump.table_header_i32.add("ieos", 13);
275 write_headeropts_eos(13, dump, eos);
276 }
277
278 /*
279 case(14)
280 !
281 !--Locally isothermal eos from Farris et al. (2014) for binary system
282 !
283 ! uses the locations of the first two sink particles
284 !
285 */
286
287 void eos14_load(const PhantomDump &dump, f64 &cs0, f64 &q, f64 &r0) {
288 assert_ieos_val(dump, 14);
289 EOSPhConfig eos = read_headeropts_eos(dump, 14);
290
291 cs0 = sycl::sqrt(eos.polyk);
292 q = eos.qfacdisc;
293 r0 = 1; // the polyk in phantom include the 1/r0^2 ?
294 }
295
296 void eos14_write(PhantomDump &dump, const f64 &cs0, const f64 &q, const f64 &r0) {
297 EOSPhConfig eos;
298
299 eos.polyk = cs0 * cs0 / (r0 * r0);
300 eos.qfacdisc = q;
301
302 dump.table_header_i32.add("ieos", 14);
303 write_headeropts_eos(14, dump, eos);
304 }
305} // 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:40
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.