Skip to content

Commit

Permalink
Merge pull request #429 from xylar/global_ocean_mesh_reorg
Browse files Browse the repository at this point in the history
Switch `global_ocean` and `hurricane` to framework base and culled mesh
  • Loading branch information
xylar authored Aug 30, 2022
2 parents 6842269 + db62191 commit c3dceb8
Show file tree
Hide file tree
Showing 30 changed files with 526 additions and 522 deletions.
39 changes: 37 additions & 2 deletions compass/ocean/cached_files.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,40 @@
"ocean/global_convergence/qu/cosine_bell/QU60/init/namelist.ocean": "global_convergence/qu/cosine_bell/QU60/init/namelist.220528.ocean",
"ocean/global_convergence/qu/cosine_bell/QU60/init/initial_state.nc": "global_convergence/qu/cosine_bell/QU60/init/initial_state.220528.nc",
"ocean/global_convergence/qu/cosine_bell/QU90/init/namelist.ocean": "global_convergence/qu/cosine_bell/QU90/init/namelist.220528.ocean",
"ocean/global_convergence/qu/cosine_bell/QU90/init/initial_state.nc": "global_convergence/qu/cosine_bell/QU90/init/initial_state.220528.nc"
}
"ocean/global_convergence/qu/cosine_bell/QU90/init/initial_state.nc": "global_convergence/qu/cosine_bell/QU90/init/initial_state.220528.nc",
"ocean/global_ocean/Icos240/mesh/base_mesh/mesh.msh": "global_ocean/Icos240/mesh/base_mesh/mesh.220814.msh",
"ocean/global_ocean/Icos240/mesh/base_mesh/base_mesh.nc": "global_ocean/Icos240/mesh/base_mesh/base_mesh.220814.nc",
"ocean/global_ocean/Icos240/mesh/base_mesh/cellWidthVsLatLon.nc": "global_ocean/Icos240/mesh/base_mesh/cellWidthVsLatLon.220814.nc",
"ocean/global_ocean/Icos240/mesh/base_mesh/graph.info": "global_ocean/Icos240/mesh/base_mesh/graph.220814.info",
"ocean/global_ocean/Icos240/mesh/cull_mesh/culled_mesh.nc": "global_ocean/Icos240/mesh/cull_mesh/culled_mesh.220814.nc",
"ocean/global_ocean/Icos240/mesh/cull_mesh/culled_graph.info": "global_ocean/Icos240/mesh/cull_mesh/culled_graph.220814.info",
"ocean/global_ocean/Icos240/mesh/cull_mesh/critical_passages_mask_final.nc": "global_ocean/Icos240/mesh/cull_mesh/critical_passages_mask_final.220814.nc",
"ocean/global_ocean/QU240/mesh/base_mesh/mesh.msh": "global_ocean/QU240/mesh/base_mesh/mesh.220814.msh",
"ocean/global_ocean/QU240/mesh/base_mesh/base_mesh.nc": "global_ocean/QU240/mesh/base_mesh/base_mesh.220814.nc",
"ocean/global_ocean/QU240/mesh/base_mesh/cellWidthVsLatLon.nc": "global_ocean/QU240/mesh/base_mesh/cellWidthVsLatLon.220814.nc",
"ocean/global_ocean/QU240/mesh/base_mesh/graph.info": "global_ocean/QU240/mesh/base_mesh/graph.220814.info",
"ocean/global_ocean/QU240/mesh/cull_mesh/culled_mesh.nc": "global_ocean/QU240/mesh/cull_mesh/culled_mesh.220814.nc",
"ocean/global_ocean/QU240/mesh/cull_mesh/culled_graph.info": "global_ocean/QU240/mesh/cull_mesh/culled_graph.220814.info",
"ocean/global_ocean/QU240/mesh/cull_mesh/critical_passages_mask_final.nc": "global_ocean/QU240/mesh/cull_mesh/critical_passages_mask_final.220814.nc",
"ocean/global_ocean/QUwISC240/mesh/base_mesh/mesh.msh": "global_ocean/QUwISC240/mesh/base_mesh/mesh.220814.msh",
"ocean/global_ocean/QUwISC240/mesh/base_mesh/base_mesh.nc": "global_ocean/QUwISC240/mesh/base_mesh/base_mesh.220814.nc",
"ocean/global_ocean/QUwISC240/mesh/base_mesh/cellWidthVsLatLon.nc": "global_ocean/QUwISC240/mesh/base_mesh/cellWidthVsLatLon.220814.nc",
"ocean/global_ocean/QUwISC240/mesh/base_mesh/graph.info": "global_ocean/QUwISC240/mesh/base_mesh/graph.220814.info",
"ocean/global_ocean/QUwISC240/mesh/cull_mesh/culled_mesh.nc": "global_ocean/QUwISC240/mesh/cull_mesh/culled_mesh.220814.nc",
"ocean/global_ocean/QUwISC240/mesh/cull_mesh/culled_graph.info": "global_ocean/QUwISC240/mesh/cull_mesh/culled_graph.220814.info",
"ocean/global_ocean/QUwISC240/mesh/cull_mesh/critical_passages_mask_final.nc": "global_ocean/QUwISC240/mesh/cull_mesh/critical_passages_mask_final.220814.nc",
"ocean/global_ocean/EC30to60/mesh/base_mesh/mesh.msh": "global_ocean/EC30to60/mesh/base_mesh/mesh.220814.msh",
"ocean/global_ocean/EC30to60/mesh/base_mesh/base_mesh.nc": "global_ocean/EC30to60/mesh/base_mesh/base_mesh.220814.nc",
"ocean/global_ocean/EC30to60/mesh/base_mesh/cellWidthVsLatLon.nc": "global_ocean/EC30to60/mesh/base_mesh/cellWidthVsLatLon.220814.nc",
"ocean/global_ocean/EC30to60/mesh/base_mesh/graph.info": "global_ocean/EC30to60/mesh/base_mesh/graph.220814.info",
"ocean/global_ocean/EC30to60/mesh/cull_mesh/culled_mesh.nc": "global_ocean/EC30to60/mesh/cull_mesh/culled_mesh.220814.nc",
"ocean/global_ocean/EC30to60/mesh/cull_mesh/culled_graph.info": "global_ocean/EC30to60/mesh/cull_mesh/culled_graph.220814.info",
"ocean/global_ocean/EC30to60/mesh/cull_mesh/critical_passages_mask_final.nc": "global_ocean/EC30to60/mesh/cull_mesh/critical_passages_mask_final.220814.nc",
"ocean/global_ocean/ECwISC30to60/mesh/base_mesh/mesh.msh": "global_ocean/ECwISC30to60/mesh/base_mesh/mesh.220814.msh",
"ocean/global_ocean/ECwISC30to60/mesh/base_mesh/base_mesh.nc": "global_ocean/ECwISC30to60/mesh/base_mesh/base_mesh.220814.nc",
"ocean/global_ocean/ECwISC30to60/mesh/base_mesh/cellWidthVsLatLon.nc": "global_ocean/ECwISC30to60/mesh/base_mesh/cellWidthVsLatLon.220814.nc",
"ocean/global_ocean/ECwISC30to60/mesh/base_mesh/graph.info": "global_ocean/ECwISC30to60/mesh/base_mesh/graph.220814.info",
"ocean/global_ocean/ECwISC30to60/mesh/cull_mesh/culled_mesh.nc": "global_ocean/ECwISC30to60/mesh/cull_mesh/culled_mesh.220814.nc",
"ocean/global_ocean/ECwISC30to60/mesh/cull_mesh/culled_graph.info": "global_ocean/ECwISC30to60/mesh/cull_mesh/culled_graph.220814.info",
"ocean/global_ocean/ECwISC30to60/mesh/cull_mesh/critical_passages_mask_final.nc": "global_ocean/ECwISC30to60/mesh/cull_mesh/critical_passages_mask_final.220814.nc"
}
Empty file added compass/ocean/mesh/__init__.py
Empty file.
117 changes: 117 additions & 0 deletions ...ass/ocean/tests/global_ocean/mesh/cull.py → compass/ocean/mesh/cull.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,16 +1,133 @@
import xarray
import os

