Skip to content

Commit

Permalink
adapted for daily melt_f in dynamic calibration (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
pat-schmitt committed Mar 1, 2023
1 parent 0a5b854 commit e8753c6
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
23 changes: 16 additions & 7 deletions oggm/core/dynamic_spinup.py
Original file line number Diff line number Diff line change
Expand Up @@ -1597,7 +1597,7 @@ def dynamic_melt_f_run_fallback(
def run_dynamic_melt_f_calibration(
gdir, ref_dmdtda=None, err_ref_dmdtda=None, err_dmdtda_scaling_factor=1,
ref_period='', melt_f_min=None,
melt_f_max=None, melt_f_max_step_length=5, maxiter=20,
melt_f_max=None, melt_f_max_step_length_minimum=0.1, maxiter=20,
ignore_errors=False, output_filesuffix='_dynamic_melt_f',
ys=None, ye=None,
run_function=dynamic_melt_f_run_with_dynamic_spinup,
Expand Down Expand Up @@ -1659,10 +1659,11 @@ def run_dynamic_melt_f_calibration(
melt_f_max : float or None
Upper absolute limit for melt_f.
Default is None (-> cfg.PARAMS['melt_f_max'])
melt_f_max_step_length : float
Defines the maximum allowed change of melt_f between two iterations.
Is needed to avoid to large changes.
Default is 5
melt_f_max_step_length_minimum : float
Defines a minimum maximal change of melt_f between two iterations. The
maximum step length is needed to avoid too large steps, which likely
lead to an error.
Default is 0.1
maxiter : int
Maximum number of minimisation iterations of minimising mismatch to
dmdtda by changing melt_f. Each of this iterations conduct a complete
Expand Down Expand Up @@ -1821,6 +1822,14 @@ def run_dynamic_melt_f_calibration(
# (using the fallback function) if an error occurs
melt_f_initial = gdir.read_json('mb_calib')['melt_f']

# define maximum allowed change of melt_f between two iterations. Is needed
# to avoid to large changes (=likely lead to an error). It is defined in a
# way that in maxiter steps the further away limit can be reached
melt_f_max_step_length = np.max(
[np.max(np.abs(np.array([melt_f_min, melt_f_min]) - melt_f_initial)) /
maxiter,
melt_f_max_step_length_minimum])

# only used to check performance of minimisation
dynamic_melt_f_calibration_runs = [0]

Expand Down Expand Up @@ -2103,12 +2112,12 @@ def get_mismatch(melt_f):
# mismatch = 2 * err_ref_dmdtda this corresponds to 100%; for 100% or
# 150% the next step is (-1) * melt_f_max_step_length; if mismatch
# -40%, next step is 0.4 * melt_f_max_step_length; but always at least
# an absolute change of 0.5 is imposed to prevent too close guesses).
# an absolute change of 0.02 is imposed to prevent too close guesses).
# (-1) as if mismatch is negative we need a larger melt_f to get closer
# to 0.
step = (-1) * np.sign(mismatch[-1]) * \
max((np.abs(mismatch[-1]) - err_ref_dmdtda) / err_ref_dmdtda *
melt_f_max_step_length, 0.5)
melt_f_max_step_length, 0.02)
new_mismatch, new_melt_f = get_mismatch(melt_f_guess[0] + step)
melt_f_guess.append(new_melt_f)
mismatch.append(new_mismatch)
Expand Down
3 changes: 2 additions & 1 deletion oggm/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5050,7 +5050,7 @@ def test_hydro_dynamical_spinup(self, hef_gdir, inversion_params):
@pytest.mark.parametrize('do_inversion', [True, False])
@pytest.mark.slow
def test_hydro_dynamic_melt_f_with_dynamic_spinup(self, inversion_params,
do_inversion):
do_inversion):

# reset kcalving for this test and set it back to the previous value
# after the test
Expand All @@ -5077,6 +5077,7 @@ def test_hydro_dynamic_melt_f_with_dynamic_spinup(self, inversion_params,
# Needed for this to run
cfg.PARAMS['store_model_geometry'] = True

melt_f_max = 1000 * 12 / 365
tasks.run_with_hydro(
gdir, run_task=tasks.run_dynamic_melt_f_calibration,
store_monthly_hydro=True, ref_area_from_y0=True,
Expand Down

0 comments on commit e8753c6

Please sign in to comment.