def get_monthly_mb(self, heights, year=None, **kwargs): """Calculate the monthly mass balance for the glacier. Parameters ---------- heights : np.ndarray altitudes at which to compute the MB year : float, optional The current hydrological year. Used to evaluate if mass balance model should be updated. Returns ------- The monthly mass-balances for each height. """ # A year will always be provided during a model run, the only time we do this evaluation. # In ohter cases i.e. plotting annual mb, we don't evaluate this. # We check if its a float instead of simply if year since this would miss the 0th year. if isinstance(year, float): # Since we are progressing the glacier we want the next year of the climate to update # the mass balance. year = year + 1 # If we have a future climate scenario essentially. if year <= self.temp_bias_series.year.iloc[-1]: # We get a temp bias from the series, update the ela of our mb. # Uses the temp_bias setter. self.temp_bias = self.temp_bias_series.bias[ self.temp_bias_series.year == year].values[0] # If there is no future climate scenario, we simply append the current bias to the history. # e.g. when climate remains constant. else: # Add the current temperature bias (unchanged) to the history. self.temp_bias_series = [self.temp_bias] # Compute the mb # We use the _gradient_lookup to get an array of gradients matching the length of heights. # _breakpoint_diff computes the mb difference at the breakpoint height for the two different # gradients. Used to adjust the intercept of the new gradient curve. mb = (np.asarray(heights) - self.ela_h) * self._gradient_lookup( heights) + self._breakpoint_diff(heights) # Adjust intercept for the case when breakpoint is above ELA. # Essentially making sure that the mb profile is zero at the ELA. ela_idx = np.argmin(np.abs(np.asarray(heights) - self.ela_h)) mb = mb - mb[ela_idx] # Should we cap the mb? if self.max_mb: clip_max(mb, self.max_mb, out=mb) return mb / SEC_IN_YEAR / self.rho
def _vol_below_water(surface_h, bed_h, bed_shape, thick, widths, is_rectangular, fac, dx, water_level): bsl = (bed_h < water_level) & (thick > 0) n_thick = np.copy(thick) n_thick[~bsl] = 0 n_thick[bsl] = utils.clip_max(surface_h[bsl], water_level) - bed_h[bsl] with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=RuntimeWarning) n_w = np.sqrt(4 * n_thick / bed_shape) n_w[is_rectangular] = widths[is_rectangular] return fac * n_thick * n_w * dx
def _vol_below_water(surface_h, bed_h, bed_shape, thick, widths, is_rectangular, is_trapezoid, fac, t_lambda, dx, water_level): bsl = (bed_h < water_level) & (thick > 0) n_thick = np.copy(thick) n_thick[~bsl] = 0 n_thick[bsl] = utils.clip_max(surface_h[bsl], water_level) - bed_h[bsl] with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=RuntimeWarning) n_w = np.sqrt(4 * n_thick / bed_shape) n_w[is_rectangular] = widths[is_rectangular] out = fac * n_thick * n_w * dx # Trap it = is_trapezoid out[it] = (n_w[it] + n_w[it] - t_lambda*n_thick[it]) / 2*n_thick[it]*dx return out
def get_monthly_mb(self, heights, **kwargs): mb = (np.asarray(heights) - self.ela_h) * self.grad if self.max_mb is not None: clip_max(mb, self.max_mb, out=mb) return mb / SEC_IN_YEAR / self.rho