Skip to content

Commit 559418a

Browse files
authored
Merge pull request #723 from cbegeman/ocn-fix-grounded-land-ice-pressure
Fixup ISOMIP+ land ice pressure: This PR changes the calculation of land ice pressure for ISOMIP+ thin-film test cases so that it is a function of the land ice thickness rather than land ice draft. The land ice pressure is not perfectly identical between Ocean0 and thin_film_Ocean0 test cases, mostly because in the former case we smooth the draft and in the latter we smooth ice thickness. This PR also fixes a bug wherein the thin film region was culled from the domain.
2 parents f848537 + 602d98e commit 559418a

File tree

17 files changed

+713
-356
lines changed

17 files changed

+713
-356
lines changed

compass/ocean/iceshelf.py

Lines changed: 72 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,94 @@
1111
from compass.model import partition, run_model
1212

1313

14-
def compute_land_ice_pressure_and_draft(ssh, modify_mask, ref_density):
14+
def compute_land_ice_pressure_from_thickness(land_ice_thickness, modify_mask,
15+
land_ice_density=None):
1516
"""
16-
Compute the pressure from and overlying ice shelf and the ice-shelf draft
17+
Compute the pressure from an overlying ice shelf from ice thickness
1718
1819
Parameters
1920
----------
20-
ssh : xarray.DataArray
21-
The sea surface height (the ice draft)
21+
land_ice_thickness: xarray.DataArray
22+
The ice thickness
2223
2324
modify_mask : xarray.DataArray
2425
A mask that is 1 where ``landIcePressure`` can be deviate from 0
2526
26-
ref_density : float
27+
land_ice_density : float, optional
28+
A reference density for land ice
29+
30+
Returns
31+
-------
32+
land_ice_pressure : xarray.DataArray
33+
The pressure from the overlying land ice on the ocean
34+
"""
35+
gravity = constants['SHR_CONST_G']
36+
if land_ice_density is None:
37+
land_ice_density = constants['SHR_CONST_RHOICE']
38+
land_ice_pressure = modify_mask * \
39+
numpy.maximum(land_ice_density * gravity * land_ice_thickness, 0.)
40+
return land_ice_pressure
41+
42+
43+
def compute_land_ice_pressure_from_draft(land_ice_draft, modify_mask,
44+
ref_density=None):
45+
"""
46+
Compute the pressure from an overlying ice shelf from ice draft
47+
48+
Parameters
49+
----------
50+
land_ice_draft : xarray.DataArray
51+
The ice draft (sea surface height)
52+
53+
modify_mask : xarray.DataArray
54+
A mask that is 1 where ``landIcePressure`` can be deviate from 0
55+
56+
ref_density : float, optional
2757
A reference density for seawater displaced by the ice shelf
2858
2959
Returns
3060
-------
31-
landIcePressure : xarray.DataArray
61+
land_ice_pressure : xarray.DataArray
3262
The pressure from the overlying land ice on the ocean
63+
"""
64+
gravity = constants['SHR_CONST_G']
65+
if ref_density is None:
66+
ref_density = constants['SHR_CONST_RHOSW']
67+
land_ice_pressure = \
68+
modify_mask * numpy.maximum(-ref_density * gravity * land_ice_draft,
69+
0.)
70+
return land_ice_pressure
71+
72+
73+
def compute_land_ice_draft_from_pressure(land_ice_pressure, modify_mask,
74+
ref_density=None):
75+
"""
76+
Compute the ice-shelf draft associated with the pressure from an overlying
77+
ice shelf
78+
79+
Parameters
80+
----------
81+
land_ice_pressure : xarray.DataArray
82+
The pressure from the overlying land ice on the ocean
83+
84+
modify_mask : xarray.DataArray
85+
A mask that is 1 where ``landIcePressure`` can be deviate from 0
3386
34-
landIceDraft : xarray.DataArray
35-
The ice draft, equal to the initial ``ssh``
87+
ref_density : float, optional
88+
A reference density for seawater displaced by the ice shelf
89+
90+
Returns
91+
-------
92+
land_ice_draft : xarray.DataArray
93+
The ice draft
3694
"""
3795
gravity = constants['SHR_CONST_G']
38-
landIcePressure = \
39-
modify_mask * numpy.maximum(-ref_density * gravity * ssh, 0.)
40-
landIceDraft = ssh
41-
return landIcePressure, landIceDraft
96+
if ref_density is None:
97+
ref_density = constants['SHR_CONST_RHOSW']
98+
land_ice_draft_array = \
99+
modify_mask * -land_ice_pressure / (ref_density * gravity)
100+
land_ice_draft = land_ice_draft_array.transpose(*land_ice_pressure.dims)
101+
return land_ice_draft
42102

