xref: /honee/qfunctions/riemann_solver.h (revision 475f0cac5d40259768f4556cf888e8f2448554cb)
1ae2b091fSJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2024, HONEE contributors.
2ae2b091fSJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause
39ed3d70dSJames Wright 
49ed3d70dSJames Wright /// @file
59ed3d70dSJames Wright /// Helper functions for solving the Riemann problem.
69ed3d70dSJames Wright // The left and right states are specified from the perspective of an outward-facing normal vector pointing left to right:
79ed3d70dSJames Wright //
89ed3d70dSJames Wright //     (domain)
99ed3d70dSJames Wright //    /               (outward facing normal)
109ed3d70dSJames Wright // |------------|   /
119ed3d70dSJames Wright // |            |  /
129ed3d70dSJames Wright // |    Left    |---->  Right
139ed3d70dSJames Wright // | (Interior) |    (Exterior)
149ed3d70dSJames Wright // |------------|
159ed3d70dSJames Wright //
169ed3d70dSJames Wright // The right state is exterior to the domain and the left state is the interior to the domain.
179ed3d70dSJames Wright // Much of the work references Eleuterio F. Toro's "Riemann Solvers and Numerical Methods for Fluid Dynamics", 2009
189ed3d70dSJames Wright #include "newtonian_state.h"
199ed3d70dSJames Wright #include "newtonian_types.h"
209ed3d70dSJames Wright 
219ed3d70dSJames Wright enum RiemannFluxType_ { RIEMANN_HLL, RIEMANN_HLLC };
229ed3d70dSJames Wright typedef enum RiemannFluxType_ RiemannFluxType;
239ed3d70dSJames Wright 
249ed3d70dSJames Wright typedef struct {
259ed3d70dSJames Wright   CeedScalar left, right;
269ed3d70dSJames Wright } RoeWeights;
279ed3d70dSJames Wright 
RoeSetup(CeedScalar rho_left,CeedScalar rho_right)289ed3d70dSJames Wright CEED_QFUNCTION_HELPER RoeWeights RoeSetup(CeedScalar rho_left, CeedScalar rho_right) {
299ed3d70dSJames Wright   CeedScalar sqrt_left = sqrt(rho_left), sqrt_right = sqrt(rho_right);
309ed3d70dSJames Wright   RoeWeights w = {sqrt_left / (sqrt_left + sqrt_right), sqrt_right / (sqrt_left + sqrt_right)};
319ed3d70dSJames Wright   return w;
329ed3d70dSJames Wright }
339ed3d70dSJames Wright 
RoeSetup_fwd(CeedScalar rho_left,CeedScalar rho_right,CeedScalar drho_left,CeedScalar drho_right)349ed3d70dSJames Wright CEED_QFUNCTION_HELPER RoeWeights RoeSetup_fwd(CeedScalar rho_left, CeedScalar rho_right, CeedScalar drho_left, CeedScalar drho_right) {
359ed3d70dSJames Wright   CeedScalar sqrt_left = sqrt(rho_left), sqrt_right = sqrt(rho_right);
369ed3d70dSJames Wright   CeedScalar square_sum_root = Square(sqrt_left + sqrt_right);
379ed3d70dSJames Wright   CeedScalar r_right = (sqrt_left / (2 * sqrt_right * square_sum_root)) * drho_right - (sqrt_right / (2 * sqrt_left * square_sum_root)) * drho_left;
389ed3d70dSJames Wright   CeedScalar r_left  = (sqrt_right / (2 * sqrt_left * square_sum_root)) * drho_left - (sqrt_left / (2 * sqrt_right * square_sum_root)) * drho_right;
399ed3d70dSJames Wright   RoeWeights dw      = {r_left, r_right};
409ed3d70dSJames Wright   return dw;
419ed3d70dSJames Wright }
429ed3d70dSJames Wright 
RoeAverage(RoeWeights r,CeedScalar q_left,CeedScalar q_right)439ed3d70dSJames Wright CEED_QFUNCTION_HELPER CeedScalar RoeAverage(RoeWeights r, CeedScalar q_left, CeedScalar q_right) { return r.left * q_left + r.right * q_right; }
449ed3d70dSJames Wright 
RoeAverage_fwd(RoeWeights r,RoeWeights dr,CeedScalar q_left,CeedScalar q_right,CeedScalar dq_left,CeedScalar dq_right)459ed3d70dSJames Wright CEED_QFUNCTION_HELPER CeedScalar RoeAverage_fwd(RoeWeights r, RoeWeights dr, CeedScalar q_left, CeedScalar q_right, CeedScalar dq_left,
469ed3d70dSJames Wright                                                 CeedScalar dq_right) {
479ed3d70dSJames Wright   return q_right * dr.right + q_left * dr.left + r.right * dq_right + r.left * dq_left;
489ed3d70dSJames Wright }
499ed3d70dSJames Wright 
Flux_HLL(State left,State right,StateConservative flux_left,StateConservative flux_right,CeedScalar s_left,CeedScalar s_right)509ed3d70dSJames Wright CEED_QFUNCTION_HELPER StateConservative Flux_HLL(State left, State right, StateConservative flux_left, StateConservative flux_right,
519ed3d70dSJames Wright                                                  CeedScalar s_left, CeedScalar s_right) {
529ed3d70dSJames Wright   CeedScalar U_left[5], U_right[5], F_right[5], F_left[5], F_hll[5];
539ed3d70dSJames Wright   UnpackState_U(left.U, U_left);
549ed3d70dSJames Wright   UnpackState_U(right.U, U_right);
559ed3d70dSJames Wright   UnpackState_U(flux_left, F_left);
569ed3d70dSJames Wright   UnpackState_U(flux_right, F_right);
579ed3d70dSJames Wright   for (int i = 0; i < 5; i++) {
589ed3d70dSJames Wright     F_hll[i] = (s_right * F_left[i] - s_left * F_right[i] + s_left * s_right * (U_right[i] - U_left[i])) / (s_right - s_left);
599ed3d70dSJames Wright   }
609ed3d70dSJames Wright   StateConservative F = {
619ed3d70dSJames Wright       F_hll[0],
629ed3d70dSJames Wright       {F_hll[1], F_hll[2], F_hll[3]},
639ed3d70dSJames Wright       F_hll[4],
649ed3d70dSJames Wright   };
659ed3d70dSJames Wright   return F;
669ed3d70dSJames Wright }
679ed3d70dSJames Wright 
Flux_HLL_fwd(State left,State right,State dleft,State dright,StateConservative flux_left,StateConservative flux_right,StateConservative dflux_left,StateConservative dflux_right,CeedScalar S_l,CeedScalar S_r,CeedScalar dS_l,CeedScalar dS_r)689ed3d70dSJames Wright CEED_QFUNCTION_HELPER StateConservative Flux_HLL_fwd(State left, State right, State dleft, State dright, StateConservative flux_left,
699ed3d70dSJames Wright                                                      StateConservative flux_right, StateConservative dflux_left, StateConservative dflux_right,
709ed3d70dSJames Wright                                                      CeedScalar S_l, CeedScalar S_r, CeedScalar dS_l, CeedScalar dS_r) {
719ed3d70dSJames Wright   CeedScalar U_l[5], U_r[5], F_r[5], F_l[5];
729ed3d70dSJames Wright   UnpackState_U(left.U, U_l);
739ed3d70dSJames Wright   UnpackState_U(right.U, U_r);
749ed3d70dSJames Wright   UnpackState_U(flux_left, F_l);
759ed3d70dSJames Wright   UnpackState_U(flux_right, F_r);
769ed3d70dSJames Wright 
779ed3d70dSJames Wright   CeedScalar dU_l[5], dU_r[5], dF_r[5], dF_l[5], dF_hll[5] = {0.};
789ed3d70dSJames Wright   UnpackState_U(dleft.U, dU_l);
799ed3d70dSJames Wright   UnpackState_U(dright.U, dU_r);
809ed3d70dSJames Wright   UnpackState_U(dflux_left, dF_l);
819ed3d70dSJames Wright   UnpackState_U(dflux_right, dF_r);
829ed3d70dSJames Wright   for (int i = 0; i < 5; i++) {
839ed3d70dSJames Wright     const CeedScalar S_diff = S_r - S_l;
849ed3d70dSJames Wright 
859bafb137SJames Wright     dF_hll[i] += (S_l * (-F_l[i] + F_r[i] + S_l * U_l[i] - S_l * U_r[i]) / Square(S_diff)) * dS_r;
869bafb137SJames Wright     dF_hll[i] += (S_r * (F_l[i] - F_r[i] - S_r * U_l[i] + S_r * U_r[i]) / Square(S_diff)) * dS_l;
879bafb137SJames Wright     dF_hll[i] += (S_r * dF_l[i] - S_l * dF_r[i] + S_r * S_l * (dU_r[i] - dU_l[i])) / S_diff;
889ed3d70dSJames Wright   }
899ed3d70dSJames Wright   StateConservative dF = {
909ed3d70dSJames Wright       dF_hll[0],
919ed3d70dSJames Wright       {dF_hll[1], dF_hll[2], dF_hll[3]},
929ed3d70dSJames Wright       dF_hll[4],
939ed3d70dSJames Wright   };
949ed3d70dSJames Wright   return dF;
959ed3d70dSJames Wright }
969ed3d70dSJames Wright 
ComputeHLLSpeeds_Roe(NewtonianIGProperties gas,State left,CeedScalar u_left,State right,CeedScalar u_right,CeedScalar * s_left,CeedScalar * s_right)97*cde3d787SJames Wright CEED_QFUNCTION_HELPER void ComputeHLLSpeeds_Roe(NewtonianIGProperties gas, State left, CeedScalar u_left, State right, CeedScalar u_right,
989ed3d70dSJames Wright                                                 CeedScalar *s_left, CeedScalar *s_right) {
999ed3d70dSJames Wright   const CeedScalar gamma = HeatCapacityRatio(gas);
1009ed3d70dSJames Wright 
1019ed3d70dSJames Wright   RoeWeights r = RoeSetup(left.U.density, right.U.density);
1029ed3d70dSJames Wright   // Speed estimate
1039ed3d70dSJames Wright   // Roe average eigenvalues for left and right non-linear waves.
1049ed3d70dSJames Wright   // Stability requires that these speed estimates are *at least* as fast as the physical wave speeds.
1059ed3d70dSJames Wright   CeedScalar u_roe = RoeAverage(r, u_left, u_right);
1069ed3d70dSJames Wright 
1079ed3d70dSJames Wright   CeedScalar H_left  = TotalSpecificEnthalpy(gas, left);
1089ed3d70dSJames Wright   CeedScalar H_right = TotalSpecificEnthalpy(gas, right);
1099ed3d70dSJames Wright   CeedScalar H_roe   = RoeAverage(r, H_left, H_right);
1109ed3d70dSJames Wright   CeedScalar a_roe   = sqrt((gamma - 1) * (H_roe - 0.5 * Square(u_roe)));
1119ed3d70dSJames Wright 
1129ed3d70dSJames Wright   // Einfeldt (1988) justifies (and Toro's book repeats) that Roe speeds can be used here.
1139ed3d70dSJames Wright   *s_left  = u_roe - a_roe;
1149ed3d70dSJames Wright   *s_right = u_roe + a_roe;
1159ed3d70dSJames Wright }
1169ed3d70dSJames Wright 
ComputeHLLSpeeds_Roe_fwd(NewtonianIGProperties gas,State left,State dleft,CeedScalar u_left,CeedScalar du_left,State right,State dright,CeedScalar u_right,CeedScalar du_right,CeedScalar * s_left,CeedScalar * ds_left,CeedScalar * s_right,CeedScalar * ds_right)117*cde3d787SJames Wright CEED_QFUNCTION_HELPER void ComputeHLLSpeeds_Roe_fwd(NewtonianIGProperties gas, State left, State dleft, CeedScalar u_left, CeedScalar du_left,
1189ed3d70dSJames Wright                                                     State right, State dright, CeedScalar u_right, CeedScalar du_right, CeedScalar *s_left,
1199ed3d70dSJames Wright                                                     CeedScalar *ds_left, CeedScalar *s_right, CeedScalar *ds_right) {
1209ed3d70dSJames Wright   const CeedScalar gamma = HeatCapacityRatio(gas);
1219ed3d70dSJames Wright 
1229ed3d70dSJames Wright   RoeWeights r  = RoeSetup(left.U.density, right.U.density);
1239ed3d70dSJames Wright   RoeWeights dr = RoeSetup_fwd(left.U.density, right.U.density, dleft.U.density, dright.U.density);
1249ed3d70dSJames Wright   // Speed estimate
1259ed3d70dSJames Wright   // Roe average eigenvalues for left and right non-linear waves.
1269ed3d70dSJames Wright   // Stability requires that these speed estimates are *at least* as fast as the physical wave speeds.
1279ed3d70dSJames Wright   CeedScalar u_roe  = RoeAverage(r, u_left, u_right);
1289ed3d70dSJames Wright   CeedScalar du_roe = RoeAverage_fwd(r, dr, u_left, u_right, du_left, du_right);
1299ed3d70dSJames Wright 
1309ed3d70dSJames Wright   CeedScalar H_left   = TotalSpecificEnthalpy(gas, left);
1319ed3d70dSJames Wright   CeedScalar H_right  = TotalSpecificEnthalpy(gas, right);
1329ed3d70dSJames Wright   CeedScalar dH_left  = TotalSpecificEnthalpy_fwd(gas, left, dleft);
1339ed3d70dSJames Wright   CeedScalar dH_right = TotalSpecificEnthalpy_fwd(gas, right, dright);
1349ed3d70dSJames Wright 
1359ed3d70dSJames Wright   CeedScalar H_roe  = RoeAverage(r, H_left, H_right);
1369ed3d70dSJames Wright   CeedScalar dH_roe = RoeAverage_fwd(r, dr, H_left, H_right, dH_left, dH_right);
1379ed3d70dSJames Wright   CeedScalar a_roe  = sqrt((gamma - 1) * (H_roe - 0.5 * Square(u_roe)));
1389bafb137SJames Wright   CeedScalar da_roe = 0.5 * sqrt((gamma - 1) / (H_roe - 0.5 * Square(u_roe))) * dH_roe;  // (da/dH) dH
1399bafb137SJames Wright   da_roe -= 0.5 * sqrt(gamma - 1) * u_roe / sqrt(H_roe - 0.5 * Square(u_roe)) * du_roe;  // (da/du) du
1409ed3d70dSJames Wright 
1419ed3d70dSJames Wright   *s_left   = u_roe - a_roe;
1429ed3d70dSJames Wright   *ds_left  = du_roe - da_roe;
1439ed3d70dSJames Wright   *s_right  = u_roe + a_roe;
1449ed3d70dSJames Wright   *ds_right = du_roe + da_roe;
1459ed3d70dSJames Wright }
1469ed3d70dSJames Wright 
1479ed3d70dSJames Wright // *****************************************************************************
1489ed3d70dSJames Wright // @brief Harten Lax VanLeer (HLL) approximate Riemann solver.
1499ed3d70dSJames Wright // Taking in two states (left, right) and returns RiemannFlux_HLL.
1509ed3d70dSJames Wright // The left and right states are specified from the perspective of an outward-facing normal vector pointing left to right.
1519ed3d70dSJames Wright //
152*cde3d787SJames Wright // @param[in] gas    NewtonianIGProperties for the fluid
1539ed3d70dSJames Wright // @param[in] left   Fluid state of the domain interior (the current solution)
1549ed3d70dSJames Wright // @param[in] right  Fluid state of the domain exterior (free stream conditions)
1559ed3d70dSJames Wright // @param[in] normal Normalized, outward facing boundary normal vector
1569ed3d70dSJames Wright //
1579ed3d70dSJames Wright // @return StateConservative with HLL Riemann Flux
1589ed3d70dSJames Wright // *****************************************************************************
RiemannFlux_HLL(NewtonianIGProperties gas,State left,State right,const CeedScalar normal[3])159*cde3d787SJames Wright CEED_QFUNCTION_HELPER StateConservative RiemannFlux_HLL(NewtonianIGProperties gas, State left, State right, const CeedScalar normal[3]) {
1609ed3d70dSJames Wright   StateConservative flux_left  = FluxInviscidDotNormal(gas, left, normal);
1619ed3d70dSJames Wright   StateConservative flux_right = FluxInviscidDotNormal(gas, right, normal);
1629ed3d70dSJames Wright 
1639ed3d70dSJames Wright   CeedScalar u_left  = Dot3(left.Y.velocity, normal);
1649ed3d70dSJames Wright   CeedScalar u_right = Dot3(right.Y.velocity, normal);
1659ed3d70dSJames Wright 
1669ed3d70dSJames Wright   CeedScalar s_left, s_right;
1679ed3d70dSJames Wright   ComputeHLLSpeeds_Roe(gas, left, u_left, right, u_right, &s_left, &s_right);
1689ed3d70dSJames Wright 
1699ed3d70dSJames Wright   // Compute HLL flux
1709ed3d70dSJames Wright   if (0 <= s_left) {
1719ed3d70dSJames Wright     return flux_left;
1729ed3d70dSJames Wright   } else if (s_right <= 0) {
1739ed3d70dSJames Wright     return flux_right;
1749ed3d70dSJames Wright   } else {
1759ed3d70dSJames Wright     return Flux_HLL(left, right, flux_left, flux_right, s_left, s_right);
1769ed3d70dSJames Wright   }
1779ed3d70dSJames Wright }
1789ed3d70dSJames Wright 
1799ed3d70dSJames Wright // *****************************************************************************
1809ed3d70dSJames Wright // @brief Forward-mode Derivative of Harten Lax VanLeer (HLL) approximate Riemann solver.
1819ed3d70dSJames Wright //
182*cde3d787SJames Wright // @param gas    NewtonianIGProperties for the fluid
1839ed3d70dSJames Wright // @param left   Fluid state of the domain interior (the current solution)
1849ed3d70dSJames Wright // @param right  Fluid state of the domain exterior (free stream conditions)
1859ed3d70dSJames Wright // @param dleft  Derivative of fluid state of the domain interior (the current solution)
1869ed3d70dSJames Wright // @param dright Derivative of fluid state of the domain exterior (free stream conditions)
1879ed3d70dSJames Wright // @param normal Normalized, outward facing boundary normal vector
1889ed3d70dSJames Wright //
1899ed3d70dSJames Wright // @return StateConservative with derivative of HLL Riemann Flux
1909ed3d70dSJames Wright // *****************************************************************************
RiemannFlux_HLL_fwd(NewtonianIGProperties gas,State left,State dleft,State right,State dright,const CeedScalar normal[3])191*cde3d787SJames Wright CEED_QFUNCTION_HELPER StateConservative RiemannFlux_HLL_fwd(NewtonianIGProperties gas, State left, State dleft, State right, State dright,
1929ed3d70dSJames Wright                                                             const CeedScalar normal[3]) {
1939ed3d70dSJames Wright   StateConservative flux_left   = FluxInviscidDotNormal(gas, left, normal);
1949ed3d70dSJames Wright   StateConservative flux_right  = FluxInviscidDotNormal(gas, right, normal);
1959ed3d70dSJames Wright   StateConservative dflux_left  = FluxInviscidDotNormal_fwd(gas, left, dleft, normal);
1969ed3d70dSJames Wright   StateConservative dflux_right = FluxInviscidDotNormal_fwd(gas, right, dright, normal);
1979ed3d70dSJames Wright 
1989ed3d70dSJames Wright   CeedScalar u_left   = Dot3(left.Y.velocity, normal);
1999ed3d70dSJames Wright   CeedScalar u_right  = Dot3(right.Y.velocity, normal);
2009ed3d70dSJames Wright   CeedScalar du_left  = Dot3(dleft.Y.velocity, normal);
2019ed3d70dSJames Wright   CeedScalar du_right = Dot3(dright.Y.velocity, normal);
2029ed3d70dSJames Wright 
2039ed3d70dSJames Wright   CeedScalar s_left, ds_left, s_right, ds_right;
2049ed3d70dSJames Wright   ComputeHLLSpeeds_Roe_fwd(gas, left, dleft, u_left, du_left, right, dright, u_right, du_right, &s_left, &ds_left, &s_right, &ds_right);
2059ed3d70dSJames Wright 
2069ed3d70dSJames Wright   if (0 <= s_left) {
2079ed3d70dSJames Wright     return dflux_left;
2089ed3d70dSJames Wright   } else if (s_right <= 0) {
2099ed3d70dSJames Wright     return dflux_right;
2109ed3d70dSJames Wright   } else {
2119ed3d70dSJames Wright     return Flux_HLL_fwd(left, right, dleft, dright, flux_left, flux_right, dflux_left, dflux_right, s_left, s_right, ds_left, ds_right);
2129ed3d70dSJames Wright   }
2139ed3d70dSJames Wright }
2149ed3d70dSJames Wright 
RiemannFlux_HLLC_Star(NewtonianIGProperties gas,State side,StateConservative F_side,const CeedScalar normal[3],CeedScalar u_side,CeedScalar s_side,CeedScalar s_star)215*cde3d787SJames Wright CEED_QFUNCTION_HELPER StateConservative RiemannFlux_HLLC_Star(NewtonianIGProperties gas, State side, StateConservative F_side,
2169ed3d70dSJames Wright                                                               const CeedScalar normal[3], CeedScalar u_side, CeedScalar s_side, CeedScalar s_star) {
2179ed3d70dSJames Wright   CeedScalar fact  = side.U.density * (s_side - u_side) / (s_side - s_star);
2189ed3d70dSJames Wright   CeedScalar denom = side.U.density * (s_side - u_side);
2199ed3d70dSJames Wright   // U_* = fact * star
2209ed3d70dSJames Wright   StateConservative star = {
2219ed3d70dSJames Wright       1.0,
2229ed3d70dSJames Wright       {
2239ed3d70dSJames Wright         side.Y.velocity[0] + (s_star - u_side) * normal[0],
2249ed3d70dSJames Wright         side.Y.velocity[1] + (s_star - u_side) * normal[1],
2259ed3d70dSJames Wright         side.Y.velocity[2] + (s_star - u_side) * normal[2],
2269ed3d70dSJames Wright         },
2279ed3d70dSJames Wright       side.U.E_total / side.U.density  //
2289ed3d70dSJames Wright           + (s_star - u_side) * (s_star + side.Y.pressure / denom)
2299ed3d70dSJames Wright   };
2309ed3d70dSJames Wright   return StateConservativeAXPBYPCZ(1, F_side, s_side * fact, star, -s_side, side.U);
2319ed3d70dSJames Wright }
2329ed3d70dSJames Wright 
RiemannFlux_HLLC_Star_fwd(NewtonianIGProperties gas,State side,State dside,StateConservative F_side,StateConservative dF_side,const CeedScalar normal[3],CeedScalar u_side,CeedScalar du_side,CeedScalar s_side,CeedScalar ds_side,CeedScalar s_star,CeedScalar ds_star)233*cde3d787SJames Wright CEED_QFUNCTION_HELPER StateConservative RiemannFlux_HLLC_Star_fwd(NewtonianIGProperties gas, State side, State dside, StateConservative F_side,
2349ed3d70dSJames Wright                                                                   StateConservative dF_side, const CeedScalar normal[3], CeedScalar u_side,
2359ed3d70dSJames Wright                                                                   CeedScalar du_side, CeedScalar s_side, CeedScalar ds_side, CeedScalar s_star,
2369ed3d70dSJames Wright                                                                   CeedScalar ds_star) {
2379ed3d70dSJames Wright   CeedScalar fact  = side.U.density * (s_side - u_side) / (s_side - s_star);
2389ed3d70dSJames Wright   CeedScalar dfact = (side.U.density * (ds_side - du_side) + dside.U.density * (s_side - u_side)) / (s_side - s_star)  //
2399ed3d70dSJames Wright                      - fact / (s_side - s_star) * (ds_side - ds_star);
2409ed3d70dSJames Wright   CeedScalar denom  = side.U.density * (s_side - u_side);
2419ed3d70dSJames Wright   CeedScalar ddenom = side.U.density * (ds_side - du_side) + dside.U.density * (s_side - u_side);
2429ed3d70dSJames Wright 
2439ed3d70dSJames Wright   StateConservative star = {
2449ed3d70dSJames Wright       1.0,
2459ed3d70dSJames Wright       {
2469ed3d70dSJames Wright         side.Y.velocity[0] + (s_star - u_side) * normal[0],
2479ed3d70dSJames Wright         side.Y.velocity[1] + (s_star - u_side) * normal[1],
2489ed3d70dSJames Wright         side.Y.velocity[2] + (s_star - u_side) * normal[2],
2499ed3d70dSJames Wright         },
2509ed3d70dSJames Wright       side.U.E_total / side.U.density  //
2519ed3d70dSJames Wright           + (s_star - u_side) * (s_star + side.Y.pressure / denom)
2529ed3d70dSJames Wright   };
2539ed3d70dSJames Wright   StateConservative dstar = {
2549ed3d70dSJames Wright       0.,
2559ed3d70dSJames Wright       {
2569ed3d70dSJames Wright         dside.Y.velocity[0] + (ds_star - du_side) * normal[0],
2579ed3d70dSJames Wright         dside.Y.velocity[1] + (ds_star - du_side) * normal[1],
2589ed3d70dSJames Wright         dside.Y.velocity[2] + (ds_star - du_side) * normal[2],
2599ed3d70dSJames Wright         },
2609ed3d70dSJames Wright       dside.U.E_total / side.U.density - side.U.E_total / Square(side.U.density) * dside.U.density  //
2619ed3d70dSJames Wright           + (ds_star - du_side) * (s_star + side.Y.pressure / denom)  //
2629ed3d70dSJames Wright           + (s_star - u_side) * (ds_star + dside.Y.pressure / denom - side.Y.pressure / Square(denom) * ddenom)  //
2639ed3d70dSJames Wright   };
2649ed3d70dSJames Wright 
2659ed3d70dSJames Wright   const CeedScalar        a[] = {1, ds_side * fact + s_side * dfact, s_side * fact, -ds_side, -s_side};
2669ed3d70dSJames Wright   const StateConservative U[] = {dF_side, star, dstar, side.U, dside.U};
2679ed3d70dSJames Wright   return StateConservativeMult(5, a, U);
2689ed3d70dSJames Wright }
2699ed3d70dSJames Wright 
2709ed3d70dSJames Wright // HLLC Riemann solver (from Toro's book)
RiemannFlux_HLLC(NewtonianIGProperties gas,State left,State right,const CeedScalar normal[3])271*cde3d787SJames Wright CEED_QFUNCTION_HELPER StateConservative RiemannFlux_HLLC(NewtonianIGProperties gas, State left, State right, const CeedScalar normal[3]) {
2729ed3d70dSJames Wright   StateConservative flux_left  = FluxInviscidDotNormal(gas, left, normal);
2739ed3d70dSJames Wright   StateConservative flux_right = FluxInviscidDotNormal(gas, right, normal);
2749ed3d70dSJames Wright 
2759ed3d70dSJames Wright   CeedScalar u_left  = Dot3(left.Y.velocity, normal);
2769ed3d70dSJames Wright   CeedScalar u_right = Dot3(right.Y.velocity, normal);
2779ed3d70dSJames Wright   CeedScalar s_left, s_right;
2789ed3d70dSJames Wright   ComputeHLLSpeeds_Roe(gas, left, u_left, right, u_right, &s_left, &s_right);
2799ed3d70dSJames Wright 
2809ed3d70dSJames Wright   // Contact wave speed; Toro (10.37)
2819ed3d70dSJames Wright   CeedScalar rhou_left = left.U.density * u_left, rhou_right = right.U.density * u_right;
2829ed3d70dSJames Wright   CeedScalar numer  = right.Y.pressure - left.Y.pressure + rhou_left * (s_left - u_left) - rhou_right * (s_right - u_right);
2839ed3d70dSJames Wright   CeedScalar denom  = left.U.density * (s_left - u_left) - right.U.density * (s_right - u_right);
2849ed3d70dSJames Wright   CeedScalar s_star = numer / denom;
2859ed3d70dSJames Wright 
2869ed3d70dSJames Wright   // Compute HLLC flux
2879ed3d70dSJames Wright   if (0 <= s_left) {
2889ed3d70dSJames Wright     return flux_left;
2899ed3d70dSJames Wright   } else if (0 <= s_star) {
2909ed3d70dSJames Wright     return RiemannFlux_HLLC_Star(gas, left, flux_left, normal, u_left, s_left, s_star);
2919ed3d70dSJames Wright   } else if (0 <= s_right) {
2929ed3d70dSJames Wright     return RiemannFlux_HLLC_Star(gas, right, flux_right, normal, u_right, s_right, s_star);
2939ed3d70dSJames Wright   } else {
2949ed3d70dSJames Wright     return flux_right;
2959ed3d70dSJames Wright   }
2969ed3d70dSJames Wright }
2979ed3d70dSJames Wright 
RiemannFlux_HLLC_fwd(NewtonianIGProperties gas,State left,State dleft,State right,State dright,const CeedScalar normal[3])298*cde3d787SJames Wright CEED_QFUNCTION_HELPER StateConservative RiemannFlux_HLLC_fwd(NewtonianIGProperties gas, State left, State dleft, State right, State dright,
2999ed3d70dSJames Wright                                                              const CeedScalar normal[3]) {
3009ed3d70dSJames Wright   StateConservative flux_left   = FluxInviscidDotNormal(gas, left, normal);
3019ed3d70dSJames Wright   StateConservative flux_right  = FluxInviscidDotNormal(gas, right, normal);
3029ed3d70dSJames Wright   StateConservative dflux_left  = FluxInviscidDotNormal_fwd(gas, left, dleft, normal);
3039ed3d70dSJames Wright   StateConservative dflux_right = FluxInviscidDotNormal_fwd(gas, right, dright, normal);
3049ed3d70dSJames Wright 
3059ed3d70dSJames Wright   CeedScalar u_left   = Dot3(left.Y.velocity, normal);
3069ed3d70dSJames Wright   CeedScalar u_right  = Dot3(right.Y.velocity, normal);
3079ed3d70dSJames Wright   CeedScalar du_left  = Dot3(dleft.Y.velocity, normal);
3089ed3d70dSJames Wright   CeedScalar du_right = Dot3(dright.Y.velocity, normal);
3099ed3d70dSJames Wright 
3109ed3d70dSJames Wright   CeedScalar s_left, ds_left, s_right, ds_right;
3119ed3d70dSJames Wright   ComputeHLLSpeeds_Roe_fwd(gas, left, dleft, u_left, du_left, right, dright, u_right, du_right, &s_left, &ds_left, &s_right, &ds_right);
3129ed3d70dSJames Wright 
3139ed3d70dSJames Wright   // Contact wave speed; Toro (10.37)
3149ed3d70dSJames Wright   CeedScalar rhou_left = left.U.density * u_left, drhou_left = left.U.density * du_left + dleft.U.density * u_left;
3159ed3d70dSJames Wright   CeedScalar rhou_right = right.U.density * u_right, drhou_right = right.U.density * du_right + dright.U.density * u_right;
3169ed3d70dSJames Wright   CeedScalar numer = right.Y.pressure - left.Y.pressure  //
3179ed3d70dSJames Wright                      + rhou_left * (s_left - u_left)     //
3189ed3d70dSJames Wright                      - rhou_right * (s_right - u_right);
3199ed3d70dSJames Wright   CeedScalar dnumer = dright.Y.pressure - dleft.Y.pressure                                //
3209ed3d70dSJames Wright                       + rhou_left * (ds_left - du_left) + drhou_left * (s_left - u_left)  //
3219ed3d70dSJames Wright                       - rhou_right * (ds_right - du_right) - drhou_right * (s_right - u_right);
3229ed3d70dSJames Wright   CeedScalar denom  = left.U.density * (s_left - u_left) - right.U.density * (s_right - u_right);
3239ed3d70dSJames Wright   CeedScalar ddenom = left.U.density * (ds_left - du_left) + dleft.U.density * (s_left - u_left)  //
3249ed3d70dSJames Wright                       - right.U.density * (ds_right - du_right) - dright.U.density * (s_right - u_right);
3259ed3d70dSJames Wright   CeedScalar s_star  = numer / denom;
3269ed3d70dSJames Wright   CeedScalar ds_star = dnumer / denom - numer / Square(denom) * ddenom;
3279ed3d70dSJames Wright 
3289ed3d70dSJames Wright   // Compute HLLC flux
3299ed3d70dSJames Wright   if (0 <= s_left) {
3309ed3d70dSJames Wright     return dflux_left;
3319ed3d70dSJames Wright   } else if (0 <= s_star) {
3329ed3d70dSJames Wright     return RiemannFlux_HLLC_Star_fwd(gas, left, dleft, flux_left, dflux_left, normal, u_left, du_left, s_left, ds_left, s_star, ds_star);
3339ed3d70dSJames Wright   } else if (0 <= s_right) {
3349ed3d70dSJames Wright     return RiemannFlux_HLLC_Star_fwd(gas, right, dright, flux_right, dflux_right, normal, u_right, du_right, s_right, ds_right, s_star, ds_star);
3359ed3d70dSJames Wright   } else {
3369ed3d70dSJames Wright     return dflux_right;
3379ed3d70dSJames Wright   }
3389ed3d70dSJames Wright }
339