13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 388b783a1SJames Wright // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 588b783a1SJames Wright // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 788b783a1SJames Wright 888b783a1SJames Wright /// @file 988b783a1SJames Wright /// Operator for Navier-Stokes example using PETSc 1088b783a1SJames Wright 1188b783a1SJames Wright 1288b783a1SJames Wright #ifndef newtonian_h 1388b783a1SJames Wright #define newtonian_h 1488b783a1SJames Wright 1588b783a1SJames Wright #include <ceed.h> 16c9c2c079SJeremy L Thompson #include <math.h> 17c6e8c570SJames Wright #include "newtonian_state.h" 18c9c2c079SJeremy L Thompson #include "newtonian_types.h" 192b89d87eSLeila Ghaffari #include "stabilization.h" 20c9c2c079SJeremy L Thompson #include "utils.h" 2188626eedSJames Wright 2288626eedSJames Wright // ***************************************************************************** 2388b783a1SJames Wright // This QFunction sets a "still" initial condition for generic Newtonian IG problems 2488b783a1SJames Wright // ***************************************************************************** 2588b783a1SJames Wright CEED_QFUNCTION(ICsNewtonianIG)(void *ctx, CeedInt Q, 2688b783a1SJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 2788b783a1SJames Wright // Inputs 2888b783a1SJames Wright const CeedScalar (*X)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0]; 2988b783a1SJames Wright 3088b783a1SJames Wright // Outputs 3188b783a1SJames Wright CeedScalar (*q0)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 3288b783a1SJames Wright 3388626eedSJames Wright // Context 3488626eedSJames Wright const SetupContext context = (SetupContext)ctx; 3588626eedSJames Wright const CeedScalar theta0 = context->theta0; 3688626eedSJames Wright const CeedScalar P0 = context->P0; 3788626eedSJames Wright const CeedScalar cv = context->cv; 3888626eedSJames Wright const CeedScalar cp = context->cp; 3988626eedSJames Wright const CeedScalar *g = context->g; 4088626eedSJames Wright const CeedScalar Rd = cp - cv; 4188626eedSJames Wright 4288b783a1SJames Wright // Quadrature Point Loop 4388b783a1SJames Wright CeedPragmaSIMD 4488b783a1SJames Wright for (CeedInt i=0; i<Q; i++) { 4588b783a1SJames Wright CeedScalar q[5] = {0.}; 4688b783a1SJames Wright 4788b783a1SJames Wright // Setup 4888b783a1SJames Wright // -- Coordinates 4988626eedSJames Wright const CeedScalar x[3] = {X[0][i], X[1][i], X[2][i]}; 502b89d87eSLeila Ghaffari const CeedScalar e_potential = -Dot3(g, x); 5188b783a1SJames Wright 5288b783a1SJames Wright // -- Density 5388626eedSJames Wright const CeedScalar rho = P0 / (Rd*theta0); 5488b783a1SJames Wright 5588b783a1SJames Wright // Initial Conditions 5688b783a1SJames Wright q[0] = rho; 5788b783a1SJames Wright q[1] = 0.0; 5888b783a1SJames Wright q[2] = 0.0; 5988b783a1SJames Wright q[3] = 0.0; 6088626eedSJames Wright q[4] = rho * (cv*theta0 + e_potential); 6188b783a1SJames Wright 6288b783a1SJames Wright for (CeedInt j=0; j<5; j++) 6388b783a1SJames Wright q0[j][i] = q[j]; 642b89d87eSLeila Ghaffari 6588b783a1SJames Wright } // End of Quadrature Point Loop 6688b783a1SJames Wright return 0; 6788b783a1SJames Wright } 6888b783a1SJames Wright 6988b783a1SJames Wright // ***************************************************************************** 70dc805cc4SLeila Ghaffari // This QFunction sets a "still" initial condition for generic Newtonian IG 71dc805cc4SLeila Ghaffari // problems in primitive variables 72dc805cc4SLeila Ghaffari // ***************************************************************************** 73dc805cc4SLeila Ghaffari CEED_QFUNCTION(ICsNewtonianIG_Prim)(void *ctx, CeedInt Q, 74dc805cc4SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 75dc805cc4SLeila Ghaffari // Outputs 76dc805cc4SLeila Ghaffari CeedScalar (*q0)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 77dc805cc4SLeila Ghaffari 78dc805cc4SLeila Ghaffari // Context 79dc805cc4SLeila Ghaffari const SetupContext context = (SetupContext)ctx; 80dc805cc4SLeila Ghaffari const CeedScalar theta0 = context->theta0; 81dc805cc4SLeila Ghaffari const CeedScalar P0 = context->P0; 82dc805cc4SLeila Ghaffari 83dc805cc4SLeila Ghaffari // Quadrature Point Loop 84dc805cc4SLeila Ghaffari CeedPragmaSIMD 85dc805cc4SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 86dc805cc4SLeila Ghaffari CeedScalar q[5] = {0.}; 87dc805cc4SLeila Ghaffari 88dc805cc4SLeila Ghaffari // Initial Conditions 89dc805cc4SLeila Ghaffari q[0] = P0; 90dc805cc4SLeila Ghaffari q[1] = 0.0; 91dc805cc4SLeila Ghaffari q[2] = 0.0; 92dc805cc4SLeila Ghaffari q[3] = 0.0; 93dc805cc4SLeila Ghaffari q[4] = theta0; 94dc805cc4SLeila Ghaffari 95dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) 96dc805cc4SLeila Ghaffari q0[j][i] = q[j]; 97dc805cc4SLeila Ghaffari 98dc805cc4SLeila Ghaffari } // End of Quadrature Point Loop 99dc805cc4SLeila Ghaffari return 0; 100dc805cc4SLeila Ghaffari } 101dc805cc4SLeila Ghaffari 102dc805cc4SLeila Ghaffari // ***************************************************************************** 10388b783a1SJames Wright // This QFunction implements the following formulation of Navier-Stokes with 10488b783a1SJames Wright // explicit time stepping method 10588b783a1SJames Wright // 10688b783a1SJames Wright // This is 3D compressible Navier-Stokes in conservation form with state 10788b783a1SJames Wright // variables of density, momentum density, and total energy density. 10888b783a1SJames Wright // 10988b783a1SJames Wright // State Variables: q = ( rho, U1, U2, U3, E ) 11088b783a1SJames Wright // rho - Mass Density 11188b783a1SJames Wright // Ui - Momentum Density, Ui = rho ui 11288b783a1SJames Wright // E - Total Energy Density, E = rho (cv T + (u u)/2 + g z) 11388b783a1SJames Wright // 11488b783a1SJames Wright // Navier-Stokes Equations: 11588b783a1SJames Wright // drho/dt + div( U ) = 0 11688b783a1SJames Wright // dU/dt + div( rho (u x u) + P I3 ) + rho g khat = div( Fu ) 11788b783a1SJames Wright // dE/dt + div( (E + P) u ) = div( Fe ) 11888b783a1SJames Wright // 11988b783a1SJames Wright // Viscous Stress: 12088b783a1SJames Wright // Fu = mu (grad( u ) + grad( u )^T + lambda div ( u ) I3) 12188b783a1SJames Wright // 12288b783a1SJames Wright // Thermal Stress: 12388b783a1SJames Wright // Fe = u Fu + k grad( T ) 12488626eedSJames Wright // Equation of State 12588b783a1SJames Wright // P = (gamma - 1) (E - rho (u u) / 2 - rho g z) 12688b783a1SJames Wright // 12788b783a1SJames Wright // Stabilization: 12888b783a1SJames Wright // Tau = diag(TauC, TauM, TauM, TauM, TauE) 12988b783a1SJames Wright // f1 = rho sqrt(ui uj gij) 13088b783a1SJames Wright // gij = dXi/dX * dXi/dX 13188b783a1SJames Wright // TauC = Cc f1 / (8 gii) 13288b783a1SJames Wright // TauM = min( 1 , 1 / f1 ) 13388b783a1SJames Wright // TauE = TauM / (Ce cv) 13488b783a1SJames Wright // 13588b783a1SJames Wright // SU = Galerkin + grad(v) . ( Ai^T * Tau * (Aj q,j) ) 13688b783a1SJames Wright // 13788b783a1SJames Wright // Constants: 13888b783a1SJames Wright // lambda = - 2 / 3, From Stokes hypothesis 13988b783a1SJames Wright // mu , Dynamic viscosity 14088b783a1SJames Wright // k , Thermal conductivity 14188b783a1SJames Wright // cv , Specific heat, constant volume 14288b783a1SJames Wright // cp , Specific heat, constant pressure 14388b783a1SJames Wright // g , Gravity 14488b783a1SJames Wright // gamma = cp / cv, Specific heat ratio 14588b783a1SJames Wright // 14688b783a1SJames Wright // We require the product of the inverse of the Jacobian (dXdx_j,k) and 14788b783a1SJames Wright // its transpose (dXdx_k,j) to properly compute integrals of the form: 14888b783a1SJames Wright // int( gradv gradu ) 14988b783a1SJames Wright // 15088b783a1SJames Wright // ***************************************************************************** 1515c677226SJed Brown CEED_QFUNCTION(RHSFunction_Newtonian)(void *ctx, CeedInt Q, 15288b783a1SJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 15388b783a1SJames Wright // *INDENT-OFF* 15488b783a1SJames Wright // Inputs 15588b783a1SJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 156a3ae0734SJed Brown (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 15788b783a1SJames Wright (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 15888b783a1SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 15988b783a1SJames Wright // Outputs 16088b783a1SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 161a3ae0734SJed Brown (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1]; 16288b783a1SJames Wright // *INDENT-ON* 16388b783a1SJames Wright 16488b783a1SJames Wright // Context 16588b783a1SJames Wright NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 16688626eedSJames Wright const CeedScalar *g = context->g; 16788626eedSJames Wright const CeedScalar dt = context->dt; 16888b783a1SJames Wright 16988b783a1SJames Wright CeedPragmaSIMD 17088b783a1SJames Wright // Quadrature Point Loop 17188b783a1SJames Wright for (CeedInt i=0; i<Q; i++) { 1725c677226SJed Brown CeedScalar U[5]; 1735c677226SJed Brown for (int j=0; j<5; j++) U[j] = q[j][i]; 1745c677226SJed Brown const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 1755c677226SJed Brown State s = StateFromU(context, U, x_i); 1765c677226SJed Brown 17788b783a1SJames Wright // -- Interp-to-Interp q_data 17888b783a1SJames Wright const CeedScalar wdetJ = q_data[0][i]; 17988b783a1SJames Wright // -- Interp-to-Grad q_data 18088b783a1SJames Wright // ---- Inverse of change of coordinate matrix: X_i,j 18188b783a1SJames Wright // *INDENT-OFF* 182*23d6ba15SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 183*23d6ba15SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 184*23d6ba15SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 18588b783a1SJames Wright }; 18688b783a1SJames Wright // *INDENT-ON* 1875c677226SJed Brown State grad_s[3]; 1883c4b7af6SJed Brown for (CeedInt j=0; j<3; j++) { 1896f00d0e6SJed Brown CeedScalar dx_i[3] = {0}, dU[5]; 19039c69132SJed Brown for (CeedInt k=0; k<5; k++) 19139c69132SJed Brown dU[k] = Grad_q[0][k][i] * dXdx[0][j] + 19239c69132SJed Brown Grad_q[1][k][i] * dXdx[1][j] + 19339c69132SJed Brown Grad_q[2][k][i] * dXdx[2][j]; 1945c677226SJed Brown dx_i[j] = 1.; 1956f00d0e6SJed Brown grad_s[j] = StateFromU_fwd(context, s, dU, x_i, dx_i); 1965c677226SJed Brown } 1975c677226SJed Brown 1985c677226SJed Brown CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 1995c677226SJed Brown KMStrainRate(grad_s, strain_rate); 2005c677226SJed Brown NewtonianStress(context, strain_rate, kmstress); 2015c677226SJed Brown KMUnpack(kmstress, stress); 2025c677226SJed Brown ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 2035c677226SJed Brown 2045c677226SJed Brown StateConservative F_inviscid[3]; 2055c677226SJed Brown FluxInviscid(context, s, F_inviscid); 2065c677226SJed Brown 2075c677226SJed Brown // Total flux 2085c677226SJed Brown CeedScalar Flux[5][3]; 2092b89d87eSLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 2105c677226SJed Brown 2112b89d87eSLeila Ghaffari for (CeedInt j=0; j<3; j++) 2122b89d87eSLeila Ghaffari for (CeedInt k=0; k<5; k++) 213a3ae0734SJed Brown Grad_v[j][k][i] = wdetJ * (dXdx[j][0] * Flux[k][0] + 2145c677226SJed Brown dXdx[j][1] * Flux[k][1] + 2155c677226SJed Brown dXdx[j][2] * Flux[k][2]); 2165c677226SJed Brown 2175c677226SJed Brown const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 2185c677226SJed Brown for (int j=0; j<5; j++) 2195c677226SJed Brown v[j][i] = wdetJ * body_force[j]; 22088b783a1SJames Wright 2212b89d87eSLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 2222b89d87eSLeila Ghaffari CeedScalar Tau_d[3], stab[5][3], U_dot[5] = {0}; 2232b89d87eSLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 2242b89d87eSLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 22588b783a1SJames Wright 226ba6664aeSJames Wright for (CeedInt j=0; j<5; j++) 227ba6664aeSJames Wright for (CeedInt k=0; k<3; k++) 228a3ae0734SJed Brown Grad_v[k][j][i] -= wdetJ*(stab[j][0] * dXdx[k][0] + 22988b783a1SJames Wright stab[j][1] * dXdx[k][1] + 23088b783a1SJames Wright stab[j][2] * dXdx[k][2]); 23188b783a1SJames Wright 23288b783a1SJames Wright } // End Quadrature Point Loop 23388b783a1SJames Wright 23488b783a1SJames Wright // Return 23588b783a1SJames Wright return 0; 23688b783a1SJames Wright } 23788b783a1SJames Wright 23888b783a1SJames Wright // ***************************************************************************** 23988b783a1SJames Wright // This QFunction implements the Navier-Stokes equations (mentioned above) with 24088b783a1SJames Wright // implicit time stepping method 24188b783a1SJames Wright // 24288b783a1SJames Wright // SU = Galerkin + grad(v) . ( Ai^T * Tau * (Aj q,j) ) 24388b783a1SJames Wright // SUPG = Galerkin + grad(v) . ( Ai^T * Tau * (q_dot + Aj q,j - body force) ) 24488b783a1SJames Wright // (diffussive terms will be added later) 24588b783a1SJames Wright // 24688b783a1SJames Wright // ***************************************************************************** 24788b783a1SJames Wright CEED_QFUNCTION(IFunction_Newtonian)(void *ctx, CeedInt Q, 248dc805cc4SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 24988b783a1SJames Wright // *INDENT-OFF* 25088b783a1SJames Wright // Inputs 25188b783a1SJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 252a3ae0734SJed Brown (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 25388b783a1SJames Wright (*q_dot)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 25488b783a1SJames Wright (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 25588b783a1SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 25688b783a1SJames Wright // Outputs 25788b783a1SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 258a3ae0734SJed Brown (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1], 259a3ae0734SJed Brown (*jac_data)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[2]; 26088b783a1SJames Wright // *INDENT-ON* 26188b783a1SJames Wright // Context 26288b783a1SJames Wright NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 26388626eedSJames Wright const CeedScalar *g = context->g; 26488626eedSJames Wright const CeedScalar dt = context->dt; 26588b783a1SJames Wright 26688b783a1SJames Wright CeedPragmaSIMD 26788b783a1SJames Wright // Quadrature Point Loop 26888b783a1SJames Wright for (CeedInt i=0; i<Q; i++) { 2695c677226SJed Brown CeedScalar U[5]; 2703c4b7af6SJed Brown for (CeedInt j=0; j<5; j++) U[j] = q[j][i]; 2715c677226SJed Brown const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 2725c677226SJed Brown State s = StateFromU(context, U, x_i); 2735c677226SJed Brown 27488b783a1SJames Wright // -- Interp-to-Interp q_data 27588b783a1SJames Wright const CeedScalar wdetJ = q_data[0][i]; 27688b783a1SJames Wright // -- Interp-to-Grad q_data 27788b783a1SJames Wright // ---- Inverse of change of coordinate matrix: X_i,j 27888b783a1SJames Wright // *INDENT-OFF* 279*23d6ba15SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 280*23d6ba15SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 281*23d6ba15SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 28288b783a1SJames Wright }; 28388b783a1SJames Wright // *INDENT-ON* 2845c677226SJed Brown State grad_s[3]; 285ba6664aeSJames Wright for (CeedInt j=0; j<3; j++) { 2866f00d0e6SJed Brown CeedScalar dx_i[3] = {0}, dU[5]; 28739c69132SJed Brown for (CeedInt k=0; k<5; k++) 28839c69132SJed Brown dU[k] = Grad_q[0][k][i] * dXdx[0][j] + 28939c69132SJed Brown Grad_q[1][k][i] * dXdx[1][j] + 29039c69132SJed Brown Grad_q[2][k][i] * dXdx[2][j]; 2915c677226SJed Brown dx_i[j] = 1.; 2926f00d0e6SJed Brown grad_s[j] = StateFromU_fwd(context, s, dU, x_i, dx_i); 29388b783a1SJames Wright } 2945c677226SJed Brown 2955c677226SJed Brown CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 2965c677226SJed Brown KMStrainRate(grad_s, strain_rate); 2975c677226SJed Brown NewtonianStress(context, strain_rate, kmstress); 2985c677226SJed Brown KMUnpack(kmstress, stress); 2995c677226SJed Brown ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 3005c677226SJed Brown 3015c677226SJed Brown StateConservative F_inviscid[3]; 3025c677226SJed Brown FluxInviscid(context, s, F_inviscid); 3035c677226SJed Brown 3045c677226SJed Brown // Total flux 3055c677226SJed Brown CeedScalar Flux[5][3]; 3062b89d87eSLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 3075c677226SJed Brown 3082b89d87eSLeila Ghaffari for (CeedInt j=0; j<3; j++) 3092b89d87eSLeila Ghaffari for (CeedInt k=0; k<5; k++) 310a3ae0734SJed Brown Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * Flux[k][0] + 3115c677226SJed Brown dXdx[j][1] * Flux[k][1] + 3125c677226SJed Brown dXdx[j][2] * Flux[k][2]); 3135c677226SJed Brown 3145c677226SJed Brown const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 3153c4b7af6SJed Brown for (CeedInt j=0; j<5; j++) 3165c677226SJed Brown v[j][i] = wdetJ * (q_dot[j][i] - body_force[j]); 31788b783a1SJames Wright 3182b89d87eSLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 3192b89d87eSLeila Ghaffari CeedScalar Tau_d[3], stab[5][3], U_dot[5] = {0}; 3202b89d87eSLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = q_dot[j][i]; 3212b89d87eSLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 3222b89d87eSLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 32388b783a1SJames Wright 324ba6664aeSJames Wright for (CeedInt j=0; j<5; j++) 325ba6664aeSJames Wright for (CeedInt k=0; k<3; k++) 326a3ae0734SJed Brown Grad_v[k][j][i] += wdetJ*(stab[j][0] * dXdx[k][0] + 32788b783a1SJames Wright stab[j][1] * dXdx[k][1] + 32888b783a1SJames Wright stab[j][2] * dXdx[k][2]); 3293c4b7af6SJed Brown 3303c4b7af6SJed Brown for (CeedInt j=0; j<5; j++) jac_data[j][i] = U[j]; 3313c4b7af6SJed Brown for (CeedInt j=0; j<6; j++) jac_data[5+j][i] = kmstress[j]; 3323c4b7af6SJed Brown for (CeedInt j=0; j<3; j++) jac_data[5+6+j][i] = Tau_d[j]; 33388b783a1SJames Wright 33488b783a1SJames Wright } // End Quadrature Point Loop 33588b783a1SJames Wright 33688b783a1SJames Wright // Return 33788b783a1SJames Wright return 0; 33888b783a1SJames Wright } 339e334ad8fSJed Brown 340dc805cc4SLeila Ghaffari // ***************************************************************************** 341dc805cc4SLeila Ghaffari // This QFunction implements the jacobean of the Navier-Stokes equations 342dc805cc4SLeila Ghaffari // for implicit time stepping method. 343dc805cc4SLeila Ghaffari // 344dc805cc4SLeila Ghaffari // ***************************************************************************** 345e334ad8fSJed Brown CEED_QFUNCTION(IJacobian_Newtonian)(void *ctx, CeedInt Q, 346e334ad8fSJed Brown const CeedScalar *const *in, 347e334ad8fSJed Brown CeedScalar *const *out) { 348e334ad8fSJed Brown // *INDENT-OFF* 349e334ad8fSJed Brown // Inputs 350e334ad8fSJed Brown const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 351e334ad8fSJed Brown (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 352e334ad8fSJed Brown (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 353e334ad8fSJed Brown (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 354e334ad8fSJed Brown (*jac_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 355e334ad8fSJed Brown // Outputs 356e334ad8fSJed Brown CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 357e334ad8fSJed Brown (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1]; 358e334ad8fSJed Brown // *INDENT-ON* 359e334ad8fSJed Brown // Context 360e334ad8fSJed Brown NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 361e334ad8fSJed Brown const CeedScalar *g = context->g; 362e334ad8fSJed Brown 363e334ad8fSJed Brown CeedPragmaSIMD 364e334ad8fSJed Brown // Quadrature Point Loop 365e334ad8fSJed Brown for (CeedInt i=0; i<Q; i++) { 366e334ad8fSJed Brown // -- Interp-to-Interp q_data 367e334ad8fSJed Brown const CeedScalar wdetJ = q_data[0][i]; 368e334ad8fSJed Brown // -- Interp-to-Grad q_data 369e334ad8fSJed Brown // ---- Inverse of change of coordinate matrix: X_i,j 370e334ad8fSJed Brown // *INDENT-OFF* 371*23d6ba15SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 372*23d6ba15SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 373*23d6ba15SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 374e334ad8fSJed Brown }; 375e334ad8fSJed Brown // *INDENT-ON* 376e334ad8fSJed Brown 377e334ad8fSJed Brown CeedScalar U[5], kmstress[6], Tau_d[3] __attribute((unused)); 378e334ad8fSJed Brown for (int j=0; j<5; j++) U[j] = jac_data[j][i]; 379e334ad8fSJed Brown for (int j=0; j<6; j++) kmstress[j] = jac_data[5+j][i]; 380e334ad8fSJed Brown for (int j=0; j<3; j++) Tau_d[j] = jac_data[5+6+j][i]; 381e334ad8fSJed Brown const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 382e334ad8fSJed Brown State s = StateFromU(context, U, x_i); 383e334ad8fSJed Brown 384e334ad8fSJed Brown CeedScalar dU[5], dx0[3] = {0}; 385e334ad8fSJed Brown for (int j=0; j<5; j++) dU[j] = dq[j][i]; 386e334ad8fSJed Brown State ds = StateFromU_fwd(context, s, dU, x_i, dx0); 387e334ad8fSJed Brown 388e334ad8fSJed Brown State grad_ds[3]; 389e334ad8fSJed Brown for (int j=0; j<3; j++) { 390e334ad8fSJed Brown CeedScalar dUj[5]; 3912b89d87eSLeila Ghaffari for (int k=0; k<5; k++) 3922b89d87eSLeila Ghaffari dUj[k] = Grad_dq[0][k][i] * dXdx[0][j] + 3932b89d87eSLeila Ghaffari Grad_dq[1][k][i] * dXdx[1][j] + 3942b89d87eSLeila Ghaffari Grad_dq[2][k][i] * dXdx[2][j]; 395e334ad8fSJed Brown grad_ds[j] = StateFromU_fwd(context, s, dUj, x_i, dx0); 396e334ad8fSJed Brown } 397e334ad8fSJed Brown 398e334ad8fSJed Brown CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 399e334ad8fSJed Brown KMStrainRate(grad_ds, dstrain_rate); 400e334ad8fSJed Brown NewtonianStress(context, dstrain_rate, dkmstress); 401e334ad8fSJed Brown KMUnpack(dkmstress, dstress); 402e334ad8fSJed Brown KMUnpack(kmstress, stress); 403e334ad8fSJed Brown ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 404e334ad8fSJed Brown 405e334ad8fSJed Brown StateConservative dF_inviscid[3]; 406e334ad8fSJed Brown FluxInviscid_fwd(context, s, ds, dF_inviscid); 407e334ad8fSJed Brown 408e334ad8fSJed Brown // Total flux 409e334ad8fSJed Brown CeedScalar dFlux[5][3]; 4102b89d87eSLeila Ghaffari FluxTotal(dF_inviscid, dstress, dFe, dFlux); 411e334ad8fSJed Brown 4122b89d87eSLeila Ghaffari for (int j=0; j<3; j++) 4132b89d87eSLeila Ghaffari for (int k=0; k<5; k++) 414e334ad8fSJed Brown Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * dFlux[k][0] + 415e334ad8fSJed Brown dXdx[j][1] * dFlux[k][1] + 416e334ad8fSJed Brown dXdx[j][2] * dFlux[k][2]); 417e334ad8fSJed Brown 418e334ad8fSJed Brown const CeedScalar dbody_force[5] = {0, ds.U.density *g[0], ds.U.density *g[1], ds.U.density *g[2], 0}; 419e334ad8fSJed Brown for (int j=0; j<5; j++) 420e334ad8fSJed Brown v[j][i] = wdetJ * (context->ijacobian_time_shift * dU[j] - dbody_force[j]); 421e334ad8fSJed Brown 4222b89d87eSLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 4232b89d87eSLeila Ghaffari CeedScalar dstab[5][3], U_dot[5] = {0}; 4242b89d87eSLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = context->ijacobian_time_shift * dU[j]; 4252b89d87eSLeila Ghaffari Stabilization(context, s, Tau_d, grad_ds, U_dot, dbody_force, x_i, dstab); 4262b89d87eSLeila Ghaffari 427e334ad8fSJed Brown for (int j=0; j<5; j++) 428e334ad8fSJed Brown for (int k=0; k<3; k++) 429e334ad8fSJed Brown Grad_v[k][j][i] += wdetJ*(dstab[j][0] * dXdx[k][0] + 430e334ad8fSJed Brown dstab[j][1] * dXdx[k][1] + 431e334ad8fSJed Brown dstab[j][2] * dXdx[k][2]); 432e334ad8fSJed Brown 433e334ad8fSJed Brown } // End Quadrature Point Loop 434e334ad8fSJed Brown return 0; 435e334ad8fSJed Brown } 43665dd5cafSJames Wright 4372b89d87eSLeila Ghaffari // ***************************************************************************** 43865dd5cafSJames Wright // Compute boundary integral (ie. for strongly set inflows) 4392b89d87eSLeila Ghaffari // ***************************************************************************** 44065dd5cafSJames Wright CEED_QFUNCTION(BoundaryIntegral)(void *ctx, CeedInt Q, 44165dd5cafSJames Wright const CeedScalar *const *in, 44265dd5cafSJames Wright CeedScalar *const *out) { 44365dd5cafSJames Wright 44465dd5cafSJames Wright //*INDENT-OFF* 44565dd5cafSJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 4462c4e60d7SJames Wright (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 4472c4e60d7SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 4482c4e60d7SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 44965dd5cafSJames Wright 450b55ac660SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA]) out[0], 451b55ac660SJames Wright (*jac_data_sur)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA]) out[1]; 45265dd5cafSJames Wright 45365dd5cafSJames Wright //*INDENT-ON* 45465dd5cafSJames Wright 4552c4e60d7SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext) ctx; 4562c4e60d7SJames Wright const bool is_implicit = context->is_implicit; 457efe9d856SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 458efe9d856SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 459efe9d856SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 460efe9d856SJames Wright State s, const CeedScalar dqi[5], 461efe9d856SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 462*23d6ba15SJames Wright StateFromQi = context->use_primitive ? &StateFromY : &StateFromU; 463*23d6ba15SJames Wright StateFromQi_fwd = context->use_primitive ? &StateFromY_fwd : &StateFromU_fwd; 464efe9d856SJames Wright 46565dd5cafSJames Wright 46665dd5cafSJames Wright CeedPragmaSIMD 46765dd5cafSJames Wright for(CeedInt i=0; i<Q; i++) { 4682c4e60d7SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 469efe9d856SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 470efe9d856SJames Wright State s = StateFromQi(context, qi, x_i); 47165dd5cafSJames Wright 47265dd5cafSJames Wright const CeedScalar wdetJb = (is_implicit ? -1. : 1.) * q_data_sur[0][i]; 47365dd5cafSJames Wright // ---- Normal vect 47465dd5cafSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 47565dd5cafSJames Wright q_data_sur[2][i], 47665dd5cafSJames Wright q_data_sur[3][i] 47765dd5cafSJames Wright }; 47865dd5cafSJames Wright 4792c4e60d7SJames Wright const CeedScalar dXdx[2][3] = { 4802c4e60d7SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 4812c4e60d7SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 4822c4e60d7SJames Wright }; 48365dd5cafSJames Wright 4842c4e60d7SJames Wright State grad_s[3]; 4852c4e60d7SJames Wright for (CeedInt j=0; j<3; j++) { 486efe9d856SJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 4872c4e60d7SJames Wright for (CeedInt k=0; k<5; k++) 488efe9d856SJames Wright dqi[k] = Grad_q[0][k][i] * dXdx[0][j] + 4892c4e60d7SJames Wright Grad_q[1][k][i] * dXdx[1][j]; 4902c4e60d7SJames Wright dx_i[j] = 1.; 491efe9d856SJames Wright grad_s[j] = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 4922c4e60d7SJames Wright } 49365dd5cafSJames Wright 4942c4e60d7SJames Wright CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 4952c4e60d7SJames Wright KMStrainRate(grad_s, strain_rate); 4962c4e60d7SJames Wright NewtonianStress(context, strain_rate, kmstress); 4972c4e60d7SJames Wright KMUnpack(kmstress, stress); 4982c4e60d7SJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 4992c4e60d7SJames Wright 5002c4e60d7SJames Wright StateConservative F_inviscid[3]; 5012c4e60d7SJames Wright FluxInviscid(context, s, F_inviscid); 5022c4e60d7SJames Wright 5032c4e60d7SJames Wright CeedScalar Flux[5] = {0.}; 5042c4e60d7SJames Wright for (int j=0; j<3; j++) { 5052c4e60d7SJames Wright Flux[0] += F_inviscid[j].density * norm[j]; 5062c4e60d7SJames Wright for (int k=0; k<3; k++) 5072c4e60d7SJames Wright Flux[k+1] += (F_inviscid[j].momentum[k] - stress[k][j]) * norm[j]; 5082c4e60d7SJames Wright Flux[4] += (F_inviscid[j].E_total + Fe[j]) * norm[j]; 5092c4e60d7SJames Wright } 5102c4e60d7SJames Wright 51165dd5cafSJames Wright // -- Density 5122c4e60d7SJames Wright v[0][i] = -wdetJb * Flux[0]; 51365dd5cafSJames Wright 51465dd5cafSJames Wright // -- Momentum 51565dd5cafSJames Wright for (CeedInt j=0; j<3; j++) 5162c4e60d7SJames Wright v[j+1][i] = -wdetJb * Flux[j+1]; 51765dd5cafSJames Wright 51865dd5cafSJames Wright // -- Total Energy Density 5192c4e60d7SJames Wright v[4][i] = -wdetJb * Flux[4]; 520b55ac660SJames Wright 521*23d6ba15SJames Wright if (context->use_primitive) { 52257e55a1cSJames Wright jac_data_sur[0][i] = s.Y.pressure; 52357e55a1cSJames Wright for (int j=0; j<3; j++) jac_data_sur[j+1][i] = s.Y.velocity[j]; 52457e55a1cSJames Wright jac_data_sur[4][i] = s.Y.temperature; 52557e55a1cSJames Wright } else { 526b55ac660SJames Wright jac_data_sur[0][i] = s.U.density; 52757e55a1cSJames Wright for (int j=0; j<3; j++) jac_data_sur[j+1][i] = s.U.momentum[j]; 528b55ac660SJames Wright jac_data_sur[4][i] = s.U.E_total; 52957e55a1cSJames Wright } 530b55ac660SJames Wright for (int j=0; j<6; j++) jac_data_sur[5+j][i] = kmstress[j]; 53165dd5cafSJames Wright } 53265dd5cafSJames Wright return 0; 53365dd5cafSJames Wright } 53465dd5cafSJames Wright 5352b89d87eSLeila Ghaffari // ***************************************************************************** 536b55ac660SJames Wright // Jacobian for "set nothing" boundary integral 5372b89d87eSLeila Ghaffari // ***************************************************************************** 538b55ac660SJames Wright CEED_QFUNCTION(BoundaryIntegral_Jacobian)(void *ctx, CeedInt Q, 539b55ac660SJames Wright const CeedScalar *const *in, 540b55ac660SJames Wright CeedScalar *const *out) { 541b55ac660SJames Wright // *INDENT-OFF* 542b55ac660SJames Wright // Inputs 543b55ac660SJames Wright const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 544b55ac660SJames Wright (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 545b55ac660SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 546b55ac660SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 547b55ac660SJames Wright (*jac_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 548b55ac660SJames Wright // Outputs 549b55ac660SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 550b55ac660SJames Wright // *INDENT-ON* 551b55ac660SJames Wright 552b55ac660SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 553b55ac660SJames Wright const bool implicit = context->is_implicit; 554efe9d856SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 555efe9d856SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 556efe9d856SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 557efe9d856SJames Wright State s, const CeedScalar dqi[5], 558efe9d856SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 559*23d6ba15SJames Wright StateFromQi = context->use_primitive ? &StateFromY : &StateFromU; 560*23d6ba15SJames Wright StateFromQi_fwd = context->use_primitive ? &StateFromY_fwd : &StateFromU_fwd; 561b55ac660SJames Wright 562b55ac660SJames Wright CeedPragmaSIMD 563b55ac660SJames Wright // Quadrature Point Loop 564b55ac660SJames Wright for (CeedInt i=0; i<Q; i++) { 565b55ac660SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 566b55ac660SJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 567b55ac660SJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 568b55ac660SJames Wright q_data_sur[2][i], 569b55ac660SJames Wright q_data_sur[3][i] 570b55ac660SJames Wright }; 571b55ac660SJames Wright const CeedScalar dXdx[2][3] = { 572b55ac660SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 573b55ac660SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 574b55ac660SJames Wright }; 575b55ac660SJames Wright 576efe9d856SJames Wright CeedScalar qi[5], kmstress[6], dqi[5], dx_i[3] = {0.}; 577efe9d856SJames Wright for (int j=0; j<5; j++) qi[j] = jac_data_sur[j][i]; 578b55ac660SJames Wright for (int j=0; j<6; j++) kmstress[j] = jac_data_sur[5+j][i]; 579efe9d856SJames Wright for (int j=0; j<5; j++) dqi[j] = dq[j][i]; 58057e55a1cSJames Wright 581efe9d856SJames Wright State s = StateFromQi(context, qi, x_i); 582efe9d856SJames Wright State ds = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 583b55ac660SJames Wright 584b55ac660SJames Wright State grad_ds[3]; 585b55ac660SJames Wright for (CeedInt j=0; j<3; j++) { 586efe9d856SJames Wright CeedScalar dx_i[3] = {0}, dqi_j[5]; 587b55ac660SJames Wright for (CeedInt k=0; k<5; k++) 588efe9d856SJames Wright dqi_j[k] = Grad_dq[0][k][i] * dXdx[0][j] + 589b55ac660SJames Wright Grad_dq[1][k][i] * dXdx[1][j]; 590b55ac660SJames Wright dx_i[j] = 1.; 591efe9d856SJames Wright grad_ds[j] = StateFromQi_fwd(context, s, dqi_j, x_i, dx_i); 592b55ac660SJames Wright } 593b55ac660SJames Wright 594b55ac660SJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 595b55ac660SJames Wright KMStrainRate(grad_ds, dstrain_rate); 596b55ac660SJames Wright NewtonianStress(context, dstrain_rate, dkmstress); 597b55ac660SJames Wright KMUnpack(dkmstress, dstress); 598b55ac660SJames Wright KMUnpack(kmstress, stress); 599b55ac660SJames Wright ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 600b55ac660SJames Wright 601b55ac660SJames Wright StateConservative dF_inviscid[3]; 602b55ac660SJames Wright FluxInviscid_fwd(context, s, ds, dF_inviscid); 603b55ac660SJames Wright 604b55ac660SJames Wright CeedScalar dFlux[5] = {0.}; 605b55ac660SJames Wright for (int j=0; j<3; j++) { 606b55ac660SJames Wright dFlux[0] += dF_inviscid[j].density * norm[j]; 607b55ac660SJames Wright for (int k=0; k<3; k++) 608b55ac660SJames Wright dFlux[k+1] += (dF_inviscid[j].momentum[k] - dstress[k][j]) * norm[j]; 609b55ac660SJames Wright dFlux[4] += (dF_inviscid[j].E_total + dFe[j]) * norm[j]; 610b55ac660SJames Wright } 611b55ac660SJames Wright 612b55ac660SJames Wright for (int j=0; j<5; j++) 613b55ac660SJames Wright v[j][i] = -wdetJb * dFlux[j]; 614b55ac660SJames Wright } // End Quadrature Point Loop 615b55ac660SJames Wright return 0; 616b55ac660SJames Wright } 617b55ac660SJames Wright 6182b89d87eSLeila Ghaffari // ***************************************************************************** 61930e9fa81SJames Wright // Outflow boundary condition, weakly setting a constant pressure 6202b89d87eSLeila Ghaffari // ***************************************************************************** 62130e9fa81SJames Wright CEED_QFUNCTION(PressureOutflow)(void *ctx, CeedInt Q, 62230e9fa81SJames Wright const CeedScalar *const *in, 62330e9fa81SJames Wright CeedScalar *const *out) { 62430e9fa81SJames Wright // *INDENT-OFF* 62530e9fa81SJames Wright // Inputs 62630e9fa81SJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 627ce9b5c20SJames Wright (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 628ce9b5c20SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 629ce9b5c20SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 63030e9fa81SJames Wright // Outputs 63130e9fa81SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 63230e9fa81SJames Wright (*jac_data_sur)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[1]; 63330e9fa81SJames Wright // *INDENT-ON* 63430e9fa81SJames Wright 63530e9fa81SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 63630e9fa81SJames Wright const bool implicit = context->is_implicit; 63730e9fa81SJames Wright const CeedScalar P0 = context->P0; 63830e9fa81SJames Wright 639efe9d856SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 640efe9d856SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 641efe9d856SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 642efe9d856SJames Wright State s, const CeedScalar dqi[5], 643efe9d856SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 644*23d6ba15SJames Wright StateFromQi = context->use_primitive ? &StateFromY : &StateFromU; 645*23d6ba15SJames Wright StateFromQi_fwd = context->use_primitive ? &StateFromY_fwd : &StateFromU_fwd; 646efe9d856SJames Wright 64730e9fa81SJames Wright CeedPragmaSIMD 64830e9fa81SJames Wright // Quadrature Point Loop 64930e9fa81SJames Wright for (CeedInt i=0; i<Q; i++) { 65030e9fa81SJames Wright // Setup 65130e9fa81SJames Wright // -- Interp in 652ce9b5c20SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 653efe9d856SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 654efe9d856SJames Wright State s = StateFromQi(context, qi, x_i); 655ce9b5c20SJames Wright s.Y.pressure = P0; 65630e9fa81SJames Wright 65730e9fa81SJames Wright // -- Interp-to-Interp q_data 65830e9fa81SJames Wright // For explicit mode, the surface integral is on the RHS of ODE q_dot = f(q). 65930e9fa81SJames Wright // For implicit mode, it gets pulled to the LHS of implicit ODE/DAE g(q_dot, q). 66030e9fa81SJames Wright // We can effect this by swapping the sign on this weight 66130e9fa81SJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 66230e9fa81SJames Wright 66330e9fa81SJames Wright // ---- Normal vect 66430e9fa81SJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 66530e9fa81SJames Wright q_data_sur[2][i], 66630e9fa81SJames Wright q_data_sur[3][i] 66730e9fa81SJames Wright }; 66830e9fa81SJames Wright 669ce9b5c20SJames Wright const CeedScalar dXdx[2][3] = { 670ce9b5c20SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 671ce9b5c20SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 672ce9b5c20SJames Wright }; 67330e9fa81SJames Wright 674ce9b5c20SJames Wright State grad_s[3]; 675ce9b5c20SJames Wright for (CeedInt j=0; j<3; j++) { 676efe9d856SJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 677ce9b5c20SJames Wright for (CeedInt k=0; k<5; k++) 678efe9d856SJames Wright dqi[k] = Grad_q[0][k][i] * dXdx[0][j] + 679ce9b5c20SJames Wright Grad_q[1][k][i] * dXdx[1][j]; 680ce9b5c20SJames Wright dx_i[j] = 1.; 681efe9d856SJames Wright grad_s[j] = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 682ce9b5c20SJames Wright } 683ce9b5c20SJames Wright 684ce9b5c20SJames Wright CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 685ce9b5c20SJames Wright KMStrainRate(grad_s, strain_rate); 686ce9b5c20SJames Wright NewtonianStress(context, strain_rate, kmstress); 687ce9b5c20SJames Wright KMUnpack(kmstress, stress); 688ce9b5c20SJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 689ce9b5c20SJames Wright 690ce9b5c20SJames Wright StateConservative F_inviscid[3]; 691ce9b5c20SJames Wright FluxInviscid(context, s, F_inviscid); 692ce9b5c20SJames Wright 693ce9b5c20SJames Wright CeedScalar Flux[5] = {0.}; 694ce9b5c20SJames Wright for (int j=0; j<3; j++) { 695ce9b5c20SJames Wright Flux[0] += F_inviscid[j].density * norm[j]; 696ce9b5c20SJames Wright for (int k=0; k<3; k++) 697ce9b5c20SJames Wright Flux[k+1] += (F_inviscid[j].momentum[k] - stress[k][j]) * norm[j]; 698ce9b5c20SJames Wright Flux[4] += (F_inviscid[j].E_total + Fe[j])*norm[j]; 699ce9b5c20SJames Wright } 70030e9fa81SJames Wright 70130e9fa81SJames Wright // -- Density 702ce9b5c20SJames Wright v[0][i] = -wdetJb * Flux[0]; 70330e9fa81SJames Wright 70430e9fa81SJames Wright // -- Momentum 70530e9fa81SJames Wright for (CeedInt j=0; j<3; j++) 706ce9b5c20SJames Wright v[j+1][i] = -wdetJb * Flux[j+1]; 70730e9fa81SJames Wright 70830e9fa81SJames Wright // -- Total Energy Density 709ce9b5c20SJames Wright v[4][i] = -wdetJb * Flux[4]; 71030e9fa81SJames Wright 71130e9fa81SJames Wright // Save values for Jacobian 712*23d6ba15SJames Wright if (context->use_primitive) { 71357e55a1cSJames Wright jac_data_sur[0][i] = s.Y.pressure; 71457e55a1cSJames Wright for (int j=0; j<3; j++) jac_data_sur[j+1][i] = s.Y.velocity[j]; 71557e55a1cSJames Wright jac_data_sur[4][i] = s.Y.temperature; 71657e55a1cSJames Wright } else { 717ce9b5c20SJames Wright jac_data_sur[0][i] = s.U.density; 71857e55a1cSJames Wright for (int j=0; j<3; j++) jac_data_sur[j+1][i] = s.U.momentum[j]; 719ce9b5c20SJames Wright jac_data_sur[4][i] = s.U.E_total; 72057e55a1cSJames Wright } 7210ec2498eSJames Wright for (int j=0; j<6; j++) jac_data_sur[5+j][i] = kmstress[j]; 72230e9fa81SJames Wright } // End Quadrature Point Loop 72330e9fa81SJames Wright return 0; 72430e9fa81SJames Wright } 72530e9fa81SJames Wright 7262b89d87eSLeila Ghaffari // ***************************************************************************** 72730e9fa81SJames Wright // Jacobian for weak-pressure outflow boundary condition 7282b89d87eSLeila Ghaffari // ***************************************************************************** 72930e9fa81SJames Wright CEED_QFUNCTION(PressureOutflow_Jacobian)(void *ctx, CeedInt Q, 730efe9d856SJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 73130e9fa81SJames Wright // *INDENT-OFF* 73230e9fa81SJames Wright // Inputs 73330e9fa81SJames Wright const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 7340ec2498eSJames Wright (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 7350ec2498eSJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 7360ec2498eSJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 7370ec2498eSJames Wright (*jac_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 73830e9fa81SJames Wright // Outputs 73930e9fa81SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 74030e9fa81SJames Wright // *INDENT-ON* 74130e9fa81SJames Wright 74230e9fa81SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 74330e9fa81SJames Wright const bool implicit = context->is_implicit; 74430e9fa81SJames Wright 745efe9d856SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 746efe9d856SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 747efe9d856SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 748efe9d856SJames Wright State s, const CeedScalar dQi[5], 749efe9d856SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 750*23d6ba15SJames Wright StateFromQi = context->use_primitive ? &StateFromY : &StateFromU; 751*23d6ba15SJames Wright StateFromQi_fwd = context->use_primitive ? &StateFromY_fwd : &StateFromU_fwd; 752efe9d856SJames Wright 75330e9fa81SJames Wright CeedPragmaSIMD 75430e9fa81SJames Wright // Quadrature Point Loop 75530e9fa81SJames Wright for (CeedInt i=0; i<Q; i++) { 7560ec2498eSJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 75730e9fa81SJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 75830e9fa81SJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 75930e9fa81SJames Wright q_data_sur[2][i], 76030e9fa81SJames Wright q_data_sur[3][i] 76130e9fa81SJames Wright }; 7620ec2498eSJames Wright const CeedScalar dXdx[2][3] = { 7630ec2498eSJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 7640ec2498eSJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 7650ec2498eSJames Wright }; 7660ec2498eSJames Wright 767efe9d856SJames Wright CeedScalar qi[5], kmstress[6], dqi[5], dx_i[3] = {0.}; 768efe9d856SJames Wright for (int j=0; j<5; j++) qi[j] = jac_data_sur[j][i]; 7690ec2498eSJames Wright for (int j=0; j<6; j++) kmstress[j] = jac_data_sur[5+j][i]; 770efe9d856SJames Wright for (int j=0; j<5; j++) dqi[j] = dq[j][i]; 77157e55a1cSJames Wright 772efe9d856SJames Wright State s = StateFromQi(context, qi, x_i); 773efe9d856SJames Wright State ds = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 7740ec2498eSJames Wright s.Y.pressure = context->P0; 7750ec2498eSJames Wright ds.Y.pressure = 0.; 7760ec2498eSJames Wright 7770ec2498eSJames Wright State grad_ds[3]; 7780ec2498eSJames Wright for (CeedInt j=0; j<3; j++) { 779efe9d856SJames Wright CeedScalar dx_i[3] = {0}, dqi_j[5]; 7800ec2498eSJames Wright for (CeedInt k=0; k<5; k++) 781efe9d856SJames Wright dqi_j[k] = Grad_dq[0][k][i] * dXdx[0][j] + 7820ec2498eSJames Wright Grad_dq[1][k][i] * dXdx[1][j]; 7830ec2498eSJames Wright dx_i[j] = 1.; 784efe9d856SJames Wright grad_ds[j] = StateFromQi_fwd(context, s, dqi_j, x_i, dx_i); 7850ec2498eSJames Wright } 7860ec2498eSJames Wright 7870ec2498eSJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 7880ec2498eSJames Wright KMStrainRate(grad_ds, dstrain_rate); 7890ec2498eSJames Wright NewtonianStress(context, dstrain_rate, dkmstress); 7900ec2498eSJames Wright KMUnpack(dkmstress, dstress); 7910ec2498eSJames Wright KMUnpack(kmstress, stress); 7920ec2498eSJames Wright ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 79330e9fa81SJames Wright 794b5d317f8SJames Wright StateConservative dF_inviscid[3]; 795b5d317f8SJames Wright FluxInviscid_fwd(context, s, ds, dF_inviscid); 79630e9fa81SJames Wright 797b5d317f8SJames Wright CeedScalar dFlux[5] = {0.}; 798b5d317f8SJames Wright for (int j=0; j<3; j++) { 799b5d317f8SJames Wright dFlux[0] += dF_inviscid[j].density * norm[j]; 800b5d317f8SJames Wright for (int k=0; k<3; k++) 8010ec2498eSJames Wright dFlux[k+1] += (dF_inviscid[j].momentum[k] - dstress[k][j]) * norm[j]; 8020ec2498eSJames Wright dFlux[4] += (dF_inviscid[j].E_total + dFe[j]) * norm[j]; 803b5d317f8SJames Wright } 804b5d317f8SJames Wright 805b5d317f8SJames Wright for (int j=0; j<5; j++) 806b5d317f8SJames Wright v[j][i] = -wdetJb * dFlux[j]; 80730e9fa81SJames Wright } // End Quadrature Point Loop 80830e9fa81SJames Wright return 0; 80930e9fa81SJames Wright } 81030e9fa81SJames Wright 81188b783a1SJames Wright // ***************************************************************************** 812dc805cc4SLeila Ghaffari // This QFunction implements the Navier-Stokes equations (mentioned above) in 813dc805cc4SLeila Ghaffari // primitive variables and with implicit time stepping method 814dc805cc4SLeila Ghaffari // 815dc805cc4SLeila Ghaffari // ***************************************************************************** 816dc805cc4SLeila Ghaffari CEED_QFUNCTION(IFunction_Newtonian_Prim)(void *ctx, CeedInt Q, 817dc805cc4SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 818dc805cc4SLeila Ghaffari // *INDENT-OFF* 819dc805cc4SLeila Ghaffari // Inputs 820dc805cc4SLeila Ghaffari const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 821dc805cc4SLeila Ghaffari (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 822dc805cc4SLeila Ghaffari (*q_dot)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 823dc805cc4SLeila Ghaffari (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 824dc805cc4SLeila Ghaffari (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 825dc805cc4SLeila Ghaffari // Outputs 826dc805cc4SLeila Ghaffari CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 827dc805cc4SLeila Ghaffari (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1], 828dc805cc4SLeila Ghaffari (*jac_data)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[2]; 829dc805cc4SLeila Ghaffari // *INDENT-ON* 830dc805cc4SLeila Ghaffari // Context 831dc805cc4SLeila Ghaffari NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 832dc805cc4SLeila Ghaffari const CeedScalar *g = context->g; 833dc805cc4SLeila Ghaffari const CeedScalar dt = context->dt; 834dc805cc4SLeila Ghaffari 835dc805cc4SLeila Ghaffari CeedPragmaSIMD 836dc805cc4SLeila Ghaffari // Quadrature Point Loop 837dc805cc4SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 838dc805cc4SLeila Ghaffari CeedScalar Y[5]; 839dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) Y[j] = q[j][i]; 840dc805cc4SLeila Ghaffari const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 841dc805cc4SLeila Ghaffari State s = StateFromY(context, Y, x_i); 842dc805cc4SLeila Ghaffari 843dc805cc4SLeila Ghaffari // -- Interp-to-Interp q_data 844dc805cc4SLeila Ghaffari const CeedScalar wdetJ = q_data[0][i]; 845dc805cc4SLeila Ghaffari // -- Interp-to-Grad q_data 846dc805cc4SLeila Ghaffari // ---- Inverse of change of coordinate matrix: X_i,j 847dc805cc4SLeila Ghaffari // *INDENT-OFF* 848*23d6ba15SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 849*23d6ba15SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 850*23d6ba15SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 851dc805cc4SLeila Ghaffari }; 852dc805cc4SLeila Ghaffari // *INDENT-ON* 853dc805cc4SLeila Ghaffari State grad_s[3]; 854dc805cc4SLeila Ghaffari for (CeedInt j=0; j<3; j++) { 855dc805cc4SLeila Ghaffari CeedScalar dx_i[3] = {0}, dY[5]; 856dc805cc4SLeila Ghaffari for (CeedInt k=0; k<5; k++) 857dc805cc4SLeila Ghaffari dY[k] = Grad_q[0][k][i] * dXdx[0][j] + 858dc805cc4SLeila Ghaffari Grad_q[1][k][i] * dXdx[1][j] + 859dc805cc4SLeila Ghaffari Grad_q[2][k][i] * dXdx[2][j]; 860dc805cc4SLeila Ghaffari dx_i[j] = 1.; 861dc805cc4SLeila Ghaffari grad_s[j] = StateFromY_fwd(context, s, dY, x_i, dx_i); 862dc805cc4SLeila Ghaffari } 863dc805cc4SLeila Ghaffari 864dc805cc4SLeila Ghaffari CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 865dc805cc4SLeila Ghaffari KMStrainRate(grad_s, strain_rate); 866dc805cc4SLeila Ghaffari NewtonianStress(context, strain_rate, kmstress); 867dc805cc4SLeila Ghaffari KMUnpack(kmstress, stress); 868dc805cc4SLeila Ghaffari ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 869dc805cc4SLeila Ghaffari 870dc805cc4SLeila Ghaffari StateConservative F_inviscid[3]; 871dc805cc4SLeila Ghaffari FluxInviscid(context, s, F_inviscid); 872dc805cc4SLeila Ghaffari 873dc805cc4SLeila Ghaffari // Total flux 874dc805cc4SLeila Ghaffari CeedScalar Flux[5][3]; 8752b89d87eSLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 876dc805cc4SLeila Ghaffari 8772b89d87eSLeila Ghaffari for (CeedInt j=0; j<3; j++) 8782b89d87eSLeila Ghaffari for (CeedInt k=0; k<5; k++) 879dc805cc4SLeila Ghaffari Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * Flux[k][0] + 880dc805cc4SLeila Ghaffari dXdx[j][1] * Flux[k][1] + 881dc805cc4SLeila Ghaffari dXdx[j][2] * Flux[k][2]); 882dc805cc4SLeila Ghaffari 883dc805cc4SLeila Ghaffari const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 884dc805cc4SLeila Ghaffari 885dc805cc4SLeila Ghaffari CeedScalar Y_dot[5], dx0[3] = {0}; 886dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) Y_dot[j] = q_dot[j][i]; 887dc805cc4SLeila Ghaffari State s_dot = StateFromY_fwd(context, s, Y_dot, x_i, dx0); 888dc805cc4SLeila Ghaffari 889dc805cc4SLeila Ghaffari CeedScalar U_dot[5] = {0.}; 8902b89d87eSLeila Ghaffari UnpackState_U(s_dot.U, U_dot); 891dc805cc4SLeila Ghaffari 892dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) 893dc805cc4SLeila Ghaffari v[j][i] = wdetJ * (U_dot[j] - body_force[j]); 894dc805cc4SLeila Ghaffari 8952b89d87eSLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 8962b89d87eSLeila Ghaffari CeedScalar Tau_d[3], stab[5][3]; 8972b89d87eSLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 8982b89d87eSLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 899dc805cc4SLeila Ghaffari 900dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) 901dc805cc4SLeila Ghaffari for (CeedInt k=0; k<3; k++) 902dc805cc4SLeila Ghaffari Grad_v[k][j][i] += wdetJ*(stab[j][0] * dXdx[k][0] + 903dc805cc4SLeila Ghaffari stab[j][1] * dXdx[k][1] + 904dc805cc4SLeila Ghaffari stab[j][2] * dXdx[k][2]); 905dc805cc4SLeila Ghaffari 906dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) jac_data[j][i] = Y[j]; 907dc805cc4SLeila Ghaffari for (CeedInt j=0; j<6; j++) jac_data[5+j][i] = kmstress[j]; 908dc805cc4SLeila Ghaffari for (CeedInt j=0; j<3; j++) jac_data[5+6+j][i] = Tau_d[j]; 909dc805cc4SLeila Ghaffari 910dc805cc4SLeila Ghaffari } // End Quadrature Point Loop 911dc805cc4SLeila Ghaffari 912dc805cc4SLeila Ghaffari // Return 913dc805cc4SLeila Ghaffari return 0; 914dc805cc4SLeila Ghaffari } 915dc805cc4SLeila Ghaffari 916dc805cc4SLeila Ghaffari // ***************************************************************************** 917dc805cc4SLeila Ghaffari // This QFunction implements the jacobean of the Navier-Stokes equations 918dc805cc4SLeila Ghaffari // in primitive variables for implicit time stepping method. 919dc805cc4SLeila Ghaffari // 920dc805cc4SLeila Ghaffari // ***************************************************************************** 921dc805cc4SLeila Ghaffari CEED_QFUNCTION(IJacobian_Newtonian_Prim)(void *ctx, CeedInt Q, 922dc805cc4SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 923dc805cc4SLeila Ghaffari // *INDENT-OFF* 924dc805cc4SLeila Ghaffari // Inputs 925dc805cc4SLeila Ghaffari const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 926dc805cc4SLeila Ghaffari (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 927dc805cc4SLeila Ghaffari (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 928dc805cc4SLeila Ghaffari (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 929dc805cc4SLeila Ghaffari (*jac_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 930dc805cc4SLeila Ghaffari // Outputs 931dc805cc4SLeila Ghaffari CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 932dc805cc4SLeila Ghaffari (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1]; 933dc805cc4SLeila Ghaffari // *INDENT-ON* 934dc805cc4SLeila Ghaffari // Context 935dc805cc4SLeila Ghaffari NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 936dc805cc4SLeila Ghaffari const CeedScalar *g = context->g; 937dc805cc4SLeila Ghaffari 938dc805cc4SLeila Ghaffari CeedPragmaSIMD 939dc805cc4SLeila Ghaffari // Quadrature Point Loop 940dc805cc4SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 941dc805cc4SLeila Ghaffari // -- Interp-to-Interp q_data 942dc805cc4SLeila Ghaffari const CeedScalar wdetJ = q_data[0][i]; 943dc805cc4SLeila Ghaffari // -- Interp-to-Grad q_data 944dc805cc4SLeila Ghaffari // ---- Inverse of change of coordinate matrix: X_i,j 945dc805cc4SLeila Ghaffari // *INDENT-OFF* 946*23d6ba15SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 947*23d6ba15SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 948*23d6ba15SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 949dc805cc4SLeila Ghaffari }; 950dc805cc4SLeila Ghaffari // *INDENT-ON* 951dc805cc4SLeila Ghaffari 952dc805cc4SLeila Ghaffari CeedScalar Y[5], kmstress[6], Tau_d[3] __attribute((unused)); 953dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) Y[j] = jac_data[j][i]; 954dc805cc4SLeila Ghaffari for (int j=0; j<6; j++) kmstress[j] = jac_data[5+j][i]; 955dc805cc4SLeila Ghaffari for (int j=0; j<3; j++) Tau_d[j] = jac_data[5+6+j][i]; 956dc805cc4SLeila Ghaffari const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 957dc805cc4SLeila Ghaffari State s = StateFromY(context, Y, x_i); 958dc805cc4SLeila Ghaffari 959dc805cc4SLeila Ghaffari CeedScalar dY[5], dx0[3] = {0}; 960dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) dY[j] = dq[j][i]; 961dc805cc4SLeila Ghaffari State ds = StateFromY_fwd(context, s, dY, x_i, dx0); 962dc805cc4SLeila Ghaffari 963dc805cc4SLeila Ghaffari State grad_ds[3]; 964dc805cc4SLeila Ghaffari for (int j=0; j<3; j++) { 965dc805cc4SLeila Ghaffari CeedScalar dYj[5]; 966dc805cc4SLeila Ghaffari for (int k=0; k<5; k++) 967dc805cc4SLeila Ghaffari dYj[k] = Grad_dq[0][k][i] * dXdx[0][j] + 968dc805cc4SLeila Ghaffari Grad_dq[1][k][i] * dXdx[1][j] + 969dc805cc4SLeila Ghaffari Grad_dq[2][k][i] * dXdx[2][j]; 970dc805cc4SLeila Ghaffari grad_ds[j] = StateFromY_fwd(context, s, dYj, x_i, dx0); 971dc805cc4SLeila Ghaffari } 972dc805cc4SLeila Ghaffari 973dc805cc4SLeila Ghaffari CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 974dc805cc4SLeila Ghaffari KMStrainRate(grad_ds, dstrain_rate); 975dc805cc4SLeila Ghaffari NewtonianStress(context, dstrain_rate, dkmstress); 976dc805cc4SLeila Ghaffari KMUnpack(dkmstress, dstress); 977dc805cc4SLeila Ghaffari KMUnpack(kmstress, stress); 978dc805cc4SLeila Ghaffari ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 979dc805cc4SLeila Ghaffari 980dc805cc4SLeila Ghaffari StateConservative dF_inviscid[3]; 981dc805cc4SLeila Ghaffari FluxInviscid_fwd(context, s, ds, dF_inviscid); 982dc805cc4SLeila Ghaffari 983dc805cc4SLeila Ghaffari // Total flux 984dc805cc4SLeila Ghaffari CeedScalar dFlux[5][3]; 9852b89d87eSLeila Ghaffari FluxTotal(dF_inviscid, dstress, dFe, dFlux); 986dc805cc4SLeila Ghaffari 9872b89d87eSLeila Ghaffari for (int j=0; j<3; j++) 9882b89d87eSLeila Ghaffari for (int k=0; k<5; k++) 989dc805cc4SLeila Ghaffari Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * dFlux[k][0] + 990dc805cc4SLeila Ghaffari dXdx[j][1] * dFlux[k][1] + 991dc805cc4SLeila Ghaffari dXdx[j][2] * dFlux[k][2]); 992dc805cc4SLeila Ghaffari 9932b89d87eSLeila Ghaffari const CeedScalar dbody_force[5] = {0, ds.U.density *g[0], ds.U.density *g[1], ds.U.density *g[2], 0}; 994dc805cc4SLeila Ghaffari CeedScalar dU[5] = {0.}; 9952b89d87eSLeila Ghaffari UnpackState_U(ds.U, dU); 996dc805cc4SLeila Ghaffari 997dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) 998dc805cc4SLeila Ghaffari v[j][i] = wdetJ * (context->ijacobian_time_shift * dU[j] - dbody_force[j]); 999dc805cc4SLeila Ghaffari 10002b89d87eSLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 10012b89d87eSLeila Ghaffari CeedScalar dstab[5][3], U_dot[5] = {0}; 10022b89d87eSLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = context->ijacobian_time_shift * dU[j]; 10032b89d87eSLeila Ghaffari Stabilization(context, s, Tau_d, grad_ds, U_dot, dbody_force, x_i, dstab); 1004dc805cc4SLeila Ghaffari 1005dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) 1006dc805cc4SLeila Ghaffari for (int k=0; k<3; k++) 1007dc805cc4SLeila Ghaffari Grad_v[k][j][i] += wdetJ*(dstab[j][0] * dXdx[k][0] + 1008dc805cc4SLeila Ghaffari dstab[j][1] * dXdx[k][1] + 1009dc805cc4SLeila Ghaffari dstab[j][2] * dXdx[k][2]); 1010dc805cc4SLeila Ghaffari 1011dc805cc4SLeila Ghaffari } // End Quadrature Point Loop 1012dc805cc4SLeila Ghaffari return 0; 1013dc805cc4SLeila Ghaffari } 1014dc805cc4SLeila Ghaffari // ***************************************************************************** 1015dc805cc4SLeila Ghaffari 101688b783a1SJames Wright #endif // newtonian_h 1017