WSL/SLF GitLab Repository

Commit 45a15df2 authored by Aschauer's avatar Aschauer
Browse files

add basic nan handling for `snowpack_evolution` function

parent fbb81d98
Pipeline #730 passed with stage
in 10 minutes and 6 seconds
......@@ -87,12 +87,14 @@ def _get_settling_resistance(
):
# calculate weights (scaling factors) of density and overburden.
w_rho = (R_max-R_min) * ratio_settling_influence_rho_vs_ob/(ratio_settling_influence_rho_vs_ob+1)
w_rho = (R_max-R_min) * ratio_settling_influence_rho_vs_ob / \
(ratio_settling_influence_rho_vs_ob+1)
w_sigma = (R_max-R_min) * 1/(ratio_settling_influence_rho_vs_ob+1)
# calculate reduction of R due to density and overburden.
R_reduction_rho = _R_reduction_density(rho_layers, rho_minsettling, rho_maxsettling)
R_reduction_sigma = _R_reduction_overburden(overburden_layers, ob_minsettling, ob_maxsettling)
R_reduction_sigma = _R_reduction_overburden(
overburden_layers, ob_minsettling, ob_maxsettling)
R = R_max - w_rho*R_reduction_rho - w_sigma*R_reduction_sigma
return R
......@@ -152,13 +154,14 @@ def _adjust_rho_max_based_on_overburden(
if o >= max_overburden:
rho_max_current[i] = rho_max_wet
else:
rho_max_current[i] = ((rho_max_wet-rho_max_dry)/max_overburden)*o + rho_max_dry
rho_max_current[i] = ((rho_max_wet-rho_max_dry) /
max_overburden)*o + rho_max_dry
updated_rho_max_layers = np.where((rho_max_current>rho_max_layers),
updated_rho_max_layers = np.where((rho_max_current > rho_max_layers),
rho_max_current,
rho_max_layers)
updated_rho_max_layers = np.where((swe_layers>0), updated_rho_max_layers, 0.)
updated_rho_max_layers = np.where((swe_layers > 0), updated_rho_max_layers, 0.)
return updated_rho_max_layers
......@@ -304,7 +307,7 @@ def timestep_forward(
# update rho, i.e. calculate settling:
rho_layers = np.where(
(swe_layers>0),
(swe_layers > 0),
rho_max_layers - (rho_max_layers-rho_layers) * np.exp(-1/R),
0.)
......@@ -315,6 +318,13 @@ def timestep_forward(
return swe_layers, rho_layers, rho_max_layers
@njit
def _set_layer_states_nan(swe_layers, rho_layers, rho_max_layers):
swe_layers = np.full_like(swe_layers, np.nan)
rho_layers = np.full_like(rho_layers, np.nan)
rho_max_layers = np.full_like(rho_max_layers, np.nan)
return swe_layers, rho_layers, rho_max_layers
@njit
def _calculate_hs_layers(swe_layers, rho_layers):
......@@ -326,6 +336,29 @@ def _calculate_hs_layers(swe_layers, rho_layers):
return hs_layers
@njit
def _nansum_numba(array):
"""
Looped numba version faster than np.nansum
Parameters
----------
array : :class:`numpy.ndarray`
1 dimensional ndarray, float dtype
Returns
-------
sum : float
"""
sum = 0.
for x in array:
if np.isnan(x):
continue
else:
sum += x
return sum
@njit
def _pad_end_of_array_with_zero(array):
# np.pad not supported in numba, we need some ugly hacking.
......@@ -382,23 +415,32 @@ def swe2hs_snowpack_evolution(
# allocate layer containers
swe_layers = np.zeros(0) # tracking of swe
rho_layers = np.zeros(0) # tracking of density
rho_max_layers = np.zeros(0) #tracking of maximum density
rho_max_layers = np.zeros(0) # tracking of maximum density
# iterate through input array.
for i, swe in enumerate(swe_input):
# get delta swe:
if i==0:
delta_swe = swe
else:
delta_swe = swe - swe_input[i-1]
swe_layers, rho_layers, rho_max_layers = _pad_layer_arrays_with_zero(
swe_layers,
rho_layers,
rho_max_layers,
)
if np.isnan(swe):
swe_layers, rho_layers, rho_max_layers = _set_layer_states_nan(
swe_layers,
rho_layers,
rho_max_layers
)
hs_out[i] = np.nan
continue
# get delta swe:
if i == 0:
delta_swe = swe
else:
delta_swe = swe - swe_input[i-1]
swe_layers, rho_layers, rho_max_layers = timestep_forward(
delta_swe,
swe_layers,
......@@ -420,7 +462,7 @@ def swe2hs_snowpack_evolution(
hs_layers = _calculate_hs_layers(swe_layers, rho_layers)
hs_out[i] = np.sum(hs_layers)
hs_out[i] = _nansum_numba(hs_layers)
hs_layers_out[:i+1, i] = hs_layers
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment