Skip to content

Commit 44d2d26

Browse files
Robustify extrapolate.py and its usage in the friction handling
1 parent cbaa4a5 commit 44d2d26

2 files changed

Lines changed: 45 additions & 12 deletions

File tree

compass/landice/extrapolate.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
from netCDF4 import Dataset
55

66

7-
def extrapolate_variable(nc_file, var_name, extrap_method, set_value=None):
7+
def extrapolate_variable(nc_file, var_name, extrap_method='auto', # noqa: C901
8+
valid_region_method='auto',
9+
set_value=None):
810
"""
911
Function to extrapolate variable values into undefined regions
1012
@@ -19,6 +21,9 @@ def extrapolate_variable(nc_file, var_name, extrap_method, set_value=None):
1921
extrap_method : str
2022
idw, min, or value method of extrapolation
2123
24+
valid_region_method : str
25+
choice of how to define region of valid data
26+
2227
set_value : float
2328
value to set variable to outside keepCellMask
2429
when using -v value
@@ -36,13 +41,33 @@ def extrapolate_variable(nc_file, var_name, extrap_method, set_value=None):
3641
xCell = dataset.variables["yCell"][:]
3742
yCell = dataset.variables["xCell"][:]
3843

44+
# Define extrap method
45+
if extrap_method == 'auto':
46+
if var_name in ["effectivePressure", "beta", "muFriction"]:
47+
extrap_method = 'min'
48+
elif var_name in ["floatingBasalMassBal"]:
49+
extrap_method = 'idw'
50+
else:
51+
extrap_method = 'idw'
52+
3953
# Define region of good data to extrapolate from.
40-
# Different methods for different variables
41-
if var_name in ["effectivePressure", "beta", "muFriction"]:
54+
if valid_region_method == 'auto':
55+
if var_name in ["effectivePressure", "beta", "muFriction"]:
56+
valid_region_method = 'grounded_ice'
57+
elif var_name in ["floatingBasalMassBal"]:
58+
valid_region_method = 'floating_ice'
59+
else:
60+
valid_region_method = 'ice'
61+
62+
print(f"Start {var_name} extrapolation using {extrap_method} method, "
63+
f"defining good data using {valid_region_method} method")
64+
65+
# Calculate seed mask baed on method for defining valid data
66+
if valid_region_method == 'positive_val':
67+
keepCellMask = (varValue[:] > 0.0)
68+
elif valid_region_method == 'grounded_ice':
4269
groundedMask = (thickness > (-1028.0 / 910.0 * bed))
4370
keepCellMask = np.copy(groundedMask)
44-
extrap_method = "min"
45-
4671
# grow mask by one cell oceanward of GL
4772
for iCell in range(nCells):
4873
for n in range(nEdgesOnCell[iCell]):
@@ -52,12 +77,14 @@ def extrapolate_variable(nc_file, var_name, extrap_method, set_value=None):
5277
continue
5378
# ensure zero muFriction does not get extrapolated
5479
keepCellMask *= (varValue > 0.0)
55-
elif var_name in ["floatingBasalMassBal"]:
80+
elif valid_region_method == 'floating_ice':
5681
floatingMask = (thickness <= (-1028.0 / 910.0 * bed))
5782
keepCellMask = floatingMask * (varValue != 0.0)
58-
extrap_method == "idw"
59-
else:
83+
elif valid_region_method == 'ice':
6084
keepCellMask = (thickness > 0.0)
85+
else:
86+
sys.exit("Unexpected value of valid_region_method encountered "
87+
"in landice/extrapolate.py")
6188

6289
if keepCellMask.sum() == 0:
6390
sys.exit("In landice/extrapolate.py, initial keepCellMask has "
@@ -76,8 +103,6 @@ def extrapolate_variable(nc_file, var_name, extrap_method, set_value=None):
76103
# 5) Update mask
77104
# 6) go to step 1)
78105

79-
print("Start {} extrapolation using {} method".format(var_name,
80-
extrap_method))
81106
if extrap_method == 'value':
82107
varValue[np.where(np.logical_not(keepCellMask))] = float(set_value)
83108
else:

compass/landice/tests/ensemble_generator/ensemble_member.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,14 +326,18 @@ def _adjust_friction_exponent(orig_fric_exp, new_fric_exp, filename,
326326
uX = f.variables['uReconstructX'][0, :, -1]
327327
uY = f.variables['uReconstructY'][0, :, -1]
328328
spd = (uX**2 + uY**2)**0.5 * (60. * 60. * 24. * 365.)
329+
if np.max(spd) == 0.0:
330+
raise ValueError("uReconstructX/Y yielding max speed of 0")
329331
mu = mu * spd**(orig_fric_exp - new_fric_exp)
330332
# The previous step leads to infs or nans in ice-free areas.
331333
# Set them all to 0.0 for the extrapolation step
332334
mu[spd == 0.0] = 0.0
333335
f.variables['muFriction'][0, :] = mu[:]
334336
f.close()
335337

336-
extrapolate_variable(filename, 'muFriction', 'min')
338+
extrapolate_variable(filename, 'muFriction',
339+
extrap_method='min',
340+
valid_region_method='positive_val')
337341

338342
# now set exp in albany yaml file
339343
# using text replacement rather than yaml parser because yaml
@@ -384,8 +388,12 @@ def _apply_fric_sample(sample_num, sample_file, mu_opt_file,
384388
n_cells = len(f.dimensions['nCells'])
385389

386390
# Set baseline mu outside of the Albany inverse region.
387-
mu = 0.2 * np.ones(n_cells)
391+
mu = -1.0 * np.ones(n_cells)
388392
mu[mpas_map[:] - 1] = np.exp(scaling * sample + log_mu_opt)
389393

390394
f.variables['muFriction'][0, :] = mu[:]
391395
f.close()
396+
397+
extrapolate_variable(ic_file, 'muFriction',
398+
extrap_method='min',
399+
valid_region_method='positive_val')

0 commit comments

Comments
 (0)