xref: /honee/problems/bc_outflow.c (revision 255e1892bd5386028f31cac4bde39f1208dcc3b9)
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