Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
riemann.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
21#include "shambackends/math.hpp"
23#include "shambackends/vec.hpp"
24#include <algorithm>
25#include <array>
26#include <cmath>
27#include <iostream>
28namespace shammath {
29
30 template<class Tvec_>
31 struct ConsState {
32 using Tvec = Tvec_;
33 using Tscal = shambase::VecComponent<Tvec>;
34
35 Tscal rho{}, rhoe{};
36 Tvec rhovel{};
37
38 const ConsState &operator+=(const ConsState &);
39 const ConsState &operator-=(const ConsState &);
40 const ConsState &operator*=(const Tscal);
41 };
42
43 template<class Tvec_>
44 struct PrimState {
45 using Tvec = Tvec_;
46 using Tscal = shambase::VecComponent<Tvec>;
47
48 Tscal rho{}, press{};
49 Tvec vel{};
50 };
51
52 template<class Tvec>
54 rho += cst.rho;
55 rhoe += cst.rhoe;
56 rhovel += cst.rhovel;
57 return *this;
58 }
59
60 template<class Tvec>
61 const ConsState<Tvec> operator+(const ConsState<Tvec> &lhs, const ConsState<Tvec> &rhs) {
62 return ConsState<Tvec>(lhs) += rhs;
63 }
64
65 template<class Tvec>
66 const ConsState<Tvec> &ConsState<Tvec>::operator-=(const ConsState<Tvec> &cst) {
67 rho -= cst.rho;
68 rhoe -= cst.rhoe;
69 rhovel -= cst.rhovel;
70 return *this;
71 }
72
73 template<class Tvec>
74 const ConsState<Tvec> operator-(const ConsState<Tvec> &lhs, const ConsState<Tvec> &rhs) {
75 return ConsState<Tvec>(lhs) -= rhs;
76 }
77
78 template<class Tvec>
79 const ConsState<Tvec> &ConsState<Tvec>::operator*=(
80 const typename ConsState<Tvec>::Tscal factor) {
81 rho *= factor;
82 rhoe *= factor;
83 rhovel *= factor;
84 return *this;
85 }
86
87 template<class Tvec>
88 const ConsState<Tvec> operator*(
89 const typename ConsState<Tvec>::Tscal factor, const ConsState<Tvec> &rhs) {
90 return ConsState<Tvec>(rhs) *= factor;
91 }
92
93 template<class Tvec>
94 const ConsState<Tvec> operator*(
95 const ConsState<Tvec> &lhs, const typename ConsState<Tvec>::Tscal factor) {
96 return ConsState<Tvec>(lhs) *= factor;
97 }
98
99 template<class Tvec_>
100 struct Fluxes {
101 using Tvec = Tvec_;
102 using Tscal = shambase::VecComponent<Tvec>;
103
104 std::array<ConsState<Tvec>, 3> F;
105 };
106
107 template<class Tvec>
108 inline constexpr shambase::VecComponent<Tvec> rhoekin(
109 shambase::VecComponent<Tvec> rho, Tvec v) {
110 using Tscal = shambase::VecComponent<Tvec>;
111 const Tscal v2 = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
112 return 0.5 * rho * v2;
113 }
114
115 template<class Tvec>
116 inline constexpr ConsState<Tvec> prim_to_cons(
117 const PrimState<Tvec> prim, typename PrimState<Tvec>::Tscal gamma) {
118 ConsState<Tvec> cons;
119
120 cons.rho = prim.rho;
121
122 const auto rhoeint = prim.press / (gamma - 1.0);
123 cons.rhoe = rhoeint + rhoekin(prim.rho, prim.vel);
124
125 cons.rhovel[0] = prim.rho * prim.vel[0];
126 cons.rhovel[1] = prim.rho * prim.vel[1];
127 cons.rhovel[2] = prim.rho * prim.vel[2];
128
129 return cons;
130 }
131
132 template<class Tvec>
133 inline constexpr PrimState<Tvec> cons_to_prim(
134 const ConsState<Tvec> cons, typename ConsState<Tvec>::Tscal gamma) {
135 PrimState<Tvec> prim;
136
137 prim.rho = cons.rho;
138
139 prim.vel[0] = cons.rhovel[0] / cons.rho;
140 prim.vel[1] = cons.rhovel[1] / cons.rho;
141 prim.vel[2] = cons.rhovel[2] / cons.rho;
142
143 const auto rhoeint = cons.rhoe - rhoekin(prim.rho, prim.vel);
144 prim.press = (gamma - 1.0) * rhoeint;
145
146 return prim;
147 }
148
149 template<class Tvec>
150 inline constexpr ConsState<Tvec> hydro_flux_x(
151 const ConsState<Tvec> cons, typename ConsState<Tvec>::Tscal gamma) {
152 ConsState<Tvec> flux;
153
154 const PrimState<Tvec> prim = cons_to_prim(cons, gamma);
155
156 flux.rho = cons.rhovel[0];
157
158 flux.rhoe = (cons.rhoe + prim.press) * prim.vel[0];
159
160 flux.rhovel[0] = cons.rho * prim.vel[0] * prim.vel[0] + prim.press;
161 flux.rhovel[1] = cons.rho * prim.vel[0] * prim.vel[1];
162 flux.rhovel[2] = cons.rho * prim.vel[0] * prim.vel[2];
163
164 return flux;
165 }
166
167 template<class Tvec>
168 inline constexpr shambase::VecComponent<Tvec> sound_speed(
169 PrimState<Tvec> prim, shambase::VecComponent<Tvec> gamma) {
170 return sycl::sqrt(gamma * prim.press / prim.rho);
171 }
172
173 // template<class Tcons>
174 // inline constexpr Tcons rusanov_flux_x(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
175 // Tcons flux;
176
177 // const auto primL = cons_to_prim(cL, gamma);
178 // const auto primR = cons_to_prim(cR, gamma);
179
180 // const auto csL = sound_speed(primL, gamma);
181 // const auto csR = sound_speed(primR, gamma);
182
183 // const auto S = sham::max(
184 // sham::max(sham::abs(primL.vel[0] - csL), sham::abs(primR.vel[0] - csR)),
185 // sham::max(sham::abs(primL.vel[0] + csL), sham::abs(primR.vel[0] + csR)));
186
187 // const auto fL = hydro_flux_x(cL, gamma);
188 // const auto fR = hydro_flux_x(cR, gamma);
189
190 // return (fL + fR) * 0.5 - (cR - cL) * S;
191 // }
192
193 template<class Tcons>
194 inline constexpr Tcons rusanov_flux_x(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
195 Tcons flux;
196
197 const auto primL = cons_to_prim(cL, gamma);
198 const auto primR = cons_to_prim(cR, gamma);
199
200 const auto csL = sound_speed(primL, gamma);
201 const auto csR = sound_speed(primR, gamma);
202
203 // Equation (10.56) from Toro 3rd Edition , Springer 2009
204 const auto S = sham::max((sham::abs(primL.vel[0]) + csL), (sham::abs(primR.vel[0]) + csR));
205
206 const auto fL = hydro_flux_x(cL, gamma);
207 const auto fR = hydro_flux_x(cR, gamma);
208
209 // Equation (10.55) from Toro 3rd Edition , Springer 2009
210 return 0.5 * ((fL + fR) - (cR - cL) * S);
211 }
212
213 template<class Tcons>
214 inline constexpr Tcons y_to_x(const Tcons c) {
215 Tcons cprime;
216 cprime.rho = c.rho;
217 cprime.rhoe = c.rhoe;
218 cprime.rhovel[0] = c.rhovel[1];
219 cprime.rhovel[1] = -c.rhovel[0];
220 cprime.rhovel[2] = c.rhovel[2];
221 return cprime;
222 }
223
224 template<class Tcons>
225 inline constexpr Tcons x_to_y(const Tcons c) {
226 Tcons cprime;
227 cprime.rho = c.rho;
228 cprime.rhoe = c.rhoe;
229 cprime.rhovel[0] = -c.rhovel[1];
230 cprime.rhovel[1] = c.rhovel[0];
231 cprime.rhovel[2] = c.rhovel[2];
232 return cprime;
233 }
234
235 template<class Tcons>
236 inline constexpr Tcons z_to_x(const Tcons c) {
237 Tcons cprime;
238 cprime.rho = c.rho;
239 cprime.rhoe = c.rhoe;
240 cprime.rhovel[0] = c.rhovel[2];
241 cprime.rhovel[1] = c.rhovel[1];
242 cprime.rhovel[2] = -c.rhovel[0];
243 return cprime;
244 }
245
246 template<class Tcons>
247 inline constexpr Tcons x_to_z(const Tcons c) {
248 Tcons cprime;
249 cprime.rho = c.rho;
250 cprime.rhoe = c.rhoe;
251 cprime.rhovel[0] = -c.rhovel[2];
252 cprime.rhovel[1] = c.rhovel[1];
253 cprime.rhovel[2] = c.rhovel[0];
254 return cprime;
255 }
256
257 template<class Tcons>
258 inline constexpr Tcons invert_axis(const Tcons c) {
259 Tcons cprime;
260 cprime.rho = c.rho;
261 cprime.rhoe = c.rhoe;
262 cprime.rhovel[0] = -c.rhovel[0];
263 cprime.rhovel[1] = -c.rhovel[1];
264 cprime.rhovel[2] = -c.rhovel[2];
265 return cprime;
266 }
267
268 template<class Tcons>
269 inline constexpr Tcons rusanov_flux_y(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
270 return x_to_y(rusanov_flux_x(y_to_x(cL), y_to_x(cR), gamma));
271 }
272
273 template<class Tcons>
274 inline constexpr Tcons rusanov_flux_z(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
275 return x_to_z(rusanov_flux_x(z_to_x(cL), z_to_x(cR), gamma));
276 }
277
278 template<class Tcons>
279 inline constexpr Tcons rusanov_flux_mx(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
280 return invert_axis(rusanov_flux_x(invert_axis(cL), invert_axis(cR), gamma));
281 }
282
283 template<class Tcons>
284 inline constexpr Tcons rusanov_flux_my(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
285 return invert_axis(rusanov_flux_y(invert_axis(cL), invert_axis(cR), gamma));
286 }
287
288 template<class Tcons>
289 inline constexpr Tcons rusanov_flux_mz(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
290 return invert_axis(rusanov_flux_z(invert_axis(cL), invert_axis(cR), gamma));
291 }
292
293 template<class Tcons>
294 inline constexpr auto hll_flux_x(
295 const Tcons consL, const Tcons consR, const typename Tcons::Tscal gamma) {
296 const auto primL = cons_to_prim(consL, gamma);
297 const auto primR = cons_to_prim(consR, gamma);
298
299 const auto csL = sound_speed(primL, gamma);
300 const auto csR = sound_speed(primR, gamma);
301
302 // Teyssier form
303 // const auto S_L = sham::min(primL.vel[0], primR.vel[0]) - sham::max(csL, csR);
304 // const auto S_R = sham::max(primL.vel[0], primR.vel[0]) + sham::max(csL, csR);
305
306 // Toro form Equation (10.48)
307 const auto S_L = sham::min(primL.vel[0] - csL, primR.vel[0] - csR);
308 const auto S_R = sham::max(primL.vel[0] + csL, primR.vel[0] + csR);
309
310 const auto fluxL = hydro_flux_x(consL, gamma);
311 const auto fluxR = hydro_flux_x(consR, gamma);
312
313 // Equation (10.26) from Toro 3rd Edition , Springer 2009
314 auto hll_flux = [=]() {
315 // const auto S_L_upwind = sham::min(S_L, 0.0);
316 // const auto S_R_upwind = sham::max(S_R, 0.0);
317 // const auto S_norm = 1.0 / (S_R_upwind - S_L_upwind);
318 // return (fluxL * S_R_upwind - fluxR * S_L_upwind
319 // + (consR - consL) * S_R_upwind * S_L_upwind)
320 // * S_norm;
321
322 if (S_L >= 0)
323 return fluxL;
324 else if (S_R <= 0)
325 return fluxR;
326 else {
327 const auto S_norm = 1.0 / (S_R - S_L);
328 return (fluxL * S_R - fluxR * S_L + (consR - consL) * S_R * S_L) * S_norm;
329 }
330 };
331
332 return hll_flux();
333 }
334
335 template<class Tcons>
336 inline constexpr Tcons hll_flux_y(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
337 return x_to_y(hll_flux_x(y_to_x(cL), y_to_x(cR), gamma));
338 }
339
340 template<class Tcons>
341 inline constexpr Tcons hll_flux_z(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
342 return x_to_z(hll_flux_x(z_to_x(cL), z_to_x(cR), gamma));
343 }
344
345 template<class Tcons>
346 inline constexpr Tcons hll_flux_mx(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
347 return invert_axis(hll_flux_x(invert_axis(cL), invert_axis(cR), gamma));
348 }
349
350 template<class Tcons>
351 inline constexpr Tcons hll_flux_my(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
352 return invert_axis(hll_flux_y(invert_axis(cL), invert_axis(cR), gamma));
353 }
354
355 template<class Tcons>
356 inline constexpr Tcons hll_flux_mz(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
357 return invert_axis(hll_flux_z(invert_axis(cL), invert_axis(cR), gamma));
358 }
359
369 template<class Tcons>
370 inline constexpr Tcons hllc_flux_x(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
371 Tcons flux;
372 using Tscal = typename Tcons::Tscal;
373 using Tvec = typename Tcons::Tvec;
374
375 // const to prim
376 const auto primL = cons_to_prim(cL, gamma);
377 const auto primR = cons_to_prim(cR, gamma);
378
379 // sound speeds
380 const auto csL = sound_speed(primL, gamma);
381 const auto csR = sound_speed(primR, gamma);
382
383 // Left and right state fluxes
384 const auto FL = hydro_flux_x(cL, gamma);
385 const auto FR = hydro_flux_x(cR, gamma);
386
387 // Left variables
388 const auto rhoL = primL.rho;
389 const auto pressL = primL.press;
390 const auto velxL = primL.vel[0];
391
392 // Right variables
393 const auto rhoR = primR.rho;
394 const auto pressR = primR.press;
395 const auto velxR = primR.vel[0];
396
398 // First compute the pressure estimation in the star region using the primitive variable
399 // solver
400 //
401 // Toro from section 9.3 or Equation (10.67).
402 //
403 // TODO: It will be interresting to implement and test various pressure estimate algorithms
404 // such as : / Two-Rarefaction Riemann Solver (TRRS), Two-Shock Riemann Solver (TSRS) and
405 // Adaptive / Riemann Solvers(AIRS or ANRS)
407 Tscal rho_bar = 0.5 * (rhoL + rhoR);
408 Tscal cs_bar = 0.5 * (csL + csR);
409 Tscal p_pvrs = 0.5 * (pressL + pressR) - 0.5 * (velxR - velxL) * rho_bar * cs_bar;
410 // Pressure in the star region estimate
411 Tscal press_star = sham::max(0., p_pvrs);
412
413 // Once the pressure in the star region is known, we then estimates the wave speeds
414 // following https://ui.adsabs.harvard.edu/abs/1994ShWav...4...25T/abstract or Equations
415 // (10.59 - 10.60) from Toro
416 Tscal qL = 0, qR = 0;
417 if (press_star <= pressL) {
418 qL = 1.;
419 } else {
420 qL = sycl::sqrt(
421 1. + (0.5 * (1. + gamma) / (Tscal) gamma) * (press_star / (Tscal) pressL - 1.));
422 }
423
424 if (press_star <= pressR) {
425 qR = 1.;
426 } else {
427 qR = sycl::sqrt(
428 1. + (0.5 * (1. + gamma) / (Tscal) gamma) * (press_star / (Tscal) pressR - 1.));
429 }
430
431 // wave speed Toro from Equation (10.59)
432 Tscal SL = velxL - csL * qL;
433 Tscal SR = velxR + csR * qR;
434
435 // lagrangian sound speed
436 const Tscal var_L = rhoL * (SL - velxL);
437 const Tscal var_R = rhoR * (SR - velxR);
438
439 // S* speed estimate
440 // Equation (10.37) from Toro 3rd Edition , Springer 2009
441 const Tscal S_star
442 = (primR.press - primL.press + velxL * var_L - velxR * var_R) / (var_L - var_R);
443
444 // New pressure estimate in the star region as average the pressure estimate at right
445 // and left of S_star in the star region
446 // Equation (10.42) from Toro 3rd Edition , Springer 2009
447 const Tscal press_LR
448 = 0.5 * (pressL + pressR + var_L * (S_star - velxL) + var_R * (S_star - velxR));
449 Tvec D{1, 0, 0};
450 Tcons D_star{0, S_star, D};
451
452 // Equation (10.40) from Toro 3rd Edition , Springer 2009
453 // Left intermediate conservative state in the star region
454 // Tcons cL_star = (SL * cL - FL + press_star * D_star) * (1.0 / (SL - S_star));
455 Tcons cL_star = (SL * cL - FL + press_LR * D_star) * (1.0 / (SL - S_star));
456
457 // Equation (10.40) from Toro 3rd Edition , Springer 2009
458 // Right intermediate conservative state in the star region
459 // Tcons cR_star = (SR * cR - FR + press_star * D_star) * (1.0 / (SR - S_star));
460 Tcons cR_star = (SR * cR - FR + press_LR * D_star) * (1.0 / (SR - S_star));
461
462 // intemediate Flux in the star region
463 // Equation (10.38) from Toro 3rd Edition , Springer 2009
464 Tcons FL_star = FL + SL * (cL_star - cL);
465 Tcons FR_star = FR + SR * (cR_star - cR);
466
467 // HLLC flux
468 auto hllc_flux = [=]() {
469 if (SL >= 0) {
470 return FL;
471 } else if (S_star >= 0) {
472 return FL_star;
473 } else if (SR >= 0) {
474 return FR_star;
475 } else
476 return FR;
477 };
478
479 return hllc_flux();
480 }
481
485 template<class Tcons>
486 inline constexpr Tcons hllc_flux_y(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
487 return x_to_y(hllc_flux_x(y_to_x(cL), y_to_x(cR), gamma));
488 }
489
493 template<class Tcons>
494 inline constexpr Tcons hllc_flux_z(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
495 return x_to_z(hllc_flux_x(z_to_x(cL), z_to_x(cR), gamma));
496 }
497
501 template<class Tcons>
502 inline constexpr Tcons hllc_flux_mx(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
503 return invert_axis(hllc_flux_x(invert_axis(cL), invert_axis(cR), gamma));
504 }
505
509 template<class Tcons>
510 inline constexpr Tcons hllc_flux_my(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
511 return invert_axis(hllc_flux_y(invert_axis(cL), invert_axis(cR), gamma));
512 }
513
517 template<class Tcons>
518 inline constexpr Tcons hllc_flux_mz(Tcons cL, Tcons cR, typename Tcons::Tscal gamma) {
519 return invert_axis(hllc_flux_z(invert_axis(cL), invert_axis(cR), gamma));
520 }
521
522} // namespace shammath
namespace for math utility
Definition AABB.hpp:26
constexpr Tcons hllc_flux_y(Tcons cL, Tcons cR, typename Tcons::Tscal gamma)
HLLC flux in the +y direction.
Definition riemann.hpp:486
constexpr Tcons hllc_flux_z(Tcons cL, Tcons cR, typename Tcons::Tscal gamma)
HLLC flux in the +z direction.
Definition riemann.hpp:494
constexpr Tcons hllc_flux_x(Tcons cL, Tcons cR, typename Tcons::Tscal gamma)
HLLC solver based on section 10.4 from Toro 3rd Edition , Springer 2009. The wave speeds estimates ar...
Definition riemann.hpp:370
constexpr Tcons hllc_flux_my(Tcons cL, Tcons cR, typename Tcons::Tscal gamma)
HLLC flux in the -y direction.
Definition riemann.hpp:510
constexpr Tcons hllc_flux_mz(Tcons cL, Tcons cR, typename Tcons::Tscal gamma)
HLLC flux in the -z direction.
Definition riemann.hpp:518
constexpr Tcons hllc_flux_mx(Tcons cL, Tcons cR, typename Tcons::Tscal gamma)
HLLC flux in the -x direction.
Definition riemann.hpp:502