1*5aed82e4SJeremy L Thompson // Copyright (c) 2017-2024, 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 #ifndef channel_h 1288626eedSJames Wright #define channel_h 1388626eedSJames Wright 14c9c2c079SJeremy L Thompson #include <ceed.h> 1588626eedSJames Wright #include <math.h> 162b730f8bSJeremy L Thompson 17dc805cc4SLeila Ghaffari #include "newtonian_state.h" 18c9c2c079SJeremy L Thompson #include "newtonian_types.h" 1913fa47b2SJames Wright #include "utils.h" 2088626eedSJames Wright 2188626eedSJames Wright typedef struct ChannelContext_ *ChannelContext; 2288626eedSJames Wright struct ChannelContext_ { 2388626eedSJames Wright bool implicit; // !< Using implicit timesteping or not 2488626eedSJames Wright CeedScalar theta0; // !< Reference temperature 2588626eedSJames Wright CeedScalar P0; // !< Reference Pressure 2688626eedSJames Wright CeedScalar umax; // !< Centerline velocity 2788626eedSJames Wright CeedScalar center; // !< Y Coordinate for center of channel 2888626eedSJames Wright CeedScalar H; // !< Channel half-height 2988626eedSJames Wright CeedScalar B; // !< Body-force driving the flow 3088626eedSJames Wright struct NewtonianIdealGasContext_ newtonian_ctx; 3188626eedSJames Wright }; 3288626eedSJames Wright 332b730f8bSJeremy L Thompson CEED_QFUNCTION_HELPER State Exact_Channel(CeedInt dim, CeedScalar time, const CeedScalar X[], CeedInt Nf, void *ctx) { 3488626eedSJames Wright const ChannelContext context = (ChannelContext)ctx; 3588626eedSJames Wright const CeedScalar theta0 = context->theta0; 3688626eedSJames Wright const CeedScalar P0 = context->P0; 3788626eedSJames Wright const CeedScalar umax = context->umax; 3888626eedSJames Wright const CeedScalar center = context->center; 3988626eedSJames Wright const CeedScalar H = context->H; 40dc805cc4SLeila Ghaffari NewtonianIdealGasContext gas = &context->newtonian_ctx; 41dc805cc4SLeila Ghaffari const CeedScalar cp = gas->cp; 42dc805cc4SLeila Ghaffari const CeedScalar mu = gas->mu; 43dc805cc4SLeila Ghaffari const CeedScalar k = gas->k; 44dc805cc4SLeila Ghaffari // There is a gravity body force but it is excluded from 45dc805cc4SLeila Ghaffari // the potential energy due to periodicity. 462b89d87eSLeila Ghaffari // g = (g, 0, 0) 472b89d87eSLeila Ghaffari // x = (0, x_2, x_3) 482b89d87eSLeila Ghaffari // e_potential = dot(g, x) = 0 492b89d87eSLeila Ghaffari const CeedScalar x[3] = {0, X[1], X[2]}; 5088626eedSJames Wright 5188626eedSJames Wright const CeedScalar Pr = mu / (cp * k); 5288626eedSJames Wright const CeedScalar Ec = (umax * umax) / (cp * theta0); 532b730f8bSJeremy L Thompson const CeedScalar theta = theta0 * (1 + (Pr * Ec / 3) * (1 - Square(Square((x[1] - center) / H)))); 54dc805cc4SLeila Ghaffari CeedScalar Y[5] = {0.}; 55dc805cc4SLeila Ghaffari Y[0] = P0; 562b89d87eSLeila Ghaffari Y[1] = umax * (1 - Square((x[1] - center) / H)); 57dc805cc4SLeila Ghaffari Y[2] = 0.; 58dc805cc4SLeila Ghaffari Y[3] = 0.; 59dc805cc4SLeila Ghaffari Y[4] = theta; 6088626eedSJames Wright 613bd61617SKenneth E. Jansen return StateFromY(gas, Y); 6288626eedSJames Wright } 6388626eedSJames Wright 6488626eedSJames Wright // ***************************************************************************** 65dc805cc4SLeila Ghaffari // This QFunction set the initial condition 6688626eedSJames Wright // ***************************************************************************** 672b730f8bSJeremy L Thompson CEED_QFUNCTION(ICsChannel)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 6888626eedSJames Wright // Inputs 6988626eedSJames Wright const CeedScalar(*X)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0]; 7088626eedSJames Wright 7188626eedSJames Wright // Outputs 7288626eedSJames Wright CeedScalar(*q0)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 7388626eedSJames Wright 74dc805cc4SLeila Ghaffari // Context 75dc805cc4SLeila Ghaffari const ChannelContext context = (ChannelContext)ctx; 76dc805cc4SLeila Ghaffari 7788626eedSJames Wright // Quadrature Point Loop 782b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 7988626eedSJames Wright const CeedScalar x[] = {X[0][i], X[1][i], X[2][i]}; 80dc805cc4SLeila Ghaffari State s = Exact_Channel(3, 0., x, 5, ctx); 812b89d87eSLeila Ghaffari CeedScalar q[5] = {0}; 8297baf651SJames Wright switch (context->newtonian_ctx.state_var) { 8397baf651SJames Wright case STATEVAR_CONSERVATIVE: 842b89d87eSLeila Ghaffari UnpackState_U(s.U, q); 8597baf651SJames Wright break; 8697baf651SJames Wright case STATEVAR_PRIMITIVE: 8797baf651SJames Wright UnpackState_Y(s.Y, q); 8897baf651SJames Wright break; 8997baf651SJames Wright } 902b89d87eSLeila Ghaffari 912b730f8bSJeremy L Thompson for (CeedInt j = 0; j < 5; j++) q0[j][i] = q[j]; 9288626eedSJames Wright 9388626eedSJames Wright } // End of Quadrature Point Loop 9488626eedSJames Wright return 0; 9588626eedSJames Wright } 9688626eedSJames Wright 9788626eedSJames Wright // ***************************************************************************** 982b89d87eSLeila Ghaffari // This QFunction set the inflow boundary condition for conservative variables 992b89d87eSLeila Ghaffari // ***************************************************************************** 1002b730f8bSJeremy L Thompson CEED_QFUNCTION(Channel_Inflow)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 10188626eedSJames Wright // Inputs 10246603fc5SJames Wright const CeedScalar(*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0]; 103f3e15844SJames Wright const CeedScalar(*q_data_sur) = in[2]; 10446603fc5SJames Wright const CeedScalar(*X)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[3]; 10588626eedSJames Wright 10688626eedSJames Wright // Outputs 10788626eedSJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 10846603fc5SJames Wright 10988626eedSJames Wright const ChannelContext context = (ChannelContext)ctx; 110f3e15844SJames Wright const bool is_implicit = context->implicit; 1112b89d87eSLeila Ghaffari NewtonianIdealGasContext gas = &context->newtonian_ctx; 1122b89d87eSLeila Ghaffari const CeedScalar cv = gas->cv; 11346603fc5SJames Wright const CeedScalar gamma = HeatCapacityRatio(&context->newtonian_ctx); 11488626eedSJames Wright 11588626eedSJames Wright // Quadrature Point Loop 11646603fc5SJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 117f3e15844SJames Wright CeedScalar wdetJb, norm[3]; 118f3e15844SJames Wright QdataBoundaryUnpack_3D(Q, i, q_data_sur, &wdetJb, NULL, norm); 119f3e15844SJames Wright wdetJb *= is_implicit ? -1. : 1.; 12088626eedSJames Wright 1212b89d87eSLeila Ghaffari // There is a gravity body force but it is excluded from 1222b89d87eSLeila Ghaffari // the potential energy due to periodicity. 1232b89d87eSLeila Ghaffari // g = (g, 0, 0) 1242b89d87eSLeila Ghaffari // x = (0, x_2, x_3) 1252b89d87eSLeila Ghaffari // e_potential = dot(g, x) = 0 1262b89d87eSLeila Ghaffari const CeedScalar x[3] = {0, X[1][i], X[2][i]}; 1272b89d87eSLeila Ghaffari 12888626eedSJames Wright // Calcualte prescribed inflow values 1292b89d87eSLeila Ghaffari State s_exact = Exact_Channel(3, 0., x, 5, ctx); 13088626eedSJames Wright CeedScalar q_exact[5] = {0.}; 1312b89d87eSLeila Ghaffari UnpackState_U(s_exact.U, q_exact); 13288626eedSJames Wright 13388626eedSJames Wright // Find pressure using state inside the domain 1342b89d87eSLeila Ghaffari CeedScalar q_inside[5] = {0}; 1352b730f8bSJeremy L Thompson for (CeedInt j = 0; j < 5; j++) q_inside[j] = q[j][i]; 1363bd61617SKenneth E. Jansen State s_inside = StateFromU(gas, q_inside); 1372b89d87eSLeila Ghaffari const CeedScalar P = s_inside.Y.pressure; 13888626eedSJames Wright 13988626eedSJames Wright // Find inflow state using calculated P and prescribed velocity, theta0 1402b89d87eSLeila Ghaffari const CeedScalar e_internal = cv * s_exact.Y.temperature; 14188626eedSJames Wright const CeedScalar rho_in = P / ((gamma - 1) * e_internal); 1422b730f8bSJeremy L Thompson const CeedScalar E_kinetic = .5 * rho_in * Dot3(s_exact.Y.velocity, s_exact.Y.velocity); 14388626eedSJames Wright const CeedScalar E = rho_in * e_internal + E_kinetic; 1442b89d87eSLeila Ghaffari 14588626eedSJames Wright // The Physics 14688626eedSJames Wright // Zero v so all future terms can safely sum into it 147ba6664aeSJames Wright for (CeedInt j = 0; j < 5; j++) v[j][i] = 0.; 14888626eedSJames Wright 1492b89d87eSLeila Ghaffari const CeedScalar u_normal = Dot3(norm, s_exact.Y.velocity); 15088626eedSJames Wright 15188626eedSJames Wright // The Physics 15288626eedSJames Wright // -- Density 15388626eedSJames Wright v[0][i] -= wdetJb * rho_in * u_normal; 15488626eedSJames Wright 15588626eedSJames Wright // -- Momentum 1562b730f8bSJeremy L Thompson for (CeedInt j = 0; j < 3; j++) v[j + 1][i] -= wdetJb * (rho_in * u_normal * s_exact.Y.velocity[j] + norm[j] * P); 15788626eedSJames Wright 15888626eedSJames Wright // -- Total Energy Density 15988626eedSJames Wright v[4][i] -= wdetJb * u_normal * (E + P); 16088626eedSJames Wright 16188626eedSJames Wright } // End Quadrature Point Loop 16288626eedSJames Wright return 0; 16388626eedSJames Wright } 16488626eedSJames Wright 16588626eedSJames Wright // ***************************************************************************** 1662b89d87eSLeila Ghaffari // This QFunction set the outflow boundary condition for conservative variables 1672b89d87eSLeila Ghaffari // ***************************************************************************** 1682b730f8bSJeremy L Thompson CEED_QFUNCTION(Channel_Outflow)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) { 16988626eedSJames Wright // Inputs 17046603fc5SJames Wright const CeedScalar(*q)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[0]; 171f3e15844SJames Wright const CeedScalar(*q_data_sur) = in[2]; 172e8b03feeSJames Wright 17388626eedSJames Wright // Outputs 17488626eedSJames Wright CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0]; 17588626eedSJames Wright 17688626eedSJames Wright const ChannelContext context = (ChannelContext)ctx; 177f3e15844SJames Wright const bool is_implicit = context->implicit; 17888626eedSJames Wright const CeedScalar P0 = context->P0; 17988626eedSJames Wright 18088626eedSJames Wright // Quadrature Point Loop 18146603fc5SJames Wright CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) { 182f3e15844SJames Wright CeedScalar wdetJb, norm[3]; 183f3e15844SJames Wright QdataBoundaryUnpack_3D(Q, i, q_data_sur, &wdetJb, NULL, norm); 184f3e15844SJames Wright wdetJb *= is_implicit ? -1. : 1.; 185f3e15844SJames Wright 18688626eedSJames Wright const CeedScalar rho = q[0][i]; 1872b730f8bSJeremy L Thompson const CeedScalar u[3] = {q[1][i] / rho, q[2][i] / rho, q[3][i] / rho}; 18888626eedSJames Wright const CeedScalar E = q[4][i]; 18988626eedSJames Wright 19088626eedSJames Wright // The Physics 19188626eedSJames Wright // Zero v so all future terms can safely sum into it 192ba6664aeSJames Wright for (CeedInt j = 0; j < 5; j++) v[j][i] = 0.; 19388626eedSJames Wright 19488626eedSJames Wright // Implementing outflow condition 19588626eedSJames Wright const CeedScalar P = P0; // pressure 19613fa47b2SJames Wright const CeedScalar u_normal = Dot3(norm, u); // Normal velocity 19788626eedSJames Wright // The Physics 19888626eedSJames Wright // -- Density 19988626eedSJames Wright v[0][i] -= wdetJb * rho * u_normal; 20088626eedSJames Wright 20188626eedSJames Wright // -- Momentum 2022b730f8bSJeremy L Thompson for (CeedInt j = 0; j < 3; j++) v[j + 1][i] -= wdetJb * (rho * u_normal * u[j] + norm[j] * P); 20388626eedSJames Wright 20488626eedSJames Wright // -- Total Energy Density 20588626eedSJames Wright v[4][i] -= wdetJb * u_normal * (E + P); 20688626eedSJames Wright 20788626eedSJames Wright } // End Quadrature Point Loop 20888626eedSJames Wright return 0; 20988626eedSJames Wright } 210dc805cc4SLeila Ghaffari 211dc805cc4SLeila Ghaffari // ***************************************************************************** 21288626eedSJames Wright #endif // channel_h 213