1*9ed3d70dSJames Wright // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 2*9ed3d70dSJames Wright // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3*9ed3d70dSJames Wright // 4*9ed3d70dSJames Wright // SPDX-License-Identifier: BSD-2-Clause 5*9ed3d70dSJames Wright // 6*9ed3d70dSJames Wright // This file is part of CEED: http://github.com/ceed 7*9ed3d70dSJames Wright 8*9ed3d70dSJames Wright /// @file 9*9ed3d70dSJames Wright /// Helper functions for solving the Riemann problem. 10*9ed3d70dSJames Wright // The left and right states are specified from the perspective of an outward-facing normal vector pointing left to right: 11*9ed3d70dSJames Wright // 12*9ed3d70dSJames Wright // (domain) 13*9ed3d70dSJames Wright // / (outward facing normal) 14*9ed3d70dSJames Wright // |------------| / 15*9ed3d70dSJames Wright // | | / 16*9ed3d70dSJames Wright // | Left |----> Right 17*9ed3d70dSJames Wright // | (Interior) | (Exterior) 18*9ed3d70dSJames Wright // |------------| 19*9ed3d70dSJames Wright // 20*9ed3d70dSJames Wright // The right state is exterior to the domain and the left state is the interior to the domain. 21*9ed3d70dSJames Wright // Much of the work references Eleuterio F. Toro's "Riemann Solvers and Numerical Methods for Fluid Dynamics", 2009 22*9ed3d70dSJames Wright 23*9ed3d70dSJames Wright #ifndef riemann_solver_h 24*9ed3d70dSJames Wright #define riemann_solver_h 25*9ed3d70dSJames Wright 26*9ed3d70dSJames Wright #include "newtonian_state.h" 27*9ed3d70dSJames Wright #include "newtonian_types.h" 28*9ed3d70dSJames Wright 29*9ed3d70dSJames Wright enum RiemannFluxType_ { RIEMANN_HLL, RIEMANN_HLLC }; 30*9ed3d70dSJames Wright typedef enum RiemannFluxType_ RiemannFluxType; 31*9ed3d70dSJames Wright 32*9ed3d70dSJames Wright typedef struct { 33*9ed3d70dSJames Wright CeedScalar left, right; 34*9ed3d70dSJames Wright } RoeWeights; 35*9ed3d70dSJames Wright 36*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER RoeWeights RoeSetup(CeedScalar rho_left, CeedScalar rho_right) { 37*9ed3d70dSJames Wright CeedScalar sqrt_left = sqrt(rho_left), sqrt_right = sqrt(rho_right); 38*9ed3d70dSJames Wright RoeWeights w = {sqrt_left / (sqrt_left + sqrt_right), sqrt_right / (sqrt_left + sqrt_right)}; 39*9ed3d70dSJames Wright return w; 40*9ed3d70dSJames Wright } 41*9ed3d70dSJames Wright 42*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER RoeWeights RoeSetup_fwd(CeedScalar rho_left, CeedScalar rho_right, CeedScalar drho_left, CeedScalar drho_right) { 43*9ed3d70dSJames Wright CeedScalar sqrt_left = sqrt(rho_left), sqrt_right = sqrt(rho_right); 44*9ed3d70dSJames Wright CeedScalar square_sum_root = Square(sqrt_left + sqrt_right); 45*9ed3d70dSJames Wright CeedScalar r_right = (sqrt_left / (2 * sqrt_right * square_sum_root)) * drho_right - (sqrt_right / (2 * sqrt_left * square_sum_root)) * drho_left; 46*9ed3d70dSJames Wright CeedScalar r_left = (sqrt_right / (2 * sqrt_left * square_sum_root)) * drho_left - (sqrt_left / (2 * sqrt_right * square_sum_root)) * drho_right; 47*9ed3d70dSJames Wright RoeWeights dw = {r_left, r_right}; 48*9ed3d70dSJames Wright return dw; 49*9ed3d70dSJames Wright } 50*9ed3d70dSJames Wright 51*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER CeedScalar RoeAverage(RoeWeights r, CeedScalar q_left, CeedScalar q_right) { return r.left * q_left + r.right * q_right; } 52*9ed3d70dSJames Wright 53*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER CeedScalar RoeAverage_fwd(RoeWeights r, RoeWeights dr, CeedScalar q_left, CeedScalar q_right, CeedScalar dq_left, 54*9ed3d70dSJames Wright CeedScalar dq_right) { 55*9ed3d70dSJames Wright return q_right * dr.right + q_left * dr.left + r.right * dq_right + r.left * dq_left; 56*9ed3d70dSJames Wright } 57*9ed3d70dSJames Wright 58*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER StateConservative Flux_HLL(State left, State right, StateConservative flux_left, StateConservative flux_right, 59*9ed3d70dSJames Wright CeedScalar s_left, CeedScalar s_right) { 60*9ed3d70dSJames Wright CeedScalar U_left[5], U_right[5], F_right[5], F_left[5], F_hll[5]; 61*9ed3d70dSJames Wright UnpackState_U(left.U, U_left); 62*9ed3d70dSJames Wright UnpackState_U(right.U, U_right); 63*9ed3d70dSJames Wright UnpackState_U(flux_left, F_left); 64*9ed3d70dSJames Wright UnpackState_U(flux_right, F_right); 65*9ed3d70dSJames Wright for (int i = 0; i < 5; i++) { 66*9ed3d70dSJames 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); 67*9ed3d70dSJames Wright } 68*9ed3d70dSJames Wright StateConservative F = { 69*9ed3d70dSJames Wright F_hll[0], 70*9ed3d70dSJames Wright {F_hll[1], F_hll[2], F_hll[3]}, 71*9ed3d70dSJames Wright F_hll[4], 72*9ed3d70dSJames Wright }; 73*9ed3d70dSJames Wright return F; 74*9ed3d70dSJames Wright } 75*9ed3d70dSJames Wright 76*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER StateConservative Flux_HLL_fwd(State left, State right, State dleft, State dright, StateConservative flux_left, 77*9ed3d70dSJames Wright StateConservative flux_right, StateConservative dflux_left, StateConservative dflux_right, 78*9ed3d70dSJames Wright CeedScalar S_l, CeedScalar S_r, CeedScalar dS_l, CeedScalar dS_r) { 79*9ed3d70dSJames Wright CeedScalar U_l[5], U_r[5], F_r[5], F_l[5]; 80*9ed3d70dSJames Wright UnpackState_U(left.U, U_l); 81*9ed3d70dSJames Wright UnpackState_U(right.U, U_r); 82*9ed3d70dSJames Wright UnpackState_U(flux_left, F_l); 83*9ed3d70dSJames Wright UnpackState_U(flux_right, F_r); 84*9ed3d70dSJames Wright 85*9ed3d70dSJames Wright CeedScalar dU_l[5], dU_r[5], dF_r[5], dF_l[5], dF_hll[5] = {0.}; 86*9ed3d70dSJames Wright UnpackState_U(dleft.U, dU_l); 87*9ed3d70dSJames Wright UnpackState_U(dright.U, dU_r); 88*9ed3d70dSJames Wright UnpackState_U(dflux_left, dF_l); 89*9ed3d70dSJames Wright UnpackState_U(dflux_right, dF_r); 90*9ed3d70dSJames Wright for (int i = 0; i < 5; i++) { 91*9ed3d70dSJames Wright const CeedScalar U_diff = U_r[i] - U_l[i]; 92*9ed3d70dSJames Wright const CeedScalar S_diff = S_r - S_l; 93*9ed3d70dSJames Wright const CeedScalar F_hll_denom = S_r * F_l[i] - S_l * F_r[i] + S_l * S_r * U_diff; 94*9ed3d70dSJames Wright 95*9ed3d70dSJames Wright dF_hll[i] += ((F_l[i] + S_r * U_diff) * S_diff - F_hll_denom) / Square(S_diff) * dS_r; 96*9ed3d70dSJames Wright dF_hll[i] += ((-F_r[i] + S_r * U_diff) * S_diff + F_hll_denom) / Square(S_diff) * dS_l; 97*9ed3d70dSJames Wright dF_hll[i] += (S_r * dF_l[i] - S_l * dF_r[i] + S_r * S_l * dU_r[i] - S_r * S_l * dU_l[i]) / S_diff; 98*9ed3d70dSJames Wright } 99*9ed3d70dSJames Wright StateConservative dF = { 100*9ed3d70dSJames Wright dF_hll[0], 101*9ed3d70dSJames Wright {dF_hll[1], dF_hll[2], dF_hll[3]}, 102*9ed3d70dSJames Wright dF_hll[4], 103*9ed3d70dSJames Wright }; 104*9ed3d70dSJames Wright return dF; 105*9ed3d70dSJames Wright } 106*9ed3d70dSJames Wright 107*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER void ComputeHLLSpeeds_Roe(NewtonianIdealGasContext gas, State left, CeedScalar u_left, State right, CeedScalar u_right, 108*9ed3d70dSJames Wright CeedScalar *s_left, CeedScalar *s_right) { 109*9ed3d70dSJames Wright const CeedScalar gamma = HeatCapacityRatio(gas); 110*9ed3d70dSJames Wright 111*9ed3d70dSJames Wright RoeWeights r = RoeSetup(left.U.density, right.U.density); 112*9ed3d70dSJames Wright // Speed estimate 113*9ed3d70dSJames Wright // Roe average eigenvalues for left and right non-linear waves. 114*9ed3d70dSJames Wright // Stability requires that these speed estimates are *at least* as fast as the physical wave speeds. 115*9ed3d70dSJames Wright CeedScalar u_roe = RoeAverage(r, u_left, u_right); 116*9ed3d70dSJames Wright 117*9ed3d70dSJames Wright // TODO: revisit this for gravity 118*9ed3d70dSJames Wright CeedScalar H_left = TotalSpecificEnthalpy(gas, left); 119*9ed3d70dSJames Wright CeedScalar H_right = TotalSpecificEnthalpy(gas, right); 120*9ed3d70dSJames Wright CeedScalar H_roe = RoeAverage(r, H_left, H_right); 121*9ed3d70dSJames Wright CeedScalar a_roe = sqrt((gamma - 1) * (H_roe - 0.5 * Square(u_roe))); 122*9ed3d70dSJames Wright 123*9ed3d70dSJames Wright // Einfeldt (1988) justifies (and Toro's book repeats) that Roe speeds can be used here. 124*9ed3d70dSJames Wright *s_left = u_roe - a_roe; 125*9ed3d70dSJames Wright *s_right = u_roe + a_roe; 126*9ed3d70dSJames Wright } 127*9ed3d70dSJames Wright 128*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER void ComputeHLLSpeeds_Roe_fwd(NewtonianIdealGasContext gas, State left, State dleft, CeedScalar u_left, CeedScalar du_left, 129*9ed3d70dSJames Wright State right, State dright, CeedScalar u_right, CeedScalar du_right, CeedScalar *s_left, 130*9ed3d70dSJames Wright CeedScalar *ds_left, CeedScalar *s_right, CeedScalar *ds_right) { 131*9ed3d70dSJames Wright const CeedScalar gamma = HeatCapacityRatio(gas); 132*9ed3d70dSJames Wright 133*9ed3d70dSJames Wright RoeWeights r = RoeSetup(left.U.density, right.U.density); 134*9ed3d70dSJames Wright RoeWeights dr = RoeSetup_fwd(left.U.density, right.U.density, dleft.U.density, dright.U.density); 135*9ed3d70dSJames Wright // Speed estimate 136*9ed3d70dSJames Wright // Roe average eigenvalues for left and right non-linear waves. 137*9ed3d70dSJames Wright // Stability requires that these speed estimates are *at least* as fast as the physical wave speeds. 138*9ed3d70dSJames Wright CeedScalar u_roe = RoeAverage(r, u_left, u_right); 139*9ed3d70dSJames Wright CeedScalar du_roe = RoeAverage_fwd(r, dr, u_left, u_right, du_left, du_right); 140*9ed3d70dSJames Wright 141*9ed3d70dSJames Wright CeedScalar H_left = TotalSpecificEnthalpy(gas, left); 142*9ed3d70dSJames Wright CeedScalar H_right = TotalSpecificEnthalpy(gas, right); 143*9ed3d70dSJames Wright CeedScalar dH_left = TotalSpecificEnthalpy_fwd(gas, left, dleft); 144*9ed3d70dSJames Wright CeedScalar dH_right = TotalSpecificEnthalpy_fwd(gas, right, dright); 145*9ed3d70dSJames Wright 146*9ed3d70dSJames Wright CeedScalar H_roe = RoeAverage(r, H_left, H_right); 147*9ed3d70dSJames Wright CeedScalar dH_roe = RoeAverage_fwd(r, dr, H_left, H_right, dH_left, dH_right); 148*9ed3d70dSJames Wright CeedScalar a_roe = sqrt((gamma - 1) * (H_roe - 0.5 * Square(u_roe))); 149*9ed3d70dSJames Wright CeedScalar da_roe = 0.5 * (gamma - 1) / sqrt(H_roe) * dH_roe - 0.5 * sqrt(gamma - 1) * u_roe / sqrt(H_roe - 0.5 * Square(u_roe)) * du_roe; 150*9ed3d70dSJames Wright 151*9ed3d70dSJames Wright *s_left = u_roe - a_roe; 152*9ed3d70dSJames Wright *ds_left = du_roe - da_roe; 153*9ed3d70dSJames Wright *s_right = u_roe + a_roe; 154*9ed3d70dSJames Wright *ds_right = du_roe + da_roe; 155*9ed3d70dSJames Wright } 156*9ed3d70dSJames Wright 157*9ed3d70dSJames Wright // ***************************************************************************** 158*9ed3d70dSJames Wright // @brief Harten Lax VanLeer (HLL) approximate Riemann solver. 159*9ed3d70dSJames Wright // Taking in two states (left, right) and returns RiemannFlux_HLL. 160*9ed3d70dSJames Wright // The left and right states are specified from the perspective of an outward-facing normal vector pointing left to right. 161*9ed3d70dSJames Wright // 162*9ed3d70dSJames Wright // @param[in] gas NewtonianIdealGasContext for the fluid 163*9ed3d70dSJames Wright // @param[in] left Fluid state of the domain interior (the current solution) 164*9ed3d70dSJames Wright // @param[in] right Fluid state of the domain exterior (free stream conditions) 165*9ed3d70dSJames Wright // @param[in] normal Normalized, outward facing boundary normal vector 166*9ed3d70dSJames Wright // 167*9ed3d70dSJames Wright // @return StateConservative with HLL Riemann Flux 168*9ed3d70dSJames Wright // ***************************************************************************** 169*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER StateConservative RiemannFlux_HLL(NewtonianIdealGasContext gas, State left, State right, const CeedScalar normal[3]) { 170*9ed3d70dSJames Wright StateConservative flux_left = FluxInviscidDotNormal(gas, left, normal); 171*9ed3d70dSJames Wright StateConservative flux_right = FluxInviscidDotNormal(gas, right, normal); 172*9ed3d70dSJames Wright 173*9ed3d70dSJames Wright CeedScalar u_left = Dot3(left.Y.velocity, normal); 174*9ed3d70dSJames Wright CeedScalar u_right = Dot3(right.Y.velocity, normal); 175*9ed3d70dSJames Wright 176*9ed3d70dSJames Wright CeedScalar s_left, s_right; 177*9ed3d70dSJames Wright ComputeHLLSpeeds_Roe(gas, left, u_left, right, u_right, &s_left, &s_right); 178*9ed3d70dSJames Wright 179*9ed3d70dSJames Wright // Compute HLL flux 180*9ed3d70dSJames Wright if (0 <= s_left) { 181*9ed3d70dSJames Wright return flux_left; 182*9ed3d70dSJames Wright } else if (s_right <= 0) { 183*9ed3d70dSJames Wright return flux_right; 184*9ed3d70dSJames Wright } else { 185*9ed3d70dSJames Wright return Flux_HLL(left, right, flux_left, flux_right, s_left, s_right); 186*9ed3d70dSJames Wright } 187*9ed3d70dSJames Wright } 188*9ed3d70dSJames Wright 189*9ed3d70dSJames Wright // ***************************************************************************** 190*9ed3d70dSJames Wright // @brief Forward-mode Derivative of Harten Lax VanLeer (HLL) approximate Riemann solver. 191*9ed3d70dSJames Wright // 192*9ed3d70dSJames Wright // @param gas NewtonianIdealGasContext for the fluid 193*9ed3d70dSJames Wright // @param left Fluid state of the domain interior (the current solution) 194*9ed3d70dSJames Wright // @param right Fluid state of the domain exterior (free stream conditions) 195*9ed3d70dSJames Wright // @param dleft Derivative of fluid state of the domain interior (the current solution) 196*9ed3d70dSJames Wright // @param dright Derivative of fluid state of the domain exterior (free stream conditions) 197*9ed3d70dSJames Wright // @param normal Normalized, outward facing boundary normal vector 198*9ed3d70dSJames Wright // 199*9ed3d70dSJames Wright // @return StateConservative with derivative of HLL Riemann Flux 200*9ed3d70dSJames Wright // ***************************************************************************** 201*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER StateConservative RiemannFlux_HLL_fwd(NewtonianIdealGasContext gas, State left, State dleft, State right, State dright, 202*9ed3d70dSJames Wright const CeedScalar normal[3]) { 203*9ed3d70dSJames Wright StateConservative flux_left = FluxInviscidDotNormal(gas, left, normal); 204*9ed3d70dSJames Wright StateConservative flux_right = FluxInviscidDotNormal(gas, right, normal); 205*9ed3d70dSJames Wright StateConservative dflux_left = FluxInviscidDotNormal_fwd(gas, left, dleft, normal); 206*9ed3d70dSJames Wright StateConservative dflux_right = FluxInviscidDotNormal_fwd(gas, right, dright, normal); 207*9ed3d70dSJames Wright 208*9ed3d70dSJames Wright CeedScalar u_left = Dot3(left.Y.velocity, normal); 209*9ed3d70dSJames Wright CeedScalar u_right = Dot3(right.Y.velocity, normal); 210*9ed3d70dSJames Wright CeedScalar du_left = Dot3(dleft.Y.velocity, normal); 211*9ed3d70dSJames Wright CeedScalar du_right = Dot3(dright.Y.velocity, normal); 212*9ed3d70dSJames Wright 213*9ed3d70dSJames Wright CeedScalar s_left, ds_left, s_right, ds_right; 214*9ed3d70dSJames 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); 215*9ed3d70dSJames Wright 216*9ed3d70dSJames Wright if (0 <= s_left) { 217*9ed3d70dSJames Wright return dflux_left; 218*9ed3d70dSJames Wright } else if (s_right <= 0) { 219*9ed3d70dSJames Wright return dflux_right; 220*9ed3d70dSJames Wright } else { 221*9ed3d70dSJames 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); 222*9ed3d70dSJames Wright } 223*9ed3d70dSJames Wright } 224*9ed3d70dSJames Wright 225*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER StateConservative RiemannFlux_HLLC_Star(NewtonianIdealGasContext gas, State side, StateConservative F_side, 226*9ed3d70dSJames Wright const CeedScalar normal[3], CeedScalar u_side, CeedScalar s_side, CeedScalar s_star) { 227*9ed3d70dSJames Wright CeedScalar fact = side.U.density * (s_side - u_side) / (s_side - s_star); 228*9ed3d70dSJames Wright CeedScalar denom = side.U.density * (s_side - u_side); 229*9ed3d70dSJames Wright // U_* = fact * star 230*9ed3d70dSJames Wright StateConservative star = { 231*9ed3d70dSJames Wright 1.0, 232*9ed3d70dSJames Wright { 233*9ed3d70dSJames Wright side.Y.velocity[0] + (s_star - u_side) * normal[0], 234*9ed3d70dSJames Wright side.Y.velocity[1] + (s_star - u_side) * normal[1], 235*9ed3d70dSJames Wright side.Y.velocity[2] + (s_star - u_side) * normal[2], 236*9ed3d70dSJames Wright }, 237*9ed3d70dSJames Wright side.U.E_total / side.U.density // 238*9ed3d70dSJames Wright + (s_star - u_side) * (s_star + side.Y.pressure / denom) 239*9ed3d70dSJames Wright }; 240*9ed3d70dSJames Wright return StateConservativeAXPBYPCZ(1, F_side, s_side * fact, star, -s_side, side.U); 241*9ed3d70dSJames Wright } 242*9ed3d70dSJames Wright 243*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER StateConservative RiemannFlux_HLLC_Star_fwd(NewtonianIdealGasContext gas, State side, State dside, StateConservative F_side, 244*9ed3d70dSJames Wright StateConservative dF_side, const CeedScalar normal[3], CeedScalar u_side, 245*9ed3d70dSJames Wright CeedScalar du_side, CeedScalar s_side, CeedScalar ds_side, CeedScalar s_star, 246*9ed3d70dSJames Wright CeedScalar ds_star) { 247*9ed3d70dSJames Wright CeedScalar fact = side.U.density * (s_side - u_side) / (s_side - s_star); 248*9ed3d70dSJames Wright CeedScalar dfact = (side.U.density * (ds_side - du_side) + dside.U.density * (s_side - u_side)) / (s_side - s_star) // 249*9ed3d70dSJames Wright - fact / (s_side - s_star) * (ds_side - ds_star); 250*9ed3d70dSJames Wright CeedScalar denom = side.U.density * (s_side - u_side); 251*9ed3d70dSJames Wright CeedScalar ddenom = side.U.density * (ds_side - du_side) + dside.U.density * (s_side - u_side); 252*9ed3d70dSJames Wright 253*9ed3d70dSJames Wright StateConservative star = { 254*9ed3d70dSJames Wright 1.0, 255*9ed3d70dSJames Wright { 256*9ed3d70dSJames Wright side.Y.velocity[0] + (s_star - u_side) * normal[0], 257*9ed3d70dSJames Wright side.Y.velocity[1] + (s_star - u_side) * normal[1], 258*9ed3d70dSJames Wright side.Y.velocity[2] + (s_star - u_side) * normal[2], 259*9ed3d70dSJames Wright }, 260*9ed3d70dSJames Wright side.U.E_total / side.U.density // 261*9ed3d70dSJames Wright + (s_star - u_side) * (s_star + side.Y.pressure / denom) 262*9ed3d70dSJames Wright }; 263*9ed3d70dSJames Wright StateConservative dstar = { 264*9ed3d70dSJames Wright 0., 265*9ed3d70dSJames Wright { 266*9ed3d70dSJames Wright dside.Y.velocity[0] + (ds_star - du_side) * normal[0], 267*9ed3d70dSJames Wright dside.Y.velocity[1] + (ds_star - du_side) * normal[1], 268*9ed3d70dSJames Wright dside.Y.velocity[2] + (ds_star - du_side) * normal[2], 269*9ed3d70dSJames Wright }, 270*9ed3d70dSJames Wright dside.U.E_total / side.U.density - side.U.E_total / Square(side.U.density) * dside.U.density // 271*9ed3d70dSJames Wright + (ds_star - du_side) * (s_star + side.Y.pressure / denom) // 272*9ed3d70dSJames Wright + (s_star - u_side) * (ds_star + dside.Y.pressure / denom - side.Y.pressure / Square(denom) * ddenom) // 273*9ed3d70dSJames Wright }; 274*9ed3d70dSJames Wright 275*9ed3d70dSJames Wright const CeedScalar a[] = {1, ds_side * fact + s_side * dfact, s_side * fact, -ds_side, -s_side}; 276*9ed3d70dSJames Wright const StateConservative U[] = {dF_side, star, dstar, side.U, dside.U}; 277*9ed3d70dSJames Wright return StateConservativeMult(5, a, U); 278*9ed3d70dSJames Wright } 279*9ed3d70dSJames Wright 280*9ed3d70dSJames Wright // HLLC Riemann solver (from Toro's book) 281*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER StateConservative RiemannFlux_HLLC(NewtonianIdealGasContext gas, State left, State right, const CeedScalar normal[3]) { 282*9ed3d70dSJames Wright StateConservative flux_left = FluxInviscidDotNormal(gas, left, normal); 283*9ed3d70dSJames Wright StateConservative flux_right = FluxInviscidDotNormal(gas, right, normal); 284*9ed3d70dSJames Wright 285*9ed3d70dSJames Wright CeedScalar u_left = Dot3(left.Y.velocity, normal); 286*9ed3d70dSJames Wright CeedScalar u_right = Dot3(right.Y.velocity, normal); 287*9ed3d70dSJames Wright CeedScalar s_left, s_right; 288*9ed3d70dSJames Wright ComputeHLLSpeeds_Roe(gas, left, u_left, right, u_right, &s_left, &s_right); 289*9ed3d70dSJames Wright 290*9ed3d70dSJames Wright // Contact wave speed; Toro (10.37) 291*9ed3d70dSJames Wright CeedScalar rhou_left = left.U.density * u_left, rhou_right = right.U.density * u_right; 292*9ed3d70dSJames Wright CeedScalar numer = right.Y.pressure - left.Y.pressure + rhou_left * (s_left - u_left) - rhou_right * (s_right - u_right); 293*9ed3d70dSJames Wright CeedScalar denom = left.U.density * (s_left - u_left) - right.U.density * (s_right - u_right); 294*9ed3d70dSJames Wright CeedScalar s_star = numer / denom; 295*9ed3d70dSJames Wright 296*9ed3d70dSJames Wright // Compute HLLC flux 297*9ed3d70dSJames Wright if (0 <= s_left) { 298*9ed3d70dSJames Wright return flux_left; 299*9ed3d70dSJames Wright } else if (0 <= s_star) { 300*9ed3d70dSJames Wright return RiemannFlux_HLLC_Star(gas, left, flux_left, normal, u_left, s_left, s_star); 301*9ed3d70dSJames Wright } else if (0 <= s_right) { 302*9ed3d70dSJames Wright return RiemannFlux_HLLC_Star(gas, right, flux_right, normal, u_right, s_right, s_star); 303*9ed3d70dSJames Wright } else { 304*9ed3d70dSJames Wright return flux_right; 305*9ed3d70dSJames Wright } 306*9ed3d70dSJames Wright } 307*9ed3d70dSJames Wright 308*9ed3d70dSJames Wright CEED_QFUNCTION_HELPER StateConservative RiemannFlux_HLLC_fwd(NewtonianIdealGasContext gas, State left, State dleft, State right, State dright, 309*9ed3d70dSJames Wright const CeedScalar normal[3]) { 310*9ed3d70dSJames Wright StateConservative flux_left = FluxInviscidDotNormal(gas, left, normal); 311*9ed3d70dSJames Wright StateConservative flux_right = FluxInviscidDotNormal(gas, right, normal); 312*9ed3d70dSJames Wright StateConservative dflux_left = FluxInviscidDotNormal_fwd(gas, left, dleft, normal); 313*9ed3d70dSJames Wright StateConservative dflux_right = FluxInviscidDotNormal_fwd(gas, right, dright, normal); 314*9ed3d70dSJames Wright 315*9ed3d70dSJames Wright CeedScalar u_left = Dot3(left.Y.velocity, normal); 316*9ed3d70dSJames Wright CeedScalar u_right = Dot3(right.Y.velocity, normal); 317*9ed3d70dSJames Wright CeedScalar du_left = Dot3(dleft.Y.velocity, normal); 318*9ed3d70dSJames Wright CeedScalar du_right = Dot3(dright.Y.velocity, normal); 319*9ed3d70dSJames Wright 320*9ed3d70dSJames Wright CeedScalar s_left, ds_left, s_right, ds_right; 321*9ed3d70dSJames 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); 322*9ed3d70dSJames Wright 323*9ed3d70dSJames Wright // Contact wave speed; Toro (10.37) 324*9ed3d70dSJames Wright CeedScalar rhou_left = left.U.density * u_left, drhou_left = left.U.density * du_left + dleft.U.density * u_left; 325*9ed3d70dSJames Wright CeedScalar rhou_right = right.U.density * u_right, drhou_right = right.U.density * du_right + dright.U.density * u_right; 326*9ed3d70dSJames Wright CeedScalar numer = right.Y.pressure - left.Y.pressure // 327*9ed3d70dSJames Wright + rhou_left * (s_left - u_left) // 328*9ed3d70dSJames Wright - rhou_right * (s_right - u_right); 329*9ed3d70dSJames Wright CeedScalar dnumer = dright.Y.pressure - dleft.Y.pressure // 330*9ed3d70dSJames Wright + rhou_left * (ds_left - du_left) + drhou_left * (s_left - u_left) // 331*9ed3d70dSJames Wright - rhou_right * (ds_right - du_right) - drhou_right * (s_right - u_right); 332*9ed3d70dSJames Wright CeedScalar denom = left.U.density * (s_left - u_left) - right.U.density * (s_right - u_right); 333*9ed3d70dSJames Wright CeedScalar ddenom = left.U.density * (ds_left - du_left) + dleft.U.density * (s_left - u_left) // 334*9ed3d70dSJames Wright - right.U.density * (ds_right - du_right) - dright.U.density * (s_right - u_right); 335*9ed3d70dSJames Wright CeedScalar s_star = numer / denom; 336*9ed3d70dSJames Wright CeedScalar ds_star = dnumer / denom - numer / Square(denom) * ddenom; 337*9ed3d70dSJames Wright 338*9ed3d70dSJames Wright // Compute HLLC flux 339*9ed3d70dSJames Wright if (0 <= s_left) { 340*9ed3d70dSJames Wright return dflux_left; 341*9ed3d70dSJames Wright } else if (0 <= s_star) { 342*9ed3d70dSJames 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); 343*9ed3d70dSJames Wright } else if (0 <= s_right) { 344*9ed3d70dSJames 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); 345*9ed3d70dSJames Wright } else { 346*9ed3d70dSJames Wright return dflux_right; 347*9ed3d70dSJames Wright } 348*9ed3d70dSJames Wright } 349*9ed3d70dSJames Wright 350*9ed3d70dSJames Wright #endif // riemann_solver_h 351