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* 18223d6ba15SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 18323d6ba15SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 18423d6ba15SJames 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* 27923d6ba15SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 28023d6ba15SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 28123d6ba15SJames 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* 37123d6ba15SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 37223d6ba15SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 37323d6ba15SJames 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]); 46223d6ba15SJames Wright StateFromQi = context->use_primitive ? &StateFromY : &StateFromU; 46323d6ba15SJames 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]; 473*5bce47c7SJames Wright // ---- Normal vector 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 503*5bce47c7SJames Wright CeedScalar Flux[5]; 504*5bce47c7SJames Wright FluxTotal_Boundary(F_inviscid, stress, Fe, norm, Flux); 5052c4e60d7SJames Wright 506*5bce47c7SJames Wright for (CeedInt j=0; j<5; j++) v[j][i] = -wdetJb * Flux[j]; 50765dd5cafSJames Wright 508*5bce47c7SJames Wright for (int j=0; j<5; j++) jac_data_sur[j][i] = qi[j]; 509b55ac660SJames Wright for (int j=0; j<6; j++) jac_data_sur[5+j][i] = kmstress[j]; 51065dd5cafSJames Wright } 51165dd5cafSJames Wright return 0; 51265dd5cafSJames Wright } 51365dd5cafSJames Wright 5142b89d87eSLeila Ghaffari // ***************************************************************************** 515b55ac660SJames Wright // Jacobian for "set nothing" boundary integral 5162b89d87eSLeila Ghaffari // ***************************************************************************** 517b55ac660SJames Wright CEED_QFUNCTION(BoundaryIntegral_Jacobian)(void *ctx, CeedInt Q, 518b55ac660SJames Wright const CeedScalar *const *in, 519b55ac660SJames Wright CeedScalar *const *out) { 520b55ac660SJames Wright // *INDENT-OFF* 521b55ac660SJames Wright // Inputs 522b55ac660SJames Wright const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 523b55ac660SJames Wright (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 524b55ac660SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 525b55ac660SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 526b55ac660SJames Wright (*jac_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 527b55ac660SJames Wright // Outputs 528b55ac660SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 529b55ac660SJames Wright // *INDENT-ON* 530b55ac660SJames Wright 531b55ac660SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 532b55ac660SJames Wright const bool implicit = context->is_implicit; 533efe9d856SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 534efe9d856SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 535efe9d856SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 536efe9d856SJames Wright State s, const CeedScalar dqi[5], 537efe9d856SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 53823d6ba15SJames Wright StateFromQi = context->use_primitive ? &StateFromY : &StateFromU; 53923d6ba15SJames Wright StateFromQi_fwd = context->use_primitive ? &StateFromY_fwd : &StateFromU_fwd; 540b55ac660SJames Wright 541b55ac660SJames Wright CeedPragmaSIMD 542b55ac660SJames Wright // Quadrature Point Loop 543b55ac660SJames Wright for (CeedInt i=0; i<Q; i++) { 544b55ac660SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 545b55ac660SJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 546b55ac660SJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 547b55ac660SJames Wright q_data_sur[2][i], 548b55ac660SJames Wright q_data_sur[3][i] 549b55ac660SJames Wright }; 550b55ac660SJames Wright const CeedScalar dXdx[2][3] = { 551b55ac660SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 552b55ac660SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 553b55ac660SJames Wright }; 554b55ac660SJames Wright 555efe9d856SJames Wright CeedScalar qi[5], kmstress[6], dqi[5], dx_i[3] = {0.}; 556efe9d856SJames Wright for (int j=0; j<5; j++) qi[j] = jac_data_sur[j][i]; 557b55ac660SJames Wright for (int j=0; j<6; j++) kmstress[j] = jac_data_sur[5+j][i]; 558efe9d856SJames Wright for (int j=0; j<5; j++) dqi[j] = dq[j][i]; 55957e55a1cSJames Wright 560efe9d856SJames Wright State s = StateFromQi(context, qi, x_i); 561efe9d856SJames Wright State ds = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 562b55ac660SJames Wright 563b55ac660SJames Wright State grad_ds[3]; 564b55ac660SJames Wright for (CeedInt j=0; j<3; j++) { 565efe9d856SJames Wright CeedScalar dx_i[3] = {0}, dqi_j[5]; 566b55ac660SJames Wright for (CeedInt k=0; k<5; k++) 567efe9d856SJames Wright dqi_j[k] = Grad_dq[0][k][i] * dXdx[0][j] + 568b55ac660SJames Wright Grad_dq[1][k][i] * dXdx[1][j]; 569b55ac660SJames Wright dx_i[j] = 1.; 570efe9d856SJames Wright grad_ds[j] = StateFromQi_fwd(context, s, dqi_j, x_i, dx_i); 571b55ac660SJames Wright } 572b55ac660SJames Wright 573b55ac660SJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 574b55ac660SJames Wright KMStrainRate(grad_ds, dstrain_rate); 575b55ac660SJames Wright NewtonianStress(context, dstrain_rate, dkmstress); 576b55ac660SJames Wright KMUnpack(dkmstress, dstress); 577b55ac660SJames Wright KMUnpack(kmstress, stress); 578b55ac660SJames Wright ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 579b55ac660SJames Wright 580b55ac660SJames Wright StateConservative dF_inviscid[3]; 581b55ac660SJames Wright FluxInviscid_fwd(context, s, ds, dF_inviscid); 582b55ac660SJames Wright 583*5bce47c7SJames Wright CeedScalar dFlux[5]; 584*5bce47c7SJames Wright FluxTotal_Boundary(dF_inviscid, dstress, dFe, norm, dFlux); 585b55ac660SJames Wright 586*5bce47c7SJames Wright for (int j=0; j<5; j++) v[j][i] = -wdetJb * dFlux[j]; 587b55ac660SJames Wright } // End Quadrature Point Loop 588b55ac660SJames Wright return 0; 589b55ac660SJames Wright } 590b55ac660SJames Wright 5912b89d87eSLeila Ghaffari // ***************************************************************************** 59230e9fa81SJames Wright // Outflow boundary condition, weakly setting a constant pressure 5932b89d87eSLeila Ghaffari // ***************************************************************************** 59430e9fa81SJames Wright CEED_QFUNCTION(PressureOutflow)(void *ctx, CeedInt Q, 59530e9fa81SJames Wright const CeedScalar *const *in, 59630e9fa81SJames Wright CeedScalar *const *out) { 59730e9fa81SJames Wright // *INDENT-OFF* 59830e9fa81SJames Wright // Inputs 59930e9fa81SJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 600ce9b5c20SJames Wright (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 601ce9b5c20SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 602ce9b5c20SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 60330e9fa81SJames Wright // Outputs 60430e9fa81SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 60530e9fa81SJames Wright (*jac_data_sur)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[1]; 60630e9fa81SJames Wright // *INDENT-ON* 60730e9fa81SJames Wright 60830e9fa81SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 60930e9fa81SJames Wright const bool implicit = context->is_implicit; 61030e9fa81SJames Wright const CeedScalar P0 = context->P0; 61130e9fa81SJames Wright 612efe9d856SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 613efe9d856SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 614efe9d856SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 615efe9d856SJames Wright State s, const CeedScalar dqi[5], 616efe9d856SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 61723d6ba15SJames Wright StateFromQi = context->use_primitive ? &StateFromY : &StateFromU; 61823d6ba15SJames Wright StateFromQi_fwd = context->use_primitive ? &StateFromY_fwd : &StateFromU_fwd; 619efe9d856SJames Wright 62030e9fa81SJames Wright CeedPragmaSIMD 62130e9fa81SJames Wright // Quadrature Point Loop 62230e9fa81SJames Wright for (CeedInt i=0; i<Q; i++) { 62330e9fa81SJames Wright // Setup 62430e9fa81SJames Wright // -- Interp in 625ce9b5c20SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 626efe9d856SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 627efe9d856SJames Wright State s = StateFromQi(context, qi, x_i); 628ce9b5c20SJames Wright s.Y.pressure = P0; 62930e9fa81SJames Wright 63030e9fa81SJames Wright // -- Interp-to-Interp q_data 63130e9fa81SJames Wright // For explicit mode, the surface integral is on the RHS of ODE q_dot = f(q). 63230e9fa81SJames Wright // For implicit mode, it gets pulled to the LHS of implicit ODE/DAE g(q_dot, q). 63330e9fa81SJames Wright // We can effect this by swapping the sign on this weight 63430e9fa81SJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 63530e9fa81SJames Wright 636*5bce47c7SJames Wright // ---- Normal vector 63730e9fa81SJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 63830e9fa81SJames Wright q_data_sur[2][i], 63930e9fa81SJames Wright q_data_sur[3][i] 64030e9fa81SJames Wright }; 64130e9fa81SJames Wright 642ce9b5c20SJames Wright const CeedScalar dXdx[2][3] = { 643ce9b5c20SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 644ce9b5c20SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 645ce9b5c20SJames Wright }; 64630e9fa81SJames Wright 647ce9b5c20SJames Wright State grad_s[3]; 648ce9b5c20SJames Wright for (CeedInt j=0; j<3; j++) { 649efe9d856SJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 650ce9b5c20SJames Wright for (CeedInt k=0; k<5; k++) 651efe9d856SJames Wright dqi[k] = Grad_q[0][k][i] * dXdx[0][j] + 652ce9b5c20SJames Wright Grad_q[1][k][i] * dXdx[1][j]; 653ce9b5c20SJames Wright dx_i[j] = 1.; 654efe9d856SJames Wright grad_s[j] = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 655ce9b5c20SJames Wright } 656ce9b5c20SJames Wright 657ce9b5c20SJames Wright CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 658ce9b5c20SJames Wright KMStrainRate(grad_s, strain_rate); 659ce9b5c20SJames Wright NewtonianStress(context, strain_rate, kmstress); 660ce9b5c20SJames Wright KMUnpack(kmstress, stress); 661ce9b5c20SJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 662ce9b5c20SJames Wright 663ce9b5c20SJames Wright StateConservative F_inviscid[3]; 664ce9b5c20SJames Wright FluxInviscid(context, s, F_inviscid); 665ce9b5c20SJames Wright 666*5bce47c7SJames Wright CeedScalar Flux[5]; 667*5bce47c7SJames Wright FluxTotal_Boundary(F_inviscid, stress, Fe, norm, Flux); 66830e9fa81SJames Wright 669*5bce47c7SJames Wright for (CeedInt j=0; j<5; j++) v[j][i] = -wdetJb * Flux[j]; 67030e9fa81SJames Wright 67130e9fa81SJames Wright // Save values for Jacobian 672*5bce47c7SJames Wright for (int j=0; j<5; j++) jac_data_sur[j][i] = qi[j]; 6730ec2498eSJames Wright for (int j=0; j<6; j++) jac_data_sur[5+j][i] = kmstress[j]; 67430e9fa81SJames Wright } // End Quadrature Point Loop 67530e9fa81SJames Wright return 0; 67630e9fa81SJames Wright } 67730e9fa81SJames Wright 6782b89d87eSLeila Ghaffari // ***************************************************************************** 67930e9fa81SJames Wright // Jacobian for weak-pressure outflow boundary condition 6802b89d87eSLeila Ghaffari // ***************************************************************************** 68130e9fa81SJames Wright CEED_QFUNCTION(PressureOutflow_Jacobian)(void *ctx, CeedInt Q, 682efe9d856SJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 68330e9fa81SJames Wright // *INDENT-OFF* 68430e9fa81SJames Wright // Inputs 68530e9fa81SJames Wright const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 6860ec2498eSJames Wright (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 6870ec2498eSJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 6880ec2498eSJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 6890ec2498eSJames Wright (*jac_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 69030e9fa81SJames Wright // Outputs 69130e9fa81SJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 69230e9fa81SJames Wright // *INDENT-ON* 69330e9fa81SJames Wright 69430e9fa81SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 69530e9fa81SJames Wright const bool implicit = context->is_implicit; 69630e9fa81SJames Wright 697efe9d856SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 698efe9d856SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 699efe9d856SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 700efe9d856SJames Wright State s, const CeedScalar dQi[5], 701efe9d856SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 70223d6ba15SJames Wright StateFromQi = context->use_primitive ? &StateFromY : &StateFromU; 70323d6ba15SJames Wright StateFromQi_fwd = context->use_primitive ? &StateFromY_fwd : &StateFromU_fwd; 704efe9d856SJames Wright 70530e9fa81SJames Wright CeedPragmaSIMD 70630e9fa81SJames Wright // Quadrature Point Loop 70730e9fa81SJames Wright for (CeedInt i=0; i<Q; i++) { 7080ec2498eSJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 70930e9fa81SJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 71030e9fa81SJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 71130e9fa81SJames Wright q_data_sur[2][i], 71230e9fa81SJames Wright q_data_sur[3][i] 71330e9fa81SJames Wright }; 7140ec2498eSJames Wright const CeedScalar dXdx[2][3] = { 7150ec2498eSJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 7160ec2498eSJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 7170ec2498eSJames Wright }; 7180ec2498eSJames Wright 719efe9d856SJames Wright CeedScalar qi[5], kmstress[6], dqi[5], dx_i[3] = {0.}; 720efe9d856SJames Wright for (int j=0; j<5; j++) qi[j] = jac_data_sur[j][i]; 7210ec2498eSJames Wright for (int j=0; j<6; j++) kmstress[j] = jac_data_sur[5+j][i]; 722efe9d856SJames Wright for (int j=0; j<5; j++) dqi[j] = dq[j][i]; 72357e55a1cSJames Wright 724efe9d856SJames Wright State s = StateFromQi(context, qi, x_i); 725efe9d856SJames Wright State ds = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 7260ec2498eSJames Wright s.Y.pressure = context->P0; 7270ec2498eSJames Wright ds.Y.pressure = 0.; 7280ec2498eSJames Wright 7290ec2498eSJames Wright State grad_ds[3]; 7300ec2498eSJames Wright for (CeedInt j=0; j<3; j++) { 731efe9d856SJames Wright CeedScalar dx_i[3] = {0}, dqi_j[5]; 7320ec2498eSJames Wright for (CeedInt k=0; k<5; k++) 733efe9d856SJames Wright dqi_j[k] = Grad_dq[0][k][i] * dXdx[0][j] + 7340ec2498eSJames Wright Grad_dq[1][k][i] * dXdx[1][j]; 7350ec2498eSJames Wright dx_i[j] = 1.; 736efe9d856SJames Wright grad_ds[j] = StateFromQi_fwd(context, s, dqi_j, x_i, dx_i); 7370ec2498eSJames Wright } 7380ec2498eSJames Wright 7390ec2498eSJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 7400ec2498eSJames Wright KMStrainRate(grad_ds, dstrain_rate); 7410ec2498eSJames Wright NewtonianStress(context, dstrain_rate, dkmstress); 7420ec2498eSJames Wright KMUnpack(dkmstress, dstress); 7430ec2498eSJames Wright KMUnpack(kmstress, stress); 7440ec2498eSJames Wright ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 74530e9fa81SJames Wright 746b5d317f8SJames Wright StateConservative dF_inviscid[3]; 747b5d317f8SJames Wright FluxInviscid_fwd(context, s, ds, dF_inviscid); 74830e9fa81SJames Wright 749*5bce47c7SJames Wright CeedScalar dFlux[5]; 750*5bce47c7SJames Wright FluxTotal_Boundary(dF_inviscid, dstress, dFe, norm, dFlux); 751b5d317f8SJames Wright 752*5bce47c7SJames Wright for (int j=0; j<5; j++) v[j][i] = -wdetJb * dFlux[j]; 75330e9fa81SJames Wright } // End Quadrature Point Loop 75430e9fa81SJames Wright return 0; 75530e9fa81SJames Wright } 75630e9fa81SJames Wright 75788b783a1SJames Wright // ***************************************************************************** 758dc805cc4SLeila Ghaffari // This QFunction implements the Navier-Stokes equations (mentioned above) in 759dc805cc4SLeila Ghaffari // primitive variables and with implicit time stepping method 760dc805cc4SLeila Ghaffari // 761dc805cc4SLeila Ghaffari // ***************************************************************************** 762dc805cc4SLeila Ghaffari CEED_QFUNCTION(IFunction_Newtonian_Prim)(void *ctx, CeedInt Q, 763dc805cc4SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 764dc805cc4SLeila Ghaffari // *INDENT-OFF* 765dc805cc4SLeila Ghaffari // Inputs 766dc805cc4SLeila Ghaffari const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 767dc805cc4SLeila Ghaffari (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 768dc805cc4SLeila Ghaffari (*q_dot)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 769dc805cc4SLeila Ghaffari (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 770dc805cc4SLeila Ghaffari (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 771dc805cc4SLeila Ghaffari // Outputs 772dc805cc4SLeila Ghaffari CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 773dc805cc4SLeila Ghaffari (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1], 774dc805cc4SLeila Ghaffari (*jac_data)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[2]; 775dc805cc4SLeila Ghaffari // *INDENT-ON* 776dc805cc4SLeila Ghaffari // Context 777dc805cc4SLeila Ghaffari NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 778dc805cc4SLeila Ghaffari const CeedScalar *g = context->g; 779dc805cc4SLeila Ghaffari const CeedScalar dt = context->dt; 780dc805cc4SLeila Ghaffari 781dc805cc4SLeila Ghaffari CeedPragmaSIMD 782dc805cc4SLeila Ghaffari // Quadrature Point Loop 783dc805cc4SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 784dc805cc4SLeila Ghaffari CeedScalar Y[5]; 785dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) Y[j] = q[j][i]; 786dc805cc4SLeila Ghaffari const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 787dc805cc4SLeila Ghaffari State s = StateFromY(context, Y, x_i); 788dc805cc4SLeila Ghaffari 789dc805cc4SLeila Ghaffari // -- Interp-to-Interp q_data 790dc805cc4SLeila Ghaffari const CeedScalar wdetJ = q_data[0][i]; 791dc805cc4SLeila Ghaffari // -- Interp-to-Grad q_data 792dc805cc4SLeila Ghaffari // ---- Inverse of change of coordinate matrix: X_i,j 793dc805cc4SLeila Ghaffari // *INDENT-OFF* 79423d6ba15SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 79523d6ba15SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 79623d6ba15SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 797dc805cc4SLeila Ghaffari }; 798dc805cc4SLeila Ghaffari // *INDENT-ON* 799dc805cc4SLeila Ghaffari State grad_s[3]; 800dc805cc4SLeila Ghaffari for (CeedInt j=0; j<3; j++) { 801dc805cc4SLeila Ghaffari CeedScalar dx_i[3] = {0}, dY[5]; 802dc805cc4SLeila Ghaffari for (CeedInt k=0; k<5; k++) 803dc805cc4SLeila Ghaffari dY[k] = Grad_q[0][k][i] * dXdx[0][j] + 804dc805cc4SLeila Ghaffari Grad_q[1][k][i] * dXdx[1][j] + 805dc805cc4SLeila Ghaffari Grad_q[2][k][i] * dXdx[2][j]; 806dc805cc4SLeila Ghaffari dx_i[j] = 1.; 807dc805cc4SLeila Ghaffari grad_s[j] = StateFromY_fwd(context, s, dY, x_i, dx_i); 808dc805cc4SLeila Ghaffari } 809dc805cc4SLeila Ghaffari 810dc805cc4SLeila Ghaffari CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 811dc805cc4SLeila Ghaffari KMStrainRate(grad_s, strain_rate); 812dc805cc4SLeila Ghaffari NewtonianStress(context, strain_rate, kmstress); 813dc805cc4SLeila Ghaffari KMUnpack(kmstress, stress); 814dc805cc4SLeila Ghaffari ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 815dc805cc4SLeila Ghaffari 816dc805cc4SLeila Ghaffari StateConservative F_inviscid[3]; 817dc805cc4SLeila Ghaffari FluxInviscid(context, s, F_inviscid); 818dc805cc4SLeila Ghaffari 819dc805cc4SLeila Ghaffari // Total flux 820dc805cc4SLeila Ghaffari CeedScalar Flux[5][3]; 8212b89d87eSLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 822dc805cc4SLeila Ghaffari 8232b89d87eSLeila Ghaffari for (CeedInt j=0; j<3; j++) 8242b89d87eSLeila Ghaffari for (CeedInt k=0; k<5; k++) 825dc805cc4SLeila Ghaffari Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * Flux[k][0] + 826dc805cc4SLeila Ghaffari dXdx[j][1] * Flux[k][1] + 827dc805cc4SLeila Ghaffari dXdx[j][2] * Flux[k][2]); 828dc805cc4SLeila Ghaffari 829dc805cc4SLeila Ghaffari const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 830dc805cc4SLeila Ghaffari 831dc805cc4SLeila Ghaffari CeedScalar Y_dot[5], dx0[3] = {0}; 832dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) Y_dot[j] = q_dot[j][i]; 833dc805cc4SLeila Ghaffari State s_dot = StateFromY_fwd(context, s, Y_dot, x_i, dx0); 834dc805cc4SLeila Ghaffari 835dc805cc4SLeila Ghaffari CeedScalar U_dot[5] = {0.}; 8362b89d87eSLeila Ghaffari UnpackState_U(s_dot.U, U_dot); 837dc805cc4SLeila Ghaffari 838dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) 839dc805cc4SLeila Ghaffari v[j][i] = wdetJ * (U_dot[j] - body_force[j]); 840dc805cc4SLeila Ghaffari 8412b89d87eSLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 8422b89d87eSLeila Ghaffari CeedScalar Tau_d[3], stab[5][3]; 8432b89d87eSLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 8442b89d87eSLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 845dc805cc4SLeila Ghaffari 846dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) 847dc805cc4SLeila Ghaffari for (CeedInt k=0; k<3; k++) 848dc805cc4SLeila Ghaffari Grad_v[k][j][i] += wdetJ*(stab[j][0] * dXdx[k][0] + 849dc805cc4SLeila Ghaffari stab[j][1] * dXdx[k][1] + 850dc805cc4SLeila Ghaffari stab[j][2] * dXdx[k][2]); 851dc805cc4SLeila Ghaffari 852dc805cc4SLeila Ghaffari for (CeedInt j=0; j<5; j++) jac_data[j][i] = Y[j]; 853dc805cc4SLeila Ghaffari for (CeedInt j=0; j<6; j++) jac_data[5+j][i] = kmstress[j]; 854dc805cc4SLeila Ghaffari for (CeedInt j=0; j<3; j++) jac_data[5+6+j][i] = Tau_d[j]; 855dc805cc4SLeila Ghaffari 856dc805cc4SLeila Ghaffari } // End Quadrature Point Loop 857dc805cc4SLeila Ghaffari 858dc805cc4SLeila Ghaffari // Return 859dc805cc4SLeila Ghaffari return 0; 860dc805cc4SLeila Ghaffari } 861dc805cc4SLeila Ghaffari 862dc805cc4SLeila Ghaffari // ***************************************************************************** 863dc805cc4SLeila Ghaffari // This QFunction implements the jacobean of the Navier-Stokes equations 864dc805cc4SLeila Ghaffari // in primitive variables for implicit time stepping method. 865dc805cc4SLeila Ghaffari // 866dc805cc4SLeila Ghaffari // ***************************************************************************** 867dc805cc4SLeila Ghaffari CEED_QFUNCTION(IJacobian_Newtonian_Prim)(void *ctx, CeedInt Q, 868dc805cc4SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 869dc805cc4SLeila Ghaffari // *INDENT-OFF* 870dc805cc4SLeila Ghaffari // Inputs 871dc805cc4SLeila Ghaffari const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 872dc805cc4SLeila Ghaffari (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 873dc805cc4SLeila Ghaffari (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 874dc805cc4SLeila Ghaffari (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 875dc805cc4SLeila Ghaffari (*jac_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 876dc805cc4SLeila Ghaffari // Outputs 877dc805cc4SLeila Ghaffari CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 878dc805cc4SLeila Ghaffari (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1]; 879dc805cc4SLeila Ghaffari // *INDENT-ON* 880dc805cc4SLeila Ghaffari // Context 881dc805cc4SLeila Ghaffari NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 882dc805cc4SLeila Ghaffari const CeedScalar *g = context->g; 883dc805cc4SLeila Ghaffari 884dc805cc4SLeila Ghaffari CeedPragmaSIMD 885dc805cc4SLeila Ghaffari // Quadrature Point Loop 886dc805cc4SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 887dc805cc4SLeila Ghaffari // -- Interp-to-Interp q_data 888dc805cc4SLeila Ghaffari const CeedScalar wdetJ = q_data[0][i]; 889dc805cc4SLeila Ghaffari // -- Interp-to-Grad q_data 890dc805cc4SLeila Ghaffari // ---- Inverse of change of coordinate matrix: X_i,j 891dc805cc4SLeila Ghaffari // *INDENT-OFF* 89223d6ba15SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 89323d6ba15SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 89423d6ba15SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 895dc805cc4SLeila Ghaffari }; 896dc805cc4SLeila Ghaffari // *INDENT-ON* 897dc805cc4SLeila Ghaffari 898dc805cc4SLeila Ghaffari CeedScalar Y[5], kmstress[6], Tau_d[3] __attribute((unused)); 899dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) Y[j] = jac_data[j][i]; 900dc805cc4SLeila Ghaffari for (int j=0; j<6; j++) kmstress[j] = jac_data[5+j][i]; 901dc805cc4SLeila Ghaffari for (int j=0; j<3; j++) Tau_d[j] = jac_data[5+6+j][i]; 902dc805cc4SLeila Ghaffari const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 903dc805cc4SLeila Ghaffari State s = StateFromY(context, Y, x_i); 904dc805cc4SLeila Ghaffari 905dc805cc4SLeila Ghaffari CeedScalar dY[5], dx0[3] = {0}; 906dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) dY[j] = dq[j][i]; 907dc805cc4SLeila Ghaffari State ds = StateFromY_fwd(context, s, dY, x_i, dx0); 908dc805cc4SLeila Ghaffari 909dc805cc4SLeila Ghaffari State grad_ds[3]; 910dc805cc4SLeila Ghaffari for (int j=0; j<3; j++) { 911dc805cc4SLeila Ghaffari CeedScalar dYj[5]; 912dc805cc4SLeila Ghaffari for (int k=0; k<5; k++) 913dc805cc4SLeila Ghaffari dYj[k] = Grad_dq[0][k][i] * dXdx[0][j] + 914dc805cc4SLeila Ghaffari Grad_dq[1][k][i] * dXdx[1][j] + 915dc805cc4SLeila Ghaffari Grad_dq[2][k][i] * dXdx[2][j]; 916dc805cc4SLeila Ghaffari grad_ds[j] = StateFromY_fwd(context, s, dYj, x_i, dx0); 917dc805cc4SLeila Ghaffari } 918dc805cc4SLeila Ghaffari 919dc805cc4SLeila Ghaffari CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 920dc805cc4SLeila Ghaffari KMStrainRate(grad_ds, dstrain_rate); 921dc805cc4SLeila Ghaffari NewtonianStress(context, dstrain_rate, dkmstress); 922dc805cc4SLeila Ghaffari KMUnpack(dkmstress, dstress); 923dc805cc4SLeila Ghaffari KMUnpack(kmstress, stress); 924dc805cc4SLeila Ghaffari ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 925dc805cc4SLeila Ghaffari 926dc805cc4SLeila Ghaffari StateConservative dF_inviscid[3]; 927dc805cc4SLeila Ghaffari FluxInviscid_fwd(context, s, ds, dF_inviscid); 928dc805cc4SLeila Ghaffari 929dc805cc4SLeila Ghaffari // Total flux 930dc805cc4SLeila Ghaffari CeedScalar dFlux[5][3]; 9312b89d87eSLeila Ghaffari FluxTotal(dF_inviscid, dstress, dFe, dFlux); 932dc805cc4SLeila Ghaffari 9332b89d87eSLeila Ghaffari for (int j=0; j<3; j++) 9342b89d87eSLeila Ghaffari for (int k=0; k<5; k++) 935dc805cc4SLeila Ghaffari Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * dFlux[k][0] + 936dc805cc4SLeila Ghaffari dXdx[j][1] * dFlux[k][1] + 937dc805cc4SLeila Ghaffari dXdx[j][2] * dFlux[k][2]); 938dc805cc4SLeila Ghaffari 9392b89d87eSLeila Ghaffari const CeedScalar dbody_force[5] = {0, ds.U.density *g[0], ds.U.density *g[1], ds.U.density *g[2], 0}; 940dc805cc4SLeila Ghaffari CeedScalar dU[5] = {0.}; 9412b89d87eSLeila Ghaffari UnpackState_U(ds.U, dU); 942dc805cc4SLeila Ghaffari 943dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) 944dc805cc4SLeila Ghaffari v[j][i] = wdetJ * (context->ijacobian_time_shift * dU[j] - dbody_force[j]); 945dc805cc4SLeila Ghaffari 9462b89d87eSLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 9472b89d87eSLeila Ghaffari CeedScalar dstab[5][3], U_dot[5] = {0}; 9482b89d87eSLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = context->ijacobian_time_shift * dU[j]; 9492b89d87eSLeila Ghaffari Stabilization(context, s, Tau_d, grad_ds, U_dot, dbody_force, x_i, dstab); 950dc805cc4SLeila Ghaffari 951dc805cc4SLeila Ghaffari for (int j=0; j<5; j++) 952dc805cc4SLeila Ghaffari for (int k=0; k<3; k++) 953dc805cc4SLeila Ghaffari Grad_v[k][j][i] += wdetJ*(dstab[j][0] * dXdx[k][0] + 954dc805cc4SLeila Ghaffari dstab[j][1] * dXdx[k][1] + 955dc805cc4SLeila Ghaffari dstab[j][2] * dXdx[k][2]); 956dc805cc4SLeila Ghaffari 957dc805cc4SLeila Ghaffari } // End Quadrature Point Loop 958dc805cc4SLeila Ghaffari return 0; 959dc805cc4SLeila Ghaffari } 960dc805cc4SLeila Ghaffari // ***************************************************************************** 961dc805cc4SLeila Ghaffari 96288b783a1SJames Wright #endif // newtonian_h 963