diff --git a/scripts/suite_objects.py b/scripts/suite_objects.py index 7100d479..15b40a65 100755 --- a/scripts/suite_objects.py +++ b/scripts/suite_objects.py @@ -52,12 +52,12 @@ 'suites':''}) ############################################################################### -def new_suite_object(item, context, parent, run_env): +def new_suite_object(item, context, parent, run_env, loop_count=0): ############################################################################### "'Factory' method to create the appropriate suite object from XML" new_item = None if item.tag == 'subcycle': - new_item = Subcycle(item, context, parent, run_env) + new_item = Subcycle(item, context, parent, run_env, loop_count=loop_count) elif item.tag == 'scheme': new_item = Scheme(item, context, parent, run_env) elif item.tag == _API_TIMESPLIT_TAG: @@ -1753,7 +1753,7 @@ def add_var_transform(self, var, compat_obj, vert_dim): self.run_env.logger.info(lmsg.format(compat_obj.v2_units, compat_obj.v1_units, compat_obj.v2_stdname, - compat_obj.v1_stdname)) + self.__subroutine_name)) self.__reverse_transforms.append([local_trans_var.get_prop_value('local_name'), var.get_prop_value('local_name'), var.get_prop_value('standard_name'), @@ -1765,7 +1765,7 @@ def add_var_transform(self, var, compat_obj, vert_dim): self.run_env.logger.info(lmsg.format(compat_obj.v1_units, compat_obj.v2_units, compat_obj.v1_stdname, - compat_obj.v2_stdname)) + self.__subroutine_name)) self.__forward_transforms.append([var.get_prop_value('local_name'), var.get_prop_value('standard_name'), local_trans_var.get_prop_value('local_name'), @@ -2039,16 +2039,17 @@ def dimension_name(self): class Subcycle(SuiteObject): """Class to represent a subcycled group of schemes or scheme collections""" - def __init__(self, sub_xml, context, parent, run_env): + def __init__(self, sub_xml, context, parent, run_env, loop_count=0): 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 + # See if our loop variable is an integer or a variable try: _ = int(self._loop_extent) self._loop = self._loop_extent self._loop_var_int = True - name = f"loop{self._loop}" + name = f"loop{loop_count}" super().__init__(name, context, parent, run_env, active_call_list=False) + loop_count = loop_count + 1 except ValueError: self._loop_var_int = False lvar = parent.find_variable(standard_name=self._loop_extent, any_scope=True) @@ -2059,12 +2060,13 @@ def __init__(self, sub_xml, context, parent, run_env): self._loop_var_int = False self._loop = lvar.get_prop_value('local_name') # end if - name = f"loop_{self._loop_extent}"[0:63] + name = f"loop{loop_count}_{self._loop_extent}"[0:63] super().__init__(name, context, parent, run_env, active_call_list=True) - parent.add_call_list_variable(lvar) + parent.add_call_list_variable(lvar, exists_ok=True) + loop_count = loop_count + 1 # end try for item in sub_xml: - new_item = new_suite_object(item, context, self, run_env) + new_item = new_suite_object(item, context, self, run_env, loop_count=loop_count) self.add_part(new_item) # end for diff --git a/test/var_compatibility_test/CMakeLists.txt b/test/var_compatibility_test/CMakeLists.txt index 9204498d..79ca1b3e 100644 --- a/test/var_compatibility_test/CMakeLists.txt +++ b/test/var_compatibility_test/CMakeLists.txt @@ -5,7 +5,7 @@ # Paths should be relative to CMAKE_SOURCE_DIR (this file's directory) # #------------------------------------------------------------------------------ -set(SCHEME_FILES "effr_calc" "effr_diag" "effr_pre" "effr_post" "rad_lw" "rad_sw") +set(SCHEME_FILES "effr_calc" "effrs_calc" "effr_diag" "effr_pre" "effr_post" "rad_lw" "rad_sw") set(HOST_FILES "module_rad_ddt" "test_host_data" "test_host_mod") set(SUITE_FILES "var_compatibility_suite.xml") # HOST is the name of the executable we will build. diff --git a/test/var_compatibility_test/README.md b/test/var_compatibility_test/README.md index 4e589cd6..a8beecf2 100644 --- a/test/var_compatibility_test/README.md +++ b/test/var_compatibility_test/README.md @@ -5,6 +5,11 @@ Tests the variable compatibility object (`VarCompatObj`): - Vertical array flipping (`top_at_one=true`) - Kind conversions (`kind_phys <-> 8`) - And various combinations thereof of the above cases +- Also tests subcycles: + - Nested subcycles + - A subcycle with dynamic iteration length (defined by a standard name) and a subcycle with fixed/integer iteration length + - Multiple subcycles with same standard name defining the iteration length + - Nested subcycles with the same iteration length ## Building/Running diff --git a/test/var_compatibility_test/effrs_calc.F90 b/test/var_compatibility_test/effrs_calc.F90 new file mode 100644 index 00000000..e9266905 --- /dev/null +++ b/test/var_compatibility_test/effrs_calc.F90 @@ -0,0 +1,32 @@ +!Test unit conversions for intent in, inout, out variables +! + +module effrs_calc + + use ccpp_kinds, only: kind_phys + + implicit none + private + + public :: effrs_calc_run + + contains + !> \section arg_table_effrs_calc_run Argument Table + !! \htmlinclude arg_table_effrs_calc_run.html + !! + subroutine effrs_calc_run(effrs_inout, errmsg, errflg) + + real(kind_phys), intent(inout) :: effrs_inout(:,:) + character(len=512), intent(out) :: errmsg + integer, intent(out) :: errflg + + !---------------------------------------------------------------- + + errmsg = '' + errflg = 0 + + effrs_inout = effrs_inout + (10.E-6_kind_phys / 3._kind_phys) ! in meters + + end subroutine effrs_calc_run + +end module effrs_calc diff --git a/test/var_compatibility_test/effrs_calc.meta b/test/var_compatibility_test/effrs_calc.meta new file mode 100644 index 00000000..9ce7b88e --- /dev/null +++ b/test/var_compatibility_test/effrs_calc.meta @@ -0,0 +1,25 @@ +[ccpp-table-properties] + name = effrs_calc + type = scheme + +[ccpp-arg-table] + name = effrs_calc_run + type = scheme +[ effrs_inout ] + standard_name = effective_radius_of_stratiform_cloud_snow_particle + units = m + type = real | kind = kind_phys + dimensions = (horizontal_loop_extent,vertical_layer_dimension) + intent = inout +[ errmsg ] + standard_name = ccpp_error_message + units = none + type = character | kind = len=512 + dimensions = () + intent = out +[ errflg ] + standard_name = ccpp_error_code + units = 1 + type = integer + dimensions = () + intent = out diff --git a/test/var_compatibility_test/test_host_mod.F90 b/test/var_compatibility_test/test_host_mod.F90 index efaeb368..09d1fdb5 100644 --- a/test/var_compatibility_test/test_host_mod.F90 +++ b/test/var_compatibility_test/test_host_mod.F90 @@ -50,7 +50,7 @@ logical function compare_data() real(kind_phys), parameter :: effrr_expected = 1.0E-3 ! 1000 microns, in meter real(kind_phys), parameter :: effrl_expected = 5.0E-5 ! 50 microns, in meter real(kind_phys), parameter :: effri_expected = 7.5E-5 ! 75 microns, in meter - real(kind_phys), parameter :: effrs_expected = 5.1E-4 ! 510 microns, in meter + real(kind_phys), parameter :: effrs_expected = 5.3E-4 ! 530 microns, in meter real(kind_phys), parameter :: scalar_expected = 2.0E3 ! 2 km, in meter real(kind_phys), parameter :: tke_expected = 10.0 ! 10 J kg-1 real(kind_phys), parameter :: tolerance = 1.0E-6 ! used as scaling factor for expected value diff --git a/test/var_compatibility_test/var_compatibility_suite.xml b/test/var_compatibility_test/var_compatibility_suite.xml index a168e2ef..07d950ef 100644 --- a/test/var_compatibility_test/var_compatibility_suite.xml +++ b/test/var_compatibility_test/var_compatibility_suite.xml @@ -5,10 +5,15 @@ effr_pre - effr_calc + + effr_calc + effr_post + + effrs_calc + effr_diag rad_lw rad_sw diff --git a/test/var_compatibility_test/var_compatibility_test_reports.py b/test/var_compatibility_test/var_compatibility_test_reports.py index 5a8bdb95..ada612c7 100755 --- a/test/var_compatibility_test/var_compatibility_test_reports.py +++ b/test/var_compatibility_test/var_compatibility_test_reports.py @@ -35,7 +35,7 @@ [os.path.join(_BUILD_DIR, "ccpp", "test_host_ccpp_cap.F90"), os.path.join(_BUILD_DIR, "ccpp", "ccpp_var_compatibility_suite_cap.F90")] _PROCESS_LIST = [""] -_MODULE_LIST = ["effr_calc", "effr_diag", "effr_post", "mod_effr_pre", "rad_lw", "rad_sw"] +_MODULE_LIST = ["effr_calc", "effrs_calc", "effr_diag", "effr_post", "mod_effr_pre", "rad_lw", "rad_sw"] _SUITE_LIST = ["var_compatibility_suite"] _DEPENDENCIES = [ os.path.join(_TEST_DIR, "module_rad_ddt.F90")] _INPUT_VARS_VAR_ACTION = ["horizontal_loop_begin", "horizontal_loop_end", "horizontal_dimension", "vertical_layer_dimension",