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> 16*c9c2c079SJeremy L Thompson #include <math.h> 17c6e8c570SJames Wright #include "newtonian_state.h" 18*c9c2c079SJeremy L Thompson #include "newtonian_types.h" 192b89d87eSLeila Ghaffari #include "stabilization.h" 20*c9c2c079SJeremy 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* 18288b783a1SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], 18388b783a1SJames Wright q_data[2][i], 18488b783a1SJames Wright q_data[3][i]}, 18588b783a1SJames Wright {q_data[4][i], 18688b783a1SJames Wright q_data[5][i], 18788b783a1SJames Wright q_data[6][i]}, 18888b783a1SJames Wright {q_data[7][i], 18988b783a1SJames Wright q_data[8][i], 19088b783a1SJames Wright q_data[9][i]} 19188b783a1SJames Wright }; 19288b783a1SJames Wright // *INDENT-ON* 1935c677226SJed Brown State grad_s[3]; 1943c4b7af6SJed Brown for (CeedInt j=0; j<3; j++) { 1956f00d0e6SJed Brown CeedScalar dx_i[3] = {0}, dU[5]; 19639c69132SJed Brown for (CeedInt k=0; k<5; k++) 19739c69132SJed Brown dU[k] = Grad_q[0][k][i] * dXdx[0][j] + 19839c69132SJed Brown Grad_q[1][k][i] * dXdx[1][j] + 19939c69132SJed Brown Grad_q[2][k][i] * dXdx[2][j]; 2005c677226SJed Brown dx_i[j] = 1.; 2016f00d0e6SJed Brown grad_s[j] = StateFromU_fwd(context, s, dU, x_i, dx_i); 2025c677226SJed Brown } 2035c677226SJed Brown 2045c677226SJed Brown CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 2055c677226SJed Brown KMStrainRate(grad_s, strain_rate); 2065c677226SJed Brown NewtonianStress(context, strain_rate, kmstress); 2075c677226SJed Brown KMUnpack(kmstress, stress); 2085c677226SJed Brown ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 2095c677226SJed Brown 2105c677226SJed Brown StateConservative F_inviscid[3]; 2115c677226SJed Brown FluxInviscid(context, s, F_inviscid); 2125c677226SJed Brown 2135c677226SJed Brown // Total flux 2145c677226SJed Brown CeedScalar Flux[5][3]; 2152b89d87eSLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 2165c677226SJed Brown 2172b89d87eSLeila Ghaffari for (CeedInt j=0; j<3; j++) 2182b89d87eSLeila Ghaffari for (CeedInt k=0; k<5; k++) 219a3ae0734SJed Brown Grad_v[j][k][i] = wdetJ * (dXdx[j][0] * Flux[k][0] + 2205c677226SJed Brown dXdx[j][1] * Flux[k][1] + 2215c677226SJed Brown dXdx[j][2] * Flux[k][2]); 2225c677226SJed Brown 2235c677226SJed Brown const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 2245c677226SJed Brown for (int j=0; j<5; j++) 2255c677226SJed Brown v[j][i] = wdetJ * body_force[j]; 22688b783a1SJames Wright 2272b89d87eSLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 2282b89d87eSLeila Ghaffari CeedScalar Tau_d[3], stab[5][3], U_dot[5] = {0}; 2292b89d87eSLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 2302b89d87eSLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 23188b783a1SJames Wright 232ba6664aeSJames Wright for (CeedInt j=0; j<5; j++) 233ba6664aeSJames Wright for (CeedInt k=0; k<3; k++) 234a3ae0734SJed Brown Grad_v[k][j][i] -= wdetJ*(stab[j][0] * dXdx[k][0] + 23588b783a1SJames Wright stab[j][1] * dXdx[k][1] + 23688b783a1SJames Wright stab[j][2] * dXdx[k][2]); 23788b783a1SJames Wright 23888b783a1SJames Wright } // End Quadrature Point Loop 23988b783a1SJames Wright 24088b783a1SJames Wright // Return 24188b783a1SJames Wright return 0; 24288b783a1SJames Wright } 24388b783a1SJames Wright 24488b783a1SJames Wright // ***************************************************************************** 24588b783a1SJames Wright // This QFunction implements the Navier-Stokes equations (mentioned above) with 24688b783a1SJames Wright // implicit time stepping method 24788b783a1SJames Wright // 24888b783a1SJames Wright // SU = Galerkin + grad(v) . ( Ai^T * Tau * (Aj q,j) ) 24988b783a1SJames Wright // SUPG = Galerkin + grad(v) . ( Ai^T * Tau * (q_dot + Aj q,j - body force) ) 25088b783a1SJames Wright // (diffussive terms will be added later) 25188b783a1SJames Wright // 25288b783a1SJames Wright // ***************************************************************************** 25388b783a1SJames Wright CEED_QFUNCTION(IFunction_Newtonian)(void *ctx, CeedInt Q, 254dc805cc4SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 25588b783a1SJames Wright // *INDENT-OFF* 25688b783a1SJames Wright // Inputs 25788b783a1SJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 258a3ae0734SJed Brown (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 25988b783a1SJames Wright (*q_dot)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 26088b783a1SJames Wright (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 26188b783a1SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 26288b783a1SJames Wright // Outputs 26388b783a1SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 264a3ae0734SJed Brown (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1], 265a3ae0734SJed Brown (*jac_data)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[2]; 26688b783a1SJames Wright // *INDENT-ON* 26788b783a1SJames Wright // Context 26888b783a1SJames Wright NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 26988626eedSJames Wright const CeedScalar *g = context->g; 27088626eedSJames Wright const CeedScalar dt = context->dt; 27188b783a1SJames Wright 27288b783a1SJames Wright CeedPragmaSIMD 27388b783a1SJames Wright // Quadrature Point Loop 27488b783a1SJames Wright for (CeedInt i=0; i<Q; i++) { 2755c677226SJed Brown CeedScalar U[5]; 2763c4b7af6SJed Brown for (CeedInt j=0; j<5; j++) U[j] = q[j][i]; 2775c677226SJed Brown const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 2785c677226SJed Brown State s = StateFromU(context, U, x_i); 2795c677226SJed Brown 28088b783a1SJames Wright // -- Interp-to-Interp q_data 28188b783a1SJames Wright const CeedScalar wdetJ = q_data[0][i]; 28288b783a1SJames Wright // -- Interp-to-Grad q_data 28388b783a1SJames Wright // ---- Inverse of change of coordinate matrix: X_i,j 28488b783a1SJames Wright // *INDENT-OFF* 28588b783a1SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], 28688b783a1SJames Wright q_data[2][i], 28788b783a1SJames Wright q_data[3][i]}, 28888b783a1SJames Wright {q_data[4][i], 28988b783a1SJames Wright q_data[5][i], 29088b783a1SJames Wright q_data[6][i]}, 29188b783a1SJames Wright {q_data[7][i], 29288b783a1SJames Wright q_data[8][i], 29388b783a1SJames Wright q_data[9][i]} 29488b783a1SJames Wright }; 29588b783a1SJames Wright // *INDENT-ON* 2965c677226SJed Brown State grad_s[3]; 297ba6664aeSJames Wright for (CeedInt j=0; j<3; j++) { 2986f00d0e6SJed Brown CeedScalar dx_i[3] = {0}, dU[5]; 29939c69132SJed Brown for (CeedInt k=0; k<5; k++) 30039c69132SJed Brown dU[k] = Grad_q[0][k][i] * dXdx[0][j] + 30139c69132SJed Brown Grad_q[1][k][i] * dXdx[1][j] + 30239c69132SJed Brown Grad_q[2][k][i] * dXdx[2][j]; 3035c677226SJed Brown dx_i[j] = 1.; 3046f00d0e6SJed Brown grad_s[j] = StateFromU_fwd(context, s, dU, x_i, dx_i); 30588b783a1SJames Wright } 3065c677226SJed Brown 3075c677226SJed Brown CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 3085c677226SJed Brown KMStrainRate(grad_s, strain_rate); 3095c677226SJed Brown NewtonianStress(context, strain_rate, kmstress); 3105c677226SJed Brown KMUnpack(kmstress, stress); 3115c677226SJed Brown ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 3125c677226SJed Brown 3135c677226SJed Brown StateConservative F_inviscid[3]; 3145c677226SJed Brown FluxInviscid(context, s, F_inviscid); 3155c677226SJed Brown 3165c677226SJed Brown // Total flux 3175c677226SJed Brown CeedScalar Flux[5][3]; 3182b89d87eSLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 3195c677226SJed Brown 3202b89d87eSLeila Ghaffari for (CeedInt j=0; j<3; j++) 3212b89d87eSLeila Ghaffari for (CeedInt k=0; k<5; k++) 322a3ae0734SJed Brown Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * Flux[k][0] + 3235c677226SJed Brown dXdx[j][1] * Flux[k][1] + 3245c677226SJed Brown dXdx[j][2] * Flux[k][2]); 3255c677226SJed Brown 3265c677226SJed Brown const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 3273c4b7af6SJed Brown for (CeedInt j=0; j<5; j++) 3285c677226SJed Brown v[j][i] = wdetJ * (q_dot[j][i] - body_force[j]); 32988b783a1SJames Wright 3302b89d87eSLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 3312b89d87eSLeila Ghaffari CeedScalar Tau_d[3], stab[5][3], U_dot[5] = {0}; 3322b89d87eSLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = q_dot[j][i]; 3332b89d87eSLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 3342b89d87eSLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 33588b783a1SJames Wright 336ba6664aeSJames Wright for (CeedInt j=0; j<5; j++) 337ba6664aeSJames Wright for (CeedInt k=0; k<3; k++) 338a3ae0734SJed Brown Grad_v[k][j][i] += wdetJ*(stab[j][0] * dXdx[k][0] + 33988b783a1SJames Wright stab[j][1] * dXdx[k][1] + 34088b783a1SJames Wright stab[j][2] * dXdx[k][2]); 3413c4b7af6SJed Brown 3423c4b7af6SJed Brown for (CeedInt j=0; j<5; j++) jac_data[j][i] = U[j]; 3433c4b7af6SJed Brown for (CeedInt j=0; j<6; j++) jac_data[5+j][i] = kmstress[j]; 3443c4b7af6SJed Brown for (CeedInt j=0; j<3; j++) jac_data[5+6+j][i] = Tau_d[j]; 34588b783a1SJames Wright 34688b783a1SJames Wright } // End Quadrature Point Loop 34788b783a1SJames Wright 34888b783a1SJames Wright // Return 34988b783a1SJames Wright return 0; 35088b783a1SJames Wright } 351e334ad8fSJed Brown 352dc805cc4SLeila Ghaffari // ***************************************************************************** 353dc805cc4SLeila Ghaffari // This QFunction implements the jacobean of the Navier-Stokes equations 354dc805cc4SLeila Ghaffari // for implicit time stepping method. 355dc805cc4SLeila Ghaffari // 356dc805cc4SLeila Ghaffari // ***************************************************************************** 357e334ad8fSJed Brown CEED_QFUNCTION(IJacobian_Newtonian)(void *ctx, CeedInt Q, 358e334ad8fSJed Brown const CeedScalar *const *in, 359e334ad8fSJed Brown CeedScalar *const *out) { 360e334ad8fSJed Brown // *INDENT-OFF* 361e334ad8fSJed Brown // Inputs 362e334ad8fSJed Brown const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 363e334ad8fSJed Brown (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 364e334ad8fSJed Brown (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 365e334ad8fSJed Brown (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 366e334ad8fSJed Brown (*jac_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 367e334ad8fSJed Brown // Outputs 368e334ad8fSJed Brown CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 369e334ad8fSJed Brown (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1]; 370e334ad8fSJed Brown // *INDENT-ON* 371e334ad8fSJed Brown // Context 372e334ad8fSJed Brown NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 373e334ad8fSJed Brown const CeedScalar *g = context->g; 374e334ad8fSJed Brown 375e334ad8fSJed Brown CeedPragmaSIMD 376e334ad8fSJed Brown // Quadrature Point Loop 377e334ad8fSJed Brown for (CeedInt i=0; i<Q; i++) { 378e334ad8fSJed Brown // -- Interp-to-Interp q_data 379e334ad8fSJed Brown const CeedScalar wdetJ = q_data[0][i]; 380e334ad8fSJed Brown // -- Interp-to-Grad q_data 381e334ad8fSJed Brown // ---- Inverse of change of coordinate matrix: X_i,j 382e334ad8fSJed Brown // *INDENT-OFF* 383e334ad8fSJed Brown const CeedScalar dXdx[3][3] = {{q_data[1][i], 384e334ad8fSJed Brown q_data[2][i], 385e334ad8fSJed Brown q_data[3][i]}, 386e334ad8fSJed Brown {q_data[4][i], 387e334ad8fSJed Brown q_data[5][i], 388e334ad8fSJed Brown q_data[6][i]}, 389e334ad8fSJed Brown {q_data[7][i], 390e334ad8fSJed Brown q_data[8][i], 391e334ad8fSJed Brown q_data[9][i]} 392e334ad8fSJed Brown }; 393e334ad8fSJed Brown // *INDENT-ON* 394e334ad8fSJed Brown 395e334ad8fSJed Brown CeedScalar U[5], kmstress[6], Tau_d[3] __attribute((unused)); 396e334ad8fSJed Brown for (int j=0; j<5; j++) U[j] = jac_data[j][i]; 397e334ad8fSJed Brown for (int j=0; j<6; j++) kmstress[j] = jac_data[5+j][i]; 398e334ad8fSJed Brown for (int j=0; j<3; j++) Tau_d[j] = jac_data[5+6+j][i]; 399e334ad8fSJed Brown const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 400e334ad8fSJed Brown State s = StateFromU(context, U, x_i); 401e334ad8fSJed Brown 402e334ad8fSJed Brown CeedScalar dU[5], dx0[3] = {0}; 403e334ad8fSJed Brown for (int j=0; j<5; j++) dU[j] = dq[j][i]; 404e334ad8fSJed Brown State ds = StateFromU_fwd(context, s, dU, x_i, dx0); 405e334ad8fSJed Brown 406e334ad8fSJed Brown State grad_ds[3]; 407e334ad8fSJed Brown for (int j=0; j<3; j++) { 408e334ad8fSJed Brown CeedScalar dUj[5]; 4092b89d87eSLeila Ghaffari for (int k=0; k<5; k++) 4102b89d87eSLeila Ghaffari dUj[k] = Grad_dq[0][k][i] * dXdx[0][j] + 4112b89d87eSLeila Ghaffari Grad_dq[1][k][i] * dXdx[1][j] + 4122b89d87eSLeila Ghaffari Grad_dq[2][k][i] * dXdx[2][j]; 413e334ad8fSJed Brown grad_ds[j] = StateFromU_fwd(context, s, dUj, x_i, dx0); 414e334ad8fSJed Brown } 415e334ad8fSJed Brown 416e334ad8fSJed Brown CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 417e334ad8fSJed Brown KMStrainRate(grad_ds, dstrain_rate); 418e334ad8fSJed Brown NewtonianStress(context, dstrain_rate, dkmstress); 419e334ad8fSJed Brown KMUnpack(dkmstress, dstress); 420e334ad8fSJed Brown KMUnpack(kmstress, stress); 421e334ad8fSJed Brown ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 422e334ad8fSJed Brown 423e334ad8fSJed Brown StateConservative dF_inviscid[3]; 424e334ad8fSJed Brown FluxInviscid_fwd(context, s, ds, dF_inviscid); 425e334ad8fSJed Brown 426e334ad8fSJed Brown // Total flux 427e334ad8fSJed Brown CeedScalar dFlux[5][3]; 4282b89d87eSLeila Ghaffari FluxTotal(dF_inviscid, dstress, dFe, dFlux); 429e334ad8fSJed Brown 4302b89d87eSLeila Ghaffari for (int j=0; j<3; j++) 4312b89d87eSLeila Ghaffari for (int k=0; k<5; k++) 432e334ad8fSJed Brown Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * dFlux[k][0] + 433e334ad8fSJed Brown dXdx[j][1] * dFlux[k][1] + 434e334ad8fSJed Brown dXdx[j][2] * dFlux[k][2]); 435e334ad8fSJed Brown 436e334ad8fSJed Brown const CeedScalar dbody_force[5] = {0, ds.U.density *g[0], ds.U.density *g[1], ds.U.density *g[2], 0}; 437e334ad8fSJed Brown for (int j=0; j<5; j++) 438e334ad8fSJed Brown v[j][i] = wdetJ * (context->ijacobian_time_shift * dU[j] - dbody_force[j]); 439e334ad8fSJed Brown 4402b89d87eSLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 4412b89d87eSLeila Ghaffari CeedScalar dstab[5][3], U_dot[5] = {0}; 4422b89d87eSLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = context->ijacobian_time_shift * dU[j]; 4432b89d87eSLeila Ghaffari Stabilization(context, s, Tau_d, grad_ds, U_dot, dbody_force, x_i, dstab); 4442b89d87eSLeila Ghaffari 445e334ad8fSJed Brown for (int j=0; j<5; j++) 446e334ad8fSJed Brown for (int k=0; k<3; k++) 447e334ad8fSJed Brown Grad_v[k][j][i] += wdetJ*(dstab[j][0] * dXdx[k][0] + 448e334ad8fSJed Brown dstab[j][1] * dXdx[k][1] + 449e334ad8fSJed Brown dstab[j][2] * dXdx[k][2]); 450e334ad8fSJed Brown 451e334ad8fSJed Brown } // End Quadrature Point Loop 452e334ad8fSJed Brown return 0; 453e334ad8fSJed Brown } 45465dd5cafSJames Wright 4552b89d87eSLeila Ghaffari // ***************************************************************************** 45665dd5cafSJames Wright // Compute boundary integral (ie. for strongly set inflows) 4572b89d87eSLeila Ghaffari // ***************************************************************************** 45865dd5cafSJames Wright CEED_QFUNCTION(BoundaryIntegral)(void *ctx, CeedInt Q, 45965dd5cafSJames Wright const CeedScalar *const *in, 46065dd5cafSJames Wright CeedScalar *const *out) { 46165dd5cafSJames Wright 46265dd5cafSJames Wright //*INDENT-OFF* 46365dd5cafSJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 4642c4e60d7SJames Wright (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 4652c4e60d7SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 4662c4e60d7SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 46765dd5cafSJames Wright 468b55ac660SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA]) out[0], 469b55ac660SJames Wright (*jac_data_sur)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA]) out[1]; 47065dd5cafSJames Wright 47165dd5cafSJames Wright //*INDENT-ON* 47265dd5cafSJames Wright 4732c4e60d7SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext) ctx; 4742c4e60d7SJames Wright const bool is_implicit = context->is_implicit; 475efe9d856SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 476efe9d856SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 477efe9d856SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 478efe9d856SJames Wright State s, const CeedScalar dqi[5], 479efe9d856SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 480efe9d856SJames Wright StateFromQi = context->is_primitive ? &StateFromY : &StateFromU; 481efe9d856SJames Wright StateFromQi_fwd = context->is_primitive ? &StateFromY_fwd : &StateFromU_fwd; 482efe9d856SJames Wright 48365dd5cafSJames Wright 48465dd5cafSJames Wright CeedPragmaSIMD 48565dd5cafSJames Wright for(CeedInt i=0; i<Q; i++) { 4862c4e60d7SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 487efe9d856SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 488efe9d856SJames Wright State s = StateFromQi(context, qi, x_i); 48965dd5cafSJames Wright 49065dd5cafSJames Wright const CeedScalar wdetJb = (is_implicit ? -1. : 1.) * q_data_sur[0][i]; 49165dd5cafSJames Wright // ---- Normal vect 49265dd5cafSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 49365dd5cafSJames Wright q_data_sur[2][i], 49465dd5cafSJames Wright q_data_sur[3][i] 49565dd5cafSJames Wright }; 49665dd5cafSJames Wright 4972c4e60d7SJames Wright const CeedScalar dXdx[2][3] = { 4982c4e60d7SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 4992c4e60d7SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 5002c4e60d7SJames Wright }; 50165dd5cafSJames Wright 5022c4e60d7SJames Wright State grad_s[3]; 5032c4e60d7SJames Wright for (CeedInt j=0; j<3; j++) { 504efe9d856SJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 5052c4e60d7SJames Wright for (CeedInt k=0; k<5; k++) 506efe9d856SJames Wright dqi[k] = Grad_q[0][k][i] * dXdx[0][j] + 5072c4e60d7SJames Wright Grad_q[1][k][i] * dXdx[1][j]; 5082c4e60d7SJames Wright dx_i[j] = 1.; 509efe9d856SJames Wright grad_s[j] = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 5102c4e60d7SJames Wright } 51165dd5cafSJames Wright 5122c4e60d7SJames Wright CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 5132c4e60d7SJames Wright KMStrainRate(grad_s, strain_rate); 5142c4e60d7SJames Wright NewtonianStress(context, strain_rate, kmstress); 5152c4e60d7SJames Wright KMUnpack(kmstress, stress); 5162c4e60d7SJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 5172c4e60d7SJames Wright 5182c4e60d7SJames Wright StateConservative F_inviscid[3]; 5192c4e60d7SJames Wright FluxInviscid(context, s, F_inviscid); 5202c4e60d7SJames Wright 5212c4e60d7SJames Wright CeedScalar Flux[5] = {0.}; 5222c4e60d7SJames Wright for (int j=0; j<3; j++) { 5232c4e60d7SJames Wright Flux[0] += F_inviscid[j].density * norm[j]; 5242c4e60d7SJames Wright for (int k=0; k<3; k++) 5252c4e60d7SJames Wright Flux[k+1] += (F_inviscid[j].momentum[k] - stress[k][j]) * norm[j]; 5262c4e60d7SJames Wright Flux[4] += (F_inviscid[j].E_total + Fe[j]) * norm[j]; 5272c4e60d7SJames Wright } 5282c4e60d7SJames Wright 52965dd5cafSJames Wright // -- Density 5302c4e60d7SJames Wright v[0][i] = -wdetJb * Flux[0]; 53165dd5cafSJames Wright 53265dd5cafSJames Wright // -- Momentum 53365dd5cafSJames Wright for (CeedInt j=0; j<3; j++) 5342c4e60d7SJames Wright v[j+1][i] = -wdetJb * Flux[j+1]; 53565dd5cafSJames Wright 53665dd5cafSJames Wright // -- Total Energy Density 5372c4e60d7SJames Wright v[4][i] = -wdetJb * Flux[4]; 538b55ac660SJames Wright 53957e55a1cSJames Wright if (context->is_primitive) { 54057e55a1cSJames Wright jac_data_sur[0][i] = s.Y.pressure; 54157e55a1cSJames Wright for (int j=0; j<3; j++) jac_data_sur[j+1][i] = s.Y.velocity[j]; 54257e55a1cSJames Wright jac_data_sur[4][i] = s.Y.temperature; 54357e55a1cSJames Wright } else { 544b55ac660SJames Wright jac_data_sur[0][i] = s.U.density; 54557e55a1cSJames Wright for (int j=0; j<3; j++) jac_data_sur[j+1][i] = s.U.momentum[j]; 546b55ac660SJames Wright jac_data_sur[4][i] = s.U.E_total; 54757e55a1cSJames Wright } 548b55ac660SJames Wright for (int j=0; j<6; j++) jac_data_sur[5+j][i] = kmstress[j]; 54965dd5cafSJames Wright } 55065dd5cafSJames Wright return 0; 55165dd5cafSJames Wright } 55265dd5cafSJames Wright 5532b89d87eSLeila Ghaffari // ***************************************************************************** 554b55ac660SJames Wright // Jacobian for "set nothing" boundary integral 5552b89d87eSLeila Ghaffari // ***************************************************************************** 556b55ac660SJames Wright CEED_QFUNCTION(BoundaryIntegral_Jacobian)(void *ctx, CeedInt Q, 557b55ac660SJames Wright const CeedScalar *const *in, 558b55ac660SJames Wright CeedScalar *const *out) { 559b55ac660SJames Wright // *INDENT-OFF* 560b55ac660SJames Wright // Inputs 561b55ac660SJames Wright const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 562b55ac660SJames Wright (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 563b55ac660SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 564b55ac660SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 565b55ac660SJames Wright (*jac_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 566b55ac660SJames Wright // Outputs 567b55ac660SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 568b55ac660SJames Wright // *INDENT-ON* 569b55ac660SJames Wright 570b55ac660SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 571b55ac660SJames Wright const bool implicit = context->is_implicit; 572efe9d856SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 573efe9d856SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 574efe9d856SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 575efe9d856SJames Wright State s, const CeedScalar dqi[5], 576efe9d856SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 577efe9d856SJames Wright StateFromQi = context->is_primitive ? &StateFromY : &StateFromU; 578efe9d856SJames Wright StateFromQi_fwd = context->is_primitive ? &StateFromY_fwd : &StateFromU_fwd; 579b55ac660SJames Wright 580b55ac660SJames Wright CeedPragmaSIMD 581b55ac660SJames Wright // Quadrature Point Loop 582b55ac660SJames Wright for (CeedInt i=0; i<Q; i++) { 583b55ac660SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 584b55ac660SJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 585b55ac660SJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 586b55ac660SJames Wright q_data_sur[2][i], 587b55ac660SJames Wright q_data_sur[3][i] 588b55ac660SJames Wright }; 589b55ac660SJames Wright const CeedScalar dXdx[2][3] = { 590b55ac660SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 591b55ac660SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 592b55ac660SJames Wright }; 593b55ac660SJames Wright 594efe9d856SJames Wright CeedScalar qi[5], kmstress[6], dqi[5], dx_i[3] = {0.}; 595efe9d856SJames Wright for (int j=0; j<5; j++) qi[j] = jac_data_sur[j][i]; 596b55ac660SJames Wright for (int j=0; j<6; j++) kmstress[j] = jac_data_sur[5+j][i]; 597efe9d856SJames Wright for (int j=0; j<5; j++) dqi[j] = dq[j][i]; 59857e55a1cSJames Wright 599efe9d856SJames Wright State s = StateFromQi(context, qi, x_i); 600efe9d856SJames Wright State ds = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 601b55ac660SJames Wright 602b55ac660SJames Wright State grad_ds[3]; 603b55ac660SJames Wright for (CeedInt j=0; j<3; j++) { 604efe9d856SJames Wright CeedScalar dx_i[3] = {0}, dqi_j[5]; 605b55ac660SJames Wright for (CeedInt k=0; k<5; k++) 606efe9d856SJames Wright dqi_j[k] = Grad_dq[0][k][i] * dXdx[0][j] + 607b55ac660SJames Wright Grad_dq[1][k][i] * dXdx[1][j]; 608b55ac660SJames Wright dx_i[j] = 1.; 609efe9d856SJames Wright grad_ds[j] = StateFromQi_fwd(context, s, dqi_j, x_i, dx_i); 610b55ac660SJames Wright } 611b55ac660SJames Wright 612b55ac660SJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 613b55ac660SJames Wright KMStrainRate(grad_ds, dstrain_rate); 614b55ac660SJames Wright NewtonianStress(context, dstrain_rate, dkmstress); 615b55ac660SJames Wright KMUnpack(dkmstress, dstress); 616b55ac660SJames Wright KMUnpack(kmstress, stress); 617b55ac660SJames Wright ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 618b55ac660SJames Wright 619b55ac660SJames Wright StateConservative dF_inviscid[3]; 620b55ac660SJames Wright FluxInviscid_fwd(context, s, ds, dF_inviscid); 621b55ac660SJames Wright 622b55ac660SJames Wright CeedScalar dFlux[5] = {0.}; 623b55ac660SJames Wright for (int j=0; j<3; j++) { 624b55ac660SJames Wright dFlux[0] += dF_inviscid[j].density * norm[j]; 625b55ac660SJames Wright for (int k=0; k<3; k++) 626b55ac660SJames Wright dFlux[k+1] += (dF_inviscid[j].momentum[k] - dstress[k][j]) * norm[j]; 627b55ac660SJames Wright dFlux[4] += (dF_inviscid[j].E_total + dFe[j]) * norm[j]; 628b55ac660SJames Wright } 629b55ac660SJames Wright 630b55ac660SJames Wright for (int j=0; j<5; j++) 631b55ac660SJames Wright v[j][i] = -wdetJb * dFlux[j]; 632b55ac660SJames Wright } // End Quadrature Point Loop 633b55ac660SJames Wright return 0; 634b55ac660SJames Wright } 635b55ac660SJames Wright 6362b89d87eSLeila Ghaffari // ***************************************************************************** 63730e9fa81SJames Wright // Outflow boundary condition, weakly setting a constant pressure 6382b89d87eSLeila Ghaffari // ***************************************************************************** 63930e9fa81SJames Wright CEED_QFUNCTION(PressureOutflow)(void *ctx, CeedInt Q, 64030e9fa81SJames Wright const CeedScalar *const *in, 64130e9fa81SJames Wright CeedScalar *const *out) { 64230e9fa81SJames Wright // *INDENT-OFF* 64330e9fa81SJames Wright // Inputs 64430e9fa81SJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 645ce9b5c20SJames Wright (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 646ce9b5c20SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 647ce9b5c20SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 64830e9fa81SJames Wright // Outputs 64930e9fa81SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 65030e9fa81SJames Wright (*jac_data_sur)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[1]; 65130e9fa81SJames Wright // *INDENT-ON* 65230e9fa81SJames Wright 65330e9fa81SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 65430e9fa81SJames Wright const bool implicit = context->is_implicit; 65530e9fa81SJames Wright const CeedScalar P0 = context->P0; 65630e9fa81SJames Wright 657efe9d856SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 658efe9d856SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 659efe9d856SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 660efe9d856SJames Wright State s, const CeedScalar dqi[5], 661efe9d856SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 662efe9d856SJames Wright StateFromQi = context->is_primitive ? &StateFromY : &StateFromU; 663efe9d856SJames Wright StateFromQi_fwd = context->is_primitive ? &StateFromY_fwd : &StateFromU_fwd; 664efe9d856SJames Wright 66530e9fa81SJames Wright CeedPragmaSIMD 66630e9fa81SJames Wright // Quadrature Point Loop 66730e9fa81SJames Wright for (CeedInt i=0; i<Q; i++) { 66830e9fa81SJames Wright // Setup 66930e9fa81SJames Wright // -- Interp in 670ce9b5c20SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 671efe9d856SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 672efe9d856SJames Wright State s = StateFromQi(context, qi, x_i); 673ce9b5c20SJames Wright s.Y.pressure = P0; 67430e9fa81SJames Wright 67530e9fa81SJames Wright // -- Interp-to-Interp q_data 67630e9fa81SJames Wright // For explicit mode, the surface integral is on the RHS of ODE q_dot = f(q). 67730e9fa81SJames Wright // For implicit mode, it gets pulled to the LHS of implicit ODE/DAE g(q_dot, q). 67830e9fa81SJames Wright // We can effect this by swapping the sign on this weight 67930e9fa81SJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 68030e9fa81SJames Wright 68130e9fa81SJames Wright // ---- Normal vect 68230e9fa81SJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 68330e9fa81SJames Wright q_data_sur[2][i], 68430e9fa81SJames Wright q_data_sur[3][i] 68530e9fa81SJames Wright }; 68630e9fa81SJames Wright 687ce9b5c20SJames Wright const CeedScalar dXdx[2][3] = { 688ce9b5c20SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 689ce9b5c20SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 690ce9b5c20SJames Wright }; 69130e9fa81SJames Wright 692ce9b5c20SJames Wright State grad_s[3]; 693ce9b5c20SJames Wright for (CeedInt j=0; j<3; j++) { 694efe9d856SJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 695ce9b5c20SJames Wright for (CeedInt k=0; k<5; k++) 696efe9d856SJames Wright dqi[k] = Grad_q[0][k][i] * dXdx[0][j] + 697ce9b5c20SJames Wright Grad_q[1][k][i] * dXdx[1][j]; 698ce9b5c20SJames Wright dx_i[j] = 1.; 699efe9d856SJames Wright grad_s[j] = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 700ce9b5c20SJames Wright } 701ce9b5c20SJames Wright 702ce9b5c20SJames Wright CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 703ce9b5c20SJames Wright KMStrainRate(grad_s, strain_rate); 704ce9b5c20SJames Wright NewtonianStress(context, strain_rate, kmstress); 705ce9b5c20SJames Wright KMUnpack(kmstress, stress); 706ce9b5c20SJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 707ce9b5c20SJames Wright 708ce9b5c20SJames Wright StateConservative F_inviscid[3]; 709ce9b5c20SJames Wright FluxInviscid(context, s, F_inviscid); 710ce9b5c20SJames Wright 711ce9b5c20SJames Wright CeedScalar Flux[5] = {0.}; 712ce9b5c20SJames Wright for (int j=0; j<3; j++) { 713ce9b5c20SJames Wright Flux[0] += F_inviscid[j].density * norm[j]; 714ce9b5c20SJames Wright for (int k=0; k<3; k++) 715ce9b5c20SJames Wright Flux[k+1] += (F_inviscid[j].momentum[k] - stress[k][j]) * norm[j]; 716ce9b5c20SJames Wright Flux[4] += (F_inviscid[j].E_total + Fe[j])*norm[j]; 717ce9b5c20SJames Wright } 71830e9fa81SJames Wright 71930e9fa81SJames Wright // -- Density 720ce9b5c20SJames Wright v[0][i] = -wdetJb * Flux[0]; 72130e9fa81SJames Wright 72230e9fa81SJames Wright // -- Momentum 72330e9fa81SJames Wright for (CeedInt j=0; j<3; j++) 724ce9b5c20SJames Wright v[j+1][i] = -wdetJb * Flux[j+1]; 72530e9fa81SJames Wright 72630e9fa81SJames Wright // -- Total Energy Density 727ce9b5c20SJames Wright v[4][i] = -wdetJb * Flux[4]; 72830e9fa81SJames Wright 72930e9fa81SJames Wright // Save values for Jacobian 73057e55a1cSJames Wright if (context->is_primitive) { 73157e55a1cSJames Wright jac_data_sur[0][i] = s.Y.pressure; 73257e55a1cSJames Wright for (int j=0; j<3; j++) jac_data_sur[j+1][i] = s.Y.velocity[j]; 73357e55a1cSJames Wright jac_data_sur[4][i] = s.Y.temperature; 73457e55a1cSJames Wright } else { 735ce9b5c20SJames Wright jac_data_sur[0][i] = s.U.density; 73657e55a1cSJames Wright for (int j=0; j<3; j++) jac_data_sur[j+1][i] = s.U.momentum[j]; 737ce9b5c20SJames Wright jac_data_sur[4][i] = s.U.E_total; 73857e55a1cSJames Wright } 7390ec2498eSJames Wright for (int j=0; j<6; j++) jac_data_sur[5+j][i] = kmstress[j]; 74030e9fa81SJames Wright } // End Quadrature Point Loop 74130e9fa81SJames Wright return 0; 74230e9fa81SJames Wright } 74330e9fa81SJames Wright 7442b89d87eSLeila Ghaffari // ***************************************************************************** 74530e9fa81SJames Wright // Jacobian for weak-pressure outflow boundary condition 7462b89d87eSLeila Ghaffari // ***************************************************************************** 74730e9fa81SJames Wright CEED_QFUNCTION(PressureOutflow_Jacobian)(void *ctx, CeedInt Q, 748efe9d856SJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 74930e9fa81SJames Wright // *INDENT-OFF* 75030e9fa81SJames Wright // Inputs 75130e9fa81SJames Wright const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 7520ec2498eSJames Wright (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 7530ec2498eSJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 7540ec2498eSJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 7550ec2498eSJames Wright (*jac_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 75630e9fa81SJames Wright // Outputs 75730e9fa81SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 75830e9fa81SJames Wright // *INDENT-ON* 75930e9fa81SJames Wright 76030e9fa81SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 76130e9fa81SJames Wright const bool implicit = context->is_implicit; 76230e9fa81SJames Wright 763efe9d856SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 764efe9d856SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 765efe9d856SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 766efe9d856SJames Wright State s, const CeedScalar dQi[5], 767efe9d856SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 768efe9d856SJames Wright StateFromQi = context->is_primitive ? &StateFromY : &StateFromU; 769efe9d856SJames Wright StateFromQi_fwd = context->is_primitive ? &StateFromY_fwd : &StateFromU_fwd; 770efe9d856SJames Wright 77130e9fa81SJames Wright CeedPragmaSIMD 77230e9fa81SJames Wright // Quadrature Point Loop 77330e9fa81SJames Wright for (CeedInt i=0; i<Q; i++) { 7740ec2498eSJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 77530e9fa81SJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 77630e9fa81SJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 77730e9fa81SJames Wright q_data_sur[2][i], 77830e9fa81SJames Wright q_data_sur[3][i] 77930e9fa81SJames Wright }; 7800ec2498eSJames Wright const CeedScalar dXdx[2][3] = { 7810ec2498eSJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 7820ec2498eSJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 7830ec2498eSJames Wright }; 7840ec2498eSJames Wright 785efe9d856SJames Wright CeedScalar qi[5], kmstress[6], dqi[5], dx_i[3] = {0.}; 786efe9d856SJames Wright for (int j=0; j<5; j++) qi[j] = jac_data_sur[j][i]; 7870ec2498eSJames Wright for (int j=0; j<6; j++) kmstress[j] = jac_data_sur[5+j][i]; 788efe9d856SJames Wright for (int j=0; j<5; j++) dqi[j] = dq[j][i]; 78957e55a1cSJames Wright 790efe9d856SJames Wright State s = StateFromQi(context, qi, x_i); 791efe9d856SJames Wright State ds = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 7920ec2498eSJames Wright s.Y.pressure = context->P0; 7930ec2498eSJames Wright ds.Y.pressure = 0.; 7940ec2498eSJames Wright 7950ec2498eSJames Wright State grad_ds[3]; 7960ec2498eSJames Wright for (CeedInt j=0; j<3; j++) { 797efe9d856SJames Wright CeedScalar dx_i[3] = {0}, dqi_j[5]; 7980ec2498eSJames Wright for (CeedInt k=0; k<5; k++) 799efe9d856SJames Wright dqi_j[k] = Grad_dq[0][k][i] * dXdx[0][j] + 8000ec2498eSJames Wright Grad_dq[1][k][i] * dXdx[1][j]; 8010ec2498eSJames Wright dx_i[j] = 1.; 802efe9d856SJames Wright grad_ds[j] = StateFromQi_fwd(context, s, dqi_j, x_i, dx_i); 8030ec2498eSJames Wright } 8040ec2498eSJames Wright 8050ec2498eSJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 8060ec2498eSJames Wright KMStrainRate(grad_ds, dstrain_rate); 8070ec2498eSJames Wright NewtonianStress(context, dstrain_rate, dkmstress); 8080ec2498eSJames Wright KMUnpack(dkmstress, dstress); 8090ec2498eSJames Wright KMUnpack(kmstress, stress); 8100ec2498eSJames Wright ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 81130e9fa81SJames Wright 812b5d317f8SJames Wright StateConservative dF_inviscid[3]; 813b5d317f8SJames Wright FluxInviscid_fwd(context, s, ds, dF_inviscid); 81430e9fa81SJames Wright 815b5d317f8SJames Wright CeedScalar dFlux[5] = {0.}; 816b5d317f8SJames Wright for (int j=0; j<3; j++) { 817b5d317f8SJames Wright dFlux[0] += dF_inviscid[j].density * norm[j]; 818b5d317f8SJames Wright for (int k=0; k<3; k++) 8190ec2498eSJames Wright dFlux[k+1] += (dF_inviscid[j].momentum[k] - dstress[k][j]) * norm[j]; 8200ec2498eSJames Wright dFlux[4] += (dF_inviscid[j].E_total + dFe[j]) * norm[j]; 821b5d317f8SJames Wright } 822b5d317f8SJames Wright 823b5d317f8SJames Wright for (int j=0; j<5; j++) 824b5d317f8SJames Wright v[j][i] = -wdetJb * dFlux[j]; 82530e9fa81SJames Wright } // End Quadrature Point Loop 82630e9fa81SJames Wright return 0; 82730e9fa81SJames Wright } 82830e9fa81SJames Wright 82988b783a1SJames Wright // ***************************************************************************** 830dc805cc4SLeila Ghaffari // This QFunction implements the Navier-Stokes equations (mentioned above) in 831dc805cc4SLeila Ghaffari // primitive variables and with implicit time stepping method 832dc805cc4SLeila Ghaffari // 833dc805cc4SLeila Ghaffari // ***************************************************************************** 834dc805cc4SLeila Ghaffari CEED_QFUNCTION(IFunction_Newtonian_Prim)(void *ctx, CeedInt Q, 835dc805cc4SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 836dc805cc4SLeila Ghaffari // *INDENT-OFF* 837dc805cc4SLeila Ghaffari // Inputs 838dc805cc4SLeila Ghaffari const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 839dc805cc4SLeila Ghaffari (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 840dc805cc4SLeila Ghaffari (*q_dot)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 841dc805cc4SLeila Ghaffari (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 842dc805cc4SLeila Ghaffari (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 843dc805cc4SLeila Ghaffari // Outputs 844dc805cc4SLeila Ghaffari CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 845dc805cc4SLeila Ghaffari (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1], 846dc805cc4SLeila Ghaffari (*jac_data)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[2]; 847dc805cc4SLeila Ghaffari // *INDENT-ON* 848dc805cc4SLeila Ghaffari // Context 849dc805cc4SLeila Ghaffari NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 850dc805cc4SLeila Ghaffari const CeedScalar *g = context->g; 851dc805cc4SLeila Ghaffari const CeedScalar dt = context->dt; 852dc805cc4SLeila Ghaffari 853dc805cc4SLeila Ghaffari CeedPragmaSIMD 854dc805cc4SLeila Ghaffari // Quadrature Point Loop 855dc805cc4SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 856dc805cc4SLeila Ghaffari CeedScalar Y[5]; 857dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) Y[j] = q[j][i]; 858dc805cc4SLeila Ghaffari const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 859dc805cc4SLeila Ghaffari State s = StateFromY(context, Y, x_i); 860dc805cc4SLeila Ghaffari 861dc805cc4SLeila Ghaffari // -- Interp-to-Interp q_data 862dc805cc4SLeila Ghaffari const CeedScalar wdetJ = q_data[0][i]; 863dc805cc4SLeila Ghaffari // -- Interp-to-Grad q_data 864dc805cc4SLeila Ghaffari // ---- Inverse of change of coordinate matrix: X_i,j 865dc805cc4SLeila Ghaffari // *INDENT-OFF* 866dc805cc4SLeila Ghaffari const CeedScalar dXdx[3][3] = {{q_data[1][i], 867dc805cc4SLeila Ghaffari q_data[2][i], 868dc805cc4SLeila Ghaffari q_data[3][i]}, 869dc805cc4SLeila Ghaffari {q_data[4][i], 870dc805cc4SLeila Ghaffari q_data[5][i], 871dc805cc4SLeila Ghaffari q_data[6][i]}, 872dc805cc4SLeila Ghaffari {q_data[7][i], 873dc805cc4SLeila Ghaffari q_data[8][i], 874dc805cc4SLeila Ghaffari q_data[9][i]} 875dc805cc4SLeila Ghaffari }; 876dc805cc4SLeila Ghaffari // *INDENT-ON* 877dc805cc4SLeila Ghaffari State grad_s[3]; 878dc805cc4SLeila Ghaffari for (CeedInt j=0; j<3; j++) { 879dc805cc4SLeila Ghaffari CeedScalar dx_i[3] = {0}, dY[5]; 880dc805cc4SLeila Ghaffari for (CeedInt k=0; k<5; k++) 881dc805cc4SLeila Ghaffari dY[k] = Grad_q[0][k][i] * dXdx[0][j] + 882dc805cc4SLeila Ghaffari Grad_q[1][k][i] * dXdx[1][j] + 883dc805cc4SLeila Ghaffari Grad_q[2][k][i] * dXdx[2][j]; 884dc805cc4SLeila Ghaffari dx_i[j] = 1.; 885dc805cc4SLeila Ghaffari grad_s[j] = StateFromY_fwd(context, s, dY, x_i, dx_i); 886dc805cc4SLeila Ghaffari } 887dc805cc4SLeila Ghaffari 888dc805cc4SLeila Ghaffari CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 889dc805cc4SLeila Ghaffari KMStrainRate(grad_s, strain_rate); 890dc805cc4SLeila Ghaffari NewtonianStress(context, strain_rate, kmstress); 891dc805cc4SLeila Ghaffari KMUnpack(kmstress, stress); 892dc805cc4SLeila Ghaffari ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 893dc805cc4SLeila Ghaffari 894dc805cc4SLeila Ghaffari StateConservative F_inviscid[3]; 895dc805cc4SLeila Ghaffari FluxInviscid(context, s, F_inviscid); 896dc805cc4SLeila Ghaffari 897dc805cc4SLeila Ghaffari // Total flux 898dc805cc4SLeila Ghaffari CeedScalar Flux[5][3]; 8992b89d87eSLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 900dc805cc4SLeila Ghaffari 9012b89d87eSLeila Ghaffari for (CeedInt j=0; j<3; j++) 9022b89d87eSLeila Ghaffari for (CeedInt k=0; k<5; k++) 903dc805cc4SLeila Ghaffari Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * Flux[k][0] + 904dc805cc4SLeila Ghaffari dXdx[j][1] * Flux[k][1] + 905dc805cc4SLeila Ghaffari dXdx[j][2] * Flux[k][2]); 906dc805cc4SLeila Ghaffari 907dc805cc4SLeila Ghaffari const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 908dc805cc4SLeila Ghaffari 909dc805cc4SLeila Ghaffari CeedScalar Y_dot[5], dx0[3] = {0}; 910dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) Y_dot[j] = q_dot[j][i]; 911dc805cc4SLeila Ghaffari State s_dot = StateFromY_fwd(context, s, Y_dot, x_i, dx0); 912dc805cc4SLeila Ghaffari 913dc805cc4SLeila Ghaffari CeedScalar U_dot[5] = {0.}; 9142b89d87eSLeila Ghaffari UnpackState_U(s_dot.U, U_dot); 915dc805cc4SLeila Ghaffari 916dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) 917dc805cc4SLeila Ghaffari v[j][i] = wdetJ * (U_dot[j] - body_force[j]); 918dc805cc4SLeila Ghaffari 9192b89d87eSLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 9202b89d87eSLeila Ghaffari CeedScalar Tau_d[3], stab[5][3]; 9212b89d87eSLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 9222b89d87eSLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 923dc805cc4SLeila Ghaffari 924dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) 925dc805cc4SLeila Ghaffari for (CeedInt k=0; k<3; k++) 926dc805cc4SLeila Ghaffari Grad_v[k][j][i] += wdetJ*(stab[j][0] * dXdx[k][0] + 927dc805cc4SLeila Ghaffari stab[j][1] * dXdx[k][1] + 928dc805cc4SLeila Ghaffari stab[j][2] * dXdx[k][2]); 929dc805cc4SLeila Ghaffari 930dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) jac_data[j][i] = Y[j]; 931dc805cc4SLeila Ghaffari for (CeedInt j=0; j<6; j++) jac_data[5+j][i] = kmstress[j]; 932dc805cc4SLeila Ghaffari for (CeedInt j=0; j<3; j++) jac_data[5+6+j][i] = Tau_d[j]; 933dc805cc4SLeila Ghaffari 934dc805cc4SLeila Ghaffari } // End Quadrature Point Loop 935dc805cc4SLeila Ghaffari 936dc805cc4SLeila Ghaffari // Return 937dc805cc4SLeila Ghaffari return 0; 938dc805cc4SLeila Ghaffari } 939dc805cc4SLeila Ghaffari 940dc805cc4SLeila Ghaffari // ***************************************************************************** 941dc805cc4SLeila Ghaffari // This QFunction implements the jacobean of the Navier-Stokes equations 942dc805cc4SLeila Ghaffari // in primitive variables for implicit time stepping method. 943dc805cc4SLeila Ghaffari // 944dc805cc4SLeila Ghaffari // ***************************************************************************** 945dc805cc4SLeila Ghaffari CEED_QFUNCTION(IJacobian_Newtonian_Prim)(void *ctx, CeedInt Q, 946dc805cc4SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 947dc805cc4SLeila Ghaffari // *INDENT-OFF* 948dc805cc4SLeila Ghaffari // Inputs 949dc805cc4SLeila Ghaffari const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 950dc805cc4SLeila Ghaffari (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 951dc805cc4SLeila Ghaffari (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 952dc805cc4SLeila Ghaffari (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 953dc805cc4SLeila Ghaffari (*jac_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 954dc805cc4SLeila Ghaffari // Outputs 955dc805cc4SLeila Ghaffari CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 956dc805cc4SLeila Ghaffari (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1]; 957dc805cc4SLeila Ghaffari // *INDENT-ON* 958dc805cc4SLeila Ghaffari // Context 959dc805cc4SLeila Ghaffari NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 960dc805cc4SLeila Ghaffari const CeedScalar *g = context->g; 961dc805cc4SLeila Ghaffari 962dc805cc4SLeila Ghaffari CeedPragmaSIMD 963dc805cc4SLeila Ghaffari // Quadrature Point Loop 964dc805cc4SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 965dc805cc4SLeila Ghaffari // -- Interp-to-Interp q_data 966dc805cc4SLeila Ghaffari const CeedScalar wdetJ = q_data[0][i]; 967dc805cc4SLeila Ghaffari // -- Interp-to-Grad q_data 968dc805cc4SLeila Ghaffari // ---- Inverse of change of coordinate matrix: X_i,j 969dc805cc4SLeila Ghaffari // *INDENT-OFF* 970dc805cc4SLeila Ghaffari const CeedScalar dXdx[3][3] = {{q_data[1][i], 971dc805cc4SLeila Ghaffari q_data[2][i], 972dc805cc4SLeila Ghaffari q_data[3][i]}, 973dc805cc4SLeila Ghaffari {q_data[4][i], 974dc805cc4SLeila Ghaffari q_data[5][i], 975dc805cc4SLeila Ghaffari q_data[6][i]}, 976dc805cc4SLeila Ghaffari {q_data[7][i], 977dc805cc4SLeila Ghaffari q_data[8][i], 978dc805cc4SLeila Ghaffari q_data[9][i]} 979dc805cc4SLeila Ghaffari }; 980dc805cc4SLeila Ghaffari // *INDENT-ON* 981dc805cc4SLeila Ghaffari 982dc805cc4SLeila Ghaffari CeedScalar Y[5], kmstress[6], Tau_d[3] __attribute((unused)); 983dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) Y[j] = jac_data[j][i]; 984dc805cc4SLeila Ghaffari for (int j=0; j<6; j++) kmstress[j] = jac_data[5+j][i]; 985dc805cc4SLeila Ghaffari for (int j=0; j<3; j++) Tau_d[j] = jac_data[5+6+j][i]; 986dc805cc4SLeila Ghaffari const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 987dc805cc4SLeila Ghaffari State s = StateFromY(context, Y, x_i); 988dc805cc4SLeila Ghaffari 989dc805cc4SLeila Ghaffari CeedScalar dY[5], dx0[3] = {0}; 990dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) dY[j] = dq[j][i]; 991dc805cc4SLeila Ghaffari State ds = StateFromY_fwd(context, s, dY, x_i, dx0); 992dc805cc4SLeila Ghaffari 993dc805cc4SLeila Ghaffari State grad_ds[3]; 994dc805cc4SLeila Ghaffari for (int j=0; j<3; j++) { 995dc805cc4SLeila Ghaffari CeedScalar dYj[5]; 996dc805cc4SLeila Ghaffari for (int k=0; k<5; k++) 997dc805cc4SLeila Ghaffari dYj[k] = Grad_dq[0][k][i] * dXdx[0][j] + 998dc805cc4SLeila Ghaffari Grad_dq[1][k][i] * dXdx[1][j] + 999dc805cc4SLeila Ghaffari Grad_dq[2][k][i] * dXdx[2][j]; 1000dc805cc4SLeila Ghaffari grad_ds[j] = StateFromY_fwd(context, s, dYj, x_i, dx0); 1001dc805cc4SLeila Ghaffari } 1002dc805cc4SLeila Ghaffari 1003dc805cc4SLeila Ghaffari CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 1004dc805cc4SLeila Ghaffari KMStrainRate(grad_ds, dstrain_rate); 1005dc805cc4SLeila Ghaffari NewtonianStress(context, dstrain_rate, dkmstress); 1006dc805cc4SLeila Ghaffari KMUnpack(dkmstress, dstress); 1007dc805cc4SLeila Ghaffari KMUnpack(kmstress, stress); 1008dc805cc4SLeila Ghaffari ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 1009dc805cc4SLeila Ghaffari 1010dc805cc4SLeila Ghaffari StateConservative dF_inviscid[3]; 1011dc805cc4SLeila Ghaffari FluxInviscid_fwd(context, s, ds, dF_inviscid); 1012dc805cc4SLeila Ghaffari 1013dc805cc4SLeila Ghaffari // Total flux 1014dc805cc4SLeila Ghaffari CeedScalar dFlux[5][3]; 10152b89d87eSLeila Ghaffari FluxTotal(dF_inviscid, dstress, dFe, dFlux); 1016dc805cc4SLeila Ghaffari 10172b89d87eSLeila Ghaffari for (int j=0; j<3; j++) 10182b89d87eSLeila Ghaffari for (int k=0; k<5; k++) 1019dc805cc4SLeila Ghaffari Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * dFlux[k][0] + 1020dc805cc4SLeila Ghaffari dXdx[j][1] * dFlux[k][1] + 1021dc805cc4SLeila Ghaffari dXdx[j][2] * dFlux[k][2]); 1022dc805cc4SLeila Ghaffari 10232b89d87eSLeila Ghaffari const CeedScalar dbody_force[5] = {0, ds.U.density *g[0], ds.U.density *g[1], ds.U.density *g[2], 0}; 1024dc805cc4SLeila Ghaffari CeedScalar dU[5] = {0.}; 10252b89d87eSLeila Ghaffari UnpackState_U(ds.U, dU); 1026dc805cc4SLeila Ghaffari 1027dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) 1028dc805cc4SLeila Ghaffari v[j][i] = wdetJ * (context->ijacobian_time_shift * dU[j] - dbody_force[j]); 1029dc805cc4SLeila Ghaffari 10302b89d87eSLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 10312b89d87eSLeila Ghaffari CeedScalar dstab[5][3], U_dot[5] = {0}; 10322b89d87eSLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = context->ijacobian_time_shift * dU[j]; 10332b89d87eSLeila Ghaffari Stabilization(context, s, Tau_d, grad_ds, U_dot, dbody_force, x_i, dstab); 1034dc805cc4SLeila Ghaffari 1035dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) 1036dc805cc4SLeila Ghaffari for (int k=0; k<3; k++) 1037dc805cc4SLeila Ghaffari Grad_v[k][j][i] += wdetJ*(dstab[j][0] * dXdx[k][0] + 1038dc805cc4SLeila Ghaffari dstab[j][1] * dXdx[k][1] + 1039dc805cc4SLeila Ghaffari dstab[j][2] * dXdx[k][2]); 1040dc805cc4SLeila Ghaffari 1041dc805cc4SLeila Ghaffari } // End Quadrature Point Loop 1042dc805cc4SLeila Ghaffari return 0; 1043dc805cc4SLeila Ghaffari } 1044dc805cc4SLeila Ghaffari // ***************************************************************************** 1045dc805cc4SLeila Ghaffari 104688b783a1SJames Wright #endif // newtonian_h 1047