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 typedef struct { 22 OutflowType outflow_type; 23 } *OutflowHoneeBCCtx; 24 25 static PetscErrorCode OutflowBCSetup_CreateIFunctionQF(BCDefinition bc_def, CeedQFunction *qf) { 26 Honee honee; 27 HoneeBCStruct honee_bc; 28 29 PetscFunctionBeginUser; 30 PetscCall(BCDefinitionGetContext(bc_def, &honee_bc)); 31 honee = honee_bc->honee; 32 OutflowHoneeBCCtx outflow_honee_bc = (OutflowHoneeBCCtx)honee_bc->ctx; 33 34 switch (honee->phys->state_var) { 35 case STATEVAR_CONSERVATIVE: 36 switch (outflow_honee_bc->outflow_type) { 37 case OUTFLOW_RIEMANN: 38 PetscCall(HoneeBCCreateIFunctionQF(bc_def, RiemannOutflow_Conserv, RiemannOutflow_Conserv_loc, honee_bc->qfctx, qf)); 39 break; 40 case OUTFLOW_PRESSURE: 41 PetscCall(HoneeBCCreateIFunctionQF(bc_def, PressureOutflow_Conserv, PressureOutflow_Conserv_loc, honee_bc->qfctx, qf)); 42 break; 43 } 44 break; 45 case STATEVAR_PRIMITIVE: 46 switch (outflow_honee_bc->outflow_type) { 47 case OUTFLOW_RIEMANN: 48 PetscCall(HoneeBCCreateIFunctionQF(bc_def, RiemannOutflow_Prim, RiemannOutflow_Prim_loc, honee_bc->qfctx, qf)); 49 break; 50 case OUTFLOW_PRESSURE: 51 PetscCall(HoneeBCCreateIFunctionQF(bc_def, PressureOutflow_Prim, PressureOutflow_Prim_loc, honee_bc->qfctx, qf)); 52 break; 53 } 54 break; 55 case STATEVAR_ENTROPY: 56 switch (outflow_honee_bc->outflow_type) { 57 case OUTFLOW_RIEMANN: 58 PetscCall(HoneeBCCreateIFunctionQF(bc_def, RiemannOutflow_Entropy, RiemannOutflow_Entropy_loc, honee_bc->qfctx, qf)); 59 break; 60 case OUTFLOW_PRESSURE: 61 PetscCall(HoneeBCCreateIFunctionQF(bc_def, PressureOutflow_Entropy, PressureOutflow_Entropy_loc, honee_bc->qfctx, qf)); 62 break; 63 } 64 break; 65 } 66 PetscFunctionReturn(PETSC_SUCCESS); 67 } 68 69 static PetscErrorCode OutflowBCSetup_CreateIJacobianQF(BCDefinition bc_def, CeedQFunction *qf) { 70 Honee honee; 71 HoneeBCStruct honee_bc; 72 73 PetscFunctionBeginUser; 74 PetscCall(BCDefinitionGetContext(bc_def, &honee_bc)); 75 honee = honee_bc->honee; 76 OutflowHoneeBCCtx outflow_honee_bc = (OutflowHoneeBCCtx)honee_bc->ctx; 77 78 switch (honee->phys->state_var) { 79 case STATEVAR_CONSERVATIVE: 80 switch (outflow_honee_bc->outflow_type) { 81 case OUTFLOW_RIEMANN: 82 PetscCall(HoneeBCCreateIJacobianQF(bc_def, RiemannOutflow_Jacobian_Conserv, RiemannOutflow_Jacobian_Conserv_loc, honee_bc->qfctx, qf)); 83 break; 84 case OUTFLOW_PRESSURE: 85 PetscCall(HoneeBCCreateIJacobianQF(bc_def, PressureOutflow_Jacobian_Conserv, PressureOutflow_Jacobian_Conserv_loc, honee_bc->qfctx, qf)); 86 break; 87 } 88 break; 89 case STATEVAR_PRIMITIVE: 90 switch (outflow_honee_bc->outflow_type) { 91 case OUTFLOW_RIEMANN: 92 PetscCall(HoneeBCCreateIJacobianQF(bc_def, RiemannOutflow_Jacobian_Prim, RiemannOutflow_Jacobian_Prim_loc, honee_bc->qfctx, qf)); 93 break; 94 case OUTFLOW_PRESSURE: 95 PetscCall(HoneeBCCreateIJacobianQF(bc_def, PressureOutflow_Jacobian_Prim, PressureOutflow_Jacobian_Prim_loc, honee_bc->qfctx, qf)); 96 break; 97 } 98 break; 99 case STATEVAR_ENTROPY: 100 switch (outflow_honee_bc->outflow_type) { 101 case OUTFLOW_RIEMANN: 102 PetscCall(HoneeBCCreateIJacobianQF(bc_def, RiemannOutflow_Jacobian_Entropy, RiemannOutflow_Jacobian_Entropy_loc, honee_bc->qfctx, qf)); 103 break; 104 case OUTFLOW_PRESSURE: 105 PetscCall(HoneeBCCreateIJacobianQF(bc_def, PressureOutflow_Jacobian_Entropy, PressureOutflow_Jacobian_Entropy_loc, honee_bc->qfctx, qf)); 106 break; 107 } 108 break; 109 } 110 PetscFunctionReturn(PETSC_SUCCESS); 111 } 112 113 PetscErrorCode OutflowBCSetup(BCDefinition bc_def, ProblemData problem, DM dm, void *ctx, NewtonianIdealGasContext newtonian_ig_ctx, 114 const StatePrimitive *reference) { 115 Honee honee = *(Honee *)ctx; 116 Ceed ceed = honee->ceed; 117 OutflowContext outflow_ctx; 118 OutflowType outflow_type = OUTFLOW_RIEMANN; 119 CeedQFunctionContext outflow_qfctx; 120 Units units = honee->units; 121 HoneeBCStruct honee_bc; 122 OutflowHoneeBCCtx outflow_honee_bc; 123 124 PetscFunctionBeginUser; 125 CeedScalar pressure = reference->pressure / units->Pascal; 126 CeedScalar temperature = reference->temperature / units->Kelvin; 127 CeedScalar recirc = 1, softplus_velocity = 1e-2; 128 PetscOptionsBegin(honee->comm, NULL, "Options for Outflow boundary condition", NULL); 129 PetscCall(PetscOptionsEnum("-outflow_type", "Type of outflow condition", NULL, OutflowTypes, (PetscEnum)outflow_type, (PetscEnum *)&outflow_type, 130 NULL)); 131 PetscCall(PetscOptionsScalar("-outflow_pressure", "Pressure at outflow condition", NULL, pressure, &pressure, NULL)); 132 if (outflow_type == OUTFLOW_RIEMANN) { 133 PetscCall(PetscOptionsScalar("-outflow_temperature", "Temperature at outflow condition", NULL, temperature, &temperature, NULL)); 134 PetscCall(PetscOptionsReal("-outflow_recirc", "Fraction of recirculation to allow in exterior velocity state [0,1]", NULL, recirc, &recirc, 135 NULL)); 136 PetscCall(PetscOptionsReal("-outflow_softplus_velocity", "Characteristic velocity of softplus regularization", NULL, softplus_velocity, 137 &softplus_velocity, NULL)); 138 } 139 PetscOptionsEnd(); 140 pressure *= units->Pascal; 141 temperature *= units->Kelvin; 142 143 PetscCall(PetscNew(&outflow_ctx)); 144 *outflow_ctx = (struct OutflowContext_){ 145 .newt_ctx = *newtonian_ig_ctx, 146 .recirc = recirc, 147 .softplus_velocity = softplus_velocity, 148 .pressure = pressure, 149 .temperature = temperature, 150 }; 151 PetscCallCeed(ceed, CeedQFunctionContextCreate(honee->ceed, &outflow_qfctx)); 152 PetscCallCeed(ceed, CeedQFunctionContextSetData(outflow_qfctx, CEED_MEM_HOST, CEED_USE_POINTER, sizeof(*outflow_ctx), outflow_ctx)); 153 PetscCallCeed(ceed, CeedQFunctionContextSetDataDestroy(outflow_qfctx, CEED_MEM_HOST, FreeContextPetsc)); 154 155 PetscCall(PetscNew(&outflow_honee_bc)); 156 outflow_honee_bc->outflow_type = outflow_type; 157 PetscCall(PetscNew(&honee_bc)); 158 *honee_bc = (struct HoneeBCStruct_){ 159 .ctx = outflow_honee_bc, 160 .DestroyCtx = PetscCtxDestroyDefault, 161 .honee = honee, 162 .num_comps_jac_data = honee->phys->implicit ? 11 : 0, 163 .qfctx = outflow_qfctx, 164 }; 165 PetscCall(BCDefinitionSetContext(bc_def, HoneeBCDestroy, honee_bc)); 166 167 PetscCall(BCDefinitionSetIFunction(bc_def, OutflowBCSetup_CreateIFunctionQF, HoneeBCAddIFunctionOp)); 168 PetscCall(BCDefinitionSetIJacobian(bc_def, OutflowBCSetup_CreateIJacobianQF, HoneeBCAddIJacobianOp)); 169 PetscFunctionReturn(PETSC_SUCCESS); 170 } 171