Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ def run(self):
os.remove(f)

# Place output in the appropriate directory
output_path = os.path.join(output_base_path, "excess_melt",
f"{model}_{scenario}")
output_path = os.path.join(output_base_path, f"{model}_{scenario}",
"excess_melt")
if not os.path.exists(output_path):
os.makedirs(output_path)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ def run(self):
os.remove(f)

# Place output in the appropriate directory
output_path = os.path.join(output_base_path, "lake_properties",
f"{model}_{scenario}")
output_path = os.path.join(output_base_path, f"{model}_{scenario}",
"lake_properties")
if not os.path.exists(output_path):
os.makedirs(output_path)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ def run(self):
os.remove(remapped_file)

# Place output in the appropriate directory
output_path = os.path.join(output_base_path, "shelf_collapse",
f"{model}_{scenario}")
output_path = os.path.join(output_base_path, f"{model}_{scenario}",
"shelf_collapse")
if not os.path.exists(output_path):
os.makedirs(output_path)

Expand Down
6 changes: 3 additions & 3 deletions compass/landice/tests/ismip7_run/ismip7_ais/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
EXPERIMENTS = {
'historical_CESM2-WACCM': {
'scenario': 'historical', 'model': 'CESM2-WACCM',
'start_time': '2000-01-01_00:00:00',
'start_time': '2008-01-01_00:00:00',
Comment thread
trhille marked this conversation as resolved.
'stop_time': '2015-01-01_00:00:00',
'is_historical': True},
'historical_MRI-ESM2-0': {
'scenario': 'historical', 'model': 'MRI-ESM2-0',
'start_time': '2000-01-01_00:00:00',
'start_time': '2008-01-01_00:00:00',
'stop_time': '2015-01-01_00:00:00',
'is_historical': True},
'ssp370_CESM2-WACCM': {
Expand Down Expand Up @@ -62,7 +62,7 @@
'is_historical': False},
'ocx': {
'scenario': 'ocx', 'model': None,
'start_time': '1990-01-01_00:00:00',
'start_time': '2008-01-01_00:00:00',
'stop_time': '2026-01-01_00:00:00',
'is_historical': True},
}
Expand Down
12 changes: 12 additions & 0 deletions compass/landice/tests/ismip7_run/ismip7_ais/ismip7_ais.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ calving_method = restore
# Only required if calving_method is set to 'von_mises'.
von_mises_parameter_path = NotAvailable

# Whether to apply the ISMIP7 Path C ice shelf collapse mask (from
# ismip7_forcing fracture) as hydrofracture-gated mask calving. Expected
# layout: {forcing_basepath}/{model}_{scenario}/shelf_collapse/*.nc
# Not used for historical, ctrl, or ocx experiments. If true and the mask
# file is missing for an experiment that should have one, setup fails.
use_hydrofracture_forcing = true

# Ice fracture toughness (K_IC, Pa m^0.5) used in the hydrofracture
# vulnerability criterion gating mask calving. Only used when
# use_hydrofracture_forcing is true.
calving_fracture_toughness = 2.0e5

# True if running coupled MALI-sea level model simulation
sea_level_model = false

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
config_velocity_solver = 'FO'
config_fem_extension_method = 'ismip7-era'
Comment thread
trhille marked this conversation as resolved.
config_do_velocity_reconstruction_for_external_dycore = .false.
config_unrealistic_velocity = 00.00159
config_nonconvergence_error = .false.
Expand Down
46 changes: 46 additions & 0 deletions compass/landice/tests/ismip7_run/ismip7_ais/set_up_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ def setup(self): # noqa: C901
reference_surface_path = section.get('reference_surface_path')
reference_surface_fname = os.path.split(reference_surface_path)[-1]
calving_method = section.get('calving_method')
use_hydrofracture_forcing = section.getboolean(
'use_hydrofracture_forcing')
calving_fracture_toughness = section.get(
'calving_fracture_toughness')
sea_level_model = section.getboolean('sea_level_model')

exp_info = self.exp_info
Expand Down Expand Up @@ -229,6 +233,27 @@ def setup(self): # noqa: C901
sys.exit(f"ERROR: Expected 1 TF file at {tf_search}, "
f"found {len(tf_list)}: {tf_list}")

