@@ -26,13 +26,13 @@ relaxation to the mean velocity (i.e. u′→0) then Fᵤ = -u′ / τ then we c
26
26
u′ⁿ⁺¹ = (uⁿ + Ũu′ⁿ⁺¹ᵢ₋₁ - Uⁿ⁺¹) / (1 + Ũ + Δt/τ),
27
27
28
28
where Ũ = U Δt / Δx, then uⁿ⁺¹ is:
29
- uⁿ⁺¹ = (uᵢⁿ + Ũuᵢ₋₁ⁿ⁺¹ + Uⁿ⁺¹τ̃) / (1 + τ̃ + U )
29
+ uⁿ⁺¹ = (uᵢⁿ + Ũuᵢ₋₁ⁿ⁺¹ + Uⁿ⁺¹τ̃) / (1 + τ̃ + Ũ )
30
30
31
31
where τ̃ = Δt/τ.
32
32
33
33
The same operation can be repeated for left boundaries.
34
34
35
- The relaxation timescale ``τ`` can be set to different values depending on whether the
35
+ The relaxation timescale ``τ`` can be set to different values depending on whether
36
36
``U`` points in or out of the domain (`inflow_timescale`/`outflow_timescale`). Since the
37
37
scheme is only valid when the flow is directed out of the domain the boundary condition
38
38
falls back to relaxation to the prescribed value. By default this happens instantly but
@@ -64,6 +64,8 @@ details about this method, refer to the docstring for `PerturbationAdvection`.
64
64
function PerturbationAdvectionOpenBoundaryCondition (val, FT = defaults. FloatType;
65
65
outflow_timescale = Inf ,
66
66
inflow_timescale = 0 , kwargs... )
67
+ inflow_timescale = convert (FT, inflow_timescale)
68
+ outflow_timescale = convert (FT, outflow_timescale)
67
69
68
70
classification = Open (PerturbationAdvection (inflow_timescale, outflow_timescale))
69
71
@@ -76,45 +78,48 @@ const PAOBC = BoundaryCondition{<:Open{<:PerturbationAdvection}}
76
78
77
79
@inline function step_right_boundary! (bc:: PAOBC , l, m, boundary_indices, boundary_adjacent_indices,
78
80
grid, u, clock, model_fields, ΔX)
81
+ iᴮ, jᴮ, kᴮ = boundary_indices
82
+ iᴬ, jᴬ, kᴬ = boundary_adjacent_indices
79
83
Δt = clock. last_stage_Δt
80
84
Δt = ifelse (isinf (Δt), 0 , Δt)
81
85
82
- ūⁿ⁺¹ = getbc (bc, l, m, grid, clock, model_fields)
83
- uᵢⁿ = @inbounds getindex (u, boundary_indices ... )
84
- uᵢ₋₁ⁿ⁺¹ = @inbounds getindex (u, boundary_adjacent_indices ... )
86
+ ūⁿ⁺¹ = getbc (bc, l, m, grid, clock, model_fields)
87
+ uᵢⁿ = @inbounds getindex (u, iᴮ, jᴮ, kᴮ )
88
+ uᵢ₋₁ⁿ⁺¹ = @inbounds getindex (u, iᴬ, jᴬ, kᴬ )
85
89
U = max (0 , min (1 , Δt / ΔX * ūⁿ⁺¹))
86
90
87
91
pa = bc. classification. matching_scheme
88
92
τ = ifelse (ūⁿ⁺¹ >= 0 , pa. outflow_timescale, pa. inflow_timescale)
89
- τ̃ = Δt / τ
93
+ τ̃ = Δt / τ # last stage Δt normalized by the inflow/output timescale
90
94
91
95
relaxed_uᵢⁿ⁺¹ = (uᵢⁿ + U * uᵢ₋₁ⁿ⁺¹ + ūⁿ⁺¹ * τ̃) / (1 + τ̃ + U)
92
- uᵢⁿ⁺¹ = ifelse (τ == 0 , ūⁿ⁺¹, relaxed_uᵢⁿ⁺¹)
96
+ uᵢⁿ⁺¹ = ifelse (τ == 0 , ūⁿ⁺¹, relaxed_uᵢⁿ⁺¹)
93
97
94
- @inbounds setindex! (u, uᵢⁿ⁺¹, boundary_indices ... )
98
+ @inbounds setindex! (u, uᵢⁿ⁺¹, iᴮ, jᴮ, kᴮ )
95
99
96
100
return nothing
97
101
end
98
102
99
- @inline function step_left_boundary! (bc:: PAOBC , l, m, boundary_indices, boundary_adjacent_indices, boundary_secret_storage_indices,
103
+ @inline function step_left_boundary! (bc:: PAOBC , l, m, boundary_indices, boundary_adjacent_indices,
100
104
grid, u, clock, model_fields, ΔX)
105
+ iᴮ, jᴮ, kᴮ = boundary_indices
106
+ iᴬ, jᴬ, kᴬ = boundary_adjacent_indices
101
107
Δt = clock. last_stage_Δt
102
108
Δt = ifelse (isinf (Δt), 0 , Δt)
103
109
104
- ūⁿ⁺¹ = getbc (bc, l, m, grid, clock, model_fields)
105
- uᵢⁿ = @inbounds getindex (u, boundary_secret_storage_indices ... )
106
- uᵢ₋₁ⁿ⁺¹ = @inbounds getindex (u, boundary_adjacent_indices ... )
110
+ ūⁿ⁺¹ = getbc (bc, l, m, grid, clock, model_fields)
111
+ uᵢⁿ = @inbounds getindex (u, iᴮ, jᴮ, kᴮ )
112
+ uᵢ₋₁ⁿ⁺¹ = @inbounds getindex (u, iᴬ, jᴬ, kᴬ )
107
113
U = min (0 , max (- 1 , Δt / ΔX * ūⁿ⁺¹))
108
114
109
115
pa = bc. classification. matching_scheme
110
116
τ = ifelse (ūⁿ⁺¹ <= 0 , pa. outflow_timescale, pa. inflow_timescale)
111
- τ̃ = Δt / τ
117
+ τ̃ = Δt / τ # last stage Δt normalized by the inflow/output timescale
112
118
113
119
relaxed_u₁ⁿ⁺¹ = (uᵢⁿ - U * uᵢ₋₁ⁿ⁺¹ + ūⁿ⁺¹ * τ̃) / (1 + τ̃ - U)
114
- u₁ⁿ⁺¹ = ifelse (τ == 0 , ūⁿ⁺¹, relaxed_u₁ⁿ⁺¹)
120
+ u₁ⁿ⁺¹ = ifelse (τ == 0 , ūⁿ⁺¹, relaxed_u₁ⁿ⁺¹)
115
121
116
- @inbounds setindex! (u, u₁ⁿ⁺¹, boundary_indices... )
117
- @inbounds setindex! (u, u₁ⁿ⁺¹, boundary_secret_storage_indices... )
122
+ @inbounds setindex! (u, u₁ⁿ⁺¹, iᴮ, jᴮ, kᴮ)
118
123
119
124
return nothing
120
125
end
134
139
@inline function _fill_west_halo! (j, k, grid, u, bc:: PAOBC , :: Tuple{Face, Any, Any} , clock, model_fields)
135
140
boundary_indices = (1 , j, k)
136
141
boundary_adjacent_indices = (2 , j, k)
137
- boundary_secret_storage_indices = (0 , j, k)
138
142
139
143
Δx = Δxᶠᶜᶜ (1 , j, k, grid)
140
-
141
- step_left_boundary! (bc, j, k, boundary_indices, boundary_adjacent_indices, boundary_secret_storage_indices, grid, u, clock, model_fields, Δx)
144
+ step_left_boundary! (bc, j, k, boundary_indices, boundary_adjacent_indices, grid, u, clock, model_fields, Δx)
142
145
143
146
return nothing
144
147
end
149
152
boundary_adjacent_indices = (i, j- 1 , k)
150
153
151
154
Δy = Δyᶜᶠᶜ (i, j, k, grid)
152
-
153
155
step_right_boundary! (bc, i, k, boundary_indices, boundary_adjacent_indices, grid, u, clock, model_fields, Δy)
154
156
155
157
return nothing
158
160
@inline function _fill_south_halo! (i, k, grid, u, bc:: PAOBC , :: Tuple{Any, Face, Any} , clock, model_fields)
159
161
boundary_indices = (i, 1 , k)
160
162
boundary_adjacent_indices = (i, 2 , k)
161
- boundary_secret_storage_indices = (i, 0 , k)
162
163
163
164
Δy = Δyᶜᶠᶜ (i, 1 , k, grid)
164
-
165
- step_left_boundary! (bc, i, k, boundary_indices, boundary_adjacent_indices, boundary_secret_storage_indices, grid, u, clock, model_fields, Δy)
165
+ step_left_boundary! (bc, i, k, boundary_indices, boundary_adjacent_indices, grid, u, clock, model_fields, Δy)
166
166
167
167
return nothing
168
168
end
173
173
boundary_adjacent_indices = (i, j, k- 1 )
174
174
175
175
Δz = Δzᶜᶜᶠ (i, j, k, grid)
176
-
177
176
step_right_boundary! (bc, i, j, boundary_indices, boundary_adjacent_indices, grid, u, clock, model_fields, Δz)
178
177
179
178
return nothing
182
181
@inline function _fill_bottom_halo! (i, j, grid, u, bc:: PAOBC , :: Tuple{Any, Any, Face} , clock, model_fields)
183
182
boundary_indices = (i, j, 1 )
184
183
boundary_adjacent_indices = (i, j, 2 )
185
- boundary_secret_storage_indices = (i, j, 0 )
186
184
187
185
Δz = Δzᶜᶜᶠ (i, j, 1 , grid)
188
-
189
- step_left_boundary! (bc, i, j, boundary_indices, boundary_adjacent_indices, boundary_secret_storage_indices, grid, u, clock, model_fields, Δz)
186
+ step_left_boundary! (bc, i, j, boundary_indices, boundary_adjacent_indices, grid, u, clock, model_fields, Δz)
190
187
191
188
return nothing
192
189
end
0 commit comments