13#include "../global/global.h"
14#include "../global/global_cuda.h"
15#include "../utils/cuda_utilities.h"
16#include "../utils/gpu.hpp"
17#include "../utils/hydro_utilities.h"
18#include "../utils/mhd_utilities.h"
54 #error "no reconstruction selected"
63 Real magnetosonic_speed_fast, magnetosonic_speed_slow, magnetosonic_speed_fast_squared,
64 magnetosonic_speed_slow_squared;
65 Real alpha_fast, alpha_slow;
72 Real q_prime_fast, q_prime_slow;
73 Real a_prime_fast, a_prime_slow;
86 Real a0, a1, a2, a3, a4;
109bool __device__ __host__ __inline__
Thread_Guard(
int const &nx,
int const &ny,
int const &nz,
int const &xid,
110 int const &yid,
int const &zid)
115 bool out_of_bounds_thread = xid < order - 1 or xid >= nx - order;
119 out_of_bounds_thread = yid < order - 1 or yid >= ny - order or out_of_bounds_thread;
124 out_of_bounds_thread = zid < order - 1 or zid >= nz - order or out_of_bounds_thread;
128 out_of_bounds_thread = zid >= nz or out_of_bounds_thread;
131 return out_of_bounds_thread;
153 Real
const *dev_conserved,
size_t const &xid,
size_t const &yid,
size_t const &zid,
size_t const &nx,
154 size_t const &ny,
size_t const &n_cells,
size_t const &o1,
size_t const &o2,
size_t const &o3, Real
const &gamma)
156 size_t const id = cuda_utilities::compute1DIndex(xid, yid, zid, nx, ny);
162 loaded_data.density = dev_conserved[grid_enum::density * n_cells + id];
163 loaded_data.velocity.
x() = dev_conserved[o1 * n_cells + id] / loaded_data.density;
164 loaded_data.velocity.y() = dev_conserved[o2 * n_cells + id] / loaded_data.density;
165 loaded_data.velocity.z() = dev_conserved[o3 * n_cells + id] / loaded_data.density;
170 auto magnetic_centered = mhd::utils::cellCenteredMagneticFields(dev_conserved,
id, xid, yid, zid, n_cells, nx, ny);
172 case grid_enum::momentum_x:
173 loaded_data.magnetic.x() = magnetic_centered.x();
174 loaded_data.magnetic.y() = magnetic_centered.y();
175 loaded_data.magnetic.z() = magnetic_centered.z();
177 case grid_enum::momentum_y:
178 loaded_data.magnetic.x() = magnetic_centered.y();
179 loaded_data.magnetic.y() = magnetic_centered.z();
180 loaded_data.magnetic.z() = magnetic_centered.x();
182 case grid_enum::momentum_z:
183 loaded_data.magnetic.x() = magnetic_centered.z();
184 loaded_data.magnetic.y() = magnetic_centered.x();
185 loaded_data.magnetic.z() = magnetic_centered.y();
192 Real
const energy = dev_conserved[grid_enum::Energy * n_cells + id];
193 Real
const gas_energy = dev_conserved[grid_enum::GasEnergy * n_cells + id];
196 loaded_data.density, loaded_data.velocity.
x(), loaded_data.velocity.y(), loaded_data.velocity.z());
199 energy_non_thermal +=
200 mhd::utils::computeMagneticEnergy(magnetic_centered.x(), magnetic_centered.y(), magnetic_centered.z());
203 loaded_data.pressure = hydro_utilities::Get_Pressure_From_DE(energy, energy - energy_non_thermal, gas_energy, gamma);
204 loaded_data.gas_energy = gas_energy / loaded_data.density;
207 loaded_data.pressure = hydro_utilities::Calc_Pressure_Primitive(
208 dev_conserved[grid_enum::Energy * n_cells +
id], loaded_data.density, loaded_data.velocity.
x(),
209 loaded_data.velocity.y(), loaded_data.velocity.z(), gamma, loaded_data.magnetic.x(), loaded_data.magnetic.y(),
210 loaded_data.magnetic.z());
212 loaded_data.pressure = hydro_utilities::Calc_Pressure_Primitive(
213 dev_conserved[grid_enum::Energy * n_cells +
id], loaded_data.density, loaded_data.velocity.
x(),
214 loaded_data.velocity.y(), loaded_data.velocity.z(), gamma);
219 for (
size_t i = 0; i < grid_enum::nscalars; i++) {
220 loaded_data.scalar[i] = dev_conserved[(grid_enum::scalar + i) * n_cells +
id] / loaded_data.density;
242template <
int reconstruction>
244 size_t const xid,
size_t const yid,
size_t const zid)
255 bool out_of_bounds_thread =
false;
258 out_of_bounds_thread = xid < order - 1 or xid >= nx - order or out_of_bounds_thread;
262 out_of_bounds_thread = yid < order - 1 or yid >= ny - order or out_of_bounds_thread;
267 out_of_bounds_thread = zid < order - 1 or zid >= nz - order or out_of_bounds_thread;
271 out_of_bounds_thread = zid >= nz or out_of_bounds_thread;
274 return out_of_bounds_thread;
289 Real
const &coef = 1.0)
293 slopes.density = coef * (right.density - left.density);
294 slopes.velocity.
x() = coef * (right.velocity.
x() - left.velocity.
x());
295 slopes.velocity.y() = coef * (right.velocity.y() - left.velocity.y());
296 slopes.velocity.z() = coef * (right.velocity.z() - left.velocity.z());
297 slopes.pressure = coef * (right.pressure - left.pressure);
300 slopes.magnetic.y() = coef * (right.magnetic.y() - left.magnetic.y());
301 slopes.magnetic.z() = coef * (right.magnetic.z() - left.magnetic.z());
305 slopes.gas_energy = coef * (right.gas_energy - left.gas_energy);
309 for (
size_t i = 0; i < grid_enum::nscalars; i++) {
310 slopes.scalar[i] = coef * (right.scalar[i] - left.scalar[i]);
331 auto Calc_Vl_Slope = [](Real
const &left, Real
const &right) -> Real {
332 if (left * right > 0.0) {
333 return 2.0 * left * right / (left + right);
339 vl_slopes.density = Calc_Vl_Slope(left_slope.density, right_slope.density);
340 vl_slopes.velocity.
x() = Calc_Vl_Slope(left_slope.velocity.
x(), right_slope.velocity.
x());
341 vl_slopes.velocity.y() = Calc_Vl_Slope(left_slope.velocity.y(), right_slope.velocity.y());
342 vl_slopes.velocity.z() = Calc_Vl_Slope(left_slope.velocity.z(), right_slope.velocity.z());
343 vl_slopes.pressure = Calc_Vl_Slope(left_slope.pressure, right_slope.pressure);
346 vl_slopes.magnetic.y() = Calc_Vl_Slope(left_slope.magnetic.y(), right_slope.magnetic.y());
347 vl_slopes.magnetic.z() = Calc_Vl_Slope(left_slope.magnetic.z(), right_slope.magnetic.z());
351 vl_slopes.gas_energy = Calc_Vl_Slope(left_slope.gas_energy, right_slope.gas_energy);
355 for (
size_t i = 0; i < grid_enum::nscalars; i++) {
356 vl_slopes.scalar[i] = Calc_Vl_Slope(left_slope.scalar[i], right_slope.scalar[i]);
382 output.magnetosonic_speed_fast =
383 mhd::utils::fastMagnetosonicSpeed(primitive.density, primitive.pressure, primitive.magnetic.x(),
384 primitive.magnetic.y(), primitive.magnetic.z(), gamma);
385 output.magnetosonic_speed_slow =
386 mhd::utils::slowMagnetosonicSpeed(primitive.density, primitive.pressure, primitive.magnetic.x(),
387 primitive.magnetic.y(), primitive.magnetic.z(), gamma);
389 output.magnetosonic_speed_fast_squared = output.magnetosonic_speed_fast * output.magnetosonic_speed_fast;
390 output.magnetosonic_speed_slow_squared = output.magnetosonic_speed_slow * output.magnetosonic_speed_slow;
392 Real
const sound_speed_squared = output.sound_speed * output.sound_speed;
395 if (Real
const denom = (output.magnetosonic_speed_fast_squared - output.magnetosonic_speed_slow_squared),
396 numerator_2 = (output.magnetosonic_speed_fast_squared - sound_speed_squared);
397 denom <= 0.0 or numerator_2 <= 0.0) {
398 output.alpha_fast = 1.0;
399 output.alpha_slow = 0.0;
400 }
else if (Real
const numerator_1 = (sound_speed_squared - output.magnetosonic_speed_slow_squared);
401 numerator_1 <= 0.0) {
402 output.alpha_fast = 0.0;
403 output.alpha_slow = 1.0;
405 output.alpha_fast = sqrt(numerator_1 / denom);
406 output.alpha_slow = sqrt(numerator_2 / denom);
411 Real
const beta_denom = rhypot(primitive.magnetic.y(), primitive.magnetic.z());
412 output.beta_y = (isfinite(beta_denom)) ? primitive.magnetic.y() * beta_denom : 1.0;
413 output.beta_z = (isfinite(beta_denom)) ? primitive.magnetic.z() * beta_denom : 0.0;
416 output.sign = copysign(1.0, primitive.magnetic.x());
417 output.n_fs = 0.5 / sound_speed_squared;
418 output.q_prime_fast = output.sign * output.n_fs * output.alpha_fast * output.magnetosonic_speed_fast;
419 output.q_prime_slow = output.sign * output.n_fs * output.alpha_slow * output.magnetosonic_speed_slow;
420 output.q_fast = output.sign * output.alpha_fast * output.magnetosonic_speed_fast;
421 output.q_slow = output.sign * output.alpha_slow * output.magnetosonic_speed_slow;
424 output.a_fast = output.alpha_fast * output.sound_speed * sqrt(primitive.density);
425 output.a_slow = output.alpha_slow * output.sound_speed * sqrt(primitive.density);
426 output.a_prime_fast = 0.5 * output.alpha_fast / (output.sound_speed * sqrt(primitive.density));
427 output.a_prime_slow = 0.5 * output.alpha_slow / (output.sound_speed * sqrt(primitive.density));
447 EigenVecs const &eigen, Real
const &gamma)
453 Real
const inverse_sqrt_density = rsqrt(primitive.density);
455 eigen.n_fs * eigen.alpha_fast *
456 (primitive_slope.pressure / primitive.density -
457 eigen.magnetosonic_speed_fast * primitive_slope.velocity.
x()) +
458 eigen.q_prime_slow * (eigen.beta_y * primitive_slope.velocity.y() + eigen.beta_z * primitive_slope.velocity.z()) +
459 eigen.a_prime_slow * (eigen.beta_y * primitive_slope.magnetic.y() + eigen.beta_z * primitive_slope.magnetic.z());
462 0.5 * (eigen.beta_y *
463 (primitive_slope.magnetic.z() * eigen.sign * inverse_sqrt_density + primitive_slope.velocity.z()) -
465 (primitive_slope.magnetic.y() * eigen.sign * inverse_sqrt_density + primitive_slope.velocity.y()));
468 eigen.n_fs * eigen.alpha_slow *
469 (primitive_slope.pressure / primitive.density -
470 eigen.magnetosonic_speed_slow * primitive_slope.velocity.
x()) -
471 eigen.q_prime_fast * (eigen.beta_y * primitive_slope.velocity.y() + eigen.beta_z * primitive_slope.velocity.z()) -
472 eigen.a_prime_fast * (eigen.beta_y * primitive_slope.magnetic.y() + eigen.beta_z * primitive_slope.magnetic.z());
474 output.a3 = primitive_slope.density - primitive_slope.pressure / (eigen.sound_speed * eigen.sound_speed);
477 eigen.n_fs * eigen.alpha_slow *
478 (primitive_slope.pressure / primitive.density +
479 eigen.magnetosonic_speed_slow * primitive_slope.velocity.
x()) +
480 eigen.q_prime_fast * (eigen.beta_y * primitive_slope.velocity.y() + eigen.beta_z * primitive_slope.velocity.z()) -
481 eigen.a_prime_fast * (eigen.beta_y * primitive_slope.magnetic.y() + eigen.beta_z * primitive_slope.magnetic.z());
483 0.5 * (eigen.beta_y *
484 (primitive_slope.magnetic.z() * eigen.sign * inverse_sqrt_density - primitive_slope.velocity.z()) -
486 (primitive_slope.magnetic.y() * eigen.sign * inverse_sqrt_density - primitive_slope.velocity.y()));
489 eigen.n_fs * eigen.alpha_fast *
490 (primitive_slope.pressure / primitive.density +
491 eigen.magnetosonic_speed_fast * primitive_slope.velocity.
x()) -
492 eigen.q_prime_slow * (eigen.beta_y * primitive_slope.velocity.y() + eigen.beta_z * primitive_slope.velocity.z()) +
493 eigen.a_prime_slow * (eigen.beta_y * primitive_slope.magnetic.y() + eigen.beta_z * primitive_slope.magnetic.z());
496 output.a0 = -primitive.density * primitive_slope.velocity.
x() / (2.0 * eigen.sound_speed) +
497 primitive_slope.pressure / (2.0 * (eigen.sound_speed * eigen.sound_speed));
498 output.a1 = primitive_slope.density - primitive_slope.pressure / ((eigen.sound_speed * eigen.sound_speed));
499 output.a2 = primitive_slope.velocity.y();
500 output.a3 = primitive_slope.velocity.z();
501 output.a4 = primitive.density * primitive_slope.velocity.
x() / (2.0 * eigen.sound_speed) +
502 primitive_slope.pressure / (2.0 * (eigen.sound_speed * eigen.sound_speed));
527 output.density = primitive.density * (eigen.alpha_fast * (characteristic_slope.a0 + characteristic_slope.a6) +
528 eigen.alpha_slow * (characteristic_slope.a2 + characteristic_slope.a4)) +
529 characteristic_slope.a3;
530 output.velocity.
x() =
531 eigen.magnetosonic_speed_fast * eigen.alpha_fast * (characteristic_slope.a6 - characteristic_slope.a0) +
532 eigen.magnetosonic_speed_slow * eigen.alpha_slow * (characteristic_slope.a4 - characteristic_slope.a2);
533 output.velocity.y() = eigen.beta_y * (eigen.q_slow * (characteristic_slope.a0 - characteristic_slope.a6) +
534 eigen.q_fast * (characteristic_slope.a4 - characteristic_slope.a2)) +
535 eigen.beta_z * (characteristic_slope.a5 - characteristic_slope.a1);
536 output.velocity.z() = eigen.beta_z * (eigen.q_slow * (characteristic_slope.a0 - characteristic_slope.a6) +
537 eigen.q_fast * (characteristic_slope.a4 - characteristic_slope.a2)) +
538 eigen.beta_y * (characteristic_slope.a1 - characteristic_slope.a5);
539 output.pressure = primitive.density * (eigen.sound_speed * eigen.sound_speed) *
540 (eigen.alpha_fast * (characteristic_slope.a0 + characteristic_slope.a6) +
541 eigen.alpha_slow * (characteristic_slope.a2 + characteristic_slope.a4));
542 output.magnetic.y() =
543 eigen.beta_y * (eigen.a_slow * (characteristic_slope.a0 + characteristic_slope.a6) -
544 eigen.a_fast * (characteristic_slope.a2 + characteristic_slope.a4)) -
545 eigen.beta_z * eigen.sign * sqrt(primitive.density) * (characteristic_slope.a5 + characteristic_slope.a1);
546 output.magnetic.z() =
547 eigen.beta_z * (eigen.a_slow * (characteristic_slope.a0 + characteristic_slope.a6) -
548 eigen.a_fast * (characteristic_slope.a2 + characteristic_slope.a4)) +
549 eigen.beta_y * eigen.sign * sqrt(primitive.density) * (characteristic_slope.a5 + characteristic_slope.a1);
552 output.density = characteristic_slope.a0 + characteristic_slope.a1 + characteristic_slope.a4;
553 output.velocity.
x() = eigen.sound_speed / primitive.density * (characteristic_slope.a4 - characteristic_slope.a0);
554 output.velocity.y() = characteristic_slope.a2;
555 output.velocity.z() = characteristic_slope.a3;
556 output.pressure = (eigen.sound_speed * eigen.sound_speed) * (characteristic_slope.a0 + characteristic_slope.a4);
573Real __device__ __host__ __inline__
Van_Leer_Limiter(Real
const &left, Real
const &right, Real
const ¢ered,
574 Real
const &van_leer)
576 if (left * right > 0.0) {
577 Real
const lim_slope_a = 2.0 * fmin(fabs(left), fabs(right));
578 Real
const lim_slope_b = fmin(fabs(centered), fabs(van_leer));
579 return copysign(fmin(lim_slope_a, lim_slope_b), centered);
606 del_a_m.a0 =
Van_Leer_Limiter(del_a_L.a0, del_a_R.a0, del_a_C.a0, del_a_G.a0);
607 del_a_m.a1 =
Van_Leer_Limiter(del_a_L.a1, del_a_R.a1, del_a_C.a1, del_a_G.a1);
608 del_a_m.a2 =
Van_Leer_Limiter(del_a_L.a2, del_a_R.a2, del_a_C.a2, del_a_G.a2);
609 del_a_m.a3 =
Van_Leer_Limiter(del_a_L.a3, del_a_R.a3, del_a_C.a3, del_a_G.a3);
610 del_a_m.a4 =
Van_Leer_Limiter(del_a_L.a4, del_a_R.a4, del_a_C.a4, del_a_G.a4);
613 del_a_m.a5 =
Van_Leer_Limiter(del_a_L.a5, del_a_R.a5, del_a_C.a5, del_a_G.a5);
614 del_a_m.a6 =
Van_Leer_Limiter(del_a_L.a6, del_a_R.a6, del_a_C.a6, del_a_G.a6);
641 del_m.density =
Van_Leer_Limiter(del_L.density, del_R.density, del_C.density, del_G.density);
642 del_m.velocity.
x() =
Van_Leer_Limiter(del_L.velocity.
x(), del_R.velocity.
x(), del_C.velocity.
x(), del_G.velocity.
x());
643 del_m.velocity.y() =
Van_Leer_Limiter(del_L.velocity.y(), del_R.velocity.y(), del_C.velocity.y(), del_G.velocity.y());
644 del_m.velocity.z() =
Van_Leer_Limiter(del_L.velocity.z(), del_R.velocity.z(), del_C.velocity.z(), del_G.velocity.z());
645 del_m.pressure =
Van_Leer_Limiter(del_L.pressure, del_R.pressure, del_C.pressure, del_G.pressure);
648 del_m.magnetic.y() =
Van_Leer_Limiter(del_L.magnetic.y(), del_R.magnetic.y(), del_C.magnetic.y(), del_G.magnetic.y());
649 del_m.magnetic.z() =
Van_Leer_Limiter(del_L.magnetic.z(), del_R.magnetic.z(), del_C.magnetic.z(), del_G.magnetic.z());
653 del_m.gas_energy =
Van_Leer_Limiter(del_L.gas_energy, del_R.gas_energy, del_C.gas_energy, del_G.gas_energy);
656 for (
int i = 0; i < NSCALARS; i++) {
657 del_m.scalar[i] =
Van_Leer_Limiter(del_L.scalar[i], del_R.scalar[i], del_C.scalar[i], del_G.scalar[i]);
683 auto Monotonize = [](Real
const &state_i, Real
const &state_im1, Real
const &state_ip1, Real &interface_L,
686 Real
const term_1 = 6.0 * (interface_L - interface_R) * (state_i - 0.5 * (interface_R + interface_L));
687 Real
const term_2 = pow(interface_L - interface_R, 2.0);
690 if ((interface_L - state_i) * (state_i - interface_R) <= 0.0) {
691 interface_L = state_i;
692 interface_R = state_i;
695 else if (term_1 > term_2) {
696 interface_R = 3.0 * state_i - 2.0 * interface_L;
699 else if (term_1 < -term_2) {
700 interface_L = 3.0 * state_i - 2.0 * interface_R;
704 interface_R = fmax(fmin(state_i, state_im1), interface_R);
705 interface_R = fmin(fmax(state_i, state_im1), interface_R);
706 interface_L = fmax(fmin(state_i, state_ip1), interface_L);
707 interface_L = fmin(fmax(state_i, state_ip1), interface_L);
711 Monotonize(cell_i.density, cell_im1.density, cell_ip1.density, interface_L_iph.density, interface_R_imh.density);
712 Monotonize(cell_i.velocity.
x(), cell_im1.velocity.
x(), cell_ip1.velocity.
x(), interface_L_iph.velocity.
x(),
713 interface_R_imh.velocity.
x());
714 Monotonize(cell_i.velocity.y(), cell_im1.velocity.y(), cell_ip1.velocity.y(), interface_L_iph.velocity.y(),
715 interface_R_imh.velocity.y());
716 Monotonize(cell_i.velocity.z(), cell_im1.velocity.z(), cell_ip1.velocity.z(), interface_L_iph.velocity.z(),
717 interface_R_imh.velocity.z());
718 Monotonize(cell_i.pressure, cell_im1.pressure, cell_ip1.pressure, interface_L_iph.pressure, interface_R_imh.pressure);
721 Monotonize(cell_i.magnetic.y(), cell_im1.magnetic.y(), cell_ip1.magnetic.y(), interface_L_iph.magnetic.y(),
722 interface_R_imh.magnetic.y());
723 Monotonize(cell_i.magnetic.z(), cell_im1.magnetic.z(), cell_ip1.magnetic.z(), interface_L_iph.magnetic.z(),
724 interface_R_imh.magnetic.z());
728 Monotonize(cell_i.gas_energy, cell_im1.gas_energy, cell_ip1.gas_energy, interface_L_iph.gas_energy,
729 interface_R_imh.gas_energy);
732 for (
int i = 0; i < NSCALARS; i++) {
733 Monotonize(cell_i.scalar[i], cell_im1.scalar[i], cell_ip1.scalar[i], interface_L_iph.scalar[i],
734 interface_R_imh.scalar[i]);
754 auto interface = [&sign](Real
const &state, Real
const &slope) -> Real {
return state + sign * 0.5 * slope; };
756 output.density = interface(primitive.density, slopes.density);
757 output.velocity.
x() = interface(primitive.velocity.
x(), slopes.velocity.
x());
758 output.velocity.y() = interface(primitive.velocity.y(), slopes.velocity.y());
759 output.velocity.z() = interface(primitive.velocity.z(), slopes.velocity.z());
760 output.pressure = interface(primitive.pressure, slopes.pressure);
763 output.magnetic.y() = interface(primitive.magnetic.y(), slopes.magnetic.y());
764 output.magnetic.z() = interface(primitive.magnetic.z(), slopes.magnetic.z());
768 output.gas_energy = interface(primitive.gas_energy, slopes.gas_energy);
771 for (
int i = 0; i < NSCALARS; i++) {
772 output.scalar[i] = interface(primitive.scalar[i], slopes.scalar[i]);
797 auto interface = [](Real const &state_i, Real
const &state_im1, Real
const &slope_i, Real
const &slope_im1) -> Real {
798 return 0.5 * (state_i + state_im1) - (slope_i - slope_im1) / 6.0;
801 output.density = interface(cell_i.density, cell_im1.density, slopes_i.density, slopes_im1.density);
802 output.velocity.
x() =
803 interface(cell_i.velocity.
x(), cell_im1.velocity.
x(), slopes_i.velocity.
x(), slopes_im1.velocity.
x());
804 output.velocity.y() =
805 interface(cell_i.velocity.y(), cell_im1.velocity.y(), slopes_i.velocity.y(), slopes_im1.velocity.y());
806 output.velocity.z() =
807 interface(cell_i.velocity.z(), cell_im1.velocity.z(), slopes_i.velocity.z(), slopes_im1.velocity.z());
808 output.pressure = interface(cell_i.pressure, cell_im1.pressure, slopes_i.pressure, slopes_im1.pressure);
811 output.magnetic.y() =
812 interface(cell_i.magnetic.y(), cell_im1.magnetic.y(), slopes_i.magnetic.y(), slopes_im1.magnetic.y());
813 output.magnetic.z() =
814 interface(cell_i.magnetic.z(), cell_im1.magnetic.z(), slopes_i.magnetic.z(), slopes_im1.magnetic.z());
818 output.gas_energy = interface(cell_i.gas_energy, cell_im1.gas_energy, slopes_i.gas_energy, slopes_im1.gas_energy);
821 for (
int i = 0; i < NSCALARS; i++) {
822 output.scalar[i] = interface(cell_i.scalar[i], cell_im1.scalar[i], slopes_i.scalar[i], slopes_im1.scalar[i]);
853void __device__ __host__ __inline__
PPM_Single_Variable(Real
const &cell_im2, Real
const &cell_im1, Real
const &cell_i,
854 Real
const &cell_ip1, Real
const &cell_ip2,
855 Real &interface_L_iph, Real &interface_R_imh)
860 Real
const C2 = 1.25;
863 auto limit_interface = [&C2](Real
const &cell_i, Real
const &cell_im1, Real
const &interface, Real
const &slope_2nd_i,
864 Real
const &slope_2nd_im1) -> Real {
867 Real slope_2nd_centered = 3.0 * (cell_im1 + cell_i - 2.0 * interface);
869 Real limited_slope = 0.0;
870 if (SIGN(slope_2nd_centered) == SIGN(slope_2nd_im1) and SIGN(slope_2nd_centered) == SIGN(slope_2nd_i)) {
871 limited_slope = SIGN(slope_2nd_centered) *
872 fmin(C2 * abs(slope_2nd_im1), fmin(C2 * abs(slope_2nd_i), abs(slope_2nd_centered)));
876 Real
const diff_left =
interface - cell_im1;
877 Real
const diff_right = cell_i - interface;
878 if (diff_left * diff_right < 0.0) {
880 return 0.5 * (cell_im1 + cell_i) - limited_slope / 6.0;
889 Real
const slope_left = (cell_i - cell_im1);
890 Real
const slope_right = (cell_ip1 - cell_i);
891 Real
const slope_avg_im1 = 0.5 * slope_left + 0.5 * (cell_im1 - cell_im2);
892 Real
const slope_avg_i = 0.5 * slope_right + 0.5 * slope_left;
893 Real
const slope_avg_ip1 = 0.5 * (cell_ip2 - cell_ip1) + 0.5 * slope_right;
897 interface_R_imh = 0.5 * (cell_im1 + cell_i) + (slope_avg_im1 - slope_avg_i) / 6.0;
898 interface_L_iph = 0.5 * (cell_i + cell_ip1) + (slope_avg_i - slope_avg_ip1) / 6.0;
904 Real
const slope_2nd_im1 = cell_im2 + cell_i - 2.0 * cell_im1;
905 Real
const slope_2nd_i = cell_im1 + cell_ip1 - 2.0 * cell_i;
906 Real
const slope_2nd_ip1 = cell_i + cell_ip2 - 2.0 * cell_ip1;
908 interface_R_imh = limit_interface(cell_i, cell_im1, interface_R_imh, slope_2nd_i, slope_2nd_im1);
909 interface_L_iph = limit_interface(cell_ip1, cell_i, interface_L_iph, slope_2nd_ip1, slope_2nd_i);
914 Real slope_2nd_face = 6.0 * (interface_R_imh + interface_L_iph - 2.0 * cell_i);
916 Real slope_2nd_limited = 0.0;
917 if (SIGN(slope_2nd_im1) == SIGN(slope_2nd_i) and SIGN(slope_2nd_im1) == SIGN(slope_2nd_ip1) and
918 SIGN(slope_2nd_im1) == SIGN(slope_2nd_face)) {
921 slope_2nd_limited = SIGN(slope_2nd_face) * fmin(fmin(C2 * abs(slope_2nd_im1), C2 * abs(slope_2nd_i)),
922 fmin(C2 * abs(slope_2nd_ip1), abs(slope_2nd_face)));
926 Real cell_max = fmax(abs(cell_im2), abs(cell_im1));
927 cell_max = fmax(cell_max, abs(cell_i));
928 cell_max = fmax(cell_max, abs(cell_ip1));
929 cell_max = fmax(cell_max, abs(cell_ip2));
933 Real
const rho = (abs(slope_2nd_face) > (1.0e-12) * cell_max) ? slope_2nd_limited / slope_2nd_face : 0.0;
936 Real slope_face_left = cell_i - interface_R_imh;
937 Real slope_face_right = interface_L_iph - cell_i;
940 if ((slope_face_left * slope_face_right) <= 0.0 or ((cell_ip1 - cell_i) * (cell_i - cell_im1)) <= 0.0) {
943 if (rho <= (1.0 - (1.0e-12))) {
946 interface_R_imh = cell_i - rho * slope_face_left;
947 interface_L_iph = cell_i + rho * slope_face_right;
952 if (abs(slope_face_left) >= 2.0 * abs(slope_face_right)) {
953 interface_R_imh = cell_i - 2.0 * slope_face_right;
956 if (abs(slope_face_right) >= 2.0 * abs(slope_face_left)) {
957 interface_L_iph = cell_i + 2.0 * slope_face_left;
978 Real
const *dev_conserved,
size_t const &
id,
size_t const &n_cells,
979 size_t const &o1,
size_t const &o2,
size_t const &o3, Real
const &gamma)
982 dev_interface[grid_enum::density * n_cells + id] = interface_state.density;
983 dev_interface[o1 * n_cells + id] = interface_state.density * interface_state.velocity.
x();
984 dev_interface[o2 * n_cells + id] = interface_state.density * interface_state.velocity.y();
985 dev_interface[o3 * n_cells + id] = interface_state.density * interface_state.velocity.z();
991 case grid_enum::momentum_x:
992 dev_interface[grid_enum::Q_x_magnetic_y * n_cells + id] = interface_state.magnetic.y();
993 dev_interface[grid_enum::Q_x_magnetic_z * n_cells + id] = interface_state.magnetic.z();
994 magnetic_x = dev_conserved[grid_enum::magnetic_x * n_cells + id];
996 case grid_enum::momentum_y:
997 dev_interface[grid_enum::Q_y_magnetic_z * n_cells + id] = interface_state.magnetic.y();
998 dev_interface[grid_enum::Q_y_magnetic_x * n_cells + id] = interface_state.magnetic.z();
999 magnetic_x = dev_conserved[grid_enum::magnetic_y * n_cells + id];
1001 case grid_enum::momentum_z:
1002 dev_interface[grid_enum::Q_z_magnetic_x * n_cells + id] = interface_state.magnetic.y();
1003 dev_interface[grid_enum::Q_z_magnetic_y * n_cells + id] = interface_state.magnetic.z();
1004 magnetic_x = dev_conserved[grid_enum::magnetic_z * n_cells + id];
1009 dev_interface[grid_enum::Energy * n_cells + id] = hydro_utilities::Calc_Energy_Primitive(
1010 interface_state.pressure, interface_state.density, interface_state.velocity.
x(), interface_state.velocity.y(),
1011 interface_state.velocity.z(), gamma, magnetic_x, interface_state.magnetic.y(), interface_state.magnetic.z());
1014 dev_interface[grid_enum::Energy * n_cells + id] = hydro_utilities::Calc_Energy_Primitive(
1015 interface_state.pressure, interface_state.density, interface_state.velocity.
x(), interface_state.velocity.y(),
1016 interface_state.velocity.z(), gamma);
1020 dev_interface[grid_enum::GasEnergy * n_cells + id] = interface_state.density * interface_state.gas_energy;
1023 for (
int i = 0; i < NSCALARS; i++) {
1024 dev_interface[(grid_enum::scalar + i) * n_cells +
id] = interface_state.density * interface_state.scalar[i];
__host__ __device__ Real Calc_Sound_Speed(Real const &E, Real const &d, Real const &mx, Real const &my, Real const &mz, Real const &gamma)
Compute the sound speed in the cell from conserved variables.
Definition hydro_utilities.h:194
__host__ __device__ Real Calc_Kinetic_Energy_From_Velocity(Real const &d, Real const &vx, Real const &vy, Real const &vz)
Compute the kinetic energy from the density and velocities.
Definition hydro_utilities.h:162
Namespace to contain various utilities for the interface reconstruction kernels.
Definition pcm_cuda.h:23
hydro_utilities::Primitive __device__ __host__ Load_Data(Real const *dev_conserved, size_t const &xid, size_t const &yid, size_t const &zid, size_t const &nx, size_t const &ny, size_t const &n_cells, size_t const &o1, size_t const &o2, size_t const &o3, Real const &gamma)
Load the data for reconstruction.
Definition reconstruction_internals.h:152
hydro_utilities::Primitive __device__ __host__ Compute_Van_Leer_Slope(hydro_utilities::Primitive const &left_slope, hydro_utilities::Primitive const &right_slope)
Compute the Van Lear slope from the left and right slopes.
Definition reconstruction_internals.h:326
void __device__ __host__ Write_Data(hydro_utilities::Primitive const &interface_state, Real *dev_interface, Real const *dev_conserved, size_t const &id, size_t const &n_cells, size_t const &o1, size_t const &o2, size_t const &o3, Real const &gamma)
Write the interface data to the appropriate arrays.
Definition reconstruction_internals.h:977
bool __device__ __host__ Thread_Guard(int const &nx, int const &ny, int const &nz, int const &xid, int const &yid, int const &zid)
Determine if a thread is within the allowed range.
Definition reconstruction_internals.h:109
Kind
This enum is used to select which reconstructor to use. The idea is that either one of its implicitly...
Definition reconstruction_internals.h:36
bool __device__ __host__ Riemann_Thread_Guard(size_t const nx, size_t const ny, size_t const nz, size_t const xid, size_t const yid, size_t const zid)
Determine if a thread is within the allowed range.
Definition reconstruction_internals.h:243
hydro_utilities::Primitive __device__ __host__ Compute_Slope(hydro_utilities::Primitive const &left, hydro_utilities::Primitive const &right, Real const &coef=1.0)
Compute a simple slope. Equation is coef * (right - left).
Definition reconstruction_internals.h:287
Characteristic __device__ Primitive_To_Characteristic(hydro_utilities::Primitive const &primitive, hydro_utilities::Primitive const &primitive_slope, EigenVecs const &eigen, Real const &gamma)
Project from the primitive variables slopes to the characteristic variables slopes....
Definition reconstruction_internals.h:445
hydro_utilities::Primitive __device__ __host__ Calc_Interface_Linear(hydro_utilities::Primitive const &primitive, hydro_utilities::Primitive const &slopes, Real const &sign)
Compute the interface state from the slope and cell centered state using linear interpolation.
Definition reconstruction_internals.h:749
Real __device__ __host__ Van_Leer_Limiter(Real const &left, Real const &right, Real const ¢ered, Real const &van_leer)
Compute the limited slope using the Van Leer limiter.
Definition reconstruction_internals.h:573
hydro_utilities::Primitive __device__ __host__ Calc_Interface_Parabolic(hydro_utilities::Primitive const &cell_i, hydro_utilities::Primitive const &cell_im1, hydro_utilities::Primitive const &slopes_i, hydro_utilities::Primitive const &slopes_im1)
Compute the interface state for the CTU version fo the reconstructor from the slope and cell centered...
Definition reconstruction_internals.h:791
EigenVecs __device__ Compute_Eigenvectors(hydro_utilities::Primitive const &primitive, Real const &gamma)
Compute the eigenvectors in the given cell.
Definition reconstruction_internals.h:372
void __device__ __host__ Monotonize_Parabolic_Interface(hydro_utilities::Primitive const &cell_i, hydro_utilities::Primitive const &cell_im1, hydro_utilities::Primitive const &cell_ip1, hydro_utilities::Primitive &interface_L_iph, hydro_utilities::Primitive &interface_R_imh)
Monotonize the parabolic interface states.
Definition reconstruction_internals.h:676
hydro_utilities::Primitive __device__ __host__ Characteristic_To_Primitive(hydro_utilities::Primitive const &primitive, Characteristic const &characteristic_slope, EigenVecs const &eigen, Real const &gamma)
Project from the characteristic variables slopes to the primitive variables slopes....
Definition reconstruction_internals.h:520
void __device__ __host__ PPM_Single_Variable(Real const &cell_im2, Real const &cell_im1, Real const &cell_i, Real const &cell_ip1, Real const &cell_ip2, Real &interface_L_iph, Real &interface_R_imh)
Compute the PPM interface state for a given field/stencil.
Definition reconstruction_internals.h:853
A data only struct for the primitive variables.
Definition basic_structs.h:124
__device__ __host__ T & x() noexcept
Directly access the x, y, and z elements. Const version is needed if the object instance is declared ...
Definition basic_structs.h:68
A struct for the characteristic variables. We use the same notation as Stone et al....
Definition reconstruction_internals.h:84
Definition reconstruction_internals.h:60