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 <ceed.h> 16d0cce58aSJeremy L Thompson #include <math.h> 17475b2820SJames Wright #include "newtonian_state.h" 18d0cce58aSJeremy L Thompson #include "newtonian_types.h" 19d1b9ef12SLeila Ghaffari #include "stabilization.h" 20d0cce58aSJeremy L Thompson #include "utils.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]}; 50d1b9ef12SLeila 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]; 64d1b9ef12SLeila 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* 18234ea8d65SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 18334ea8d65SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 18434ea8d65SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 1853a8779fbSJames Wright }; 1863a8779fbSJames Wright // *INDENT-ON* 187c1a52365SJed Brown State grad_s[3]; 188eef2387dSJed Brown for (CeedInt j=0; j<3; j++) { 1892f7ce6c1SJed Brown CeedScalar dx_i[3] = {0}, dU[5]; 1902556a851SJed Brown for (CeedInt k=0; k<5; k++) 1912556a851SJed Brown dU[k] = Grad_q[0][k][i] * dXdx[0][j] + 1922556a851SJed Brown Grad_q[1][k][i] * dXdx[1][j] + 1932556a851SJed Brown Grad_q[2][k][i] * dXdx[2][j]; 194c1a52365SJed Brown dx_i[j] = 1.; 1952f7ce6c1SJed Brown grad_s[j] = StateFromU_fwd(context, s, dU, x_i, dx_i); 196c1a52365SJed Brown } 197c1a52365SJed Brown 198c1a52365SJed Brown CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 199c1a52365SJed Brown KMStrainRate(grad_s, strain_rate); 200c1a52365SJed Brown NewtonianStress(context, strain_rate, kmstress); 201c1a52365SJed Brown KMUnpack(kmstress, stress); 202c1a52365SJed Brown ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 203c1a52365SJed Brown 204c1a52365SJed Brown StateConservative F_inviscid[3]; 205c1a52365SJed Brown FluxInviscid(context, s, F_inviscid); 206c1a52365SJed Brown 207c1a52365SJed Brown // Total flux 208c1a52365SJed Brown CeedScalar Flux[5][3]; 209d1b9ef12SLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 210c1a52365SJed Brown 211d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<3; j++) 212d1b9ef12SLeila Ghaffari for (CeedInt k=0; k<5; k++) 213752f40e3SJed Brown Grad_v[j][k][i] = wdetJ * (dXdx[j][0] * Flux[k][0] + 214c1a52365SJed Brown dXdx[j][1] * Flux[k][1] + 215c1a52365SJed Brown dXdx[j][2] * Flux[k][2]); 216c1a52365SJed Brown 217c1a52365SJed Brown const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 218c1a52365SJed Brown for (int j=0; j<5; j++) 219c1a52365SJed Brown v[j][i] = wdetJ * body_force[j]; 2203a8779fbSJames Wright 221d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 222d1b9ef12SLeila Ghaffari CeedScalar Tau_d[3], stab[5][3], U_dot[5] = {0}; 223d1b9ef12SLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 224d1b9ef12SLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 2253a8779fbSJames Wright 226493642f1SJames Wright for (CeedInt j=0; j<5; j++) 227493642f1SJames Wright for (CeedInt k=0; k<3; k++) 228752f40e3SJed Brown Grad_v[k][j][i] -= wdetJ*(stab[j][0] * dXdx[k][0] + 2293a8779fbSJames Wright stab[j][1] * dXdx[k][1] + 2303a8779fbSJames Wright stab[j][2] * dXdx[k][2]); 2313a8779fbSJames Wright 2323a8779fbSJames Wright } // End Quadrature Point Loop 2333a8779fbSJames Wright 2343a8779fbSJames Wright // Return 2353a8779fbSJames Wright return 0; 2363a8779fbSJames Wright } 2373a8779fbSJames Wright 2383a8779fbSJames Wright // ***************************************************************************** 2393a8779fbSJames Wright // This QFunction implements the Navier-Stokes equations (mentioned above) with 2403a8779fbSJames Wright // implicit time stepping method 2413a8779fbSJames Wright // 2423a8779fbSJames Wright // SU = Galerkin + grad(v) . ( Ai^T * Tau * (Aj q,j) ) 2433a8779fbSJames Wright // SUPG = Galerkin + grad(v) . ( Ai^T * Tau * (q_dot + Aj q,j - body force) ) 2443a8779fbSJames Wright // (diffussive terms will be added later) 2453a8779fbSJames Wright // 2463a8779fbSJames Wright // ***************************************************************************** 2473a8779fbSJames Wright CEED_QFUNCTION(IFunction_Newtonian)(void *ctx, CeedInt Q, 248cbe60e31SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 2493a8779fbSJames Wright // *INDENT-OFF* 2503a8779fbSJames Wright // Inputs 2513a8779fbSJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 252752f40e3SJed Brown (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 2533a8779fbSJames Wright (*q_dot)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 2543a8779fbSJames Wright (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 2553a8779fbSJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 2563a8779fbSJames Wright // Outputs 2573a8779fbSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 258752f40e3SJed Brown (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1], 259752f40e3SJed Brown (*jac_data)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[2]; 2603a8779fbSJames Wright // *INDENT-ON* 2613a8779fbSJames Wright // Context 2623a8779fbSJames Wright NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 263bb8a0c61SJames Wright const CeedScalar *g = context->g; 264bb8a0c61SJames Wright const CeedScalar dt = context->dt; 2653a8779fbSJames Wright 2663a8779fbSJames Wright CeedPragmaSIMD 2673a8779fbSJames Wright // Quadrature Point Loop 2683a8779fbSJames Wright for (CeedInt i=0; i<Q; i++) { 269c1a52365SJed Brown CeedScalar U[5]; 270eef2387dSJed Brown for (CeedInt j=0; j<5; j++) U[j] = q[j][i]; 271c1a52365SJed Brown const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 272c1a52365SJed Brown State s = StateFromU(context, U, x_i); 273c1a52365SJed Brown 2743a8779fbSJames Wright // -- Interp-to-Interp q_data 2753a8779fbSJames Wright const CeedScalar wdetJ = q_data[0][i]; 2763a8779fbSJames Wright // -- Interp-to-Grad q_data 2773a8779fbSJames Wright // ---- Inverse of change of coordinate matrix: X_i,j 2783a8779fbSJames Wright // *INDENT-OFF* 27934ea8d65SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 28034ea8d65SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 28134ea8d65SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 2823a8779fbSJames Wright }; 2833a8779fbSJames Wright // *INDENT-ON* 284c1a52365SJed Brown State grad_s[3]; 285493642f1SJames Wright for (CeedInt j=0; j<3; j++) { 2862f7ce6c1SJed Brown CeedScalar dx_i[3] = {0}, dU[5]; 2872556a851SJed Brown for (CeedInt k=0; k<5; k++) 2882556a851SJed Brown dU[k] = Grad_q[0][k][i] * dXdx[0][j] + 2892556a851SJed Brown Grad_q[1][k][i] * dXdx[1][j] + 2902556a851SJed Brown Grad_q[2][k][i] * dXdx[2][j]; 291c1a52365SJed Brown dx_i[j] = 1.; 2922f7ce6c1SJed Brown grad_s[j] = StateFromU_fwd(context, s, dU, x_i, dx_i); 2933a8779fbSJames Wright } 294c1a52365SJed Brown 295c1a52365SJed Brown CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 296c1a52365SJed Brown KMStrainRate(grad_s, strain_rate); 297c1a52365SJed Brown NewtonianStress(context, strain_rate, kmstress); 298c1a52365SJed Brown KMUnpack(kmstress, stress); 299c1a52365SJed Brown ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 300c1a52365SJed Brown 301c1a52365SJed Brown StateConservative F_inviscid[3]; 302c1a52365SJed Brown FluxInviscid(context, s, F_inviscid); 303c1a52365SJed Brown 304c1a52365SJed Brown // Total flux 305c1a52365SJed Brown CeedScalar Flux[5][3]; 306d1b9ef12SLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 307c1a52365SJed Brown 308d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<3; j++) 309d1b9ef12SLeila Ghaffari for (CeedInt k=0; k<5; k++) 310752f40e3SJed Brown Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * Flux[k][0] + 311c1a52365SJed Brown dXdx[j][1] * Flux[k][1] + 312c1a52365SJed Brown dXdx[j][2] * Flux[k][2]); 313c1a52365SJed Brown 314c1a52365SJed Brown const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 315eef2387dSJed Brown for (CeedInt j=0; j<5; j++) 316c1a52365SJed Brown v[j][i] = wdetJ * (q_dot[j][i] - body_force[j]); 3173a8779fbSJames Wright 318d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 319d1b9ef12SLeila Ghaffari CeedScalar Tau_d[3], stab[5][3], U_dot[5] = {0}; 320d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = q_dot[j][i]; 321d1b9ef12SLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 322d1b9ef12SLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 3233a8779fbSJames Wright 324493642f1SJames Wright for (CeedInt j=0; j<5; j++) 325493642f1SJames Wright for (CeedInt k=0; k<3; k++) 326752f40e3SJed Brown Grad_v[k][j][i] += wdetJ*(stab[j][0] * dXdx[k][0] + 3273a8779fbSJames Wright stab[j][1] * dXdx[k][1] + 3283a8779fbSJames Wright stab[j][2] * dXdx[k][2]); 329eef2387dSJed Brown 330eef2387dSJed Brown for (CeedInt j=0; j<5; j++) jac_data[j][i] = U[j]; 331eef2387dSJed Brown for (CeedInt j=0; j<6; j++) jac_data[5+j][i] = kmstress[j]; 332eef2387dSJed Brown for (CeedInt j=0; j<3; j++) jac_data[5+6+j][i] = Tau_d[j]; 3333a8779fbSJames Wright 3343a8779fbSJames Wright } // End Quadrature Point Loop 3353a8779fbSJames Wright 3363a8779fbSJames Wright // Return 3373a8779fbSJames Wright return 0; 3383a8779fbSJames Wright } 339f0b65372SJed Brown 340cbe60e31SLeila Ghaffari // ***************************************************************************** 341cbe60e31SLeila Ghaffari // This QFunction implements the jacobean of the Navier-Stokes equations 342cbe60e31SLeila Ghaffari // for implicit time stepping method. 343cbe60e31SLeila Ghaffari // 344cbe60e31SLeila Ghaffari // ***************************************************************************** 345f0b65372SJed Brown CEED_QFUNCTION(IJacobian_Newtonian)(void *ctx, CeedInt Q, 346f0b65372SJed Brown const CeedScalar *const *in, 347f0b65372SJed Brown CeedScalar *const *out) { 348f0b65372SJed Brown // *INDENT-OFF* 349f0b65372SJed Brown // Inputs 350f0b65372SJed Brown const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 351f0b65372SJed Brown (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 352f0b65372SJed Brown (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 353f0b65372SJed Brown (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 354f0b65372SJed Brown (*jac_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 355f0b65372SJed Brown // Outputs 356f0b65372SJed Brown CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 357f0b65372SJed Brown (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1]; 358f0b65372SJed Brown // *INDENT-ON* 359f0b65372SJed Brown // Context 360f0b65372SJed Brown NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 361f0b65372SJed Brown const CeedScalar *g = context->g; 362f0b65372SJed Brown 363f0b65372SJed Brown CeedPragmaSIMD 364f0b65372SJed Brown // Quadrature Point Loop 365f0b65372SJed Brown for (CeedInt i=0; i<Q; i++) { 366f0b65372SJed Brown // -- Interp-to-Interp q_data 367f0b65372SJed Brown const CeedScalar wdetJ = q_data[0][i]; 368f0b65372SJed Brown // -- Interp-to-Grad q_data 369f0b65372SJed Brown // ---- Inverse of change of coordinate matrix: X_i,j 370f0b65372SJed Brown // *INDENT-OFF* 37134ea8d65SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 37234ea8d65SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 37334ea8d65SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 374f0b65372SJed Brown }; 375f0b65372SJed Brown // *INDENT-ON* 376f0b65372SJed Brown 377f0b65372SJed Brown CeedScalar U[5], kmstress[6], Tau_d[3] __attribute((unused)); 378f0b65372SJed Brown for (int j=0; j<5; j++) U[j] = jac_data[j][i]; 379f0b65372SJed Brown for (int j=0; j<6; j++) kmstress[j] = jac_data[5+j][i]; 380f0b65372SJed Brown for (int j=0; j<3; j++) Tau_d[j] = jac_data[5+6+j][i]; 381f0b65372SJed Brown const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 382f0b65372SJed Brown State s = StateFromU(context, U, x_i); 383f0b65372SJed Brown 384f0b65372SJed Brown CeedScalar dU[5], dx0[3] = {0}; 385f0b65372SJed Brown for (int j=0; j<5; j++) dU[j] = dq[j][i]; 386f0b65372SJed Brown State ds = StateFromU_fwd(context, s, dU, x_i, dx0); 387f0b65372SJed Brown 388f0b65372SJed Brown State grad_ds[3]; 389f0b65372SJed Brown for (int j=0; j<3; j++) { 390f0b65372SJed Brown CeedScalar dUj[5]; 391d1b9ef12SLeila Ghaffari for (int k=0; k<5; k++) 392d1b9ef12SLeila Ghaffari dUj[k] = Grad_dq[0][k][i] * dXdx[0][j] + 393d1b9ef12SLeila Ghaffari Grad_dq[1][k][i] * dXdx[1][j] + 394d1b9ef12SLeila Ghaffari Grad_dq[2][k][i] * dXdx[2][j]; 395f0b65372SJed Brown grad_ds[j] = StateFromU_fwd(context, s, dUj, x_i, dx0); 396f0b65372SJed Brown } 397f0b65372SJed Brown 398f0b65372SJed Brown CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 399f0b65372SJed Brown KMStrainRate(grad_ds, dstrain_rate); 400f0b65372SJed Brown NewtonianStress(context, dstrain_rate, dkmstress); 401f0b65372SJed Brown KMUnpack(dkmstress, dstress); 402f0b65372SJed Brown KMUnpack(kmstress, stress); 403f0b65372SJed Brown ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 404f0b65372SJed Brown 405f0b65372SJed Brown StateConservative dF_inviscid[3]; 406f0b65372SJed Brown FluxInviscid_fwd(context, s, ds, dF_inviscid); 407f0b65372SJed Brown 408f0b65372SJed Brown // Total flux 409f0b65372SJed Brown CeedScalar dFlux[5][3]; 410d1b9ef12SLeila Ghaffari FluxTotal(dF_inviscid, dstress, dFe, dFlux); 411f0b65372SJed Brown 412d1b9ef12SLeila Ghaffari for (int j=0; j<3; j++) 413d1b9ef12SLeila Ghaffari for (int k=0; k<5; k++) 414f0b65372SJed Brown Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * dFlux[k][0] + 415f0b65372SJed Brown dXdx[j][1] * dFlux[k][1] + 416f0b65372SJed Brown dXdx[j][2] * dFlux[k][2]); 417f0b65372SJed Brown 418f0b65372SJed Brown const CeedScalar dbody_force[5] = {0, ds.U.density *g[0], ds.U.density *g[1], ds.U.density *g[2], 0}; 419f0b65372SJed Brown for (int j=0; j<5; j++) 420f0b65372SJed Brown v[j][i] = wdetJ * (context->ijacobian_time_shift * dU[j] - dbody_force[j]); 421f0b65372SJed Brown 422d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 423d1b9ef12SLeila Ghaffari CeedScalar dstab[5][3], U_dot[5] = {0}; 424d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = context->ijacobian_time_shift * dU[j]; 425d1b9ef12SLeila Ghaffari Stabilization(context, s, Tau_d, grad_ds, U_dot, dbody_force, x_i, dstab); 426d1b9ef12SLeila Ghaffari 427f0b65372SJed Brown for (int j=0; j<5; j++) 428f0b65372SJed Brown for (int k=0; k<3; k++) 429f0b65372SJed Brown Grad_v[k][j][i] += wdetJ*(dstab[j][0] * dXdx[k][0] + 430f0b65372SJed Brown dstab[j][1] * dXdx[k][1] + 431f0b65372SJed Brown dstab[j][2] * dXdx[k][2]); 432f0b65372SJed Brown 433f0b65372SJed Brown } // End Quadrature Point Loop 434f0b65372SJed Brown return 0; 435f0b65372SJed Brown } 4368085925cSJames Wright 437d1b9ef12SLeila Ghaffari // ***************************************************************************** 4388085925cSJames Wright // Compute boundary integral (ie. for strongly set inflows) 439d1b9ef12SLeila Ghaffari // ***************************************************************************** 4408085925cSJames Wright CEED_QFUNCTION(BoundaryIntegral)(void *ctx, CeedInt Q, 4418085925cSJames Wright const CeedScalar *const *in, 4428085925cSJames Wright CeedScalar *const *out) { 4438085925cSJames Wright 4448085925cSJames Wright //*INDENT-OFF* 4458085925cSJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 446d3b25f3aSJames Wright (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 447d3b25f3aSJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 448d3b25f3aSJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 4498085925cSJames Wright 45068ae065aSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA]) out[0], 45168ae065aSJames Wright (*jac_data_sur)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA]) out[1]; 4528085925cSJames Wright 4538085925cSJames Wright //*INDENT-ON* 4548085925cSJames Wright 455d3b25f3aSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext) ctx; 456d3b25f3aSJames Wright const bool is_implicit = context->is_implicit; 45741e73928SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 45841e73928SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 45941e73928SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 46041e73928SJames Wright State s, const CeedScalar dqi[5], 46141e73928SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 46234ea8d65SJames Wright StateFromQi = context->use_primitive ? &StateFromY : &StateFromU; 46334ea8d65SJames Wright StateFromQi_fwd = context->use_primitive ? &StateFromY_fwd : &StateFromU_fwd; 46441e73928SJames Wright 4658085925cSJames Wright 4668085925cSJames Wright CeedPragmaSIMD 4678085925cSJames Wright for(CeedInt i=0; i<Q; i++) { 468d3b25f3aSJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 46941e73928SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 47041e73928SJames Wright State s = StateFromQi(context, qi, x_i); 4718085925cSJames Wright 4728085925cSJames Wright const CeedScalar wdetJb = (is_implicit ? -1. : 1.) * q_data_sur[0][i]; 473*c5740391SJames Wright // ---- Normal vector 4748085925cSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 4758085925cSJames Wright q_data_sur[2][i], 4768085925cSJames Wright q_data_sur[3][i] 4778085925cSJames Wright }; 4788085925cSJames Wright 479d3b25f3aSJames Wright const CeedScalar dXdx[2][3] = { 480d3b25f3aSJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 481d3b25f3aSJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 482d3b25f3aSJames Wright }; 4838085925cSJames Wright 484d3b25f3aSJames Wright State grad_s[3]; 485d3b25f3aSJames Wright for (CeedInt j=0; j<3; j++) { 48641e73928SJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 487d3b25f3aSJames Wright for (CeedInt k=0; k<5; k++) 48841e73928SJames Wright dqi[k] = Grad_q[0][k][i] * dXdx[0][j] + 489d3b25f3aSJames Wright Grad_q[1][k][i] * dXdx[1][j]; 490d3b25f3aSJames Wright dx_i[j] = 1.; 49141e73928SJames Wright grad_s[j] = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 492d3b25f3aSJames Wright } 4938085925cSJames Wright 494d3b25f3aSJames Wright CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 495d3b25f3aSJames Wright KMStrainRate(grad_s, strain_rate); 496d3b25f3aSJames Wright NewtonianStress(context, strain_rate, kmstress); 497d3b25f3aSJames Wright KMUnpack(kmstress, stress); 498d3b25f3aSJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 499d3b25f3aSJames Wright 500d3b25f3aSJames Wright StateConservative F_inviscid[3]; 501d3b25f3aSJames Wright FluxInviscid(context, s, F_inviscid); 502d3b25f3aSJames Wright 503*c5740391SJames Wright CeedScalar Flux[5]; 504*c5740391SJames Wright FluxTotal_Boundary(F_inviscid, stress, Fe, norm, Flux); 505d3b25f3aSJames Wright 506*c5740391SJames Wright for (CeedInt j=0; j<5; j++) v[j][i] = -wdetJb * Flux[j]; 5078085925cSJames Wright 508*c5740391SJames Wright for (int j=0; j<5; j++) jac_data_sur[j][i] = qi[j]; 50968ae065aSJames Wright for (int j=0; j<6; j++) jac_data_sur[5+j][i] = kmstress[j]; 5108085925cSJames Wright } 5118085925cSJames Wright return 0; 5128085925cSJames Wright } 5138085925cSJames Wright 514d1b9ef12SLeila Ghaffari // ***************************************************************************** 51568ae065aSJames Wright // Jacobian for "set nothing" boundary integral 516d1b9ef12SLeila Ghaffari // ***************************************************************************** 51768ae065aSJames Wright CEED_QFUNCTION(BoundaryIntegral_Jacobian)(void *ctx, CeedInt Q, 51868ae065aSJames Wright const CeedScalar *const *in, 51968ae065aSJames Wright CeedScalar *const *out) { 52068ae065aSJames Wright // *INDENT-OFF* 52168ae065aSJames Wright // Inputs 52268ae065aSJames Wright const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 52368ae065aSJames Wright (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 52468ae065aSJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 52568ae065aSJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 52668ae065aSJames Wright (*jac_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 52768ae065aSJames Wright // Outputs 52868ae065aSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 52968ae065aSJames Wright // *INDENT-ON* 53068ae065aSJames Wright 53168ae065aSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 53268ae065aSJames Wright const bool implicit = context->is_implicit; 53341e73928SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 53441e73928SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 53541e73928SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 53641e73928SJames Wright State s, const CeedScalar dqi[5], 53741e73928SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 53834ea8d65SJames Wright StateFromQi = context->use_primitive ? &StateFromY : &StateFromU; 53934ea8d65SJames Wright StateFromQi_fwd = context->use_primitive ? &StateFromY_fwd : &StateFromU_fwd; 54068ae065aSJames Wright 54168ae065aSJames Wright CeedPragmaSIMD 54268ae065aSJames Wright // Quadrature Point Loop 54368ae065aSJames Wright for (CeedInt i=0; i<Q; i++) { 54468ae065aSJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 54568ae065aSJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 54668ae065aSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 54768ae065aSJames Wright q_data_sur[2][i], 54868ae065aSJames Wright q_data_sur[3][i] 54968ae065aSJames Wright }; 55068ae065aSJames Wright const CeedScalar dXdx[2][3] = { 55168ae065aSJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 55268ae065aSJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 55368ae065aSJames Wright }; 55468ae065aSJames Wright 55541e73928SJames Wright CeedScalar qi[5], kmstress[6], dqi[5], dx_i[3] = {0.}; 55641e73928SJames Wright for (int j=0; j<5; j++) qi[j] = jac_data_sur[j][i]; 55768ae065aSJames Wright for (int j=0; j<6; j++) kmstress[j] = jac_data_sur[5+j][i]; 55841e73928SJames Wright for (int j=0; j<5; j++) dqi[j] = dq[j][i]; 5593934e2b1SJames Wright 56041e73928SJames Wright State s = StateFromQi(context, qi, x_i); 56141e73928SJames Wright State ds = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 56268ae065aSJames Wright 56368ae065aSJames Wright State grad_ds[3]; 56468ae065aSJames Wright for (CeedInt j=0; j<3; j++) { 56541e73928SJames Wright CeedScalar dx_i[3] = {0}, dqi_j[5]; 56668ae065aSJames Wright for (CeedInt k=0; k<5; k++) 56741e73928SJames Wright dqi_j[k] = Grad_dq[0][k][i] * dXdx[0][j] + 56868ae065aSJames Wright Grad_dq[1][k][i] * dXdx[1][j]; 56968ae065aSJames Wright dx_i[j] = 1.; 57041e73928SJames Wright grad_ds[j] = StateFromQi_fwd(context, s, dqi_j, x_i, dx_i); 57168ae065aSJames Wright } 57268ae065aSJames Wright 57368ae065aSJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 57468ae065aSJames Wright KMStrainRate(grad_ds, dstrain_rate); 57568ae065aSJames Wright NewtonianStress(context, dstrain_rate, dkmstress); 57668ae065aSJames Wright KMUnpack(dkmstress, dstress); 57768ae065aSJames Wright KMUnpack(kmstress, stress); 57868ae065aSJames Wright ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 57968ae065aSJames Wright 58068ae065aSJames Wright StateConservative dF_inviscid[3]; 58168ae065aSJames Wright FluxInviscid_fwd(context, s, ds, dF_inviscid); 58268ae065aSJames Wright 583*c5740391SJames Wright CeedScalar dFlux[5]; 584*c5740391SJames Wright FluxTotal_Boundary(dF_inviscid, dstress, dFe, norm, dFlux); 58568ae065aSJames Wright 586*c5740391SJames Wright for (int j=0; j<5; j++) v[j][i] = -wdetJb * dFlux[j]; 58768ae065aSJames Wright } // End Quadrature Point Loop 58868ae065aSJames Wright return 0; 58968ae065aSJames Wright } 59068ae065aSJames Wright 591d1b9ef12SLeila Ghaffari // ***************************************************************************** 59204b9037bSJames Wright // Outflow boundary condition, weakly setting a constant pressure 593d1b9ef12SLeila Ghaffari // ***************************************************************************** 59404b9037bSJames Wright CEED_QFUNCTION(PressureOutflow)(void *ctx, CeedInt Q, 59504b9037bSJames Wright const CeedScalar *const *in, 59604b9037bSJames Wright CeedScalar *const *out) { 59704b9037bSJames Wright // *INDENT-OFF* 59804b9037bSJames Wright // Inputs 59904b9037bSJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 60025bfcc41SJames Wright (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 60125bfcc41SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 60225bfcc41SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 60304b9037bSJames Wright // Outputs 60404b9037bSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 60504b9037bSJames Wright (*jac_data_sur)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[1]; 60604b9037bSJames Wright // *INDENT-ON* 60704b9037bSJames Wright 60804b9037bSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 60904b9037bSJames Wright const bool implicit = context->is_implicit; 61004b9037bSJames Wright const CeedScalar P0 = context->P0; 61104b9037bSJames Wright 61241e73928SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 61341e73928SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 61441e73928SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 61541e73928SJames Wright State s, const CeedScalar dqi[5], 61641e73928SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 61734ea8d65SJames Wright StateFromQi = context->use_primitive ? &StateFromY : &StateFromU; 61834ea8d65SJames Wright StateFromQi_fwd = context->use_primitive ? &StateFromY_fwd : &StateFromU_fwd; 61941e73928SJames Wright 62004b9037bSJames Wright CeedPragmaSIMD 62104b9037bSJames Wright // Quadrature Point Loop 62204b9037bSJames Wright for (CeedInt i=0; i<Q; i++) { 62304b9037bSJames Wright // Setup 62404b9037bSJames Wright // -- Interp in 62525bfcc41SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 62641e73928SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 62741e73928SJames Wright State s = StateFromQi(context, qi, x_i); 62825bfcc41SJames Wright s.Y.pressure = P0; 62904b9037bSJames Wright 63004b9037bSJames Wright // -- Interp-to-Interp q_data 63104b9037bSJames Wright // For explicit mode, the surface integral is on the RHS of ODE q_dot = f(q). 63204b9037bSJames Wright // For implicit mode, it gets pulled to the LHS of implicit ODE/DAE g(q_dot, q). 63304b9037bSJames Wright // We can effect this by swapping the sign on this weight 63404b9037bSJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 63504b9037bSJames Wright 636*c5740391SJames Wright // ---- Normal vector 63704b9037bSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 63804b9037bSJames Wright q_data_sur[2][i], 63904b9037bSJames Wright q_data_sur[3][i] 64004b9037bSJames Wright }; 64104b9037bSJames Wright 64225bfcc41SJames Wright const CeedScalar dXdx[2][3] = { 64325bfcc41SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 64425bfcc41SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 64525bfcc41SJames Wright }; 64604b9037bSJames Wright 64725bfcc41SJames Wright State grad_s[3]; 64825bfcc41SJames Wright for (CeedInt j=0; j<3; j++) { 64941e73928SJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 65025bfcc41SJames Wright for (CeedInt k=0; k<5; k++) 65141e73928SJames Wright dqi[k] = Grad_q[0][k][i] * dXdx[0][j] + 65225bfcc41SJames Wright Grad_q[1][k][i] * dXdx[1][j]; 65325bfcc41SJames Wright dx_i[j] = 1.; 65441e73928SJames Wright grad_s[j] = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 65525bfcc41SJames Wright } 65625bfcc41SJames Wright 65725bfcc41SJames Wright CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 65825bfcc41SJames Wright KMStrainRate(grad_s, strain_rate); 65925bfcc41SJames Wright NewtonianStress(context, strain_rate, kmstress); 66025bfcc41SJames Wright KMUnpack(kmstress, stress); 66125bfcc41SJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 66225bfcc41SJames Wright 66325bfcc41SJames Wright StateConservative F_inviscid[3]; 66425bfcc41SJames Wright FluxInviscid(context, s, F_inviscid); 66525bfcc41SJames Wright 666*c5740391SJames Wright CeedScalar Flux[5]; 667*c5740391SJames Wright FluxTotal_Boundary(F_inviscid, stress, Fe, norm, Flux); 66804b9037bSJames Wright 669*c5740391SJames Wright for (CeedInt j=0; j<5; j++) v[j][i] = -wdetJb * Flux[j]; 67004b9037bSJames Wright 67104b9037bSJames Wright // Save values for Jacobian 672*c5740391SJames Wright for (int j=0; j<5; j++) jac_data_sur[j][i] = qi[j]; 673b01ba163SJames Wright for (int j=0; j<6; j++) jac_data_sur[5+j][i] = kmstress[j]; 67404b9037bSJames Wright } // End Quadrature Point Loop 67504b9037bSJames Wright return 0; 67604b9037bSJames Wright } 67704b9037bSJames Wright 678d1b9ef12SLeila Ghaffari // ***************************************************************************** 67904b9037bSJames Wright // Jacobian for weak-pressure outflow boundary condition 680d1b9ef12SLeila Ghaffari // ***************************************************************************** 68104b9037bSJames Wright CEED_QFUNCTION(PressureOutflow_Jacobian)(void *ctx, CeedInt Q, 68241e73928SJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 68304b9037bSJames Wright // *INDENT-OFF* 68404b9037bSJames Wright // Inputs 68504b9037bSJames Wright const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 686b01ba163SJames Wright (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 687b01ba163SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 688b01ba163SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 689b01ba163SJames Wright (*jac_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 69004b9037bSJames Wright // Outputs 69104b9037bSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 69204b9037bSJames Wright // *INDENT-ON* 69304b9037bSJames Wright 69404b9037bSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 69504b9037bSJames Wright const bool implicit = context->is_implicit; 69604b9037bSJames Wright 69741e73928SJames Wright State (*StateFromQi)(NewtonianIdealGasContext gas, 69841e73928SJames Wright const CeedScalar qi[5], const CeedScalar x[3]); 69941e73928SJames Wright State (*StateFromQi_fwd)(NewtonianIdealGasContext gas, 70041e73928SJames Wright State s, const CeedScalar dQi[5], 70141e73928SJames Wright const CeedScalar x[3], const CeedScalar dx[3]); 70234ea8d65SJames Wright StateFromQi = context->use_primitive ? &StateFromY : &StateFromU; 70334ea8d65SJames Wright StateFromQi_fwd = context->use_primitive ? &StateFromY_fwd : &StateFromU_fwd; 70441e73928SJames Wright 70504b9037bSJames Wright CeedPragmaSIMD 70604b9037bSJames Wright // Quadrature Point Loop 70704b9037bSJames Wright for (CeedInt i=0; i<Q; i++) { 708b01ba163SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 70904b9037bSJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 71004b9037bSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 71104b9037bSJames Wright q_data_sur[2][i], 71204b9037bSJames Wright q_data_sur[3][i] 71304b9037bSJames Wright }; 714b01ba163SJames Wright const CeedScalar dXdx[2][3] = { 715b01ba163SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 716b01ba163SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 717b01ba163SJames Wright }; 718b01ba163SJames Wright 71941e73928SJames Wright CeedScalar qi[5], kmstress[6], dqi[5], dx_i[3] = {0.}; 72041e73928SJames Wright for (int j=0; j<5; j++) qi[j] = jac_data_sur[j][i]; 721b01ba163SJames Wright for (int j=0; j<6; j++) kmstress[j] = jac_data_sur[5+j][i]; 72241e73928SJames Wright for (int j=0; j<5; j++) dqi[j] = dq[j][i]; 7233934e2b1SJames Wright 72441e73928SJames Wright State s = StateFromQi(context, qi, x_i); 72541e73928SJames Wright State ds = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 726b01ba163SJames Wright s.Y.pressure = context->P0; 727b01ba163SJames Wright ds.Y.pressure = 0.; 728b01ba163SJames Wright 729b01ba163SJames Wright State grad_ds[3]; 730b01ba163SJames Wright for (CeedInt j=0; j<3; j++) { 73141e73928SJames Wright CeedScalar dx_i[3] = {0}, dqi_j[5]; 732b01ba163SJames Wright for (CeedInt k=0; k<5; k++) 73341e73928SJames Wright dqi_j[k] = Grad_dq[0][k][i] * dXdx[0][j] + 734b01ba163SJames Wright Grad_dq[1][k][i] * dXdx[1][j]; 735b01ba163SJames Wright dx_i[j] = 1.; 73641e73928SJames Wright grad_ds[j] = StateFromQi_fwd(context, s, dqi_j, x_i, dx_i); 737b01ba163SJames Wright } 738b01ba163SJames Wright 739b01ba163SJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 740b01ba163SJames Wright KMStrainRate(grad_ds, dstrain_rate); 741b01ba163SJames Wright NewtonianStress(context, dstrain_rate, dkmstress); 742b01ba163SJames Wright KMUnpack(dkmstress, dstress); 743b01ba163SJames Wright KMUnpack(kmstress, stress); 744b01ba163SJames Wright ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 74504b9037bSJames Wright 746e6b47afbSJames Wright StateConservative dF_inviscid[3]; 747e6b47afbSJames Wright FluxInviscid_fwd(context, s, ds, dF_inviscid); 74804b9037bSJames Wright 749*c5740391SJames Wright CeedScalar dFlux[5]; 750*c5740391SJames Wright FluxTotal_Boundary(dF_inviscid, dstress, dFe, norm, dFlux); 751e6b47afbSJames Wright 752*c5740391SJames Wright for (int j=0; j<5; j++) v[j][i] = -wdetJb * dFlux[j]; 75304b9037bSJames Wright } // End Quadrature Point Loop 75404b9037bSJames Wright return 0; 75504b9037bSJames Wright } 75604b9037bSJames Wright 7573a8779fbSJames Wright // ***************************************************************************** 758cbe60e31SLeila Ghaffari // This QFunction implements the Navier-Stokes equations (mentioned above) in 759cbe60e31SLeila Ghaffari // primitive variables and with implicit time stepping method 760cbe60e31SLeila Ghaffari // 761cbe60e31SLeila Ghaffari // ***************************************************************************** 762cbe60e31SLeila Ghaffari CEED_QFUNCTION(IFunction_Newtonian_Prim)(void *ctx, CeedInt Q, 763cbe60e31SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 764cbe60e31SLeila Ghaffari // *INDENT-OFF* 765cbe60e31SLeila Ghaffari // Inputs 766cbe60e31SLeila Ghaffari const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 767cbe60e31SLeila Ghaffari (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 768cbe60e31SLeila Ghaffari (*q_dot)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 769cbe60e31SLeila Ghaffari (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 770cbe60e31SLeila Ghaffari (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 771cbe60e31SLeila Ghaffari // Outputs 772cbe60e31SLeila Ghaffari CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 773cbe60e31SLeila Ghaffari (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1], 774cbe60e31SLeila Ghaffari (*jac_data)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[2]; 775cbe60e31SLeila Ghaffari // *INDENT-ON* 776cbe60e31SLeila Ghaffari // Context 777cbe60e31SLeila Ghaffari NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 778cbe60e31SLeila Ghaffari const CeedScalar *g = context->g; 779cbe60e31SLeila Ghaffari const CeedScalar dt = context->dt; 780cbe60e31SLeila Ghaffari 781cbe60e31SLeila Ghaffari CeedPragmaSIMD 782cbe60e31SLeila Ghaffari // Quadrature Point Loop 783cbe60e31SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 784cbe60e31SLeila Ghaffari CeedScalar Y[5]; 785cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) Y[j] = q[j][i]; 786cbe60e31SLeila Ghaffari const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 787cbe60e31SLeila Ghaffari State s = StateFromY(context, Y, x_i); 788cbe60e31SLeila Ghaffari 789cbe60e31SLeila Ghaffari // -- Interp-to-Interp q_data 790cbe60e31SLeila Ghaffari const CeedScalar wdetJ = q_data[0][i]; 791cbe60e31SLeila Ghaffari // -- Interp-to-Grad q_data 792cbe60e31SLeila Ghaffari // ---- Inverse of change of coordinate matrix: X_i,j 793cbe60e31SLeila Ghaffari // *INDENT-OFF* 79434ea8d65SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 79534ea8d65SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 79634ea8d65SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 797cbe60e31SLeila Ghaffari }; 798cbe60e31SLeila Ghaffari // *INDENT-ON* 799cbe60e31SLeila Ghaffari State grad_s[3]; 800cbe60e31SLeila Ghaffari for (CeedInt j=0; j<3; j++) { 801cbe60e31SLeila Ghaffari CeedScalar dx_i[3] = {0}, dY[5]; 802cbe60e31SLeila Ghaffari for (CeedInt k=0; k<5; k++) 803cbe60e31SLeila Ghaffari dY[k] = Grad_q[0][k][i] * dXdx[0][j] + 804cbe60e31SLeila Ghaffari Grad_q[1][k][i] * dXdx[1][j] + 805cbe60e31SLeila Ghaffari Grad_q[2][k][i] * dXdx[2][j]; 806cbe60e31SLeila Ghaffari dx_i[j] = 1.; 807cbe60e31SLeila Ghaffari grad_s[j] = StateFromY_fwd(context, s, dY, x_i, dx_i); 808cbe60e31SLeila Ghaffari } 809cbe60e31SLeila Ghaffari 810cbe60e31SLeila Ghaffari CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 811cbe60e31SLeila Ghaffari KMStrainRate(grad_s, strain_rate); 812cbe60e31SLeila Ghaffari NewtonianStress(context, strain_rate, kmstress); 813cbe60e31SLeila Ghaffari KMUnpack(kmstress, stress); 814cbe60e31SLeila Ghaffari ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 815cbe60e31SLeila Ghaffari 816cbe60e31SLeila Ghaffari StateConservative F_inviscid[3]; 817cbe60e31SLeila Ghaffari FluxInviscid(context, s, F_inviscid); 818cbe60e31SLeila Ghaffari 819cbe60e31SLeila Ghaffari // Total flux 820cbe60e31SLeila Ghaffari CeedScalar Flux[5][3]; 821d1b9ef12SLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 822cbe60e31SLeila Ghaffari 823d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<3; j++) 824d1b9ef12SLeila Ghaffari for (CeedInt k=0; k<5; k++) 825cbe60e31SLeila Ghaffari Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * Flux[k][0] + 826cbe60e31SLeila Ghaffari dXdx[j][1] * Flux[k][1] + 827cbe60e31SLeila Ghaffari dXdx[j][2] * Flux[k][2]); 828cbe60e31SLeila Ghaffari 829cbe60e31SLeila Ghaffari const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 830cbe60e31SLeila Ghaffari 831cbe60e31SLeila Ghaffari CeedScalar Y_dot[5], dx0[3] = {0}; 832cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) Y_dot[j] = q_dot[j][i]; 833cbe60e31SLeila Ghaffari State s_dot = StateFromY_fwd(context, s, Y_dot, x_i, dx0); 834cbe60e31SLeila Ghaffari 835cbe60e31SLeila Ghaffari CeedScalar U_dot[5] = {0.}; 836d1b9ef12SLeila Ghaffari UnpackState_U(s_dot.U, U_dot); 837cbe60e31SLeila Ghaffari 838cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) 839cbe60e31SLeila Ghaffari v[j][i] = wdetJ * (U_dot[j] - body_force[j]); 840cbe60e31SLeila Ghaffari 841d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 842d1b9ef12SLeila Ghaffari CeedScalar Tau_d[3], stab[5][3]; 843d1b9ef12SLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 844d1b9ef12SLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 845cbe60e31SLeila Ghaffari 846cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) 847cbe60e31SLeila Ghaffari for (CeedInt k=0; k<3; k++) 848cbe60e31SLeila Ghaffari Grad_v[k][j][i] += wdetJ*(stab[j][0] * dXdx[k][0] + 849cbe60e31SLeila Ghaffari stab[j][1] * dXdx[k][1] + 850cbe60e31SLeila Ghaffari stab[j][2] * dXdx[k][2]); 851cbe60e31SLeila Ghaffari 852cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) jac_data[j][i] = Y[j]; 853cbe60e31SLeila Ghaffari for (CeedInt j=0; j<6; j++) jac_data[5+j][i] = kmstress[j]; 854cbe60e31SLeila Ghaffari for (CeedInt j=0; j<3; j++) jac_data[5+6+j][i] = Tau_d[j]; 855cbe60e31SLeila Ghaffari 856cbe60e31SLeila Ghaffari } // End Quadrature Point Loop 857cbe60e31SLeila Ghaffari 858cbe60e31SLeila Ghaffari // Return 859cbe60e31SLeila Ghaffari return 0; 860cbe60e31SLeila Ghaffari } 861cbe60e31SLeila Ghaffari 862cbe60e31SLeila Ghaffari // ***************************************************************************** 863cbe60e31SLeila Ghaffari // This QFunction implements the jacobean of the Navier-Stokes equations 864cbe60e31SLeila Ghaffari // in primitive variables for implicit time stepping method. 865cbe60e31SLeila Ghaffari // 866cbe60e31SLeila Ghaffari // ***************************************************************************** 867cbe60e31SLeila Ghaffari CEED_QFUNCTION(IJacobian_Newtonian_Prim)(void *ctx, CeedInt Q, 868cbe60e31SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 869cbe60e31SLeila Ghaffari // *INDENT-OFF* 870cbe60e31SLeila Ghaffari // Inputs 871cbe60e31SLeila Ghaffari const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 872cbe60e31SLeila Ghaffari (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 873cbe60e31SLeila Ghaffari (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 874cbe60e31SLeila Ghaffari (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 875cbe60e31SLeila Ghaffari (*jac_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 876cbe60e31SLeila Ghaffari // Outputs 877cbe60e31SLeila Ghaffari CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 878cbe60e31SLeila Ghaffari (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1]; 879cbe60e31SLeila Ghaffari // *INDENT-ON* 880cbe60e31SLeila Ghaffari // Context 881cbe60e31SLeila Ghaffari NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 882cbe60e31SLeila Ghaffari const CeedScalar *g = context->g; 883cbe60e31SLeila Ghaffari 884cbe60e31SLeila Ghaffari CeedPragmaSIMD 885cbe60e31SLeila Ghaffari // Quadrature Point Loop 886cbe60e31SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 887cbe60e31SLeila Ghaffari // -- Interp-to-Interp q_data 888cbe60e31SLeila Ghaffari const CeedScalar wdetJ = q_data[0][i]; 889cbe60e31SLeila Ghaffari // -- Interp-to-Grad q_data 890cbe60e31SLeila Ghaffari // ---- Inverse of change of coordinate matrix: X_i,j 891cbe60e31SLeila Ghaffari // *INDENT-OFF* 89234ea8d65SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 89334ea8d65SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 89434ea8d65SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 895cbe60e31SLeila Ghaffari }; 896cbe60e31SLeila Ghaffari // *INDENT-ON* 897cbe60e31SLeila Ghaffari 898cbe60e31SLeila Ghaffari CeedScalar Y[5], kmstress[6], Tau_d[3] __attribute((unused)); 899cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) Y[j] = jac_data[j][i]; 900cbe60e31SLeila Ghaffari for (int j=0; j<6; j++) kmstress[j] = jac_data[5+j][i]; 901cbe60e31SLeila Ghaffari for (int j=0; j<3; j++) Tau_d[j] = jac_data[5+6+j][i]; 902cbe60e31SLeila Ghaffari const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 903cbe60e31SLeila Ghaffari State s = StateFromY(context, Y, x_i); 904cbe60e31SLeila Ghaffari 905cbe60e31SLeila Ghaffari CeedScalar dY[5], dx0[3] = {0}; 906cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) dY[j] = dq[j][i]; 907cbe60e31SLeila Ghaffari State ds = StateFromY_fwd(context, s, dY, x_i, dx0); 908cbe60e31SLeila Ghaffari 909cbe60e31SLeila Ghaffari State grad_ds[3]; 910cbe60e31SLeila Ghaffari for (int j=0; j<3; j++) { 911cbe60e31SLeila Ghaffari CeedScalar dYj[5]; 912cbe60e31SLeila Ghaffari for (int k=0; k<5; k++) 913cbe60e31SLeila Ghaffari dYj[k] = Grad_dq[0][k][i] * dXdx[0][j] + 914cbe60e31SLeila Ghaffari Grad_dq[1][k][i] * dXdx[1][j] + 915cbe60e31SLeila Ghaffari Grad_dq[2][k][i] * dXdx[2][j]; 916cbe60e31SLeila Ghaffari grad_ds[j] = StateFromY_fwd(context, s, dYj, x_i, dx0); 917cbe60e31SLeila Ghaffari } 918cbe60e31SLeila Ghaffari 919cbe60e31SLeila Ghaffari CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 920cbe60e31SLeila Ghaffari KMStrainRate(grad_ds, dstrain_rate); 921cbe60e31SLeila Ghaffari NewtonianStress(context, dstrain_rate, dkmstress); 922cbe60e31SLeila Ghaffari KMUnpack(dkmstress, dstress); 923cbe60e31SLeila Ghaffari KMUnpack(kmstress, stress); 924cbe60e31SLeila Ghaffari ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 925cbe60e31SLeila Ghaffari 926cbe60e31SLeila Ghaffari StateConservative dF_inviscid[3]; 927cbe60e31SLeila Ghaffari FluxInviscid_fwd(context, s, ds, dF_inviscid); 928cbe60e31SLeila Ghaffari 929cbe60e31SLeila Ghaffari // Total flux 930cbe60e31SLeila Ghaffari CeedScalar dFlux[5][3]; 931d1b9ef12SLeila Ghaffari FluxTotal(dF_inviscid, dstress, dFe, dFlux); 932cbe60e31SLeila Ghaffari 933d1b9ef12SLeila Ghaffari for (int j=0; j<3; j++) 934d1b9ef12SLeila Ghaffari for (int k=0; k<5; k++) 935cbe60e31SLeila Ghaffari Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * dFlux[k][0] + 936cbe60e31SLeila Ghaffari dXdx[j][1] * dFlux[k][1] + 937cbe60e31SLeila Ghaffari dXdx[j][2] * dFlux[k][2]); 938cbe60e31SLeila Ghaffari 939d1b9ef12SLeila Ghaffari const CeedScalar dbody_force[5] = {0, ds.U.density *g[0], ds.U.density *g[1], ds.U.density *g[2], 0}; 940cbe60e31SLeila Ghaffari CeedScalar dU[5] = {0.}; 941d1b9ef12SLeila Ghaffari UnpackState_U(ds.U, dU); 942cbe60e31SLeila Ghaffari 943cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) 944cbe60e31SLeila Ghaffari v[j][i] = wdetJ * (context->ijacobian_time_shift * dU[j] - dbody_force[j]); 945cbe60e31SLeila Ghaffari 946d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 947d1b9ef12SLeila Ghaffari CeedScalar dstab[5][3], U_dot[5] = {0}; 948d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = context->ijacobian_time_shift * dU[j]; 949d1b9ef12SLeila Ghaffari Stabilization(context, s, Tau_d, grad_ds, U_dot, dbody_force, x_i, dstab); 950cbe60e31SLeila Ghaffari 951cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) 952cbe60e31SLeila Ghaffari for (int k=0; k<3; k++) 953cbe60e31SLeila Ghaffari Grad_v[k][j][i] += wdetJ*(dstab[j][0] * dXdx[k][0] + 954cbe60e31SLeila Ghaffari dstab[j][1] * dXdx[k][1] + 955cbe60e31SLeila Ghaffari dstab[j][2] * dXdx[k][2]); 956cbe60e31SLeila Ghaffari 957cbe60e31SLeila Ghaffari } // End Quadrature Point Loop 958cbe60e31SLeila Ghaffari return 0; 959cbe60e31SLeila Ghaffari } 960cbe60e31SLeila Ghaffari // ***************************************************************************** 961cbe60e31SLeila Ghaffari 9623a8779fbSJames Wright #endif // newtonian_h 963