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
OutflowBCSetup_CreateIFunctionQF(BCDefinition bc_def,CeedQFunction * qf)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
OutflowBCSetup_CreateIJacobianQF(BCDefinition bc_def,CeedQFunction * qf)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
OutflowBCSetup(BCDefinition bc_def,ProblemData problem,DM dm,void * ctx,NewtonianIdealGasContext newtonian_ig_ctx,const StatePrimitive * reference)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, (PetscCtxDestroyFn *)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