xref: /honee/problems/bc_outflow.c (revision f978755d57fb6574cfe1ff974b5424124ae3c75e)
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   const PetscScalar    Kelvin = honee->units->Kelvin;
121   const PetscScalar    Pascal = honee->units->Pascal;
122   HoneeBCStruct        honee_bc;
123   OutflowHoneeBCCtx    outflow_honee_bc;
124 
125   PetscFunctionBeginUser;
126   CeedScalar pressure    = reference->pressure / Pascal;
127   CeedScalar temperature = reference->temperature / Kelvin;
128   CeedScalar recirc = 1, softplus_velocity = 1e-2;
129   PetscOptionsBegin(honee->comm, NULL, "Options for Outflow boundary condition", NULL);
130   PetscCall(
131       PetscOptionsEnum("-outflow_type", "Type of outflow condition", NULL, OutflowTypes, (PetscEnum)outflow_type, (PetscEnum *)&outflow_type, NULL));
132   PetscCall(PetscOptionsScalar("-outflow_pressure", "Pressure at outflow condition", NULL, pressure, &pressure, NULL));
133   if (outflow_type == OUTFLOW_RIEMANN) {
134     PetscCall(PetscOptionsScalar("-outflow_temperature", "Temperature at outflow condition", NULL, temperature, &temperature, NULL));
135     PetscCall(
136         PetscOptionsReal("-outflow_recirc", "Fraction of recirculation to allow in exterior velocity state [0,1]", NULL, recirc, &recirc, NULL));
137     PetscCall(PetscOptionsReal("-outflow_softplus_velocity", "Characteristic velocity of softplus regularization", NULL, softplus_velocity,
138                                &softplus_velocity, NULL));
139   }
140   PetscOptionsEnd();
141   pressure *= Pascal;
142   temperature *= Kelvin;
143 
144   PetscCall(PetscNew(&outflow_ctx));
145   outflow_ctx->gas               = *newtonian_ig_ctx;
146   outflow_ctx->recirc            = recirc;
147   outflow_ctx->softplus_velocity = softplus_velocity;
148   outflow_ctx->pressure          = pressure;
149   outflow_ctx->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(&honee_bc));
156   PetscCall(PetscNew(&outflow_honee_bc));
157   outflow_honee_bc->outflow_type = outflow_type;
158   honee_bc->ctx                  = outflow_honee_bc;
159   honee_bc->DestroyCtx           = PetscCtxDestroyDefault;
160   honee_bc->honee                = honee;
161   honee_bc->jac_data_size_sur    = honee->phys->implicit ? problem->jac_data_size_sur : 0;
162   honee_bc->qfctx                = outflow_qfctx;
163   PetscCall(BCDefinitionSetContext(bc_def, HoneeBCDestroy, honee_bc));
164 
165   PetscCall(BCDefinitionSetIFunction(bc_def, OutflowBCSetup_CreateIFunctionQF, HoneeBCAddIFunctionOp));
166   PetscCall(BCDefinitionSetIJacobian(bc_def, OutflowBCSetup_CreateIJacobianQF, HoneeBCAddIJacobianOp));
167 
168   PetscFunctionReturn(PETSC_SUCCESS);
169 }
170