43103

44104
def adjust_ssh(variable, iteration_count, step, update_pio=True,

compass/ocean/tests/ice_shelf_2d/initial_state.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from mpas_tools.mesh.conversion import convert, cull
66
from mpas_tools.planar_hex import make_planar_hex_mesh
77

8-
from compass.ocean.iceshelf import compute_land_ice_pressure_and_draft
8+
from compass.ocean.iceshelf import compute_land_ice_pressure_from_draft
99
from compass.ocean.vertical import init_vertical_coord
1010
from compass.step import Step
1111

@@ -103,8 +103,10 @@ def run(self):
103103
landIceFloatingMask = landIceMask.copy()
104104

105105
ref_density = constants['SHR_CONST_RHOSW']
106-
landIcePressure, landIceDraft = compute_land_ice_pressure_and_draft(
107-
ssh=ds.ssh, modify_mask=modify_mask, ref_density=ref_density)
106+
landIceDraft = ds.ssh
107+
landIcePressure = compute_land_ice_pressure_from_draft(
108+
land_ice_draft=landIceDraft, modify_mask=modify_mask,
109+
ref_density=ref_density)
108110

109111
salinity = surface_salinity + ((bottom_salinity - surface_salinity) *
110112
(ds.zMid / (-bottom_depth)))

compass/ocean/tests/isomip_plus/__init__.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def __init__(self, mpas_core):
3636
experiment=experiment,
3737
vertical_coordinate=vertical_coordinate,
3838
time_varying_forcing=True))
39-
for vertical_coordinate in ['z-star', 'sigma', 'single_layer']:
39+
for vertical_coordinate in ['z-star', 'sigma']:
4040
self.add_test_case(
4141
IsomipPlusTest(
4242
test_group=self, resolution=resolution,
@@ -50,7 +50,7 @@ def __init__(self, mpas_core):
5050
vertical_coordinate=vertical_coordinate,
5151
time_varying_forcing=True,
5252
thin_film_present=True))
53-
for vertical_coordinate in ['sigma', 'single_layer']:
53+
for vertical_coordinate in ['z-star', 'sigma']:
5454
self.add_test_case(
5555
IsomipPlusTest(
5656
test_group=self, resolution=resolution,
@@ -67,22 +67,7 @@ def __init__(self, mpas_core):
6767
time_varying_forcing=True,
6868
time_varying_load='decreasing',
6969
thin_film_present=True))
70-
for vertical_coordinate in ['sigma']:
71-
self.add_test_case(
72-
IsomipPlusTest(
73-
test_group=self, resolution=resolution,
74-
experiment=experiment,
75-
vertical_coordinate=vertical_coordinate,
76-
tidal_forcing=True,
77-
thin_film_present=True))
78-
for vertical_coordinate in ['single_layer']:
79-
self.add_test_case(
80-
IsomipPlusTest(
81-
test_group=self, resolution=resolution,
82-
experiment=experiment,
83-
vertical_coordinate=vertical_coordinate,
84-
tidal_forcing=True,
85-
thin_film_present=False))
70+
for vertical_coordinate in ['sigma', 'z-star']:
8671
self.add_test_case(
8772
IsomipPlusTest(
8873
test_group=self, resolution=resolution,

compass/ocean/tests/isomip_plus/forward.py

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
1-
import os
2-
import shutil
3-
4-
import numpy as np
5-
import xarray
6-
71
from compass.model import run_model
82
from compass.ocean.tests.isomip_plus.evap import update_evaporation_flux
9-
from compass.ocean.tests.isomip_plus.viz.plot import MoviePlotter
103
from compass.ocean.time import get_time_interval_string
114
from compass.step import Step
125

@@ -157,78 +150,6 @@ def run(self):
157150

158151
run_model(self)
159152

160-
if self.name == 'performance':
161-
# plot a few fields
162-
plot_folder = f'{self.work_dir}/plots'
163-
if os.path.exists(plot_folder):
164-
shutil.rmtree(plot_folder)
165-
166-
dsMesh = xarray.open_dataset(os.path.join(self.work_dir,
167-
'init.nc'))
168-
ds = xarray.open_dataset(os.path.join(self.work_dir, 'output.nc'))
169-
170-
section_y = self.config.getfloat('isomip_plus_viz', 'section_y')
171-
# show progress only if we're not writing to a log file
172-
show_progress = self.log_filename is None
173-
plotter = MoviePlotter(inFolder=self.work_dir,
174-
streamfunctionFolder=self.work_dir,
175-
outFolder=plot_folder, sectionY=section_y,
176-
dsMesh=dsMesh, ds=ds, expt=self.experiment,
177-
showProgress=show_progress)
178-
179-
plotter.plot_horiz_series(ds.ssh, 'ssh', 'ssh',
180-
True, vmin=-700, vmax=0)
181-
plotter.plot_3d_field_top_bot_section(
182-
ds.temperature, nameInTitle='temperature', prefix='temp',
183-
units='C', vmin=-2., vmax=1., cmap='cmo.thermal')
184-
185-
plotter.plot_3d_field_top_bot_section(
186-
ds.salinity, nameInTitle='salinity', prefix='salin',
187-
units='PSU', vmin=33.8, vmax=34.7, cmap='cmo.haline')
188-
tol = 1e-10
189-
dsIce = xarray.open_dataset(
190-
os.path.join(self.work_dir,
191-
'land_ice_fluxes.nc'))
192-
if 'topDragMagnitude' in dsIce.keys():
193-
plotter.plot_horiz_series(
194-
dsIce.topDragMagnitude,
195-
'topDragMagnitude', 'topDragMagnitude', True,
196-
vmin=0 + tol, vmax=np.max(dsIce.topDragMagnitude.values),
197-
cmap_set_under='k')
198-
if 'landIceHeatFlux' in dsIce.keys():
199-
plotter.plot_horiz_series(
200-
dsIce.landIceHeatFlux,
201-
'landIceHeatFlux', 'landIceHeatFlux', True,
202-
vmin=np.min(dsIce.landIceHeatFlux.values),
203-
vmax=np.max(dsIce.landIceHeatFlux.values))
204-
if 'landIceInterfaceTemperature' in dsIce.keys():
205-
plotter.plot_horiz_series(
206-
dsIce.landIceInterfaceTemperature,
207-
'landIceInterfaceTemperature',
208-
'landIceInterfaceTemperature',
209-
True,
210-
vmin=np.min(dsIce.landIceInterfaceTemperature.values),
211-
vmax=np.max(dsIce.landIceInterfaceTemperature.values))
212-
if 'landIceFreshwaterFlux' in dsIce.keys():
213-
plotter.plot_horiz_series(
214-
dsIce.landIceFreshwaterFlux,
215-
'landIceFreshwaterFlux', 'landIceFreshwaterFlux', True,
216-
vmin=0 + tol, vmax=1e-4,
217-
cmap_set_under='k', cmap_scale='log')
218-
if 'landIceFraction' in dsIce.keys():
219-
plotter.plot_horiz_series(
220-
dsIce.landIceFraction,
221-
'landIceFraction', 'landIceFraction', True,
222-
vmin=0 + tol, vmax=1 - tol,
223-
cmap='cmo.balance',
224-
cmap_set_under='k', cmap_set_over='r')
225-
if 'landIceFloatingFraction' in dsIce.keys():
226-
plotter.plot_horiz_series(
227-
dsIce.landIceFloatingFraction,
228-
'landIceFloatingFraction', 'landIceFloatingFraction',
229-
True, vmin=0 + tol, vmax=1 - tol,
230-
cmap='cmo.balance', cmap_set_under='k', cmap_set_over='r')
231-
232153
if self.name == 'simulation':
233154
update_evaporation_flux(
234155
in_forcing_file='forcing_data_init.nc',

compass/ocean/tests/isomip_plus/geom.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,12 @@ def interpolate_geom(ds_mesh, ds_geom, min_ocean_fraction, thin_film_present):
111111
ds_geom.landIceGroundedFraction)
112112

113113
# mask the topography to the ocean region before interpolation
114-
for var in ['Z_bed', 'Z_ice_draft', 'landIceFraction',
114+
for var in ['Z_bed', 'Z_ice_surface', 'Z_ice_draft', 'landIceFraction',
115115
'landIceFloatingFraction', 'smoothedDraftMask']:
116116
ds_geom[var] = ds_geom[var] * ds_geom['oceanFraction']
117117

118118
fields = {'bottomDepthObserved': 'Z_bed',
119+
'landIceThickness': 'iceThickness',
119120
'ssh': 'Z_ice_draft',
120121
'oceanFracObserved': 'oceanFraction',
121122
'landIceFraction': 'landIceFraction',
@@ -156,7 +157,7 @@ def _get_geom_fields(ds_geom, ds_mesh, thin_film_present):
156157
y_cell = ds_mesh.yIsomipCell.values
157158

158159
if thin_film_present:
159-
ocean_fraction = - ds_geom['landFraction'] + 1.0
160+
ocean_fraction = xarray.where(ds_geom['Z_bed'] > 0., 0., 1.)
160161
else:
161162
ocean_fraction = (ds_geom['landIceFloatingFraction'] +
162163
ds_geom['openOceanFraction'])

0 commit comments

Comments
 (0)