1*475b2820SJames Wright // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 2*475b2820SJames Wright // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3*475b2820SJames Wright // 4*475b2820SJames Wright // SPDX-License-Identifier: BSD-2-Clause 5*475b2820SJames Wright // 6*475b2820SJames Wright // This file is part of CEED: http://github.com/ceed 7*475b2820SJames Wright 8*475b2820SJames Wright /// @file 9*475b2820SJames Wright /// Structs and helper functions regarding the state of a newtonian simulation 10*475b2820SJames Wright 11*475b2820SJames Wright 12*475b2820SJames Wright #ifndef newtonian_state_h 13*475b2820SJames Wright #define newtonian_state_h 14*475b2820SJames Wright 15*475b2820SJames Wright #include <math.h> 16*475b2820SJames Wright #include <ceed.h> 17*475b2820SJames Wright #include "newtonian_types.h" 18*475b2820SJames Wright 19*475b2820SJames Wright typedef struct { 20*475b2820SJames Wright CeedScalar pressure; 21*475b2820SJames Wright CeedScalar velocity[3]; 22*475b2820SJames Wright CeedScalar temperature; 23*475b2820SJames Wright } StatePrimitive; 24*475b2820SJames Wright 25*475b2820SJames Wright typedef struct { 26*475b2820SJames Wright CeedScalar density; 27*475b2820SJames Wright CeedScalar momentum[3]; 28*475b2820SJames Wright CeedScalar E_total; 29*475b2820SJames Wright } StateConservative; 30*475b2820SJames Wright 31*475b2820SJames Wright typedef struct { 32*475b2820SJames Wright StateConservative U; 33*475b2820SJames Wright StatePrimitive Y; 34*475b2820SJames Wright } State; 35*475b2820SJames Wright 36*475b2820SJames Wright CEED_QFUNCTION_HELPER StatePrimitive StatePrimitiveFromConservative( 37*475b2820SJames Wright NewtonianIdealGasContext gas, StateConservative U, const CeedScalar x[3]) { 38*475b2820SJames Wright StatePrimitive Y; 39*475b2820SJames Wright for (CeedInt i=0; i<3; i++) Y.velocity[i] = U.momentum[i] / U.density; 40*475b2820SJames Wright CeedScalar e_kinetic = .5 * Dot3(Y.velocity, Y.velocity); 41*475b2820SJames Wright CeedScalar e_potential = -Dot3(gas->g, x); 42*475b2820SJames Wright CeedScalar e_total = U.E_total / U.density; 43*475b2820SJames Wright CeedScalar e_internal = e_total - e_kinetic - e_potential; 44*475b2820SJames Wright Y.temperature = e_internal / gas->cv; 45*475b2820SJames Wright Y.pressure = (gas->cp / gas->cv - 1) * U.density * e_internal; 46*475b2820SJames Wright return Y; 47*475b2820SJames Wright } 48*475b2820SJames Wright 49*475b2820SJames Wright CEED_QFUNCTION_HELPER StatePrimitive StatePrimitiveFromConservative_fwd( 50*475b2820SJames Wright NewtonianIdealGasContext gas, State s, StateConservative dU, 51*475b2820SJames Wright const CeedScalar x[3], const CeedScalar dx[3]) { 52*475b2820SJames Wright StatePrimitive dY; 53*475b2820SJames Wright for (CeedInt i=0; i<3; i++) { 54*475b2820SJames Wright dY.velocity[i] = (dU.momentum[i] - s.Y.velocity[i] * dU.density) / s.U.density; 55*475b2820SJames Wright } 56*475b2820SJames Wright CeedScalar e_kinetic = .5 * Dot3(s.Y.velocity, s.Y.velocity); 57*475b2820SJames Wright CeedScalar de_kinetic = Dot3(dY.velocity, s.Y.velocity); 58*475b2820SJames Wright CeedScalar e_potential = -Dot3(gas->g, x); 59*475b2820SJames Wright CeedScalar de_potential = -Dot3(gas->g, dx); 60*475b2820SJames Wright CeedScalar e_total = s.U.E_total / s.U.density; 61*475b2820SJames Wright CeedScalar de_total = (dU.E_total - e_total * dU.density) / s.U.density; 62*475b2820SJames Wright CeedScalar e_internal = e_total - e_kinetic - e_potential; 63*475b2820SJames Wright CeedScalar de_internal = de_total - de_kinetic - de_potential; 64*475b2820SJames Wright dY.temperature = de_internal / gas->cv; 65*475b2820SJames Wright dY.pressure = (gas->cp / gas->cv - 1) 66*475b2820SJames Wright * (dU.density * e_internal + s.U.density * de_internal); 67*475b2820SJames Wright return dY; 68*475b2820SJames Wright } 69*475b2820SJames Wright 70*475b2820SJames Wright CEED_QFUNCTION_HELPER State StateFromU(NewtonianIdealGasContext gas, 71*475b2820SJames Wright const CeedScalar U[5], const CeedScalar x[3]) { 72*475b2820SJames Wright State s; 73*475b2820SJames Wright s.U.density = U[0]; 74*475b2820SJames Wright s.U.momentum[0] = U[1]; 75*475b2820SJames Wright s.U.momentum[1] = U[2]; 76*475b2820SJames Wright s.U.momentum[2] = U[3]; 77*475b2820SJames Wright s.U.E_total = U[4]; 78*475b2820SJames Wright s.Y = StatePrimitiveFromConservative(gas, s.U, x); 79*475b2820SJames Wright return s; 80*475b2820SJames Wright } 81*475b2820SJames Wright 82*475b2820SJames Wright CEED_QFUNCTION_HELPER State StateFromU_fwd(NewtonianIdealGasContext gas, 83*475b2820SJames Wright State s, const CeedScalar dU[5], 84*475b2820SJames Wright const CeedScalar x[3], const CeedScalar dx[3]) { 85*475b2820SJames Wright State ds; 86*475b2820SJames Wright ds.U.density = dU[0]; 87*475b2820SJames Wright ds.U.momentum[0] = dU[1]; 88*475b2820SJames Wright ds.U.momentum[1] = dU[2]; 89*475b2820SJames Wright ds.U.momentum[2] = dU[3]; 90*475b2820SJames Wright ds.U.E_total = dU[4]; 91*475b2820SJames Wright ds.Y = StatePrimitiveFromConservative_fwd(gas, s, ds.U, x, dx); 92*475b2820SJames Wright return ds; 93*475b2820SJames Wright } 94*475b2820SJames Wright 95*475b2820SJames Wright CEED_QFUNCTION_HELPER void FluxInviscid(NewtonianIdealGasContext gas, State s, 96*475b2820SJames Wright StateConservative Flux[3]) { 97*475b2820SJames Wright for (CeedInt i=0; i<3; i++) { 98*475b2820SJames Wright Flux[i].density = s.U.momentum[i]; 99*475b2820SJames Wright for (CeedInt j=0; j<3; j++) 100*475b2820SJames Wright Flux[i].momentum[j] = s.U.momentum[i] * s.Y.velocity[j] 101*475b2820SJames Wright + s.Y.pressure * (i == j); 102*475b2820SJames Wright Flux[i].E_total = (s.U.E_total + s.Y.pressure) * s.Y.velocity[i]; 103*475b2820SJames Wright } 104*475b2820SJames Wright } 105*475b2820SJames Wright 106*475b2820SJames Wright CEED_QFUNCTION_HELPER void FluxInviscid_fwd(NewtonianIdealGasContext gas, 107*475b2820SJames Wright State s, State ds, StateConservative dFlux[3]) { 108*475b2820SJames Wright for (CeedInt i=0; i<3; i++) { 109*475b2820SJames Wright dFlux[i].density = ds.U.momentum[i]; 110*475b2820SJames Wright for (CeedInt j=0; j<3; j++) 111*475b2820SJames Wright dFlux[i].momentum[j] = ds.U.momentum[i] * s.Y.velocity[j] + 112*475b2820SJames Wright s.U.momentum[i] * ds.Y.velocity[j] + ds.Y.pressure * (i == j); 113*475b2820SJames Wright dFlux[i].E_total = (ds.U.E_total + ds.Y.pressure) * s.Y.velocity[i] + 114*475b2820SJames Wright (s.U.E_total + s.Y.pressure) * ds.Y.velocity[i]; 115*475b2820SJames Wright } 116*475b2820SJames Wright } 117*475b2820SJames Wright 118*475b2820SJames Wright // Kelvin-Mandel notation 119*475b2820SJames Wright CEED_QFUNCTION_HELPER void KMStrainRate(const State grad_s[3], 120*475b2820SJames Wright CeedScalar strain_rate[6]) { 121*475b2820SJames Wright const CeedScalar weight = 1 / sqrt(2.); 122*475b2820SJames Wright strain_rate[0] = grad_s[0].Y.velocity[0]; 123*475b2820SJames Wright strain_rate[1] = grad_s[1].Y.velocity[1]; 124*475b2820SJames Wright strain_rate[2] = grad_s[2].Y.velocity[2]; 125*475b2820SJames Wright strain_rate[3] = weight * (grad_s[2].Y.velocity[1] + grad_s[1].Y.velocity[2]); 126*475b2820SJames Wright strain_rate[4] = weight * (grad_s[2].Y.velocity[0] + grad_s[0].Y.velocity[2]); 127*475b2820SJames Wright strain_rate[5] = weight * (grad_s[1].Y.velocity[0] + grad_s[0].Y.velocity[1]); 128*475b2820SJames Wright } 129*475b2820SJames Wright 130*475b2820SJames Wright CEED_QFUNCTION_HELPER void KMUnpack(const CeedScalar v[6], CeedScalar A[3][3]) { 131*475b2820SJames Wright const CeedScalar weight = 1 / sqrt(2.); 132*475b2820SJames Wright A[0][0] = v[0]; 133*475b2820SJames Wright A[1][1] = v[1]; 134*475b2820SJames Wright A[2][2] = v[2]; 135*475b2820SJames Wright A[2][1] = A[1][2] = weight * v[3]; 136*475b2820SJames Wright A[2][0] = A[0][2] = weight * v[4]; 137*475b2820SJames Wright A[1][0] = A[0][1] = weight * v[5]; 138*475b2820SJames Wright } 139*475b2820SJames Wright 140*475b2820SJames Wright CEED_QFUNCTION_HELPER void NewtonianStress(NewtonianIdealGasContext gas, 141*475b2820SJames Wright const CeedScalar strain_rate[6], CeedScalar stress[6]) { 142*475b2820SJames Wright CeedScalar div_u = strain_rate[0] + strain_rate[1] + strain_rate[2]; 143*475b2820SJames Wright for (CeedInt i=0; i<6; i++) { 144*475b2820SJames Wright stress[i] = gas->mu * (2 * strain_rate[i] + gas->lambda * div_u * (i < 3)); 145*475b2820SJames Wright } 146*475b2820SJames Wright } 147*475b2820SJames Wright 148*475b2820SJames Wright CEED_QFUNCTION_HELPER void ViscousEnergyFlux(NewtonianIdealGasContext gas, 149*475b2820SJames Wright StatePrimitive Y, const State grad_s[3], const CeedScalar stress[3][3], 150*475b2820SJames Wright CeedScalar Fe[3]) { 151*475b2820SJames Wright for (CeedInt i=0; i<3; i++) { 152*475b2820SJames Wright Fe[i] = - Y.velocity[0] * stress[0][i] 153*475b2820SJames Wright - Y.velocity[1] * stress[1][i] 154*475b2820SJames Wright - Y.velocity[2] * stress[2][i] 155*475b2820SJames Wright - gas->k * grad_s[i].Y.temperature; 156*475b2820SJames Wright } 157*475b2820SJames Wright } 158*475b2820SJames Wright 159*475b2820SJames Wright CEED_QFUNCTION_HELPER void ViscousEnergyFlux_fwd(NewtonianIdealGasContext gas, 160*475b2820SJames Wright StatePrimitive Y, StatePrimitive dY, const State grad_ds[3], 161*475b2820SJames Wright const CeedScalar stress[3][3], 162*475b2820SJames Wright const CeedScalar dstress[3][3], 163*475b2820SJames Wright CeedScalar dFe[3]) { 164*475b2820SJames Wright for (CeedInt i=0; i<3; i++) { 165*475b2820SJames Wright dFe[i] = - Y.velocity[0] * dstress[0][i] - dY.velocity[0] * stress[0][i] 166*475b2820SJames Wright - Y.velocity[1] * dstress[1][i] - dY.velocity[1] * stress[1][i] 167*475b2820SJames Wright - Y.velocity[2] * dstress[2][i] - dY.velocity[2] * stress[2][i] 168*475b2820SJames Wright - gas->k * grad_ds[i].Y.temperature; 169*475b2820SJames Wright } 170*475b2820SJames Wright } 171*475b2820SJames Wright 172*475b2820SJames Wright #endif // newtonian_state_h 173