1*224fc8c8SJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2025, HONEE contributors. 2*224fc8c8SJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause 3*224fc8c8SJames Wright 4*224fc8c8SJames Wright /// @file 5*224fc8c8SJames Wright /// Utility functions for setting up Freestream boundary condition 6*224fc8c8SJames Wright 7*224fc8c8SJames Wright #include "../qfunctions/bc_outflow.h" 8*224fc8c8SJames Wright 9*224fc8c8SJames Wright #include <ceed.h> 10*224fc8c8SJames Wright #include <petscdm.h> 11*224fc8c8SJames Wright 12*224fc8c8SJames Wright #include <navierstokes.h> 13*224fc8c8SJames Wright #include "../qfunctions/newtonian_types.h" 14*224fc8c8SJames Wright 15*224fc8c8SJames Wright static const char *const OutflowTypes[] = {"RIEMANN", "PRESSURE", "OutflowType", "OUTFLOW_", NULL}; 16*224fc8c8SJames Wright typedef enum { 17*224fc8c8SJames Wright OUTFLOW_RIEMANN, 18*224fc8c8SJames Wright OUTFLOW_PRESSURE, 19*224fc8c8SJames Wright } OutflowType; 20*224fc8c8SJames Wright 21*224fc8c8SJames Wright PetscErrorCode OutflowBCSetup(ProblemData problem, DM dm, void *ctx, NewtonianIdealGasContext newtonian_ig_ctx, const StatePrimitive *reference) { 22*224fc8c8SJames Wright Honee honee = *(Honee *)ctx; 23*224fc8c8SJames Wright Ceed ceed = honee->ceed; 24*224fc8c8SJames Wright OutflowContext outflow_ctx; 25*224fc8c8SJames Wright OutflowType outflow_type = OUTFLOW_RIEMANN; 26*224fc8c8SJames Wright CeedQFunctionContext outflow_qfctx; 27*224fc8c8SJames Wright const PetscScalar Kelvin = honee->units->Kelvin; 28*224fc8c8SJames Wright const PetscScalar Pascal = honee->units->Pascal; 29*224fc8c8SJames Wright 30*224fc8c8SJames Wright PetscFunctionBeginUser; 31*224fc8c8SJames Wright CeedScalar pressure = reference->pressure / Pascal; 32*224fc8c8SJames Wright CeedScalar temperature = reference->temperature / Kelvin; 33*224fc8c8SJames Wright CeedScalar recirc = 1, softplus_velocity = 1e-2; 34*224fc8c8SJames Wright PetscOptionsBegin(honee->comm, NULL, "Options for Outflow boundary condition", NULL); 35*224fc8c8SJames Wright PetscCall( 36*224fc8c8SJames Wright PetscOptionsEnum("-outflow_type", "Type of outflow condition", NULL, OutflowTypes, (PetscEnum)outflow_type, (PetscEnum *)&outflow_type, NULL)); 37*224fc8c8SJames Wright PetscCall(PetscOptionsScalar("-outflow_pressure", "Pressure at outflow condition", NULL, pressure, &pressure, NULL)); 38*224fc8c8SJames Wright if (outflow_type == OUTFLOW_RIEMANN) { 39*224fc8c8SJames Wright PetscCall(PetscOptionsScalar("-outflow_temperature", "Temperature at outflow condition", NULL, temperature, &temperature, NULL)); 40*224fc8c8SJames Wright PetscCall( 41*224fc8c8SJames Wright PetscOptionsReal("-outflow_recirc", "Fraction of recirculation to allow in exterior velocity state [0,1]", NULL, recirc, &recirc, NULL)); 42*224fc8c8SJames Wright PetscCall(PetscOptionsReal("-outflow_softplus_velocity", "Characteristic velocity of softplus regularization", NULL, softplus_velocity, 43*224fc8c8SJames Wright &softplus_velocity, NULL)); 44*224fc8c8SJames Wright } 45*224fc8c8SJames Wright PetscOptionsEnd(); 46*224fc8c8SJames Wright pressure *= Pascal; 47*224fc8c8SJames Wright temperature *= Kelvin; 48*224fc8c8SJames Wright 49*224fc8c8SJames Wright switch (outflow_type) { 50*224fc8c8SJames Wright case OUTFLOW_RIEMANN: 51*224fc8c8SJames Wright switch (honee->phys->state_var) { 52*224fc8c8SJames Wright case STATEVAR_CONSERVATIVE: 53*224fc8c8SJames Wright problem->apply_outflow.qf_func_ptr = RiemannOutflow_Conserv; 54*224fc8c8SJames Wright problem->apply_outflow.qf_loc = RiemannOutflow_Conserv_loc; 55*224fc8c8SJames Wright problem->apply_outflow_jacobian.qf_func_ptr = RiemannOutflow_Jacobian_Conserv; 56*224fc8c8SJames Wright problem->apply_outflow_jacobian.qf_loc = RiemannOutflow_Jacobian_Conserv_loc; 57*224fc8c8SJames Wright break; 58*224fc8c8SJames Wright case STATEVAR_PRIMITIVE: 59*224fc8c8SJames Wright problem->apply_outflow.qf_func_ptr = RiemannOutflow_Prim; 60*224fc8c8SJames Wright problem->apply_outflow.qf_loc = RiemannOutflow_Prim_loc; 61*224fc8c8SJames Wright problem->apply_outflow_jacobian.qf_func_ptr = RiemannOutflow_Jacobian_Prim; 62*224fc8c8SJames Wright problem->apply_outflow_jacobian.qf_loc = RiemannOutflow_Jacobian_Prim_loc; 63*224fc8c8SJames Wright break; 64*224fc8c8SJames Wright case STATEVAR_ENTROPY: 65*224fc8c8SJames Wright problem->apply_outflow.qf_func_ptr = RiemannOutflow_Entropy; 66*224fc8c8SJames Wright problem->apply_outflow.qf_loc = RiemannOutflow_Entropy_loc; 67*224fc8c8SJames Wright problem->apply_outflow_jacobian.qf_func_ptr = RiemannOutflow_Jacobian_Entropy; 68*224fc8c8SJames Wright problem->apply_outflow_jacobian.qf_loc = RiemannOutflow_Jacobian_Entropy_loc; 69*224fc8c8SJames Wright break; 70*224fc8c8SJames Wright } 71*224fc8c8SJames Wright break; 72*224fc8c8SJames Wright case OUTFLOW_PRESSURE: 73*224fc8c8SJames Wright switch (honee->phys->state_var) { 74*224fc8c8SJames Wright case STATEVAR_CONSERVATIVE: 75*224fc8c8SJames Wright problem->apply_outflow.qf_func_ptr = PressureOutflow_Conserv; 76*224fc8c8SJames Wright problem->apply_outflow.qf_loc = PressureOutflow_Conserv_loc; 77*224fc8c8SJames Wright problem->apply_outflow_jacobian.qf_func_ptr = PressureOutflow_Jacobian_Conserv; 78*224fc8c8SJames Wright problem->apply_outflow_jacobian.qf_loc = PressureOutflow_Jacobian_Conserv_loc; 79*224fc8c8SJames Wright break; 80*224fc8c8SJames Wright case STATEVAR_PRIMITIVE: 81*224fc8c8SJames Wright problem->apply_outflow.qf_func_ptr = PressureOutflow_Prim; 82*224fc8c8SJames Wright problem->apply_outflow.qf_loc = PressureOutflow_Prim_loc; 83*224fc8c8SJames Wright problem->apply_outflow_jacobian.qf_func_ptr = PressureOutflow_Jacobian_Prim; 84*224fc8c8SJames Wright problem->apply_outflow_jacobian.qf_loc = PressureOutflow_Jacobian_Prim_loc; 85*224fc8c8SJames Wright break; 86*224fc8c8SJames Wright case STATEVAR_ENTROPY: 87*224fc8c8SJames Wright problem->apply_outflow.qf_func_ptr = PressureOutflow_Entropy; 88*224fc8c8SJames Wright problem->apply_outflow.qf_loc = PressureOutflow_Entropy_loc; 89*224fc8c8SJames Wright problem->apply_outflow_jacobian.qf_func_ptr = PressureOutflow_Jacobian_Entropy; 90*224fc8c8SJames Wright problem->apply_outflow_jacobian.qf_loc = PressureOutflow_Jacobian_Entropy_loc; 91*224fc8c8SJames Wright break; 92*224fc8c8SJames Wright } 93*224fc8c8SJames Wright break; 94*224fc8c8SJames Wright } 95*224fc8c8SJames Wright PetscCall(PetscCalloc1(1, &outflow_ctx)); 96*224fc8c8SJames Wright outflow_ctx->gas = *newtonian_ig_ctx; 97*224fc8c8SJames Wright outflow_ctx->recirc = recirc; 98*224fc8c8SJames Wright outflow_ctx->softplus_velocity = softplus_velocity; 99*224fc8c8SJames Wright outflow_ctx->pressure = pressure; 100*224fc8c8SJames Wright outflow_ctx->temperature = temperature; 101*224fc8c8SJames Wright 102*224fc8c8SJames Wright PetscCallCeed(ceed, CeedQFunctionContextCreate(honee->ceed, &outflow_qfctx)); 103*224fc8c8SJames Wright PetscCallCeed(ceed, CeedQFunctionContextSetData(outflow_qfctx, CEED_MEM_HOST, CEED_USE_POINTER, sizeof(*outflow_ctx), outflow_ctx)); 104*224fc8c8SJames Wright PetscCallCeed(ceed, CeedQFunctionContextSetDataDestroy(outflow_qfctx, CEED_MEM_HOST, FreeContextPetsc)); 105*224fc8c8SJames Wright problem->apply_outflow.qfctx = outflow_qfctx; 106*224fc8c8SJames Wright PetscCallCeed(ceed, CeedQFunctionContextReferenceCopy(outflow_qfctx, &problem->apply_outflow_jacobian.qfctx)); 107*224fc8c8SJames Wright PetscFunctionReturn(PETSC_SUCCESS); 108*224fc8c8SJames Wright } 109