@@ -233,8 +233,6 @@ def __init__(self, equation, saturation_curve,
233
233
# Check for the correct fields
234
234
assert vapour_name in equation .field_names , f"Field { vapour_name } does not exist in the equation set"
235
235
assert cloud_name in equation .field_names , f"Field { cloud_name } does not exist in the equation set"
236
- self .Vv_idx = equation .field_names .index (vapour_name )
237
- self .Vc_idx = equation .field_names .index (cloud_name )
238
236
239
237
if self .convective_feedback :
240
238
assert "D" in equation .field_names , "Depth field must exist for convective feedback"
@@ -244,28 +242,29 @@ def __init__(self, equation, saturation_curve,
244
242
assert "b" in equation .field_names , "Buoyancy field must exist for thermal feedback"
245
243
assert beta2 is not None , "If thermal feedback is used, beta2 parameter must be specified"
246
244
247
- # Obtain function spaces and functions
245
+ # Obtain function spaces
248
246
W = equation .function_space
247
+ self .Vv_idx = equation .field_names .index (vapour_name )
248
+ self .Vc_idx = equation .field_names .index (cloud_name )
249
249
Vv = W .sub (self .Vv_idx )
250
250
Vc = W .sub (self .Vc_idx )
251
+ # order for V_idxs is vapour, cloud
251
252
V_idxs = [self .Vv_idx , self .Vc_idx ]
252
253
253
- # Source functions for both vapour and cloud
254
- self .water_v = Function (Vv )
255
- self .cloud = Function (Vc )
256
-
257
254
# depth needed if convective feedback
258
255
if self .convective_feedback :
259
256
self .VD_idx = equation .field_names .index ("D" )
260
257
VD = W .sub (self .VD_idx )
261
258
self .D = Function (VD )
259
+ # order for V_idxs is now vapour, cloud, depth
262
260
V_idxs .append (self .VD_idx )
263
261
264
262
# buoyancy needed if thermal feedback
265
263
if self .thermal_feedback :
266
264
self .Vb_idx = equation .field_names .index ("b" )
267
265
Vb = W .sub (self .Vb_idx )
268
266
self .b = Function (Vb )
267
+ # order for V_idxs is now vapour, cloud, depth, buoyancy
269
268
V_idxs .append (self .Vb_idx )
270
269
271
270
# tau is the timescale for condensation/evaporation (may or may not be the timestep)
@@ -289,6 +288,8 @@ def __init__(self, equation, saturation_curve,
289
288
self .saturation_curve = saturation_curve
290
289
291
290
# Saturation adjustment expression, adjusted to stop negative values
291
+ self .water_v = Function (Vv )
292
+ self .cloud = Function (Vc )
292
293
sat_adj_expr = (self .water_v - self .saturation_curve ) / self .tau
293
294
sat_adj_expr = conditional (sat_adj_expr < 0 ,
294
295
max_value (sat_adj_expr ,
@@ -309,17 +310,22 @@ def __init__(self, equation, saturation_curve,
309
310
self .gamma_v = gamma_v
310
311
311
312
# Factors for multiplying source for different variables
313
+ # the order matches the order in V_idx (vapour, cloud, depth, buoyancy)
312
314
factors = [self .gamma_v , - self .gamma_v ]
313
315
if convective_feedback :
314
316
factors .append (self .gamma_v * beta1 )
315
317
if thermal_feedback :
316
318
factors .append (self .gamma_v * beta2 )
317
319
318
320
# Add terms to equations and make interpolators
321
+ # sources have the same order as V_idxs and factors
319
322
self .source = [Function (Vc ) for factor in factors ]
320
323
self .source_interpolators = [Interpolator (sat_adj_expr * factor , source )
321
324
for factor , source in zip (factors , self .source )]
322
325
326
+ # test functions have the same order as factors and sources (vapour,
327
+ # cloud, depth, buoyancy) so that the correct test function multiplies
328
+ # each source term
323
329
tests = [equation .tests [idx ] for idx in V_idxs ]
324
330
325
331
# Add source terms to residual
0 commit comments