@@ -12,6 +12,11 @@ function limit(q, dt, n::Int)
12
12
return q / dt / n
13
13
end
14
14
15
+ # the triangle inequality limiter used in ClimaAtmos
16
+ function triangle_inequality_limiter (force, limit)
17
+ return force + limit - sqrt (force^ 2 + limit^ 2 )
18
+ end
19
+
15
20
function aerosol_activation (:: Empty , state)
16
21
FT = eltype (state)
17
22
return FT (0 )
@@ -249,19 +254,29 @@ end
249
254
function condensation (params:: NonEqCondParams , PSD, state, ρ_air)
250
255
FT = eltype (state)
251
256
(; T, qₗ, qᵥ, qᵢ) = state
252
- (; tps, liquid, dt) = params
253
257
254
- q = TD. PhasePartition (qᵥ + qₗ + qᵢ, qₗ, qᵢ)
258
+ (; tps, liquid, limiter, dt) = params
259
+
260
+ qₜ = qᵥ + qₗ + qᵢ
255
261
256
- cond_rate = MNE. conv_q_vap_to_q_liq_ice_MM2015 (liquid, tps, q , FT (0 ), FT (0 ), ρ_air, T)
262
+ cond_rate = MNE. conv_q_vap_to_q_liq_ice_MM2015 (liquid, tps, qₜ, qₗ, qᵢ , FT (0 ), FT (0 ), ρ_air, T)
257
263
258
- # Using same limiter as ClimaAtmos for now
259
- # Not sure why, but without intermediate storing of the tendencies for the
260
- # if/else branch this code segfaults on julia v1.11 (works fine on v1.10)
261
- cond_limit = min (cond_rate, limit (qᵥ, dt, 1 ))
262
- evap_limit = min (abs (cond_rate), limit (qₗ, dt, 1 ))
263
- ret = ifelse (cond_rate > FT (0 ), cond_limit, - 1 * evap_limit)
264
- return ret
264
+ # Using same limiter as ClimaAtmos
265
+ if limiter
266
+ # Not sure why, but without intermediate storing of the tendencies for the
267
+ # if/else branch this code segfaults on julia v1.11 (works fine on v1.10)
268
+
269
+ cond_limit = min (cond_rate, limit (qᵥ, dt, 1 ))
270
+ evap_limit = min (abs (cond_rate), limit (qₗ, dt, 1 ))
271
+
272
+ return ifelse (
273
+ cond_rate > FT (0 ),
274
+ triangle_inequality_limiter (cond_rate, cond_limit),
275
+ - triangle_inequality_limiter (abs (cond_rate), evap_limit),
276
+ )
277
+ else
278
+ return cond_rate
279
+ end
265
280
end
266
281
267
282
function deposition (:: Empty , PSD_ice, state, ρ_air)
@@ -302,17 +317,24 @@ function deposition(params::NonEqDepParams, PSD, state, ρ_air)
302
317
FT = eltype (state)
303
318
(; T, qₗ, qᵥ, qᵢ) = state
304
319
305
- (; tps, ice, dt) = params
320
+ (; tps, ice, limiter, dt) = params
306
321
307
- q = TD . PhasePartition ( qᵥ + qₗ + qᵢ, qₗ, qᵢ)
322
+ qₜ = qᵥ + qₗ + qᵢ
308
323
309
- dep_rate = MNE. conv_q_vap_to_q_liq_ice_MM2015 (ice, tps, q , FT (0 ), FT (0 ), ρ_air, T)
324
+ dep_rate = MNE. conv_q_vap_to_q_liq_ice_MM2015 (ice, tps, qₜ, qₗ, qᵢ , FT (0 ), FT (0 ), ρ_air, T)
310
325
311
- # Using same limiter as ClimaAtmos for now
312
- # Not sure why, but without intermediate storing of the tendencies for the
313
- # if/else branch this code segfaults on julia v1.11 (works fine on v1.10)
314
- dep_limit = min (dep_rate, limit (qᵥ, dt, 1 ))
315
- sub_limit = min (abs (dep_rate), limit (qᵢ, dt, 1 ))
316
- ret = ifelse (dep_rate > FT (0 ), dep_limit, - 1 * sub_limit)
317
- return ret
326
+ # using same limiter as ClimaAtmos for now
327
+ if limiter
328
+ # Not sure why, but without intermediate storing of the tendencies for the
329
+ # if/else branch this code segfaults on julia v1.11 (works fine on v1.10)
330
+ dep_limit = min (dep_rate, limit (qᵥ, dt, 1 ))
331
+ sub_limit = min (abs (dep_rate), limit (qᵢ, dt, 1 ))
332
+ return ifelse (
333
+ dep_rate > FT (0 ),
334
+ triangle_inequality_limiter (dep_rate, dep_limit),
335
+ - triangle_inequality_limiter (abs (dep_rate), sub_limit),
336
+ )
337
+ else
338
+ return dep_rate
339
+ end
318
340
end
0 commit comments