Skip to content

Commit 4810df0

Browse files
authored
Allow a GRCBC inflow to start up smoothly (#1850)
1 parent 9355930 commit 4810df0

10 files changed

Lines changed: 83 additions & 9 deletions

File tree

docs/documentation/case.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,9 @@ The entries labeled "Characteristic." are characteristic boundary conditions bas
13281328
| `bc_[x,y,z]%%grcbc_out` | Logical | Enable grcbc for subsonic outflow (pressure)|
13291329
| `bc_[x,y,z]%%grcbc_vel_out` | Logical | Enable grcbc for subsonic outflow (pressure + normal velocity) |
13301330
| `bc_[x,y,z]%%vel_in` | Real Array | Inflow velocities in x, y and z directions |
1331+
| `bc_[x,y,z]%%vel_in_ramp` | Real | Duration of a smooth start-up of the inflow velocity (0 = none) |
1332+
| `bc_[x,y,z]%%vel_in_t0` | Real | Time at which that ramp begins |
1333+
| `bc_[x,y,z]%%vel_in_frac0` | Real | Fraction of the final inflow velocity held before the ramp |
13311334
| `bc_[x,y,z]%%vel_out` | Real Array | Outflow velocities in x, y and z directions |
13321335
| `bc_[x,y,z]%%pres_in` | Real | Inflow pressure |
13331336
| `bc_[x,y,z]%%pres_out` | Real | Outflow pressure |
@@ -1336,6 +1339,8 @@ The entries labeled "Characteristic." are characteristic boundary conditions bas
13361339

13371340
This boundary condition can be used for subsonic inflow (`bc_[x,y,z]%[beg,end]` = -7) and subsonic outflow (`bc_[x,y,z]%[beg,end]` = -8) characteristic boundary conditions. These are based on \cite Pirozzoli13. This enables to provide inflow and outflow conditions outside the computational domain.
13381341

1342+
`bc_[x,y,z]%%vel_in_ramp` starts the inflow smoothly instead of holding it constant, which is what a jet or a tunnel accelerating from rest requires: the start-up is the event of interest, not a transient to be discarded. The inflow velocity is scaled by \f$f(t) = f_0 + (1 - f_0)\left[1 + \tanh\left(6 (t - t_0)/\tau - 3\right)\right]/2\f$, with \f$\tau\f$ = `vel_in_ramp`, \f$t_0\f$ = `vel_in_t0` and \f$f_0\f$ = `vel_in_frac0`, so it leaves \f$f_0\f$ of the final velocity at \f$t_0\f$ and is within half a percent of it at \f$t_0 + \tau\f$. A boundary with `vel_in_ramp = 0` is held constant, as before.
1343+
13391344
### Patch types {#patch-types}
13401345

13411346
| # | Name | Dim. | Smooth | Description |

src/common/m_boundary_primitives.fpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,27 @@ module m_boundary_primitives
2121
logical :: dirichlet_from_buffers = .false.
2222
$:GPU_DECLARE(create='[dirichlet_from_buffers]')
2323

24+
public :: f_vel_ramp
25+
2426
contains
2527

28+
!> Velocity scaling for a GRCBC inflow that is ramping up: unity unless `bc_[x,y,z]%vel_in_ramp` is set, so an unramped case is
29+
!! untouched. Takes the time as an argument so the caller can evaluate it on the device from `mytime`, which the time stepper
30+
!! already places there, rather than computing it on the host and copying the result every Runge-Kutta stage.
31+
pure function f_vel_ramp(tau, t0, frac0, t) result(f)
32+
33+
$:GPU_ROUTINE(parallelism='[seq]')
34+
real(wp), intent(in) :: tau, t0, frac0, t
35+
real(wp) :: f
36+
37+
if (tau > 0._wp) then
38+
f = frac0 + (1._wp - frac0)*0.5_wp*(1._wp + tanh(6._wp*(t - t0)/tau - 3._wp))
39+
else
40+
f = 1._wp
41+
end if
42+
43+
end function f_vel_ramp
44+
2645
!> Fill ghost cells by copying the nearest boundary cell value along the specified direction.
2746
subroutine s_ghost_cell_extrapolation(q_prim_vf, bc_dir, bc_loc, k, l, q_T_sf)
2847

src/common/m_derived_types.fpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,12 @@ module m_derived_types
112112
real(wp), dimension(3) :: vel_in, vel_out
113113
real(wp), dimension(num_fluids_max) :: alpha_rho_in, alpha_in
114114
logical :: grcbc_in, grcbc_out, grcbc_vel_out
115-
logical :: isothermal_in, isothermal_out
116-
real(wp) :: Twall_in, Twall_out
115+
!> Smooth start-up of a GRCBC inflow: the inflow velocity is scaled by f(t) = vel_in_frac0 + (1 - vel_in_frac0) (1 + tanh(6
116+
!! (t - t0)/tau - 3))/2, so it leaves vel_in_frac0 of its final value at t0 and reaches it after vel_in_ramp. Inactive when
117+
!! the ramp duration is zero.
118+
real(wp) :: vel_in_ramp, vel_in_t0, vel_in_frac0
119+
logical :: isothermal_in, isothermal_out
120+
real(wp) :: Twall_in, Twall_out
117121
end type int_bounds_info
118122

119123
!> Groups the x, y, z boundary condition begin/end codes for passing as a single argument.

src/simulation/m_cbc.fpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module m_cbc
1212
use m_global_parameters
1313
use m_variables_conversion
1414
use m_compute_cbc
15+
use m_boundary_primitives, only: f_vel_ramp
1516
use m_constants, only: riemann_solver_hll, model_eqns_gamma_law, recon_type_weno, recon_type_muscl
1617
use m_thermochem, only: get_mixture_energy_mass, get_mixture_specific_heat_cv_mass, get_mixture_specific_heat_cp_mass, &
1718
& gas_constant, get_mixture_molecular_weight, get_species_enthalpies_rt, molecular_weights, get_species_specific_heats_r, &
@@ -473,6 +474,7 @@ contains
473474
real(wp) :: dpi_inf_dt
474475
real(wp) :: dqv_dt
475476
real(wp) :: dpres_ds
477+
real(wp) :: ramp !< inflow ramp factor; unity unless a ramp is set
476478
477479
#:if USING_AMD
478480
real(wp), dimension(${AMD_SYS_SIZE_MAX}$) :: L
@@ -596,9 +598,13 @@ contains
596598
& dalpha_rho_ds, dpres_ds, dvel_dt, dadv_dt, dalpha_rho_dt, L, lambda, Ys, dYs_dt, dYs_ds, &
597599
& h_k, Cp_i, Gamma_i, Xs, drho_dt, dpres_dt, dpi_inf_dt, dqv_dt, dgamma_dt, rho, pres, E, &
598600
& gamma, pi_inf, qv, c, Ma, T, sum_Enthalpies, Cv, Cp, e_mix, Mw, R_gas, vel_K_sum, &
599-
& vel_dv_dt_sum, i, j]', copyin='[dir_idx]')
601+
& vel_dv_dt_sum, i, j, ramp]', copyin='[dir_idx]')
600602
do r = is3%beg, is3%end
601603
do k = is2%beg, is2%end
604+
! Ramp factor for a smoothly starting inflow, evaluated here from mytime rather than
605+
! computed on the host and copied every Runge-Kutta stage. Unity unless a ramp is set.
606+
ramp = f_vel_ramp(bc_${XYZ}$%vel_in_ramp, bc_${XYZ}$%vel_in_t0, bc_${XYZ}$%vel_in_frac0, mytime)
607+
602608
! Transferring the Primitive Variables
603609
$:GPU_LOOP(parallelism='[seq]')
604610
do i = 1, eqn_idx%cont%end
@@ -735,10 +741,10 @@ contains
735741
& ${CBC_DIR}$))/Del_in(${CBC_DIR}$) - c*Ma*(pres - pres_in(${CBC_DIR}$))/Del_in(${CBC_DIR}$)
736742
end do
737743
if (n > 0) then
738-
L(eqn_idx%mom%beg + 1) = c*Ma*(vel(dir_idx(2)) - vel_in(${CBC_DIR}$, &
744+
L(eqn_idx%mom%beg + 1) = c*Ma*(vel(dir_idx(2)) - ramp*vel_in(${CBC_DIR}$, &
739745
& dir_idx(2)))/Del_in(${CBC_DIR}$)
740746
if (p > 0) then
741-
L(eqn_idx%mom%beg + 2) = c*Ma*(vel(dir_idx(3)) - vel_in(${CBC_DIR}$, &
747+
L(eqn_idx%mom%beg + 2) = c*Ma*(vel(dir_idx(3)) - ramp*vel_in(${CBC_DIR}$, &
742748
& dir_idx(3)))/Del_in(${CBC_DIR}$)
743749
end if
744750
end if
@@ -747,7 +753,7 @@ contains
747753
L(i) = c*Ma*(adv_local(i + 1 - eqn_idx%E) - alpha_in(i + 1 - eqn_idx%E, &
748754
& ${CBC_DIR}$))/Del_in(${CBC_DIR}$)
749755
end do
750-
L(eqn_idx%adv%end) = rho*c**2._wp*(1._wp + Ma)*(vel(dir_idx(1)) + vel_in(${CBC_DIR}$, &
756+
L(eqn_idx%adv%end) = rho*c**2._wp*(1._wp + Ma)*(vel(dir_idx(1)) + ramp*vel_in(${CBC_DIR}$, &
751757
& dir_idx(1))*sign(1, &
752758
& cbc_loc))/Del_in(${CBC_DIR}$) + c*(1._wp + Ma)*(pres - pres_in(${CBC_DIR}$))/Del_in(${CBC_DIR}$)
753759
end if

src/simulation/m_global_parameters.fpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ module m_global_parameters
121121
$:GPU_DECLARE(create='[bc_x%vb1, bc_x%vb2, bc_x%vb3, bc_x%ve1, bc_x%ve2, bc_x%ve3]')
122122
$:GPU_DECLARE(create='[bc_y%vb1, bc_y%vb2, bc_y%vb3, bc_y%ve1, bc_y%ve2, bc_y%ve3]')
123123
$:GPU_DECLARE(create='[bc_z%vb1, bc_z%vb2, bc_z%vb3, bc_z%ve1, bc_z%ve2, bc_z%ve3]')
124+
$:GPU_DECLARE(create='[bc_x%vel_in_ramp, bc_x%vel_in_t0, bc_x%vel_in_frac0]')
125+
$:GPU_DECLARE(create='[bc_y%vel_in_ramp, bc_y%vel_in_t0, bc_y%vel_in_frac0]')
126+
$:GPU_DECLARE(create='[bc_z%vel_in_ramp, bc_z%vel_in_t0, bc_z%vel_in_frac0]')
124127
$:GPU_DECLARE(create='[ib_bc_x%beg, ib_bc_x%end, ib_bc_y%beg, ib_bc_y%end, ib_bc_z%beg, ib_bc_z%end]')
125128
#elif defined(MFC_OpenMP)
126129
$:GPU_DECLARE(create='[bc_x, bc_y, bc_z]')
@@ -606,6 +609,9 @@ contains
606609
bc_${dir}$%grcbc_in = .false.
607610
bc_${dir}$%grcbc_out = .false.
608611
bc_${dir}$%grcbc_vel_out = .false.
612+
bc_${dir}$%vel_in_ramp = 0._wp
613+
bc_${dir}$%vel_in_t0 = 0._wp
614+
bc_${dir}$%vel_in_frac0 = 0._wp
609615
#:endfor
610616
611617
! Lagrangian subgrid bubble model

src/simulation/m_mpi_proxy.fpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,10 @@ contains
135135
& 'bc_x%pres_in','bc_x%pres_out','bc_y%pres_in','bc_y%pres_out', &
136136
& 'bc_z%pres_in','bc_z%pres_out', &
137137
& 'bc_x%Twall_in', 'bc_x%Twall_out', 'bc_y%Twall_in', 'bc_y%Twall_out', &
138-
& 'bc_z%Twall_in', 'bc_z%Twall_out']
138+
& 'bc_z%Twall_in', 'bc_z%Twall_out', &
139+
& 'bc_x%vel_in_ramp', 'bc_x%vel_in_t0', 'bc_x%vel_in_frac0', &
140+
& 'bc_y%vel_in_ramp', 'bc_y%vel_in_t0', 'bc_y%vel_in_frac0', &
141+
& 'bc_z%vel_in_ramp', 'bc_z%vel_in_t0', 'bc_z%vel_in_frac0']
139142
call MPI_BCAST(${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr)
140143
#:endfor
141144

src/simulation/m_start_up.fpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,10 @@ contains
10971097
$:GPU_UPDATE(device='[bc_y%grcbc_in, bc_y%grcbc_out, bc_y%grcbc_vel_out]')
10981098
$:GPU_UPDATE(device='[bc_z%grcbc_in, bc_z%grcbc_out, bc_z%grcbc_vel_out]')
10991099

1100+
$:GPU_UPDATE(device='[bc_x%vel_in_ramp, bc_x%vel_in_t0, bc_x%vel_in_frac0]')
1101+
$:GPU_UPDATE(device='[bc_y%vel_in_ramp, bc_y%vel_in_t0, bc_y%vel_in_frac0]')
1102+
$:GPU_UPDATE(device='[bc_z%vel_in_ramp, bc_z%vel_in_t0, bc_z%vel_in_frac0]')
1103+
11001104
$:GPU_UPDATE(device='[bc_x%isothermal_in, bc_x%isothermal_out]')
11011105
$:GPU_UPDATE(device='[bc_y%isothermal_in, bc_y%isothermal_out]')
11021106
$:GPU_UPDATE(device='[bc_z%isothermal_in, bc_z%isothermal_out]')

src/simulation/m_time_steppers.fpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,10 @@ contains
460460

461461
do s = 1, nstage
462462
call system_clock(stage_t0)
463+
! mytime is read on the device by the GRCBC inflow ramp, so it has to be current before the RHS that
464+
! reads it, not after. Its GPU_DECLARE only creates device storage and never copies the host value, so
465+
! without this the first RHS of a run reads uninitialised memory and later stages read a stale time.
466+
$:GPU_UPDATE(device='[mytime]')
463467
call s_compute_rhs(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, bc_type, rhs_vf, pb_ts(1)%sf, rhs_pb, mv_ts(1)%sf, rhs_mv, &
464468
& t_step, s)
465469

@@ -532,7 +536,6 @@ contains
532536
$:END_GPU_PARALLEL_LOOP()
533537
end if
534538

535-
$:GPU_UPDATE(device='[mytime]')
536539
if (bodyForces) call s_apply_bodyforces(q_cons_ts(1)%vf, q_prim_vf, rhs_vf, rk_coef(s, 3)*dt/rk_coef(s, 4))
537540

538541
if (synthetic_turbulence) call s_apply_synthetic_turbulence_force(q_cons_ts(1)%vf, q_prim_vf, rhs_vf, rk_coef(s, &

toolchain/mfc/case_validator.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
# to auto-generate docs/documentation/physics_constraints.md.
3333
# See the contributing guide for how to add entries.
3434
PHYSICS_DOCS = {
35+
"check_inflow_ramp": {
36+
"title": "GRCBC Inflow Ramp",
37+
"category": "Boundary Conditions",
38+
"math": r"f(t) = f_0 + (1 - f_0)\left[1 + \tanh\left(6 (t - t_0)/\tau - 3\right)\right]/2",
39+
"explanation": "A ramped inflow scales the inflow velocity from a fraction f_0 of its final value to "
40+
"that value over a duration tau. It requires grcbc_in to act on, a non-negative duration, and f_0 in [0, 1].",
41+
},
3542
# Thermodynamic Constraints
3643
"check_stiffened_eos": {
3744
"title": "Stiffened EOS Positivity",
@@ -734,6 +741,19 @@ def check_phase_change(self):
734741
self.prohibit(ptgalpha_eps is not None and ptgalpha_eps <= 0, "ptgalpha_eps must be positive")
735742
self.prohibit(ptgalpha_eps is not None and ptgalpha_eps >= 1, "ptgalpha_eps must be less than 1")
736743

744+
def check_inflow_ramp(self):
745+
"""Checks constraints on the smooth start-up of a GRCBC inflow"""
746+
for d in ("x", "y", "z"):
747+
ramp = self.get(f"bc_{d}%vel_in_ramp", 0) or 0
748+
frac0 = self.get(f"bc_{d}%vel_in_frac0", 0) or 0
749+
self.prohibit(ramp < 0, f"bc_{d}%vel_in_ramp must be >= 0")
750+
# a ramp needs an inflow to act on
751+
self.prohibit(
752+
ramp > 0 and self.get(f"bc_{d}%grcbc_in", "F") != "T",
753+
f"bc_{d}%vel_in_ramp requires bc_{d}%grcbc_in",
754+
)
755+
self.prohibit(not 0 <= frac0 <= 1, f"bc_{d}%vel_in_frac0 must lie in [0, 1]")
756+
737757
def check_ibm(self):
738758
"""Checks constraints on Immersed Boundaries parameters"""
739759
ib = self.get("ib", "F") == "T"
@@ -2812,6 +2832,7 @@ def validate_common(self):
28122832
self.check_hypoelasticity()
28132833
self.check_phase_change()
28142834
self.check_ibm()
2835+
self.check_inflow_ramp()
28152836
self.check_eos_selector()
28162837
self.check_stiffened_eos()
28172838
self.check_eos_parameter_sanity()

toolchain/mfc/params/definitions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ def _fc(name: str, default: int) -> int:
6969

7070
HINTS = {
7171
"bc": {
72+
"vel_in_ramp": "Duration of the smooth start-up of the inflow velocity (0 = no ramp)",
73+
"vel_in_t0": "Time at which the inflow velocity ramp begins",
74+
"vel_in_frac0": "Fraction of the final inflow velocity held before the ramp",
7275
"grcbc_in": "Enables GRCBC subsonic inflow (bc type -7)",
7376
"grcbc_out": "Enables GRCBC subsonic outflow (bc type -8)",
7477
"grcbc_vel_out": "GRCBC velocity outlet (requires `grcbc_out`)",
@@ -1110,7 +1113,7 @@ def _load():
11101113
# Extended BC
11111114
for d in ["x", "y", "z"]:
11121115
px = f"bc_{d}%"
1113-
for a in ["vb1", "vb2", "vb3", "ve1", "ve2", "ve3", "pres_in", "pres_out"]:
1116+
for a in ["vb1", "vb2", "vb3", "ve1", "ve2", "ve3", "pres_in", "pres_out", "vel_in_ramp", "vel_in_t0", "vel_in_frac0"]:
11141117
_r(f"{px}{a}", REAL, {"bc"})
11151118
for a in ["grcbc_in", "grcbc_out", "grcbc_vel_out"]:
11161119
_r(f"{px}{a}", LOG, {"bc"})

0 commit comments

Comments
 (0)