1c6e8c570SJames Wright // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 2c6e8c570SJames Wright // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3c6e8c570SJames Wright // 4c6e8c570SJames Wright // SPDX-License-Identifier: BSD-2-Clause 5c6e8c570SJames Wright // 6c6e8c570SJames Wright // This file is part of CEED: http://github.com/ceed 7c6e8c570SJames Wright 8c6e8c570SJames Wright /// @file 9c6e8c570SJames Wright /// Structs and helper functions regarding the state of a newtonian simulation 10c6e8c570SJames Wright 11c6e8c570SJames Wright #ifndef newtonian_state_h 12c6e8c570SJames Wright #define newtonian_state_h 13c6e8c570SJames Wright 14c6e8c570SJames Wright #include <ceed.h> 15c9c2c079SJeremy L Thompson #include <math.h> 162b730f8bSJeremy L Thompson 17c6e8c570SJames Wright #include "newtonian_types.h" 1813fa47b2SJames Wright #include "utils.h" 19c6e8c570SJames Wright 20c6e8c570SJames Wright typedef struct { 21c6e8c570SJames Wright CeedScalar density; 22c6e8c570SJames Wright CeedScalar momentum[3]; 23c6e8c570SJames Wright CeedScalar E_total; 24c6e8c570SJames Wright } StateConservative; 25c6e8c570SJames Wright 26c6e8c570SJames Wright typedef struct { 27c6e8c570SJames Wright StateConservative U; 28c6e8c570SJames Wright StatePrimitive Y; 29c6e8c570SJames Wright } State; 30c6e8c570SJames Wright 312b89d87eSLeila Ghaffari CEED_QFUNCTION_HELPER void UnpackState_U(StateConservative s, CeedScalar U[5]) { 322b89d87eSLeila Ghaffari U[0] = s.density; 332b89d87eSLeila Ghaffari for (int i = 0; i < 3; i++) U[i + 1] = s.momentum[i]; 342b89d87eSLeila Ghaffari U[4] = s.E_total; 352b89d87eSLeila Ghaffari } 362b89d87eSLeila Ghaffari 372b89d87eSLeila Ghaffari CEED_QFUNCTION_HELPER void UnpackState_Y(StatePrimitive s, CeedScalar Y[5]) { 382b89d87eSLeila Ghaffari Y[0] = s.pressure; 392b89d87eSLeila Ghaffari for (int i = 0; i < 3; i++) Y[i + 1] = s.velocity[i]; 402b89d87eSLeila Ghaffari Y[4] = s.temperature; 412b89d87eSLeila Ghaffari } 422b89d87eSLeila Ghaffari 432b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER CeedScalar HeatCapacityRatio(NewtonianIdealGasContext gas) { return gas->cp / gas->cv; } 442518f336SLeila Ghaffari 452b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER CeedScalar GasConstant(NewtonianIdealGasContext gas) { return gas->cp - gas->cv; } 462518f336SLeila Ghaffari 472b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER CeedScalar Prandtl(NewtonianIdealGasContext gas) { return gas->cp * gas->mu / gas->k; } 482518f336SLeila Ghaffari 492b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER CeedScalar SoundSpeed(NewtonianIdealGasContext gas, CeedScalar T) { return sqrt(gas->cp * (HeatCapacityRatio(gas) - 1.) * T); } 502518f336SLeila Ghaffari 512b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER CeedScalar Mach(NewtonianIdealGasContext gas, CeedScalar T, CeedScalar u) { return u / SoundSpeed(gas, T); } 522518f336SLeila Ghaffari 532b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER CeedScalar TotalSpecificEnthalpy(NewtonianIdealGasContext gas, const State s) { 54f0a19222SJames Wright // Ignoring potential energy 55f0a19222SJames Wright CeedScalar e_internal = gas->cv * s.Y.temperature; 56f0a19222SJames Wright CeedScalar e_kinetic = 0.5 * Dot3(s.Y.velocity, s.Y.velocity); 57f0a19222SJames Wright return e_internal + e_kinetic + s.Y.pressure / s.U.density; 58f0a19222SJames Wright } 59f0a19222SJames Wright 602b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER CeedScalar TotalSpecificEnthalpy_fwd(NewtonianIdealGasContext gas, const State s, const State ds) { 61f0a19222SJames Wright // Ignoring potential energy 62f0a19222SJames Wright CeedScalar de_kinetic = Dot3(ds.Y.velocity, s.Y.velocity); 63f0a19222SJames Wright CeedScalar de_internal = gas->cv * ds.Y.temperature; 642b730f8bSJeremy L Thompson return de_internal + de_kinetic + ds.Y.pressure / s.U.density - s.Y.pressure / Square(s.U.density) * ds.U.density; 65f0a19222SJames Wright } 66f0a19222SJames Wright 672b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER StatePrimitive StatePrimitiveFromConservative(NewtonianIdealGasContext gas, StateConservative U, const CeedScalar x[3]) { 68c6e8c570SJames Wright StatePrimitive Y; 69c6e8c570SJames Wright for (CeedInt i = 0; i < 3; i++) Y.velocity[i] = U.momentum[i] / U.density; 70c6e8c570SJames Wright CeedScalar e_kinetic = .5 * Dot3(Y.velocity, Y.velocity); 71c6e8c570SJames Wright CeedScalar e_potential = -Dot3(gas->g, x); 72c6e8c570SJames Wright CeedScalar e_total = U.E_total / U.density; 73c6e8c570SJames Wright CeedScalar e_internal = e_total - e_kinetic - e_potential; 74c6e8c570SJames Wright Y.temperature = e_internal / gas->cv; 752518f336SLeila Ghaffari Y.pressure = (HeatCapacityRatio(gas) - 1) * U.density * e_internal; 76c6e8c570SJames Wright return Y; 77c6e8c570SJames Wright } 78c6e8c570SJames Wright 792b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER StatePrimitive StatePrimitiveFromConservative_fwd(NewtonianIdealGasContext gas, State s, StateConservative dU, 80c6e8c570SJames Wright const CeedScalar x[3], const CeedScalar dx[3]) { 81c6e8c570SJames Wright StatePrimitive dY; 82c6e8c570SJames Wright for (CeedInt i = 0; i < 3; i++) { 83c6e8c570SJames Wright dY.velocity[i] = (dU.momentum[i] - s.Y.velocity[i] * dU.density) / s.U.density; 84c6e8c570SJames Wright } 85c6e8c570SJames Wright CeedScalar e_kinetic = .5 * Dot3(s.Y.velocity, s.Y.velocity); 86c6e8c570SJames Wright CeedScalar de_kinetic = Dot3(dY.velocity, s.Y.velocity); 87c6e8c570SJames Wright CeedScalar e_potential = -Dot3(gas->g, x); 88c6e8c570SJames Wright CeedScalar de_potential = -Dot3(gas->g, dx); 89c6e8c570SJames Wright CeedScalar e_total = s.U.E_total / s.U.density; 90c6e8c570SJames Wright CeedScalar de_total = (dU.E_total - e_total * dU.density) / s.U.density; 91c6e8c570SJames Wright CeedScalar e_internal = e_total - e_kinetic - e_potential; 92c6e8c570SJames Wright CeedScalar de_internal = de_total - de_kinetic - de_potential; 93c6e8c570SJames Wright dY.temperature = de_internal / gas->cv; 942b730f8bSJeremy L Thompson dY.pressure = (HeatCapacityRatio(gas) - 1) * (dU.density * e_internal + s.U.density * de_internal); 95c6e8c570SJames Wright return dY; 96c6e8c570SJames Wright } 97c6e8c570SJames Wright 982b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER StateConservative StateConservativeFromPrimitive(NewtonianIdealGasContext gas, StatePrimitive Y, const CeedScalar x[3]) { 99dc805cc4SLeila Ghaffari StateConservative U; 1002518f336SLeila Ghaffari U.density = Y.pressure / (GasConstant(gas) * Y.temperature); 101dc805cc4SLeila Ghaffari for (int i = 0; i < 3; i++) U.momentum[i] = U.density * Y.velocity[i]; 102dc805cc4SLeila Ghaffari CeedScalar e_internal = gas->cv * Y.temperature; 103dc805cc4SLeila Ghaffari CeedScalar e_kinetic = .5 * Dot3(Y.velocity, Y.velocity); 104dc805cc4SLeila Ghaffari CeedScalar e_potential = -Dot3(gas->g, x); 105dc805cc4SLeila Ghaffari CeedScalar e_total = e_internal + e_kinetic + e_potential; 106dc805cc4SLeila Ghaffari U.E_total = U.density * e_total; 107dc805cc4SLeila Ghaffari return U; 108dc805cc4SLeila Ghaffari } 109dc805cc4SLeila Ghaffari 1102b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER StateConservative StateConservativeFromPrimitive_fwd(NewtonianIdealGasContext gas, State s, StatePrimitive dY, 111dc805cc4SLeila Ghaffari const CeedScalar x[3], const CeedScalar dx[3]) { 112dc805cc4SLeila Ghaffari StateConservative dU; 1132b730f8bSJeremy L Thompson dU.density = (dY.pressure * s.Y.temperature - s.Y.pressure * dY.temperature) / (GasConstant(gas) * s.Y.temperature * s.Y.temperature); 114dc805cc4SLeila Ghaffari for (int i = 0; i < 3; i++) { 115dc805cc4SLeila Ghaffari dU.momentum[i] = dU.density * s.Y.velocity[i] + s.U.density * dY.velocity[i]; 116dc805cc4SLeila Ghaffari } 117dc805cc4SLeila Ghaffari CeedScalar e_kinetic = .5 * Dot3(s.Y.velocity, s.Y.velocity); 118dc805cc4SLeila Ghaffari CeedScalar de_kinetic = Dot3(dY.velocity, s.Y.velocity); 119dc805cc4SLeila Ghaffari CeedScalar e_potential = -Dot3(gas->g, x); 120dc805cc4SLeila Ghaffari CeedScalar de_potential = -Dot3(gas->g, dx); 121dc805cc4SLeila Ghaffari CeedScalar e_internal = gas->cv * s.Y.temperature; 122dc805cc4SLeila Ghaffari CeedScalar de_internal = gas->cv * dY.temperature; 123dc805cc4SLeila Ghaffari CeedScalar e_total = e_internal + e_kinetic + e_potential; 124dc805cc4SLeila Ghaffari CeedScalar de_total = de_internal + de_kinetic + de_potential; 125dc805cc4SLeila Ghaffari dU.E_total = dU.density * e_total + s.U.density * de_total; 126dc805cc4SLeila Ghaffari return dU; 127dc805cc4SLeila Ghaffari } 128dc805cc4SLeila Ghaffari 129d310b3d3SAdeleke O. Bankole CEED_QFUNCTION_HELPER State StateFromPrimitive(NewtonianIdealGasContext gas, StatePrimitive Y, const CeedScalar x[3]) { 130d310b3d3SAdeleke O. Bankole StateConservative U = StateConservativeFromPrimitive(gas, Y, x); 131d310b3d3SAdeleke O. Bankole State s; 132d310b3d3SAdeleke O. Bankole s.U = U; 133d310b3d3SAdeleke O. Bankole s.Y = Y; 134d310b3d3SAdeleke O. Bankole return s; 135d310b3d3SAdeleke O. Bankole } 136d310b3d3SAdeleke O. Bankole 1378a94a473SJed Brown CEED_QFUNCTION_HELPER State StateFromPrimitive_fwd(NewtonianIdealGasContext gas, State s, StatePrimitive dY, const CeedScalar x[3], 1388a94a473SJed Brown const CeedScalar dx[3]) { 1398a94a473SJed Brown StateConservative dU = StateConservativeFromPrimitive_fwd(gas, s, dY, x, dx); 1408a94a473SJed Brown State ds; 1418a94a473SJed Brown ds.U = dU; 1428a94a473SJed Brown ds.Y = dY; 1438a94a473SJed Brown return ds; 1448a94a473SJed Brown } 1458a94a473SJed Brown 146c95797efSJed Brown // linear combination of n states 147c95797efSJed Brown CEED_QFUNCTION_HELPER StateConservative StateConservativeMult(CeedInt n, const CeedScalar a[], const StateConservative X[]) { 148c95797efSJed Brown StateConservative R = {0}; 149c95797efSJed Brown for (CeedInt i = 0; i < n; i++) { 150c95797efSJed Brown R.density += a[i] * X[i].density; 151c95797efSJed Brown for (int j = 0; j < 3; j++) R.momentum[j] += a[i] * X[i].momentum[j]; 152c95797efSJed Brown R.E_total += a[i] * X[i].E_total; 153c95797efSJed Brown } 15484ae27ebSJed Brown return R; 15584ae27ebSJed Brown } 15684ae27ebSJed Brown 15784ae27ebSJed Brown CEED_QFUNCTION_HELPER StateConservative StateConservativeAXPBYPCZ(CeedScalar a, StateConservative X, CeedScalar b, StateConservative Y, CeedScalar c, 15884ae27ebSJed Brown StateConservative Z) { 15984ae27ebSJed Brown StateConservative R; 16084ae27ebSJed Brown R.density = a * X.density + b * Y.density + c * Z.density; 16184ae27ebSJed Brown for (int i = 0; i < 3; i++) R.momentum[i] = a * X.momentum[i] + b * Y.momentum[i] + c * Z.momentum[i]; 16284ae27ebSJed Brown R.E_total = a * X.E_total + b * Y.E_total + c * Z.E_total; 16384ae27ebSJed Brown return R; 16484ae27ebSJed Brown } 16584ae27ebSJed Brown 166d310b3d3SAdeleke O. Bankole CEED_QFUNCTION_HELPER void StateToU(NewtonianIdealGasContext gas, const State input, CeedScalar U[5]) { UnpackState_U(input.U, U); } 167d310b3d3SAdeleke O. Bankole 168d310b3d3SAdeleke O. Bankole CEED_QFUNCTION_HELPER void StateToY(NewtonianIdealGasContext gas, const State input, CeedScalar Y[5]) { UnpackState_Y(input.Y, Y); } 169f179a332SJames Wright 170be91e165SJames Wright CEED_QFUNCTION_HELPER void StateToQ(NewtonianIdealGasContext gas, const State input, CeedScalar Q[5], StateVariable state_var) { 171be91e165SJames Wright switch (state_var) { 172be91e165SJames Wright case STATEVAR_CONSERVATIVE: 173be91e165SJames Wright StateToU(gas, input, Q); 174be91e165SJames Wright break; 175be91e165SJames Wright case STATEVAR_PRIMITIVE: 176be91e165SJames Wright StateToY(gas, input, Q); 177be91e165SJames Wright break; 178be91e165SJames Wright } 179be91e165SJames Wright } 18020840d50SJames Wright 1812b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER State StateFromU(NewtonianIdealGasContext gas, const CeedScalar U[5], const CeedScalar x[3]) { 182c6e8c570SJames Wright State s; 183c6e8c570SJames Wright s.U.density = U[0]; 184c6e8c570SJames Wright s.U.momentum[0] = U[1]; 185c6e8c570SJames Wright s.U.momentum[1] = U[2]; 186c6e8c570SJames Wright s.U.momentum[2] = U[3]; 187c6e8c570SJames Wright s.U.E_total = U[4]; 188c6e8c570SJames Wright s.Y = StatePrimitiveFromConservative(gas, s.U, x); 189c6e8c570SJames Wright return s; 190c6e8c570SJames Wright } 191c6e8c570SJames Wright 1922b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER State StateFromU_fwd(NewtonianIdealGasContext gas, State s, const CeedScalar dU[5], const CeedScalar x[3], 1932b730f8bSJeremy L Thompson const CeedScalar dx[3]) { 194c6e8c570SJames Wright State ds; 195c6e8c570SJames Wright ds.U.density = dU[0]; 196c6e8c570SJames Wright ds.U.momentum[0] = dU[1]; 197c6e8c570SJames Wright ds.U.momentum[1] = dU[2]; 198c6e8c570SJames Wright ds.U.momentum[2] = dU[3]; 199c6e8c570SJames Wright ds.U.E_total = dU[4]; 200c6e8c570SJames Wright ds.Y = StatePrimitiveFromConservative_fwd(gas, s, ds.U, x, dx); 201c6e8c570SJames Wright return ds; 202c6e8c570SJames Wright } 203c6e8c570SJames Wright 2042b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER State StateFromY(NewtonianIdealGasContext gas, const CeedScalar Y[5], const CeedScalar x[3]) { 205dc805cc4SLeila Ghaffari State s; 206dc805cc4SLeila Ghaffari s.Y.pressure = Y[0]; 207dc805cc4SLeila Ghaffari s.Y.velocity[0] = Y[1]; 208dc805cc4SLeila Ghaffari s.Y.velocity[1] = Y[2]; 209dc805cc4SLeila Ghaffari s.Y.velocity[2] = Y[3]; 210dc805cc4SLeila Ghaffari s.Y.temperature = Y[4]; 211dc805cc4SLeila Ghaffari s.U = StateConservativeFromPrimitive(gas, s.Y, x); 212dc805cc4SLeila Ghaffari return s; 213dc805cc4SLeila Ghaffari } 214dc805cc4SLeila Ghaffari 2152b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER State StateFromY_fwd(NewtonianIdealGasContext gas, State s, const CeedScalar dY[5], const CeedScalar x[3], 2162b730f8bSJeremy L Thompson const CeedScalar dx[3]) { 217dc805cc4SLeila Ghaffari State ds; 218dc805cc4SLeila Ghaffari ds.Y.pressure = dY[0]; 219dc805cc4SLeila Ghaffari ds.Y.velocity[0] = dY[1]; 220dc805cc4SLeila Ghaffari ds.Y.velocity[1] = dY[2]; 221dc805cc4SLeila Ghaffari ds.Y.velocity[2] = dY[3]; 222dc805cc4SLeila Ghaffari ds.Y.temperature = dY[4]; 223dc805cc4SLeila Ghaffari ds.U = StateConservativeFromPrimitive_fwd(gas, s, ds.Y, x, dx); 224dc805cc4SLeila Ghaffari return ds; 225dc805cc4SLeila Ghaffari } 226dc805cc4SLeila Ghaffari 227be91e165SJames Wright CEED_QFUNCTION_HELPER State StateFromQ(NewtonianIdealGasContext gas, const CeedScalar Q[5], const CeedScalar x[3], StateVariable state_var) { 228be91e165SJames Wright State s; 229be91e165SJames Wright switch (state_var) { 230be91e165SJames Wright case STATEVAR_CONSERVATIVE: 231be91e165SJames Wright s = StateFromU(gas, Q, x); 232be91e165SJames Wright break; 233be91e165SJames Wright case STATEVAR_PRIMITIVE: 234be91e165SJames Wright s = StateFromY(gas, Q, x); 235be91e165SJames Wright break; 236be91e165SJames Wright } 237be91e165SJames Wright return s; 238be91e165SJames Wright } 239be91e165SJames Wright 240be91e165SJames Wright CEED_QFUNCTION_HELPER State StateFromQ_fwd(NewtonianIdealGasContext gas, State s, const CeedScalar dQ[5], const CeedScalar x[3], 241be91e165SJames Wright const CeedScalar dx[3], StateVariable state_var) { 242be91e165SJames Wright State ds; 243be91e165SJames Wright switch (state_var) { 244be91e165SJames Wright case STATEVAR_CONSERVATIVE: 245be91e165SJames Wright ds = StateFromU_fwd(gas, s, dQ, x, dx); 246be91e165SJames Wright break; 247be91e165SJames Wright case STATEVAR_PRIMITIVE: 248be91e165SJames Wright ds = StateFromY_fwd(gas, s, dQ, x, dx); 249be91e165SJames Wright break; 250be91e165SJames Wright } 251be91e165SJames Wright return ds; 252be91e165SJames Wright } 253be91e165SJames Wright 2542b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER void FluxInviscid(NewtonianIdealGasContext gas, State s, StateConservative Flux[3]) { 255c6e8c570SJames Wright for (CeedInt i = 0; i < 3; i++) { 256c6e8c570SJames Wright Flux[i].density = s.U.momentum[i]; 2572b730f8bSJeremy L Thompson for (CeedInt j = 0; j < 3; j++) Flux[i].momentum[j] = s.U.momentum[i] * s.Y.velocity[j] + s.Y.pressure * (i == j); 258c6e8c570SJames Wright Flux[i].E_total = (s.U.E_total + s.Y.pressure) * s.Y.velocity[i]; 259c6e8c570SJames Wright } 260c6e8c570SJames Wright } 261c6e8c570SJames Wright 2622b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER void FluxInviscid_fwd(NewtonianIdealGasContext gas, State s, State ds, StateConservative dFlux[3]) { 263f0a19222SJames Wright for (CeedInt i = 0; i < 3; i++) { 264f0a19222SJames Wright dFlux[i].density = ds.U.momentum[i]; 2652b730f8bSJeremy L Thompson for (CeedInt j = 0; j < 3; j++) { 2662b730f8bSJeremy L Thompson dFlux[i].momentum[j] = ds.U.momentum[i] * s.Y.velocity[j] + s.U.momentum[i] * ds.Y.velocity[j] + ds.Y.pressure * (i == j); 2672b730f8bSJeremy L Thompson } 2682b730f8bSJeremy L Thompson dFlux[i].E_total = (ds.U.E_total + ds.Y.pressure) * s.Y.velocity[i] + (s.U.E_total + s.Y.pressure) * ds.Y.velocity[i]; 269f0a19222SJames Wright } 270f0a19222SJames Wright } 271f0a19222SJames Wright 2722b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER StateConservative FluxInviscidDotNormal(NewtonianIdealGasContext gas, State s, const CeedScalar normal[3]) { 273738af36cSAdelekeBankole StateConservative Flux[3], Flux_dot_n = {0}; 274738af36cSAdelekeBankole FluxInviscid(gas, s, Flux); 275738af36cSAdelekeBankole for (CeedInt i = 0; i < 3; i++) { 276738af36cSAdelekeBankole Flux_dot_n.density += Flux[i].density * normal[i]; 2772b730f8bSJeremy L Thompson for (CeedInt j = 0; j < 3; j++) Flux_dot_n.momentum[j] += Flux[i].momentum[j] * normal[i]; 278738af36cSAdelekeBankole Flux_dot_n.E_total += Flux[i].E_total * normal[i]; 279738af36cSAdelekeBankole } 280738af36cSAdelekeBankole return Flux_dot_n; 281738af36cSAdelekeBankole } 282738af36cSAdelekeBankole 2832b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER StateConservative FluxInviscidDotNormal_fwd(NewtonianIdealGasContext gas, State s, State ds, const CeedScalar normal[3]) { 284f0a19222SJames Wright StateConservative dFlux[3], Flux_dot_n = {0}; 285f0a19222SJames Wright FluxInviscid_fwd(gas, s, ds, dFlux); 286c6e8c570SJames Wright for (CeedInt i = 0; i < 3; i++) { 287f0a19222SJames Wright Flux_dot_n.density += dFlux[i].density * normal[i]; 2882b730f8bSJeremy L Thompson for (CeedInt j = 0; j < 3; j++) Flux_dot_n.momentum[j] += dFlux[i].momentum[j] * normal[i]; 289f0a19222SJames Wright Flux_dot_n.E_total += dFlux[i].E_total * normal[i]; 290c6e8c570SJames Wright } 291f0a19222SJames Wright return Flux_dot_n; 292c6e8c570SJames Wright } 293c6e8c570SJames Wright 2942b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER void FluxInviscidStrong(NewtonianIdealGasContext gas, State s, State ds[3], CeedScalar strong_conv[5]) { 2952b89d87eSLeila Ghaffari for (CeedInt i = 0; i < 5; i++) strong_conv[i] = 0; 2962b89d87eSLeila Ghaffari for (CeedInt i = 0; i < 3; i++) { 2972b89d87eSLeila Ghaffari StateConservative dF[3]; 2982b89d87eSLeila Ghaffari FluxInviscid_fwd(gas, s, ds[i], dF); 2992b89d87eSLeila Ghaffari CeedScalar dF_i[5]; 3002b89d87eSLeila Ghaffari UnpackState_U(dF[i], dF_i); 3012b730f8bSJeremy L Thompson for (CeedInt j = 0; j < 5; j++) strong_conv[j] += dF_i[j]; 3022b89d87eSLeila Ghaffari } 3032b89d87eSLeila Ghaffari } 3042b89d87eSLeila Ghaffari 3052b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER void FluxTotal(const StateConservative F_inviscid[3], CeedScalar stress[3][3], CeedScalar Fe[3], CeedScalar Flux[5][3]) { 3062b89d87eSLeila Ghaffari for (CeedInt j = 0; j < 3; j++) { 3072b89d87eSLeila Ghaffari Flux[0][j] = F_inviscid[j].density; 3082b730f8bSJeremy L Thompson for (CeedInt k = 0; k < 3; k++) Flux[k + 1][j] = F_inviscid[j].momentum[k] - stress[k][j]; 3092b89d87eSLeila Ghaffari Flux[4][j] = F_inviscid[j].E_total + Fe[j]; 3102b89d87eSLeila Ghaffari } 3112b89d87eSLeila Ghaffari } 3122b89d87eSLeila Ghaffari 3132b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER void FluxTotal_Boundary(const StateConservative F_inviscid[3], const CeedScalar stress[3][3], const CeedScalar Fe[3], 3142b730f8bSJeremy L Thompson const CeedScalar normal[3], CeedScalar Flux[5]) { 3155bce47c7SJames Wright for (CeedInt j = 0; j < 5; j++) Flux[j] = 0.; 3165bce47c7SJames Wright for (CeedInt j = 0; j < 3; j++) { 3175bce47c7SJames Wright Flux[0] += F_inviscid[j].density * normal[j]; 3185bce47c7SJames Wright for (CeedInt k = 0; k < 3; k++) { 3195bce47c7SJames Wright Flux[k + 1] += (F_inviscid[j].momentum[k] - stress[k][j]) * normal[j]; 3205bce47c7SJames Wright } 3215bce47c7SJames Wright Flux[4] += (F_inviscid[j].E_total + Fe[j]) * normal[j]; 3225bce47c7SJames Wright } 3235bce47c7SJames Wright } 3245bce47c7SJames Wright 3258a94a473SJed Brown CEED_QFUNCTION_HELPER void FluxTotal_RiemannBoundary(const StateConservative F_inviscid_normal, const CeedScalar stress[3][3], const CeedScalar Fe[3], 3268a94a473SJed Brown const CeedScalar normal[3], CeedScalar Flux[5]) { 3278a94a473SJed Brown Flux[0] = F_inviscid_normal.density; 3288a94a473SJed Brown for (CeedInt k = 0; k < 3; k++) Flux[k + 1] = F_inviscid_normal.momentum[k]; 3298a94a473SJed Brown Flux[4] = F_inviscid_normal.E_total; 3308a94a473SJed Brown for (CeedInt j = 0; j < 3; j++) { 3318a94a473SJed Brown for (CeedInt k = 0; k < 3; k++) { 3328a94a473SJed Brown Flux[k + 1] -= stress[k][j] * normal[j]; 3338a94a473SJed Brown } 3348a94a473SJed Brown Flux[4] += Fe[j] * normal[j]; 3358a94a473SJed Brown } 3368a94a473SJed Brown } 3378a94a473SJed Brown 338d08fcc28SJames Wright CEED_QFUNCTION_HELPER void VelocityGradient(const State grad_s[3], CeedScalar grad_velocity[3][3]) { 339d08fcc28SJames Wright grad_velocity[0][0] = grad_s[0].Y.velocity[0]; 340d08fcc28SJames Wright grad_velocity[0][1] = grad_s[1].Y.velocity[0]; 341d08fcc28SJames Wright grad_velocity[0][2] = grad_s[2].Y.velocity[0]; 342d08fcc28SJames Wright grad_velocity[1][0] = grad_s[0].Y.velocity[1]; 343d08fcc28SJames Wright grad_velocity[1][1] = grad_s[1].Y.velocity[1]; 344d08fcc28SJames Wright grad_velocity[1][2] = grad_s[2].Y.velocity[1]; 345d08fcc28SJames Wright grad_velocity[2][0] = grad_s[0].Y.velocity[2]; 346d08fcc28SJames Wright grad_velocity[2][1] = grad_s[1].Y.velocity[2]; 347d08fcc28SJames Wright grad_velocity[2][2] = grad_s[2].Y.velocity[2]; 348d08fcc28SJames Wright } 349d08fcc28SJames Wright 350d08fcc28SJames Wright CEED_QFUNCTION_HELPER void KMStrainRate(const CeedScalar grad_velocity[3][3], CeedScalar strain_rate[6]) { 351d08fcc28SJames Wright const CeedScalar weight = 1 / sqrt(2.); // Really sqrt(2.) / 2 352d08fcc28SJames Wright strain_rate[0] = grad_velocity[0][0]; 353d08fcc28SJames Wright strain_rate[1] = grad_velocity[1][1]; 354d08fcc28SJames Wright strain_rate[2] = grad_velocity[2][2]; 355d08fcc28SJames Wright strain_rate[3] = weight * (grad_velocity[1][2] + grad_velocity[2][1]); 356d08fcc28SJames Wright strain_rate[4] = weight * (grad_velocity[0][2] + grad_velocity[2][0]); 357d08fcc28SJames Wright strain_rate[5] = weight * (grad_velocity[0][1] + grad_velocity[1][0]); 358d08fcc28SJames Wright } 359d08fcc28SJames Wright 360c6e8c570SJames Wright // Kelvin-Mandel notation 361d08fcc28SJames Wright CEED_QFUNCTION_HELPER void KMStrainRate_State(const State grad_s[3], CeedScalar strain_rate[6]) { 362d08fcc28SJames Wright CeedScalar grad_velocity[3][3]; 363d08fcc28SJames Wright VelocityGradient(grad_s, grad_velocity); 364d08fcc28SJames Wright KMStrainRate(grad_velocity, strain_rate); 365d08fcc28SJames Wright } 366d08fcc28SJames Wright 367d08fcc28SJames Wright CEED_QFUNCTION_HELPER void RotationRate(const CeedScalar grad_velocity[3][3], CeedScalar rotation_rate[3][3]) { 368d08fcc28SJames Wright rotation_rate[0][0] = 0; 369d08fcc28SJames Wright rotation_rate[1][1] = 0; 370d08fcc28SJames Wright rotation_rate[2][2] = 0; 371d08fcc28SJames Wright rotation_rate[1][2] = 0.5 * (grad_velocity[1][2] - grad_velocity[2][1]); 372d08fcc28SJames Wright rotation_rate[0][2] = 0.5 * (grad_velocity[0][2] - grad_velocity[2][0]); 373d08fcc28SJames Wright rotation_rate[0][1] = 0.5 * (grad_velocity[0][1] - grad_velocity[1][0]); 374d08fcc28SJames Wright rotation_rate[2][1] = -rotation_rate[1][2]; 375d08fcc28SJames Wright rotation_rate[2][0] = -rotation_rate[0][2]; 376d08fcc28SJames Wright rotation_rate[1][0] = -rotation_rate[0][1]; 377c6e8c570SJames Wright } 378c6e8c570SJames Wright 3792b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER void NewtonianStress(NewtonianIdealGasContext gas, const CeedScalar strain_rate[6], CeedScalar stress[6]) { 380c6e8c570SJames Wright CeedScalar div_u = strain_rate[0] + strain_rate[1] + strain_rate[2]; 381c6e8c570SJames Wright for (CeedInt i = 0; i < 6; i++) { 382c6e8c570SJames Wright stress[i] = gas->mu * (2 * strain_rate[i] + gas->lambda * div_u * (i < 3)); 383c6e8c570SJames Wright } 384c6e8c570SJames Wright } 385c6e8c570SJames Wright 3862b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER void ViscousEnergyFlux(NewtonianIdealGasContext gas, StatePrimitive Y, const State grad_s[3], const CeedScalar stress[3][3], 387c6e8c570SJames Wright CeedScalar Fe[3]) { 388c6e8c570SJames Wright for (CeedInt i = 0; i < 3; i++) { 3892b730f8bSJeremy L Thompson Fe[i] = -Y.velocity[0] * stress[0][i] - Y.velocity[1] * stress[1][i] - Y.velocity[2] * stress[2][i] - gas->k * grad_s[i].Y.temperature; 390c6e8c570SJames Wright } 391c6e8c570SJames Wright } 392c6e8c570SJames Wright 3932b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER void ViscousEnergyFlux_fwd(NewtonianIdealGasContext gas, StatePrimitive Y, StatePrimitive dY, const State grad_ds[3], 3942b730f8bSJeremy L Thompson const CeedScalar stress[3][3], const CeedScalar dstress[3][3], CeedScalar dFe[3]) { 395c6e8c570SJames Wright for (CeedInt i = 0; i < 3; i++) { 3962b730f8bSJeremy L Thompson dFe[i] = -Y.velocity[0] * dstress[0][i] - dY.velocity[0] * stress[0][i] - Y.velocity[1] * dstress[1][i] - dY.velocity[1] * stress[1][i] - 3972b730f8bSJeremy L Thompson Y.velocity[2] * dstress[2][i] - dY.velocity[2] * stress[2][i] - gas->k * grad_ds[i].Y.temperature; 398c6e8c570SJames Wright } 399c6e8c570SJames Wright } 400c6e8c570SJames Wright 401d08fcc28SJames Wright CEED_QFUNCTION_HELPER void Vorticity(const State grad_s[3], CeedScalar vorticity[3]) { 402d08fcc28SJames Wright CeedScalar grad_velocity[3][3]; 403d08fcc28SJames Wright VelocityGradient(grad_s, grad_velocity); 404d08fcc28SJames Wright Curl3(grad_velocity, vorticity); 405d08fcc28SJames Wright } 406d08fcc28SJames Wright 407*9b6a821dSJames Wright CEED_QFUNCTION_HELPER void StatePhysicalGradientFromReference(CeedInt Q, CeedInt i, NewtonianIdealGasContext gas, State s, const CeedScalar x_i[3], 408*9b6a821dSJames Wright StateVariable state_var, const CeedScalar *grad_q, const CeedScalar dXdx[3][3], 409*9b6a821dSJames Wright bool zero_dx, State grad_s[3]) { 410*9b6a821dSJames Wright for (CeedInt k = 0; k < 3; k++) { 411*9b6a821dSJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 412*9b6a821dSJames Wright for (CeedInt j = 0; j < 5; j++) { 413*9b6a821dSJames Wright dqi[j] = 414*9b6a821dSJames Wright grad_q[(Q * 5) * 0 + Q * j + i] * dXdx[0][k] + grad_q[(Q * 5) * 1 + Q * j + i] * dXdx[1][k] + grad_q[(Q * 5) * 2 + Q * j + i] * dXdx[2][k]; 415*9b6a821dSJames Wright } 416*9b6a821dSJames Wright dx_i[k] = zero_dx ? 0. : 1.; 417*9b6a821dSJames Wright grad_s[k] = StateFromQ_fwd(gas, s, dqi, x_i, dx_i, state_var); 418*9b6a821dSJames Wright } 419*9b6a821dSJames Wright } 420*9b6a821dSJames Wright 421*9b6a821dSJames Wright CEED_QFUNCTION_HELPER void StatePhysicalGradientFromReference_Boundary(CeedInt Q, CeedInt i, NewtonianIdealGasContext gas, State s, 422*9b6a821dSJames Wright const CeedScalar x_i[3], StateVariable state_var, const CeedScalar *grad_q, 423*9b6a821dSJames Wright const CeedScalar dXdx[2][3], bool zero_dx, State grad_s[3]) { 424*9b6a821dSJames Wright for (CeedInt k = 0; k < 3; k++) { 425*9b6a821dSJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 426*9b6a821dSJames Wright for (CeedInt j = 0; j < 5; j++) { 427*9b6a821dSJames Wright dqi[j] = grad_q[(Q * 5) * 0 + Q * j + i] * dXdx[0][k] + grad_q[(Q * 5) * 1 + Q * j + i] * dXdx[1][k]; 428*9b6a821dSJames Wright } 429*9b6a821dSJames Wright dx_i[k] = zero_dx ? 0. : 1.; 430*9b6a821dSJames Wright grad_s[k] = StateFromQ_fwd(gas, s, dqi, x_i, dx_i, state_var); 431*9b6a821dSJames Wright } 432*9b6a821dSJames Wright } 433*9b6a821dSJames Wright 434c6e8c570SJames Wright #endif // newtonian_state_h 435