From f042d740b7d58489ba0664c37acb7426c7a925b0 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Wed, 29 Jan 2025 03:17:01 +0000 Subject: [PATCH 01/10] Bug fix and exercise change in testing. --- scripts/metavar.py | 25 +++++++++++++++++++ test/var_compatibility_test/effr_diag.F90 | 3 ++- test/var_compatibility_test/effr_diag.meta | 8 ++++++ test/var_compatibility_test/effr_post.F90 | 3 ++- test/var_compatibility_test/effr_post.meta | 8 ++++++ test/var_compatibility_test/effr_pre.F90 | 3 ++- test/var_compatibility_test/effr_pre.meta | 8 ++++++ test/var_compatibility_test/test_host.F90 | 10 ++++++-- .../var_compatibility_test/test_host_data.F90 | 3 +++ .../test_host_data.meta | 21 ++++++++++++++++ test/var_compatibility_test/test_reports.py | 3 +++ 11 files changed, 90 insertions(+), 5 deletions(-) diff --git a/scripts/metavar.py b/scripts/metavar.py index b686453e..f997755f 100755 --- a/scripts/metavar.py +++ b/scripts/metavar.py @@ -1677,12 +1677,37 @@ def add_variable(self, newvar, run_env, exists_ok=False, gen_unique=False, context=newvar.context) # end if # end if + # Check if local_name exists in Group. If applicable, Create new + # variable with uniquie name. There are two instances when new names are + # created: + # - Same used in different DDTs. + # - Different using the same in a Group. + # During the Group analyze phase, is True. lname = newvar.get_prop_value('local_name') lvar = self.find_local_name(lname) if lvar is not None: + # Check if is part of a different DDT than . + # The API uses the full variable references when calling the Group Caps, + # and . + # Within the context of a full reference, it is allowable for local_names + # to be the same in different data containers. + newvar_callstr = newvar.call_string(self) + lvar_callstr = lvar.call_string(self) + if newvar_callstr and lvar_callstr: + if newvar_callstr != lvar_callstr: + if not gen_unique: + exists_ok = True + # end if + # end if + # end if if gen_unique: new_lname = self.new_internal_variable_name(prefix=lname) newvar = newvar.clone(new_lname) + # Local_name needs to be the local_name for the new + # internal variable, otherwise multiple instances of the same + # local_name in the Group cap will all be overwritten with the + # same local_name + lname = new_lname elif not exists_ok: errstr = 'Invalid local_name: {} already registered{}' cstr = context_string(lvar.source.context, with_comma=True) diff --git a/test/var_compatibility_test/effr_diag.F90 b/test/var_compatibility_test/effr_diag.F90 index 463b7be9..bfa8af38 100644 --- a/test/var_compatibility_test/effr_diag.F90 +++ b/test/var_compatibility_test/effr_diag.F90 @@ -27,9 +27,10 @@ end subroutine effr_diag_init !> \section arg_table_effr_diag_run Argument Table !! \htmlinclude arg_table_effr_diag_run.html !! - subroutine effr_diag_run( effrr_in, errmsg, errflg) + subroutine effr_diag_run( effrr_in, scalar_var, errmsg, errflg) real(kind_phys), intent(in) :: effrr_in(:,:) + real(kind_phys), intent(in) :: scalar_var character(len=512), intent(out) :: errmsg integer, intent(out) :: errflg !---------------------------------------------------------------- diff --git a/test/var_compatibility_test/effr_diag.meta b/test/var_compatibility_test/effr_diag.meta index 3a83e154..845b30b6 100644 --- a/test/var_compatibility_test/effr_diag.meta +++ b/test/var_compatibility_test/effr_diag.meta @@ -34,6 +34,14 @@ kind = kind_phys intent = in top_at_one = True +[ scalar_var ] + standard_name = scalar_variable_for_testing_c + long_name = unused scalar variable C + units = m + dimensions = () + type = real + kind = kind_phys + intent = in [ errmsg ] standard_name = ccpp_error_message long_name = Error message for error handling in CCPP diff --git a/test/var_compatibility_test/effr_post.F90 b/test/var_compatibility_test/effr_post.F90 index c40b5df5..d6f5e523 100644 --- a/test/var_compatibility_test/effr_post.F90 +++ b/test/var_compatibility_test/effr_post.F90 @@ -27,9 +27,10 @@ end subroutine effr_post_init !> \section arg_table_effr_post_run Argument Table !! \htmlinclude arg_table_effr_post_run.html !! - subroutine effr_post_run( effrr_inout, errmsg, errflg) + subroutine effr_post_run( effrr_inout, scalar_var, errmsg, errflg) real(kind_phys), intent(inout) :: effrr_inout(:,:) + real(kind_phys), intent(in) :: scalar_var character(len=512), intent(out) :: errmsg integer, intent(out) :: errflg !---------------------------------------------------------------- diff --git a/test/var_compatibility_test/effr_post.meta b/test/var_compatibility_test/effr_post.meta index 2440a86e..e41625d0 100644 --- a/test/var_compatibility_test/effr_post.meta +++ b/test/var_compatibility_test/effr_post.meta @@ -33,6 +33,14 @@ type = real kind = kind_phys intent = inout +[ scalar_var ] + standard_name = scalar_variable_for_testing_b + long_name = unused scalar variable B + units = m + dimensions = () + type = real + kind = kind_phys + intent = in [ errmsg ] standard_name = ccpp_error_message long_name = Error message for error handling in CCPP diff --git a/test/var_compatibility_test/effr_pre.F90 b/test/var_compatibility_test/effr_pre.F90 index c744f1fc..0e4f840a 100644 --- a/test/var_compatibility_test/effr_pre.F90 +++ b/test/var_compatibility_test/effr_pre.F90 @@ -26,9 +26,10 @@ end subroutine effr_pre_init !> \section arg_table_effr_pre_run Argument Table !! \htmlinclude arg_table_effr_pre_run.html !! - subroutine effr_pre_run( effrr_inout, errmsg, errflg) + subroutine effr_pre_run( effrr_inout, scalar_var, errmsg, errflg) real(kind_phys), intent(inout) :: effrr_inout(:,:) + real(kind_phys), intent(in) :: scalar_var character(len=512), intent(out) :: errmsg integer, intent(out) :: errflg !---------------------------------------------------------------- diff --git a/test/var_compatibility_test/effr_pre.meta b/test/var_compatibility_test/effr_pre.meta index b24e8db6..c9fe2caa 100644 --- a/test/var_compatibility_test/effr_pre.meta +++ b/test/var_compatibility_test/effr_pre.meta @@ -33,6 +33,14 @@ type = real kind = kind_phys intent = inout +[ scalar_var ] + standard_name = scalar_variable_for_testing_a + long_name = unused scalar variable A + units = m + dimensions = () + type = real + kind = kind_phys + intent = in [ errmsg ] standard_name = ccpp_error_message long_name = Error message for error handling in CCPP diff --git a/test/var_compatibility_test/test_host.F90 b/test/var_compatibility_test/test_host.F90 index 3bb50da4..bbd77641 100644 --- a/test/var_compatibility_test/test_host.F90 +++ b/test/var_compatibility_test/test_host.F90 @@ -351,13 +351,16 @@ program test character(len=cs), target :: test_parts1(1) = (/ 'radiation ' /) - character(len=cm), target :: test_invars1(8) = (/ & + character(len=cm), target :: test_invars1(11) = (/ & 'effective_radius_of_stratiform_cloud_rain_particle ', & 'effective_radius_of_stratiform_cloud_liquid_water_particle', & 'effective_radius_of_stratiform_cloud_snow_particle ', & 'effective_radius_of_stratiform_cloud_graupel ', & 'cloud_graupel_number_concentration ', & 'scalar_variable_for_testing ', & + 'scalar_variable_for_testing_a ', & + 'scalar_variable_for_testing_b ', & + 'scalar_variable_for_testing_c ', & 'flag_indicating_cloud_microphysics_has_graupel ', & 'flag_indicating_cloud_microphysics_has_ice '/) @@ -371,7 +374,7 @@ program test 'cloud_ice_number_concentration ', & 'scalar_variable_for_testing ' /) - character(len=cm), target :: test_reqvars1(12) = (/ & + character(len=cm), target :: test_reqvars1(15) = (/ & 'ccpp_error_code ', & 'ccpp_error_message ', & 'effective_radius_of_stratiform_cloud_rain_particle ', & @@ -382,6 +385,9 @@ program test 'cloud_graupel_number_concentration ', & 'cloud_ice_number_concentration ', & 'scalar_variable_for_testing ', & + 'scalar_variable_for_testing_a ', & + 'scalar_variable_for_testing_b ', & + 'scalar_variable_for_testing_c ', & 'flag_indicating_cloud_microphysics_has_graupel ', & 'flag_indicating_cloud_microphysics_has_ice '/) diff --git a/test/var_compatibility_test/test_host_data.F90 b/test/var_compatibility_test/test_host_data.F90 index 9d0ca306..8c40ec5d 100644 --- a/test/var_compatibility_test/test_host_data.F90 +++ b/test/var_compatibility_test/test_host_data.F90 @@ -13,6 +13,9 @@ module test_host_data ncg, & ! number concentration of cloud graupel nci ! number concentration of cloud ice real(kind_phys) :: scalar_var + real(kind_phys) :: scalar_varA + real(kind_phys) :: scalar_varB + real(kind_phys) :: scalar_varC end type physics_state public allocate_physics_state diff --git a/test/var_compatibility_test/test_host_data.meta b/test/var_compatibility_test/test_host_data.meta index d3bca89b..5a209277 100644 --- a/test/var_compatibility_test/test_host_data.meta +++ b/test/var_compatibility_test/test_host_data.meta @@ -59,3 +59,24 @@ dimensions = () type = real kind = kind_phys +[scalar_varA] + standard_name = scalar_variable_for_testing_a + long_name = unused scalar variable A + units = m + dimensions = () + type = real + kind = kind_phys +[scalar_varB] + standard_name = scalar_variable_for_testing_b + long_name = unused scalar variable B + units = m + dimensions = () + type = real + kind = kind_phys +[scalar_varC] + standard_name = scalar_variable_for_testing_c + long_name = unused scalar variable C + units = m + dimensions = () + type = real + kind = kind_phys \ No newline at end of file diff --git a/test/var_compatibility_test/test_reports.py b/test/var_compatibility_test/test_reports.py index 6f10fc6d..23dddb29 100755 --- a/test/var_compatibility_test/test_reports.py +++ b/test/var_compatibility_test/test_reports.py @@ -74,6 +74,9 @@ def usage(errmsg=None): "effective_radius_of_stratiform_cloud_graupel", "cloud_graupel_number_concentration", "scalar_variable_for_testing", + "scalar_variable_for_testing_a", + "scalar_variable_for_testing_b", + "scalar_variable_for_testing_c", "flag_indicating_cloud_microphysics_has_graupel", "flag_indicating_cloud_microphysics_has_ice"] _OUTPUT_VARS_VAR_ACTION = ["ccpp_error_code", "ccpp_error_message", From f2df25826a1c61971f9a68e9a152f2ae3853af29 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Wed, 29 Jan 2025 03:34:40 +0000 Subject: [PATCH 02/10] Omission from previous commit --- test/var_compatibility_test/run_test | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/var_compatibility_test/run_test b/test/var_compatibility_test/run_test index 5a1d6b5c..dabd3e4d 100755 --- a/test/var_compatibility_test/run_test +++ b/test/var_compatibility_test/run_test @@ -144,6 +144,9 @@ required_vars_var_compatibility="${required_vars_var_compatibility},horizontal_d required_vars_var_compatibility="${required_vars_var_compatibility},horizontal_loop_begin" required_vars_var_compatibility="${required_vars_var_compatibility},horizontal_loop_end" required_vars_var_compatibility="${required_vars_var_compatibility},scalar_variable_for_testing" +required_vars_var_compatibility="${required_vars_var_compatibility},scalar_variable_for_testing_a" +required_vars_var_compatibility="${required_vars_var_compatibility},scalar_variable_for_testing_b" +required_vars_var_compatibility="${required_vars_var_compatibility},scalar_variable_for_testing_c" required_vars_var_compatibility="${required_vars_var_compatibility},vertical_layer_dimension" input_vars_var_compatibility="cloud_graupel_number_concentration" #input_vars_var_compatibility="${input_vars_var_compatibility},cloud_ice_number_concentration" @@ -157,6 +160,9 @@ input_vars_var_compatibility="${input_vars_var_compatibility},horizontal_dimensi input_vars_var_compatibility="${input_vars_var_compatibility},horizontal_loop_begin" input_vars_var_compatibility="${input_vars_var_compatibility},horizontal_loop_end" input_vars_var_compatibility="${input_vars_var_compatibility},scalar_variable_for_testing" +input_vars_var_compatibility="${input_vars_var_compatibility},scalar_variable_for_testing_a" +input_vars_var_compatibility="${input_vars_var_compatibility},scalar_variable_for_testing_b" +input_vars_var_compatibility="${input_vars_var_compatibility},scalar_variable_for_testing_c" input_vars_var_compatibility="${input_vars_var_compatibility},vertical_layer_dimension" output_vars_var_compatibility="ccpp_error_code,ccpp_error_message" output_vars_var_compatibility="${output_vars_var_compatibility},cloud_ice_number_concentration" From 421e0260c090ff122b31fbdad8cb6dad12d83c5c Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Wed, 29 Jan 2025 21:04:35 +0000 Subject: [PATCH 03/10] Fix subcycling and add test --- scripts/ccpp_datafile.py | 2 +- scripts/suite_objects.py | 13 ++++++------- .../var_compatibility_suite.xml | 4 +++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/scripts/ccpp_datafile.py b/scripts/ccpp_datafile.py index 6bb5e537..605dc053 100755 --- a/scripts/ccpp_datafile.py +++ b/scripts/ccpp_datafile.py @@ -1096,7 +1096,7 @@ def _add_suite_object(parent, suite_object): obj_elem.set("dimension_name", suite_object.dimension_name) # end if if isinstance(suite_object, Subcycle): - obj_elem.set("loop", suite_object.loop) + obj_elem.set("loop", suite_object._loop) # end if for obj_part in suite_object.parts: _add_suite_object(obj_elem, obj_part) diff --git a/scripts/suite_objects.py b/scripts/suite_objects.py index 7317e75d..80f75e96 100755 --- a/scripts/suite_objects.py +++ b/scripts/suite_objects.py @@ -2006,12 +2006,11 @@ def analyze(self, phase, group, scheme_library, suite_vars, level): if self.name is None: self.name = "subcycle_index{}".format(level) # end if - # Create a variable for the loop index - self.add_variable(Var({'local_name':self.name, - 'standard_name':'loop_variable', - 'type':'integer', 'units':'count', - 'dimensions':'()'}, _API_SOURCE, self.run_env), - self.run_env) + # Create a Group variable for the subcycle index. + newvar = Var({'local_name':self.name, 'standard_name':self.name, + 'type':'integer', 'units':'count', 'dimensions':'()'}, + _API_LOCAL, self.run_env) + group.manage_variable(newvar) # Handle all the suite objects inside of this subcycle scheme_mods = set() for item in self.parts: @@ -2025,7 +2024,7 @@ def analyze(self, phase, group, scheme_library, suite_vars, level): def write(self, outfile, errcode, errmsg, indent): """Write code for the subcycle loop, including contents, to """ - outfile.write('do {} = 1, {}'.format(self.name, self.loop), indent) + outfile.write('do {} = 1, {}'.format(self.name, self._loop), indent) # Note that 'scheme' may be a sybcycle or other construct for item in self.parts: item.write(outfile, errcode, errmsg, indent+1) diff --git a/test/var_compatibility_test/var_compatibility_suite.xml b/test/var_compatibility_test/var_compatibility_suite.xml index 5956a8bd..58262ea3 100644 --- a/test/var_compatibility_test/var_compatibility_suite.xml +++ b/test/var_compatibility_test/var_compatibility_suite.xml @@ -5,6 +5,8 @@ effr_pre effr_calc effr_post - effr_diag + + effr_diag + From 9d9a04f221ac81650e325b6a5bb50ecb6d53ed84 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Wed, 29 Jan 2025 22:30:09 +0000 Subject: [PATCH 04/10] Remove sorting of suite part list --- scripts/ccpp_suite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ccpp_suite.py b/scripts/ccpp_suite.py index b3225573..12873c26 100644 --- a/scripts/ccpp_suite.py +++ b/scripts/ccpp_suite.py @@ -759,7 +759,7 @@ def write_var_set_loop(ofile, varlist_name, var_list, indent, ofile.write("allocate({}({}))".format(varlist_name, len(var_list)), indent) # end if - for ind, var in enumerate(sorted(var_list)): + for ind, var in enumerate(var_list): if start_var: ind_str = "{} + {}".format(start_var, ind + start_index) else: From 44f39e15689f1613dfe4baea80689eda72b72ec5 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Wed, 29 Jan 2025 23:07:52 +0000 Subject: [PATCH 05/10] Address reviewers comments --- scripts/metavar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/metavar.py b/scripts/metavar.py index f997755f..9a502127 100755 --- a/scripts/metavar.py +++ b/scripts/metavar.py @@ -1677,8 +1677,8 @@ def add_variable(self, newvar, run_env, exists_ok=False, gen_unique=False, context=newvar.context) # end if # end if - # Check if local_name exists in Group. If applicable, Create new - # variable with uniquie name. There are two instances when new names are + # Check if local_name exists in Group. If applicable, create new + # variable with unique name. There are two instances when new names are # created: # - Same used in different DDTs. # - Different using the same in a Group. From 1fe9f2e2bb8cdeb1c5b0248fb2b93f5a4a2f8fb8 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Thu, 30 Jan 2025 02:29:45 +0000 Subject: [PATCH 06/10] Exercise subcycling in var_compatability test --- test/var_compatibility_test/effr_calc.F90 | 2 +- test/var_compatibility_test/var_compatibility_suite.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/var_compatibility_test/effr_calc.F90 b/test/var_compatibility_test/effr_calc.F90 index 1b075a3c..b43be673 100644 --- a/test/var_compatibility_test/effr_calc.F90 +++ b/test/var_compatibility_test/effr_calc.F90 @@ -72,7 +72,7 @@ subroutine effr_calc_run(ncol, nlev, effrr_in, effrg_in, ncg_in, nci_out, & if (present(nci_out)) nci_out_local = nci_out effrl_inout = min(max(effrl_inout,re_qc_min),re_qc_max) if (present(effri_out)) effri_out = re_qi_avg - effrs_inout = effrs_inout + 10.0 ! in micrometer + effrs_inout = effrs_inout + 5.0 ! in micrometer scalar_var = 2.0 ! in km end subroutine effr_calc_run diff --git a/test/var_compatibility_test/var_compatibility_suite.xml b/test/var_compatibility_test/var_compatibility_suite.xml index 58262ea3..378ff181 100644 --- a/test/var_compatibility_test/var_compatibility_suite.xml +++ b/test/var_compatibility_test/var_compatibility_suite.xml @@ -3,10 +3,10 @@ effr_pre - effr_calc - effr_post - - effr_diag + + effr_calc + effr_post + effr_diag From dd2f30e6a918de4d77ba86c1156e90580d6ca462 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Tue, 4 Feb 2025 03:42:30 +0000 Subject: [PATCH 07/10] Change one test scalar to type int. --- test/var_compatibility_test/effr_diag.F90 | 2 +- test/var_compatibility_test/effr_diag.meta | 3 +-- test/var_compatibility_test/test_host_data.F90 | 2 +- test/var_compatibility_test/test_host_data.meta | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/test/var_compatibility_test/effr_diag.F90 b/test/var_compatibility_test/effr_diag.F90 index 0e998bee..c0cd4c5f 100644 --- a/test/var_compatibility_test/effr_diag.F90 +++ b/test/var_compatibility_test/effr_diag.F90 @@ -39,7 +39,7 @@ end subroutine effr_diag_init subroutine effr_diag_run( effrr_in, scalar_var, errmsg, errflg) real(kind_phys), intent(in) :: effrr_in(:,:) - real(kind_phys), intent(in) :: scalar_var + integer, intent(in) :: scalar_var character(len=512), intent(out) :: errmsg integer, intent(out) :: errflg !---------------------------------------------------------------- diff --git a/test/var_compatibility_test/effr_diag.meta b/test/var_compatibility_test/effr_diag.meta index f1541329..9e0e4fc2 100644 --- a/test/var_compatibility_test/effr_diag.meta +++ b/test/var_compatibility_test/effr_diag.meta @@ -46,8 +46,7 @@ long_name = unused scalar variable C units = m dimensions = () - type = real - kind = kind_phys + type = integer intent = in [ errmsg ] standard_name = ccpp_error_message diff --git a/test/var_compatibility_test/test_host_data.F90 b/test/var_compatibility_test/test_host_data.F90 index 2dcba006..6f351535 100644 --- a/test/var_compatibility_test/test_host_data.F90 +++ b/test/var_compatibility_test/test_host_data.F90 @@ -15,7 +15,7 @@ module test_host_data real(kind_phys) :: scalar_var real(kind_phys) :: scalar_varA real(kind_phys) :: scalar_varB - real(kind_phys) :: scalar_varC + integer :: scalar_varC integer :: scheme_order end type physics_state diff --git a/test/var_compatibility_test/test_host_data.meta b/test/var_compatibility_test/test_host_data.meta index 358b5f20..ba4b2297 100644 --- a/test/var_compatibility_test/test_host_data.meta +++ b/test/var_compatibility_test/test_host_data.meta @@ -78,8 +78,7 @@ long_name = unused scalar variable C units = m dimensions = () - type = real - kind = kind_phys + type = integer [scheme_order] standard_name = scheme_order_in_suite long_name = scheme order in suite definition file From 7cba200353e28996ee295e0406b4e3ede53d04b5 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Tue, 11 Feb 2025 03:57:18 +0000 Subject: [PATCH 08/10] Add modification for CAM-SIMA --- scripts/suite_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/suite_objects.py b/scripts/suite_objects.py index 4fac98b8..fb3a66c6 100755 --- a/scripts/suite_objects.py +++ b/scripts/suite_objects.py @@ -2273,7 +2273,7 @@ def manage_variable(self, newvar): ParseSource(_API_SOURCE_NAME, _API_LOCAL_VAR_NAME, newvar.context), self.run_env) - self.add_variable(local_var, self.run_env, exists_ok=True) + self.add_variable(local_var, self.run_env, exists_ok=True, gen_unique=True) # Finally, make sure all dimensions are accounted for emsg = self.add_variable_dimensions(local_var, _API_LOCAL_VAR_TYPES, adjust_intent=True, From 637921f03be129f60d2536bfd8f3ebc23dc98d45 Mon Sep 17 00:00:00 2001 From: Dustin Swales Date: Wed, 12 Feb 2025 17:58:18 +0000 Subject: [PATCH 09/10] Omission from previous commmit --- scripts/metavar.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/metavar.py b/scripts/metavar.py index 559d2670..66784e2e 100755 --- a/scripts/metavar.py +++ b/scripts/metavar.py @@ -1677,8 +1677,7 @@ def add_variable(self, newvar, run_env, exists_ok=False, gen_unique=False, context=newvar.context) # end if # end if - - # Check if local_name exists in Group. If applicable, create new + # Check if local_name exists in Group. If applicable, Create new # variable with unique name. There are two instances when new names are # created: # - Same used in different DDTs. From a76d60fe59ba2f3e6b66963217c12d19eb90651e Mon Sep 17 00:00:00 2001 From: Steve Goldhaber Date: Tue, 18 Feb 2025 22:15:24 +0100 Subject: [PATCH 10/10] Permit variables as loop variables A standard name can be used instead of a literal integer Modified the var_compatibility test to test both a literal integer subcycle and a loop variable subcycle. --- scripts/metavar.py | 8 ++-- scripts/suite_objects.py | 48 +++++++++---------- test/var_compatibility_test/effr_calc.F90 | 4 +- test/var_compatibility_test/run_test | 2 + test/var_compatibility_test/test_host.F90 | 8 ++-- .../var_compatibility_test/test_host_data.F90 | 3 ++ .../test_host_data.meta | 6 +++ test/var_compatibility_test/test_reports.py | 3 +- .../var_compatibility_suite.xml | 10 ++-- 9 files changed, 53 insertions(+), 39 deletions(-) diff --git a/scripts/metavar.py b/scripts/metavar.py index 66784e2e..8f283df6 100755 --- a/scripts/metavar.py +++ b/scripts/metavar.py @@ -1677,7 +1677,7 @@ def add_variable(self, newvar, run_env, exists_ok=False, gen_unique=False, context=newvar.context) # end if # end if - # Check if local_name exists in Group. If applicable, Create new + # Check if local_name exists in Group. If applicable, Create new # variable with unique name. There are two instances when new names are # created: # - Same used in different DDTs. @@ -1709,10 +1709,8 @@ def add_variable(self, newvar, run_env, exists_ok=False, gen_unique=False, # same local_name lname = new_lname elif not exists_ok: - errstr = 'Invalid local_name: {} already registered{}' - cstr = context_string(lvar.source.context, with_comma=True) - raise ParseSyntaxError(errstr.format(lname, cstr), - context=newvar.source.context) + errstr = f"Invalid local_name: {lname} already registered" + raise ParseSyntaxError(errstr, context=newvar.source.context) # end if (no else, things are okay) # end if (no else, things are okay) # Check if this variable has a parent (i.e., it is an array reference) diff --git a/scripts/suite_objects.py b/scripts/suite_objects.py index 5fcaeb90..13d2c6a2 100755 --- a/scripts/suite_objects.py +++ b/scripts/suite_objects.py @@ -142,7 +142,7 @@ def call_string(self, cldicts=None, is_func_call=False, subname=None, sub_lname_ raise CCPPError(errmsg.format(stdname, clnames)) # end if lname = dvar.get_prop_value('local_name') - # Optional variables in the caps are associated with + # Optional variables in the caps are associated with # local pointers of _ptr if dvar.get_prop_value('optional'): lname = dummy+'_ptr' @@ -1161,7 +1161,7 @@ def update_group_call_list_variable(self, var): gvar = None # end if if gvar is None: - my_group.add_call_list_variable(var) + my_group.add_call_list_variable(var, gen_unique=True) # end if # end if @@ -1219,7 +1219,7 @@ def analyze(self, phase, group, scheme_library, suite_vars, level): # end if # We have a match, make sure var is in call list if new_dims == vdims: - self.add_call_list_variable(var, exists_ok=True) + self.add_call_list_variable(var, exists_ok=True, gen_unique=True) self.update_group_call_list_variable(var) else: subst_dict = {'dimensions':new_dims} @@ -1461,7 +1461,7 @@ def write_var_debug_check(self, var, internal_var, cldicts, outfile, errcode, er local_name = dvar.get_prop_value('local_name') # If the variable is allocatable and the intent for the scheme is 'out', - # then we can't test anything because the scheme is going to allocate + # then we can't test anything because the scheme is going to allocate # the variable. We don't have this information earlier in # add_var_debug_check, therefore need to back out here, # using the information from the scheme variable (call list). @@ -1794,11 +1794,11 @@ def write(self, outfile, errcode, errmsg, indent): # if self.__optional_vars: outfile.write('! Associate conditional variables', indent+1) - # end if + # end if for (dict_var, var, var_ptr, has_transform) in self.__optional_vars: tstmt = self.associate_optional_var(dict_var, var, var_ptr, has_transform, cldicts, indent+1, outfile) # end for - # + # # Write the scheme call. # if self._has_run_phase: @@ -1813,7 +1813,7 @@ def write(self, outfile, errcode, errmsg, indent): # first_ptr_declaration=True for (dict_var, var, var_ptr, has_transform) in self.__optional_vars: - if first_ptr_declaration: + if first_ptr_declaration: outfile.write('! Copy any local pointers to dummy/local variables', indent+1) first_ptr_declaration=False # end if @@ -1977,23 +1977,29 @@ class Subcycle(SuiteObject): """Class to represent a subcycled group of schemes or scheme collections""" def __init__(self, sub_xml, context, parent, run_env): - name = sub_xml.get('name', None) # Iteration count - loop_extent = sub_xml.get('loop', "1") # Number of iterations + self._loop_extent = sub_xml.get('loop', "1") # Number of iterations + self._loop = None # See if our loop variable is an interger or a variable try: - loop_int = int(loop_extent) # pylint: disable=unused-variable - self._loop = loop_extent + _ = int(self._loop_extent) + self._loop = self._loop_extent self._loop_var_int = True + name = f"loop{self._loop}" + super().__init__(name, context, parent, run_env, active_call_list=False) except ValueError: self._loop_var_int = False - lvar = parent.find_variable(standard_name=self.loop, any_scope=True) + lvar = parent.find_variable(standard_name=self._loop_extent, any_scope=True) if lvar is None: - emsg = "Subcycle, {}, specifies {} iterations but {} not found" - raise CCPPError(emsg.format(name, self.loop, self.loop)) + emsg = "Subcycle, {}, specifies {} iterations, variable not found" + raise CCPPError(emsg.format(name, self._loop_extent)) + else: + self._loop_var_int = False + self._loop = lvar.get_prop_value('local_name') # end if + name = f"loop_{self._loop_extent}"[0:63] + super().__init__(name, context, parent, run_env, active_call_list=True) parent.add_call_list_variable(lvar) # end try - super().__init__(name, context, parent, run_env) for item in sub_xml: new_item = new_suite_object(item, context, self, run_env) self.add_part(new_item) @@ -2032,13 +2038,7 @@ def write(self, outfile, errcode, errmsg, indent): @property def loop(self): """Return the loop value or variable local_name""" - lvar = self.find_variable(standard_name=self.loop, any_scope=True) - if lvar is None: - emsg = "Subcycle, {}, specifies {} iterations but {} not found" - raise CCPPError(emsg.format(self.name, self.loop, self.loop)) - # end if - lname = lvar.get_prop_value('local_name') - return lname + return self._loop ############################################################################### @@ -2407,8 +2407,8 @@ def write(self, outfile, host_arglist, indent, const_mod, # end if # end if # end for - # All optional dummy variables within group need to have - # an associated pointer array declared. + # All optional dummy variables within group need to have + # an associated pointer array declared. for cvar in self.call_list.variable_list(): opt_var = cvar.get_prop_value('optional') if opt_var: diff --git a/test/var_compatibility_test/effr_calc.F90 b/test/var_compatibility_test/effr_calc.F90 index b43be673..0bef2949 100644 --- a/test/var_compatibility_test/effr_calc.F90 +++ b/test/var_compatibility_test/effr_calc.F90 @@ -31,7 +31,7 @@ subroutine effr_calc_init(scheme_order, errmsg, errflg) endif end subroutine effr_calc_init - + !> \section arg_table_effr_calc_run Argument Table !! \htmlinclude arg_table_effr_calc_run.html !! @@ -72,7 +72,7 @@ subroutine effr_calc_run(ncol, nlev, effrr_in, effrg_in, ncg_in, nci_out, & if (present(nci_out)) nci_out_local = nci_out effrl_inout = min(max(effrl_inout,re_qc_min),re_qc_max) if (present(effri_out)) effri_out = re_qi_avg - effrs_inout = effrs_inout + 5.0 ! in micrometer + effrs_inout = effrs_inout + (10.0 / 6.0) ! in micrometer scalar_var = 2.0 ! in km end subroutine effr_calc_run diff --git a/test/var_compatibility_test/run_test b/test/var_compatibility_test/run_test index b2fa0f90..0eb0e7dd 100755 --- a/test/var_compatibility_test/run_test +++ b/test/var_compatibility_test/run_test @@ -143,6 +143,7 @@ required_vars_var_compatibility="${required_vars_var_compatibility},flag_indicat required_vars_var_compatibility="${required_vars_var_compatibility},horizontal_dimension" required_vars_var_compatibility="${required_vars_var_compatibility},horizontal_loop_begin" required_vars_var_compatibility="${required_vars_var_compatibility},horizontal_loop_end" +required_vars_var_compatibility="${required_vars_var_compatibility},num_subcycles_for_effr" required_vars_var_compatibility="${required_vars_var_compatibility},scalar_variable_for_testing" required_vars_var_compatibility="${required_vars_var_compatibility},scalar_variable_for_testing_a" required_vars_var_compatibility="${required_vars_var_compatibility},scalar_variable_for_testing_b" @@ -160,6 +161,7 @@ input_vars_var_compatibility="${input_vars_var_compatibility},flag_indicating_cl input_vars_var_compatibility="${input_vars_var_compatibility},horizontal_dimension" input_vars_var_compatibility="${input_vars_var_compatibility},horizontal_loop_begin" input_vars_var_compatibility="${input_vars_var_compatibility},horizontal_loop_end" +input_vars_var_compatibility="${input_vars_var_compatibility},num_subcycles_for_effr" input_vars_var_compatibility="${input_vars_var_compatibility},scalar_variable_for_testing" input_vars_var_compatibility="${input_vars_var_compatibility},scalar_variable_for_testing_a" input_vars_var_compatibility="${input_vars_var_compatibility},scalar_variable_for_testing_b" diff --git a/test/var_compatibility_test/test_host.F90 b/test/var_compatibility_test/test_host.F90 index 14b80a60..5d7f2a4f 100644 --- a/test/var_compatibility_test/test_host.F90 +++ b/test/var_compatibility_test/test_host.F90 @@ -351,7 +351,7 @@ program test character(len=cs), target :: test_parts1(1) = (/ 'radiation ' /) - character(len=cm), target :: test_invars1(12) = (/ & + character(len=cm), target :: test_invars1(13) = (/ & 'effective_radius_of_stratiform_cloud_rain_particle ', & 'effective_radius_of_stratiform_cloud_liquid_water_particle', & 'effective_radius_of_stratiform_cloud_snow_particle ', & @@ -362,6 +362,7 @@ program test 'scalar_variable_for_testing_b ', & 'scalar_variable_for_testing_c ', & 'scheme_order_in_suite ', & + 'num_subcycles_for_effr ', & 'flag_indicating_cloud_microphysics_has_graupel ', & 'flag_indicating_cloud_microphysics_has_ice '/) @@ -375,9 +376,9 @@ program test 'cloud_ice_number_concentration ', & 'scalar_variable_for_testing ', & 'scheme_order_in_suite '/) - - character(len=cm), target :: test_reqvars1(16) = (/ & + + character(len=cm), target :: test_reqvars1(17) = (/ & 'ccpp_error_code ', & 'ccpp_error_message ', & 'effective_radius_of_stratiform_cloud_rain_particle ', & @@ -392,6 +393,7 @@ program test 'scalar_variable_for_testing_b ', & 'scalar_variable_for_testing_c ', & 'scheme_order_in_suite ', & + 'num_subcycles_for_effr ', & 'flag_indicating_cloud_microphysics_has_graupel ', & 'flag_indicating_cloud_microphysics_has_ice '/) diff --git a/test/var_compatibility_test/test_host_data.F90 b/test/var_compatibility_test/test_host_data.F90 index 6f351535..5754a093 100644 --- a/test/var_compatibility_test/test_host_data.F90 +++ b/test/var_compatibility_test/test_host_data.F90 @@ -17,6 +17,7 @@ module test_host_data real(kind_phys) :: scalar_varB integer :: scalar_varC integer :: scheme_order + integer :: num_subcycles end type physics_state @@ -69,6 +70,8 @@ subroutine allocate_physics_state(cols, levels, state, has_graupel, has_ice) ! Initialize scheme counter. state%scheme_order = 1 + ! Initialize subcycle counter. + state%num_subcycles = 3 end subroutine allocate_physics_state diff --git a/test/var_compatibility_test/test_host_data.meta b/test/var_compatibility_test/test_host_data.meta index ba4b2297..094f26d5 100644 --- a/test/var_compatibility_test/test_host_data.meta +++ b/test/var_compatibility_test/test_host_data.meta @@ -85,3 +85,9 @@ units = None dimensions = () type = integer +[num_subcycles] + standard_name = num_subcycles_for_effr + long_name = Number of times to subcycle the effr calculation + units = None + dimensions = () + type = integer diff --git a/test/var_compatibility_test/test_reports.py b/test/var_compatibility_test/test_reports.py index 47f8e33b..0eb7ef1c 100755 --- a/test/var_compatibility_test/test_reports.py +++ b/test/var_compatibility_test/test_reports.py @@ -79,7 +79,8 @@ def usage(errmsg=None): "scalar_variable_for_testing_c", "scheme_order_in_suite", "flag_indicating_cloud_microphysics_has_graupel", - "flag_indicating_cloud_microphysics_has_ice"] + "flag_indicating_cloud_microphysics_has_ice", + "num_subcycles_for_effr"] _OUTPUT_VARS_VAR_ACTION = ["ccpp_error_code", "ccpp_error_message", "effective_radius_of_stratiform_cloud_ice_particle", "effective_radius_of_stratiform_cloud_liquid_water_particle", diff --git a/test/var_compatibility_test/var_compatibility_suite.xml b/test/var_compatibility_test/var_compatibility_suite.xml index 378ff181..a5d4eb48 100644 --- a/test/var_compatibility_test/var_compatibility_suite.xml +++ b/test/var_compatibility_test/var_compatibility_suite.xml @@ -2,11 +2,13 @@ - effr_pre - - effr_calc + + effr_pre + + effr_calc + + effr_post - effr_post effr_diag