1ae2b091fSJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2024, HONEE contributors.
2ae2b091fSJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause
33a8779fbSJames Wright
43a8779fbSJames Wright /// @file
5ea615d4cSJames Wright /// Newtonian fluids operator for HONEE
63e17a7a1SJames Wright #include <ceed/types.h>
72b916ea7SJeremy L Thompson
8475b2820SJames Wright #include "newtonian_state.h"
9d0cce58aSJeremy L Thompson #include "newtonian_types.h"
10d1b9ef12SLeila Ghaffari #include "stabilization.h"
11d0cce58aSJeremy L Thompson #include "utils.h"
12bb8a0c61SJames Wright
13bb8a0c61SJames Wright // *****************************************************************************
143a8779fbSJames Wright // This QFunction sets a "still" initial condition for generic Newtonian IG problems
153a8779fbSJames Wright // *****************************************************************************
ICsNewtonianIG(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out,StateVariable state_var)168fff8293SJames Wright CEED_QFUNCTION_HELPER int ICsNewtonianIG(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, StateVariable state_var) {
173a8779fbSJames Wright CeedScalar(*q0)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
183a8779fbSJames Wright
19bb8a0c61SJames Wright const SetupContext context = (SetupContext)ctx;
20*cde3d787SJames Wright NewtonianIGProperties gas = context->newt_ctx.gas;
21bb8a0c61SJames Wright
222b916ea7SJeremy L Thompson CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
23a541e550SJames Wright CeedScalar q[5];
24*cde3d787SJames Wright State s = StateFromPrimitive(gas, context->reference);
25*cde3d787SJames Wright StateToQ(gas, s, q, state_var);
262b916ea7SJeremy L Thompson for (CeedInt j = 0; j < 5; j++) q0[j][i] = q[j];
27b193fadcSJames Wright }
283a8779fbSJames Wright return 0;
293a8779fbSJames Wright }
303a8779fbSJames Wright
ICsNewtonianIG_Conserv(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)319b103f75SJames Wright CEED_QFUNCTION(ICsNewtonianIG_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
329b103f75SJames Wright return ICsNewtonianIG(ctx, Q, in, out, STATEVAR_CONSERVATIVE);
339b103f75SJames Wright }
349b103f75SJames Wright
ICsNewtonianIG_Prim(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)352b916ea7SJeremy L Thompson CEED_QFUNCTION(ICsNewtonianIG_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
368fff8293SJames Wright return ICsNewtonianIG(ctx, Q, in, out, STATEVAR_PRIMITIVE);
37b8fb7609SAdeleke O. Bankole }
389b103f75SJames Wright
ICsNewtonianIG_Entropy(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)399b103f75SJames Wright CEED_QFUNCTION(ICsNewtonianIG_Entropy)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
409b103f75SJames Wright return ICsNewtonianIG(ctx, Q, in, out, STATEVAR_ENTROPY);
41cbe60e31SLeila Ghaffari }
42cbe60e31SLeila Ghaffari
MassFunction_Newtonian(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out,StateVariable state_var)4397cfd714SJames Wright CEED_QFUNCTION_HELPER int MassFunction_Newtonian(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, StateVariable state_var) {
4465dee3d2SJames Wright const CeedScalar(*q_dot)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0];
4565dee3d2SJames Wright const CeedScalar(*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[1];
4665dee3d2SJames Wright const CeedScalar(*q_data) = in[2];
4765dee3d2SJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
4865dee3d2SJames Wright CeedScalar(*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1];
4965dee3d2SJames Wright
5065dee3d2SJames Wright NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx;
51*cde3d787SJames Wright NewtonianIGProperties gas = context->gas;
5265dee3d2SJames Wright
5365dee3d2SJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
5465dee3d2SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]};
5565dee3d2SJames Wright const CeedScalar qi_dot[5] = {q_dot[0][i], q_dot[1][i], q_dot[2][i], q_dot[3][i], q_dot[4][i]};
56*cde3d787SJames Wright const State s = StateFromQ(gas, qi, state_var);
57*cde3d787SJames Wright const State s_dot = StateFromQ(gas, qi_dot, state_var);
5865dee3d2SJames Wright CeedScalar wdetJ, dXdx[3][3];
5965dee3d2SJames Wright QdataUnpack_3D(Q, i, q_data, &wdetJ, dXdx);
6065dee3d2SJames Wright
6165dee3d2SJames Wright // Standard mass matrix term
6265dee3d2SJames Wright for (CeedInt f = 0; f < 5; f++) {
6365dee3d2SJames Wright v[f][i] = wdetJ * qi_dot[f];
6465dee3d2SJames Wright }
6565dee3d2SJames Wright
6665dee3d2SJames Wright // Stabilization method: none (Galerkin), SU, or SUPG
6765dee3d2SJames Wright State grad_s[3] = {{{0.}}};
688c85b835SJames Wright CeedScalar Tau_d[3], stab[5][3], body_force[5] = {0.}, divFdiff[5] = {0.}, U_dot[5];
6965dee3d2SJames Wright UnpackState_U(s_dot.U, U_dot);
70*cde3d787SJames Wright Tau_diagPrim(context->tau_coeffs, gas, s, dXdx, context->dt, Tau_d);
71*cde3d787SJames Wright Stabilization(context->stabilization, gas, s, Tau_d, grad_s, U_dot, body_force, divFdiff, stab);
7265dee3d2SJames Wright
7365dee3d2SJames Wright // Stabilized mass term
7465dee3d2SJames Wright for (CeedInt j = 0; j < 5; j++) {
7565dee3d2SJames Wright for (CeedInt k = 0; k < 3; k++) {
7665dee3d2SJames Wright Grad_v[k][j][i] = wdetJ * (stab[j][0] * dXdx[k][0] + stab[j][1] * dXdx[k][1] + stab[j][2] * dXdx[k][2]);
7765dee3d2SJames Wright }
7865dee3d2SJames Wright }
7965dee3d2SJames Wright }
8097cfd714SJames Wright return 0;
8165dee3d2SJames Wright }
8265dee3d2SJames Wright
MassFunction_Newtonian_Conserv(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)8365dee3d2SJames Wright CEED_QFUNCTION(MassFunction_Newtonian_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
8497cfd714SJames Wright return MassFunction_Newtonian(ctx, Q, in, out, STATEVAR_CONSERVATIVE);
8565dee3d2SJames Wright }
8665dee3d2SJames Wright
87e57b52dbSJames Wright // @brief Computes the residual created by IDL
InternalDampingLayer_Residual(const NewtonianIGProperties gas,const State s,const CeedScalar sigma,CeedScalar damp_Y[5],CeedScalar damp_residual[5])88*cde3d787SJames Wright CEED_QFUNCTION_HELPER void InternalDampingLayer_Residual(const NewtonianIGProperties gas, const State s, const CeedScalar sigma, CeedScalar damp_Y[5],
89*cde3d787SJames Wright CeedScalar damp_residual[5]) {
9030b5892fSJames Wright ScaleN(damp_Y, sigma, 5);
91*cde3d787SJames Wright State damp_s = StateFromY_fwd(gas, s, damp_Y);
9230b5892fSJames Wright
9330b5892fSJames Wright CeedScalar U[5];
9430b5892fSJames Wright UnpackState_U(damp_s.U, U);
9530b5892fSJames Wright for (int i = 0; i < 5; i++) damp_residual[i] += U[i];
9630b5892fSJames Wright }
9730b5892fSJames Wright
98e57b52dbSJames Wright /**
99e57b52dbSJames Wright @brief IFunction integrand for Internal Damping Layer
100e57b52dbSJames Wright
101e57b52dbSJames Wright `location` refers to whatever scalar distance is desired for IDL to ramp from.
102e57b52dbSJames Wright See `LinearRampCoefficient()` for details on the `amplitude`, `length`, `start`, and `location` arguments.
103e57b52dbSJames Wright
104e57b52dbSJames Wright @param[in] s Solution `State`
105*cde3d787SJames Wright @param[in] gas Newtonian ideal gas properties
106e57b52dbSJames Wright @param[in] amplitude Amplitude of the IDL ramp
107e57b52dbSJames Wright @param[in] length Length of the IDL ramp
108e57b52dbSJames Wright @param[in] start Start of the IDL ramp
109e57b52dbSJames Wright @param[in] location Quadrature point location (relative to IDL ramp specification)
110e57b52dbSJames Wright @param[in] pressure Pressure used to damp to
111e57b52dbSJames Wright @param[inout] v_i Output to be multiplied by weight function, summed into
112e57b52dbSJames Wright @param[out] sigma IDL ramp coefficient
113e57b52dbSJames Wright **/
InternalDampingLayer_IFunction_Integrand(const State s,const NewtonianIGProperties gas,CeedScalar amplitude,CeedScalar length,CeedScalar start,CeedScalar location,CeedScalar pressure,CeedScalar v_i[5],CeedScalar * sigma)114*cde3d787SJames Wright CEED_QFUNCTION_HELPER void InternalDampingLayer_IFunction_Integrand(const State s, const NewtonianIGProperties gas, CeedScalar amplitude,
11530b5892fSJames Wright CeedScalar length, CeedScalar start, CeedScalar location, CeedScalar pressure,
11630b5892fSJames Wright CeedScalar v_i[5], CeedScalar *sigma) {
11730b5892fSJames Wright const CeedScalar sigma_ = LinearRampCoefficient(amplitude, length, start, location);
11830b5892fSJames Wright CeedScalar damp_state[5] = {s.Y.pressure - pressure, 0, 0, 0, 0}, idl_residual[5] = {0.};
119*cde3d787SJames Wright InternalDampingLayer_Residual(gas, s, sigma_, damp_state, idl_residual);
12030b5892fSJames Wright AXPY(1, idl_residual, v_i, 5);
12130b5892fSJames Wright *sigma = sigma_;
12230b5892fSJames Wright }
12330b5892fSJames Wright
1248fd72709SJames Wright /**
1258fd72709SJames Wright @brief IJacobian integrand for Internal Damping Layer
1268fd72709SJames Wright
1278fd72709SJames Wright @note This uses a Picard-type linearization of the damping and could be replaced by an `InternalDampingLayer_fwd` that uses s and ds.
1288fd72709SJames Wright
1298fd72709SJames Wright @param[in] s Solution `State`
1308fd72709SJames Wright @param[in] ds Change in `State` of solution
131*cde3d787SJames Wright @param[in] gas Newtonian ideal gas properties
1328fd72709SJames Wright @param[in] sigma IDL ramp coefficient
1338fd72709SJames Wright @param[inout] v_i Output to be multiplied by weight function, summed into
1348fd72709SJames Wright **/
InternalDampingLayer_IJacobian_Integrand(const State s,const State ds,const NewtonianIGProperties gas,CeedScalar sigma,CeedScalar v_i[5])135*cde3d787SJames Wright CEED_QFUNCTION_HELPER void InternalDampingLayer_IJacobian_Integrand(const State s, const State ds, const NewtonianIGProperties gas, CeedScalar sigma,
136*cde3d787SJames Wright CeedScalar v_i[5]) {
1378fd72709SJames Wright CeedScalar damp_state[5] = {ds.Y.pressure, 0, 0, 0, 0}, idl_residual[5] = {0.};
138*cde3d787SJames Wright InternalDampingLayer_Residual(gas, s, sigma, damp_state, idl_residual);
1398fd72709SJames Wright AXPY(1, idl_residual, v_i, 5);
1408fd72709SJames Wright }
1418fd72709SJames Wright
142cbe60e31SLeila Ghaffari // *****************************************************************************
14304e40bb6SJeremy L Thompson // This QFunction implements the following formulation of Navier-Stokes with explicit time stepping method
1443a8779fbSJames Wright //
14504e40bb6SJeremy L Thompson // This is 3D compressible Navier-Stokes in conservation form with state variables of density, momentum density, and total energy density.
1463a8779fbSJames Wright //
1473a8779fbSJames Wright // State Variables: q = ( rho, U1, U2, U3, E )
1483a8779fbSJames Wright // rho - Mass Density
1493a8779fbSJames Wright // Ui - Momentum Density, Ui = rho ui
1503a8779fbSJames Wright // E - Total Energy Density, E = rho (cv T + (u u)/2 + g z)
1513a8779fbSJames Wright //
1523a8779fbSJames Wright // Navier-Stokes Equations:
1533a8779fbSJames Wright // drho/dt + div( U ) = 0
1543a8779fbSJames Wright // dU/dt + div( rho (u x u) + P I3 ) + rho g khat = div( Fu )
1553a8779fbSJames Wright // dE/dt + div( (E + P) u ) = div( Fe )
1563a8779fbSJames Wright //
1573a8779fbSJames Wright // Viscous Stress:
1583a8779fbSJames Wright // Fu = mu (grad( u ) + grad( u )^T + lambda div ( u ) I3)
1593a8779fbSJames Wright //
1603a8779fbSJames Wright // Thermal Stress:
1613a8779fbSJames Wright // Fe = u Fu + k grad( T )
162bb8a0c61SJames Wright // Equation of State
1633a8779fbSJames Wright // P = (gamma - 1) (E - rho (u u) / 2 - rho g z)
1643a8779fbSJames Wright //
1653a8779fbSJames Wright // Stabilization:
1663a8779fbSJames Wright // Tau = diag(TauC, TauM, TauM, TauM, TauE)
1673a8779fbSJames Wright // f1 = rho sqrt(ui uj gij)
1683a8779fbSJames Wright // gij = dXi/dX * dXi/dX
1693a8779fbSJames Wright // TauC = Cc f1 / (8 gii)
1703a8779fbSJames Wright // TauM = min( 1 , 1 / f1 )
1713a8779fbSJames Wright // TauE = TauM / (Ce cv)
1723a8779fbSJames Wright //
1733a8779fbSJames Wright // SU = Galerkin + grad(v) . ( Ai^T * Tau * (Aj q,j) )
1743a8779fbSJames Wright //
1753a8779fbSJames Wright // Constants:
1763a8779fbSJames Wright // lambda = - 2 / 3, From Stokes hypothesis
1773a8779fbSJames Wright // mu , Dynamic viscosity
1783a8779fbSJames Wright // k , Thermal conductivity
1793a8779fbSJames Wright // cv , Specific heat, constant volume
1803a8779fbSJames Wright // cp , Specific heat, constant pressure
1813a8779fbSJames Wright // g , Gravity
1823a8779fbSJames Wright // gamma = cp / cv, Specific heat ratio
1833a8779fbSJames Wright //
18404e40bb6SJeremy L Thompson // We require the product of the inverse of the Jacobian (dXdx_j,k) and its transpose (dXdx_k,j) to properly compute integrals of the form: int( gradv
18504e40bb6SJeremy L Thompson // gradu )
1863a8779fbSJames Wright // *****************************************************************************
RHSFunction_Newtonian(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)1872b916ea7SJeremy L Thompson CEED_QFUNCTION(RHSFunction_Newtonian)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
188b3b24828SJames Wright NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx;
189b3b24828SJames Wright const bool use_divFdiff = context->divFdiff_method != DIV_DIFF_FLUX_PROJ_NONE;
190b3b24828SJames Wright
1913d65b166SJames Wright const CeedScalar(*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0];
19287bd45e7SJames Wright const CeedScalar(*Grad_q) = in[1];
193ade49511SJames Wright const CeedScalar(*q_data) = in[2];
1940a32a5aaSJames Wright const CeedScalar(*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3];
195b3b24828SJames Wright const CeedScalar(*divFdiff)[CEED_Q_VLA] = use_divFdiff ? (const CeedScalar(*)[CEED_Q_VLA])in[4] : NULL;
1963d65b166SJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
1973d65b166SJames Wright CeedScalar(*Grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1];
1983a8779fbSJames Wright
199bb8a0c61SJames Wright const CeedScalar *g = context->g;
200bb8a0c61SJames Wright const CeedScalar dt = context->dt;
201*cde3d787SJames Wright const NewtonianIGProperties gas = context->gas;
2023a8779fbSJames Wright
2033d65b166SJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
204ade49511SJames Wright CeedScalar U[5], wdetJ, dXdx[3][3];
2050a32a5aaSJames Wright const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]};
206c1a52365SJed Brown for (int j = 0; j < 5; j++) U[j] = q[j][i];
2071be49596SJames Wright QdataUnpack_3D(Q, i, q_data, &wdetJ, dXdx);
208*cde3d787SJames Wright State s = StateFromU(gas, U);
209c1a52365SJed Brown
210c1a52365SJed Brown State grad_s[3];
211*cde3d787SJames Wright StatePhysicalGradientFromReference(Q, i, gas, s, STATEVAR_CONSERVATIVE, Grad_q, dXdx, grad_s);
212c1a52365SJed Brown
213c1a52365SJed Brown CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3];
21440a33f2dSJames Wright KMStrainRate_State(grad_s, strain_rate);
215*cde3d787SJames Wright NewtonianStress(gas, strain_rate, kmstress);
216c1a52365SJed Brown KMUnpack(kmstress, stress);
217*cde3d787SJames Wright ViscousEnergyFlux(gas, s.Y, grad_s, stress, Fe);
218c1a52365SJed Brown
219c1a52365SJed Brown StateConservative F_inviscid[3];
220*cde3d787SJames Wright FluxInviscid(gas, s, F_inviscid);
221c1a52365SJed Brown
222c1a52365SJed Brown // Total flux
223c1a52365SJed Brown CeedScalar Flux[5][3];
224d1b9ef12SLeila Ghaffari FluxTotal(F_inviscid, stress, Fe, Flux);
225c1a52365SJed Brown
2267523f6aaSJames Wright for (CeedInt j = 0; j < 5; j++) {
2277523f6aaSJames Wright for (CeedInt k = 0; k < 3; k++) Grad_v[k][j][i] = wdetJ * (dXdx[k][0] * Flux[j][0] + dXdx[k][1] * Flux[j][1] + dXdx[k][2] * Flux[j][2]);
2282b916ea7SJeremy L Thompson }
229c1a52365SJed Brown
23060dbb574SKenneth E. Jansen const CeedScalar body_force[5] = {0, s.U.density * g[0], s.U.density * g[1], s.U.density * g[2], Dot3(s.U.momentum, g)};
2312b916ea7SJeremy L Thompson for (int j = 0; j < 5; j++) v[j][i] = wdetJ * body_force[j];
2323a8779fbSJames Wright
2330a32a5aaSJames Wright if (context->idl_enable) {
234*cde3d787SJames Wright const CeedScalar idl_pressure = context->idl_pressure;
2350a32a5aaSJames Wright const CeedScalar sigma = LinearRampCoefficient(context->idl_amplitude, context->idl_length, context->idl_start, x_i[0]);
236b3b24828SJames Wright CeedScalar damp_state[5] = {s.Y.pressure - idl_pressure, 0, 0, 0, 0}, idl_residual[5] = {0.};
237*cde3d787SJames Wright InternalDampingLayer_Residual(gas, s, sigma, damp_state, idl_residual);
2380a32a5aaSJames Wright for (int j = 0; j < 5; j++) v[j][i] -= wdetJ * idl_residual[j];
2390a32a5aaSJames Wright }
2400a32a5aaSJames Wright
241b3b24828SJames Wright CeedScalar divFdiff_i[5] = {0.};
242b3b24828SJames Wright if (use_divFdiff)
243b3b24828SJames Wright for (int j = 1; j < 5; j++) divFdiff_i[j] = divFdiff[j - 1][i];
244b3b24828SJames Wright
245d1b9ef12SLeila Ghaffari // -- Stabilization method: none (Galerkin), SU, or SUPG
246b3b24828SJames Wright CeedScalar Tau_d[3], stab[5][3], U_dot[5] = {0};
247*cde3d787SJames Wright Tau_diagPrim(context->tau_coeffs, gas, s, dXdx, dt, Tau_d);
248*cde3d787SJames Wright Stabilization(context->stabilization, gas, s, Tau_d, grad_s, U_dot, body_force, divFdiff_i, stab);
2493a8779fbSJames Wright
2502b916ea7SJeremy L Thompson for (CeedInt j = 0; j < 5; j++) {
2512b916ea7SJeremy L Thompson for (CeedInt k = 0; k < 3; k++) Grad_v[k][j][i] -= wdetJ * (stab[j][0] * dXdx[k][0] + stab[j][1] * dXdx[k][1] + stab[j][2] * dXdx[k][2]);
2522b916ea7SJeremy L Thompson }
253b193fadcSJames Wright }
2543a8779fbSJames Wright return 0;
2553a8779fbSJames Wright }
2563a8779fbSJames Wright
257e57b52dbSJames Wright /**
258e57b52dbSJames Wright @brief IFunction integrand of Navier-Stokes for Newtonian ideal gas
259e57b52dbSJames Wright
260e57b52dbSJames Wright This is used in the quadrature point loop within a larger QFunction.
261e57b52dbSJames Wright `v_i` and `dv_i` are summed into (meaning they must be some initialized value).
262e57b52dbSJames Wright `kmstress` and `Tau_d` are given to be included as Jacobian data.
263e57b52dbSJames Wright
264e57b52dbSJames Wright @param[in] s `State` of solution
265e57b52dbSJames Wright @param[in] grad_s Physical gradient of solution
266e57b52dbSJames Wright @param[in] s_dot Time derivative of solution
267e57b52dbSJames Wright @param[in] divFdiff_i Divergence of diffusive flux
268e57b52dbSJames Wright @param[in] x_i Coordinate location of quadrature point
269*cde3d787SJames Wright @param[in] gas Ideal gas properties
270e57b52dbSJames Wright @param[in] context Newtonian context
271e57b52dbSJames Wright @param[in] dXdx Inverse of element mapping Jacobian (d\xi / dx)
272e57b52dbSJames Wright @param[inout] v_i Output to be multiplied by weight function, summed into
273e57b52dbSJames Wright @param[inout] grad_v_i Output to be multiplied by gradient of weight function, summed into
274e57b52dbSJames Wright @param[out] kmstress Viscous stress, in Kelvin-Mandel ordering
275e57b52dbSJames Wright @param[out] Tau_d Diagonal Tau coefficients
276e57b52dbSJames Wright **/
IFunction_Newtonian_Integrand(const State s,const State grad_s[3],const State s_dot,const CeedScalar divFdiff_i[5],const CeedScalar x_i[3],const NewtonianIGProperties gas,const NewtonianIdealGasContext context,const CeedScalar dXdx[3][3],CeedScalar v_i[5],CeedScalar grad_v_i[5][3],CeedScalar kmstress[6],CeedScalar Tau_d[3])27730b5892fSJames Wright CEED_QFUNCTION_HELPER void IFunction_Newtonian_Integrand(const State s, const State grad_s[3], const State s_dot, const CeedScalar divFdiff_i[5],
278*cde3d787SJames Wright const CeedScalar x_i[3], const NewtonianIGProperties gas,
279*cde3d787SJames Wright const NewtonianIdealGasContext context, const CeedScalar dXdx[3][3], CeedScalar v_i[5],
280*cde3d787SJames Wright CeedScalar grad_v_i[5][3], CeedScalar kmstress[6], CeedScalar Tau_d[3]) {
281e57b52dbSJames Wright CeedScalar strain_rate[6], stress[3][3], F_visc_energy[3], F_total[5][3];
282e57b52dbSJames Wright StateConservative F_inviscid[3];
283e57b52dbSJames Wright const CeedScalar *g = context->g, dt = context->dt;
28430b5892fSJames Wright
285e57b52dbSJames Wright // Advective and viscous fluxes
28630b5892fSJames Wright KMStrainRate_State(grad_s, strain_rate);
287*cde3d787SJames Wright NewtonianStress(gas, strain_rate, kmstress);
28830b5892fSJames Wright KMUnpack(kmstress, stress);
289*cde3d787SJames Wright ViscousEnergyFlux(gas, s.Y, grad_s, stress, F_visc_energy);
290*cde3d787SJames Wright FluxInviscid(gas, s, F_inviscid);
291e57b52dbSJames Wright FluxTotal(F_inviscid, stress, F_visc_energy, F_total);
292e57b52dbSJames Wright AXPY(-1, (CeedScalar *)F_total, (CeedScalar *)grad_v_i, 15);
29330b5892fSJames Wright
294e57b52dbSJames Wright // Body force and time derivative
29530b5892fSJames Wright const CeedScalar body_force[5] = {0, s.U.density * g[0], s.U.density * g[1], s.U.density * g[2], Dot3(s.U.momentum, g)};
296e57b52dbSJames Wright CeedScalar U_dot[5];
29730b5892fSJames Wright UnpackState_U(s_dot.U, U_dot);
29830b5892fSJames Wright for (CeedInt j = 0; j < 5; j++) v_i[j] += U_dot[j] - body_force[j];
299e57b52dbSJames Wright
300e57b52dbSJames Wright // Stabilization
301e57b52dbSJames Wright CeedScalar stab[5][3];
302*cde3d787SJames Wright Tau_diagPrim(context->tau_coeffs, gas, s, dXdx, dt, Tau_d);
303*cde3d787SJames Wright Stabilization(context->stabilization, gas, s, Tau_d, grad_s, U_dot, body_force, divFdiff_i, stab);
304e57b52dbSJames Wright AXPY(1, (CeedScalar *)stab, (CeedScalar *)grad_v_i, 15);
30530b5892fSJames Wright }
30630b5892fSJames Wright
307e57b52dbSJames Wright // @brief State-independent IFunction of Navier-Stokes for Newtonian ideal gas
IFunction_Newtonian(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out,StateVariable state_var)3088fff8293SJames Wright CEED_QFUNCTION_HELPER int IFunction_Newtonian(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, StateVariable state_var) {
3098c85b835SJames Wright NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx;
310ff684e42SJames Wright const bool use_divFdiff = context->divFdiff_method != DIV_DIFF_FLUX_PROJ_NONE;
3118c85b835SJames Wright
3123d65b166SJames Wright const CeedScalar(*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0];
313e57b52dbSJames Wright const CeedScalar(*grad_q) = in[1];
3143d65b166SJames Wright const CeedScalar(*q_dot)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2];
315ade49511SJames Wright const CeedScalar(*q_data) = in[3];
3163d65b166SJames Wright const CeedScalar(*x)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[4];
317ff684e42SJames Wright const CeedScalar(*divFdiff)[CEED_Q_VLA] = use_divFdiff ? (const CeedScalar(*)[CEED_Q_VLA])in[5] : NULL;
3183d65b166SJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
319e57b52dbSJames Wright CeedScalar(*grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1];
320ade49511SJames Wright CeedScalar(*jac_data) = out[2];
3213d65b166SJames Wright
322*cde3d787SJames Wright const NewtonianIGProperties gas = context->gas;
323*cde3d787SJames Wright
3243d65b166SJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
325e57b52dbSJames Wright const CeedScalar q_i[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]};
326e57b52dbSJames Wright const CeedScalar q_i_dot[5] = {q_dot[0][i], q_dot[1][i], q_dot[2][i], q_dot[3][i], q_dot[4][i]};
327c1a52365SJed Brown const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]};
328*cde3d787SJames Wright const State s = StateFromQ(gas, q_i, state_var);
329*cde3d787SJames Wright const State s_dot = StateFromQ_fwd(gas, s, q_i_dot, state_var);
330c1a52365SJed Brown
331ade49511SJames Wright CeedScalar wdetJ, dXdx[3][3];
332ade49511SJames Wright QdataUnpack_3D(Q, i, q_data, &wdetJ, dXdx);
333c1a52365SJed Brown State grad_s[3];
334*cde3d787SJames Wright StatePhysicalGradientFromReference(Q, i, gas, s, state_var, grad_q, dXdx, grad_s);
3358c85b835SJames Wright CeedScalar divFdiff_i[5] = {0.};
33630b5892fSJames Wright if (use_divFdiff)
3378c85b835SJames Wright for (int j = 1; j < 5; j++) divFdiff_i[j] = divFdiff[j - 1][i];
3383a8779fbSJames Wright
339ab18f1e5SJames Wright CeedScalar v_i[5] = {0.}, grad_v_i[5][3] = {{0.}}, kmstress[6], Tau_d[3], sigma = 0;
340*cde3d787SJames Wright IFunction_Newtonian_Integrand(s, grad_s, s_dot, divFdiff_i, x_i, gas, context, dXdx, v_i, grad_v_i, kmstress, Tau_d);
34130b5892fSJames Wright if (context->idl_enable)
342*cde3d787SJames Wright InternalDampingLayer_IFunction_Integrand(s, gas, context->idl_amplitude, context->idl_length, context->idl_start, x_i[0], context->idl_pressure,
343*cde3d787SJames Wright v_i, &sigma);
34430b5892fSJames Wright
34530b5892fSJames Wright for (CeedInt j = 0; j < 5; j++) v[j][i] = wdetJ * v_i[j];
3462b916ea7SJeremy L Thompson for (CeedInt j = 0; j < 5; j++) {
3478fd72709SJames Wright for (CeedInt k = 0; k < 3; k++)
348e57b52dbSJames Wright grad_v[k][j][i] = wdetJ * (grad_v_i[j][0] * dXdx[k][0] + grad_v_i[j][1] * dXdx[k][1] + grad_v_i[j][2] * dXdx[k][2]);
3493d65b166SJames Wright }
35030b5892fSJames Wright
351e57b52dbSJames Wright StoredValuesPack(Q, i, 0, 5, q_i, jac_data);
352ade49511SJames Wright StoredValuesPack(Q, i, 5, 6, kmstress, jac_data);
353ade49511SJames Wright StoredValuesPack(Q, i, 11, 3, Tau_d, jac_data);
35430b5892fSJames Wright if (context->idl_enable) StoredValuesPack(Q, i, 14, 1, &sigma, jac_data);
355b193fadcSJames Wright }
3563a8779fbSJames Wright return 0;
3573a8779fbSJames Wright }
358f0b65372SJed Brown
IFunction_Newtonian_Conserv(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)3592b916ea7SJeremy L Thompson CEED_QFUNCTION(IFunction_Newtonian_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
3608fff8293SJames Wright return IFunction_Newtonian(ctx, Q, in, out, STATEVAR_CONSERVATIVE);
36176555becSJames Wright }
36276555becSJames Wright
IFunction_Newtonian_Prim(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)3632b916ea7SJeremy L Thompson CEED_QFUNCTION(IFunction_Newtonian_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
3648fff8293SJames Wright return IFunction_Newtonian(ctx, Q, in, out, STATEVAR_PRIMITIVE);
36576555becSJames Wright }
36676555becSJames Wright
IFunction_Newtonian_Entropy(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)3679b103f75SJames Wright CEED_QFUNCTION(IFunction_Newtonian_Entropy)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
3689b103f75SJames Wright return IFunction_Newtonian(ctx, Q, in, out, STATEVAR_ENTROPY);
3699b103f75SJames Wright }
3709b103f75SJames Wright
3718fd72709SJames Wright /**
3728fd72709SJames Wright @brief IJacobian integrand of Navier-Stokes for Newtonian ideal gas
3733d65b166SJames Wright
3748fd72709SJames Wright This is used in the quadrature point loop within a larger QFunction.
3758fd72709SJames Wright `v_i` and `dv_i` are summed into (meaning they must be some initialized value).
3768fd72709SJames Wright `kmstress` and `Tau_d` are (generally) calculated and stored by the IFunction.
3778fd72709SJames Wright
3788fd72709SJames Wright @param[in] s `State` of solution
3798fd72709SJames Wright @param[in] ds Change in `State` of solution
3808fd72709SJames Wright @param[in] grad_ds Physical gradient of change in `State` of solution
381*cde3d787SJames Wright @param[in] gas Ideal gas properties
3828fd72709SJames Wright @param[in] context Newtonian context
3838fd72709SJames Wright @param[in] kmstress Viscous stress, in Kelvin-Mandel ordering
3848fd72709SJames Wright @param[in] Tau_d Diagonal Tau coefficients
3858fd72709SJames Wright @param[inout] v_i Output to be multiplied by weight function, summed into
3868fd72709SJames Wright @param[inout] grad_v_i Output to be multiplied by gradient of weight function, summed into
3878fd72709SJames Wright **/
IJacobian_Newtonian_Integrand(const State s,const State ds,const State grad_ds[3],const NewtonianIGProperties gas,const NewtonianIdealGasContext context,const CeedScalar kmstress[6],const CeedScalar Tau_d[3],CeedScalar v_i[5],CeedScalar grad_v_i[5][3])388*cde3d787SJames Wright CEED_QFUNCTION_HELPER void IJacobian_Newtonian_Integrand(const State s, const State ds, const State grad_ds[3], const NewtonianIGProperties gas,
3898fd72709SJames Wright const NewtonianIdealGasContext context, const CeedScalar kmstress[6],
3908fd72709SJames Wright const CeedScalar Tau_d[3], CeedScalar v_i[5], CeedScalar grad_v_i[5][3]) {
391f0b65372SJed Brown const CeedScalar *g = context->g;
3928fd72709SJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dF_visc_energy[3], dF_total[5][3];
3938fd72709SJames Wright StateConservative dF_inviscid[3];
394f0b65372SJed Brown
3958fd72709SJames Wright // Advective and viscous fluxes
39640a33f2dSJames Wright KMStrainRate_State(grad_ds, dstrain_rate);
397*cde3d787SJames Wright NewtonianStress(gas, dstrain_rate, dkmstress);
398f0b65372SJed Brown KMUnpack(dkmstress, dstress);
399f0b65372SJed Brown KMUnpack(kmstress, stress);
400*cde3d787SJames Wright ViscousEnergyFlux_fwd(gas, s.Y, ds.Y, grad_ds, stress, dstress, dF_visc_energy);
401*cde3d787SJames Wright FluxInviscid_fwd(gas, s, ds, dF_inviscid);
4028fd72709SJames Wright FluxTotal(dF_inviscid, dstress, dF_visc_energy, dF_total);
4038fd72709SJames Wright AXPY(-1, (CeedScalar *)dF_total, (CeedScalar *)grad_v_i, 15);
404f0b65372SJed Brown
4058fd72709SJames Wright // Body force and time derivative
40660dbb574SKenneth E. Jansen const CeedScalar dbody_force[5] = {0, ds.U.density * g[0], ds.U.density * g[1], ds.U.density * g[2], Dot3(ds.U.momentum, g)};
4078fd72709SJames Wright CeedScalar dU[5], dU_dot[5];
40876555becSJames Wright UnpackState_U(ds.U, dU);
4098fd72709SJames Wright for (CeedInt j = 0; j < 5; j++) {
4108fd72709SJames Wright dU_dot[j] = context->ijacobian_time_shift * dU[j];
4118fd72709SJames Wright v_i[j] = dU_dot[j] - dbody_force[j];
412e7754af5SKenneth E. Jansen }
413e7754af5SKenneth E. Jansen
4148fd72709SJames Wright // Stabilization
4158fd72709SJames Wright CeedScalar dstab[5][3];
4168c85b835SJames Wright const CeedScalar zeroFlux[5] = {0.};
417*cde3d787SJames Wright Stabilization(context->stabilization, gas, s, Tau_d, grad_ds, dU_dot, dbody_force, zeroFlux, dstab);
4188fd72709SJames Wright AXPY(1, (CeedScalar *)dstab, (CeedScalar *)grad_v_i, 15);
4198fd72709SJames Wright }
420d1b9ef12SLeila Ghaffari
4218fd72709SJames Wright // @brief State-independent IJacobian of Navier-Stokes for Newtonian ideal gas
IJacobian_Newtonian(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out,StateVariable state_var)4228fd72709SJames Wright CEED_QFUNCTION_HELPER int IJacobian_Newtonian(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, StateVariable state_var) {
4238fd72709SJames Wright const CeedScalar(*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0];
4248fd72709SJames Wright const CeedScalar(*grad_dq) = in[1];
4258fd72709SJames Wright const CeedScalar(*q_data) = in[2];
4268fd72709SJames Wright const CeedScalar(*jac_data) = in[3];
4278fd72709SJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
4288fd72709SJames Wright CeedScalar(*grad_v)[5][CEED_Q_VLA] = (CeedScalar(*)[5][CEED_Q_VLA])out[1];
4298fd72709SJames Wright
430*cde3d787SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx;
431*cde3d787SJames Wright const NewtonianIGProperties gas = context->gas;
4328fd72709SJames Wright
4338fd72709SJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
4348fd72709SJames Wright const CeedScalar dq_i[5] = {dq[0][i], dq[1][i], dq[2][i], dq[3][i], dq[4][i]};
4358fd72709SJames Wright CeedScalar qi[5], kmstress[6], Tau_d[3];
4368fd72709SJames Wright StoredValuesUnpack(Q, i, 0, 5, jac_data, qi);
4378fd72709SJames Wright StoredValuesUnpack(Q, i, 5, 6, jac_data, kmstress);
4388fd72709SJames Wright StoredValuesUnpack(Q, i, 11, 3, jac_data, Tau_d);
439*cde3d787SJames Wright const State s = StateFromQ(gas, qi, state_var);
440*cde3d787SJames Wright const State ds = StateFromQ_fwd(gas, s, dq_i, state_var);
4418fd72709SJames Wright
4428fd72709SJames Wright CeedScalar wdetJ, dXdx[3][3];
4438fd72709SJames Wright QdataUnpack_3D(Q, i, q_data, &wdetJ, dXdx);
4448fd72709SJames Wright State grad_ds[3];
445*cde3d787SJames Wright StatePhysicalGradientFromReference(Q, i, gas, s, state_var, grad_dq, dXdx, grad_ds);
4468fd72709SJames Wright
4478fd72709SJames Wright CeedScalar v_i[5] = {0.}, grad_v_i[5][3] = {{0.}};
448*cde3d787SJames Wright IJacobian_Newtonian_Integrand(s, ds, grad_ds, gas, context, kmstress, Tau_d, v_i, grad_v_i);
4498fd72709SJames Wright if (context->idl_enable) {
4508fd72709SJames Wright CeedScalar sigma;
4518fd72709SJames Wright StoredValuesUnpack(Q, i, 14, 1, jac_data, &sigma);
452*cde3d787SJames Wright InternalDampingLayer_IJacobian_Integrand(s, ds, gas, sigma, v_i);
4538fd72709SJames Wright for (int j = 0; j < 5; j++) v[j][i] += wdetJ * v_i[j];
4548fd72709SJames Wright }
4558fd72709SJames Wright
4568fd72709SJames Wright for (CeedInt j = 0; j < 5; j++) v[j][i] = wdetJ * v_i[j];
4572b916ea7SJeremy L Thompson for (int j = 0; j < 5; j++) {
4588fd72709SJames Wright for (int k = 0; k < 3; k++) grad_v[k][j][i] = wdetJ * (grad_v_i[j][0] * dXdx[k][0] + grad_v_i[j][1] * dXdx[k][1] + grad_v_i[j][2] * dXdx[k][2]);
4592b916ea7SJeremy L Thompson }
460b193fadcSJames Wright }
461f0b65372SJed Brown return 0;
462f0b65372SJed Brown }
4638085925cSJames Wright
IJacobian_Newtonian_Conserv(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)4642b916ea7SJeremy L Thompson CEED_QFUNCTION(IJacobian_Newtonian_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
4658fff8293SJames Wright return IJacobian_Newtonian(ctx, Q, in, out, STATEVAR_CONSERVATIVE);
46676555becSJames Wright }
46776555becSJames Wright
IJacobian_Newtonian_Prim(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)4682b916ea7SJeremy L Thompson CEED_QFUNCTION(IJacobian_Newtonian_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
4698fff8293SJames Wright return IJacobian_Newtonian(ctx, Q, in, out, STATEVAR_PRIMITIVE);
47076555becSJames Wright }
47176555becSJames Wright
IJacobian_Newtonian_Entropy(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)4729b103f75SJames Wright CEED_QFUNCTION(IJacobian_Newtonian_Entropy)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
4739b103f75SJames Wright return IJacobian_Newtonian(ctx, Q, in, out, STATEVAR_ENTROPY);
4749b103f75SJames Wright }
4759b103f75SJames Wright
476d1b9ef12SLeila Ghaffari // *****************************************************************************
4778085925cSJames Wright // Compute boundary integral (ie. for strongly set inflows)
478d1b9ef12SLeila Ghaffari // *****************************************************************************
BoundaryIntegral(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out,StateVariable state_var)4798fff8293SJames Wright CEED_QFUNCTION_HELPER int BoundaryIntegral(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, StateVariable state_var) {
4804b96a86bSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx;
4813d65b166SJames Wright const CeedScalar(*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0];
48287bd45e7SJames Wright const CeedScalar(*Grad_q) = in[1];
483ade49511SJames Wright const CeedScalar(*q_data_sur) = in[2];
4843d65b166SJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
4854b96a86bSJames Wright CeedScalar(*jac_data_sur) = context->is_implicit ? out[1] : NULL;
4868085925cSJames Wright
487d3b25f3aSJames Wright const bool is_implicit = context->is_implicit;
488*cde3d787SJames Wright const NewtonianIGProperties gas = context->gas;
4898085925cSJames Wright
4902b916ea7SJeremy L Thompson CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
49141e73928SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]};
492*cde3d787SJames Wright State s = StateFromQ(gas, qi, state_var);
4938085925cSJames Wright
49478e8b7daSJames Wright CeedScalar wdetJb, dXdx[2][3], normal[3];
49578e8b7daSJames Wright QdataBoundaryUnpack_3D(Q, i, q_data_sur, &wdetJb, dXdx, normal);
496ade49511SJames Wright wdetJb *= is_implicit ? -1. : 1.;
4978085925cSJames Wright
498d3b25f3aSJames Wright State grad_s[3];
499*cde3d787SJames Wright StatePhysicalGradientFromReference_Boundary(Q, i, gas, s, state_var, Grad_q, dXdx, grad_s);
5008085925cSJames Wright
501d3b25f3aSJames Wright CeedScalar strain_rate[6], kmstress[6], stress[3][3], Fe[3];
50240a33f2dSJames Wright KMStrainRate_State(grad_s, strain_rate);
503*cde3d787SJames Wright NewtonianStress(gas, strain_rate, kmstress);
504d3b25f3aSJames Wright KMUnpack(kmstress, stress);
505*cde3d787SJames Wright ViscousEnergyFlux(gas, s.Y, grad_s, stress, Fe);
506d3b25f3aSJames Wright
507d3b25f3aSJames Wright StateConservative F_inviscid[3];
508*cde3d787SJames Wright FluxInviscid(gas, s, F_inviscid);
509d3b25f3aSJames Wright
510c5740391SJames Wright CeedScalar Flux[5];
51178e8b7daSJames Wright FluxTotal_Boundary(F_inviscid, stress, Fe, normal, Flux);
512d3b25f3aSJames Wright
513c5740391SJames Wright for (CeedInt j = 0; j < 5; j++) v[j][i] = -wdetJb * Flux[j];
5148085925cSJames Wright
5154b96a86bSJames Wright if (is_implicit) {
516ade49511SJames Wright StoredValuesPack(Q, i, 0, 5, qi, jac_data_sur);
517ade49511SJames Wright StoredValuesPack(Q, i, 5, 6, kmstress, jac_data_sur);
5188085925cSJames Wright }
5194b96a86bSJames Wright }
5208085925cSJames Wright return 0;
5218085925cSJames Wright }
5228085925cSJames Wright
BoundaryIntegral_Conserv(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)5232b916ea7SJeremy L Thompson CEED_QFUNCTION(BoundaryIntegral_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
5248fff8293SJames Wright return BoundaryIntegral(ctx, Q, in, out, STATEVAR_CONSERVATIVE);
525d4559bbeSJames Wright }
526d4559bbeSJames Wright
BoundaryIntegral_Prim(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)5272b916ea7SJeremy L Thompson CEED_QFUNCTION(BoundaryIntegral_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
5288fff8293SJames Wright return BoundaryIntegral(ctx, Q, in, out, STATEVAR_PRIMITIVE);
529d4559bbeSJames Wright }
530d4559bbeSJames Wright
BoundaryIntegral_Entropy(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)5319b103f75SJames Wright CEED_QFUNCTION(BoundaryIntegral_Entropy)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
5329b103f75SJames Wright return BoundaryIntegral(ctx, Q, in, out, STATEVAR_ENTROPY);
5339b103f75SJames Wright }
5349b103f75SJames Wright
535d1b9ef12SLeila Ghaffari // *****************************************************************************
53668ae065aSJames Wright // Jacobian for "set nothing" boundary integral
537d1b9ef12SLeila Ghaffari // *****************************************************************************
BoundaryIntegral_Jacobian(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out,StateVariable state_var)5382b916ea7SJeremy L Thompson CEED_QFUNCTION_HELPER int BoundaryIntegral_Jacobian(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out,
5398fff8293SJames Wright StateVariable state_var) {
5403d65b166SJames Wright const CeedScalar(*dq)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0];
54187bd45e7SJames Wright const CeedScalar(*Grad_dq) = in[1];
542ade49511SJames Wright const CeedScalar(*q_data_sur) = in[2];
543c1484fadSKenneth E. Jansen const CeedScalar(*jac_data_sur) = in[4];
54468ae065aSJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
54568ae065aSJames Wright
54668ae065aSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx;
547*cde3d787SJames Wright const NewtonianIGProperties gas = context->gas;
548ade49511SJames Wright const bool is_implicit = context->is_implicit;
54968ae065aSJames Wright
5503d65b166SJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
55178e8b7daSJames Wright CeedScalar wdetJb, dXdx[2][3], normal[3];
55278e8b7daSJames Wright QdataBoundaryUnpack_3D(Q, i, q_data_sur, &wdetJb, dXdx, normal);
553ade49511SJames Wright wdetJb *= is_implicit ? -1. : 1.;
55468ae065aSJames Wright
555edcfef1bSKenneth E. Jansen CeedScalar qi[5], kmstress[6], dqi[5];
556ade49511SJames Wright StoredValuesUnpack(Q, i, 0, 5, jac_data_sur, qi);
557ade49511SJames Wright StoredValuesUnpack(Q, i, 5, 6, jac_data_sur, kmstress);
55841e73928SJames Wright for (int j = 0; j < 5; j++) dqi[j] = dq[j][i];
5593934e2b1SJames Wright
560*cde3d787SJames Wright State s = StateFromQ(gas, qi, state_var);
561*cde3d787SJames Wright State ds = StateFromQ_fwd(gas, s, dqi, state_var);
56268ae065aSJames Wright
56368ae065aSJames Wright State grad_ds[3];
564*cde3d787SJames Wright StatePhysicalGradientFromReference_Boundary(Q, i, gas, s, state_var, Grad_dq, dXdx, grad_ds);
56568ae065aSJames Wright
56668ae065aSJames Wright CeedScalar dstrain_rate[6], dkmstress[6], stress[3][3], dstress[3][3], dFe[3];
56740a33f2dSJames Wright KMStrainRate_State(grad_ds, dstrain_rate);
568*cde3d787SJames Wright NewtonianStress(gas, dstrain_rate, dkmstress);
56968ae065aSJames Wright KMUnpack(dkmstress, dstress);
57068ae065aSJames Wright KMUnpack(kmstress, stress);
571*cde3d787SJames Wright ViscousEnergyFlux_fwd(gas, s.Y, ds.Y, grad_ds, stress, dstress, dFe);
57268ae065aSJames Wright
57368ae065aSJames Wright StateConservative dF_inviscid[3];
574*cde3d787SJames Wright FluxInviscid_fwd(gas, s, ds, dF_inviscid);
57568ae065aSJames Wright
576c5740391SJames Wright CeedScalar dFlux[5];
57778e8b7daSJames Wright FluxTotal_Boundary(dF_inviscid, dstress, dFe, normal, dFlux);
57868ae065aSJames Wright
579c5740391SJames Wright for (int j = 0; j < 5; j++) v[j][i] = -wdetJb * dFlux[j];
580512c8ec7SJames Wright }
58168ae065aSJames Wright return 0;
58268ae065aSJames Wright }
58368ae065aSJames Wright
BoundaryIntegral_Jacobian_Conserv(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)5842b916ea7SJeremy L Thompson CEED_QFUNCTION(BoundaryIntegral_Jacobian_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
5858fff8293SJames Wright return BoundaryIntegral_Jacobian(ctx, Q, in, out, STATEVAR_CONSERVATIVE);
586d4559bbeSJames Wright }
587d4559bbeSJames Wright
BoundaryIntegral_Jacobian_Prim(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)5882b916ea7SJeremy L Thompson CEED_QFUNCTION(BoundaryIntegral_Jacobian_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
5898fff8293SJames Wright return BoundaryIntegral_Jacobian(ctx, Q, in, out, STATEVAR_PRIMITIVE);
590d4559bbeSJames Wright }
5919b103f75SJames Wright
BoundaryIntegral_Jacobian_Entropy(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)5929b103f75SJames Wright CEED_QFUNCTION(BoundaryIntegral_Jacobian_Entropy)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
5939b103f75SJames Wright return BoundaryIntegral_Jacobian(ctx, Q, in, out, STATEVAR_ENTROPY);
5949b103f75SJames Wright }
59536038bbcSJames Wright
5968561fee2SJames Wright // @brief Volume integral for RHS of divergence of diffusive flux direct projection
DivDiffusiveFluxVolumeRHS_NS(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out,StateVariable state_var)59736038bbcSJames Wright CEED_QFUNCTION_HELPER int DivDiffusiveFluxVolumeRHS_NS(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out,
59836038bbcSJames Wright StateVariable state_var) {
59936038bbcSJames Wright const CeedScalar(*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0];
60036038bbcSJames Wright const CeedScalar(*Grad_q) = in[1];
60136038bbcSJames Wright const CeedScalar(*q_data) = in[2];
60236038bbcSJames Wright CeedScalar(*Grad_v)[4][CEED_Q_VLA] = (CeedScalar(*)[4][CEED_Q_VLA])out[0];
60336038bbcSJames Wright
60436038bbcSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx;
605*cde3d787SJames Wright const NewtonianIGProperties gas = context->gas;
60636038bbcSJames Wright const StateConservative ZeroInviscidFluxes[3] = {{0}};
60736038bbcSJames Wright
60836038bbcSJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
60936038bbcSJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]};
610*cde3d787SJames Wright const State s = StateFromQ(gas, qi, state_var);
61136038bbcSJames Wright CeedScalar wdetJ, dXdx[3][3];
61236038bbcSJames Wright CeedScalar stress[3][3], Fe[3], Fdiff[5][3];
61336038bbcSJames Wright
61436038bbcSJames Wright QdataUnpack_3D(Q, i, q_data, &wdetJ, dXdx);
61536038bbcSJames Wright { // Get stress and Fe
61636038bbcSJames Wright State grad_s[3];
61736038bbcSJames Wright CeedScalar strain_rate[6], kmstress[6];
61836038bbcSJames Wright
619*cde3d787SJames Wright StatePhysicalGradientFromReference(Q, i, gas, s, state_var, Grad_q, dXdx, grad_s);
62036038bbcSJames Wright KMStrainRate_State(grad_s, strain_rate);
621*cde3d787SJames Wright NewtonianStress(gas, strain_rate, kmstress);
62236038bbcSJames Wright KMUnpack(kmstress, stress);
623*cde3d787SJames Wright ViscousEnergyFlux(gas, s.Y, grad_s, stress, Fe);
62436038bbcSJames Wright }
62536038bbcSJames Wright
62636038bbcSJames Wright FluxTotal(ZeroInviscidFluxes, stress, Fe, Fdiff);
62736038bbcSJames Wright
62836038bbcSJames Wright for (CeedInt j = 1; j < 5; j++) { // Continuity has no diffusive flux, therefore skip
62936038bbcSJames Wright for (CeedInt k = 0; k < 3; k++) {
63036038bbcSJames Wright Grad_v[k][j - 1][i] = -wdetJ * Dot3(dXdx[k], Fdiff[j]);
63136038bbcSJames Wright }
63236038bbcSJames Wright }
63336038bbcSJames Wright }
63436038bbcSJames Wright return 0;
63536038bbcSJames Wright }
63636038bbcSJames Wright
DivDiffusiveFluxVolumeRHS_NS_Conserv(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)63736038bbcSJames Wright CEED_QFUNCTION(DivDiffusiveFluxVolumeRHS_NS_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
63836038bbcSJames Wright return DivDiffusiveFluxVolumeRHS_NS(ctx, Q, in, out, STATEVAR_CONSERVATIVE);
63936038bbcSJames Wright }
64036038bbcSJames Wright
DivDiffusiveFluxVolumeRHS_NS_Prim(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)64136038bbcSJames Wright CEED_QFUNCTION(DivDiffusiveFluxVolumeRHS_NS_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
64236038bbcSJames Wright return DivDiffusiveFluxVolumeRHS_NS(ctx, Q, in, out, STATEVAR_PRIMITIVE);
64336038bbcSJames Wright }
64436038bbcSJames Wright
DivDiffusiveFluxVolumeRHS_NS_Entropy(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)64536038bbcSJames Wright CEED_QFUNCTION(DivDiffusiveFluxVolumeRHS_NS_Entropy)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
64636038bbcSJames Wright return DivDiffusiveFluxVolumeRHS_NS(ctx, Q, in, out, STATEVAR_ENTROPY);
64736038bbcSJames Wright }
64836038bbcSJames Wright
6498561fee2SJames Wright // @brief Boundary integral for RHS of divergence of diffusive flux direct projection
DivDiffusiveFluxBoundaryRHS_NS(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out,StateVariable state_var)65036038bbcSJames Wright CEED_QFUNCTION_HELPER int DivDiffusiveFluxBoundaryRHS_NS(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out,
65136038bbcSJames Wright StateVariable state_var) {
65236038bbcSJames Wright const CeedScalar(*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0];
65336038bbcSJames Wright const CeedScalar(*Grad_q) = in[1];
65436038bbcSJames Wright const CeedScalar(*q_data) = in[2];
65536038bbcSJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
65636038bbcSJames Wright
65736038bbcSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx;
658*cde3d787SJames Wright const NewtonianIGProperties gas = context->gas;
65936038bbcSJames Wright const StateConservative ZeroInviscidFluxes[3] = {{0}};
66036038bbcSJames Wright
66136038bbcSJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
66236038bbcSJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]};
663*cde3d787SJames Wright const State s = StateFromQ(gas, qi, state_var);
66436038bbcSJames Wright CeedScalar wdetJ, dXdx[3][3], normal[3];
66536038bbcSJames Wright CeedScalar stress[3][3], Fe[3], Fdiff[5];
66636038bbcSJames Wright
66736038bbcSJames Wright QdataBoundaryGradientUnpack_3D(Q, i, q_data, &wdetJ, dXdx, normal);
66836038bbcSJames Wright { // Get stress and Fe
66936038bbcSJames Wright State grad_s[3];
67036038bbcSJames Wright CeedScalar strain_rate[6], kmstress[6];
67136038bbcSJames Wright
672*cde3d787SJames Wright StatePhysicalGradientFromReference(Q, i, gas, s, state_var, Grad_q, dXdx, grad_s);
67336038bbcSJames Wright KMStrainRate_State(grad_s, strain_rate);
674*cde3d787SJames Wright NewtonianStress(gas, strain_rate, kmstress);
67536038bbcSJames Wright KMUnpack(kmstress, stress);
676*cde3d787SJames Wright ViscousEnergyFlux(gas, s.Y, grad_s, stress, Fe);
67736038bbcSJames Wright }
67836038bbcSJames Wright
67936038bbcSJames Wright FluxTotal_Boundary(ZeroInviscidFluxes, stress, Fe, normal, Fdiff);
68036038bbcSJames Wright
68136038bbcSJames Wright // Continuity has no diffusive flux, therefore skip
68236038bbcSJames Wright for (CeedInt j = 1; j < 5; j++) v[j - 1][i] = wdetJ * Fdiff[j];
68336038bbcSJames Wright }
68436038bbcSJames Wright return 0;
68536038bbcSJames Wright }
68636038bbcSJames Wright
DivDiffusiveFluxBoundaryRHS_NS_Conserv(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)68736038bbcSJames Wright CEED_QFUNCTION(DivDiffusiveFluxBoundaryRHS_NS_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
68836038bbcSJames Wright return DivDiffusiveFluxBoundaryRHS_NS(ctx, Q, in, out, STATEVAR_CONSERVATIVE);
68936038bbcSJames Wright }
69036038bbcSJames Wright
DivDiffusiveFluxBoundaryRHS_NS_Prim(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)69136038bbcSJames Wright CEED_QFUNCTION(DivDiffusiveFluxBoundaryRHS_NS_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
69236038bbcSJames Wright return DivDiffusiveFluxBoundaryRHS_NS(ctx, Q, in, out, STATEVAR_PRIMITIVE);
69336038bbcSJames Wright }
69436038bbcSJames Wright
DivDiffusiveFluxBoundaryRHS_NS_Entropy(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)69536038bbcSJames Wright CEED_QFUNCTION(DivDiffusiveFluxBoundaryRHS_NS_Entropy)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
69636038bbcSJames Wright return DivDiffusiveFluxBoundaryRHS_NS(ctx, Q, in, out, STATEVAR_ENTROPY);
69736038bbcSJames Wright }
69836038bbcSJames Wright
6998561fee2SJames Wright // @brief Integral for RHS of diffusive flux indirect projection
DiffusiveFluxRHS_NS(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out,StateVariable state_var)70036038bbcSJames Wright CEED_QFUNCTION_HELPER int DiffusiveFluxRHS_NS(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, StateVariable state_var) {
70136038bbcSJames Wright const CeedScalar(*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0];
70236038bbcSJames Wright const CeedScalar(*Grad_q) = in[1];
70336038bbcSJames Wright const CeedScalar(*q_data) = in[2];
70436038bbcSJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
70536038bbcSJames Wright
70636038bbcSJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx;
707*cde3d787SJames Wright const NewtonianIGProperties gas = context->gas;
70836038bbcSJames Wright const StateConservative ZeroInviscidFluxes[3] = {{0}};
70936038bbcSJames Wright
71036038bbcSJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
71136038bbcSJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]};
712*cde3d787SJames Wright const State s = StateFromQ(gas, qi, state_var);
71336038bbcSJames Wright CeedScalar wdetJ, dXdx[3][3];
71436038bbcSJames Wright CeedScalar stress[3][3], Fe[3], Fdiff[5][3];
71536038bbcSJames Wright
71636038bbcSJames Wright QdataUnpack_3D(Q, i, q_data, &wdetJ, dXdx);
71736038bbcSJames Wright { // Get stress and Fe
71836038bbcSJames Wright State grad_s[3];
71936038bbcSJames Wright CeedScalar strain_rate[6], kmstress[6];
72036038bbcSJames Wright
721*cde3d787SJames Wright StatePhysicalGradientFromReference(Q, i, gas, s, state_var, Grad_q, dXdx, grad_s);
72236038bbcSJames Wright KMStrainRate_State(grad_s, strain_rate);
723*cde3d787SJames Wright NewtonianStress(gas, strain_rate, kmstress);
72436038bbcSJames Wright KMUnpack(kmstress, stress);
725*cde3d787SJames Wright ViscousEnergyFlux(gas, s.Y, grad_s, stress, Fe);
72636038bbcSJames Wright }
72736038bbcSJames Wright
72836038bbcSJames Wright FluxTotal(ZeroInviscidFluxes, stress, Fe, Fdiff);
72936038bbcSJames Wright
73036038bbcSJames Wright for (CeedInt j = 1; j < 5; j++) { // Continuity has no diffusive flux, therefore skip
73136038bbcSJames Wright for (CeedInt k = 0; k < 3; k++) {
73236038bbcSJames Wright v[(j - 1) * 3 + k][i] = wdetJ * Fdiff[j][k];
73336038bbcSJames Wright }
73436038bbcSJames Wright }
73536038bbcSJames Wright }
73636038bbcSJames Wright return 0;
73736038bbcSJames Wright }
73836038bbcSJames Wright
DiffusiveFluxRHS_NS_Conserv(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)73936038bbcSJames Wright CEED_QFUNCTION(DiffusiveFluxRHS_NS_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
74036038bbcSJames Wright return DiffusiveFluxRHS_NS(ctx, Q, in, out, STATEVAR_CONSERVATIVE);
74136038bbcSJames Wright }
74236038bbcSJames Wright
DiffusiveFluxRHS_NS_Prim(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)74336038bbcSJames Wright CEED_QFUNCTION(DiffusiveFluxRHS_NS_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
74436038bbcSJames Wright return DiffusiveFluxRHS_NS(ctx, Q, in, out, STATEVAR_PRIMITIVE);
74536038bbcSJames Wright }
74636038bbcSJames Wright
DiffusiveFluxRHS_NS_Entropy(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)74736038bbcSJames Wright CEED_QFUNCTION(DiffusiveFluxRHS_NS_Entropy)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
74836038bbcSJames Wright return DiffusiveFluxRHS_NS(ctx, Q, in, out, STATEVAR_ENTROPY);
74936038bbcSJames Wright }
750