Skip to content

Module smb

Brief summary

The smb module is a unified dispatcher for surface mass balance computation. It delegates to one of three implementations selected by the method parameter: simple, oggm, or accpdd, under a single entry point with a consistent interface.

State variables

Reads: —

Writes: smb

Units

The oggm and accpdd methods take state.precipitation in kg m⁻² yr⁻¹, i.e. mm water equivalent per year, and state.air_temp in °C (as produced by the climate module). Accumulation and melt are computed in water equivalent; the resulting state.smb is converted once, at the end, to m ice equivalent per year.

Choosing a method

Set processes.smb.method in your configuration:

processes:
  smb:
    method: simple   # or: oggm | accpdd

Method: simple

Models a simple SMB parametrized by a time-evolving equilibrium line altitude (ELA) \(z_{\rm ELA}\), ablation gradient \(\beta_{\rm abl}\), accumulation gradient \(\beta_{\rm acc}\), and maximum accumulation \(m_{\rm acc}\):

\[\mathrm{SMB}(z) = \begin{cases} \min(\beta_{\rm acc}\cdot(z - z_{\rm ELA}),\, m_{\rm acc}) & z > z_{\rm ELA} \\ \beta_{\rm abl}\cdot(z - z_{\rm ELA}) & \text{otherwise} \end{cases}\]

Parameters can be provided as an inline array:

processes:
  smb:
    method: simple
    simple:
      array:
        - ["time", "gradabl", "gradacc", "ela", "accmax"]
        - [ 1900,      0.009,     0.005,  2800,      2.0]
        - [ 2100,      0.009,     0.005,  3300,      2.0]

If array is empty ([]), the module reads from the file specified by file. The four parameters are interpolated linearly over time and the SMB is recomputed every update_freq years (default 1).

If an icemask field is present, the module assigns \(-10\,\mathrm{m\,yr^{-1}}\) to areas where positive SMB would otherwise occur outside the mask, preventing overflow into neighbouring catchments.


Add-on: correction for insolation (North-South correction with a simple ELA model)

The simple method can optionally account for the effect of slope and aspect on the received solar radiation (Henz et al., 2025). Instead of a uniform ELA, a spatially varying ELA \(z_{\rm ELA}^{*}(x,y)\) is used, shifted according to the difference between the solar incidence angle on the local surface and on a flat surface:

\[z_{\rm ELA}^{*}(x,y) = z_{\rm ELA} + c \cdot \bigl( (90^\circ - \alpha) - \varphi(x,y) \bigr),\]

where \(\alpha\) is the solar elevation angle, \(90^\circ - \alpha\) is the incidence angle on a flat surface, \(c\) is the ELA shift per degree of incidence angle (ela_per_degree_incidence, in m per degree), and \(\varphi(x,y)\) is the incidence angle between the surface normal vector \(\mathbf{n}\) and the sun vector \(\mathbf{s}\):

\[\cos(\varphi) = \frac{\mathbf{n} \cdot \mathbf{s}}{\|\thinspace\mathbf{n}\| \|\mathbf{s}\thinspace\|}.\]

The surface normal vector is computed from the gradients of the ice surface elevation \(z\):

\[\mathbf{n} = \left( -\frac{\partial z}{\partial x}\, -\frac{\partial z}{\partial y}\, 1 \right).\]

The sun vector is determined by the solar elevation angle \(\alpha\) (solar_elevation) and the solar azimuth angle \(\beta\) (solar_azimuth, clockwise from north):

\[\mathbf{s} = \bigl( \cos(\alpha)\sin(\beta)\, \cos(\alpha)\cos(\beta)\, \sin(\alpha) \bigr).\]

By default, the sun is positioned in the south (\(\beta = 180^\circ\)) at an elevation of \(\alpha = 60^\circ\) above the horizon, which is typical for Central Europe in June.

Sun-facing slopes (\(\varphi < 90^\circ - \alpha\)) get a higher ELA and therefore more melt, shaded slopes a lower ELA. On a flat surface the ELA is unchanged. The corrected ELA \(z_{\rm ELA}^{*}\) then replaces \(z_{\rm ELA}\) in the SMB formula above. Because the correction follows the evolving ice surface, it is recomputed at every SMB update.

The correction is off by default.

processes:
  smb:
    method: simple
    simple:
      correction_for_insolation:
        enabled: false                  # change here to true to switch it on
        solar_elevation: 60.0           # degrees above the horizon (for summer in the European Alps, 60° is around noon)
        solar_azimuth: 180.0            # degrees clockwise from north (180° = sun from the south)
        ela_per_degree_incidence: 5.0   # m of ELA shift per degree of incidence angle
        plot_insolation_check: false

or from the command line: processes.smb.simple.correction_for_insolation.enabled=true.

Check the orientation

