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 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 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 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 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 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 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 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 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 // ***************************************************************************** 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 // ***************************************************************************** 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 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 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) 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 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