diff --git a/compass/ocean/tests/global_ocean/global_ocean.cfg b/compass/ocean/tests/global_ocean/global_ocean.cfg index 9d032e857a..e6657eb166 100644 --- a/compass/ocean/tests/global_ocean/global_ocean.cfg +++ b/compass/ocean/tests/global_ocean/global_ocean.cfg @@ -47,6 +47,12 @@ btr_dt_per_km = 1.5 # Maximum allowed Haney number for configurations with ice-shelf cavities rx1_max = 20 +# the number of iterations of topography smoothing (0 means no smoothing) +topo_smooth_num_passes = 0 +# The distance in km over which the Gaussian filter is applied +topo_smooth_distance_limit = 200.0 +# The standard deviation in km of the Gaussian filter +topo_smooth_std_deviation = 100.0 # number of cores to use init_ntasks = 36 diff --git a/compass/ocean/tests/global_ocean/init/initial_state.py b/compass/ocean/tests/global_ocean/init/initial_state.py index d9ea96eedf..87cb8e70e4 100644 --- a/compass/ocean/tests/global_ocean/init/initial_state.py +++ b/compass/ocean/tests/global_ocean/init/initial_state.py @@ -1,6 +1,12 @@ import os -from importlib.resources import contents +from importlib.resources import contents, read_text +import xarray as xr +from jinja2 import Template +from mpas_tools.io import write_netcdf +from mpas_tools.logging import check_call + +from compass.io import symlink from compass.model import run_model from compass.ocean.plot import plot_initial_state, plot_vertical_grid from compass.ocean.tests.global_ocean.metadata import ( @@ -79,7 +85,7 @@ def __init__(self, test_case, mesh, initial_condition): cull_step = self.mesh.steps['cull_mesh'] target = os.path.join(cull_step.path, 'topography_culled.nc') - self.add_input_file(filename='topography.nc', + self.add_input_file(filename='topography_culled.nc', work_dir_target=target) self.add_input_file( @@ -162,6 +168,8 @@ def run(self): Run this step of the testcase """ config = self.config + self._smooth_topography() + interfaces = generate_1d_grid(config=config) write_1d_grid(interfaces=interfaces, out_filename='vertical_grid.nc') @@ -186,3 +194,43 @@ def _get_resources(self): self.cpus_per_task = config.getint('global_ocean', 'init_cpus_per_task') self.min_cpus_per_task = self.cpus_per_task + + def _smooth_topography(self): + """ Smooth the topography using a Gaussian filter """ + config = self.config + section = config['global_ocean'] + num_passes = section.getint('topo_smooth_num_passes') + if num_passes == 0: + # just symlink the culled topography to be the topography used for + # the initial condition + symlink(target='topography_culled.nc', link_name='topography.nc') + return + + distance_limit = section.getfloat('topo_smooth_distance_limit') + std_deviation = section.getfloat('topo_smooth_std_deviation') + + template = Template(read_text( + 'compass.ocean.tests.global_ocean.init', 'smooth_topo.template')) + + text = template.render(num_passes=f'{num_passes}', + distance_limit=f'{distance_limit}', + std_deviation=f'{std_deviation}') + + # add trailing end line + text = f'{text}\n' + + with open('smooth_depth_in', 'w') as file: + file.write(text) + + check_call(args=['ocean_smooth_topo_before_init'], + logger=self.logger) + + with (xr.open_dataset('topography_culled.nc') as ds_topo): + with xr.open_dataset('topography_orig_and_smooth.nc') as ds_smooth: + for field in ['bed_elevation', 'landIceDraftObserved', + 'landIceThkObserved']: + attrs = ds_topo[field].attrs + ds_topo[field] = ds_smooth[f'{field}New'] + ds_topo[field].attrs = attrs + + write_netcdf(ds_topo, 'topography.nc') diff --git a/compass/ocean/tests/global_ocean/init/smooth_topo.template b/compass/ocean/tests/global_ocean/init/smooth_topo.template new file mode 100644 index 0000000000..9deb8a6cf0 --- /dev/null +++ b/compass/ocean/tests/global_ocean/init/smooth_topo.template @@ -0,0 +1,8 @@ +&smooth + filename_depth_in = "topography_culled.nc" + filename_depth_out = "topography_orig_and_smooth.nc" + filename_mpas_mesh = "mesh.nc" + distanceLimit = {{ distance_limit }} + stdDeviation = {{ std_deviation }} + numSmoothingPasses = {{ num_passes }} +/ diff --git a/compass/ocean/tests/global_ocean/mesh/qu/dynamic_adjustment.yaml b/compass/ocean/tests/global_ocean/mesh/qu/dynamic_adjustment.yaml index 339334ae02..7df1beb8ff 100644 --- a/compass/ocean/tests/global_ocean/mesh/qu/dynamic_adjustment.yaml +++ b/compass/ocean/tests/global_ocean/mesh/qu/dynamic_adjustment.yaml @@ -1,5 +1,5 @@ dynamic_adjustment: - land_ice_flux_mode: data + land_ice_flux_mode: pressure_only get_dt_from_min_res: True steps: @@ -16,7 +16,7 @@ dynamic_adjustment: Rayleigh_damping_coeff: 1.0e-5 simulation: - run_duration: 10_00:00:00 + run_duration: 80_00:00:00 output_interval: 10_00:00:00 restart_interval: 10_00:00:00 Rayleigh_damping_coeff: None diff --git a/compass/ocean/tests/global_ocean/mesh/qu/qu.cfg b/compass/ocean/tests/global_ocean/mesh/qu/qu.cfg index 30e8069735..8593c5b44c 100644 --- a/compass/ocean/tests/global_ocean/mesh/qu/qu.cfg +++ b/compass/ocean/tests/global_ocean/mesh/qu/qu.cfg @@ -34,19 +34,18 @@ prefix = QU # a description of the mesh mesh_description = MPAS quasi-uniform mesh for E3SM version ${e3sm_version} at ${min_res}-km global resolution with <<>> vertical - level - + levels. # E3SM version that the mesh is intended for e3sm_version = 3 # The revision number of the mesh, which should be incremented each time the # mesh is revised -mesh_revision = 2 +mesh_revision = 5 # the minimum (finest) resolution in the mesh min_res = ${qu_resolution} # the maximum (coarsest) resolution in the mesh, can be the same as min_res max_res = ${qu_resolution} # The URL of the pull request documenting the creation of the mesh -pull_request = https://github.com/MPAS-Dev/compass/pull/691 +pull_request = https://github.com/MPAS-Dev/compass/pull/735 # the resolution of the QU or Icos mesh in km -qu_resolution = 120 +qu_resolution = 30 diff --git a/compass/ocean/tests/global_ocean/streams.forward b/compass/ocean/tests/global_ocean/streams.forward index 56ca24f4a9..767b381610 100644 --- a/compass/ocean/tests/global_ocean/streams.forward +++ b/compass/ocean/tests/global_ocean/streams.forward @@ -18,6 +18,7 @@ +