The correction depends on the orientation of the input grid. When using a new domain, set plot_insolation_check: true once: at the first SMB update a figure check_insolation_correction.png is written to the run folder, showing the surface topography next to the ELA shift (north up). South-facing slopes (Northern Hemisphere) should show a positive shift.


Method: oggm

Implements the monthly temperature-index model calibrated on geodetic mass balance data (Hugonnet et al., 2021)1 by OGGM. The yearly SMB is:

\[\mathrm{SMB} = \frac{\rho_w}{\rho_i} \sum_{i=1}^{12} \Bigl(P_i^{\rm sol} - d_f \max\{T_i - T_{\rm melt},\,0\}\Bigr),\]

where \(P_i^{\rm sol}\) is monthly solid precipitation, \(T_i\) is monthly temperature, \(d_f\) is the melt factor (melt_f), and \(T_{\rm melt}\) is the melt threshold (temp_melt). Solid precipitation equals total precipitation below temp_all_solid, drops to zero above temp_all_liq, with a linear transition in between. All calibrated parameters are provided by the oggm_shop module (Maussion et al., 2019)2. Requires state.precipitation and state.air_temp (e.g. from the climate module with method: oggm).


Method: accpdd

Implements a combined accumulation and temperature-index model (Hock, 2003)3. Accumulation equals solid precipitation when temperature is below a threshold and decreases linearly to zero in a transition zone. Ablation is proportional to the number of Positive Degree Days (PDD). The model tracks snow layer depth and applies different PDD factors for snow and ice.

PDD computation uses the expectation-integration formulation (Calov & Greve, 2005)4. The snowpack and refreezing parameterisation follows the PyPDD and PISM implementations (Seguinot, 2019)5. Requires state.precipitation, state.air_temp, and optionally state.air_temp_sd.

Parameters

Default configuration file (smb.yaml):

smb:
  # Choose the surface mass-balance implementation: simple | oggm | accpdd
  method: simple

  # SMB imposed outside the icemask (if any) where the computed SMB is positive [m ice eq. yr-1]
  smb_outside_icemask: -10.0

  # ------------------------------------------------------------------
  # simple — gradient-based SMB from a time-series of (gradabl, gradacc,
  # ela, maxacc). Mirrors the legacy `smb_simple` module.
  # ------------------------------------------------------------------
  simple:
    update_freq: 1.0
    file: param.txt
    array: []

    # Block from Insolation correction (Henz et al. 2025, TC, https://doi.org/10.5194/tc-19-5913-2025)
    # switch the ELA correction for insolation on/off
    correction_for_insolation: 
      enabled: false # default is off, here you switch it on
      # solar elevation angle above the horizon [degrees], 
      # --> this is depending on the average latitude of the study region
      solar_elevation: 60.0 # for Alps latitude, midsummer midday value (see Henz et al. 2025)
      # solar azimuth, clockwise from north [degrees] (180 = sun from the south, e.g. for the Northern hemisphere)
      solar_azimuth: 180.0
      # ELA shift per degree of incidence-angle difference to a flat surface [m / degree]
      # (replaces the old aspect_enhancement_factor: old factor f  ->  5.0 * f here)
      ela_per_degree_incidence: 5.0 # comming from Henz et al. 2025 https://doi.org/10.5194/tc-19-5913-2025
      # save check_insolation_correction.png (topography + ELA shift) at the first SMB update
      plot_insolation_check: false

  # ------------------------------------------------------------------
  # oggm — temperature-index melt model using OGGM calibration json.
  # Requires state.precipitation and state.air_temp (e.g. from a climate
  # module). Mirrors the legacy `smb_oggm` module.
  # ------------------------------------------------------------------
  oggm:
    update_freq: 1.0
    ice_density: 910.0
    wat_density: 1000.0
    melt_enhancer: 1.0

  # ------------------------------------------------------------------
  # accpdd — accumulation + positive-degree-day (Hock 2003 / PyPDD)
  # melt model. Requires state.precipitation, state.air_temp, and
  # optionally state.air_temp_sd. Mirrors the legacy `smb_accpdd` module.
  # ------------------------------------------------------------------
  accpdd:
    update_freq: 1.0
    refreeze_factor: 0.6
    thr_temp_snow: 0.0
    thr_temp_rain: 2.0
    melt_factor_snow: 1.095726596343   # m w.e. yr-1 °C-1 (= 3 mm w.e. d-1 °C-1)
    melt_factor_ice:  2.921937590248   # m w.e. yr-1 °C-1 (= 8 mm w.e. d-1 °C-1)
    shift_hydro_year: 0.75
    ice_density: 910.0
    wat_density: 1000.0
    smb_maximum_accumulation: 6.0

Structure of the parameters:

smb
├── method
├── smb_outside_icemask
├── simple
│   └── ...
├── oggm
│   └── ...
└── accpdd
    └── ...

Description of the parameters:

