1*8c85b835SJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2024, HONEE contributors. 2*8c85b835SJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause 3*8c85b835SJames Wright 4*8c85b835SJames Wright #include <ceed.h> 5*8c85b835SJames Wright 6*8c85b835SJames Wright #include "newtonian_state.h" 7*8c85b835SJames Wright #include "utils.h" 8*8c85b835SJames Wright 9*8c85b835SJames Wright // @brief Volume integral for RHS of divergence of diffusive flux projection 10*8c85b835SJames Wright CEED_QFUNCTION_HELPER int DivDiffusiveFluxVolumeRHS(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, 11*8c85b835SJames Wright StateVariable state_var) { 12*8c85b835SJames Wright const CeedScalar(*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0]; 13*8c85b835SJames Wright const CeedScalar(*Grad_q) = in[1]; 14*8c85b835SJames Wright const CeedScalar(*q_data) = in[2]; 15*8c85b835SJames Wright CeedScalar(*Grad_v)[4][CEED_Q_VLA] = (CeedScalar(*)[4][CEED_Q_VLA])out[0]; 16*8c85b835SJames Wright 17*8c85b835SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 18*8c85b835SJames Wright const StateConservative ZeroInviscidFluxes[3] = {{0}}; 19*8c85b835SJames Wright 20*8c85b835SJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 21*8c85b835SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 22*8c85b835SJames Wright const State s = StateFromQ(context, qi, state_var); 23*8c85b835SJames Wright CeedScalar wdetJ, dXdx[3][3]; 24*8c85b835SJames Wright CeedScalar stress[3][3], Fe[3], Fdiff[5][3]; 25*8c85b835SJames Wright 26*8c85b835SJames Wright QdataUnpack_3D(Q, i, q_data, &wdetJ, dXdx); 27*8c85b835SJames Wright { // Get stress and Fe 28*8c85b835SJames Wright State grad_s[3]; 29*8c85b835SJames Wright CeedScalar strain_rate[6], kmstress[6]; 30*8c85b835SJames Wright 31*8c85b835SJames Wright StatePhysicalGradientFromReference(Q, i, context, s, state_var, Grad_q, dXdx, grad_s); 32*8c85b835SJames Wright KMStrainRate_State(grad_s, strain_rate); 33*8c85b835SJames Wright NewtonianStress(context, strain_rate, kmstress); 34*8c85b835SJames Wright KMUnpack(kmstress, stress); 35*8c85b835SJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 36*8c85b835SJames Wright } 37*8c85b835SJames Wright 38*8c85b835SJames Wright FluxTotal(ZeroInviscidFluxes, stress, Fe, Fdiff); 39*8c85b835SJames Wright 40*8c85b835SJames Wright for (CeedInt j = 1; j < 5; j++) { // Continuity has no diffusive flux, therefore skip 41*8c85b835SJames Wright for (CeedInt k = 0; k < 3; k++) { 42*8c85b835SJames Wright Grad_v[k][j - 1][i] = -wdetJ * Dot3(dXdx[k], Fdiff[j]); 43*8c85b835SJames Wright } 44*8c85b835SJames Wright } 45*8c85b835SJames Wright } 46*8c85b835SJames Wright return 0; 47*8c85b835SJames Wright } 48*8c85b835SJames Wright 49*8c85b835SJames Wright CEED_QFUNCTION(DivDiffusiveFluxVolumeRHS_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 50*8c85b835SJames Wright return DivDiffusiveFluxVolumeRHS(ctx, Q, in, out, STATEVAR_CONSERVATIVE); 51*8c85b835SJames Wright } 52*8c85b835SJames Wright 53*8c85b835SJames Wright CEED_QFUNCTION(DivDiffusiveFluxVolumeRHS_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 54*8c85b835SJames Wright return DivDiffusiveFluxVolumeRHS(ctx, Q, in, out, STATEVAR_PRIMITIVE); 55*8c85b835SJames Wright } 56*8c85b835SJames Wright 57*8c85b835SJames Wright CEED_QFUNCTION(DivDiffusiveFluxVolumeRHS_Entropy)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 58*8c85b835SJames Wright return DivDiffusiveFluxVolumeRHS(ctx, Q, in, out, STATEVAR_ENTROPY); 59*8c85b835SJames Wright } 60*8c85b835SJames Wright 61*8c85b835SJames Wright // @brief Boundary integral for RHS of divergence of diffusive flux projection 62*8c85b835SJames Wright CEED_QFUNCTION_HELPER int DivDiffusiveFluxBoundaryRHS(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, 63*8c85b835SJames Wright StateVariable state_var) { 64*8c85b835SJames Wright const CeedScalar(*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0]; 65*8c85b835SJames Wright const CeedScalar(*Grad_q) = in[1]; 66*8c85b835SJames Wright const CeedScalar(*q_data) = in[2]; 67*8c85b835SJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 68*8c85b835SJames Wright 69*8c85b835SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 70*8c85b835SJames Wright const StateConservative ZeroInviscidFluxes[3] = {{0}}; 71*8c85b835SJames Wright 72*8c85b835SJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 73*8c85b835SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 74*8c85b835SJames Wright const State s = StateFromQ(context, qi, state_var); 75*8c85b835SJames Wright CeedScalar wdetJ, dXdx[3][3], normal[3]; 76*8c85b835SJames Wright CeedScalar stress[3][3], Fe[3], Fdiff[5]; 77*8c85b835SJames Wright 78*8c85b835SJames Wright QdataBoundaryGradientUnpack_3D(Q, i, q_data, &wdetJ, dXdx, normal); 79*8c85b835SJames Wright { // Get stress and Fe 80*8c85b835SJames Wright State grad_s[3]; 81*8c85b835SJames Wright CeedScalar strain_rate[6], kmstress[6]; 82*8c85b835SJames Wright 83*8c85b835SJames Wright StatePhysicalGradientFromReference(Q, i, context, s, state_var, Grad_q, dXdx, grad_s); 84*8c85b835SJames Wright KMStrainRate_State(grad_s, strain_rate); 85*8c85b835SJames Wright NewtonianStress(context, strain_rate, kmstress); 86*8c85b835SJames Wright KMUnpack(kmstress, stress); 87*8c85b835SJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 88*8c85b835SJames Wright } 89*8c85b835SJames Wright 90*8c85b835SJames Wright FluxTotal_Boundary(ZeroInviscidFluxes, stress, Fe, normal, Fdiff); 91*8c85b835SJames Wright 92*8c85b835SJames Wright // Continuity has no diffusive flux, therefore skip 93*8c85b835SJames Wright for (CeedInt j = 1; j < 5; j++) v[j - 1][i] = wdetJ * Fdiff[j]; 94*8c85b835SJames Wright } 95*8c85b835SJames Wright return 0; 96*8c85b835SJames Wright } 97*8c85b835SJames Wright 98*8c85b835SJames Wright CEED_QFUNCTION(DivDiffusiveFluxBoundaryRHS_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 99*8c85b835SJames Wright return DivDiffusiveFluxBoundaryRHS(ctx, Q, in, out, STATEVAR_CONSERVATIVE); 100*8c85b835SJames Wright } 101*8c85b835SJames Wright 102*8c85b835SJames Wright CEED_QFUNCTION(DivDiffusiveFluxBoundaryRHS_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 103*8c85b835SJames Wright return DivDiffusiveFluxBoundaryRHS(ctx, Q, in, out, STATEVAR_PRIMITIVE); 104*8c85b835SJames Wright } 105*8c85b835SJames Wright 106*8c85b835SJames Wright CEED_QFUNCTION(DivDiffusiveFluxBoundaryRHS_Entropy)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 107*8c85b835SJames Wright return DivDiffusiveFluxBoundaryRHS(ctx, Q, in, out, STATEVAR_ENTROPY); 108*8c85b835SJames Wright } 109*8c85b835SJames Wright 110*8c85b835SJames Wright // @brief Integral for RHS of diffusive flux projection 111*8c85b835SJames Wright CEED_QFUNCTION_HELPER int DiffusiveFluxRHS(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, StateVariable state_var) { 112*8c85b835SJames Wright const CeedScalar(*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0]; 113*8c85b835SJames Wright const CeedScalar(*Grad_q) = in[1]; 114*8c85b835SJames Wright const CeedScalar(*q_data) = in[2]; 115*8c85b835SJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 116*8c85b835SJames Wright 117*8c85b835SJames Wright const NewtonianIdealGasContext context = (NewtonianIdealGasContext)ctx; 118*8c85b835SJames Wright const StateConservative ZeroInviscidFluxes[3] = {{0}}; 119*8c85b835SJames Wright 120*8c85b835SJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 121*8c85b835SJames Wright const CeedScalar qi[5] = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]}; 122*8c85b835SJames Wright const State s = StateFromQ(context, qi, state_var); 123*8c85b835SJames Wright CeedScalar wdetJ, dXdx[3][3]; 124*8c85b835SJames Wright CeedScalar stress[3][3], Fe[3], Fdiff[5][3]; 125*8c85b835SJames Wright 126*8c85b835SJames Wright QdataUnpack_3D(Q, i, q_data, &wdetJ, dXdx); 127*8c85b835SJames Wright { // Get stress and Fe 128*8c85b835SJames Wright State grad_s[3]; 129*8c85b835SJames Wright CeedScalar strain_rate[6], kmstress[6]; 130*8c85b835SJames Wright 131*8c85b835SJames Wright StatePhysicalGradientFromReference(Q, i, context, s, state_var, Grad_q, dXdx, grad_s); 132*8c85b835SJames Wright KMStrainRate_State(grad_s, strain_rate); 133*8c85b835SJames Wright NewtonianStress(context, strain_rate, kmstress); 134*8c85b835SJames Wright KMUnpack(kmstress, stress); 135*8c85b835SJames Wright ViscousEnergyFlux(context, s.Y, grad_s, stress, Fe); 136*8c85b835SJames Wright } 137*8c85b835SJames Wright 138*8c85b835SJames Wright FluxTotal(ZeroInviscidFluxes, stress, Fe, Fdiff); 139*8c85b835SJames Wright 140*8c85b835SJames Wright for (CeedInt j = 1; j < 5; j++) { // Continuity has no diffusive flux, therefore skip 141*8c85b835SJames Wright for (CeedInt k = 0; k < 3; k++) { 142*8c85b835SJames Wright v[(j - 1) * 3 + k][i] = wdetJ * Fdiff[j][k]; 143*8c85b835SJames Wright } 144*8c85b835SJames Wright } 145*8c85b835SJames Wright } 146*8c85b835SJames Wright return 0; 147*8c85b835SJames Wright } 148*8c85b835SJames Wright 149*8c85b835SJames Wright CEED_QFUNCTION(DiffusiveFluxRHS_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 150*8c85b835SJames Wright return DiffusiveFluxRHS(ctx, Q, in, out, STATEVAR_CONSERVATIVE); 151*8c85b835SJames Wright } 152*8c85b835SJames Wright 153*8c85b835SJames Wright CEED_QFUNCTION(DiffusiveFluxRHS_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 154*8c85b835SJames Wright return DiffusiveFluxRHS(ctx, Q, in, out, STATEVAR_PRIMITIVE); 155*8c85b835SJames Wright } 156*8c85b835SJames Wright 157*8c85b835SJames Wright CEED_QFUNCTION(DiffusiveFluxRHS_Entropy)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 158*8c85b835SJames Wright return DiffusiveFluxRHS(ctx, Q, in, out, STATEVAR_ENTROPY); 159*8c85b835SJames Wright } 160*8c85b835SJames Wright 161*8c85b835SJames Wright // @brief QFunction to calculate the divergence of the diffusive flux 162*8c85b835SJames Wright CEED_QFUNCTION_HELPER int ComputeDivDiffusiveFluxGeneric(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, const CeedInt dim, 163*8c85b835SJames Wright const CeedInt num_comps) { 164*8c85b835SJames Wright const CeedScalar *grad_q = in[0]; 165*8c85b835SJames Wright const CeedScalar(*q_data) = in[1]; 166*8c85b835SJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 167*8c85b835SJames Wright 168*8c85b835SJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 169*8c85b835SJames Wright CeedScalar dXdx[9]; 170*8c85b835SJames Wright 171*8c85b835SJames Wright QdataUnpack_ND(dim, Q, i, q_data, NULL, dXdx); 172*8c85b835SJames Wright CeedPragmaSIMD for (CeedInt n = 0; n < num_comps; n++) { 173*8c85b835SJames Wright CeedScalar grad_qn[9]; 174*8c85b835SJames Wright 175*8c85b835SJames Wright // Get gradient into dim x dim matrix form, with orientation [flux_direction][gradient_direction] 176*8c85b835SJames Wright // Equivalent of GradUnpackN 177*8c85b835SJames Wright const CeedInt offset = Q * n * dim; // offset to reach nth component flux gradients 178*8c85b835SJames Wright for (CeedInt g = 0; g < dim; g++) { 179*8c85b835SJames Wright for (CeedInt f = 0; f < dim; f++) { 180*8c85b835SJames Wright grad_qn[f * dim + g] = grad_q[offset + (Q * num_comps * dim) * g + Q * f + i]; 181*8c85b835SJames Wright } 182*8c85b835SJames Wright } 183*8c85b835SJames Wright v[n][i] = 0; 184*8c85b835SJames Wright DivergenceND(grad_qn, dXdx, dim, &v[n][i]); 185*8c85b835SJames Wright } 186*8c85b835SJames Wright } 187*8c85b835SJames Wright return 0; 188*8c85b835SJames Wright } 189*8c85b835SJames Wright 190*8c85b835SJames Wright CEED_QFUNCTION(ComputeDivDiffusiveFlux3D_4)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 191*8c85b835SJames Wright return ComputeDivDiffusiveFluxGeneric(ctx, Q, in, out, 3, 4); 192*8c85b835SJames Wright } 193