From 6763b18c4c2573a405eed7088f3d702e53c1fab4 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Sun, 25 Sep 2022 15:10:11 -0600 Subject: [PATCH 1/4] Add TimeSeriesStatsRestartTest to global ocean This test case makes sure the timeSeriesStats* analysis member produces the same results with a full 8-hour run and with two 4-hour runs with a restart in between. --- compass/ocean/tests/global_ocean/__init__.py | 8 ++ .../__init__.py | 92 +++++++++++++++++++ .../namelist.full | 9 ++ .../namelist.restart | 9 ++ .../streams.forward | 24 +++++ 5 files changed, 142 insertions(+) create mode 100644 compass/ocean/tests/global_ocean/time_series_stats_restart_test/__init__.py create mode 100644 compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.full create mode 100644 compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.restart create mode 100644 compass/ocean/tests/global_ocean/time_series_stats_restart_test/streams.forward diff --git a/compass/ocean/tests/global_ocean/__init__.py b/compass/ocean/tests/global_ocean/__init__.py index a394b3bf64..2421660f1b 100644 --- a/compass/ocean/tests/global_ocean/__init__.py +++ b/compass/ocean/tests/global_ocean/__init__.py @@ -18,6 +18,8 @@ from compass.ocean.tests.global_ocean.threads_test import ThreadsTest from compass.ocean.tests.global_ocean.analysis_test import AnalysisTest from compass.ocean.tests.global_ocean.daily_output_test import DailyOutputTest +from compass.ocean.tests.global_ocean.time_series_stats_restart_test import \ + TimeSeriesStatsRestartTest from compass.ocean.tests.global_ocean.monthly_output_test import \ MonthlyOutputTest from compass.ocean.tests.global_ocean.files_for_e3sm import FilesForE3SM @@ -72,10 +74,16 @@ def __init__(self, mpas_core): DailyOutputTest( test_group=self, mesh=mesh, init=init, time_integrator=time_integrator)) + self.add_test_case( + TimeSeriesStatsRestartTest( + test_group=self, mesh=mesh, init=init, analysis='Daily')) self.add_test_case( MonthlyOutputTest( test_group=self, mesh=mesh, init=init, time_integrator=time_integrator)) + self.add_test_case( + TimeSeriesStatsRestartTest( + test_group=self, mesh=mesh, init=init, analysis='Monthly')) dynamic_adjustment = QU240DynamicAdjustment( test_group=self, mesh=mesh, init=init, diff --git a/compass/ocean/tests/global_ocean/time_series_stats_restart_test/__init__.py b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/__init__.py new file mode 100644 index 0000000000..3461daa009 --- /dev/null +++ b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/__init__.py @@ -0,0 +1,92 @@ +from compass.validate import compare_variables +from compass.ocean.tests.global_ocean.forward import ForwardTestCase, \ + ForwardStep + + +class TimeSeriesStatsRestartTest(ForwardTestCase): + """ + A test case to test bit-for-bit restart capabilities from the + TimeSeriesStats analysis members in E3SM. + + Attributes + ---------- + analysis : {'Daily', 'Monthly'} + The suffix for the ``timeSeriesStats`` analysis member to check. + + """ + + def __init__(self, test_group, mesh, init, analysis): + """ + Create test case + + Parameters + ---------- + test_group : compass.ocean.tests.global_ocean.GlobalOcean + The global ocean test group that this test case belongs to + + mesh : compass.ocean.tests.global_ocean.mesh.Mesh + The test case that produces the mesh for this run + + init : compass.ocean.tests.global_ocean.init.Init + The test case that produces the initial condition for this run + + analysis : {'Daily', 'Monthly'} + The suffix for the ``timeSeriesStats`` analysis member to check. + """ + name = f'{analysis.lower()}_restart_test' + time_integrator = 'split_explicit' + super().__init__(test_group=test_group, mesh=mesh, init=init, + time_integrator=time_integrator, name=name) + module = self.__module__ + self.analysis = analysis + + output_interval = '0000-00-00_04:00:00' + + replacements = dict(analysis=analysis, + output_interval=output_interval) + + restart_filename = '../restarts/rst.0001-01-01_04.00.00.nc' + analysis_restart_filename = \ + f'../restarts/rst.timeSeriesStats{analysis}.0001-01-01_04.00.00.nc' + analysis_filename = \ + f'analysis_members/mpaso.hist.am.timeSeriesStats{analysis}.0001-01-01_08.00.00.nc' + + for part in ['full', 'restart']: + name = f'{part}_run' + step = ForwardStep(test_case=self, mesh=mesh, init=init, + time_integrator=time_integrator, name=name, + subdir=name, ntasks=4, openmp_threads=1) + + step.add_namelist_file(module, f'namelist.{part}') + step.add_streams_file(module, 'streams.forward', + template_replacements=replacements) + if part == 'full': + step.add_output_file(restart_filename) + step.add_output_file(analysis_restart_filename) + else: + step.add_input_file(restart_filename) + step.add_input_file(analysis_restart_filename) + step.add_output_file(analysis_filename) + self.add_step(step) + + def validate(self): + """ + Test cases can override this method to perform validation of variables + and timers + """ + analysis = self.analysis + variables = [ + 'Time', 'Time_bnds', + f'time{analysis}_avg_activeTracers_temperature', + f'time{analysis}_avg_activeTracers_salinity', + f'time{analysis}_avg_layerThickness', + f'time{analysis}_avg_normalVelocity', + f'time{analysis}_avg_ssh'] + + analysis_filename = \ + f'analysis_members/mpaso.hist.am.timeSeriesStats{analysis}.0001-02-01.nc' + + compare_variables( + test_case=self, variables=variables, + filename1=f'full_run/{analysis_filename}', + filename2=f'restart_run/{analysis_filename}') diff --git a/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.full b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.full new file mode 100644 index 0000000000..238ed54a6a --- /dev/null +++ b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.full @@ -0,0 +1,9 @@ +config_start_time = '0001-01-01_00:00:00' +config_run_duration = '08:00:00' +config_do_restart = .false. +config_AM_timeSeriesStatsDaily_enable = .true. +config_AM_timeSeriesStatsDaily_compute_on_startup = .false. +config_AM_timeSeriesStatsDaily_write_on_startup = .false. +config_AM_timeSeriesStatsDaily_compute_interval = '00-00-00_04:00:00' +config_AM_timeSeriesStatsDaily_reset_intervals = '00-00-00_04:00:00' +config_AM_timeSeriesStatsDaily_backward_output_offset = '00-00-00_04:00:00' diff --git a/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.restart b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.restart new file mode 100644 index 0000000000..cf2a0e8cf5 --- /dev/null +++ b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.restart @@ -0,0 +1,9 @@ +config_start_time = '0001-01-01_04:00:00' +config_run_duration = '04:00:00' +config_do_restart = .true. +config_AM_timeSeriesStatsDaily_enable = .true. +config_AM_timeSeriesStatsDaily_compute_on_startup = .false. +config_AM_timeSeriesStatsDaily_write_on_startup = .false. +config_AM_timeSeriesStatsDaily_compute_interval = '00-00-00_04:00:00' +config_AM_timeSeriesStatsDaily_reset_intervals = '00-00-00_04:00:00' +config_AM_timeSeriesStatsDaily_backward_output_offset = '00-00-00_04:00:00' diff --git a/compass/ocean/tests/global_ocean/time_series_stats_restart_test/streams.forward b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/streams.forward new file mode 100644 index 0000000000..2669a65ccf --- /dev/null +++ b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/streams.forward @@ -0,0 +1,24 @@ + + + + + + + + + + + + + From 06cde4ea8c732db6543735d468e4737632722da4 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Wed, 5 Oct 2022 10:42:57 -0600 Subject: [PATCH 2/4] Include analysis restart in timeSeriesStats restart One version of each restart test does not include analysis restart (the configuration that E3SM uses) and another does (the default in standalone MPAS-Ocean). --- compass/ocean/tests/global_ocean/__init__.py | 14 ++++- .../__init__.py | 62 ++++++++++++++----- .../namelist.full | 7 +-- .../namelist.restart | 7 +-- .../streams.forward | 6 +- 5 files changed, 66 insertions(+), 30 deletions(-) diff --git a/compass/ocean/tests/global_ocean/__init__.py b/compass/ocean/tests/global_ocean/__init__.py index 2421660f1b..8e840fb9a1 100644 --- a/compass/ocean/tests/global_ocean/__init__.py +++ b/compass/ocean/tests/global_ocean/__init__.py @@ -76,14 +76,24 @@ def __init__(self, mpas_core): time_integrator=time_integrator)) self.add_test_case( TimeSeriesStatsRestartTest( - test_group=self, mesh=mesh, init=init, analysis='Daily')) + test_group=self, mesh=mesh, init=init, analysis='Daily', + with_analysis_restart=True)) + self.add_test_case( + TimeSeriesStatsRestartTest( + test_group=self, mesh=mesh, init=init, analysis='Daily', + with_analysis_restart=False)) self.add_test_case( MonthlyOutputTest( test_group=self, mesh=mesh, init=init, time_integrator=time_integrator)) self.add_test_case( TimeSeriesStatsRestartTest( - test_group=self, mesh=mesh, init=init, analysis='Monthly')) + test_group=self, mesh=mesh, init=init, analysis='Monthly', + with_analysis_restart=True)) + self.add_test_case( + TimeSeriesStatsRestartTest( + test_group=self, mesh=mesh, init=init, analysis='Monthly', + with_analysis_restart=False)) dynamic_adjustment = QU240DynamicAdjustment( test_group=self, mesh=mesh, init=init, diff --git a/compass/ocean/tests/global_ocean/time_series_stats_restart_test/__init__.py b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/__init__.py index 3461daa009..c82607f3bb 100644 --- a/compass/ocean/tests/global_ocean/time_series_stats_restart_test/__init__.py +++ b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/__init__.py @@ -15,7 +15,8 @@ class TimeSeriesStatsRestartTest(ForwardTestCase): """ - def __init__(self, test_group, mesh, init, analysis): + def __init__(self, test_group, mesh, init, analysis, + with_analysis_restart): """ Create test case @@ -32,8 +33,14 @@ def __init__(self, test_group, mesh, init, analysis): analysis : {'Daily', 'Monthly'} The suffix for the ``timeSeriesStats`` analysis member to check. + + with_analysis_restart : bool + Whether to save a restart file from ``timeSeriesStats`` """ - name = f'{analysis.lower()}_restart_test' + if with_analysis_restart: + name = f'{analysis.lower()}_analysis_restart' + else: + name = f'{analysis.lower()}_model_restart' time_integrator = 'split_explicit' super().__init__(test_group=test_group, mesh=mesh, init=init, time_integrator=time_integrator, name=name) @@ -42,14 +49,35 @@ def __init__(self, test_group, mesh, init, analysis): output_interval = '0000-00-00_04:00:00' - replacements = dict(analysis=analysis, - output_interval=output_interval) - restart_filename = '../restarts/rst.0001-01-01_04.00.00.nc' - analysis_restart_filename = \ - f'../restarts/rst.timeSeriesStats{analysis}.0001-01-01_04.00.00.nc' + if with_analysis_restart: + analysis_restart_filename = \ + f'../restarts/rst.timeSeriesStats{analysis}.0001-01-01_04.00.00.nc' + analysis_restart_input_interval = 'initial_only' + analysis_restart_output_interval = 'stream:restart:output_interval' + else: + analysis_restart_filename = None + analysis_restart_input_interval = 'none' + analysis_restart_output_interval = 'none' analysis_filename = \ - f'analysis_members/mpaso.hist.am.timeSeriesStats{analysis}.0001-01-01_08.00.00.nc' + f'analysis_members/mpaso.hist.am.timeSeriesStats{analysis}.0001-01-01_04.00.00.nc' + + replacements = dict( + analysis=analysis, + output_interval=output_interval, + analysis_restart_input_interval=analysis_restart_input_interval, + analysis_restart_output_interval=analysis_restart_output_interval) + + namelist_options = { + f'config_AM_timeSeriesStats{analysis}_enable': '.true.', + f'config_AM_timeSeriesStats{analysis}_compute_on_startup': '.false.', + f'config_AM_timeSeriesStats{analysis}_write_on_startup': '.false.', + f'config_AM_timeSeriesStats{analysis}_compute_interval': "'00-00-00_01:00:00'", + f'config_AM_timeSeriesStats{analysis}_reset_intervals': "'00-00-00_04:00:00'", + f'config_AM_timeSeriesStats{analysis}_backward_output_offset': "'00-00-00_04:00:00'"} + + if not with_analysis_restart: + namelist_options[f'config_AM_timeSeriesStats{analysis}_restart_stream'] = "'none'" for part in ['full', 'restart']: name = f'{part}_run' @@ -58,14 +86,17 @@ def __init__(self, test_group, mesh, init, analysis): subdir=name, ntasks=4, openmp_threads=1) step.add_namelist_file(module, f'namelist.{part}') + step.add_namelist_options(namelist_options) step.add_streams_file(module, 'streams.forward', template_replacements=replacements) if part == 'full': step.add_output_file(restart_filename) - step.add_output_file(analysis_restart_filename) + if analysis_restart_filename is not None: + step.add_output_file(analysis_restart_filename) else: step.add_input_file(restart_filename) - step.add_input_file(analysis_restart_filename) + if analysis_restart_filename is not None: + step.add_input_file(analysis_restart_filename) step.add_output_file(analysis_filename) self.add_step(step) @@ -77,14 +108,17 @@ def validate(self): analysis = self.analysis variables = [ 'Time', 'Time_bnds', - f'time{analysis}_avg_activeTracers_temperature', - f'time{analysis}_avg_activeTracers_salinity', - f'time{analysis}_avg_layerThickness', f'time{analysis}_avg_normalVelocity', f'time{analysis}_avg_ssh'] + if analysis == 'Monthly': + variables.extend([ + f'time{analysis}_avg_activeTracers_temperature', + f'time{analysis}_avg_activeTracers_salinity', + f'time{analysis}_avg_layerThickness']) + analysis_filename = \ - f'analysis_members/mpaso.hist.am.timeSeriesStats{analysis}.0001-02-01.nc' + f'analysis_members/mpaso.hist.am.timeSeriesStats{analysis}.0001-01-01_04.00.00.nc' compare_variables( test_case=self, variables=variables, diff --git a/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.full b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.full index 238ed54a6a..b9c81da623 100644 --- a/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.full +++ b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.full @@ -1,9 +1,4 @@ config_start_time = '0001-01-01_00:00:00' config_run_duration = '08:00:00' +config_dt = '00:30:00' config_do_restart = .false. -config_AM_timeSeriesStatsDaily_enable = .true. -config_AM_timeSeriesStatsDaily_compute_on_startup = .false. -config_AM_timeSeriesStatsDaily_write_on_startup = .false. -config_AM_timeSeriesStatsDaily_compute_interval = '00-00-00_04:00:00' -config_AM_timeSeriesStatsDaily_reset_intervals = '00-00-00_04:00:00' -config_AM_timeSeriesStatsDaily_backward_output_offset = '00-00-00_04:00:00' diff --git a/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.restart b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.restart index cf2a0e8cf5..b7c15dcb0a 100644 --- a/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.restart +++ b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/namelist.restart @@ -1,9 +1,4 @@ config_start_time = '0001-01-01_04:00:00' config_run_duration = '04:00:00' +config_dt = '00:30:00' config_do_restart = .true. -config_AM_timeSeriesStatsDaily_enable = .true. -config_AM_timeSeriesStatsDaily_compute_on_startup = .false. -config_AM_timeSeriesStatsDaily_write_on_startup = .false. -config_AM_timeSeriesStatsDaily_compute_interval = '00-00-00_04:00:00' -config_AM_timeSeriesStatsDaily_reset_intervals = '00-00-00_04:00:00' -config_AM_timeSeriesStatsDaily_backward_output_offset = '00-00-00_04:00:00' diff --git a/compass/ocean/tests/global_ocean/time_series_stats_restart_test/streams.forward b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/streams.forward index 2669a65ccf..fe00ac99b7 100644 --- a/compass/ocean/tests/global_ocean/time_series_stats_restart_test/streams.forward +++ b/compass/ocean/tests/global_ocean/time_series_stats_restart_test/streams.forward @@ -9,8 +9,10 @@ output_interval="{{ output_interval }}"> - + Date: Wed, 5 Oct 2022 10:46:16 -0600 Subject: [PATCH 3/4] Add daily and monthly restart tests to pr suite --- compass/ocean/suites/pr.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compass/ocean/suites/pr.txt b/compass/ocean/suites/pr.txt index ed5bc7c90c..882a447fd6 100644 --- a/compass/ocean/suites/pr.txt +++ b/compass/ocean/suites/pr.txt @@ -15,6 +15,12 @@ ocean/global_ocean/QU240/PHC/restart_test ocean/global_ocean/QU240/PHC/decomp_test ocean/global_ocean/QU240/PHC/threads_test ocean/global_ocean/QU240/PHC/analysis_test +ocean/global_ocean/QU240/PHC/analysis_test +ocean/global_ocean/QU240/PHC/analysis_test +ocean/global_ocean/QU240/PHC/daily_analysis_restart +ocean/global_ocean/QU240/PHC/daily_model_restart +ocean/global_ocean/QU240/PHC/monthly_analysis_restart +ocean/global_ocean/QU240/PHC/monthly_model_restart ocean/global_ocean/QU240/PHC/dynamic_adjustment ocean/global_ocean/QU240/PHC/files_for_e3sm From 9f45a8d11c90a49d73557d3f15461cbbf965e228 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Wed, 5 Oct 2022 16:58:48 -0600 Subject: [PATCH 4/4] Add time_series_stats suite --- compass/ocean/suites/time_series_stats.txt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 compass/ocean/suites/time_series_stats.txt diff --git a/compass/ocean/suites/time_series_stats.txt b/compass/ocean/suites/time_series_stats.txt new file mode 100644 index 0000000000..3963e73054 --- /dev/null +++ b/compass/ocean/suites/time_series_stats.txt @@ -0,0 +1,8 @@ +ocean/global_ocean/QU240/mesh +ocean/global_ocean/QU240/PHC/init +ocean/global_ocean/QU240/PHC/daily_analysis_restart +ocean/global_ocean/QU240/PHC/daily_model_restart +ocean/global_ocean/QU240/PHC/monthly_analysis_restart +ocean/global_ocean/QU240/PHC/monthly_model_restart +ocean/global_ocean/QU240/PHC/daily_output_test +ocean/global_ocean/QU240/PHC/monthly_output_test