Skip to content

Commit

Permalink
new commit: retain reset_state() function capability with single call…
Browse files Browse the repository at this point in the history
… in apparent_mb_from_any_mb subject to kwarg, no other changes
  • Loading branch information
dngoldberg committed Jan 17, 2025
1 parent 9e235bc commit 7b27486
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 44 deletions.
16 changes: 7 additions & 9 deletions docs/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@ Enhancements
``dis_from_border``, ...) to define this ranking, providing greater flexibility
and control over how the melting sequence is visualized (:pull:`1746`).
By `Patrick Schmitt <https://github.com/pat-schmitt>`_
- Added "reset_state" functionality to ``MassBalanceModel.get_specific_mb()`` to
signal any state-dependent mass balance model to "reset its state" at the start
of the period. This is achieved through a "reset_state" kwarg passed by
``MassBalanceModel.get_annual_mb()``. Done to address that
``apparent_mb_from_any_mb()`` calls ``get_specific_mb()`` twice, leading to nonzero
terminal flux (potentially) with a state-dependent mass balance model.
`apparent_mb_from_any_mb()` also changed accordingly. Similar change also
made to ``MultipleFlowlineMassBalanceModel.get_specific_mb()``. Does not impact
any current functionality within oggm.
- Added "reset_state()" function to ``MassBalanceModel`` to signal any state-dependent
mass balance model to "reset its state" at the start of the period. This function
does nothing in the parent class and would only be implemented by a state-ful
mass balance model. Done mainly to address that ``apparent_mb_from_any_mb()`` calls
``get_specific_mb()`` twice, leading to nonzero terminal flux (potentially) with a
state-dependent mass balance model. `apparent_mb_from_any_mb()` also changed
accordingly.

Bug fixes
~~~~~~~~~
Expand Down
49 changes: 14 additions & 35 deletions oggm/core/massbalance.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ def __repr__(self):

def reset_state(self):
"""Reset any internal state of the model.
This might not be needed by most models, but some models have an
internal state (e.g. a snow cover history) which can be reset
this way.
Expand Down Expand Up @@ -135,7 +134,7 @@ def get_annual_mb(self, heights, year=None, fl_id=None, fls=None):
raise NotImplementedError()

def get_specific_mb(self, heights=None, widths=None, fls=None,
year=None, reset_state=False):
year=None):
"""Specific mb for this year and a specific glacier geometry.
Units: [mm w.e. yr-1], or millimeter water equivalent per year
Expand All @@ -153,27 +152,18 @@ def get_specific_mb(self, heights=None, widths=None, fls=None,
provided.
year: float, optional
the time (in the "floating year" convention)
reset_state: bool, optional
if True, call mb_model.reset_state() before computing the
mass balance each year. This is useful for models that have
an internal state (in which case they need to implement the
reset_state() method).
Returns
-------
the specific mass balance (units: mm w.e. yr-1)
"""

if len(np.atleast_1d(year)) > 1:
out = [self.get_specific_mb(heights=heights, widths=widths,
fls=fls, year=yr,
reset_state=reset_state) for yr in year]
fls=fls, year=yr)
for yr in year]
return np.asarray(out)

# The code above is a recursive call to the below, which is
# why we reset only now, if annual spec MB is needed.
if reset_state:
self.reset_state()

if fls is not None:
mbs = []
widths = []
Expand All @@ -186,8 +176,7 @@ def get_specific_mb(self, heights=None, widths=None, fls=None,
pass
widths = np.append(widths, _widths)
mbs = np.append(mbs, self.get_annual_mb(fl.surface_h,
fls=fls,
fl_id=i,
fls=fls, fl_id=i,
year=year))
else:
mbs = self.get_annual_mb(heights, year=year)
Expand Down Expand Up @@ -1315,7 +1304,7 @@ def get_annual_mb_on_flowlines(self, fls=None, year=None):
return heights, widths, mbs

def get_specific_mb(self, heights=None, widths=None, fls=None,
year=None, reset_state=False):
year=None):

if heights is not None or widths is not None:
raise ValueError('`heights` and `widths` kwargs do not work with '
Expand All @@ -1325,13 +1314,9 @@ def get_specific_mb(self, heights=None, widths=None, fls=None,
fls = self.fls

if len(np.atleast_1d(year)) > 1:
out = [self.get_specific_mb(fls=fls, year=yr, reset_state=reset_state)
for yr in year]
out = [self.get_specific_mb(fls=fls, year=yr) for yr in year]
return np.asarray(out)

if reset_state:
self.reset_state()

mbs = []
widths = []
for i, (fl, mb_mod) in enumerate(zip(fls, self.flowline_mb_models)):
Expand Down Expand Up @@ -2110,8 +2095,7 @@ def to_minimize(ela_h):
@entity_task(log, writes=['inversion_flowlines'])
def apparent_mb_from_any_mb(gdir, mb_model=None,
mb_model_class=MonthlyTIModel,
mb_years=None,
reset_state=False):
mb_years=None, reset_state=False):
"""Compute apparent mb from an arbitrary mass balance profile.
This searches for a mass balance residual to add to the mass balance
Expand Down Expand Up @@ -2162,14 +2146,16 @@ def apparent_mb_from_any_mb(gdir, mb_model=None,
mb_years = np.arange(*mb_years, 1)

# Unchanged SMB
o_smb = np.mean(mb_model.get_specific_mb(fls=fls, year=mb_years,
reset_state=reset_state))
o_smb = np.mean(mb_model.get_specific_mb(fls=fls, year=mb_years))

def to_minimize(residual_to_opt):
return o_smb + residual_to_opt - cmb

residual = optimize.brentq(to_minimize, -1e5, 1e5)

if (reset_state):
mb_model.reset_state()

# Reset flux
for fl in fls:
fl.reset_flux()
Expand All @@ -2179,15 +2165,8 @@ def to_minimize(residual_to_opt):
for fl_id, fl in enumerate(fls):
mbz = 0
for yr in mb_years:
if reset_state:
mb_model.reset_state()
if yr == mb_years[0]:
mbz += mb_model.get_annual_mb(fl.surface_h, year=yr,
fls=fls, fl_id=fl_id)
else:
mbz += mb_model.get_annual_mb(fl.surface_h, year=yr,
fls=fls, fl_id=fl_id)

mbz += mb_model.get_annual_mb(fl.surface_h, year=yr,
fls=fls, fl_id=fl_id)
mbz = mbz / len(mb_years)
fl.set_apparent_mb(mbz * cfg.SEC_IN_YEAR * rho + residual,
is_calving=is_calving)
Expand Down

0 comments on commit 7b27486

Please sign in to comment.