Name Description Default value Units
method SMB implementation to use: simple, oggm, or accpdd. simple —
smb_outside_icemask SMB imposed outside the icemask (if an icemask is provided) where the computed SMB is positive, to prevent ice build-up in masked-out areas, which results from accumulation plus incoming ice flux. Lower it (e.g. -50) if ice still builds up outside the mask. -10.0 m yr\( ^{-1} \) ice eq.
simple
Name Description Default value Units
simple.update_freq Update SMB every X years. 1.0 yr
simple.file Input file for the simple SMB model (columns: time, gradabl, gradacc, ela, accmax). param.txt —
simple.array Inline time-dependent SMB parameters (time, gradabl, gradacc, ela, accmax); overrides file if non-empty. [] —
simple.correction_for_insolation.enabled Enable the correction of the ELA for insolation (aspect and slope of the surface). False —
simple.correction_for_insolation.solar_elevation Solar elevation angle above the horizon (one single value as a midsummer midday value, depending on latitude, see Henz et al. 2025) [degrees]. 60.0 ° (degree)
simple.correction_for_insolation.solar_azimuth Solar azimuth angle [degrees]. Clockwise from north (180 = sun from the south, e.g. for the Northern hemisphere). 180.0 ° (degree)
simple.correction_for_insolation.ela_per_degree_incidence Change in ELA per degree of incidence angle [m/°]. 5.0 m °\( ^{-1} \)
simple.correction_for_insolation.plot_insolation_check Plot a diagnostic figure to check the insolation correction. False —
oggm
Name Description Default value Units
oggm.update_freq Update SMB every X years. 1.0 yr
oggm.ice_density Ice density used to convert melt from water equivalent. 910.0 kg m\( ^{-3} \)
oggm.wat_density Water density used to convert melt from water equivalent. 1000.0 kg m\( ^{-3} \)
oggm.melt_enhancer Multiplicative factor applied to the melt rate. 1.0 —
accpdd
Name Description Default value Units
accpdd.update_freq Update SMB every X years. 1.0 yr
accpdd.refreeze_factor Fraction of meltwater that refreezes (Hock 2003). 0.6 —
accpdd.thr_temp_snow Temperature threshold below which precipitation falls as snow. 0.0 °C
accpdd.thr_temp_rain Temperature threshold above which precipitation falls as rain. 2.0 °C
accpdd.melt_factor_snow Degree-day melt factor for snow, in water equivalent. The default corresponds to 3 mm w.e. d-1 °C-1 (value in mm w.e. d-1 °C-1 × 0.365242). 1.095726596343 m yr\( ^{-1} \) °C\( ^{-1} \) w.e.
accpdd.melt_factor_ice Degree-day melt factor for ice, in water equivalent. The default corresponds to 8 mm w.e. d-1 °C-1 (value in mm w.e. d-1 °C-1 × 0.365242). 2.921937590248 m yr\( ^{-1} \) °C\( ^{-1} \) w.e.
accpdd.shift_hydro_year Fractional year shift for the start of the hydrological year. 0.75 yr
accpdd.ice_density Ice density used for unit conversion. 910.0 kg m\( ^{-3} \)
accpdd.wat_density Water density used for unit conversion. 1000.0 kg m\( ^{-3} \)
accpdd.smb_maximum_accumulation Cap on the accumulation rate to avoid unrealistically large values. 6.0 m yr\( ^{-1} \)

Contributors: Guillaume Jouvet, Fabien Maussion.


  1. Hugonnet, R., McNabb, R., Berthier, E., Menounos, B., Nuth, C., Girod, L., Farinotti, D., Huss, M., Dussaillant, I., Brun, F., & Kääb, A. (2021). Accelerated global glacier mass loss in the early twenty-first century. Nature, 592(7856), 726--731. https://doi.org/10.1038/s41586-021-03436-z ↩

  2. Maussion, F., Butenko, A., Champollion, N., Dusch, M., Eis, J., Fourteau, K., Gregor, P., Jarosch, A. H., Landmann, J., Oesterle, F., Recinos, B., Rothenpieler, T., Vlug, A., Wild, C. T., & Marzeion, B. (2019). The open global glacier model (OGGM) v1.1. Geoscientific Model Development, 12(3), 909--931. https://doi.org/10.5194/gmd-12-909-2019 ↩

  3. Hock, R. (2003). Temperature index melt modelling in mountain areas. Journal of Hydrology, 282(1--4), 104--115. https://doi.org/10.1016/s0022-1694(03)00257-9 ↩

  4. Calov, R., & Greve, R. (2005). A semi-analytical solution for the positive degree-day model with stochastic temperature variations. Journal of Glaciology, 51(172), 173--175. https://doi.org/10.3189/172756505781829601 ↩

  5. Seguinot, J. (2019). PyPDD: A positive degree day model for glacier surface mass balance. https://doi.org/10.5281/ZENODO.3467639 ↩