Skip to content

Commit 6fedb76

Browse files
committed
Add SMB and BMB forcing fields
Adds surface and basal mass balances fields and their respective uncertainties to the uummmannaq/disko mesh_gen test case. used for the dhdt albany optimization
1 parent 5879744 commit 6fedb76

File tree

2 files changed

+147
-6
lines changed

2 files changed

+147
-6
lines changed

compass/landice/tests/uummannaq_disko/mesh.py

Lines changed: 141 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import jigsawpy
55
import numpy as np
66
import xarray as xr
7+
from mpas_tools.logging import check_call
78
from mpas_tools.scrip.from_mpas import scrip_from_mpas
89

910
from compass.landice.mesh import (
@@ -81,9 +82,13 @@ def run(self):
8182
data_path = section_gis.get('data_path')
8283
measures_filename = section_gis.get("measures_filename")
8384
bedmachine_filename = section_gis.get("bedmachine_filename")
85+
smb_filename = section_gis.get("smb_filename")
86+
bmb_filename = section_gis.get("bmb_filename")
8487

8588
measures_dataset = os.path.join(data_path, measures_filename)
8689
bedmachine_dataset = os.path.join(data_path, bedmachine_filename)
90+
smb_dataset = os.path.join(data_path, smb_filename)
91+
bmb_dataset = os.path.join(data_path, bmb_filename)
8792

8893
section_name = 'mesh'
8994

@@ -133,6 +138,127 @@ def run(self):
133138
self.mesh_filename, src_proj,
134139
variables=measures_vars)
135140

141+
# Insert SMB fields for dh/dt constraint
142+
# Create copy of smb file with mean and stdev smb
143+
# for 2002 – 2012, named to be consistent with MALI
144+
start_yr = 52 # 2002
145+
end_yr = 63 # 2012
146+
147+
file, ext = os.path.splitext(smb_dataset)
148+
smb_altered = file + '.tmp.copy' + ext
149+
150+
ds = xr.open_dataset(smb_dataset)
151+
smb_rec = ds['smb_rec'][start_yr:end_yr, :, :].values
152+
smb_mean = np.nanmean(smb_rec, axis=0).astype('float64')
153+
smb_stdev = np.nanstd(smb_rec, axis=0).astype('float64')
154+
x = ds['x'].values
155+
y = ds['y'].values
156+
ds['x'] = xr.DataArray(x.astype('int32'), dims=("x"),
157+
attrs={'units': 'm'})
158+
ds['y'] = xr.DataArray(y.astype('int32'), dims=("y"),
159+
attrs={'units': 'm'})
160+
ds['x1'] = ds['x']
161+
ds['y1'] = ds['y']
162+
ds['sfcMassBal'] = xr.DataArray(smb_mean, dims=("y", "x"))
163+
ds['sfcMassBalUncertainty'] = xr.DataArray(smb_stdev, dims=("y", "x"))
164+
ds.to_netcdf(smb_altered)
165+
ds.close()
166+
167+
args = (["ncatted", "-a", "_FillValue,,d,,", smb_altered])
168+
check_call(args)
169+
170+
# interpolate
171+
smb_scrip = ['smb_rec.1950-2014.BN_RACMO2.'
172+
'3p2-CESM2-Historical.1km.YY.scrip.nc']
173+
args = ['create_scrip_file_from_planar_rectangular_grid',
174+
'-i', smb_altered,
175+
'-s', smb_scrip,
176+
'-p', 'gis-gimp', '-r', '2']
177+
check_call(args)
178+
179+
args = [parallel_executable, '-n', nProcs, 'ESMF_RegridWeightGen',
180+
'--source', smb_scrip, '--destination', dst_scrip_file,
181+
'--weight', 'SMB_to_UD_weights.nc',
182+
'--method', 'conserve', '--netcdf4',
183+
'--dst_regional', '--src_regional', '--ignore_unmapped']
184+
check_call(args)
185+
186+
args = ['ncremap', '-i', smb_altered,
187+
'-o', 'smb_remapped.nc',
188+
'-m', 'SMB_to_UD_weights.nc',
189+
'-v', 'sfcMassBal,sfcMassBalUncertainty']
190+
check_call(args)
191+
192+
# Repeat with BMB fields for dh/dt constraint
193+
# rename variables to be compatible
194+
# with MALI and interpolator
195+
196+
# interpolate
197+
bmb_scrip = 'basalmelt_Karlssonetal2021_updated2022.scrip.nc'
198+
args = ['create_scrip_file_from_planar_rectangular_grid',
199+
'-i', bmb_dataset,
200+
'-s', bmb_scrip,
201+
'-p', 'gis-gimp', '-r', '2']
202+
check_call(args)
203+
204+
args = [parallel_executable, '-n', nProcs, 'ESMF_RegridWeightGen',
205+
'--source', bmb_scrip, '--destination', dst_scrip_file,
206+
'--weight', 'BMB_to_UD_weights.nc',
207+
'--method', 'conserve', '--netcdf4',
208+
'--dst_regional', '--src_regional', '--ignore_unmapped']
209+
check_call(args)
210+
211+
args = ['ncremap', '-i', bmb_dataset,
212+
'-o', 'bmb_remapped.nc',
213+
'-m', 'BMB_to_UD_weights.nc',
214+
'-v', 'bmb,bmbErr']
215+
check_call(args)
216+
217+
# transfer remapped SMB and BMB to final mesh
218+
ds_bmb = xr.open_dataset('bmb_remapped.nc')
219+
ds_smb = xr.open_dataset('smb_remapped.nc')
220+
ds = xr.open_dataset(self.mesh_filename)
221+
222+
bmb = ds_bmb['bmb'].values
223+
bmbErr = ds_bmb['bmbErr'].values
224+
smb = ds_smb['sfcMassBal'].values
225+
smbU = ds_smb['sfcMassBalUncertainty'].values
226+
227+
# unit conversions to MALI standards
228+
# mm w.e./yr to kg/(m2 s)
229+
smb = smb / 3.15e7
230+
smbU = smbU / 3.15e7
231+
# m/yr to kg/(m2 s)
232+
bmb = (bmb * 910) / 3.15e7
233+
bmbErr = (bmbErr * 910) / 3.15e7
234+
235+
bmb = bmb.reshape(1, len(bmb))
236+
bmbErr = bmbErr.reshape(1, len(bmbErr))
237+
smb = smb.reshape(1, len(smb))
238+
smbU = smbU.reshape(1, len(smbU))
239+
240+
ds['floatingBasalMassBal'] = \
241+
xr.DataArray(bmb,
242+
dims=("Time", "nCells"),
243+
attrs={'units': 'kg m^-2 s^-1'})
244+
ds['floatingBasalMassBalUncertainty'] = \
245+
xr.DataArray(bmbErr, dims=("Time", "nCells"),
246+
attrs={'units': 'kg m^-2 s^-1'})
247+
ds['sfcMassBal'] = xr.DataArray(smb, dims=("Time", "nCells"),
248+
attrs={'units': 'kg m^-2 s^-1'})
249+
ds['sfcMassBalUncertainty'] = \
250+
xr.DataArray(smbU,
251+
dims=("Time", "nCells"),
252+
attrs={'units': 'kg m^-2 s^-1'})
253+
254+
ds.to_netcdf(self.mesh_filename, 'a')
255+
ds.close()
256+
ds_smb.close()
257+
ds_bmb.close()
258+
259+
args = (["ncatted", "-a", "_FillValue,,d,,", self.mesh_filename])
260+
check_call(args)
261+
136262
# perform some final cleanup details
137263
clean_up_after_interp(self.mesh_filename)
138264

