33
33
'number_of_mpi_tasks' }
34
34
# Variable input types
35
35
_INPUT_TYPES = set (['in' , 'inout' ])
36
+ _OUTPUT_TYPES = set (['out' , 'inout' ])
36
37
37
38
# Include files to insert in the module preamble
38
39
_PHYS_VARS_PREAMBLE_INCS = ["cam_var_init_marks_decl.inc" ]
@@ -131,7 +132,7 @@ def write_init_files(cap_database, ic_names, registry_constituents, vars_init_va
131
132
132
133
# Gather all the host model variables that are required by
133
134
# any of the compiled CCPP physics suites.
134
- host_vars , constituent_set , retmsg = gather_ccpp_req_vars (cap_database , registry_constituents )
135
+ in_vars , out_vars , constituent_set , retmsg = gather_ccpp_req_vars (cap_database , registry_constituents )
135
136
136
137
# Quit now if there are missing variables
137
138
if retmsg :
@@ -173,13 +174,17 @@ def write_init_files(cap_database, ic_names, registry_constituents, vars_init_va
173
174
outfile .include (filepath )
174
175
# end for
175
176
177
+ all_req_vars = in_vars + out_vars
178
+ # Remove duplicates but preserve order for testing
179
+ unique_req_vars = list (OrderedDict .fromkeys (all_req_vars ))
180
+
176
181
# Write public parameters:
177
- retvals = write_ic_params (outfile , host_vars , ic_names , registry_constituents )
182
+ retvals = write_ic_params (outfile , unique_req_vars , ic_names , registry_constituents )
178
183
ic_names , ic_max_len , stdname_max_len = retvals
179
184
180
185
# Write initial condition arrays:
181
186
write_ic_arrays (outfile , ic_names , ic_max_len ,
182
- stdname_max_len , host_vars , registry_constituents )
187
+ stdname_max_len , unique_req_vars , registry_constituents )
183
188
184
189
# Add "contains" statement:
185
190
outfile .end_module_header ()
@@ -234,18 +239,19 @@ def write_init_files(cap_database, ic_names, registry_constituents, vars_init_va
234
239
# Grab the host dictionary from the database
235
240
host_dict = cap_database .host_model_dict ()
236
241
237
- # Collect imported host variables
238
- host_imports = collect_host_var_imports (host_vars , host_dict , constituent_set )
239
-
242
+ # Collect imported host variables for physics read
243
+ host_imports = collect_host_var_imports (in_vars , host_dict , constituent_set )
240
244
# Write physics_read_data subroutine:
241
- write_phys_read_subroutine (outfile , host_dict , host_vars , host_imports ,
245
+ write_phys_read_subroutine (outfile , host_dict , in_vars , host_imports ,
242
246
phys_check_fname_str , constituent_set ,
243
247
vars_init_value )
244
248
245
249
outfile .blank_line ()
246
250
251
+ # Collect imported host variables for physics check
252
+ host_imports = collect_host_var_imports (out_vars , host_dict , constituent_set )
247
253
# Write physics_check_data subroutine:
248
- write_phys_check_subroutine (outfile , host_dict , host_vars , host_imports ,
254
+ write_phys_check_subroutine (outfile , host_dict , out_vars , host_imports ,
249
255
phys_check_fname_str , constituent_set )
250
256
251
257
# --------------------------------------
@@ -315,7 +321,8 @@ def gather_ccpp_req_vars(cap_database, registry_constituents):
315
321
316
322
# Dictionary of all 'in' and 'inout' suite variables.
317
323
# Key is standard name, value is host-model or constituent variable
318
- req_vars = {}
324
+ in_vars = {}
325
+ out_vars = {}
319
326
missing_vars = set ()
320
327
constituent_vars = set ()
321
328
retmsg = ""
@@ -330,22 +337,31 @@ def gather_ccpp_req_vars(cap_database, registry_constituents):
330
337
intent = cvar .get_prop_value ('intent' )
331
338
is_const = cvar .get_prop_value ('advected' ) or cvar .get_prop_value ('constituent' )
332
339
if ((intent in _INPUT_TYPES ) and
333
- (stdname not in req_vars ) and
340
+ (stdname not in in_vars ) and
334
341
(stdname not in _EXCLUDED_STDNAMES )):
335
342
if is_const :
336
343
#Add variable to constituent set:
337
344
constituent_vars .add (stdname )
338
345
#Add variable to required variable list if it's not a registry constituent
339
346
if stdname not in registry_constituents :
340
- req_vars [stdname ] = cvar
347
+ in_vars [stdname ] = cvar
341
348
# end if
342
349
else :
343
350
# We need to work with the host model version of this variable
344
351
missing = _find_and_add_host_variable (stdname , host_dict ,
345
- req_vars )
352
+ in_vars )
346
353
missing_vars .update (missing )
347
354
# end if
348
- # end if (do not include output variables)
355
+ # end if (only input variables)
356
+ if ((intent in _OUTPUT_TYPES ) and
357
+ (stdname not in out_vars ) and
358
+ (stdname not in _EXCLUDED_STDNAMES )):
359
+ if not is_const :
360
+ missing = _find_and_add_host_variable (stdname , host_dict ,
361
+ out_vars )
362
+ # do nothing with missing variables
363
+ # end if
364
+ # end if (only output variables)
349
365
# end for (loop over call list)
350
366
# end for (loop over phases)
351
367
@@ -354,7 +370,7 @@ def gather_ccpp_req_vars(cap_database, registry_constituents):
354
370
retmsg = f"Error: Missing required host variables: { mvlist } "
355
371
# end if
356
372
# Return the required variables as a list
357
- return list (req_vars .values ()), constituent_vars , retmsg
373
+ return list (in_vars . values ()), list ( out_vars .values ()), constituent_vars , retmsg
358
374
359
375
##########################
360
376
#FORTRAN WRITING FUNCTIONS
@@ -1178,8 +1194,6 @@ def write_phys_read_subroutine(outfile, host_dict, host_vars, host_imports,
1178
1194
outfile .write ("end do" , 2 )
1179
1195
outfile .blank_line ()
1180
1196
1181
- # start default case steps:
1182
-
1183
1197
# End subroutine:
1184
1198
outfile .write ("end subroutine physics_read_data" , 1 )
1185
1199
@@ -1240,8 +1254,8 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports,
1240
1254
call_str += f"timestep, { var_locname } , '{ var_stdname } ', "
1241
1255
call_str += "min_difference, min_relative_value, is_first, diff_found)"
1242
1256
else :
1243
- call_str = f"call endrun('Cannot check status of { var_locname } '" + \
1244
- f"//', { reason } ') "
1257
+ # For check field, don't endrun
1258
+ call_str = f"! do nothing - ' { var_locname } ' can't be checked against a file because { reason } "
1245
1259
# end if
1246
1260
# Add string to dictionary:
1247
1261
call_string_dict [call_string_key ] = call_str
@@ -1376,7 +1390,7 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports,
1376
1390
"that they can be read from input file if need be:" , 3 )
1377
1391
outfile .write ("call ccpp_physics_suite_variables(suite_names" + \
1378
1392
"(suite_idx), ccpp_required_data, errmsg, errflg, " + \
1379
- "input_vars=.true ., output_vars=.false .)" , 4 )
1393
+ "input_vars=.false ., output_vars=.true .)" , 4 )
1380
1394
outfile .blank_line ()
1381
1395
1382
1396
# Loop over required variables:
@@ -1385,37 +1399,48 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports,
1385
1399
outfile .write ("do req_idx = 1, size(ccpp_required_data, 1)" , 3 )
1386
1400
outfile .blank_line ()
1387
1401
1388
- # First check if the required variable is a constituent
1389
- outfile .comment ("First check if the required variable is a constituent:" , 4 )
1390
- outfile .write ("call const_get_index(ccpp_required_data(req_idx), constituent_idx, abort=.false., warning=.false.)" , 4 )
1391
- outfile .write ("if (constituent_idx > -1) then" , 4 )
1392
- outfile .write ("cycle" , 5 )
1393
- outfile .write ("else" , 4 )
1394
- outfile .comment ("The required variable is not a constituent. Check if the variable was read from a file" , 5 )
1395
-
1396
1402
# Call input name search function:
1397
- outfile .comment ("Find IC file input name array index for required variable:" , 5 )
1398
- outfile .write ("call is_read_from_file(ccpp_required_data(req_idx), " + \
1399
- "is_read, stdnam_idx_out=name_idx)" , 5 )
1400
- outfile .write ("if (.not. is_read) then" , 5 )
1401
- outfile .write ("cycle" , 6 )
1402
- outfile .write ("end if" , 5 )
1403
+ outfile .comment ("Find IC file input name array index for required variable:" , 4 )
1404
+ outfile .write ("name_idx = find_input_name_idx(ccpp_required_data(req_idx), .true., constituent_idx)" , 4 )
1405
+
1406
+ # Start select-case statement:
1407
+ outfile .blank_line ()
1408
+ outfile .comment ("Check for special index values:" , 4 )
1409
+ outfile .write ("select case (name_idx)" , 4 )
1410
+ outfile .blank_line ()
1411
+
1412
+ # Skip constituent variables:
1413
+ outfile .write ("case (const_idx)" , 5 )
1414
+ outfile .blank_line ()
1415
+ outfile .comment ("If variable is a constituent, then do nothing. We'll handle these later" , 6 )
1416
+ outfile .blank_line ()
1417
+
1418
+ # Generate error message if required variable isn't found:
1419
+ outfile .write ("case (no_exist_idx)" , 5 )
1420
+ outfile .blank_line ()
1421
+ outfile .comment ("If the index for an output variable was not found, then do nothing. We won't try to check these." , 6 )
1422
+ outfile .blank_line ()
1423
+
1424
+ # start default case steps:
1425
+ outfile .write ("case default" , 5 )
1426
+ outfile .blank_line ()
1403
1427
1404
1428
# Generate "check_field" calls:
1405
- outfile .comment ("Check variable vs input check file:" , 5 )
1429
+ outfile .comment ("Check variable vs input check file:" , 6 )
1406
1430
outfile .blank_line ()
1407
- outfile .write ("select case (trim(phys_var_stdnames(name_idx)))" , 5 )
1431
+ outfile .write ("select case (trim(phys_var_stdnames(name_idx)))" , 6 )
1408
1432
for case_call , read_call in call_string_dict .items ():
1409
- outfile .write (case_call , 5 )
1410
- outfile .write (read_call , 6 )
1433
+ outfile .write (case_call , 6 )
1434
+ outfile .write (read_call , 7 )
1411
1435
outfile .blank_line ()
1412
- outfile .write ("end select !check variables" , 5 )
1413
- outfile .write ("if (diff_found) then" , 5 )
1414
- outfile .write ("overall_diff_found = .true." , 6 )
1415
- outfile .write ("end if" , 5 )
1416
- outfile .write ("end if !check if constituent" , 4 )
1436
+ outfile .write ("end select !check variables" , 6 )
1437
+ outfile .write ("if (diff_found) then" , 6 )
1438
+ outfile .write ("overall_diff_found = .true." , 7 )
1439
+ outfile .write ("end if" , 6 )
1417
1440
1418
1441
# End select case and required variables loop:
1442
+ outfile .write ("end select !special indices" , 4 )
1443
+ outfile .blank_line ()
1419
1444
outfile .write ("end do !Suite-required variables" , 3 )
1420
1445
outfile .blank_line ()
1421
1446
0 commit comments