# --- Find shelf collapse (calving) mask from ismip7_forcing
# fracture Path C, if requested ---
# historical, ctrl, and ocx experiments never use hydrofracture
# forcing, regardless of use_hydrofracture_forcing.
useCalvingMask = False
if (use_hydrofracture_forcing and
scenario not in ('historical', 'ctrl', 'ocx')):
mask_search = os.path.join(forcing_dir, 'shelf_collapse',
'*ice_shelf_collapse_mask_*.nc')
mask_list = glob.glob(mask_search)
if len(mask_list) == 1:
mask_fname = os.path.split(mask_list[0])[-1]
os.symlink(mask_list[0],
os.path.join(self.work_dir, mask_fname))
useCalvingMask = True
else:
sys.exit(
f"ERROR: use_hydrofracture_forcing is True but did not "
f"find exactly 1 shelf collapse mask file at "
f"{mask_search}: {mask_list}")

# --- Set up streams ---
# Determine forcing interval
if scenario == 'ctrl':
Expand Down Expand Up @@ -266,6 +291,14 @@ def setup(self): # noqa: C901
out_name='streams.landice',
template_replacements=stream_replacements)

if useCalvingMask:
mask_stream_replacements = {
'input_file_calving_mask_forcing_name': mask_fname}
self.add_streams_file(
resource_location, 'streams.mask_calving',
out_name='streams.landice',
template_replacements=mask_stream_replacements)

# --- Set up namelist ---
self.add_namelist_file(
resource_location, 'namelist.landice',
Expand Down Expand Up @@ -307,6 +340,19 @@ def setup(self): # noqa: C901
out_name='streams.landice',
template_replacements=vM_stream_replacements)

# Mask calving options (ismip7_forcing fracture Path C), gated by
# hydrofracture vulnerability (MALI PR #187)
if useCalvingMask:
options = {
'config_apply_calving_mask': ".true.",
'config_restore_calving_front': ".false.",
'config_require_extensional_stresses_for_mask_calving':
".true.",
'config_calving_fracture_toughness':
f'{calving_fracture_toughness}'}
self.add_namelist_options(options=options,
out_name='namelist.landice')

# Sea-level model options
if sea_level_model:
slm_input_ice = section.get('slm_input_ice')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
filename_template="output/output_2d_$Y.nc"
type="output">

<stream name="basicmesh"/>
<stream name="minmesh"/>
<var name="xtime"/>
<var name="simulationStartTime"/>
<var name="thickness"/>
Expand All @@ -128,6 +128,8 @@
<var name="cellMask"/>
<var name="deltat"/>
<var name="ismip6shelfMelt_TFdraft"/>
<var name="calvingMask"/>
<var name="hydrofractureVulnerabilityMask"/>
<var_struct name="timeAveraging"/>
</stream>

Expand Down
12 changes: 12 additions & 0 deletions compass/landice/tests/ismip7_run/ismip7_ais/streams.mask_calving
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<streams>

<stream name="ismip7_calving_mask"
type="input"
filename_template="{{ input_file_calving_mask_forcing_name }}"
input_interval="0001-00-00_00:00:00"
reference_time="2000-01-01_00:00:00"
Comment thread
trhille marked this conversation as resolved.
runtime_format="single_file">
<var name="calvingMask"/>
</stream>

