188626eedSJames Wright // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 288626eedSJames Wright // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 388626eedSJames Wright // 488626eedSJames Wright // SPDX-License-Identifier: BSD-2-Clause 588626eedSJames Wright // 688626eedSJames Wright // This file is part of CEED: http://github.com/ceed 788626eedSJames Wright 888626eedSJames Wright /// @file 988626eedSJames Wright /// Operator for Navier-Stokes example using PETSc 1088626eedSJames Wright 1188626eedSJames Wright 1288626eedSJames Wright #ifndef blasius_h 1388626eedSJames Wright #define blasius_h 1488626eedSJames Wright 1588626eedSJames Wright #include <math.h> 1688626eedSJames Wright #include <ceed.h> 17841e4c73SJed Brown #include "newtonian_types.h" 1888626eedSJames Wright 1988626eedSJames Wright typedef struct BlasiusContext_ *BlasiusContext; 2088626eedSJames Wright struct BlasiusContext_ { 2188626eedSJames Wright bool implicit; // !< Using implicit timesteping or not 22871db79fSKenneth E. Jansen bool weakT; // !< flag to set Temperature weakly at inflow 2388626eedSJames Wright CeedScalar delta0; // !< Boundary layer height at inflow 2488626eedSJames Wright CeedScalar Uinf; // !< Velocity at boundary layer edge 2588626eedSJames Wright CeedScalar P0; // !< Pressure at outflow 2688626eedSJames Wright CeedScalar theta0; // !< Temperature at inflow 27*f1122ed0SJames Wright CeedScalar x_inflow; // !< Location of inflow in x 2888626eedSJames Wright struct NewtonianIdealGasContext_ newtonian_ctx; 2988626eedSJames Wright }; 3088626eedSJames Wright 3188626eedSJames Wright #ifndef M_PI 3288626eedSJames Wright #define M_PI 3.14159265358979323846 3388626eedSJames Wright #endif 3488626eedSJames Wright 3588626eedSJames Wright void CEED_QFUNCTION_HELPER(BlasiusSolution)(const CeedScalar y, 3688626eedSJames Wright const CeedScalar Uinf, const CeedScalar x0, const CeedScalar x, 3788626eedSJames Wright const CeedScalar rho, CeedScalar *u, CeedScalar *v, CeedScalar *t12, 3888626eedSJames Wright const NewtonianIdealGasContext newt_ctx) { 3988626eedSJames Wright 4088626eedSJames Wright CeedInt nprofs = 50; 4188626eedSJames Wright // *INDENT-OFF* 4288626eedSJames Wright CeedScalar eta_table[] = { 4388626eedSJames Wright 0.000000000000000000e+00, 1.282051282051281937e-01, 2.564102564102563875e-01, 3.846153846153845812e-01, 5.128205128205127750e-01, 4488626eedSJames Wright 6.410256410256409687e-01, 7.692307692307691624e-01, 8.974358974358973562e-01, 1.025641025641025550e+00, 1.153846153846153744e+00, 4588626eedSJames Wright 1.282051282051281937e+00, 1.410256410256410131e+00, 1.538461538461538325e+00, 1.666666666666666519e+00, 1.794871794871794712e+00, 4688626eedSJames Wright 1.923076923076922906e+00, 2.051282051282051100e+00, 2.179487179487179294e+00, 2.307692307692307487e+00, 2.435897435897435681e+00, 4788626eedSJames Wright 2.564102564102563875e+00, 2.692307692307692069e+00, 2.820512820512820262e+00, 2.948717948717948456e+00, 3.076923076923076650e+00, 4888626eedSJames Wright 3.205128205128204844e+00, 3.333333333333333037e+00, 3.461538461538461231e+00, 3.589743589743589425e+00, 3.717948717948717618e+00, 4988626eedSJames Wright 3.846153846153845812e+00, 3.974358974358974006e+00, 4.102564102564102200e+00, 4.230769230769229949e+00, 4.358974358974358587e+00, 5088626eedSJames Wright 4.487179487179487225e+00, 4.615384615384614975e+00, 4.743589743589742724e+00, 4.871794871794871362e+00, 5.000000000000000000e+00, 5188626eedSJames Wright 5.500000000000000000e+00, 6.000000000000000000e+00, 6.500000000000000000e+00, 7.000000000000000000e+00, 7.500000000000000000e+00, 5288626eedSJames Wright 8.000000000000000000e+00, 8.500000000000000000e+00, 9.000000000000000000e+00, 9.500000000000000000e+00, 1.000000000000000000e+01}; 5388626eedSJames Wright 5488626eedSJames Wright CeedScalar f_table[] = { 5588626eedSJames Wright 0.000000000000000000e+00, 2.728923405566200267e-03, 1.091524811461423369e-02, 2.455658828897525764e-02, 4.364674649279581820e-02, 5688626eedSJames Wright 6.817382707725749835e-02, 9.811838418932711248e-02, 1.334516294237205192e-01, 1.741337304561980659e-01, 2.201122374410622862e-01, 5788626eedSJames Wright 2.713206781625860375e-01, 3.276773654929600599e-01, 3.890844612583744255e-01, 4.554273387986328414e-01, 5.265742820946719416e-01, 5888626eedSJames Wright 6.023765522220410062e-01, 6.826688421431770237e-01, 7.672701287583111318e-01, 8.559849171804534418e-01, 9.486048570979430661e-01, 5988626eedSJames Wright 1.044910695686512625e+00, 1.144674516826549082e+00, 1.247662203367335465e+00, 1.353636048811749593e+00, 1.462357437868362364e+00, 6088626eedSJames Wright 1.573589512396551759e+00, 1.687099740622293842e+00, 1.802662313062363353e+00, 1.920060297987626230e+00, 2.039087501786055245e+00, 6188626eedSJames Wright 2.159549994377929050e+00, 2.281267275838891884e+00, 2.404073076539093190e+00, 2.527815798402052838e+00, 2.652358618452637540e+00, 6288626eedSJames Wright 2.777579287003750341e+00, 2.903369661199559637e+00, 3.029635020019957992e+00, 3.156293209307130088e+00, 3.283273665161465349e+00, 6388626eedSJames Wright 3.780571892998292771e+00, 4.279620922520262383e+00, 4.779322325882148448e+00, 5.279238811036782053e+00, 5.779218028455369804e+00, 6488626eedSJames Wright 6.279213431354994768e+00, 6.779212528163703233e+00, 7.279212370655419484e+00, 7.779212346288013613e+00, 8.279212342945751146e+00}; 6588626eedSJames Wright 6688626eedSJames Wright CeedScalar fp_table[] = { 6788626eedSJames Wright 0.000000000000000000e+00, 4.257083277988830267e-02, 8.513297869782740501e-02, 1.276641169537044151e-01, 1.701271279078802878e-01, 6888626eedSJames Wright 2.124702831905590783e-01, 2.546276046951935212e-01, 2.965194442747576264e-01, 3.380533304776729975e-01, 3.791251204629754179e-01, 6988626eedSJames Wright 4.196204840172004791e-01, 4.594167322894788796e-01, 4.983849866855867838e-01, 5.363926638765821320e-01, 5.733062319885513514e-01, 7088626eedSJames Wright 6.089941719927144392e-01, 6.433300586189647507e-01, 6.761956584341198839e-01, 7.074839307288774970e-01, 7.371018110314454530e-01, 7188626eedSJames Wright 7.649726585225528064e-01, 7.910382579383948842e-01, 8.152602836158657773e-01, 8.376211573266827415e-01, 8.581242609418713307e-01, 7288626eedSJames Wright 8.767934976651666767e-01, 8.936722290953328374e-01, 9.088216471306606037e-01, 9.223186672607004422e-01, 9.342534510898168332e-01, 7388626eedSJames Wright 9.447266795705382414e-01, 9.538467037387058367e-01, 9.617266968332524035e-01, 9.684819213624265011e-01, 9.742272083384174719e-01, 7488626eedSJames Wright 9.790747253056680810e-01, 9.831320868743089747e-01, 9.865008381344084754e-01, 9.892753192614093249e-01, 9.915419001656551323e-01, 7588626eedSJames Wright 9.968788209317821503e-01, 9.989728724371175206e-01, 9.996990677381791812e-01, 9.999216041491896245e-01, 9.999818594083667023e-01, 7688626eedSJames Wright 9.999962745365539307e-01, 9.999993214550036980e-01, 9.999998904550418954e-01, 9.999999843329338001e-01, 9.999999980166356384e-01}; 7788626eedSJames Wright 7888626eedSJames Wright CeedScalar fpp_table[] = { 7988626eedSJames Wright 3.320573362157903663e-01, 3.320379743512646420e-01, 3.319024760665882368e-01, 3.315350015070190337e-01, 3.308206767975666041e-01, 8088626eedSJames Wright 3.296466995822193158e-01, 3.279038639411161471e-01, 3.254884713737624113e-01, 3.223045750196085746e-01, 3.182664816607024272e-01, 8188626eedSJames Wright 3.133014118810801829e-01, 3.073521951089355775e-01, 3.003798556086043625e-01, 2.923659305537876785e-01, 2.833143548208253981e-01, 8288626eedSJames Wright 2.732527514995234941e-01, 2.622329840371728227e-01, 2.503308560706500874e-01, 2.376448876931176457e-01, 2.242941499773744018e-01, 8388626eedSJames Wright 2.104151994284793603e-01, 1.961582158440171031e-01, 1.816825052623964043e-01, 1.671515786102889534e-01, 1.527280512426029968e-01, 8488626eedSJames Wright 1.385686249977987894e-01, 1.248194106805364800e-01, 1.116118251613979206e-01, 9.905925581301598670e-02, 8.725462988794610575e-02, 8588626eedSJames Wright 7.626896310981794158e-02, 6.615089622448211415e-02, 5.692716644118058639e-02, 4.860390768479891377e-02, 4.116863313890323922e-02, 8688626eedSJames Wright 3.459272784597366285e-02, 2.883426862493499582e-02, 2.384099224121952881e-02, 1.955324839409207718e-02, 1.590679868531958210e-02, 8788626eedSJames Wright 6.578593141419011685e-03, 2.402039843751689954e-03, 7.741093231657678389e-04, 2.201689553063347941e-04, 5.526217815680267893e-05, 8888626eedSJames Wright 1.224092624232004387e-05, 2.392841910090350858e-06, 4.127879363882133676e-07, 6.284244603762621373e-08, 8.442944409712819646e-09}; 8988626eedSJames Wright // *INDENT-ON* 9088626eedSJames Wright 9188626eedSJames Wright CeedScalar nu = newt_ctx->mu / rho; 9288626eedSJames Wright CeedScalar eta = y*sqrt(Uinf/(nu*(x0+x))); 9388626eedSJames Wright CeedInt idx=-1; 9488626eedSJames Wright 9588626eedSJames Wright for(CeedInt i=0; i<nprofs; i++) { 9688626eedSJames Wright if (eta < eta_table[i]) { 9788626eedSJames Wright idx = i; 9888626eedSJames Wright break; 9988626eedSJames Wright } 10088626eedSJames Wright } 10188626eedSJames Wright CeedScalar f, fp, fpp; 10288626eedSJames Wright 10388626eedSJames Wright if (idx > 0) { // eta within the bounds of eta_table 10488626eedSJames Wright CeedScalar coeff = (eta - eta_table[idx-1]) / (eta_table[idx] - eta_table[idx 10588626eedSJames Wright -1]); 10688626eedSJames Wright 10788626eedSJames Wright f = f_table[idx-1] + coeff*( f_table[idx] - f_table[idx-1] ); 10888626eedSJames Wright fp = fp_table[idx-1] + coeff*( fp_table[idx] - fp_table[idx-1] ); 10988626eedSJames Wright fpp = fpp_table[idx-1] + coeff*( fpp_table[idx] - fpp_table[idx-1] ); 11088626eedSJames Wright } else { // eta outside bounds of eta_table 11188626eedSJames Wright f = f_table[nprofs-1]; 11288626eedSJames Wright fp = fp_table[nprofs-1]; 11388626eedSJames Wright fpp = fpp_table[nprofs-1]; 11488626eedSJames Wright eta = eta_table[nprofs-1]; 11588626eedSJames Wright } 11688626eedSJames Wright 11788626eedSJames Wright *u = Uinf*fp; 11888626eedSJames Wright *t12 = rho*nu*Uinf*fpp*sqrt(Uinf/(nu*(x0+x))); 11988626eedSJames Wright *v = 0.5*sqrt(nu*Uinf/(x0+x))*(eta*fp - f); 12088626eedSJames Wright } 12188626eedSJames Wright 12288626eedSJames Wright // ***************************************************************************** 12388626eedSJames Wright // This QFunction sets a Blasius boundary layer for the initial condition 12488626eedSJames Wright // ***************************************************************************** 12588626eedSJames Wright CEED_QFUNCTION(ICsBlasius)(void *ctx, CeedInt Q, 12688626eedSJames Wright const CeedScalar *const *in, CeedScalar *const *out) { 12788626eedSJames Wright // Inputs 12888626eedSJames Wright const CeedScalar (*X)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0]; 12988626eedSJames Wright 13088626eedSJames Wright // Outputs 13188626eedSJames Wright CeedScalar (*q0)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 13288626eedSJames Wright 13388626eedSJames Wright const BlasiusContext context = (BlasiusContext)ctx; 13488626eedSJames Wright const CeedScalar cv = context->newtonian_ctx.cv; 13588626eedSJames Wright const CeedScalar cp = context->newtonian_ctx.cp; 13688626eedSJames Wright const CeedScalar gamma = cp/cv; 13788626eedSJames Wright const CeedScalar mu = context->newtonian_ctx.mu; 13888626eedSJames Wright 13988626eedSJames Wright const CeedScalar theta0 = context->theta0; 14088626eedSJames Wright const CeedScalar P0 = context->P0; 14188626eedSJames Wright const CeedScalar delta0 = context->delta0; 14288626eedSJames Wright const CeedScalar Uinf = context->Uinf; 143*f1122ed0SJames Wright const CeedScalar x_inflow = context->x_inflow; 14488626eedSJames Wright 14588626eedSJames Wright const CeedScalar e_internal = cv * theta0; 14688626eedSJames Wright const CeedScalar rho = P0 / ((gamma - 1) * e_internal); 14788626eedSJames Wright const CeedScalar x0 = Uinf*rho / (mu*25/ (delta0*delta0) ); 14888626eedSJames Wright CeedScalar u, v, t12; 14988626eedSJames Wright 15088626eedSJames Wright // Quadrature Point Loop 15188626eedSJames Wright CeedPragmaSIMD 15288626eedSJames Wright for (CeedInt i=0; i<Q; i++) { 15388626eedSJames Wright const CeedScalar x[] = {X[0][i], X[1][i], X[2][i]}; 15488626eedSJames Wright 155*f1122ed0SJames Wright BlasiusSolution(x[1], Uinf, x0, x[0] - x_inflow, rho, &u, &v, &t12, 15688626eedSJames Wright &context->newtonian_ctx); 15788626eedSJames Wright 15888626eedSJames Wright q0[0][i] = rho; 15988626eedSJames Wright q0[1][i] = u * rho; 16088626eedSJames Wright q0[2][i] = v * rho; 16188626eedSJames Wright q0[3][i] = 0.; 16288626eedSJames Wright q0[4][i] = rho * e_internal + 0.5*(u*u + v*v)*rho; 16388626eedSJames Wright } // End of Quadrature Point Loop 16488626eedSJames Wright return 0; 16588626eedSJames Wright } 16688626eedSJames Wright 16788626eedSJames Wright // ***************************************************************************** 16888626eedSJames Wright CEED_QFUNCTION(Blasius_Inflow)(void *ctx, CeedInt Q, 16988626eedSJames Wright const CeedScalar *const *in, 17088626eedSJames Wright CeedScalar *const *out) { 17188626eedSJames Wright // *INDENT-OFF* 17288626eedSJames Wright // Inputs 17388626eedSJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 17488626eedSJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[1], 17588626eedSJames Wright (*X)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2]; 17688626eedSJames Wright 17788626eedSJames Wright // Outputs 17888626eedSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 17988626eedSJames Wright // *INDENT-ON* 18088626eedSJames Wright const BlasiusContext context = (BlasiusContext)ctx; 18188626eedSJames Wright const bool implicit = context->implicit; 18288626eedSJames Wright const CeedScalar mu = context->newtonian_ctx.mu; 18388626eedSJames Wright const CeedScalar cv = context->newtonian_ctx.cv; 18488626eedSJames Wright const CeedScalar cp = context->newtonian_ctx.cp; 18588626eedSJames Wright const CeedScalar Rd = cp - cv; 186871db79fSKenneth E. Jansen const CeedScalar gamma = cp/cv; 18788626eedSJames Wright 18888626eedSJames Wright const CeedScalar theta0 = context->theta0; 18988626eedSJames Wright const CeedScalar P0 = context->P0; 19088626eedSJames Wright const CeedScalar delta0 = context->delta0; 19188626eedSJames Wright const CeedScalar Uinf = context->Uinf; 192*f1122ed0SJames Wright const CeedScalar x_inflow = context->x_inflow; 193871db79fSKenneth E. Jansen const bool weakT = context->weakT; 19488626eedSJames Wright const CeedScalar rho_0 = P0 / (Rd * theta0); 19588626eedSJames Wright const CeedScalar x0 = Uinf*rho_0 / (mu*25/ (delta0*delta0) ); 19688626eedSJames Wright 19788626eedSJames Wright CeedPragmaSIMD 19888626eedSJames Wright // Quadrature Point Loop 19988626eedSJames Wright for (CeedInt i=0; i<Q; i++) { 20088626eedSJames Wright // Setup 20188626eedSJames Wright // -- Interp-to-Interp q_data 20288626eedSJames Wright // For explicit mode, the surface integral is on the RHS of ODE q_dot = f(q). 20388626eedSJames Wright // For implicit mode, it gets pulled to the LHS of implicit ODE/DAE g(q_dot, q). 20488626eedSJames Wright // We can effect this by swapping the sign on this weight 20588626eedSJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 20688626eedSJames Wright 207871db79fSKenneth E. Jansen // Calculate inflow values 20888626eedSJames Wright const CeedScalar x[3] = {X[0][i], X[1][i], X[2][i]}; 20988626eedSJames Wright CeedScalar velocity[3] = {0.}; 21088626eedSJames Wright CeedScalar t12; 211*f1122ed0SJames Wright BlasiusSolution(x[1], Uinf, x0, x[0] - x_inflow, rho_0, &velocity[0], 212*f1122ed0SJames Wright &velocity[1], &t12, &context->newtonian_ctx); 21388626eedSJames Wright 214871db79fSKenneth E. Jansen // enabling user to choose between weak T and weak rho inflow 215871db79fSKenneth E. Jansen CeedScalar rho,E_internal, P, E_kinetic; 216871db79fSKenneth E. Jansen if (weakT) { 217871db79fSKenneth E. Jansen // rho should be from the current solution 218871db79fSKenneth E. Jansen rho = q[0][i]; 219871db79fSKenneth E. Jansen // Temperature is being set weakly (theta0) and for constant cv this sets E_internal 220871db79fSKenneth E. Jansen E_internal = rho * cv * theta0; 221871db79fSKenneth E. Jansen // Find pressure using 222871db79fSKenneth E. Jansen P=rho*Rd*theta0; // interior rho with exterior T 223871db79fSKenneth E. Jansen E_kinetic = .5 * rho * (velocity[0]*velocity[0] + 22488626eedSJames Wright velocity[1]*velocity[1] + 22588626eedSJames Wright velocity[2]*velocity[2]); 226871db79fSKenneth E. Jansen } else { 227871db79fSKenneth E. Jansen // Fixing rho weakly on the inflow to a value consistent with theta0 and P0 228871db79fSKenneth E. Jansen rho = rho_0; 229871db79fSKenneth E. Jansen E_kinetic = .5 * rho * (velocity[0]*velocity[0] + 230871db79fSKenneth E. Jansen velocity[1]*velocity[1] + 231871db79fSKenneth E. Jansen velocity[2]*velocity[2]); 232871db79fSKenneth E. Jansen E_internal = q[4][i] - E_kinetic; // uses set rho and u but E from solution 233871db79fSKenneth E. Jansen P = E_internal * (gamma - 1.); 234871db79fSKenneth E. Jansen } 235871db79fSKenneth E. Jansen const CeedScalar E = E_internal + E_kinetic; 23688626eedSJames Wright // ---- Normal vect 23788626eedSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 23888626eedSJames Wright q_data_sur[2][i], 23988626eedSJames Wright q_data_sur[3][i] 24088626eedSJames Wright }; 24188626eedSJames Wright 24288626eedSJames Wright // The Physics 24388626eedSJames Wright // Zero v so all future terms can safely sum into it 244ba6664aeSJames Wright for (CeedInt j=0; j<5; j++) v[j][i] = 0.; 24588626eedSJames Wright 24688626eedSJames Wright const CeedScalar u_normal = norm[0]*velocity[0] + 24788626eedSJames Wright norm[1]*velocity[1] + 24888626eedSJames Wright norm[2]*velocity[2]; 24988626eedSJames Wright 25088626eedSJames Wright // The Physics 25188626eedSJames Wright // -- Density 25288626eedSJames Wright v[0][i] -= wdetJb * rho * u_normal; // interior rho 25388626eedSJames Wright 25488626eedSJames Wright // -- Momentum 255ba6664aeSJames Wright for (CeedInt j=0; j<3; j++) 25688626eedSJames Wright v[j+1][i] -= wdetJb * (rho * u_normal * velocity[j] + // interior rho 25788626eedSJames Wright norm[j] * P); // mixed P 25888626eedSJames Wright v[2][i] -= wdetJb * t12 ; 25988626eedSJames Wright 26088626eedSJames Wright // -- Total Energy Density 26188626eedSJames Wright v[4][i] -= wdetJb * u_normal * (E + P); 26288626eedSJames Wright v[4][i] -= wdetJb * t12 * velocity[1]; 26388626eedSJames Wright 26488626eedSJames Wright } // End Quadrature Point Loop 26588626eedSJames Wright return 0; 26688626eedSJames Wright } 26788626eedSJames Wright 26888626eedSJames Wright // ***************************************************************************** 26988626eedSJames Wright CEED_QFUNCTION(Blasius_Outflow)(void *ctx, CeedInt Q, 27088626eedSJames Wright const CeedScalar *const *in, 27188626eedSJames Wright CeedScalar *const *out) { 27288626eedSJames Wright // *INDENT-OFF* 27388626eedSJames Wright // Inputs 27488626eedSJames Wright const CeedScalar (*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0], 27588626eedSJames Wright (*q_data_sur)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[1], 27688626eedSJames Wright (*X)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2]; 27788626eedSJames Wright // Outputs 27888626eedSJames Wright CeedScalar (*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 27988626eedSJames Wright // *INDENT-ON* 28088626eedSJames Wright 28188626eedSJames Wright const BlasiusContext context = (BlasiusContext)ctx; 28288626eedSJames Wright const bool implicit = context->implicit; 28388626eedSJames Wright const CeedScalar mu = context->newtonian_ctx.mu; 28488626eedSJames Wright const CeedScalar cv = context->newtonian_ctx.cv; 28588626eedSJames Wright const CeedScalar cp = context->newtonian_ctx.cp; 28688626eedSJames Wright const CeedScalar Rd = cp - cv; 28788626eedSJames Wright 28888626eedSJames Wright const CeedScalar theta0 = context->theta0; 28988626eedSJames Wright const CeedScalar P0 = context->P0; 29088626eedSJames Wright const CeedScalar rho_0 = P0 / (Rd*theta0); 29188626eedSJames Wright const CeedScalar delta0 = context->delta0; 29288626eedSJames Wright const CeedScalar Uinf = context->Uinf; 29388626eedSJames Wright const CeedScalar x0 = Uinf*rho_0 / (mu*25/ (delta0*delta0) ); 294*f1122ed0SJames Wright const CeedScalar x_inflow = context->x_inflow; 29588626eedSJames Wright 29688626eedSJames Wright CeedPragmaSIMD 29788626eedSJames Wright // Quadrature Point Loop 29888626eedSJames Wright for (CeedInt i=0; i<Q; i++) { 29988626eedSJames Wright // Setup 30088626eedSJames Wright // -- Interp in 30188626eedSJames Wright const CeedScalar rho = q[0][i]; 30288626eedSJames Wright const CeedScalar u[3] = {q[1][i] / rho, 30388626eedSJames Wright q[2][i] / rho, 30488626eedSJames Wright q[3][i] / rho 30588626eedSJames Wright }; 30688626eedSJames Wright const CeedScalar E = q[4][i]; 30788626eedSJames Wright 30888626eedSJames Wright // -- Interp-to-Interp q_data 30988626eedSJames Wright // For explicit mode, the surface integral is on the RHS of ODE q_dot = f(q). 31088626eedSJames Wright // For implicit mode, it gets pulled to the LHS of implicit ODE/DAE g(q_dot, q). 31188626eedSJames Wright // We can effect this by swapping the sign on this weight 31288626eedSJames Wright const CeedScalar wdetJb = (implicit ? -1. : 1.) * q_data_sur[0][i]; 31388626eedSJames Wright 31488626eedSJames Wright // ---- Normal vect 31588626eedSJames Wright const CeedScalar norm[3] = {q_data_sur[1][i], 31688626eedSJames Wright q_data_sur[2][i], 31788626eedSJames Wright q_data_sur[3][i] 31888626eedSJames Wright }; 31988626eedSJames Wright 32088626eedSJames Wright // The Physics 32188626eedSJames Wright // Zero v so all future terms can safely sum into it 322ba6664aeSJames Wright for (CeedInt j=0; j<5; j++) v[j][i] = 0.; 32388626eedSJames Wright 32488626eedSJames Wright // Implementing outflow condition 32588626eedSJames Wright const CeedScalar P = P0; // pressure 32688626eedSJames Wright const CeedScalar u_normal = norm[0]*u[0] + norm[1]*u[1] + 32788626eedSJames Wright norm[2]*u[2]; // Normal velocity 32888626eedSJames Wright 32988626eedSJames Wright // Calculate prescribed outflow traction values 33088626eedSJames Wright const CeedScalar x[3] = {X[0][i], X[1][i], X[2][i]}; 33188626eedSJames Wright CeedScalar velocity[3] = {0.}; 33288626eedSJames Wright CeedScalar t12; 333*f1122ed0SJames Wright BlasiusSolution(x[1], Uinf, x0, x[0] - x_inflow, rho_0, &velocity[0], 334*f1122ed0SJames Wright &velocity[1], &t12, &context->newtonian_ctx); 33588626eedSJames Wright // The Physics 33688626eedSJames Wright // -- Density 33788626eedSJames Wright v[0][i] -= wdetJb * rho * u_normal; 33888626eedSJames Wright 33988626eedSJames Wright // -- Momentum 340ba6664aeSJames Wright for (CeedInt j=0; j<3; j++) 34188626eedSJames Wright v[j+1][i] -= wdetJb *(rho * u_normal * u[j] + norm[j] * P); 34288626eedSJames Wright v[2][i] += wdetJb * t12 ; 34388626eedSJames Wright 34488626eedSJames Wright // -- Total Energy Density 34588626eedSJames Wright v[4][i] -= wdetJb * u_normal * (E + P); 34688626eedSJames Wright v[4][i] += wdetJb * t12 * velocity[1]; 34788626eedSJames Wright 34888626eedSJames Wright } // End Quadrature Point Loop 34988626eedSJames Wright return 0; 35088626eedSJames Wright } 35188626eedSJames Wright #endif // blasius_h 352