from geometric_features import GeometricFeatures, FeatureCollection, \
read_feature_collection
from mpas_tools.mesh.conversion import cull
from mpas_tools.mesh.mask import compute_mpas_flood_fill_mask
import mpas_tools.io
from mpas_tools.io import write_netcdf
from mpas_tools.ocean import inject_bathymetry
from mpas_tools.ocean.coastline_alteration import widen_transect_edge_masks, \
add_critical_land_blockages, add_land_locked_cells_to_mask
from mpas_tools.viz.paraview_extractor import extract_vtk
from mpas_tools.logging import LoggingContext, check_call

from compass.step import Step


class CullMeshStep(Step):
"""
A step for culling a global MPAS-Ocean mesh
Attributes
----------
base_mesh_step : compass.mesh.spherical.SphericalBaseStep
The base mesh step containing input files to this step
with_ice_shelf_cavities : bool
Whether the mesh includes ice-shelf cavities
do_inject_bathymetry : bool
Whether to interpolate bathymetry from a data file so it
can be used as a culling criteria
preserve_floodplain : bool
Whether to leave land cells in the mesh based on bathymetry
specified by do_inject_bathymetry
"""

def __init__(self, test_case, base_mesh_step, with_ice_shelf_cavities,
name='cull_mesh', subdir=None, do_inject_bathymetry=False,
preserve_floodplain=False):
"""
Create a new step
Parameters
----------
test_case : compass.ocean.tests.global_ocean.mesh.Mesh
The test case this step belongs to
base_mesh_step : compass.mesh.spherical.SphericalBaseStep
The base mesh step containing input files to this step
with_ice_shelf_cavities : bool
Whether the mesh includes ice-shelf cavities
name : str, optional
the name of the step
subdir : str, optional
the subdirectory for the step. The default is ``name``
do_inject_bathymetry : bool, optional
Whether to interpolate bathymetry from a data file so it
can be used as a culling criteria
preserve_floodplain : bool, optional
Whether to leave land cells in the mesh based on bathymetry
specified by do_inject_bathymetry
"""
super().__init__(test_case, name=name, subdir=subdir,
cpus_per_task=None, min_cpus_per_task=None)
self.base_mesh_step = base_mesh_step