</streams>
2 changes: 1 addition & 1 deletion compass/landice/tests/ismip7_run/ismip7_gris/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
'is_historical': False},
'ocx': {
'scenario': 'ocx', 'model': None,
'start_time': '1990-01-01_00:00:00',
'start_time': '2007-01-01_00:00:00',
'stop_time': '2026-01-01_00:00:00',
'is_historical': True},
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
config_velocity_solver = 'FO'
config_fem_extension_method = 'ismip7-era'
config_do_velocity_reconstruction_for_external_dycore = .false.
config_unrealistic_velocity = 00.00159
config_nonconvergence_error = .false.
Expand Down
25 changes: 18 additions & 7 deletions docs/developers_guide/landice/test_groups/ismip7_run.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,27 @@ The ``setup`` method sets up the experiment directory by:
and restart frequency.
5. Adding calving-specific streams (face melting, von Mises params) if
configured.
6. Creating a restart symlink for projection experiments pointing to
6. If ``use_hydrofracture_forcing`` is true and the experiment's scenario
is not ``historical``, ``ctrl``, or ``ocx``, looking for a single Path C
``ice_shelf_collapse_mask_*.nc`` file under
``{forcing_basepath}/{model}_{scenario}/shelf_collapse/`` (from
:ref:`landice_ismip7_forcing_fracture`). If found, it is symlinked in,
the ``streams.mask_calving`` stream is added, and
``config_apply_calving_mask``, ``config_restore_calving_front``,
``config_require_extensional_stresses_for_mask_calving``, and
``config_calving_fracture_toughness`` are set accordingly. If not
found, setup fails with an error, since the mask is required whenever
``use_hydrofracture_forcing`` is true for that scenario.
7. Creating a restart symlink for projection experiments pointing to
the corresponding ESM's historical restart
(``../historical_{model}/rst.2015-01-01.nc``).
7. Setting up CTRL2015 experiments with constant-climate forcing
8. Setting up CTRL2015 experiments with constant-climate forcing
(``initial_only`` intervals).
8. Setting up the OCX experiment with reanalysis-based forcing.
9. If SLM coupling is enabled, adding a ``CreateSlmMappingFiles`` step
and writing the SLM namelist from the Jinja2 template.
10. Generating a ``graph.info`` file and a SLURM job script.
11. Symlinking the compass load script into the run directory.
9. Setting up the OCX experiment with reanalysis-based forcing.
10. If SLM coupling is enabled, adding a ``CreateSlmMappingFiles`` step
and writing the SLM namelist from the Jinja2 template.
11. Generating a ``graph.info`` file and a SLURM job script.
12. Symlinking the compass load script into the run directory.

The ``run`` method executes MALI for the given experiment.

Expand Down
9 changes: 6 additions & 3 deletions docs/users_guide/landice/test_groups/ismip7_forcing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ Processed forcing is written under ``output_base_path`` in a layout that the
{output_base_path}/{group}/atmosphere/{mesh}_temperature_{source}_{scenario}_{years}.nc
{output_base_path}/{group}/atmosphere/{mesh}_runoff_... (and the two gradients)
{output_base_path}/{group}/ocean_thermal_forcing/{mesh}_thermal_forcing_{source}_{scenario}_{years}.nc
{output_base_path}/{group}/shelf_collapse/{mesh}_ice_shelf_collapse_mask_*.nc
{output_base_path}/{group}/excess_melt/{mesh}_excess_melt_*.nc
{output_base_path}/{group}/lake_properties/{mesh}_lake_properties_*.nc

The ``group`` directory is ``{model}_{scenario}`` for ESM scenarios and ``OCX``
for GrIS OCX. AIS OCX writes one group per selected ocean product,
Expand Down Expand Up @@ -365,7 +368,7 @@ is useful when only some of the pathway source files are available.
(melt + rain after firn air content depletion), matching
``excess_melt_*.nc``. The output variable is ``ismip7ExcessMelt``
(converted from mm w.e. yr-1 to SI units of kg m-2 s-1) and is written to
``{output_base_path}/excess_melt/{model}_{scenario}/``. Conservative
``{output_base_path}/{model}_{scenario}/excess_melt/``. Conservative
remapping is used by default since this is a flux. This source file has no
``x``/``y`` coordinate variables and its array is flipped along the y axis
relative to the other fracture files, so the step reconstructs the source
Expand All @@ -376,7 +379,7 @@ is useful when only some of the pathway source files are available.
depth and area fraction from the Grau et al. (2025) parameterization,
matching ``lake_properties_*.nc``. The output variables are
``ismip7LakeDepth`` (m) and ``ismip7LakeAreaFraction`` (unitless), written
to ``{output_base_path}/lake_properties/{model}_{scenario}/``. Bilinear
to ``{output_base_path}/{model}_{scenario}/lake_properties/``. Bilinear
remapping is used by default.

* **process_shelf_collapse** (Path C): Remaps the annual ice shelf collapse
Expand All @@ -389,7 +392,7 @@ is useful when only some of the pathway source files are available.
that the 0/1 mask values are preserved, and the remapped mask is rounded to
0/1. The output variable is ``calvingMask`` with an accompanying ``xtime``
variable, and the result is written to
``{output_base_path}/shelf_collapse/{model}_{scenario}/``.
``{output_base_path}/{model}_{scenario}/shelf_collapse/``.

