xref: /honee/problems/bc_outflow.c (revision f978755d57fb6574cfe1ff974b5424124ae3c75e)
1224fc8c8SJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2025, HONEE contributors.
2224fc8c8SJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause
3224fc8c8SJames Wright 
4224fc8c8SJames Wright /// @file
5224fc8c8SJames Wright /// Utility functions for setting up Freestream boundary condition
6224fc8c8SJames Wright 
7224fc8c8SJames Wright #include "../qfunctions/bc_outflow.h"
8224fc8c8SJames Wright 
9224fc8c8SJames Wright #include <ceed.h>
10224fc8c8SJames Wright #include <petscdm.h>
11224fc8c8SJames Wright 
12224fc8c8SJames Wright #include <navierstokes.h>
13224fc8c8SJames Wright #include "../qfunctions/newtonian_types.h"
14224fc8c8SJames Wright 
15224fc8c8SJames Wright static const char *const OutflowTypes[] = {"RIEMANN", "PRESSURE", "OutflowType", "OUTFLOW_", NULL};
16224fc8c8SJames Wright typedef enum {
17224fc8c8SJames Wright   OUTFLOW_RIEMANN,
18224fc8c8SJames Wright   OUTFLOW_PRESSURE,
19224fc8c8SJames Wright } OutflowType;
20224fc8c8SJames Wright 
21*f978755dSJames Wright typedef struct {
22*f978755dSJames Wright   OutflowType outflow_type;
23*f978755dSJames Wright } *OutflowHoneeBCCtx;
24*f978755dSJames Wright 
25*f978755dSJames Wright static PetscErrorCode OutflowBCSetup_CreateIFunctionQF(BCDefinition bc_def, CeedQFunction *qf) {
26*f978755dSJames Wright   Honee         honee;
27*f978755dSJames Wright   HoneeBCStruct honee_bc;
28*f978755dSJames Wright 
29*f978755dSJames Wright   PetscFunctionBeginUser;
30*f978755dSJames Wright   PetscCall(BCDefinitionGetContext(bc_def, &honee_bc));
31*f978755dSJames Wright   honee                              = honee_bc->honee;
32*f978755dSJames Wright   OutflowHoneeBCCtx outflow_honee_bc = (OutflowHoneeBCCtx)honee_bc->ctx;
33*f978755dSJames Wright 
34*f978755dSJames Wright   switch (honee->phys->state_var) {
35*f978755dSJames Wright     case STATEVAR_CONSERVATIVE:
36*f978755dSJames Wright       switch (outflow_honee_bc->outflow_type) {
37*f978755dSJames Wright         case OUTFLOW_RIEMANN:
38*f978755dSJames Wright           PetscCall(HoneeBCCreateIFunctionQF(bc_def, RiemannOutflow_Conserv, RiemannOutflow_Conserv_loc, honee_bc->qfctx, qf));
39*f978755dSJames Wright           break;
40*f978755dSJames Wright         case OUTFLOW_PRESSURE:
41*f978755dSJames Wright           PetscCall(HoneeBCCreateIFunctionQF(bc_def, PressureOutflow_Conserv, PressureOutflow_Conserv_loc, honee_bc->qfctx, qf));
42*f978755dSJames Wright           break;
43*f978755dSJames Wright       }
44*f978755dSJames Wright       break;
45*f978755dSJames Wright     case STATEVAR_PRIMITIVE:
46*f978755dSJames Wright       switch (outflow_honee_bc->outflow_type) {
47*f978755dSJames Wright         case OUTFLOW_RIEMANN:
48*f978755dSJames Wright           PetscCall(HoneeBCCreateIFunctionQF(bc_def, RiemannOutflow_Prim, RiemannOutflow_Prim_loc, honee_bc->qfctx, qf));
49*f978755dSJames Wright           break;
50*f978755dSJames Wright         case OUTFLOW_PRESSURE:
51*f978755dSJames Wright           PetscCall(HoneeBCCreateIFunctionQF(bc_def, PressureOutflow_Prim, PressureOutflow_Prim_loc, honee_bc->qfctx, qf));
52*f978755dSJames Wright           break;
53*f978755dSJames Wright       }
54*f978755dSJames Wright       break;
55*f978755dSJames Wright     case STATEVAR_ENTROPY:
56*f978755dSJames Wright       switch (outflow_honee_bc->outflow_type) {
57*f978755dSJames Wright         case OUTFLOW_RIEMANN:
58*f978755dSJames Wright           PetscCall(HoneeBCCreateIFunctionQF(bc_def, RiemannOutflow_Entropy, RiemannOutflow_Entropy_loc, honee_bc->qfctx, qf));
59*f978755dSJames Wright           break;
60*f978755dSJames Wright         case OUTFLOW_PRESSURE:
61*f978755dSJames Wright           PetscCall(HoneeBCCreateIFunctionQF(bc_def, PressureOutflow_Entropy, PressureOutflow_Entropy_loc, honee_bc->qfctx, qf));
62*f978755dSJames Wright           break;
63*f978755dSJames Wright       }
64*f978755dSJames Wright       break;
65*f978755dSJames Wright   }
66*f978755dSJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
67*f978755dSJames Wright }
68*f978755dSJames Wright 
69*f978755dSJames Wright static PetscErrorCode OutflowBCSetup_CreateIJacobianQF(BCDefinition bc_def, CeedQFunction *qf) {
70*f978755dSJames Wright   Honee         honee;
71*f978755dSJames Wright   HoneeBCStruct honee_bc;
72*f978755dSJames Wright 
73*f978755dSJames Wright   PetscFunctionBeginUser;
74*f978755dSJames Wright   PetscCall(BCDefinitionGetContext(bc_def, &honee_bc));
75*f978755dSJames Wright   honee                              = honee_bc->honee;
76*f978755dSJames Wright   OutflowHoneeBCCtx outflow_honee_bc = (OutflowHoneeBCCtx)honee_bc->ctx;
77*f978755dSJames Wright 
78*f978755dSJames Wright   switch (honee->phys->state_var) {
79*f978755dSJames Wright     case STATEVAR_CONSERVATIVE:
80*f978755dSJames Wright       switch (outflow_honee_bc->outflow_type) {
81*f978755dSJames Wright         case OUTFLOW_RIEMANN:
82*f978755dSJames Wright           PetscCall(HoneeBCCreateIJacobianQF(bc_def, RiemannOutflow_Jacobian_Conserv, RiemannOutflow_Jacobian_Conserv_loc, honee_bc->qfctx, qf));
83*f978755dSJames Wright           break;
84*f978755dSJames Wright         case OUTFLOW_PRESSURE:
85*f978755dSJames Wright           PetscCall(HoneeBCCreateIJacobianQF(bc_def, PressureOutflow_Jacobian_Conserv, PressureOutflow_Jacobian_Conserv_loc, honee_bc->qfctx, qf));
86*f978755dSJames Wright           break;
87*f978755dSJames Wright       }
88*f978755dSJames Wright       break;
89*f978755dSJames Wright     case STATEVAR_PRIMITIVE:
90*f978755dSJames Wright       switch (outflow_honee_bc->outflow_type) {
91*f978755dSJames Wright         case OUTFLOW_RIEMANN:
92*f978755dSJames Wright           PetscCall(HoneeBCCreateIJacobianQF(bc_def, RiemannOutflow_Jacobian_Prim, RiemannOutflow_Jacobian_Prim_loc, honee_bc->qfctx, qf));
93*f978755dSJames Wright           break;
94*f978755dSJames Wright         case OUTFLOW_PRESSURE:
95*f978755dSJames Wright           PetscCall(HoneeBCCreateIJacobianQF(bc_def, PressureOutflow_Jacobian_Prim, PressureOutflow_Jacobian_Prim_loc, honee_bc->qfctx, qf));
96*f978755dSJames Wright           break;
97*f978755dSJames Wright       }
98*f978755dSJames Wright       break;
99*f978755dSJames Wright     case STATEVAR_ENTROPY:
100*f978755dSJames Wright       switch (outflow_honee_bc->outflow_type) {
101*f978755dSJames Wright         case OUTFLOW_RIEMANN:
102*f978755dSJames Wright           PetscCall(HoneeBCCreateIJacobianQF(bc_def, RiemannOutflow_Jacobian_Entropy, RiemannOutflow_Jacobian_Entropy_loc, honee_bc->qfctx, qf));
103*f978755dSJames Wright           break;
104*f978755dSJames Wright         case OUTFLOW_PRESSURE:
105*f978755dSJames Wright           PetscCall(HoneeBCCreateIJacobianQF(bc_def, PressureOutflow_Jacobian_Entropy, PressureOutflow_Jacobian_Entropy_loc, honee_bc->qfctx, qf));
106*f978755dSJames Wright           break;
107*f978755dSJames Wright       }
108*f978755dSJames Wright       break;
109*f978755dSJames Wright   }
110*f978755dSJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
111*f978755dSJames Wright }
112*f978755dSJames Wright 
113*f978755dSJames Wright PetscErrorCode OutflowBCSetup(BCDefinition bc_def, ProblemData problem, DM dm, void *ctx, NewtonianIdealGasContext newtonian_ig_ctx,
114*f978755dSJames Wright                               const StatePrimitive *reference) {
115224fc8c8SJames Wright   Honee                honee = *(Honee *)ctx;
116224fc8c8SJames Wright   Ceed                 ceed  = honee->ceed;
117224fc8c8SJames Wright   OutflowContext       outflow_ctx;
118224fc8c8SJames Wright   OutflowType          outflow_type = OUTFLOW_RIEMANN;
119224fc8c8SJames Wright   CeedQFunctionContext outflow_qfctx;
120224fc8c8SJames Wright   const PetscScalar    Kelvin = honee->units->Kelvin;
121224fc8c8SJames Wright   const PetscScalar    Pascal = honee->units->Pascal;
122*f978755dSJames Wright   HoneeBCStruct        honee_bc;
123*f978755dSJames Wright   OutflowHoneeBCCtx    outflow_honee_bc;
124224fc8c8SJames Wright 
125224fc8c8SJames Wright   PetscFunctionBeginUser;
126224fc8c8SJames Wright   CeedScalar pressure    = reference->pressure / Pascal;
127224fc8c8SJames Wright   CeedScalar temperature = reference->temperature / Kelvin;
128224fc8c8SJames Wright   CeedScalar recirc = 1, softplus_velocity = 1e-2;
129224fc8c8SJames Wright   PetscOptionsBegin(honee->comm, NULL, "Options for Outflow boundary condition", NULL);
130224fc8c8SJames Wright   PetscCall(
131224fc8c8SJames Wright       PetscOptionsEnum("-outflow_type", "Type of outflow condition", NULL, OutflowTypes, (PetscEnum)outflow_type, (PetscEnum *)&outflow_type, NULL));
132224fc8c8SJames Wright   PetscCall(PetscOptionsScalar("-outflow_pressure", "Pressure at outflow condition", NULL, pressure, &pressure, NULL));
133224fc8c8SJames Wright   if (outflow_type == OUTFLOW_RIEMANN) {
134224fc8c8SJames Wright     PetscCall(PetscOptionsScalar("-outflow_temperature", "Temperature at outflow condition", NULL, temperature, &temperature, NULL));
135224fc8c8SJames Wright     PetscCall(
136224fc8c8SJames Wright         PetscOptionsReal("-outflow_recirc", "Fraction of recirculation to allow in exterior velocity state [0,1]", NULL, recirc, &recirc, NULL));
137224fc8c8SJames Wright     PetscCall(PetscOptionsReal("-outflow_softplus_velocity", "Characteristic velocity of softplus regularization", NULL, softplus_velocity,
138224fc8c8SJames Wright                                &softplus_velocity, NULL));
139224fc8c8SJames Wright   }
140224fc8c8SJames Wright   PetscOptionsEnd();
141224fc8c8SJames Wright   pressure *= Pascal;
142224fc8c8SJames Wright   temperature *= Kelvin;
143224fc8c8SJames Wright 
144*f978755dSJames Wright   PetscCall(PetscNew(&outflow_ctx));
145224fc8c8SJames Wright   outflow_ctx->gas               = *newtonian_ig_ctx;
146224fc8c8SJames Wright   outflow_ctx->recirc            = recirc;
147224fc8c8SJames Wright   outflow_ctx->softplus_velocity = softplus_velocity;
148224fc8c8SJames Wright   outflow_ctx->pressure          = pressure;
149224fc8c8SJames Wright   outflow_ctx->temperature       = temperature;
150224fc8c8SJames Wright 
151224fc8c8SJames Wright   PetscCallCeed(ceed, CeedQFunctionContextCreate(honee->ceed, &outflow_qfctx));
152224fc8c8SJames Wright   PetscCallCeed(ceed, CeedQFunctionContextSetData(outflow_qfctx, CEED_MEM_HOST, CEED_USE_POINTER, sizeof(*outflow_ctx), outflow_ctx));
153224fc8c8SJames Wright   PetscCallCeed(ceed, CeedQFunctionContextSetDataDestroy(outflow_qfctx, CEED_MEM_HOST, FreeContextPetsc));
154*f978755dSJames Wright 
155*f978755dSJames Wright   PetscCall(PetscNew(&honee_bc));
156*f978755dSJames Wright   PetscCall(PetscNew(&outflow_honee_bc));
157*f978755dSJames Wright   outflow_honee_bc->outflow_type = outflow_type;
158*f978755dSJames Wright   honee_bc->ctx                  = outflow_honee_bc;
159*f978755dSJames Wright   honee_bc->DestroyCtx           = PetscCtxDestroyDefault;
160*f978755dSJames Wright   honee_bc->honee                = honee;
161*f978755dSJames Wright   honee_bc->jac_data_size_sur    = honee->phys->implicit ? problem->jac_data_size_sur : 0;
162*f978755dSJames Wright   honee_bc->qfctx                = outflow_qfctx;
163*f978755dSJames Wright   PetscCall(BCDefinitionSetContext(bc_def, HoneeBCDestroy, honee_bc));
164*f978755dSJames Wright 
165*f978755dSJames Wright   PetscCall(BCDefinitionSetIFunction(bc_def, OutflowBCSetup_CreateIFunctionQF, HoneeBCAddIFunctionOp));
166*f978755dSJames Wright   PetscCall(BCDefinitionSetIJacobian(bc_def, OutflowBCSetup_CreateIJacobianQF, HoneeBCAddIJacobianOp));
167*f978755dSJames Wright 
168224fc8c8SJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
169224fc8c8SJames Wright }
170