for file in ['culled_mesh.nc', 'culled_graph.info',
'critical_passages_mask_final.nc']:
self.add_output_file(filename=file)

self.with_ice_shelf_cavities = with_ice_shelf_cavities
self.do_inject_bathymetry = do_inject_bathymetry
self.preserve_floodplain = preserve_floodplain

def setup(self):
"""
Set up the test case in the work directory, including downloading any
dependencies.
"""
super().setup()
if self.do_inject_bathymetry:
self.add_input_file(
filename='earth_relief_15s.nc',
target='SRTM15_plus_earth_relief_15s.nc',
database='bathymetry_database')

# get the these properties from the config options
config = self.config
# todo: move to constrain_resources()
self.cpus_per_task = config.getint('spherical_mesh',
'cull_mesh_cpus_per_task')
self.min_cpus_per_task = config.getint('spherical_mesh',
'cull_mesh_min_cpus_per_task')

base_path = self.base_mesh_step.path
base_filename = self.base_mesh_step.config.get(
'spherical_mesh', 'mpas_mesh_filename')
target = os.path.join(base_path, base_filename)
self.add_input_file(filename='base_mesh.nc', work_dir_target=target)

def run(self):
"""
Run this step of the test case
"""
with_ice_shelf_cavities = self.with_ice_shelf_cavities
logger = self.logger

# only use progress bars if we're not writing to a log file
use_progress_bar = self.log_filename is None

do_inject_bathymetry = self.do_inject_bathymetry
preserve_floodplain = self.preserve_floodplain

cull_mesh(with_critical_passages=True, logger=logger,
use_progress_bar=use_progress_bar,
preserve_floodplain=preserve_floodplain,
with_cavities=with_ice_shelf_cavities,
process_count=self.cpus_per_task)

if do_inject_bathymetry:
inject_bathymetry(mesh_file='culled_mesh.nc')


