Source code for pcse.soil.snowmaus

# -*- coding: utf-8 -*-
# Copyright (c) 2004-2014 Alterra, Wageningen-UR
# Allard de Wit (allard.dewit@wur.nl), April 2014

from ..traitlets import Float
from ..decorators import prepare_rates, prepare_states
from ..util import limit, merge_dict
from ..base_classes import ParamTemplate, StatesTemplate, RatesTemplate, \
     SimulationObject
from .. import signals
from .. import exceptions as exc

[docs]class SnowMAUS(SimulationObject): """Simple snow accumulation model for agrometeorological applications. This is an implementation of the SnowMAUS model which describes the accumulation and melt of snow due to precipitation, snowmelt and sublimation. The SnowMAUS model is designed to keep track of the thickness of the layer of water that is present as snow on the surface, e.g. the Snow Water Equivalent Depth (state variable SWEDEPTH [cm]). Conversion of the SWEDEPTH to the actual snow depth (state variable SNOWDEPTH [cm]) is done by dividing the SWEDEPTH with the snow density in [cm_water/cm_snow]. Snow density is taken as a fixed value despite the fact that the snow density is known to vary with the type of snowfall, the temperature and the age of the snow pack. However, more complicated algorithms for snow density would not be consistent with the simplicy of SnowMAUS. A drawback of the current implementation is that there is no link to the water balance yet. Reference: M. Trnka, E. Kocmánková, J. Balek, J. Eitzinger, F. Ruget, H. Formayer, P. Hlavinka, A. Schaumberger, V. Horáková, M. Možný, Z. Žalud, Simple snow cover model for agrometeorological applications, Agricultural and Forest Meteorology, Volume 150, Issues 7–8, 15 July 2010, Pages 1115-1127, ISSN 0168-1923 http://dx.doi.org/10.1016/j.agrformet.2010.04.012 **Simulation parameters:** (provide in crop, soil and sitedata dictionary) ============ =========================================== ======= ========== Name Description Type Unit ============ =========================================== ======= ========== TMINACCU1 Upper critical minimum temperature for snow SSi |C| accumulation. TMINACCU2 Lower critical minimum temperature for snow SSi |C| accumulation TMINCRIT Critical minimum temperature for snow melt SSi |C| TMAXCRIT Critical maximum temperature for snow melt SSi |C| RMELT Melting rate per day per degree Celcius SSi |cmC-1day-1| above the critical minimum temperature. SCTHRESHOLD Snow water equivalent above which the SSi cm sublimation is taken into account. SNOWDENSITY Density of snow SSi cm/cm SWEDEPTHI Initial depth of layer of water present as snow on the soil surface SSi cm ============ =========================================== ======= ========== **State variables:** =============== ========================================== ==== ============ Name Description Pbl Unit =============== ========================================== ==== ============ SWEDEPTH Depth of layer of water present as snow N cm on the surface SNOWDEPTH Depth of snow present on the surface. Y cm =============== ========================================== ==== ============ **Rate variables:** ============ ============================================= ==== ============ Name Description Pbl Unit ============ ============================================= ==== ============ RSNOWACCUM Rate of snow accumulation N |cmday-1| RSNOWSUBLIM Rate of snow sublimation N |cmday-1| RSNOWMELT Rate of snow melting N |cmday-1| ============ ============================================= ==== ============ """
[docs] class Parameters(ParamTemplate): TMINACCU1 = Float(-99.) TMINACCU2 = Float(-99.) TMINCRIT = Float(-99.) TMAXCRIT = Float(-99.) RMELT = Float(-99.) SCTHRESHOLD = Float(-99.) SNOWDENSITY = Float(-99) SWEDEPTHI = Float(-99)
[docs] class StateVariables(StatesTemplate): SWEDEPTH = Float(-99.) SNOWDEPTH = Float(-99.)
[docs] class RateVariables(RatesTemplate): RSNOWACCUM = Float(-99.) RSNOWSUBLIM = Float(-99.) RSNOWMELT = Float(-99.)
[docs] def initialize(self, day, kiosk, parvalues): """ :param day: start date of the simulation :param kiosk: variable kiosk of this PCSE instance :param sitedata: dictionary with WOFOST sitedata key/value pairs """ if parvalues["SNOWDENSITY"] <= 0.: msg = ("SNOWDENSITY parameter of SnowMAUS module cannot <= zero " + "to avoid division by zero") raise exc.ParameterError(msg) self.params = self.Parameters(parvalues) self.rates = self.RateVariables(kiosk) SWEDEPTH = self.params.SWEDEPTHI SNOWDEPTH = SWEDEPTH/self.params.SNOWDENSITY self.states = self.StateVariables(kiosk, SWEDEPTH=SWEDEPTH, SNOWDEPTH=SNOWDEPTH, publish="SNOWDEPTH")
@prepare_rates def calc_rates(self, day, drv): p = self.params r = self.rates s = self.states # Snow accumulation rate (RSNOWACCUM) if drv.TMIN <= p.TMINACCU2: r.RSNOWACCUM = drv.RAIN elif drv.TMIN >= p.TMINACCU1: r.RSNOWACCUM = 0. else: rr = (drv.TMIN - p.TMINACCU2)/ abs(p.TMINACCU1 - p.TMINACCU2) r.RSNOWACCUM = (1-rr) * drv.RAIN # Snow sublimation rate (RSNOWSUBLIM) if s.SWEDEPTH > p.SCTHRESHOLD and r.RSNOWACCUM == 0.: RSNOWSUBLIM = drv.E0 else: RSNOWSUBLIM = 0. # Avoid sublimating more snow than available r.RSNOWSUBLIM = limit(0, s.SWEDEPTH, RSNOWSUBLIM) # Snow melting rate (RSNOWMELT) if drv.TMIN < p.TMINCRIT: RSNOWMELT = 0. else: if drv.TMIN <= 0. and drv.TMAX < p.TMAXCRIT: RSNOWMELT = 0. else: RSNOWMELT = (drv.TMIN - p.TMINCRIT) * p.RMELT # Avoid melting more snow than available r.RSNOWMELT = limit(0, (s.SWEDEPTH - r.RSNOWSUBLIM), RSNOWMELT) @prepare_states def integrate(self, day, delt=1.0): s = self.states r = self.rates p = self.params s.SWEDEPTH += (r.RSNOWACCUM - r.RSNOWSUBLIM - r.RSNOWMELT) s.SNOWDEPTH = s.SWEDEPTH/p.SNOWDENSITY