@@ -152,19 +278,28 @@ def run(self):
152278
ds = xr.open_dataset(self.mesh_filename)
153279
# Ensure basalHeatFlux is positive
154280
ds["basalHeatFlux"] = np.abs(ds.basalHeatFlux)
155-
# Ensure reasonable dHdt values
281+
282+
# Ensure reasonable dHdt and dHdtErr values
156283
dHdt = ds["observedThicknessTendency"]
157-
# Arbitrary 5% uncertainty; improve this later
158-
dHdtErr = np.abs(dHdt) * 0.05
284+
# Calculate dHdt err using Csatho et al 2014 estimates
285+
# Error is approximated based on surface velocity
286+
baselineUncertainty = 0.01 # m/yr
287+
ux = ds['observedSurfaceVelocityX'].values
288+
uy = ds['observedSurfaceVelocityY'].values
289+
spd = np.sqrt(ux**2 + uy**2)
290+
mask = spd > (50.0 / 3.15E7) # cutoff at 50 m/yr
291+
dHdtErr = baselineUncertainty * np.ones(dHdt.values.shape) / 3.15E7
292+
dHdtErr[mask] = 2.0 / 3.15E7 # From Csatho 2014
159293
# Use threshold of |dHdt| > 1.0 to determine invalid data
160294
mask = np.abs(dHdt) > 1.0
161-
# Assign very large uncertainty where data is missing
162-
dHdtErr = dHdtErr.where(~mask, 1.0)
163295
# Remove ridiculous values
164296
dHdt = dHdt.where(~mask, 0.0)
297+
165298
# Put the updated fields back in the dataset
166299
ds["observedThicknessTendency"] = dHdt
167-
ds["observedThicknessTendencyUncertainty"] = dHdtErr
300+
dhdterr = xr.DataArray(dHdtErr.astype('float64'),
301+
dims=("Time", "nCells"))
302+
ds["observedThicknessTendencyUncertainty"] = dhdterr
168303
# Write the data to disk
169304
ds.to_netcdf(self.mesh_filename, 'a')
170305

compass/landice/tests/uummannaq_disko/mesh_gen/mesh_gen.cfg

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ bedmachine_filename = BedMachineGreenland-v5_edits_floodFill_extrap.nc
5757
# (default value is for Perlmutter)
5858
measures_filename = greenland_vel_mosaic500_extrap.nc
5959

60+
# filename of SMB dataset needed for dh/dt optimization constraint
61+
smb_filename = smb_rec.1950-2014.BN_RACMO2.3p2-CESM2-Historical.1km.YY.nc
62+
63+
# filename of BMB dataset needed for dh/dt optimization constraint
64+
bmb_filename = basalmelt_Karlssonetal2021_updated2022_extrap.nc
65+
6066
# projection of the source datasets, according to the dictionary keys
6167
# create_SCRIP_file_from_planar_rectangular_grid.py from MPAS_Tools
6268
src_proj = gis-gimp

0 commit comments

Comments
 (0)