1727da7e7SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 2727da7e7SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 33a8779fbSJames Wright // 4727da7e7SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 53a8779fbSJames Wright // 6727da7e7SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 73a8779fbSJames Wright 83a8779fbSJames Wright /// @file 93a8779fbSJames Wright /// Operator for Navier-Stokes example using PETSc 103a8779fbSJames Wright 113a8779fbSJames Wright 123a8779fbSJames Wright #ifndef newtonian_h 133a8779fbSJames Wright #define newtonian_h 143a8779fbSJames Wright 153a8779fbSJames Wright #include <math.h> 163a8779fbSJames Wright #include <ceed.h> 1715a3537eSJed Brown #include "newtonian_types.h" 18475b2820SJames Wright #include "newtonian_state.h" 19704b8bbeSJames Wright #include "utils.h" 20*d1b9ef12SLeila Ghaffari #include "stabilization.h" 21bb8a0c61SJames Wright 22bb8a0c61SJames Wright // ***************************************************************************** 233a8779fbSJames Wright // This QFunction sets a "still" initial condition for generic Newtonian IG problems 243a8779fbSJames Wright // ***************************************************************************** 253a8779fbSJames Wright CEED_QFUNCTION(ICsNewtonianIG)(void *ctx, CeedInt Q, 263a8779fbSJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 273a8779fbSJames Wright // Inputs 283a8779fbSJames Wright const CeedScalar (*X)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0]; 293a8779fbSJames Wright 303a8779fbSJames Wright // Outputs 313a8779fbSJames Wright CeedScalar (*q0)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 323a8779fbSJames Wright 33bb8a0c61SJames Wright // Context 34bb8a0c61SJames Wright const SetupContext context = (SetupContext)ctx; 35bb8a0c61SJames Wright const CeedScalar theta0 = context->theta0; 36bb8a0c61SJames Wright const CeedScalar P0 = context->P0; 37bb8a0c61SJames Wright const CeedScalar cv = context->cv; 38bb8a0c61SJames Wright const CeedScalar cp = context->cp; 39bb8a0c61SJames Wright const CeedScalar *g = context->g; 40bb8a0c61SJames Wright const CeedScalar Rd = cp - cv; 41bb8a0c61SJames Wright 423a8779fbSJames Wright // Quadrature Point Loop 433a8779fbSJames Wright CeedPragmaSIMD 443a8779fbSJames Wright for (CeedInt i=0; i<Q; i++) { 453a8779fbSJames Wright CeedScalar q[5] = {0.}; 463a8779fbSJames Wright 473a8779fbSJames Wright // Setup 483a8779fbSJames Wright // -- Coordinates 49bb8a0c61SJames Wright const CeedScalar x[3] = {X[0][i], X[1][i], X[2][i]}; 50*d1b9ef12SLeila Ghaffari const CeedScalar e_potential = -Dot3(g, x); 513a8779fbSJames Wright 523a8779fbSJames Wright // -- Density 53bb8a0c61SJames Wright const CeedScalar rho = P0 / (Rd*theta0); 543a8779fbSJames Wright 553a8779fbSJames Wright // Initial Conditions 563a8779fbSJames Wright q[0] = rho; 573a8779fbSJames Wright q[1] = 0.0; 583a8779fbSJames Wright q[2] = 0.0; 593a8779fbSJames Wright q[3] = 0.0; 60bb8a0c61SJames Wright q[4] = rho * (cv*theta0 + e_potential); 613a8779fbSJames Wright 623a8779fbSJames Wright for (CeedInt j=0; j<5; j++) 633a8779fbSJames Wright q0[j][i] = q[j]; 64*d1b9ef12SLeila Ghaffari 653a8779fbSJames Wright } // End of Quadrature Point Loop 663a8779fbSJames Wright return 0; 673a8779fbSJames Wright } 683a8779fbSJames Wright 693a8779fbSJames Wright // ***************************************************************************** 70cbe60e31SLeila Ghaffari // This QFunction sets a "still" initial condition for generic Newtonian IG 71cbe60e31SLeila Ghaffari // problems in primitive variables 72cbe60e31SLeila Ghaffari // ***************************************************************************** 73cbe60e31SLeila Ghaffari CEED_QFUNCTION(ICsNewtonianIG_Prim)(void *ctx, CeedInt Q, 74cbe60e31SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 75cbe60e31SLeila Ghaffari // Outputs 76cbe60e31SLeila Ghaffari CeedScalar (*q0)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 77cbe60e31SLeila Ghaffari 78cbe60e31SLeila Ghaffari // Context 79cbe60e31SLeila Ghaffari const SetupContext context = (SetupContext)ctx; 80cbe60e31SLeila Ghaffari const CeedScalar theta0 = context->theta0; 81cbe60e31SLeila Ghaffari const CeedScalar P0 = context->P0; 82cbe60e31SLeila Ghaffari 83cbe60e31SLeila Ghaffari // Quadrature Point Loop 84cbe60e31SLeila Ghaffari CeedPragmaSIMD 85cbe60e31SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 86cbe60e31SLeila Ghaffari CeedScalar q[5] = {0.}; 87cbe60e31SLeila Ghaffari 88cbe60e31SLeila Ghaffari // Initial Conditions 89cbe60e31SLeila Ghaffari q[0] = P0; 90cbe60e31SLeila Ghaffari q[1] = 0.0; 91cbe60e31SLeila Ghaffari q[2] = 0.0; 92cbe60e31SLeila Ghaffari q[3] = 0.0; 93cbe60e31SLeila Ghaffari q[4] = theta0; 94cbe60e31SLeila Ghaffari 95cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) 96cbe60e31SLeila Ghaffari q0[j][i] = q[j]; 97cbe60e31SLeila Ghaffari 98cbe60e31SLeila Ghaffari } // End of Quadrature Point Loop 99cbe60e31SLeila Ghaffari return 0; 100cbe60e31SLeila Ghaffari } 101cbe60e31SLeila Ghaffari 102cbe60e31SLeila Ghaffari // ***************************************************************************** 1033a8779fbSJames Wright // This QFunction implements the following formulation of Navier-Stokes with 1043a8779fbSJames Wright // explicit time stepping method 1053a8779fbSJames Wright // 1063a8779fbSJames Wright // This is 3D compressible Navier-Stokes in conservation form with state 1073a8779fbSJames Wright // variables of density, momentum density, and total energy density. 1083a8779fbSJames Wright // 1093a8779fbSJames Wright // State Variables: q = ( rho, U1, U2, U3, E ) 1103a8779fbSJames Wright // rho - Mass Density 1113a8779fbSJames Wright // Ui - Momentum Density, Ui = rho ui 1123a8779fbSJames Wright // E - Total Energy Density, E = rho (cv T + (u u)/2 + g z) 1133a8779fbSJames Wright // 1143a8779fbSJames Wright // Navier-Stokes Equations: 1153a8779fbSJames Wright // drho/dt + div( U ) = 0 1163a8779fbSJames Wright // dU/dt + div( rho (u x u) + P I3 ) + rho g khat = div( Fu ) 1173a8779fbSJames Wright // dE/dt + div( (E + P) u ) = div( Fe ) 1183a8779fbSJames Wright // 1193a8779fbSJames Wright // Viscous Stress: 1203a8779fbSJames Wright // Fu = mu (grad( u ) + grad( u )^T + lambda div ( u ) I3) 1213a8779fbSJames Wright // 1223a8779fbSJames Wright // Thermal Stress: 1233a8779fbSJames Wright // Fe = u Fu + k grad( T ) 124bb8a0c61SJames Wright // Equation of State 1253a8779fbSJames Wright // P = (gamma - 1) (E - rho (u u) / 2 - rho g z) 1263a8779fbSJames Wright // 1273a8779fbSJames Wright // Stabilization: 1283a8779fbSJames Wright // Tau = diag(TauC, TauM, TauM, TauM, TauE) 1293a8779fbSJames Wright // f1 = rho sqrt(ui uj gij) 1303a8779fbSJames Wright // gij = dXi/dX * dXi/dX 1313a8779fbSJames Wright // TauC = Cc f1 / (8 gii) 1323a8779fbSJames Wright // TauM = min( 1 , 1 / f1 ) 1333a8779fbSJames Wright // TauE = TauM / (Ce cv) 1343a8779fbSJames Wright // 1353a8779fbSJames Wright // SU = Galerkin + grad(v) . ( Ai^T * Tau * (Aj q,j) ) 1363a8779fbSJames Wright // 1373a8779fbSJames Wright // Constants: 1383a8779fbSJames Wright // lambda = - 2 / 3, From Stokes hypothesis 1393a8779fbSJames Wright // mu , Dynamic viscosity 1403a8779fbSJames Wright // k , Thermal conductivity 1413a8779fbSJames Wright // cv , Specific heat, constant volume 1423a8779fbSJames Wright // cp , Specific heat, constant pressure 1433a8779fbSJames Wright // g , Gravity 1443a8779fbSJames Wright // gamma = cp / cv, Specific heat ratio 1453a8779fbSJames Wright // 1463a8779fbSJames Wright // We require the product of the inverse of the Jacobian (dXdx_j,k) and 1473a8779fbSJames Wright // its transpose (dXdx_k,j) to properly compute integrals of the form: 1483a8779fbSJames Wright // int( gradv gradu ) 1493a8779fbSJames Wright // 1503a8779fbSJames Wright // ***************************************************************************** 151c1a52365SJed Brown CEED_QFUNCTION(RHSFunction_Newtonian)(void *ctx, CeedInt Q, 1523a8779fbSJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 1533a8779fbSJames Wright // *INDENT-OFF* 1543a8779fbSJames Wright // Inputs 1553a8779fbSJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 156752f40e3SJed Brown (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 1573a8779fbSJames Wright (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 1583a8779fbSJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 1593a8779fbSJames Wright // Outputs 1603a8779fbSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 161752f40e3SJed Brown (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1]; 1623a8779fbSJames Wright // *INDENT-ON* 1633a8779fbSJames Wright 1643a8779fbSJames Wright // Context 1653a8779fbSJames Wright NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 166bb8a0c61SJames Wright const CeedScalar *g = context->g; 167bb8a0c61SJames Wright const CeedScalar dt = context->dt; 1683a8779fbSJames Wright 1693a8779fbSJames Wright CeedPragmaSIMD 1703a8779fbSJames Wright // Quadrature Point Loop 1713a8779fbSJames Wright for (CeedInt i=0; i<Q; i++) { 172c1a52365SJed Brown CeedScalar U[5]; 173c1a52365SJed Brown for (int j=0; j<5; j++) U[j] = q[j][i]; 174c1a52365SJed Brown const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 175c1a52365SJed Brown State s = StateFromU(context, U, x_i); 176c1a52365SJed Brown 1773a8779fbSJames Wright // -- Interp-to-Interp q_data 1783a8779fbSJames Wright const CeedScalar wdetJ = q_data[0][i]; 1793a8779fbSJames Wright // -- Interp-to-Grad q_data 1803a8779fbSJames Wright // ---- Inverse of change of coordinate matrix: X_i,j 1813a8779fbSJames Wright // *INDENT-OFF* 1823a8779fbSJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], 1833a8779fbSJames Wright q_data[2][i], 1843a8779fbSJames Wright q_data[3][i]}, 1853a8779fbSJames Wright {q_data[4][i], 1863a8779fbSJames Wright q_data[5][i], 1873a8779fbSJames Wright q_data[6][i]}, 1883a8779fbSJames Wright {q_data[7][i], 1893a8779fbSJames Wright q_data[8][i], 1903a8779fbSJames Wright q_data[9][i]} 1913a8779fbSJames Wright }; 1923a8779fbSJames Wright // *INDENT-ON* 193c1a52365SJed Brown State grad_s[3]; 194eef2387dSJed Brown for (CeedInt j=0; j<3; j++) { 1952f7ce6c1SJed Brown CeedScalar dx_i[3] = {0}, dU[5]; 1962556a851SJed Brown for (CeedInt k=0; k<5; k++) 1972556a851SJed Brown dU[k] = Grad_q[0][k][i] * dXdx[0][j] + 1982556a851SJed Brown Grad_q[1][k][i] * dXdx[1][j] + 1992556a851SJed Brown Grad_q[2][k][i] * dXdx[2][j]; 200c1a52365SJed Brown dx_i[j] = 1.; 2012f7ce6c1SJed Brown grad_s[j] = StateFromU_fwd(context, s, dU, x_i, dx_i); 202c1a52365SJed Brown } 203c1a52365SJed Brown 204c1a52365SJed Brown CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 205c1a52365SJed Brown KMStrainRate(grad_s, strain_rate); 206c1a52365SJed Brown NewtonianStress(context, strain_rate, kmstress); 207c1a52365SJed Brown KMUnpack(kmstress, stress); 208c1a52365SJed Brown ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 209c1a52365SJed Brown 210c1a52365SJed Brown StateConservative F_inviscid[3]; 211c1a52365SJed Brown FluxInviscid(context, s, F_inviscid); 212c1a52365SJed Brown 213c1a52365SJed Brown // Total flux 214c1a52365SJed Brown CeedScalar Flux[5][3]; 215*d1b9ef12SLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 216c1a52365SJed Brown 217*d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<3; j++) 218*d1b9ef12SLeila Ghaffari for (CeedInt k=0; k<5; k++) 219752f40e3SJed Brown Grad_v[j][k][i] = wdetJ * (dXdx[j][0] * Flux[k][0] + 220c1a52365SJed Brown dXdx[j][1] * Flux[k][1] + 221c1a52365SJed Brown dXdx[j][2] * Flux[k][2]); 222c1a52365SJed Brown 223c1a52365SJed Brown const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 224c1a52365SJed Brown for (int j=0; j<5; j++) 225c1a52365SJed Brown v[j][i] = wdetJ * body_force[j]; 2263a8779fbSJames Wright 227*d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 228*d1b9ef12SLeila Ghaffari CeedScalar Tau_d[3], stab[5][3], U_dot[5] = {0}; 229*d1b9ef12SLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 230*d1b9ef12SLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 2313a8779fbSJames Wright 232493642f1SJames Wright for (CeedInt j=0; j<5; j++) 233493642f1SJames Wright for (CeedInt k=0; k<3; k++) 234752f40e3SJed Brown Grad_v[k][j][i] -= wdetJ*(stab[j][0] * dXdx[k][0] + 2353a8779fbSJames Wright stab[j][1] * dXdx[k][1] + 2363a8779fbSJames Wright stab[j][2] * dXdx[k][2]); 2373a8779fbSJames Wright 2383a8779fbSJames Wright } // End Quadrature Point Loop 2393a8779fbSJames Wright 2403a8779fbSJames Wright // Return 2413a8779fbSJames Wright return 0; 2423a8779fbSJames Wright } 2433a8779fbSJames Wright 2443a8779fbSJames Wright // ***************************************************************************** 2453a8779fbSJames Wright // This QFunction implements the Navier-Stokes equations (mentioned above) with 2463a8779fbSJames Wright // implicit time stepping method 2473a8779fbSJames Wright // 2483a8779fbSJames Wright // SU = Galerkin + grad(v) . ( Ai^T * Tau * (Aj q,j) ) 2493a8779fbSJames Wright // SUPG = Galerkin + grad(v) . ( Ai^T * Tau * (q_dot + Aj q,j - body force) ) 2503a8779fbSJames Wright // (diffussive terms will be added later) 2513a8779fbSJames Wright // 2523a8779fbSJames Wright // ***************************************************************************** 2533a8779fbSJames Wright CEED_QFUNCTION(IFunction_Newtonian)(void *ctx, CeedInt Q, 254cbe60e31SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 2553a8779fbSJames Wright // *INDENT-OFF* 2563a8779fbSJames Wright // Inputs 2573a8779fbSJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 258752f40e3SJed Brown (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 2593a8779fbSJames Wright (*q_dot)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 2603a8779fbSJames Wright (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 2613a8779fbSJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 2623a8779fbSJames Wright // Outputs 2633a8779fbSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 264752f40e3SJed Brown (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1], 265752f40e3SJed Brown (*jac_data)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[2]; 2663a8779fbSJames Wright // *INDENT-ON* 2673a8779fbSJames Wright // Context 2683a8779fbSJames Wright NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 269bb8a0c61SJames Wright const CeedScalar *g = context->g; 270bb8a0c61SJames Wright const CeedScalar dt = context->dt; 2713a8779fbSJames Wright 2723a8779fbSJames Wright CeedPragmaSIMD 2733a8779fbSJames Wright // Quadrature Point Loop 2743a8779fbSJames Wright for (CeedInt i=0; i<Q; i++) { 275c1a52365SJed Brown CeedScalar U[5]; 276eef2387dSJed Brown for (CeedInt j=0; j<5; j++) U[j] = q[j][i]; 277c1a52365SJed Brown const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 278c1a52365SJed Brown State s = StateFromU(context, U, x_i); 279c1a52365SJed Brown 2803a8779fbSJames Wright // -- Interp-to-Interp q_data 2813a8779fbSJames Wright const CeedScalar wdetJ = q_data[0][i]; 2823a8779fbSJames Wright // -- Interp-to-Grad q_data 2833a8779fbSJames Wright // ---- Inverse of change of coordinate matrix: X_i,j 2843a8779fbSJames Wright // *INDENT-OFF* 2853a8779fbSJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], 2863a8779fbSJames Wright q_data[2][i], 2873a8779fbSJames Wright q_data[3][i]}, 2883a8779fbSJames Wright {q_data[4][i], 2893a8779fbSJames Wright q_data[5][i], 2903a8779fbSJames Wright q_data[6][i]}, 2913a8779fbSJames Wright {q_data[7][i], 2923a8779fbSJames Wright q_data[8][i], 2933a8779fbSJames Wright q_data[9][i]} 2943a8779fbSJames Wright }; 2953a8779fbSJames Wright // *INDENT-ON* 296c1a52365SJed Brown State grad_s[3]; 297493642f1SJames Wright for (CeedInt j=0; j<3; j++) { 2982f7ce6c1SJed Brown CeedScalar dx_i[3] = {0}, dU[5]; 2992556a851SJed Brown for (CeedInt k=0; k<5; k++) 3002556a851SJed Brown dU[k] = Grad_q[0][k][i] * dXdx[0][j] + 3012556a851SJed Brown Grad_q[1][k][i] * dXdx[1][j] + 3022556a851SJed Brown Grad_q[2][k][i] * dXdx[2][j]; 303c1a52365SJed Brown dx_i[j] = 1.; 3042f7ce6c1SJed Brown grad_s[j] = StateFromU_fwd(context, s, dU, x_i, dx_i); 3053a8779fbSJames Wright } 306c1a52365SJed Brown 307c1a52365SJed Brown CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 308c1a52365SJed Brown KMStrainRate(grad_s, strain_rate); 309c1a52365SJed Brown NewtonianStress(context, strain_rate, kmstress); 310c1a52365SJed Brown KMUnpack(kmstress, stress); 311c1a52365SJed Brown ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 312c1a52365SJed Brown 313c1a52365SJed Brown StateConservative F_inviscid[3]; 314c1a52365SJed Brown FluxInviscid(context, s, F_inviscid); 315c1a52365SJed Brown 316c1a52365SJed Brown // Total flux 317c1a52365SJed Brown CeedScalar Flux[5][3]; 318*d1b9ef12SLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 319c1a52365SJed Brown 320*d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<3; j++) 321*d1b9ef12SLeila Ghaffari for (CeedInt k=0; k<5; k++) 322752f40e3SJed Brown Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * Flux[k][0] + 323c1a52365SJed Brown dXdx[j][1] * Flux[k][1] + 324c1a52365SJed Brown dXdx[j][2] * Flux[k][2]); 325c1a52365SJed Brown 326c1a52365SJed Brown const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 327eef2387dSJed Brown for (CeedInt j=0; j<5; j++) 328c1a52365SJed Brown v[j][i] = wdetJ * (q_dot[j][i] - body_force[j]); 3293a8779fbSJames Wright 330*d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 331*d1b9ef12SLeila Ghaffari CeedScalar Tau_d[3], stab[5][3], U_dot[5] = {0}; 332*d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = q_dot[j][i]; 333*d1b9ef12SLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 334*d1b9ef12SLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 3353a8779fbSJames Wright 336493642f1SJames Wright for (CeedInt j=0; j<5; j++) 337493642f1SJames Wright for (CeedInt k=0; k<3; k++) 338752f40e3SJed Brown Grad_v[k][j][i] += wdetJ*(stab[j][0] * dXdx[k][0] + 3393a8779fbSJames Wright stab[j][1] * dXdx[k][1] + 3403a8779fbSJames Wright stab[j][2] * dXdx[k][2]); 341eef2387dSJed Brown 342eef2387dSJed Brown for (CeedInt j=0; j<5; j++) jac_data[j][i] = U[j]; 343eef2387dSJed Brown for (CeedInt j=0; j<6; j++) jac_data[5+j][i] = kmstress[j]; 344eef2387dSJed Brown for (CeedInt j=0; j<3; j++) jac_data[5+6+j][i] = Tau_d[j]; 3453a8779fbSJames Wright 3463a8779fbSJames Wright } // End Quadrature Point Loop 3473a8779fbSJames Wright 3483a8779fbSJames Wright // Return 3493a8779fbSJames Wright return 0; 3503a8779fbSJames Wright } 351f0b65372SJed Brown 352cbe60e31SLeila Ghaffari // ***************************************************************************** 353cbe60e31SLeila Ghaffari // This QFunction implements the jacobean of the Navier-Stokes equations 354cbe60e31SLeila Ghaffari // for implicit time stepping method. 355cbe60e31SLeila Ghaffari // 356cbe60e31SLeila Ghaffari // ***************************************************************************** 357f0b65372SJed Brown CEED_QFUNCTION(IJacobian_Newtonian)(void *ctx, CeedInt Q, 358f0b65372SJed Brown const CeedScalar *const *in, 359f0b65372SJed Brown CeedScalar *const *out) { 360f0b65372SJed Brown // *INDENT-OFF* 361f0b65372SJed Brown // Inputs 362f0b65372SJed Brown const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 363f0b65372SJed Brown (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 364f0b65372SJed Brown (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 365f0b65372SJed Brown (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 366f0b65372SJed Brown (*jac_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 367f0b65372SJed Brown // Outputs 368f0b65372SJed Brown CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 369f0b65372SJed Brown (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1]; 370f0b65372SJed Brown // *INDENT-ON* 371f0b65372SJed Brown // Context 372f0b65372SJed Brown NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 373f0b65372SJed Brown const CeedScalar *g = context->g; 374f0b65372SJed Brown 375f0b65372SJed Brown CeedPragmaSIMD 376f0b65372SJed Brown // Quadrature Point Loop 377f0b65372SJed Brown for (CeedInt i=0; i<Q; i++) { 378f0b65372SJed Brown // -- Interp-to-Interp q_data 379f0b65372SJed Brown const CeedScalar wdetJ = q_data[0][i]; 380f0b65372SJed Brown // -- Interp-to-Grad q_data 381f0b65372SJed Brown // ---- Inverse of change of coordinate matrix: X_i,j 382f0b65372SJed Brown // *INDENT-OFF* 383f0b65372SJed Brown const CeedScalar dXdx[3][3] = {{q_data[1][i], 384f0b65372SJed Brown q_data[2][i], 385f0b65372SJed Brown q_data[3][i]}, 386f0b65372SJed Brown {q_data[4][i], 387f0b65372SJed Brown q_data[5][i], 388f0b65372SJed Brown q_data[6][i]}, 389f0b65372SJed Brown {q_data[7][i], 390f0b65372SJed Brown q_data[8][i], 391f0b65372SJed Brown q_data[9][i]} 392f0b65372SJed Brown }; 393f0b65372SJed Brown // *INDENT-ON* 394f0b65372SJed Brown 395f0b65372SJed Brown CeedScalar U[5], kmstress[6], Tau_d[3] __attribute((unused)); 396f0b65372SJed Brown for (int j=0; j<5; j++) U[j] = jac_data[j][i]; 397f0b65372SJed Brown for (int j=0; j<6; j++) kmstress[j] = jac_data[5+j][i]; 398f0b65372SJed Brown for (int j=0; j<3; j++) Tau_d[j] = jac_data[5+6+j][i]; 399f0b65372SJed Brown const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 400f0b65372SJed Brown State s = StateFromU(context, U, x_i); 401f0b65372SJed Brown 402f0b65372SJed Brown CeedScalar dU[5], dx0[3] = {0}; 403f0b65372SJed Brown for (int j=0; j<5; j++) dU[j] = dq[j][i]; 404f0b65372SJed Brown State ds = StateFromU_fwd(context, s, dU, x_i, dx0); 405f0b65372SJed Brown 406f0b65372SJed Brown State grad_ds[3]; 407f0b65372SJed Brown for (int j=0; j<3; j++) { 408f0b65372SJed Brown CeedScalar dUj[5]; 409*d1b9ef12SLeila Ghaffari for (int k=0; k<5; k++) 410*d1b9ef12SLeila Ghaffari dUj[k] = Grad_dq[0][k][i] * dXdx[0][j] + 411*d1b9ef12SLeila Ghaffari Grad_dq[1][k][i] * dXdx[1][j] + 412*d1b9ef12SLeila Ghaffari Grad_dq[2][k][i] * dXdx[2][j]; 413f0b65372SJed Brown grad_ds[j] = StateFromU_fwd(context, s, dUj, x_i, dx0); 414f0b65372SJed Brown } 415f0b65372SJed Brown 416f0b65372SJed Brown CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 417f0b65372SJed Brown KMStrainRate(grad_ds, dstrain_rate); 418f0b65372SJed Brown NewtonianStress(context, dstrain_rate, dkmstress); 419f0b65372SJed Brown KMUnpack(dkmstress, dstress); 420f0b65372SJed Brown KMUnpack(kmstress, stress); 421f0b65372SJed Brown ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 422f0b65372SJed Brown 423f0b65372SJed Brown StateConservative dF_inviscid[3]; 424f0b65372SJed Brown FluxInviscid_fwd(context, s, ds, dF_inviscid); 425f0b65372SJed Brown 426f0b65372SJed Brown // Total flux 427f0b65372SJed Brown CeedScalar dFlux[5][3]; 428*d1b9ef12SLeila Ghaffari FluxTotal(dF_inviscid, dstress, dFe, dFlux); 429f0b65372SJed Brown 430*d1b9ef12SLeila Ghaffari for (int j=0; j<3; j++) 431*d1b9ef12SLeila Ghaffari for (int k=0; k<5; k++) 432f0b65372SJed Brown Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * dFlux[k][0] + 433f0b65372SJed Brown dXdx[j][1] * dFlux[k][1] + 434f0b65372SJed Brown dXdx[j][2] * dFlux[k][2]); 435f0b65372SJed Brown 436f0b65372SJed Brown const CeedScalar dbody_force[5] = {0, ds.U.density *g[0], ds.U.density *g[1], ds.U.density *g[2], 0}; 437f0b65372SJed Brown for (int j=0; j<5; j++) 438f0b65372SJed Brown v[j][i] = wdetJ * (context->ijacobian_time_shift * dU[j] - dbody_force[j]); 439f0b65372SJed Brown 440*d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 441*d1b9ef12SLeila Ghaffari CeedScalar dstab[5][3], U_dot[5] = {0}; 442*d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = context->ijacobian_time_shift * dU[j]; 443*d1b9ef12SLeila Ghaffari Stabilization(context, s, Tau_d, grad_ds, U_dot, dbody_force, x_i, dstab); 444*d1b9ef12SLeila Ghaffari 445f0b65372SJed Brown for (int j=0; j<5; j++) 446f0b65372SJed Brown for (int k=0; k<3; k++) 447f0b65372SJed Brown Grad_v[k][j][i] += wdetJ*(dstab[j][0] * dXdx[k][0] + 448f0b65372SJed Brown dstab[j][1] * dXdx[k][1] + 449f0b65372SJed Brown dstab[j][2] * dXdx[k][2]); 450f0b65372SJed Brown 451f0b65372SJed Brown } // End Quadrature Point Loop 452f0b65372SJed Brown return 0; 453f0b65372SJed Brown } 4548085925cSJames Wright 455*d1b9ef12SLeila Ghaffari // ***************************************************************************** 4568085925cSJames Wright // Compute boundary integral (ie. for strongly set inflows) 457*d1b9ef12SLeila Ghaffari // ***************************************************************************** 4588085925cSJames Wright CEED_QFUNCTION(BoundaryIntegral)(void *ctx, CeedInt Q, 4598085925cSJames Wright const CeedScalar *const *in, 4608085925cSJames Wright CeedScalar *const *out) { 4618085925cSJames Wright 4628085925cSJames Wright //*INDENT-OFF* 4638085925cSJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 464d3b25f3aSJames Wright (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 465d3b25f3aSJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 466d3b25f3aSJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 4678085925cSJames Wright 46868ae065aSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA]) out[0], 46968ae065aSJames Wright (*jac_data_sur)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA]) out[1]; 4708085925cSJames Wright 4718085925cSJames Wright //*INDENT-ON* 4728085925cSJames Wright 473d3b25f3aSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext) ctx; 474d3b25f3aSJames Wright const bool is_implicit = context->is_implicit; 47541e73928SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 47641e73928SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 47741e73928SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 47841e73928SJames Wright State s, const CeedScalar dqi[5], 47941e73928SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 48041e73928SJames Wright StateFromQi = context->is_primitive ? &StateFromY : &StateFromU; 48141e73928SJames Wright StateFromQi_fwd = context->is_primitive ? &StateFromY_fwd : &StateFromU_fwd; 48241e73928SJames Wright 4838085925cSJames Wright 4848085925cSJames Wright CeedPragmaSIMD 4858085925cSJames Wright for(CeedInt i=0; i<Q; i++) { 486d3b25f3aSJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 48741e73928SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 48841e73928SJames Wright State s = StateFromQi(context, qi, x_i); 4898085925cSJames Wright 4908085925cSJames Wright const CeedScalar wdetJb = (is_implicit ? -1. : 1.) * q_data_sur[0][i]; 4918085925cSJames Wright // ---- Normal vect 4928085925cSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 4938085925cSJames Wright q_data_sur[2][i], 4948085925cSJames Wright q_data_sur[3][i] 4958085925cSJames Wright }; 4968085925cSJames Wright 497d3b25f3aSJames Wright const CeedScalar dXdx[2][3] = { 498d3b25f3aSJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 499d3b25f3aSJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 500d3b25f3aSJames Wright }; 5018085925cSJames Wright 502d3b25f3aSJames Wright State grad_s[3]; 503d3b25f3aSJames Wright for (CeedInt j=0; j<3; j++) { 50441e73928SJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 505d3b25f3aSJames Wright for (CeedInt k=0; k<5; k++) 50641e73928SJames Wright dqi[k] = Grad_q[0][k][i] * dXdx[0][j] + 507d3b25f3aSJames Wright Grad_q[1][k][i] * dXdx[1][j]; 508d3b25f3aSJames Wright dx_i[j] = 1.; 50941e73928SJames Wright grad_s[j] = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 510d3b25f3aSJames Wright } 5118085925cSJames Wright 512d3b25f3aSJames Wright CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 513d3b25f3aSJames Wright KMStrainRate(grad_s, strain_rate); 514d3b25f3aSJames Wright NewtonianStress(context, strain_rate, kmstress); 515d3b25f3aSJames Wright KMUnpack(kmstress, stress); 516d3b25f3aSJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 517d3b25f3aSJames Wright 518d3b25f3aSJames Wright StateConservative F_inviscid[3]; 519d3b25f3aSJames Wright FluxInviscid(context, s, F_inviscid); 520d3b25f3aSJames Wright 521d3b25f3aSJames Wright CeedScalar Flux[5] = {0.}; 522d3b25f3aSJames Wright for (int j=0; j<3; j++) { 523d3b25f3aSJames Wright Flux[0] += F_inviscid[j].density * norm[j]; 524d3b25f3aSJames Wright for (int k=0; k<3; k++) 525d3b25f3aSJames Wright Flux[k+1] += (F_inviscid[j].momentum[k] - stress[k][j]) * norm[j]; 526d3b25f3aSJames Wright Flux[4] += (F_inviscid[j].E_total + Fe[j]) * norm[j]; 527d3b25f3aSJames Wright } 528d3b25f3aSJames Wright 5298085925cSJames Wright // -- Density 530d3b25f3aSJames Wright v[0][i] = -wdetJb * Flux[0]; 5318085925cSJames Wright 5328085925cSJames Wright // -- Momentum 5338085925cSJames Wright for (CeedInt j=0; j<3; j++) 534d3b25f3aSJames Wright v[j+1][i] = -wdetJb * Flux[j+1]; 5358085925cSJames Wright 5368085925cSJames Wright // -- Total Energy Density 537d3b25f3aSJames Wright v[4][i] = -wdetJb * Flux[4]; 53868ae065aSJames Wright 5393934e2b1SJames Wright if (context->is_primitive) { 5403934e2b1SJames Wright jac_data_sur[0][i] = s.Y.pressure; 5413934e2b1SJames Wright for (int j=0; j<3; j++) jac_data_sur[j+1][i] = s.Y.velocity[j]; 5423934e2b1SJames Wright jac_data_sur[4][i] = s.Y.temperature; 5433934e2b1SJames Wright } else { 54468ae065aSJames Wright jac_data_sur[0][i] = s.U.density; 5453934e2b1SJames Wright for (int j=0; j<3; j++) jac_data_sur[j+1][i] = s.U.momentum[j]; 54668ae065aSJames Wright jac_data_sur[4][i] = s.U.E_total; 5473934e2b1SJames Wright } 54868ae065aSJames Wright for (int j=0; j<6; j++) jac_data_sur[5+j][i] = kmstress[j]; 5498085925cSJames Wright } 5508085925cSJames Wright return 0; 5518085925cSJames Wright } 5528085925cSJames Wright 553*d1b9ef12SLeila Ghaffari // ***************************************************************************** 55468ae065aSJames Wright // Jacobian for "set nothing" boundary integral 555*d1b9ef12SLeila Ghaffari // ***************************************************************************** 55668ae065aSJames Wright CEED_QFUNCTION(BoundaryIntegral_Jacobian)(void *ctx, CeedInt Q, 55768ae065aSJames Wright const CeedScalar *const *in, 55868ae065aSJames Wright CeedScalar *const *out) { 55968ae065aSJames Wright // *INDENT-OFF* 56068ae065aSJames Wright // Inputs 56168ae065aSJames Wright const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 56268ae065aSJames Wright (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 56368ae065aSJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 56468ae065aSJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 56568ae065aSJames Wright (*jac_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 56668ae065aSJames Wright // Outputs 56768ae065aSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 56868ae065aSJames Wright // *INDENT-ON* 56968ae065aSJames Wright 57068ae065aSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 57168ae065aSJames Wright const bool implicit = context->is_implicit; 57241e73928SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 57341e73928SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 57441e73928SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 57541e73928SJames Wright State s, const CeedScalar dqi[5], 57641e73928SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 57741e73928SJames Wright StateFromQi = context->is_primitive ? &StateFromY : &StateFromU; 57841e73928SJames Wright StateFromQi_fwd = context->is_primitive ? &StateFromY_fwd : &StateFromU_fwd; 57968ae065aSJames Wright 58068ae065aSJames Wright CeedPragmaSIMD 58168ae065aSJames Wright // Quadrature Point Loop 58268ae065aSJames Wright for (CeedInt i=0; i<Q; i++) { 58368ae065aSJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 58468ae065aSJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 58568ae065aSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 58668ae065aSJames Wright q_data_sur[2][i], 58768ae065aSJames Wright q_data_sur[3][i] 58868ae065aSJames Wright }; 58968ae065aSJames Wright const CeedScalar dXdx[2][3] = { 59068ae065aSJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 59168ae065aSJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 59268ae065aSJames Wright }; 59368ae065aSJames Wright 59441e73928SJames Wright CeedScalar qi[5], kmstress[6], dqi[5], dx_i[3] = {0.}; 59541e73928SJames Wright for (int j=0; j<5; j++) qi[j] = jac_data_sur[j][i]; 59668ae065aSJames Wright for (int j=0; j<6; j++) kmstress[j] = jac_data_sur[5+j][i]; 59741e73928SJames Wright for (int j=0; j<5; j++) dqi[j] = dq[j][i]; 5983934e2b1SJames Wright 59941e73928SJames Wright State s = StateFromQi(context, qi, x_i); 60041e73928SJames Wright State ds = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 60168ae065aSJames Wright 60268ae065aSJames Wright State grad_ds[3]; 60368ae065aSJames Wright for (CeedInt j=0; j<3; j++) { 60441e73928SJames Wright CeedScalar dx_i[3] = {0}, dqi_j[5]; 60568ae065aSJames Wright for (CeedInt k=0; k<5; k++) 60641e73928SJames Wright dqi_j[k] = Grad_dq[0][k][i] * dXdx[0][j] + 60768ae065aSJames Wright Grad_dq[1][k][i] * dXdx[1][j]; 60868ae065aSJames Wright dx_i[j] = 1.; 60941e73928SJames Wright grad_ds[j] = StateFromQi_fwd(context, s, dqi_j, x_i, dx_i); 61068ae065aSJames Wright } 61168ae065aSJames Wright 61268ae065aSJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 61368ae065aSJames Wright KMStrainRate(grad_ds, dstrain_rate); 61468ae065aSJames Wright NewtonianStress(context, dstrain_rate, dkmstress); 61568ae065aSJames Wright KMUnpack(dkmstress, dstress); 61668ae065aSJames Wright KMUnpack(kmstress, stress); 61768ae065aSJames Wright ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 61868ae065aSJames Wright 61968ae065aSJames Wright StateConservative dF_inviscid[3]; 62068ae065aSJames Wright FluxInviscid_fwd(context, s, ds, dF_inviscid); 62168ae065aSJames Wright 62268ae065aSJames Wright CeedScalar dFlux[5] = {0.}; 62368ae065aSJames Wright for (int j=0; j<3; j++) { 62468ae065aSJames Wright dFlux[0] += dF_inviscid[j].density * norm[j]; 62568ae065aSJames Wright for (int k=0; k<3; k++) 62668ae065aSJames Wright dFlux[k+1] += (dF_inviscid[j].momentum[k] - dstress[k][j]) * norm[j]; 62768ae065aSJames Wright dFlux[4] += (dF_inviscid[j].E_total + dFe[j]) * norm[j]; 62868ae065aSJames Wright } 62968ae065aSJames Wright 63068ae065aSJames Wright for (int j=0; j<5; j++) 63168ae065aSJames Wright v[j][i] = -wdetJb * dFlux[j]; 63268ae065aSJames Wright } // End Quadrature Point Loop 63368ae065aSJames Wright return 0; 63468ae065aSJames Wright } 63568ae065aSJames Wright 636*d1b9ef12SLeila Ghaffari // ***************************************************************************** 63704b9037bSJames Wright // Outflow boundary condition, weakly setting a constant pressure 638*d1b9ef12SLeila Ghaffari // ***************************************************************************** 63904b9037bSJames Wright CEED_QFUNCTION(PressureOutflow)(void *ctx, CeedInt Q, 64004b9037bSJames Wright const CeedScalar *const *in, 64104b9037bSJames Wright CeedScalar *const *out) { 64204b9037bSJames Wright // *INDENT-OFF* 64304b9037bSJames Wright // Inputs 64404b9037bSJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 64525bfcc41SJames Wright (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 64625bfcc41SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 64725bfcc41SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 64804b9037bSJames Wright // Outputs 64904b9037bSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 65004b9037bSJames Wright (*jac_data_sur)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[1]; 65104b9037bSJames Wright // *INDENT-ON* 65204b9037bSJames Wright 65304b9037bSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 65404b9037bSJames Wright const bool implicit = context->is_implicit; 65504b9037bSJames Wright const CeedScalar P0 = context->P0; 65604b9037bSJames Wright 65741e73928SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 65841e73928SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 65941e73928SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 66041e73928SJames Wright State s, const CeedScalar dqi[5], 66141e73928SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 66241e73928SJames Wright StateFromQi = context->is_primitive ? &StateFromY : &StateFromU; 66341e73928SJames Wright StateFromQi_fwd = context->is_primitive ? &StateFromY_fwd : &StateFromU_fwd; 66441e73928SJames Wright 66504b9037bSJames Wright CeedPragmaSIMD 66604b9037bSJames Wright // Quadrature Point Loop 66704b9037bSJames Wright for (CeedInt i=0; i<Q; i++) { 66804b9037bSJames Wright // Setup 66904b9037bSJames Wright // -- Interp in 67025bfcc41SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 67141e73928SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 67241e73928SJames Wright State s = StateFromQi(context, qi, x_i); 67325bfcc41SJames Wright s.Y.pressure = P0; 67404b9037bSJames Wright 67504b9037bSJames Wright // -- Interp-to-Interp q_data 67604b9037bSJames Wright // For explicit mode, the surface integral is on the RHS of ODE q_dot = f(q). 67704b9037bSJames Wright // For implicit mode, it gets pulled to the LHS of implicit ODE/DAE g(q_dot, q). 67804b9037bSJames Wright // We can effect this by swapping the sign on this weight 67904b9037bSJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 68004b9037bSJames Wright 68104b9037bSJames Wright // ---- Normal vect 68204b9037bSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 68304b9037bSJames Wright q_data_sur[2][i], 68404b9037bSJames Wright q_data_sur[3][i] 68504b9037bSJames Wright }; 68604b9037bSJames Wright 68725bfcc41SJames Wright const CeedScalar dXdx[2][3] = { 68825bfcc41SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 68925bfcc41SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 69025bfcc41SJames Wright }; 69104b9037bSJames Wright 69225bfcc41SJames Wright State grad_s[3]; 69325bfcc41SJames Wright for (CeedInt j=0; j<3; j++) { 69441e73928SJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 69525bfcc41SJames Wright for (CeedInt k=0; k<5; k++) 69641e73928SJames Wright dqi[k] = Grad_q[0][k][i] * dXdx[0][j] + 69725bfcc41SJames Wright Grad_q[1][k][i] * dXdx[1][j]; 69825bfcc41SJames Wright dx_i[j] = 1.; 69941e73928SJames Wright grad_s[j] = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 70025bfcc41SJames Wright } 70125bfcc41SJames Wright 70225bfcc41SJames Wright CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 70325bfcc41SJames Wright KMStrainRate(grad_s, strain_rate); 70425bfcc41SJames Wright NewtonianStress(context, strain_rate, kmstress); 70525bfcc41SJames Wright KMUnpack(kmstress, stress); 70625bfcc41SJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 70725bfcc41SJames Wright 70825bfcc41SJames Wright StateConservative F_inviscid[3]; 70925bfcc41SJames Wright FluxInviscid(context, s, F_inviscid); 71025bfcc41SJames Wright 71125bfcc41SJames Wright CeedScalar Flux[5] = {0.}; 71225bfcc41SJames Wright for (int j=0; j<3; j++) { 71325bfcc41SJames Wright Flux[0] += F_inviscid[j].density * norm[j]; 71425bfcc41SJames Wright for (int k=0; k<3; k++) 71525bfcc41SJames Wright Flux[k+1] += (F_inviscid[j].momentum[k] - stress[k][j]) * norm[j]; 71625bfcc41SJames Wright Flux[4] += (F_inviscid[j].E_total + Fe[j])*norm[j]; 71725bfcc41SJames Wright } 71804b9037bSJames Wright 71904b9037bSJames Wright // -- Density 72025bfcc41SJames Wright v[0][i] = -wdetJb * Flux[0]; 72104b9037bSJames Wright 72204b9037bSJames Wright // -- Momentum 72304b9037bSJames Wright for (CeedInt j=0; j<3; j++) 72425bfcc41SJames Wright v[j+1][i] = -wdetJb * Flux[j+1]; 72504b9037bSJames Wright 72604b9037bSJames Wright // -- Total Energy Density 72725bfcc41SJames Wright v[4][i] = -wdetJb * Flux[4]; 72804b9037bSJames Wright 72904b9037bSJames Wright // Save values for Jacobian 7303934e2b1SJames Wright if (context->is_primitive) { 7313934e2b1SJames Wright jac_data_sur[0][i] = s.Y.pressure; 7323934e2b1SJames Wright for (int j=0; j<3; j++) jac_data_sur[j+1][i] = s.Y.velocity[j]; 7333934e2b1SJames Wright jac_data_sur[4][i] = s.Y.temperature; 7343934e2b1SJames Wright } else { 73525bfcc41SJames Wright jac_data_sur[0][i] = s.U.density; 7363934e2b1SJames Wright for (int j=0; j<3; j++) jac_data_sur[j+1][i] = s.U.momentum[j]; 73725bfcc41SJames Wright jac_data_sur[4][i] = s.U.E_total; 7383934e2b1SJames Wright } 739b01ba163SJames Wright for (int j=0; j<6; j++) jac_data_sur[5+j][i] = kmstress[j]; 74004b9037bSJames Wright } // End Quadrature Point Loop 74104b9037bSJames Wright return 0; 74204b9037bSJames Wright } 74304b9037bSJames Wright 744*d1b9ef12SLeila Ghaffari // ***************************************************************************** 74504b9037bSJames Wright // Jacobian for weak-pressure outflow boundary condition 746*d1b9ef12SLeila Ghaffari // ***************************************************************************** 74704b9037bSJames Wright CEED_QFUNCTION(PressureOutflow_Jacobian)(void *ctx, CeedInt Q, 74841e73928SJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 74904b9037bSJames Wright // *INDENT-OFF* 75004b9037bSJames Wright // Inputs 75104b9037bSJames Wright const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 752b01ba163SJames Wright (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 753b01ba163SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 754b01ba163SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 755b01ba163SJames Wright (*jac_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 75604b9037bSJames Wright // Outputs 75704b9037bSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 75804b9037bSJames Wright // *INDENT-ON* 75904b9037bSJames Wright 76004b9037bSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 76104b9037bSJames Wright const bool implicit = context->is_implicit; 76204b9037bSJames Wright 76341e73928SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 76441e73928SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 76541e73928SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 76641e73928SJames Wright State s, const CeedScalar dQi[5], 76741e73928SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 76841e73928SJames Wright StateFromQi = context->is_primitive ? &StateFromY : &StateFromU; 76941e73928SJames Wright StateFromQi_fwd = context->is_primitive ? &StateFromY_fwd : &StateFromU_fwd; 77041e73928SJames Wright 77104b9037bSJames Wright CeedPragmaSIMD 77204b9037bSJames Wright // Quadrature Point Loop 77304b9037bSJames Wright for (CeedInt i=0; i<Q; i++) { 774b01ba163SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 77504b9037bSJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 77604b9037bSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 77704b9037bSJames Wright q_data_sur[2][i], 77804b9037bSJames Wright q_data_sur[3][i] 77904b9037bSJames Wright }; 780b01ba163SJames Wright const CeedScalar dXdx[2][3] = { 781b01ba163SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 782b01ba163SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 783b01ba163SJames Wright }; 784b01ba163SJames Wright 78541e73928SJames Wright CeedScalar qi[5], kmstress[6], dqi[5], dx_i[3] = {0.}; 78641e73928SJames Wright for (int j=0; j<5; j++) qi[j] = jac_data_sur[j][i]; 787b01ba163SJames Wright for (int j=0; j<6; j++) kmstress[j] = jac_data_sur[5+j][i]; 78841e73928SJames Wright for (int j=0; j<5; j++) dqi[j] = dq[j][i]; 7893934e2b1SJames Wright 79041e73928SJames Wright State s = StateFromQi(context, qi, x_i); 79141e73928SJames Wright State ds = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 792b01ba163SJames Wright s.Y.pressure = context->P0; 793b01ba163SJames Wright ds.Y.pressure = 0.; 794b01ba163SJames Wright 795b01ba163SJames Wright State grad_ds[3]; 796b01ba163SJames Wright for (CeedInt j=0; j<3; j++) { 79741e73928SJames Wright CeedScalar dx_i[3] = {0}, dqi_j[5]; 798b01ba163SJames Wright for (CeedInt k=0; k<5; k++) 79941e73928SJames Wright dqi_j[k] = Grad_dq[0][k][i] * dXdx[0][j] + 800b01ba163SJames Wright Grad_dq[1][k][i] * dXdx[1][j]; 801b01ba163SJames Wright dx_i[j] = 1.; 80241e73928SJames Wright grad_ds[j] = StateFromQi_fwd(context, s, dqi_j, x_i, dx_i); 803b01ba163SJames Wright } 804b01ba163SJames Wright 805b01ba163SJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 806b01ba163SJames Wright KMStrainRate(grad_ds, dstrain_rate); 807b01ba163SJames Wright NewtonianStress(context, dstrain_rate, dkmstress); 808b01ba163SJames Wright KMUnpack(dkmstress, dstress); 809b01ba163SJames Wright KMUnpack(kmstress, stress); 810b01ba163SJames Wright ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 81104b9037bSJames Wright 812e6b47afbSJames Wright StateConservative dF_inviscid[3]; 813e6b47afbSJames Wright FluxInviscid_fwd(context, s, ds, dF_inviscid); 81404b9037bSJames Wright 815e6b47afbSJames Wright CeedScalar dFlux[5] = {0.}; 816e6b47afbSJames Wright for (int j=0; j<3; j++) { 817e6b47afbSJames Wright dFlux[0] += dF_inviscid[j].density * norm[j]; 818e6b47afbSJames Wright for (int k=0; k<3; k++) 819b01ba163SJames Wright dFlux[k+1] += (dF_inviscid[j].momentum[k] - dstress[k][j]) * norm[j]; 820b01ba163SJames Wright dFlux[4] += (dF_inviscid[j].E_total + dFe[j]) * norm[j]; 821e6b47afbSJames Wright } 822e6b47afbSJames Wright 823e6b47afbSJames Wright for (int j=0; j<5; j++) 824e6b47afbSJames Wright v[j][i] = -wdetJb * dFlux[j]; 82504b9037bSJames Wright } // End Quadrature Point Loop 82604b9037bSJames Wright return 0; 82704b9037bSJames Wright } 82804b9037bSJames Wright 8293a8779fbSJames Wright // ***************************************************************************** 830cbe60e31SLeila Ghaffari // This QFunction implements the Navier-Stokes equations (mentioned above) in 831cbe60e31SLeila Ghaffari // primitive variables and with implicit time stepping method 832cbe60e31SLeila Ghaffari // 833cbe60e31SLeila Ghaffari // ***************************************************************************** 834cbe60e31SLeila Ghaffari CEED_QFUNCTION(IFunction_Newtonian_Prim)(void *ctx, CeedInt Q, 835cbe60e31SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 836cbe60e31SLeila Ghaffari // *INDENT-OFF* 837cbe60e31SLeila Ghaffari // Inputs 838cbe60e31SLeila Ghaffari const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 839cbe60e31SLeila Ghaffari (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 840cbe60e31SLeila Ghaffari (*q_dot)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 841cbe60e31SLeila Ghaffari (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 842cbe60e31SLeila Ghaffari (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 843cbe60e31SLeila Ghaffari // Outputs 844cbe60e31SLeila Ghaffari CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 845cbe60e31SLeila Ghaffari (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1], 846cbe60e31SLeila Ghaffari (*jac_data)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[2]; 847cbe60e31SLeila Ghaffari // *INDENT-ON* 848cbe60e31SLeila Ghaffari // Context 849cbe60e31SLeila Ghaffari NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 850cbe60e31SLeila Ghaffari const CeedScalar *g = context->g; 851cbe60e31SLeila Ghaffari const CeedScalar dt = context->dt; 852cbe60e31SLeila Ghaffari 853cbe60e31SLeila Ghaffari CeedPragmaSIMD 854cbe60e31SLeila Ghaffari // Quadrature Point Loop 855cbe60e31SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 856cbe60e31SLeila Ghaffari CeedScalar Y[5]; 857cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) Y[j] = q[j][i]; 858cbe60e31SLeila Ghaffari const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 859cbe60e31SLeila Ghaffari State s = StateFromY(context, Y, x_i); 860cbe60e31SLeila Ghaffari 861cbe60e31SLeila Ghaffari // -- Interp-to-Interp q_data 862cbe60e31SLeila Ghaffari const CeedScalar wdetJ = q_data[0][i]; 863cbe60e31SLeila Ghaffari // -- Interp-to-Grad q_data 864cbe60e31SLeila Ghaffari // ---- Inverse of change of coordinate matrix: X_i,j 865cbe60e31SLeila Ghaffari // *INDENT-OFF* 866cbe60e31SLeila Ghaffari const CeedScalar dXdx[3][3] = {{q_data[1][i], 867cbe60e31SLeila Ghaffari q_data[2][i], 868cbe60e31SLeila Ghaffari q_data[3][i]}, 869cbe60e31SLeila Ghaffari {q_data[4][i], 870cbe60e31SLeila Ghaffari q_data[5][i], 871cbe60e31SLeila Ghaffari q_data[6][i]}, 872cbe60e31SLeila Ghaffari {q_data[7][i], 873cbe60e31SLeila Ghaffari q_data[8][i], 874cbe60e31SLeila Ghaffari q_data[9][i]} 875cbe60e31SLeila Ghaffari }; 876cbe60e31SLeila Ghaffari // *INDENT-ON* 877cbe60e31SLeila Ghaffari State grad_s[3]; 878cbe60e31SLeila Ghaffari for (CeedInt j=0; j<3; j++) { 879cbe60e31SLeila Ghaffari CeedScalar dx_i[3] = {0}, dY[5]; 880cbe60e31SLeila Ghaffari for (CeedInt k=0; k<5; k++) 881cbe60e31SLeila Ghaffari dY[k] = Grad_q[0][k][i] * dXdx[0][j] + 882cbe60e31SLeila Ghaffari Grad_q[1][k][i] * dXdx[1][j] + 883cbe60e31SLeila Ghaffari Grad_q[2][k][i] * dXdx[2][j]; 884cbe60e31SLeila Ghaffari dx_i[j] = 1.; 885cbe60e31SLeila Ghaffari grad_s[j] = StateFromY_fwd(context, s, dY, x_i, dx_i); 886cbe60e31SLeila Ghaffari } 887cbe60e31SLeila Ghaffari 888cbe60e31SLeila Ghaffari CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 889cbe60e31SLeila Ghaffari KMStrainRate(grad_s, strain_rate); 890cbe60e31SLeila Ghaffari NewtonianStress(context, strain_rate, kmstress); 891cbe60e31SLeila Ghaffari KMUnpack(kmstress, stress); 892cbe60e31SLeila Ghaffari ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 893cbe60e31SLeila Ghaffari 894cbe60e31SLeila Ghaffari StateConservative F_inviscid[3]; 895cbe60e31SLeila Ghaffari FluxInviscid(context, s, F_inviscid); 896cbe60e31SLeila Ghaffari 897cbe60e31SLeila Ghaffari // Total flux 898cbe60e31SLeila Ghaffari CeedScalar Flux[5][3]; 899*d1b9ef12SLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 900cbe60e31SLeila Ghaffari 901*d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<3; j++) 902*d1b9ef12SLeila Ghaffari for (CeedInt k=0; k<5; k++) 903cbe60e31SLeila Ghaffari Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * Flux[k][0] + 904cbe60e31SLeila Ghaffari dXdx[j][1] * Flux[k][1] + 905cbe60e31SLeila Ghaffari dXdx[j][2] * Flux[k][2]); 906cbe60e31SLeila Ghaffari 907cbe60e31SLeila Ghaffari const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 908cbe60e31SLeila Ghaffari 909cbe60e31SLeila Ghaffari CeedScalar Y_dot[5], dx0[3] = {0}; 910cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) Y_dot[j] = q_dot[j][i]; 911cbe60e31SLeila Ghaffari State s_dot = StateFromY_fwd(context, s, Y_dot, x_i, dx0); 912cbe60e31SLeila Ghaffari 913cbe60e31SLeila Ghaffari CeedScalar U_dot[5] = {0.}; 914*d1b9ef12SLeila Ghaffari UnpackState_U(s_dot.U, U_dot); 915cbe60e31SLeila Ghaffari 916cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) 917cbe60e31SLeila Ghaffari v[j][i] = wdetJ * (U_dot[j] - body_force[j]); 918cbe60e31SLeila Ghaffari 919*d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 920*d1b9ef12SLeila Ghaffari CeedScalar Tau_d[3], stab[5][3]; 921*d1b9ef12SLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 922*d1b9ef12SLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 923cbe60e31SLeila Ghaffari 924cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) 925cbe60e31SLeila Ghaffari for (CeedInt k=0; k<3; k++) 926cbe60e31SLeila Ghaffari Grad_v[k][j][i] += wdetJ*(stab[j][0] * dXdx[k][0] + 927cbe60e31SLeila Ghaffari stab[j][1] * dXdx[k][1] + 928cbe60e31SLeila Ghaffari stab[j][2] * dXdx[k][2]); 929cbe60e31SLeila Ghaffari 930cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) jac_data[j][i] = Y[j]; 931cbe60e31SLeila Ghaffari for (CeedInt j=0; j<6; j++) jac_data[5+j][i] = kmstress[j]; 932cbe60e31SLeila Ghaffari for (CeedInt j=0; j<3; j++) jac_data[5+6+j][i] = Tau_d[j]; 933cbe60e31SLeila Ghaffari 934cbe60e31SLeila Ghaffari } // End Quadrature Point Loop 935cbe60e31SLeila Ghaffari 936cbe60e31SLeila Ghaffari // Return 937cbe60e31SLeila Ghaffari return 0; 938cbe60e31SLeila Ghaffari } 939cbe60e31SLeila Ghaffari 940cbe60e31SLeila Ghaffari // ***************************************************************************** 941cbe60e31SLeila Ghaffari // This QFunction implements the jacobean of the Navier-Stokes equations 942cbe60e31SLeila Ghaffari // in primitive variables for implicit time stepping method. 943cbe60e31SLeila Ghaffari // 944cbe60e31SLeila Ghaffari // ***************************************************************************** 945cbe60e31SLeila Ghaffari CEED_QFUNCTION(IJacobian_Newtonian_Prim)(void *ctx, CeedInt Q, 946cbe60e31SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 947cbe60e31SLeila Ghaffari // *INDENT-OFF* 948cbe60e31SLeila Ghaffari // Inputs 949cbe60e31SLeila Ghaffari const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 950cbe60e31SLeila Ghaffari (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 951cbe60e31SLeila Ghaffari (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 952cbe60e31SLeila Ghaffari (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 953cbe60e31SLeila Ghaffari (*jac_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 954cbe60e31SLeila Ghaffari // Outputs 955cbe60e31SLeila Ghaffari CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 956cbe60e31SLeila Ghaffari (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1]; 957cbe60e31SLeila Ghaffari // *INDENT-ON* 958cbe60e31SLeila Ghaffari // Context 959cbe60e31SLeila Ghaffari NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 960cbe60e31SLeila Ghaffari const CeedScalar *g = context->g; 961cbe60e31SLeila Ghaffari 962cbe60e31SLeila Ghaffari CeedPragmaSIMD 963cbe60e31SLeila Ghaffari // Quadrature Point Loop 964cbe60e31SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 965cbe60e31SLeila Ghaffari // -- Interp-to-Interp q_data 966cbe60e31SLeila Ghaffari const CeedScalar wdetJ = q_data[0][i]; 967cbe60e31SLeila Ghaffari // -- Interp-to-Grad q_data 968cbe60e31SLeila Ghaffari // ---- Inverse of change of coordinate matrix: X_i,j 969cbe60e31SLeila Ghaffari // *INDENT-OFF* 970cbe60e31SLeila Ghaffari const CeedScalar dXdx[3][3] = {{q_data[1][i], 971cbe60e31SLeila Ghaffari q_data[2][i], 972cbe60e31SLeila Ghaffari q_data[3][i]}, 973cbe60e31SLeila Ghaffari {q_data[4][i], 974cbe60e31SLeila Ghaffari q_data[5][i], 975cbe60e31SLeila Ghaffari q_data[6][i]}, 976cbe60e31SLeila Ghaffari {q_data[7][i], 977cbe60e31SLeila Ghaffari q_data[8][i], 978cbe60e31SLeila Ghaffari q_data[9][i]} 979cbe60e31SLeila Ghaffari }; 980cbe60e31SLeila Ghaffari // *INDENT-ON* 981cbe60e31SLeila Ghaffari 982cbe60e31SLeila Ghaffari CeedScalar Y[5], kmstress[6], Tau_d[3] __attribute((unused)); 983cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) Y[j] = jac_data[j][i]; 984cbe60e31SLeila Ghaffari for (int j=0; j<6; j++) kmstress[j] = jac_data[5+j][i]; 985cbe60e31SLeila Ghaffari for (int j=0; j<3; j++) Tau_d[j] = jac_data[5+6+j][i]; 986cbe60e31SLeila Ghaffari const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 987cbe60e31SLeila Ghaffari State s = StateFromY(context, Y, x_i); 988cbe60e31SLeila Ghaffari 989cbe60e31SLeila Ghaffari CeedScalar dY[5], dx0[3] = {0}; 990cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) dY[j] = dq[j][i]; 991cbe60e31SLeila Ghaffari State ds = StateFromY_fwd(context, s, dY, x_i, dx0); 992cbe60e31SLeila Ghaffari 993cbe60e31SLeila Ghaffari State grad_ds[3]; 994cbe60e31SLeila Ghaffari for (int j=0; j<3; j++) { 995cbe60e31SLeila Ghaffari CeedScalar dYj[5]; 996cbe60e31SLeila Ghaffari for (int k=0; k<5; k++) 997cbe60e31SLeila Ghaffari dYj[k] = Grad_dq[0][k][i] * dXdx[0][j] + 998cbe60e31SLeila Ghaffari Grad_dq[1][k][i] * dXdx[1][j] + 999cbe60e31SLeila Ghaffari Grad_dq[2][k][i] * dXdx[2][j]; 1000cbe60e31SLeila Ghaffari grad_ds[j] = StateFromY_fwd(context, s, dYj, x_i, dx0); 1001cbe60e31SLeila Ghaffari } 1002cbe60e31SLeila Ghaffari 1003cbe60e31SLeila Ghaffari CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 1004cbe60e31SLeila Ghaffari KMStrainRate(grad_ds, dstrain_rate); 1005cbe60e31SLeila Ghaffari NewtonianStress(context, dstrain_rate, dkmstress); 1006cbe60e31SLeila Ghaffari KMUnpack(dkmstress, dstress); 1007cbe60e31SLeila Ghaffari KMUnpack(kmstress, stress); 1008cbe60e31SLeila Ghaffari ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 1009cbe60e31SLeila Ghaffari 1010cbe60e31SLeila Ghaffari StateConservative dF_inviscid[3]; 1011cbe60e31SLeila Ghaffari FluxInviscid_fwd(context, s, ds, dF_inviscid); 1012cbe60e31SLeila Ghaffari 1013cbe60e31SLeila Ghaffari // Total flux 1014cbe60e31SLeila Ghaffari CeedScalar dFlux[5][3]; 1015*d1b9ef12SLeila Ghaffari FluxTotal(dF_inviscid, dstress, dFe, dFlux); 1016cbe60e31SLeila Ghaffari 1017*d1b9ef12SLeila Ghaffari for (int j=0; j<3; j++) 1018*d1b9ef12SLeila Ghaffari for (int k=0; k<5; k++) 1019cbe60e31SLeila Ghaffari Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * dFlux[k][0] + 1020cbe60e31SLeila Ghaffari dXdx[j][1] * dFlux[k][1] + 1021cbe60e31SLeila Ghaffari dXdx[j][2] * dFlux[k][2]); 1022cbe60e31SLeila Ghaffari 1023*d1b9ef12SLeila Ghaffari const CeedScalar dbody_force[5] = {0, ds.U.density *g[0], ds.U.density *g[1], ds.U.density *g[2], 0}; 1024cbe60e31SLeila Ghaffari CeedScalar dU[5] = {0.}; 1025*d1b9ef12SLeila Ghaffari UnpackState_U(ds.U, dU); 1026cbe60e31SLeila Ghaffari 1027cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) 1028cbe60e31SLeila Ghaffari v[j][i] = wdetJ * (context->ijacobian_time_shift * dU[j] - dbody_force[j]); 1029cbe60e31SLeila Ghaffari 1030*d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 1031*d1b9ef12SLeila Ghaffari CeedScalar dstab[5][3], U_dot[5] = {0}; 1032*d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = context->ijacobian_time_shift * dU[j]; 1033*d1b9ef12SLeila Ghaffari Stabilization(context, s, Tau_d, grad_ds, U_dot, dbody_force, x_i, dstab); 1034cbe60e31SLeila Ghaffari 1035cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) 1036cbe60e31SLeila Ghaffari for (int k=0; k<3; k++) 1037cbe60e31SLeila Ghaffari Grad_v[k][j][i] += wdetJ*(dstab[j][0] * dXdx[k][0] + 1038cbe60e31SLeila Ghaffari dstab[j][1] * dXdx[k][1] + 1039cbe60e31SLeila Ghaffari dstab[j][2] * dXdx[k][2]); 1040cbe60e31SLeila Ghaffari 1041cbe60e31SLeila Ghaffari } // End Quadrature Point Loop 1042cbe60e31SLeila Ghaffari return 0; 1043cbe60e31SLeila Ghaffari } 1044cbe60e31SLeila Ghaffari // ***************************************************************************** 1045cbe60e31SLeila Ghaffari 10463a8779fbSJames Wright #endif // newtonian_h 1047