All three pathways produce continuous fields (Paths A and B) or a discrete
mask (Path C) with an accompanying ``xtime`` variable. The output variable
Expand Down
56 changes: 53 additions & 3 deletions docs/users_guide/landice/test_groups/ismip7_run.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,21 @@ Usage
├── CESM2-WACCM_historical/
│ ├── atmosphere/
│ │ └── {mesh}_smb_CESM2-WACCM_historical_*.nc
│ └── ocean_thermal_forcing/
│ └── {mesh}_thermal_forcing_CESM2-WACCM_historical_*.nc
│ ├── ocean_thermal_forcing/
│ │ └── {mesh}_thermal_forcing_CESM2-WACCM_historical_*.nc
│ └── shelf_collapse/
│ └── {mesh}_ice_shelf_collapse_mask_*.nc
├── CESM2-WACCM_ssp585/
│ ├── atmosphere/
│ └── ocean_thermal_forcing/
│ ├── ocean_thermal_forcing/
│ └── shelf_collapse/
└── ...

The ``shelf_collapse`` subdirectory (ISMIP7 Path C ice shelf collapse
mask, produced by :ref:`landice_ismip7_forcing_fracture`) is required
for ``ssp*`` experiments unless ``use_hydrofracture_forcing`` is set to
``false``; see :ref:`landice_ismip7_run_mask_calving` below.

3. Create a user config file overriding the ``NotAvailable`` paths.

4. Set up and run::
Expand Down Expand Up @@ -168,6 +176,17 @@ All config options should be reviewed and altered as needed.
calving_method = restore
von_mises_parameter_path = NotAvailable

# Whether to apply the ISMIP7 Path C ice shelf collapse mask as
# hydrofracture-gated mask calving (not used for historical, ctrl, or
# ocx experiments). If true, setup fails when the mask file is missing
# for an experiment that should have one.
use_hydrofracture_forcing = true

# Ice fracture toughness (Pa m^0.5) for the hydrofracture vulnerability
# criterion gating mask calving, used only when use_hydrofracture_forcing
# is true.
calving_fracture_toughness = 2.0e5

# Face melting
use_face_melting = false

Expand Down Expand Up @@ -211,6 +230,37 @@ ISMIP7 uses more forcing fields than ISMIP6, at mixed temporal resolutions:
For CTRL2015 experiments, all forcing intervals are set to
``initial_only`` (constant climate).

.. _landice_ismip7_run_mask_calving:

Mask Calving (Path C)
----------------------

``ismip7_ais`` can optionally apply the ISMIP7 Path C ice shelf collapse
mask produced by :ref:`landice_ismip7_forcing_fracture`. The mask is looked
up under the same ``forcing_basepath`` used for the atmosphere/ocean
forcing, at
``{forcing_basepath}/{model}_{scenario}/shelf_collapse/*ice_shelf_collapse_mask_*.nc``.
``historical``, ``ctrl``, and ``ocx`` experiments never use this pathway,
regardless of ``use_hydrofracture_forcing``.

When ``use_hydrofracture_forcing`` is ``true`` (the default) for any other
experiment (e.g. ``ssp126``, ``ssp370``, ``ssp585``), a matching mask file
is required: if it is missing, ``compass setup`` fails with an error rather
than silently skipping mask calving. When found, the mask is symlinked into
the run directory and used to force calving:

* ``config_apply_calving_mask`` is set to ``.true.``
* ``config_restore_calving_front`` is set to ``.false.``
* ``config_require_extensional_stresses_for_mask_calving`` is set to
``.true.``, so the mask only removes floating ice that is also vulnerable
to hydrofracture per the fracture-toughness criterion of Lai et al.
(2020) / Reynolds and Nowicki (2026). The threshold depends on
``config_calving_fracture_toughness``.

Set ``use_hydrofracture_forcing = false`` to disable mask calving and the
hydrofracture gating entirely; experiments then use their normal
``calving_method`` configuration instead.

.. _landice_ismip7_run_ais:

ismip7_ais
Expand Down
Loading