Reduce number of empty cells in extended high-resolution Greenland Ice Sheet mesh#937
Reduce number of empty cells in extended high-resolution Greenland Ice Sheet mesh#937trhille wants to merge 12 commits intoMPAS-Dev:mainfrom
Conversation
Add option to set resolution in ocean based on distance from coast.
Fix coast mask definition
Remove constraint that forces maximum resolution everywhere on bare land, which leads to enormous numbers of wasted cells in Greenland.
Create a separate .cfg file for the 1–10km Greenland mesh, and change the default resolution from 3–30km to 4–40km to avoid out-of-memory errors when running ESMF_RegridWeightGen on a single Perlmutter node.
b26249d to
a02af8d
Compare
Fix unconditional reads from config file in set_cell_width, so that the config file does not need to have high_dist_coast if use_dist_to_coast == False, for example.
Remove mention of using scikit-fmm to calculate distances to grounding line, coast, and margin, since this algorithm is now very fast.
|
All |
|
docs can be found here: https://portal.nersc.gov/cfs/fanssie/trhille/compass_docs_PR937/html/ |
There was a problem hiding this comment.
Pull request overview
This PR updates the Greenland high-resolution mesh-generation workflow to reduce “wasted” (empty) cells in an extended 1–10 km mesh by refining ocean resolution near the coast while allowing coarser resolution farther offshore and over bare land.
Changes:
- Add a new coast-based mesh-density control (
use_dist_to_coast,high_dist_coast,low_dist_coast) and propagate it through cell-width generation. - Update Greenland mesh-gen defaults (e.g.,
cull_distance, min/max spacing) and add an alternativemesh_gen_1to10km.cfg. - Update Users/Developers documentation (including BedMachine v6 references and new config guidance).
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/users_guide/landice/test_groups/greenland.rst | Updates user-facing config snippet and documents the new 1–10 km alternative config and coast refinement option |
| docs/developers_guide/landice/test_groups/greenland.rst | Updates developer description to BedMachine v6 and mentions the alternative 1–10 km config |
| docs/developers_guide/landice/framework.rst | Documents new/conditional mesh-density options including use_dist_to_coast |
| compass/landice/tests/greenland/mesh_gen/mesh_gen_1to10km.cfg | Adds an alternative Greenland mesh-gen config targeting a finer 1–10 km mesh |
| compass/landice/tests/greenland/mesh_gen/mesh_gen.cfg | Updates Greenland mesh-gen defaults and adds coast-distance parameters |
| compass/landice/mesh.py | Implements coast-distance-based spacing and returns distance-to-coast from distance computation routine |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| land_mask = np.logical_and(thk == 0.0, bed >= 0.) | ||
| ocean_mask = np.logical_and(thk == 0.0, bed < 0.) | ||
|
|
||
| # Cell spacing function based on union of masks | ||
| if section.get('use_bed') == 'True': |
There was a problem hiding this comment.
set_cell_width() now computes land_mask/ocean_mask using comparisons on bed, but bed is still an optional argument (and may be None when use_bed = False). This will raise at runtime if bed is not provided. Consider either making bed required (and validating early with a clear error) or guarding these masks behind a bed is not None check.
| land_mask = np.logical_and(thk == 0.0, bed >= 0.) | |
| ocean_mask = np.logical_and(thk == 0.0, bed < 0.) | |
| # Cell spacing function based on union of masks | |
| if section.get('use_bed') == 'True': | |
| use_bed = section.get('use_bed') == 'True' | |
| if bed is None: | |
| if use_bed: | |
| raise ValueError( | |
| 'bed must be provided when use_bed is True in ' | |
| f'section "{section_name}".') | |
| land_mask = (thk == 0.0) | |
| ocean_mask = np.zeros_like(thk, dtype=bool) | |
| else: | |
| land_mask = np.logical_and(thk == 0.0, bed >= 0.) | |
| ocean_mask = np.logical_and(thk == 0.0, bed < 0.) | |
| # Cell spacing function based on union of masks | |
| if use_bed: |
| following options to be set in the given config section: | ||
| ``levels``, ``x_min``, ``x_max``, ``y_min``, ``y_max``, | ||
| ``min_spac``, ``max_spac``, ``high_log_speed``, ``low_log_speed``, | ||
| ``high_dist``, ``low_dist``, ``high_dist_bed``, ``low_dist_bed``, | ||
| ``high_bed``, ``low_bed``, ``cull_distance``, ``use_speed``, | ||
| ``use_dist_to_edge``, ``use_dist_to_grounding_line``, and ``use_bed``. | ||
| ``high_dist``, ``low_dist``, ``high_dist_coast``, ``low_dist_coast``, | ||
| ``high_dist_bed``, ``low_dist_bed``, ``high_bed``, ``low_bed``, | ||
| ``cull_distance``, ``use_speed``, ``use_dist_to_edge``, | ||
| ``use_dist_to_grounding_line``, ``use_dist_to_coast``, and ``use_bed``. |
There was a problem hiding this comment.
The docstring lists high_log_speed/low_log_speed, high_dist/low_dist, high_dist_coast/low_dist_coast, and bed-related options as always required, but the implementation only reads these when the corresponding use_* flag is enabled. Please update the docstring to reflect which options are unconditional vs. conditional to avoid misleading config authors.
There was a problem hiding this comment.
The docstring does not actually say these are required. I agree the phrasing there is a little vague, but the docstring points to documentation for more information, and I think that's the more appropriate place to add this explanation.
| low_dist = 1.e4 | ||
| # distance at which cell spacing in ocean = max_spac | ||
| high_dist_coast = 16.e3 | ||
| # distance within which cell spaceing in ocean = min_spac |
There was a problem hiding this comment.
Typo in the comment: "spaceing" → "spacing".
| # distance within which cell spaceing in ocean = min_spac | |
| # distance within which cell spacing in ocean = min_spac |
| # path to directory containing BedMachine and Measures datasets | ||
| # (default value is for Perlmutter) | ||
| data_path = /global/cfs/cdirs/fanssie/standard_datasets/GIS_datasets/ | ||
|
|
There was a problem hiding this comment.
interpolate_data is not set in this config. In compass/landice/tests/greenland/mesh.py, the default fallback is False, so optional interpolation will be skipped even though dataset paths/filenames are provided below. Consider adding interpolate_data = True/False explicitly to make the intended behavior clear.
| # whether to interpolate the input datasets onto the mesh | |
| # set explicitly to preserve the current default behavior | |
| interpolate_data = False |
Define coast mask as last land or ice cell adjacent to ocean, rather than last ocean cell adjacent to land or ice. Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Fix minor typos. Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Make `bed` required input argument for set_cell_width(), in keeping with new land and ocean masks that use `bed` for calculations. Also some minor cleanup from code review: fix typo and set `interpolate_data` in greenland 1-10km .cfg file.
Update framework in users and developers guides to explain which .cfg settings are required and which are optional.



This merge includes changes needed for a new high-resolution (1–10 km) extended Greenland mesh with variable mesh resolution in the ocean and bare land. The goal is to have high enough resolution in the ocean to resolve fjords for coupling with the ocean, but to use lower resolution where possible to reduce wasted cells. The extended 1–10km without these changes contains 1.4 million cells, only ~350k of which contain ice. With these changes, the extended 1–10km mesh is 870k cells.
Checklist
Testingin this PR) any testing that was used to verify the changes