xref: /honee/problems/bc_outflow.c (revision 5e79d5629814bf0aae86ae210d3bec329a078911)
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 PetscErrorCode OutflowBCSetup(ProblemData problem, DM dm, void *ctx, NewtonianIdealGasContext newtonian_ig_ctx, const StatePrimitive *reference) {
22   Honee                honee = *(Honee *)ctx;
23   Ceed                 ceed  = honee->ceed;
24   OutflowContext       outflow_ctx;
25   OutflowType          outflow_type = OUTFLOW_RIEMANN;
26   CeedQFunctionContext outflow_qfctx;
27   const PetscScalar    Kelvin = honee->units->Kelvin;
28   const PetscScalar    Pascal = honee->units->Pascal;
29 
30   PetscFunctionBeginUser;
31   CeedScalar pressure    = reference->pressure / Pascal;
32   CeedScalar temperature = reference->temperature / Kelvin;
33   CeedScalar recirc = 1, softplus_velocity = 1e-2;
34   PetscOptionsBegin(honee->comm, NULL, "Options for Outflow boundary condition", NULL);
35   PetscCall(
36       PetscOptionsEnum("-outflow_type", "Type of outflow condition", NULL, OutflowTypes, (PetscEnum)outflow_type, (PetscEnum *)&outflow_type, NULL));
37   PetscCall(PetscOptionsScalar("-outflow_pressure", "Pressure at outflow condition", NULL, pressure, &pressure, NULL));
38   if (outflow_type == OUTFLOW_RIEMANN) {
39     PetscCall(PetscOptionsScalar("-outflow_temperature", "Temperature at outflow condition", NULL, temperature, &temperature, NULL));
40     PetscCall(
41         PetscOptionsReal("-outflow_recirc", "Fraction of recirculation to allow in exterior velocity state [0,1]", NULL, recirc, &recirc, NULL));
42     PetscCall(PetscOptionsReal("-outflow_softplus_velocity", "Characteristic velocity of softplus regularization", NULL, softplus_velocity,
43                                &softplus_velocity, NULL));
44   }
45   PetscOptionsEnd();
46   pressure *= Pascal;
47   temperature *= Kelvin;
48 
49   switch (outflow_type) {
50     case OUTFLOW_RIEMANN:
51       switch (honee->phys->state_var) {
52         case STATEVAR_CONSERVATIVE:
53           problem->apply_outflow.qf_func_ptr          = RiemannOutflow_Conserv;
54           problem->apply_outflow.qf_loc               = RiemannOutflow_Conserv_loc;
55           problem->apply_outflow_jacobian.qf_func_ptr = RiemannOutflow_Jacobian_Conserv;
56           problem->apply_outflow_jacobian.qf_loc      = RiemannOutflow_Jacobian_Conserv_loc;
57           break;
58         case STATEVAR_PRIMITIVE:
59           problem->apply_outflow.qf_func_ptr          = RiemannOutflow_Prim;
60           problem->apply_outflow.qf_loc               = RiemannOutflow_Prim_loc;
61           problem->apply_outflow_jacobian.qf_func_ptr = RiemannOutflow_Jacobian_Prim;
62           problem->apply_outflow_jacobian.qf_loc      = RiemannOutflow_Jacobian_Prim_loc;
63           break;
64         case STATEVAR_ENTROPY:
65           problem->apply_outflow.qf_func_ptr          = RiemannOutflow_Entropy;
66           problem->apply_outflow.qf_loc               = RiemannOutflow_Entropy_loc;
67           problem->apply_outflow_jacobian.qf_func_ptr = RiemannOutflow_Jacobian_Entropy;
68           problem->apply_outflow_jacobian.qf_loc      = RiemannOutflow_Jacobian_Entropy_loc;
69           break;
70       }
71       break;
72     case OUTFLOW_PRESSURE:
73       switch (honee->phys->state_var) {
74         case STATEVAR_CONSERVATIVE:
75           problem->apply_outflow.qf_func_ptr          = PressureOutflow_Conserv;
76           problem->apply_outflow.qf_loc               = PressureOutflow_Conserv_loc;
77           problem->apply_outflow_jacobian.qf_func_ptr = PressureOutflow_Jacobian_Conserv;
78           problem->apply_outflow_jacobian.qf_loc      = PressureOutflow_Jacobian_Conserv_loc;
79           break;
80         case STATEVAR_PRIMITIVE:
81           problem->apply_outflow.qf_func_ptr          = PressureOutflow_Prim;
82           problem->apply_outflow.qf_loc               = PressureOutflow_Prim_loc;
83           problem->apply_outflow_jacobian.qf_func_ptr = PressureOutflow_Jacobian_Prim;
84           problem->apply_outflow_jacobian.qf_loc      = PressureOutflow_Jacobian_Prim_loc;
85           break;
86         case STATEVAR_ENTROPY:
87           problem->apply_outflow.qf_func_ptr          = PressureOutflow_Entropy;
88           problem->apply_outflow.qf_loc               = PressureOutflow_Entropy_loc;
89           problem->apply_outflow_jacobian.qf_func_ptr = PressureOutflow_Jacobian_Entropy;
90           problem->apply_outflow_jacobian.qf_loc      = PressureOutflow_Jacobian_Entropy_loc;
91           break;
92       }
93       break;
94   }
95   PetscCall(PetscCalloc1(1, &outflow_ctx));
96   outflow_ctx->gas               = *newtonian_ig_ctx;
97   outflow_ctx->recirc            = recirc;
98   outflow_ctx->softplus_velocity = softplus_velocity;
99   outflow_ctx->pressure          = pressure;
100   outflow_ctx->temperature       = temperature;
101 
102   PetscCallCeed(ceed, CeedQFunctionContextCreate(honee->ceed, &outflow_qfctx));
103   PetscCallCeed(ceed, CeedQFunctionContextSetData(outflow_qfctx, CEED_MEM_HOST, CEED_USE_POINTER, sizeof(*outflow_ctx), outflow_ctx));
104   PetscCallCeed(ceed, CeedQFunctionContextSetDataDestroy(outflow_qfctx, CEED_MEM_HOST, FreeContextPetsc));
105   problem->apply_outflow.qfctx = outflow_qfctx;
106   PetscCallCeed(ceed, CeedQFunctionContextReferenceCopy(outflow_qfctx, &problem->apply_outflow_jacobian.qfctx));
107   PetscFunctionReturn(PETSC_SUCCESS);
108 }
109