1224fc8c8SJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2025, HONEE contributors. 2224fc8c8SJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause 3224fc8c8SJames Wright 4224fc8c8SJames Wright /// @file 5224fc8c8SJames Wright /// Utility functions for setting up Freestream boundary condition 6224fc8c8SJames Wright 7224fc8c8SJames Wright #include "../qfunctions/bc_outflow.h" 8224fc8c8SJames Wright 9224fc8c8SJames Wright #include <ceed.h> 10224fc8c8SJames Wright #include <petscdm.h> 11224fc8c8SJames Wright 12224fc8c8SJames Wright #include <navierstokes.h> 13224fc8c8SJames Wright #include "../qfunctions/newtonian_types.h" 14224fc8c8SJames Wright 15224fc8c8SJames Wright static const char *const OutflowTypes[] = {"RIEMANN", "PRESSURE", "OutflowType", "OUTFLOW_", NULL}; 16224fc8c8SJames Wright typedef enum { 17224fc8c8SJames Wright OUTFLOW_RIEMANN, 18224fc8c8SJames Wright OUTFLOW_PRESSURE, 19224fc8c8SJames Wright } OutflowType; 20224fc8c8SJames Wright 21*f978755dSJames Wright typedef struct { 22*f978755dSJames Wright OutflowType outflow_type; 23*f978755dSJames Wright } *OutflowHoneeBCCtx; 24*f978755dSJames Wright 25*f978755dSJames Wright static PetscErrorCode OutflowBCSetup_CreateIFunctionQF(BCDefinition bc_def, CeedQFunction *qf) { 26*f978755dSJames Wright Honee honee; 27*f978755dSJames Wright HoneeBCStruct honee_bc; 28*f978755dSJames Wright 29*f978755dSJames Wright PetscFunctionBeginUser; 30*f978755dSJames Wright PetscCall(BCDefinitionGetContext(bc_def, &honee_bc)); 31*f978755dSJames Wright honee = honee_bc->honee; 32*f978755dSJames Wright OutflowHoneeBCCtx outflow_honee_bc = (OutflowHoneeBCCtx)honee_bc->ctx; 33*f978755dSJames Wright 34*f978755dSJames Wright switch (honee->phys->state_var) { 35*f978755dSJames Wright case STATEVAR_CONSERVATIVE: 36*f978755dSJames Wright switch (outflow_honee_bc->outflow_type) { 37*f978755dSJames Wright case OUTFLOW_RIEMANN: 38*f978755dSJames Wright PetscCall(HoneeBCCreateIFunctionQF(bc_def, RiemannOutflow_Conserv, RiemannOutflow_Conserv_loc, honee_bc->qfctx, qf)); 39*f978755dSJames Wright break; 40*f978755dSJames Wright case OUTFLOW_PRESSURE: 41*f978755dSJames Wright PetscCall(HoneeBCCreateIFunctionQF(bc_def, PressureOutflow_Conserv, PressureOutflow_Conserv_loc, honee_bc->qfctx, qf)); 42*f978755dSJames Wright break; 43*f978755dSJames Wright } 44*f978755dSJames Wright break; 45*f978755dSJames Wright case STATEVAR_PRIMITIVE: 46*f978755dSJames Wright switch (outflow_honee_bc->outflow_type) { 47*f978755dSJames Wright case OUTFLOW_RIEMANN: 48*f978755dSJames Wright PetscCall(HoneeBCCreateIFunctionQF(bc_def, RiemannOutflow_Prim, RiemannOutflow_Prim_loc, honee_bc->qfctx, qf)); 49*f978755dSJames Wright break; 50*f978755dSJames Wright case OUTFLOW_PRESSURE: 51*f978755dSJames Wright PetscCall(HoneeBCCreateIFunctionQF(bc_def, PressureOutflow_Prim, PressureOutflow_Prim_loc, honee_bc->qfctx, qf)); 52*f978755dSJames Wright break; 53*f978755dSJames Wright } 54*f978755dSJames Wright break; 55*f978755dSJames Wright case STATEVAR_ENTROPY: 56*f978755dSJames Wright switch (outflow_honee_bc->outflow_type) { 57*f978755dSJames Wright case OUTFLOW_RIEMANN: 58*f978755dSJames Wright PetscCall(HoneeBCCreateIFunctionQF(bc_def, RiemannOutflow_Entropy, RiemannOutflow_Entropy_loc, honee_bc->qfctx, qf)); 59*f978755dSJames Wright break; 60*f978755dSJames Wright case OUTFLOW_PRESSURE: 61*f978755dSJames Wright PetscCall(HoneeBCCreateIFunctionQF(bc_def, PressureOutflow_Entropy, PressureOutflow_Entropy_loc, honee_bc->qfctx, qf)); 62*f978755dSJames Wright break; 63*f978755dSJames Wright } 64*f978755dSJames Wright break; 65*f978755dSJames Wright } 66*f978755dSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 67*f978755dSJames Wright } 68*f978755dSJames Wright 69*f978755dSJames Wright static PetscErrorCode OutflowBCSetup_CreateIJacobianQF(BCDefinition bc_def, CeedQFunction *qf) { 70*f978755dSJames Wright Honee honee; 71*f978755dSJames Wright HoneeBCStruct honee_bc; 72*f978755dSJames Wright 73*f978755dSJames Wright PetscFunctionBeginUser; 74*f978755dSJames Wright PetscCall(BCDefinitionGetContext(bc_def, &honee_bc)); 75*f978755dSJames Wright honee = honee_bc->honee; 76*f978755dSJames Wright OutflowHoneeBCCtx outflow_honee_bc = (OutflowHoneeBCCtx)honee_bc->ctx; 77*f978755dSJames Wright 78*f978755dSJames Wright switch (honee->phys->state_var) { 79*f978755dSJames Wright case STATEVAR_CONSERVATIVE: 80*f978755dSJames Wright switch (outflow_honee_bc->outflow_type) { 81*f978755dSJames Wright case OUTFLOW_RIEMANN: 82*f978755dSJames Wright PetscCall(HoneeBCCreateIJacobianQF(bc_def, RiemannOutflow_Jacobian_Conserv, RiemannOutflow_Jacobian_Conserv_loc, honee_bc->qfctx, qf)); 83*f978755dSJames Wright break; 84*f978755dSJames Wright case OUTFLOW_PRESSURE: 85*f978755dSJames Wright PetscCall(HoneeBCCreateIJacobianQF(bc_def, PressureOutflow_Jacobian_Conserv, PressureOutflow_Jacobian_Conserv_loc, honee_bc->qfctx, qf)); 86*f978755dSJames Wright break; 87*f978755dSJames Wright } 88*f978755dSJames Wright break; 89*f978755dSJames Wright case STATEVAR_PRIMITIVE: 90*f978755dSJames Wright switch (outflow_honee_bc->outflow_type) { 91*f978755dSJames Wright case OUTFLOW_RIEMANN: 92*f978755dSJames Wright PetscCall(HoneeBCCreateIJacobianQF(bc_def, RiemannOutflow_Jacobian_Prim, RiemannOutflow_Jacobian_Prim_loc, honee_bc->qfctx, qf)); 93*f978755dSJames Wright break; 94*f978755dSJames Wright case OUTFLOW_PRESSURE: 95*f978755dSJames Wright PetscCall(HoneeBCCreateIJacobianQF(bc_def, PressureOutflow_Jacobian_Prim, PressureOutflow_Jacobian_Prim_loc, honee_bc->qfctx, qf)); 96*f978755dSJames Wright break; 97*f978755dSJames Wright } 98*f978755dSJames Wright break; 99*f978755dSJames Wright case STATEVAR_ENTROPY: 100*f978755dSJames Wright switch (outflow_honee_bc->outflow_type) { 101*f978755dSJames Wright case OUTFLOW_RIEMANN: 102*f978755dSJames Wright PetscCall(HoneeBCCreateIJacobianQF(bc_def, RiemannOutflow_Jacobian_Entropy, RiemannOutflow_Jacobian_Entropy_loc, honee_bc->qfctx, qf)); 103*f978755dSJames Wright break; 104*f978755dSJames Wright case OUTFLOW_PRESSURE: 105*f978755dSJames Wright PetscCall(HoneeBCCreateIJacobianQF(bc_def, PressureOutflow_Jacobian_Entropy, PressureOutflow_Jacobian_Entropy_loc, honee_bc->qfctx, qf)); 106*f978755dSJames Wright break; 107*f978755dSJames Wright } 108*f978755dSJames Wright break; 109*f978755dSJames Wright } 110*f978755dSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 111*f978755dSJames Wright } 112*f978755dSJames Wright 113*f978755dSJames Wright PetscErrorCode OutflowBCSetup(BCDefinition bc_def, ProblemData problem, DM dm, void *ctx, NewtonianIdealGasContext newtonian_ig_ctx, 114*f978755dSJames Wright const StatePrimitive *reference) { 115224fc8c8SJames Wright Honee honee = *(Honee *)ctx; 116224fc8c8SJames Wright Ceed ceed = honee->ceed; 117224fc8c8SJames Wright OutflowContext outflow_ctx; 118224fc8c8SJames Wright OutflowType outflow_type = OUTFLOW_RIEMANN; 119224fc8c8SJames Wright CeedQFunctionContext outflow_qfctx; 120224fc8c8SJames Wright const PetscScalar Kelvin = honee->units->Kelvin; 121224fc8c8SJames Wright const PetscScalar Pascal = honee->units->Pascal; 122*f978755dSJames Wright HoneeBCStruct honee_bc; 123*f978755dSJames Wright OutflowHoneeBCCtx outflow_honee_bc; 124224fc8c8SJames Wright 125224fc8c8SJames Wright PetscFunctionBeginUser; 126224fc8c8SJames Wright CeedScalar pressure = reference->pressure / Pascal; 127224fc8c8SJames Wright CeedScalar temperature = reference->temperature / Kelvin; 128224fc8c8SJames Wright CeedScalar recirc = 1, softplus_velocity = 1e-2; 129224fc8c8SJames Wright PetscOptionsBegin(honee->comm, NULL, "Options for Outflow boundary condition", NULL); 130224fc8c8SJames Wright PetscCall( 131224fc8c8SJames Wright PetscOptionsEnum("-outflow_type", "Type of outflow condition", NULL, OutflowTypes, (PetscEnum)outflow_type, (PetscEnum *)&outflow_type, NULL)); 132224fc8c8SJames Wright PetscCall(PetscOptionsScalar("-outflow_pressure", "Pressure at outflow condition", NULL, pressure, &pressure, NULL)); 133224fc8c8SJames Wright if (outflow_type == OUTFLOW_RIEMANN) { 134224fc8c8SJames Wright PetscCall(PetscOptionsScalar("-outflow_temperature", "Temperature at outflow condition", NULL, temperature, &temperature, NULL)); 135224fc8c8SJames Wright PetscCall( 136224fc8c8SJames Wright PetscOptionsReal("-outflow_recirc", "Fraction of recirculation to allow in exterior velocity state [0,1]", NULL, recirc, &recirc, NULL)); 137224fc8c8SJames Wright PetscCall(PetscOptionsReal("-outflow_softplus_velocity", "Characteristic velocity of softplus regularization", NULL, softplus_velocity, 138224fc8c8SJames Wright &softplus_velocity, NULL)); 139224fc8c8SJames Wright } 140224fc8c8SJames Wright PetscOptionsEnd(); 141224fc8c8SJames Wright pressure *= Pascal; 142224fc8c8SJames Wright temperature *= Kelvin; 143224fc8c8SJames Wright 144*f978755dSJames Wright PetscCall(PetscNew(&outflow_ctx)); 145224fc8c8SJames Wright outflow_ctx->gas = *newtonian_ig_ctx; 146224fc8c8SJames Wright outflow_ctx->recirc = recirc; 147224fc8c8SJames Wright outflow_ctx->softplus_velocity = softplus_velocity; 148224fc8c8SJames Wright outflow_ctx->pressure = pressure; 149224fc8c8SJames Wright outflow_ctx->temperature = temperature; 150224fc8c8SJames Wright 151224fc8c8SJames Wright PetscCallCeed(ceed, CeedQFunctionContextCreate(honee->ceed, &outflow_qfctx)); 152224fc8c8SJames Wright PetscCallCeed(ceed, CeedQFunctionContextSetData(outflow_qfctx, CEED_MEM_HOST, CEED_USE_POINTER, sizeof(*outflow_ctx), outflow_ctx)); 153224fc8c8SJames Wright PetscCallCeed(ceed, CeedQFunctionContextSetDataDestroy(outflow_qfctx, CEED_MEM_HOST, FreeContextPetsc)); 154*f978755dSJames Wright 155*f978755dSJames Wright PetscCall(PetscNew(&honee_bc)); 156*f978755dSJames Wright PetscCall(PetscNew(&outflow_honee_bc)); 157*f978755dSJames Wright outflow_honee_bc->outflow_type = outflow_type; 158*f978755dSJames Wright honee_bc->ctx = outflow_honee_bc; 159*f978755dSJames Wright honee_bc->DestroyCtx = PetscCtxDestroyDefault; 160*f978755dSJames Wright honee_bc->honee = honee; 161*f978755dSJames Wright honee_bc->jac_data_size_sur = honee->phys->implicit ? problem->jac_data_size_sur : 0; 162*f978755dSJames Wright honee_bc->qfctx = outflow_qfctx; 163*f978755dSJames Wright PetscCall(BCDefinitionSetContext(bc_def, HoneeBCDestroy, honee_bc)); 164*f978755dSJames Wright 165*f978755dSJames Wright PetscCall(BCDefinitionSetIFunction(bc_def, OutflowBCSetup_CreateIFunctionQF, HoneeBCAddIFunctionOp)); 166*f978755dSJames Wright PetscCall(BCDefinitionSetIJacobian(bc_def, OutflowBCSetup_CreateIJacobianQF, HoneeBCAddIJacobianOp)); 167*f978755dSJames Wright 168224fc8c8SJames Wright PetscFunctionReturn(PETSC_SUCCESS); 169224fc8c8SJames Wright } 170