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