def cull_mesh(with_cavities=False, with_critical_passages=False,
custom_critical_passages=None, custom_land_blockages=None,
Expand Down
63 changes: 63 additions & 0 deletions compass/ocean/mesh/floodplain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from mpas_tools.ocean import inject_bathymetry, inject_preserve_floodplain

from compass.mesh.spherical import QuasiUniformSphericalMeshStep


class FloodplainMeshStep(QuasiUniformSphericalMeshStep):
"""
A step for creating a global MPAS-Ocean mesh that includes variables
needed for preserving a floodplain
preserve_floodplain : bool
Whether the mesh includes land cells
"""

def __init__(self, test_case, name='base_mesh', subdir=None,
cell_width=None, preserve_floodplain=True):
"""
Create a new step
Parameters
----------
test_case : compass.testcase.TestCase
The test case this step belongs to
name : str
the name of the step
subdir : {str, None}
the subdirectory for the step. The default is ``name``
cell_width : float, optional
The approximate cell width in km of the mesh if constant resolution
preserve_floodplain : bool, optional
Whether the mesh includes land cells
"""

super().__init__(test_case=test_case, name=name, subdir=subdir,
cell_width=cell_width)

self.preserve_floodplain = preserve_floodplain

self.add_input_file(filename='earth_relief_15s.nc',
target='SRTM15_plus_earth_relief_15s.nc',
database='bathymetry_database')

def run(self):
"""
Run this step of the test case
"""
super().run()

config = self.config

mesh_filename = config.get('spherical_mesh', 'mpas_mesh_filename')

inject_bathymetry(mesh_file=mesh_filename)
if self.preserve_floodplain:
floodplain_elevation = config.getfloat('spherical_mesh',
'floodplain_elevation')
inject_preserve_floodplain(
mesh_file=mesh_filename,
floodplain_elevation=floodplain_elevation)
2 changes: 1 addition & 1 deletion compass/ocean/tests/global_ocean/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def __init__(self, mpas_core):
super().__init__(mpas_core=mpas_core, name='global_ocean')

# we do a lot of tests for QU240/QUwISC240
for mesh_name in ['QU240', 'QUwISC240']:
for mesh_name in ['QU240', 'Icos240', 'QUwISC240']:
mesh = Mesh(test_group=self, mesh_name=mesh_name)
self.add_test_case(mesh)

Expand Down
4 changes: 2 additions & 2 deletions compass/ocean/tests/global_ocean/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ def configure_global_ocean(test_case, mesh, init=None):
The test case that produces the initial condition for this run
"""
config = test_case.config
mesh_step = mesh.mesh_step
config.add_from_package(mesh_step.package, mesh_step.mesh_config_filename,
config.add_from_package('compass.mesh', 'mesh.cfg')
config.add_from_package(mesh.package, mesh.mesh_config_filename,
exception=True)

if mesh.with_ice_shelf_cavities:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def __init__(self, test_case, mesh, restart_filename):
self.add_input_file(filename='restart.nc',
target='../{}'.format(restart_filename))

mesh_path = mesh.mesh_step.path
mesh_path = mesh.get_cull_mesh_path()
self.add_input_file(
filename='graph.info',
work_dir_target='{}/culled_graph.info'.format(mesh_path))
Expand Down
2 changes: 1 addition & 1 deletion compass/ocean/tests/global_ocean/forward.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def __init__(self, test_case, mesh, init, time_integrator, name='forward',
self.add_streams_file(
'compass.ocean.tests.global_ocean', 'streams.bgc')

mesh_package = mesh.mesh_step.package
mesh_package = mesh.package
mesh_package_contents = list(contents(mesh_package))
mesh_namelists = ['namelist.forward',
f'namelist.{time_integrator.lower()}']
Expand Down
20 changes: 12 additions & 8 deletions compass/ocean/tests/global_ocean/global_ocean.cfg
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
# options for global ocean testcases
[global_ocean]
# options for spherical meshes
[spherical_mesh]

## each mesh should replace these with appropriate values in its config file

## config options related to the mesh step
## config options related to the step for culling land from the mesh
# number of cores to use
mesh_cpus_per_task = 18
cull_mesh_cpus_per_task = 18
# minimum of cores, below which the step fails
mesh_min_cpus_per_task = 1
cull_mesh_min_cpus_per_task = 1
# maximum memory usage allowed (in MB)
mesh_max_memory = 1000
cull_mesh_max_memory = 1000


# options for global ocean testcases
[global_ocean]

## each mesh should replace these with appropriate values in its config file

## config options related to the initial_state step
# number of cores to use
Expand Down
4 changes: 2 additions & 2 deletions compass/ocean/tests/global_ocean/init/initial_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def __init__(self, test_case, mesh, initial_condition, with_bgc):
'1timeLevel.nc',
database='initial_condition_database')

mesh_path = mesh.mesh_step.path
mesh_path = self.mesh.get_cull_mesh_path()

self.add_input_file(
filename='mesh.nc',
Expand All @@ -123,7 +123,7 @@ def __init__(self, test_case, mesh, initial_condition, with_bgc):
filename='graph.info',
work_dir_target=f'{mesh_path}/culled_graph.info')

if mesh.with_ice_shelf_cavities:
if self.mesh.with_ice_shelf_cavities:
self.add_input_file(
filename='land_ice_mask.nc',
work_dir_target=f'{mesh_path}/land_ice_mask.nc')
Expand Down
2 changes: 1 addition & 1 deletion compass/ocean/tests/global_ocean/init/ssh_adjustment.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def __init__(self, test_case, ntasks=None, min_tasks=None,
self.add_streams_file('compass.ocean.tests.global_ocean.init',
'streams.ssh_adjust')

mesh_path = test_case.mesh.mesh_step.path
mesh_path = test_case.mesh.get_cull_mesh_path()
init_path = test_case.steps['initial_state'].path

self.add_input_file(
Expand Down
Loading

0 comments on commit c3dceb8

Please sign in to comment.