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 // ***************************************************************************** 440*d4559bbeSJames Wright CEED_QFUNCTION_HELPER int BoundaryIntegral(void *ctx, CeedInt Q, 441*d4559bbeSJames Wright const CeedScalar *const *in, CeedScalar *const *out, 442*d4559bbeSJames Wright StateFromQi_t StateFromQi, StateFromQi_fwd_t StateFromQi_fwd) { 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; 4578085925cSJames Wright 4588085925cSJames Wright CeedPragmaSIMD 4598085925cSJames Wright for(CeedInt i=0; i<Q; i++) { 460d3b25f3aSJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 46141e73928SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 46241e73928SJames Wright State s = StateFromQi(context, qi, x_i); 4638085925cSJames Wright 4648085925cSJames Wright const CeedScalar wdetJb = (is_implicit ? -1. : 1.) * q_data_sur[0][i]; 465c5740391SJames Wright // ---- Normal vector 4668085925cSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 4678085925cSJames Wright q_data_sur[2][i], 4688085925cSJames Wright q_data_sur[3][i] 4698085925cSJames Wright }; 4708085925cSJames Wright 471d3b25f3aSJames Wright const CeedScalar dXdx[2][3] = { 472d3b25f3aSJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 473d3b25f3aSJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 474d3b25f3aSJames Wright }; 4758085925cSJames Wright 476d3b25f3aSJames Wright State grad_s[3]; 477d3b25f3aSJames Wright for (CeedInt j=0; j<3; j++) { 47841e73928SJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 479d3b25f3aSJames Wright for (CeedInt k=0; k<5; k++) 48041e73928SJames Wright dqi[k] = Grad_q[0][k][i] * dXdx[0][j] + 481d3b25f3aSJames Wright Grad_q[1][k][i] * dXdx[1][j]; 482d3b25f3aSJames Wright dx_i[j] = 1.; 48341e73928SJames Wright grad_s[j] = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 484d3b25f3aSJames Wright } 4858085925cSJames Wright 486d3b25f3aSJames Wright CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 487d3b25f3aSJames Wright KMStrainRate(grad_s, strain_rate); 488d3b25f3aSJames Wright NewtonianStress(context, strain_rate, kmstress); 489d3b25f3aSJames Wright KMUnpack(kmstress, stress); 490d3b25f3aSJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 491d3b25f3aSJames Wright 492d3b25f3aSJames Wright StateConservative F_inviscid[3]; 493d3b25f3aSJames Wright FluxInviscid(context, s, F_inviscid); 494d3b25f3aSJames Wright 495c5740391SJames Wright CeedScalar Flux[5]; 496c5740391SJames Wright FluxTotal_Boundary(F_inviscid, stress, Fe, norm, Flux); 497d3b25f3aSJames Wright 498c5740391SJames Wright for (CeedInt j=0; j<5; j++) v[j][i] = -wdetJb * Flux[j]; 4998085925cSJames Wright 500c5740391SJames Wright for (int j=0; j<5; j++) jac_data_sur[j][i] = qi[j]; 50168ae065aSJames Wright for (int j=0; j<6; j++) jac_data_sur[5+j][i] = kmstress[j]; 5028085925cSJames Wright } 5038085925cSJames Wright return 0; 5048085925cSJames Wright } 5058085925cSJames Wright 506*d4559bbeSJames Wright CEED_QFUNCTION(BoundaryIntegral_Conserv)(void *ctx, CeedInt Q, 507*d4559bbeSJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 508*d4559bbeSJames Wright return BoundaryIntegral(ctx, Q, in, out, StateFromU, StateFromU_fwd); 509*d4559bbeSJames Wright } 510*d4559bbeSJames Wright 511*d4559bbeSJames Wright CEED_QFUNCTION(BoundaryIntegral_Prim)(void *ctx, CeedInt Q, 512*d4559bbeSJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 513*d4559bbeSJames Wright return BoundaryIntegral(ctx, Q, in, out, StateFromY, StateFromY_fwd); 514*d4559bbeSJames Wright } 515*d4559bbeSJames Wright 516d1b9ef12SLeila Ghaffari // ***************************************************************************** 51768ae065aSJames Wright // Jacobian for "set nothing" boundary integral 518d1b9ef12SLeila Ghaffari // ***************************************************************************** 519*d4559bbeSJames Wright CEED_QFUNCTION_HELPER int BoundaryIntegral_Jacobian(void *ctx, CeedInt Q, 520*d4559bbeSJames Wright const CeedScalar *const *in, CeedScalar *const *out, 521*d4559bbeSJames Wright StateFromQi_t StateFromQi, StateFromQi_fwd_t StateFromQi_fwd) { 52268ae065aSJames Wright // *INDENT-OFF* 52368ae065aSJames Wright // Inputs 52468ae065aSJames Wright const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 52568ae065aSJames Wright (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 52668ae065aSJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 52768ae065aSJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 52868ae065aSJames Wright (*jac_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 52968ae065aSJames Wright // Outputs 53068ae065aSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 53168ae065aSJames Wright // *INDENT-ON* 53268ae065aSJames Wright 53368ae065aSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 53468ae065aSJames Wright const bool implicit = context->is_implicit; 53568ae065aSJames Wright 53668ae065aSJames Wright CeedPragmaSIMD 53768ae065aSJames Wright // Quadrature Point Loop 53868ae065aSJames Wright for (CeedInt i=0; i<Q; i++) { 53968ae065aSJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 54068ae065aSJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 54168ae065aSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 54268ae065aSJames Wright q_data_sur[2][i], 54368ae065aSJames Wright q_data_sur[3][i] 54468ae065aSJames Wright }; 54568ae065aSJames Wright const CeedScalar dXdx[2][3] = { 54668ae065aSJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 54768ae065aSJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 54868ae065aSJames Wright }; 54968ae065aSJames Wright 55041e73928SJames Wright CeedScalar qi[5], kmstress[6], dqi[5], dx_i[3] = {0.}; 55141e73928SJames Wright for (int j=0; j<5; j++) qi[j] = jac_data_sur[j][i]; 55268ae065aSJames Wright for (int j=0; j<6; j++) kmstress[j] = jac_data_sur[5+j][i]; 55341e73928SJames Wright for (int j=0; j<5; j++) dqi[j] = dq[j][i]; 5543934e2b1SJames Wright 55541e73928SJames Wright State s = StateFromQi(context, qi, x_i); 55641e73928SJames Wright State ds = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 55768ae065aSJames Wright 55868ae065aSJames Wright State grad_ds[3]; 55968ae065aSJames Wright for (CeedInt j=0; j<3; j++) { 56041e73928SJames Wright CeedScalar dx_i[3] = {0}, dqi_j[5]; 56168ae065aSJames Wright for (CeedInt k=0; k<5; k++) 56241e73928SJames Wright dqi_j[k] = Grad_dq[0][k][i] * dXdx[0][j] + 56368ae065aSJames Wright Grad_dq[1][k][i] * dXdx[1][j]; 56468ae065aSJames Wright dx_i[j] = 1.; 56541e73928SJames Wright grad_ds[j] = StateFromQi_fwd(context, s, dqi_j, x_i, dx_i); 56668ae065aSJames Wright } 56768ae065aSJames Wright 56868ae065aSJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 56968ae065aSJames Wright KMStrainRate(grad_ds, dstrain_rate); 57068ae065aSJames Wright NewtonianStress(context, dstrain_rate, dkmstress); 57168ae065aSJames Wright KMUnpack(dkmstress, dstress); 57268ae065aSJames Wright KMUnpack(kmstress, stress); 57368ae065aSJames Wright ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 57468ae065aSJames Wright 57568ae065aSJames Wright StateConservative dF_inviscid[3]; 57668ae065aSJames Wright FluxInviscid_fwd(context, s, ds, dF_inviscid); 57768ae065aSJames Wright 578c5740391SJames Wright CeedScalar dFlux[5]; 579c5740391SJames Wright FluxTotal_Boundary(dF_inviscid, dstress, dFe, norm, dFlux); 58068ae065aSJames Wright 581c5740391SJames Wright for (int j=0; j<5; j++) v[j][i] = -wdetJb * dFlux[j]; 58268ae065aSJames Wright } // End Quadrature Point Loop 58368ae065aSJames Wright return 0; 58468ae065aSJames Wright } 58568ae065aSJames Wright 586*d4559bbeSJames Wright CEED_QFUNCTION(BoundaryIntegral_Jacobian_Conserv)(void *ctx, CeedInt Q, 587*d4559bbeSJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 588*d4559bbeSJames Wright return BoundaryIntegral_Jacobian(ctx, Q, in, out, StateFromU, StateFromU_fwd); 589*d4559bbeSJames Wright } 590*d4559bbeSJames Wright 591*d4559bbeSJames Wright CEED_QFUNCTION(BoundaryIntegral_Jacobian_Prim)(void *ctx, CeedInt Q, 592*d4559bbeSJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 593*d4559bbeSJames Wright return BoundaryIntegral_Jacobian(ctx, Q, in, out, StateFromY, StateFromY_fwd); 594*d4559bbeSJames Wright } 595*d4559bbeSJames Wright 596d1b9ef12SLeila Ghaffari // ***************************************************************************** 59704b9037bSJames Wright // Outflow boundary condition, weakly setting a constant pressure 598d1b9ef12SLeila Ghaffari // ***************************************************************************** 599*d4559bbeSJames Wright CEED_QFUNCTION_HELPER int PressureOutflow(void *ctx, CeedInt Q, 600*d4559bbeSJames Wright const CeedScalar *const *in, CeedScalar *const *out, 601*d4559bbeSJames Wright StateFromQi_t StateFromQi, StateFromQi_fwd_t StateFromQi_fwd) { 60204b9037bSJames Wright // *INDENT-OFF* 60304b9037bSJames Wright // Inputs 60404b9037bSJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 60525bfcc41SJames Wright (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 60625bfcc41SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 60725bfcc41SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 60804b9037bSJames Wright // Outputs 60904b9037bSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 61004b9037bSJames Wright (*jac_data_sur)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[1]; 61104b9037bSJames Wright // *INDENT-ON* 61204b9037bSJames Wright 61304b9037bSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 61404b9037bSJames Wright const bool implicit = context->is_implicit; 61504b9037bSJames Wright const CeedScalar P0 = context->P0; 61604b9037bSJames Wright 61704b9037bSJames Wright CeedPragmaSIMD 61804b9037bSJames Wright // Quadrature Point Loop 61904b9037bSJames Wright for (CeedInt i=0; i<Q; i++) { 62004b9037bSJames Wright // Setup 62104b9037bSJames Wright // -- Interp in 62225bfcc41SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 62341e73928SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 62441e73928SJames Wright State s = StateFromQi(context, qi, x_i); 62525bfcc41SJames Wright s.Y.pressure = P0; 62604b9037bSJames Wright 62704b9037bSJames Wright // -- Interp-to-Interp q_data 62804b9037bSJames Wright // For explicit mode, the surface integral is on the RHS of ODE q_dot = f(q). 62904b9037bSJames Wright // For implicit mode, it gets pulled to the LHS of implicit ODE/DAE g(q_dot, q). 63004b9037bSJames Wright // We can effect this by swapping the sign on this weight 63104b9037bSJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 63204b9037bSJames Wright 633c5740391SJames Wright // ---- Normal vector 634*d4559bbeSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], q_data_sur[2][i], q_data_sur[3][i]}; 63504b9037bSJames Wright 63625bfcc41SJames Wright const CeedScalar dXdx[2][3] = { 63725bfcc41SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 63825bfcc41SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 63925bfcc41SJames Wright }; 64004b9037bSJames Wright 64125bfcc41SJames Wright State grad_s[3]; 64225bfcc41SJames Wright for (CeedInt j=0; j<3; j++) { 64341e73928SJames Wright CeedScalar dx_i[3] = {0}, dqi[5]; 64425bfcc41SJames Wright for (CeedInt k=0; k<5; k++) 64541e73928SJames Wright dqi[k] = Grad_q[0][k][i] * dXdx[0][j] + 64625bfcc41SJames Wright Grad_q[1][k][i] * dXdx[1][j]; 64725bfcc41SJames Wright dx_i[j] = 1.; 64841e73928SJames Wright grad_s[j] = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 64925bfcc41SJames Wright } 65025bfcc41SJames Wright 65125bfcc41SJames Wright CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 65225bfcc41SJames Wright KMStrainRate(grad_s, strain_rate); 65325bfcc41SJames Wright NewtonianStress(context, strain_rate, kmstress); 65425bfcc41SJames Wright KMUnpack(kmstress, stress); 65525bfcc41SJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 65625bfcc41SJames Wright 65725bfcc41SJames Wright StateConservative F_inviscid[3]; 65825bfcc41SJames Wright FluxInviscid(context, s, F_inviscid); 65925bfcc41SJames Wright 660c5740391SJames Wright CeedScalar Flux[5]; 661c5740391SJames Wright FluxTotal_Boundary(F_inviscid, stress, Fe, norm, Flux); 66204b9037bSJames Wright 663c5740391SJames Wright for (CeedInt j=0; j<5; j++) v[j][i] = -wdetJb * Flux[j]; 66404b9037bSJames Wright 66504b9037bSJames Wright // Save values for Jacobian 666c5740391SJames Wright for (int j=0; j<5; j++) jac_data_sur[j][i] = qi[j]; 667b01ba163SJames Wright for (int j=0; j<6; j++) jac_data_sur[5+j][i] = kmstress[j]; 66804b9037bSJames Wright } // End Quadrature Point Loop 66904b9037bSJames Wright return 0; 67004b9037bSJames Wright } 67104b9037bSJames Wright 672*d4559bbeSJames Wright CEED_QFUNCTION(PressureOutflow_Conserv)(void *ctx, CeedInt Q, 673*d4559bbeSJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 674*d4559bbeSJames Wright return PressureOutflow(ctx, Q, in, out, StateFromU, StateFromU_fwd); 675*d4559bbeSJames Wright } 676*d4559bbeSJames Wright 677*d4559bbeSJames Wright CEED_QFUNCTION(PressureOutflow_Prim)(void *ctx, CeedInt Q, 678*d4559bbeSJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 679*d4559bbeSJames Wright return PressureOutflow(ctx, Q, in, out, StateFromY, StateFromY_fwd); 680*d4559bbeSJames Wright } 681*d4559bbeSJames Wright 682d1b9ef12SLeila Ghaffari // ***************************************************************************** 68304b9037bSJames Wright // Jacobian for weak-pressure outflow boundary condition 684d1b9ef12SLeila Ghaffari // ***************************************************************************** 685*d4559bbeSJames Wright CEED_QFUNCTION_HELPER int PressureOutflow_Jacobian(void *ctx, CeedInt Q, 686*d4559bbeSJames Wright const CeedScalar *const *in, CeedScalar *const *out, 687*d4559bbeSJames Wright StateFromQi_t StateFromQi, StateFromQi_fwd_t StateFromQi_fwd) { 68804b9037bSJames Wright // *INDENT-OFF* 68904b9037bSJames Wright // Inputs 69004b9037bSJames Wright const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 691b01ba163SJames Wright (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 692b01ba163SJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 693b01ba163SJames Wright (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 694b01ba163SJames Wright (*jac_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 69504b9037bSJames Wright // Outputs 69604b9037bSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 69704b9037bSJames Wright // *INDENT-ON* 69804b9037bSJames Wright 69904b9037bSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 70004b9037bSJames Wright const bool implicit = context->is_implicit; 70104b9037bSJames Wright 70204b9037bSJames Wright CeedPragmaSIMD 70304b9037bSJames Wright // Quadrature Point Loop 70404b9037bSJames Wright for (CeedInt i=0; i<Q; i++) { 705b01ba163SJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 70604b9037bSJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 707*d4559bbeSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], q_data_sur[2][i], q_data_sur[3][i]}; 708b01ba163SJames Wright const CeedScalar dXdx[2][3] = { 709b01ba163SJames Wright {q_data_sur[4][i], q_data_sur[5][i], q_data_sur[6][i]}, 710b01ba163SJames Wright {q_data_sur[7][i], q_data_sur[8][i], q_data_sur[9][i]} 711b01ba163SJames Wright }; 712b01ba163SJames Wright 71341e73928SJames Wright CeedScalar qi[5], kmstress[6], dqi[5], dx_i[3] = {0.}; 71441e73928SJames Wright for (int j=0; j<5; j++) qi[j] = jac_data_sur[j][i]; 715b01ba163SJames Wright for (int j=0; j<6; j++) kmstress[j] = jac_data_sur[5+j][i]; 71641e73928SJames Wright for (int j=0; j<5; j++) dqi[j] = dq[j][i]; 7173934e2b1SJames Wright 71841e73928SJames Wright State s = StateFromQi(context, qi, x_i); 71941e73928SJames Wright State ds = StateFromQi_fwd(context, s, dqi, x_i, dx_i); 720b01ba163SJames Wright s.Y.pressure = context->P0; 721b01ba163SJames Wright ds.Y.pressure = 0.; 722b01ba163SJames Wright 723b01ba163SJames Wright State grad_ds[3]; 724b01ba163SJames Wright for (CeedInt j=0; j<3; j++) { 72541e73928SJames Wright CeedScalar dx_i[3] = {0}, dqi_j[5]; 726b01ba163SJames Wright for (CeedInt k=0; k<5; k++) 72741e73928SJames Wright dqi_j[k] = Grad_dq[0][k][i] * dXdx[0][j] + 728b01ba163SJames Wright Grad_dq[1][k][i] * dXdx[1][j]; 729b01ba163SJames Wright dx_i[j] = 1.; 73041e73928SJames Wright grad_ds[j] = StateFromQi_fwd(context, s, dqi_j, x_i, dx_i); 731b01ba163SJames Wright } 732b01ba163SJames Wright 733b01ba163SJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 734b01ba163SJames Wright KMStrainRate(grad_ds, dstrain_rate); 735b01ba163SJames Wright NewtonianStress(context, dstrain_rate, dkmstress); 736b01ba163SJames Wright KMUnpack(dkmstress, dstress); 737b01ba163SJames Wright KMUnpack(kmstress, stress); 738b01ba163SJames Wright ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 73904b9037bSJames Wright 740e6b47afbSJames Wright StateConservative dF_inviscid[3]; 741e6b47afbSJames Wright FluxInviscid_fwd(context, s, ds, dF_inviscid); 74204b9037bSJames Wright 743c5740391SJames Wright CeedScalar dFlux[5]; 744c5740391SJames Wright FluxTotal_Boundary(dF_inviscid, dstress, dFe, norm, dFlux); 745e6b47afbSJames Wright 746c5740391SJames Wright for (int j=0; j<5; j++) v[j][i] = -wdetJb * dFlux[j]; 74704b9037bSJames Wright } // End Quadrature Point Loop 74804b9037bSJames Wright return 0; 74904b9037bSJames Wright } 75004b9037bSJames Wright 751*d4559bbeSJames Wright CEED_QFUNCTION(PressureOutflow_Jacobian_Conserv)(void *ctx, CeedInt Q, 752*d4559bbeSJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 753*d4559bbeSJames Wright return PressureOutflow_Jacobian(ctx, Q, in, out, StateFromU, StateFromU_fwd); 754*d4559bbeSJames Wright } 755*d4559bbeSJames Wright 756*d4559bbeSJames Wright CEED_QFUNCTION(PressureOutflow_Jacobian_Prim)(void *ctx, CeedInt Q, 757*d4559bbeSJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 758*d4559bbeSJames Wright return PressureOutflow_Jacobian(ctx, Q, in, out, StateFromY, StateFromY_fwd); 759*d4559bbeSJames Wright } 760*d4559bbeSJames Wright 7613a8779fbSJames Wright // ***************************************************************************** 762cbe60e31SLeila Ghaffari // This QFunction implements the Navier-Stokes equations (mentioned above) in 763cbe60e31SLeila Ghaffari // primitive variables and with implicit time stepping method 764cbe60e31SLeila Ghaffari // 765cbe60e31SLeila Ghaffari // ***************************************************************************** 766cbe60e31SLeila Ghaffari CEED_QFUNCTION(IFunction_Newtonian_Prim)(void *ctx, CeedInt Q, 767cbe60e31SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 768cbe60e31SLeila Ghaffari // *INDENT-OFF* 769cbe60e31SLeila Ghaffari // Inputs 770cbe60e31SLeila Ghaffari const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 771cbe60e31SLeila Ghaffari (*Grad_q)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 772cbe60e31SLeila Ghaffari (*q_dot)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 773cbe60e31SLeila Ghaffari (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 774cbe60e31SLeila Ghaffari (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 775cbe60e31SLeila Ghaffari // Outputs 776cbe60e31SLeila Ghaffari CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 777cbe60e31SLeila Ghaffari (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1], 778cbe60e31SLeila Ghaffari (*jac_data)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[2]; 779cbe60e31SLeila Ghaffari // *INDENT-ON* 780cbe60e31SLeila Ghaffari // Context 781cbe60e31SLeila Ghaffari NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 782cbe60e31SLeila Ghaffari const CeedScalar *g = context->g; 783cbe60e31SLeila Ghaffari const CeedScalar dt = context->dt; 784cbe60e31SLeila Ghaffari 785cbe60e31SLeila Ghaffari CeedPragmaSIMD 786cbe60e31SLeila Ghaffari // Quadrature Point Loop 787cbe60e31SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 788cbe60e31SLeila Ghaffari CeedScalar Y[5]; 789cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) Y[j] = q[j][i]; 790cbe60e31SLeila Ghaffari const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 791cbe60e31SLeila Ghaffari State s = StateFromY(context, Y, x_i); 792cbe60e31SLeila Ghaffari 793cbe60e31SLeila Ghaffari // -- Interp-to-Interp q_data 794cbe60e31SLeila Ghaffari const CeedScalar wdetJ = q_data[0][i]; 795cbe60e31SLeila Ghaffari // -- Interp-to-Grad q_data 796cbe60e31SLeila Ghaffari // ---- Inverse of change of coordinate matrix: X_i,j 797cbe60e31SLeila Ghaffari // *INDENT-OFF* 79834ea8d65SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 79934ea8d65SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 80034ea8d65SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 801cbe60e31SLeila Ghaffari }; 802cbe60e31SLeila Ghaffari // *INDENT-ON* 803cbe60e31SLeila Ghaffari State grad_s[3]; 804cbe60e31SLeila Ghaffari for (CeedInt j=0; j<3; j++) { 805cbe60e31SLeila Ghaffari CeedScalar dx_i[3] = {0}, dY[5]; 806cbe60e31SLeila Ghaffari for (CeedInt k=0; k<5; k++) 807cbe60e31SLeila Ghaffari dY[k] = Grad_q[0][k][i] * dXdx[0][j] + 808cbe60e31SLeila Ghaffari Grad_q[1][k][i] * dXdx[1][j] + 809cbe60e31SLeila Ghaffari Grad_q[2][k][i] * dXdx[2][j]; 810cbe60e31SLeila Ghaffari dx_i[j] = 1.; 811cbe60e31SLeila Ghaffari grad_s[j] = StateFromY_fwd(context, s, dY, x_i, dx_i); 812cbe60e31SLeila Ghaffari } 813cbe60e31SLeila Ghaffari 814cbe60e31SLeila Ghaffari CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3]; 815cbe60e31SLeila Ghaffari KMStrainRate(grad_s, strain_rate); 816cbe60e31SLeila Ghaffari NewtonianStress(context, strain_rate, kmstress); 817cbe60e31SLeila Ghaffari KMUnpack(kmstress, stress); 818cbe60e31SLeila Ghaffari ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 819cbe60e31SLeila Ghaffari 820cbe60e31SLeila Ghaffari StateConservative F_inviscid[3]; 821cbe60e31SLeila Ghaffari FluxInviscid(context, s, F_inviscid); 822cbe60e31SLeila Ghaffari 823cbe60e31SLeila Ghaffari // Total flux 824cbe60e31SLeila Ghaffari CeedScalar Flux[5][3]; 825d1b9ef12SLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux); 826cbe60e31SLeila Ghaffari 827d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<3; j++) 828d1b9ef12SLeila Ghaffari for (CeedInt k=0; k<5; k++) 829cbe60e31SLeila Ghaffari Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * Flux[k][0] + 830cbe60e31SLeila Ghaffari dXdx[j][1] * Flux[k][1] + 831cbe60e31SLeila Ghaffari dXdx[j][2] * Flux[k][2]); 832cbe60e31SLeila Ghaffari 833cbe60e31SLeila Ghaffari const CeedScalar body_force[5] = {0, s.U.density *g[0], s.U.density *g[1], s.U.density *g[2], 0}; 834cbe60e31SLeila Ghaffari 835cbe60e31SLeila Ghaffari CeedScalar Y_dot[5], dx0[3] = {0}; 836cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) Y_dot[j] = q_dot[j][i]; 837cbe60e31SLeila Ghaffari State s_dot = StateFromY_fwd(context, s, Y_dot, x_i, dx0); 838cbe60e31SLeila Ghaffari 839cbe60e31SLeila Ghaffari CeedScalar U_dot[5] = {0.}; 840d1b9ef12SLeila Ghaffari UnpackState_U(s_dot.U, U_dot); 841cbe60e31SLeila Ghaffari 842cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) 843cbe60e31SLeila Ghaffari v[j][i] = wdetJ * (U_dot[j] - body_force[j]); 844cbe60e31SLeila Ghaffari 845d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 846d1b9ef12SLeila Ghaffari CeedScalar Tau_d[3], stab[5][3]; 847d1b9ef12SLeila Ghaffari Tau_diagPrim(context, s, dXdx, dt, Tau_d); 848d1b9ef12SLeila Ghaffari Stabilization(context, s, Tau_d, grad_s, U_dot, body_force, x_i, stab); 849cbe60e31SLeila Ghaffari 850cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) 851cbe60e31SLeila Ghaffari for (CeedInt k=0; k<3; k++) 852cbe60e31SLeila Ghaffari Grad_v[k][j][i] += wdetJ*(stab[j][0] * dXdx[k][0] + 853cbe60e31SLeila Ghaffari stab[j][1] * dXdx[k][1] + 854cbe60e31SLeila Ghaffari stab[j][2] * dXdx[k][2]); 855cbe60e31SLeila Ghaffari 856cbe60e31SLeila Ghaffari for (CeedInt j=0; j<5; j++) jac_data[j][i] = Y[j]; 857cbe60e31SLeila Ghaffari for (CeedInt j=0; j<6; j++) jac_data[5+j][i] = kmstress[j]; 858cbe60e31SLeila Ghaffari for (CeedInt j=0; j<3; j++) jac_data[5+6+j][i] = Tau_d[j]; 859cbe60e31SLeila Ghaffari 860cbe60e31SLeila Ghaffari } // End Quadrature Point Loop 861cbe60e31SLeila Ghaffari 862cbe60e31SLeila Ghaffari // Return 863cbe60e31SLeila Ghaffari return 0; 864cbe60e31SLeila Ghaffari } 865cbe60e31SLeila Ghaffari 866cbe60e31SLeila Ghaffari // ***************************************************************************** 867cbe60e31SLeila Ghaffari // This QFunction implements the jacobean of the Navier-Stokes equations 868cbe60e31SLeila Ghaffari // in primitive variables for implicit time stepping method. 869cbe60e31SLeila Ghaffari // 870cbe60e31SLeila Ghaffari // ***************************************************************************** 871cbe60e31SLeila Ghaffari CEED_QFUNCTION(IJacobian_Newtonian_Prim)(void *ctx, CeedInt Q, 872cbe60e31SLeila Ghaffari const CeedScalar *const *in, CeedScalar *const *out) { 873cbe60e31SLeila Ghaffari // *INDENT-OFF* 874cbe60e31SLeila Ghaffari // Inputs 875cbe60e31SLeila Ghaffari const CeedScalar (*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 876cbe60e31SLeila Ghaffari (*Grad_dq)[5][CEED_Q_VLA] = (const CeedScalar(*)[5][CEED_Q_VLA])in[1], 877cbe60e31SLeila Ghaffari (*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2], 878cbe60e31SLeila Ghaffari (*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3], 879cbe60e31SLeila Ghaffari (*jac_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4]; 880cbe60e31SLeila Ghaffari // Outputs 881cbe60e31SLeila Ghaffari CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0], 882cbe60e31SLeila Ghaffari (*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1]; 883cbe60e31SLeila Ghaffari // *INDENT-ON* 884cbe60e31SLeila Ghaffari // Context 885cbe60e31SLeila Ghaffari NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 886cbe60e31SLeila Ghaffari const CeedScalar *g = context->g; 887cbe60e31SLeila Ghaffari 888cbe60e31SLeila Ghaffari CeedPragmaSIMD 889cbe60e31SLeila Ghaffari // Quadrature Point Loop 890cbe60e31SLeila Ghaffari for (CeedInt i=0; i<Q; i++) { 891cbe60e31SLeila Ghaffari // -- Interp-to-Interp q_data 892cbe60e31SLeila Ghaffari const CeedScalar wdetJ = q_data[0][i]; 893cbe60e31SLeila Ghaffari // -- Interp-to-Grad q_data 894cbe60e31SLeila Ghaffari // ---- Inverse of change of coordinate matrix: X_i,j 895cbe60e31SLeila Ghaffari // *INDENT-OFF* 89634ea8d65SJames Wright const CeedScalar dXdx[3][3] = {{q_data[1][i], q_data[2][i], q_data[3][i]}, 89734ea8d65SJames Wright {q_data[4][i], q_data[5][i], q_data[6][i]}, 89834ea8d65SJames Wright {q_data[7][i], q_data[8][i], q_data[9][i]} 899cbe60e31SLeila Ghaffari }; 900cbe60e31SLeila Ghaffari // *INDENT-ON* 901cbe60e31SLeila Ghaffari 902cbe60e31SLeila Ghaffari CeedScalar Y[5], kmstress[6], Tau_d[3] __attribute((unused)); 903cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) Y[j] = jac_data[j][i]; 904cbe60e31SLeila Ghaffari for (int j=0; j<6; j++) kmstress[j] = jac_data[5+j][i]; 905cbe60e31SLeila Ghaffari for (int j=0; j<3; j++) Tau_d[j] = jac_data[5+6+j][i]; 906cbe60e31SLeila Ghaffari const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]}; 907cbe60e31SLeila Ghaffari State s = StateFromY(context, Y, x_i); 908cbe60e31SLeila Ghaffari 909cbe60e31SLeila Ghaffari CeedScalar dY[5], dx0[3] = {0}; 910cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) dY[j] = dq[j][i]; 911cbe60e31SLeila Ghaffari State ds = StateFromY_fwd(context, s, dY, x_i, dx0); 912cbe60e31SLeila Ghaffari 913cbe60e31SLeila Ghaffari State grad_ds[3]; 914cbe60e31SLeila Ghaffari for (int j=0; j<3; j++) { 915cbe60e31SLeila Ghaffari CeedScalar dYj[5]; 916cbe60e31SLeila Ghaffari for (int k=0; k<5; k++) 917cbe60e31SLeila Ghaffari dYj[k] = Grad_dq[0][k][i] * dXdx[0][j] + 918cbe60e31SLeila Ghaffari Grad_dq[1][k][i] * dXdx[1][j] + 919cbe60e31SLeila Ghaffari Grad_dq[2][k][i] * dXdx[2][j]; 920cbe60e31SLeila Ghaffari grad_ds[j] = StateFromY_fwd(context, s, dYj, x_i, dx0); 921cbe60e31SLeila Ghaffari } 922cbe60e31SLeila Ghaffari 923cbe60e31SLeila Ghaffari CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3]; 924cbe60e31SLeila Ghaffari KMStrainRate(grad_ds, dstrain_rate); 925cbe60e31SLeila Ghaffari NewtonianStress(context, dstrain_rate, dkmstress); 926cbe60e31SLeila Ghaffari KMUnpack(dkmstress, dstress); 927cbe60e31SLeila Ghaffari KMUnpack(kmstress, stress); 928cbe60e31SLeila Ghaffari ViscousEnergyFlux_fwd(context, s.Y, ds.Y, grad_ds, stress, dstress, dFe); 929cbe60e31SLeila Ghaffari 930cbe60e31SLeila Ghaffari StateConservative dF_inviscid[3]; 931cbe60e31SLeila Ghaffari FluxInviscid_fwd(context, s, ds, dF_inviscid); 932cbe60e31SLeila Ghaffari 933cbe60e31SLeila Ghaffari // Total flux 934cbe60e31SLeila Ghaffari CeedScalar dFlux[5][3]; 935d1b9ef12SLeila Ghaffari FluxTotal(dF_inviscid, dstress, dFe, dFlux); 936cbe60e31SLeila Ghaffari 937d1b9ef12SLeila Ghaffari for (int j=0; j<3; j++) 938d1b9ef12SLeila Ghaffari for (int k=0; k<5; k++) 939cbe60e31SLeila Ghaffari Grad_v[j][k][i] = -wdetJ * (dXdx[j][0] * dFlux[k][0] + 940cbe60e31SLeila Ghaffari dXdx[j][1] * dFlux[k][1] + 941cbe60e31SLeila Ghaffari dXdx[j][2] * dFlux[k][2]); 942cbe60e31SLeila Ghaffari 943d1b9ef12SLeila Ghaffari const CeedScalar dbody_force[5] = {0, ds.U.density *g[0], ds.U.density *g[1], ds.U.density *g[2], 0}; 944cbe60e31SLeila Ghaffari CeedScalar dU[5] = {0.}; 945d1b9ef12SLeila Ghaffari UnpackState_U(ds.U, dU); 946cbe60e31SLeila Ghaffari 947cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) 948cbe60e31SLeila Ghaffari v[j][i] = wdetJ * (context->ijacobian_time_shift * dU[j] - dbody_force[j]); 949cbe60e31SLeila Ghaffari 950d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG 951d1b9ef12SLeila Ghaffari CeedScalar dstab[5][3], U_dot[5] = {0}; 952d1b9ef12SLeila Ghaffari for (CeedInt j=0; j<5; j++) U_dot[j] = context->ijacobian_time_shift * dU[j]; 953d1b9ef12SLeila Ghaffari Stabilization(context, s, Tau_d, grad_ds, U_dot, dbody_force, x_i, dstab); 954cbe60e31SLeila Ghaffari 955cbe60e31SLeila Ghaffari for (int j=0; j<5; j++) 956cbe60e31SLeila Ghaffari for (int k=0; k<3; k++) 957cbe60e31SLeila Ghaffari Grad_v[k][j][i] += wdetJ*(dstab[j][0] * dXdx[k][0] + 958cbe60e31SLeila Ghaffari dstab[j][1] * dXdx[k][1] + 959cbe60e31SLeila Ghaffari dstab[j][2] * dXdx[k][2]); 960cbe60e31SLeila Ghaffari 961cbe60e31SLeila Ghaffari } // End Quadrature Point Loop 962cbe60e31SLeila Ghaffari return 0; 963cbe60e31SLeila Ghaffari } 964cbe60e31SLeila Ghaffari // ***************************************************************************** 965cbe60e31SLeila Ghaffari 9663a8779fbSJames Wright #endif // newtonian_h 967