From 4498542a3dede7f655bd2f70a54414873b7a05e9 Mon Sep 17 00:00:00 2001 From: Jo Basevi Date: Tue, 17 Oct 2023 13:39:20 +1100 Subject: [PATCH] refactor read mom6 parameter files and add to cesm cmeps driver --- payu/models/cesm_cmeps.py | 29 ++++++-------- payu/models/model.py | 25 +++++++----- payu/models/mom6.py | 72 +++++++++++++-------------------- test/models/test_mom6.py | 84 ++++++++++++++++----------------------- 4 files changed, 90 insertions(+), 120 deletions(-) diff --git a/payu/models/cesm_cmeps.py b/payu/models/cesm_cmeps.py index c7c20d72..a81d5f8a 100644 --- a/payu/models/cesm_cmeps.py +++ b/payu/models/cesm_cmeps.py @@ -20,16 +20,19 @@ from payu.fsops import mkdir_p, make_symlink from payu.models.model import Model from payu.models.fms import fms_collate +from payu.models.mom6 import mom6_add_parameter_files # Add as needed component_info = { "mom": { "config_files": [ "input.nml", - "MOM_input", "diag_table", ], - "optional_config_files" : ["MOM_override"] + "optional_config_files": [ + "field_table", + "data_table", + ], }, "cice": { "config_files": ["ice_in"], @@ -114,23 +117,17 @@ def set_model_pathnames(self): def setup(self): super().setup() - # Read components from nuopc.runconfig and copy component configuration files + # Read components from nuopc.runconfig self.get_runconfig(self.work_path) self.get_components() - for f_name in self.config_files: - f_path = os.path.join(self.control_path, f_name) - shutil.copy(f_path, self.work_path) - for f_name in self.optional_config_files: - f_path = os.path.join(self.control_path, f_name) - try: - shutil.copy(f_path, self.work_path) - except IOError as exc: - if exc.errno == errno.ENOENT: - pass - else: - raise - + if "mom" in self.components.values(): + # Read mom6 parameter files and add to configuration files + mom6_add_parameter_files(self) + + # Copy configuration files from control path to work path + self.setup_configuration_files() + if self.prior_restart_path and not self.expt.repeat_run: start_type = 'continue' diff --git a/payu/models/model.py b/payu/models/model.py index 8b49d94d..80548f77 100644 --- a/payu/models/model.py +++ b/payu/models/model.py @@ -199,16 +199,9 @@ def get_prior_restart_files(self): print("No prior restart files found: {error}".format(error=str(e))) return [] - def setup(self): - - print("Setting up {model}".format(model=self.name)) - # Create experiment directory structure - mkdir_p(self.work_init_path) - mkdir_p(self.work_input_path) - mkdir_p(self.work_restart_path) - mkdir_p(self.work_output_path) - - # Copy configuration files from control path + def setup_configuration_files(self): + """Copy configuration and optional configuration files from control + path to work path""" for f_name in self.config_files: f_path = os.path.join(self.control_path, f_name) shutil.copy(f_path, self.work_path) @@ -223,6 +216,18 @@ def setup(self): else: raise + def setup(self): + + print("Setting up {model}".format(model=self.name)) + # Create experiment directory structure + mkdir_p(self.work_init_path) + mkdir_p(self.work_input_path) + mkdir_p(self.work_restart_path) + mkdir_p(self.work_output_path) + + # Copy configuration files from control path + self.setup_configuration_files() + # Add restart files from prior run to restart manifest if (not self.expt.manifest.have_manifest['restart'] and self.prior_restart_path): diff --git a/payu/models/mom6.py b/payu/models/mom6.py index e4a48d12..188153e8 100644 --- a/payu/models/mom6.py +++ b/payu/models/mom6.py @@ -19,6 +19,29 @@ from payu.models.fms import Fms +def mom6_add_parameter_files(model): + """Add parameter files defined in input.nml to model configuration files. + Broken out of mom6 class so can be used in other models""" + input_nml = f90nml.read(os.path.join(model.control_path, 'input.nml')) + + input_namelists = ['MOM_input_nml'] + if 'SIS_input_nml' in input_nml: + input_namelists.append('SIS_input_nml') + + for input in input_namelists: + input_namelist = input_nml.get(input, {}) + filenames = input_namelist.get('parameter_filename', []) + + if filenames == []: + print("payu: warning: MOM6: There are no parameter files " + f"listed under {input} in input.nml") + + if isinstance(filenames, str): + model.config_files.append(filenames) + else: + model.config_files.extend(filenames) + + class Mom6(Fms): """Interface to GFDL's MOM6 ocean model.""" @@ -45,7 +68,10 @@ def setup(self): super(Mom6, self).setup() self.init_config() - self.add_config_files() + + # Add parameter files to config files and copy files over to work path + mom6_add_parameter_files(self) + self.setup_configuration_files() def init_config(self): """Patch input.nml as a new or restart run.""" @@ -65,47 +91,3 @@ def init_config(self): input_nml['SIS_input_nml']['input_filename'] = input_type f90nml.write(input_nml, input_fpath, force=True) - - def add_config_files(self): - """Add to model configuration files""" - - # Add parameter config files - config_files_to_add = self.get_parameter_files() - - # Set of all configuration files - all_config_files = set(self.config_files).union( - self.optional_config_files) - - for filename in config_files_to_add: - if filename not in all_config_files: - # Extend config files - self.config_files.append(filename) - all_config_files.add(filename) - - # Copy file from control path to work path - file_path = os.path.join(self.control_path, filename) - shutil.copy(file_path, self.work_path) - - def get_parameter_files(self): - """Return a list of parameter config files defined in input.nml""" - input_nml = f90nml.read(os.path.join(self.work_path, 'input.nml')) - - input_namelists = ['MOM_input_nml'] - if 'SIS_input_nml' in input_nml: - input_namelists.append('SIS_input_nml') - - parameter_files = [] - for input in input_namelists: - input_namelist = input_nml.get(input, {}) - filenames = input_namelist.get('parameter_filename', []) - - if filenames == []: - print("payu: warning: MOM6: There are no parameter files " - f"listed under {input} in input.nml") - - if isinstance(filenames, str): - parameter_files.append(filenames) - else: - parameter_files.extend(filenames) - - return parameter_files diff --git a/test/models/test_mom6.py b/test/models/test_mom6.py index 64b1f923..ebf5afcb 100644 --- a/test/models/test_mom6.py +++ b/test/models/test_mom6.py @@ -64,54 +64,42 @@ def teardown(): # Run test yield - # Remove any files in expt work directory - for file in os.listdir(expt_workdir): - try: - os.remove(os.path.join(expt_workdir, file)) - except Exception as e: - print(e) - @pytest.mark.parametrize( - "input_nml, expected_files_added", - [ - ( - { - "MOM_input_nml": { - "parameter_filename": "MOM_Input" - } - }, - ["MOM_Input"] - ), - ( - { - "SIS_input_nml": { - "parameter_filename": "SIS_Input" - } + "input_nml, expected_files_added", + [ + ( + { + "MOM_input_nml": { + "parameter_filename": "MOM_Input" + } + }, + ["MOM_Input"] + ), + ( + { + "SIS_input_nml": { + "parameter_filename": "SIS_Input" + } + }, + ["SIS_Input"] + ), + ( + { + "MOM_input_nml": { + "parameter_filename": ["MOM_Input", "MOM_override"] }, - ["SIS_Input"] - ), - ( - { - "MOM_input_nml": { - "parameter_filename": ["MOM_Input", "MOM_override"] - }, - "SIS_input_nml": { - "output_directory": '.' - } - }, - ["MOM_Input", "MOM_override"] - ) - ]) -def test_add_config_files(input_nml, - expected_files_added): - # Create config files in control directory - for file in expected_files_added: - filename = os.path.join(ctrldir, file) - make_random_file(filename, 8) - + "SIS_input_nml": { + "output_directory": '.' + } + }, + ["MOM_Input", "MOM_override"] + ) + ]) +def test_mom6_add_parameter_files(input_nml, + expected_files_added): # Create config.nml - input_nml_fp = os.path.join(expt_workdir, 'input.nml') + input_nml_fp = os.path.join(ctrldir, 'input.nml') f90nml.write(input_nml, input_nml_fp) with cd(ctrldir): @@ -122,13 +110,11 @@ def test_add_config_files(input_nml, prior_config_files = model.config_files[:] # Function to test - model.add_config_files() + payu.models.mom6.mom6_add_parameter_files(model) # Check files are added to config_files added_files = set(model.config_files).difference(prior_config_files) assert added_files == set(expected_files_added) - # Check the extra files are moved to model's work path - ctrl_path_files = os.listdir(model.work_path) - for file in expected_files_added: - assert file in ctrl_path_files + # Tidy up input.nml + os.remove(input_nml_fp)