MARRMOT_45

Implementation

MARRMoT v2.1.1 rev eeb7e15 m_45_prms_18p_7s; standardized continuous structure, not original model

  • Time step: daily

  • Backend: octave-cli + Octave optim

  • Calibrated parameters: 18

  • Temperature required: yes

Inspect the exact implementation.

Parameters and initial configuration

Parameter

Supported calibration range

Default

p01

-3 to 5

1.0

p02

0 to 20

10.0

p03

0 to 1

0.5

p04

0 to 1

0.5

p05

0 to 5

2.5

p06

0 to 50

25.0

p07

0 to 1

0.5

p08

0 to 1

0.5

p09

0.005 to 0.995

0.5

p10

1 to 2000

1000.5

p11

0 to 20

10.0

p12

1 to 300

150.5

p13

0 to 1

0.5

p14

1 to 5

3.0

p15

0 to 1

0.5

p16

0 to 1

0.5

p17

0 to 1

0.5

p18

0 to 1

0.5

s01

Fixed initial/configuration value

0.0

s02

Fixed initial/configuration value

0.0

s03

Fixed initial/configuration value

0.0

s04

Fixed initial/configuration value

0.0

s05

Fixed initial/configuration value

0.0

s06

Fixed initial/configuration value

0.0

s07

Fixed initial/configuration value

0.0

Ranges/defaults are implementation contracts, not universal priors or a recommended basin calibration. Consult source comments for parameter units and coupling.

Governing equations

The following source is the exact model kernel used by this adapter. For MARRMoT it includes the state derivative and each referenced flux function; the solver and routing are described above. Original notices and source citations are retained in the files.

        function [dS, fluxes] = model_fun(obj, S)
            % parameters
            theta = obj.theta;
            tt      = theta(1);     % Temperature threshold for snowfall and melt [oC]
            ddf     = theta(2);     % Degree-day factor for snowmelt [mm/oC/d]
            alpha   = theta(3);     % Fraction of rainfall on soil moisture going to interception [-] 
            beta    = theta(4);     % Fraction of catchment where rain goes to soil moisture [-]
            stor    = theta(5);     % Maximum interception capcity [mm]
            retip   = theta(6);     % Maximum impervious area storage [mm]
            fscn    = theta(7);     % Fraction of SCX where SCN is located [-]
            scx     = theta(8);     % Maximum contributing fraction area to saturation excess flow [-]
            scn     = fscn*scx;     % Minimum contributing fraction area to saturation excess flow [-]
            flz     = theta(9);     % Fraction of total soil moisture that is the lower zone [-]
            stot    = theta(10);    % Total soil moisture storage [mm]: REMX+SMAX
            remx    = (1-flz)*stot; % Maximum upper soil moisture storage [mm]
            smax    = flz*stot;     % Maximum lower soil moisture storage [mm] 
            cgw     = theta(11);    % Constant drainage to deep groundwater [mm/d]
            resmax  = theta(12);    % Maximum flow routing reservoir storage (used for scaling only, there is no overflow) [mm]
            k1      = theta(13);    % Groundwater drainage coefficient [d-1]
            k2      = theta(14);    % Groundwater drainage non-linearity [-]
            k3      = theta(15);    % Interflow coefficient 1 [d-1]
            k4      = theta(16);    % Interflow coefficient 2 [mm-1 d-1]
            k5      = theta(17);    % Baseflow coefficient [d-1]
            k6      = theta(18);    % Groundwater sink coefficient [d-1]
            
            % delta_t
            delta_t = obj.delta_t;
            
            % stores
            S1 = S(1);
            S2 = S(2);
            S3 = S(3);
            S4 = S(4);
            S5 = S(5);
            S6 = S(6);
            S7 = S(7);
            
            % climate input
            t = obj.t;                             % this time step
            climate_in = obj.input_climate(t,:);   % climate at this step
            P  = climate_in(1);
            Ep = climate_in(2);
            T  = climate_in(3);
            
            % fluxes functions
            flux_ps  = snowfall_1(P,T,tt);
            flux_pr  = rainfall_1(P,T,tt);
            flux_pim = split_1(1-beta,flux_pr);
            flux_psm = split_1(beta,flux_pr);
            flux_pby = split_1(1-alpha,flux_psm);
            flux_pin = split_1(alpha,flux_psm);
            flux_ptf = interception_1(flux_pin,S2,stor);
            flux_m   = melt_1(ddf,tt,T,S1,delta_t);
            flux_mim = split_1(1-beta,flux_m);
            flux_msm = split_1(beta,flux_m);
            flux_sas = saturation_1(flux_pim+flux_mim,S3,retip);
            flux_sro = saturation_8(scn,scx,S4,remx,flux_msm+flux_ptf+flux_pby);
            flux_inf = effective_1(flux_msm+flux_ptf+flux_pby,flux_sro);
            flux_pc  = saturation_1(flux_inf,S4,remx);
            flux_excs= saturation_1(flux_pc,S5,smax);
            flux_sep = recharge_7(cgw,flux_excs);
            flux_qres= effective_1(flux_excs,flux_sep);
            flux_gad = recharge_2(k2,S6,resmax,k1);
            flux_ras = interflow_4(k3,k4,S6);
            flux_bas = baseflow_1(k5,S7);
            flux_snk = baseflow_1(k6,S7);
            flux_ein = evap_1(S2,beta*Ep,delta_t);
            flux_eim = evap_1(S3,(1-beta)*Ep,delta_t);
            flux_ea  = evap_7(S4,remx,Ep-flux_ein-flux_eim,delta_t);
            flux_et  = evap_15(Ep-flux_ein-flux_eim-flux_ea,S5,smax,S4,Ep-flux_ein-flux_eim,delta_t);

            % stores ODEs
            dS1 = flux_ps  - flux_m;
            dS2 = flux_pin - flux_ein - flux_ptf;    
            dS3 = flux_pim + flux_mim - flux_eim - flux_sas;
            dS4 = flux_inf - flux_ea  - flux_pc;
            dS5 = flux_pc  - flux_et  - flux_excs;
            dS6 = flux_qres- flux_gad - flux_ras;
            dS7 = flux_sep + flux_gad - flux_bas - flux_snk;
            
            % outputs
            dS = [dS1 dS2 dS3 dS4 dS5 dS6 dS7];
            fluxes = [flux_ps,   flux_pr,  flux_pim, flux_psm, flux_pby...
                      flux_pin,  flux_ptf, flux_m,   flux_mim, flux_msm...
                      flux_sas,  flux_sro, flux_inf, flux_pc,  flux_excs...
                      flux_qres, flux_sep, flux_gad, flux_ras, flux_bas...
                      flux_snk,  flux_ein, flux_eim, flux_ea,  flux_et];
        end
        
        % STEP runs at the end of every timestep.
function [out] = snowfall_1(In,T,p1,varargin)
%snowfall_1 

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Snowfall based on temperature threshold
% Constraints:  -
% @(Inputs):    p1   - temperature threshold below which snowfall occurs [oC]
%               T    - current temperature [oC]
%               In   - incoming precipitation flux [mm/d]
%               varargin(1) - smoothing variable r (default 0.01)

if size(varargin,2) == 0
    out = In.*(smoothThreshold_temperature_logistic(T,p1));
elseif size(varargin,2) == 1
    out = In.*(smoothThreshold_temperature_logistic(T,p1,varargin(1)));   
end


end
function [out] = rainfall_1(In,T,p1,varargin)
%rainfall_1 

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Rainfall based on temperature threshold
% Constraints:  -
% @(Inputs):    p1   - temperature threshold above which rainfall occurs [oC]
%               T    - current temperature [oC]
%               In   - incoming precipitation flux [mm/d]
%               varargin(1) - smoothing variable r (default 0.01)

if size(varargin,2) == 0
    out = In.*(1-smoothThreshold_temperature_logistic(T,p1));
elseif size(varargin,2) == 1
    out = In.*(1-smoothThreshold_temperature_logistic(T,p1,varargin(1)));    
end

end
function [out] = split_1(p1,In)
%split_1 flow splitting

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Split flow (returns flux [mm/d])
% Constraints:  -
% @(Inputs):    p1   - fraction of flux to be diverted [-]
%               In   - incoming flux [mm/d]

out = p1.*In;

end
function [out] = interception_1(In,S,Smax,varargin)
%interception_1

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Interception excess when maximum capacity is reached
% Constraints:  -
% @(Inputs):    In   - incoming flux [mm/d]
%               S    - current storage [mm]
%               Smax - maximum storage [mm]
%               varargin(1) - smoothing variable r (default 0.01)
%               varargin(2) - smoothing variable e (default 5.00)

if size(varargin,2) == 0
    out = In.*(1-smoothThreshold_storage_logistic(S,Smax));
elseif size(varargin,2) == 1
    out = In.*(1-smoothThreshold_storage_logistic(S,Smax,varargin(1)));
elseif size(varargin,2) == 2
    out = In.*(1-smoothThreshold_storage_logistic(S,Smax,varargin(1),varargin(2)));    
end

end
function [out] = melt_1(p1,p2,T,S,dt)
%melt_1 

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Snowmelt from degree-day-factor 
% Constraints:  f <= S/dt
% @(Inputs):    p1   - degree-day factor [mm/oC/d]
%               p2   - temperature threshold for snowmelt [oC]
%               T    - current temperature [oC]
%               S    - current storage [mm]
%               dt   - time step size [d]

out = max(min(p1*(T-p2),S/dt),0);

end
function [out] = saturation_1(In,S,Smax,varargin)
%saturation_1 

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Saturation excess from a store that has reached maximum capacity
% Constraints:  -
% @(Inputs):    In   - incoming flux [mm/d]
%               S    - current storage [mm]
%               Smax - maximum storage [mm]
%               varargin(1) - smoothing variable r (default 0.01)
%               varargin(2) - smoothing variable e (default 5.00)

if size(varargin,2) == 0
    out = In.*(1-smoothThreshold_storage_logistic(S,Smax));
elseif size(varargin,2) == 1
    out = In.*(1-smoothThreshold_storage_logistic(S,Smax,varargin(1)));
elseif size(varargin,2) == 2
    out = In.*(1-smoothThreshold_storage_logistic(S,Smax,varargin(1),varargin(2)));    
end

end
function [out] = saturation_8(p1,p2,S,Smax,In)
%saturation_8 

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Saturation excess flow from a store with different degrees 
%               of saturation (min-max linear variant)
% Constraints:  -
% @(Inputs):    p1   - minimum fraction contributing area [-]
%               p2   - maximum fraction contributing area [-]
%               S    - current storage [mm]
%               Smax - maximum contributing storage [mm]
%               In   - incoming flux [mm/d]

out = (p1+(p2-p1)*S/Smax)*In;

end
function [out] = effective_1(In1,In2)
%effective_1 

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  General effective flow (returns flux [mm/d])
% Constraints:  In1 > In2
% @(Inputs):    In1  - first flux [mm/d]
%               In2  - second flux [mm/d]

out = max(In1-In2,0);

end
function [out] = recharge_7(p1,fin)
%recharge_7 

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Constant recharge limited by incoming flux
% Constraints:  -
% @(Inputs):    p1   - maximum recharge rate [mm/d]
%               fin  - incoming flux [mm/d]

out = min(p1,fin);

end
function [out] = recharge_2(p1,S,Smax,flux)
%recharge_2 

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Recharge as non-linear scaling of incoming flux
% Constraints:  S >= 0
% @(Inputs):    p1   - recharge scaling non-linearity [-]
%               S    - current storage [mm]
%               Smax - maximum contributing storage [mm]
%               flux - incoming flux [mm/d]

out = flux*((max(S,0)/Smax)^p1);

end
function [out] = interflow_4(p1,p2,S)
%interflow_4 

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Combined linear and scaled quadratic interflow
% Constraints:  f <= S
%               S >= 0     - prevents numerical issues with complex numbers
% @(Inputs):    p1   - time coefficient [d-1]
%               p2   - scaling factor [mm-1 d-1]
%               S    - current storage [mm]

out = min(max(S,0),p1*max(S,0)+p2*max(S,0)^2);

end
function [out] = baseflow_1(p1,S)
% baseflow_1 

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Outflow from a linear reservoir
% Constraints:  -
% @(Inputs):    p1   - time scale parameter [d-1]
%               S    - current storage [mm]

out = p1.*S;

end
function [out] = evap_1(S,Ep,dt)
%evap_1 

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Evaporation at the potential rate
% Constraints:  f <= S/dt
% @(Inputs):    S    - current storage [mm]
%               Ep   - potential evaporation rate [mm/d]
%               dt   - time step size

out = min(S/dt,Ep);

end
function [out] = evap_7(S,Smax,Ep,dt)
%evap_7 evaporation based on scaled current water storage, limited by
%potential rate.

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Evaporation scaled by relative storage
% Constraints:  f <= S/dt
% @(Inputs):    S    - current storage [mm]
%               Smax - maximum contributing storage [mm]
%               Ep   - potential evapotranspiration rate [mm/d]
%               dt   - time step size [d]

out = min(S./Smax.*Ep,S/dt);

end
function [out] = evap_15(Ep,S1,S1max,S2,S2min,dt)
%evap_15 

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Scaled evaporation if another store is below a threshold
% Constraints:  f <= S1/dt
% @(Inputs):    Ep    - potential evapotranspiration rate [mm/d]
%               S1    - current storage in S1 [mm]
%               S1max - maximum storage in S1 [mm]
%               S2    - current storage in S2 [mm]
%               S2max - maximum storage in S2 [mm]
%               dt    - time step size [d]

out = min((S1/S1max*Ep).*smoothThreshold_storage_logistic(S2,S2min),S1/dt);

end
function [out] = smoothThreshold_temperature_logistic(T,Tt,r)
%smoothThreshold_temperature_logistic Logisitic smoother for temperature threshold functions.

% Copyright (C) 2018 Wouter J.M. Knoben
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

%   Smooths the transition of threshold functions of the form:
%
%   Snowfall = { P, if T <  Tt
%              { 0, if T >= Tt
%
%   By transforming the equation above to Sf = f(P,T,Tt,r):
%   Sf = P * 1/ (1+exp((T-Tt)/r))
%
%   Inputs:
%   P       : current precipitation
%   T       : current temperature
%   Tt      : threshold temperature below which snowfall occurs
%   r       : [optional] smoothing parameter rho, default = 0.01
%
%   NOTE: this function only outputs the multiplier. This needs to be
%   applied to the proper flux utside of this function.

% Check for inputs and use defaults if not provided
% NOTE: this is not very elegant, but it is more than a factor 10 faster then: 
% if ~exist('r','var'); r = 0.01; end
if nargin == 2
    r = 0.01;
end

% Calculate multiplier
out = 1 ./ (1+exp((T-Tt)/(r)));

end
function [out] = smoothThreshold_storage_logistic(S,Smax,r,e)
%smoothThreshold_storage_logistic Logisitic smoother for storage threshold functions.

% Copyright (C) 2018 Wouter J.M. Knoben
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

%   Smooths the transition of threshold functions of the form:
%
%   Q = { P, if S = Smax
%       { 0, if S < Smax
%
%   By transforming the equation above to Q = f(P,S,Smax,e,r):
%   Q = P * 1/ (1+exp((S-Smax+r*e*Smax)/(r*Smax)))
%
%   Inputs:
%   S       : current storage
%   Smax    : maximum storage
%   r       : [optional] smoothing parameter rho, default = 0.01
%   e       : [optional] smoothing parameter e, default 5
%
%   NOTE: this function only outputs the multiplier. This needs to be
%   applied to the proper flux utside of this function.
%
%   NOTE: can be applied for temperature thresholds as well (i.e. snow
%   modules). This simply means that S becomes T, and Smax T0.

% Check for inputs and use defaults if not provided
% NOTE: this is not very elegant, but it is more than a factor 10 faster then: 
% if ~exist('r','var'); r = 0.01; end
% if ~exist('e','var'); e = 5.00; end
if nargin == 2
    r = 0.01;
    e = 5.00;
elseif nargin == 3
    r = r{1};
    e = 5.00;
elseif nargin == 4
    r = r{1};
    e = e{1};
end

% Calculate multiplier
Smax = max(Smax,0);   % this avoids numerical instabilities when Smax<0
if r*Smax == 0
    out = 1 ./ (1+exp((S-Smax+r*e*Smax)/(r)));
else
    out = 1 ./ (1+exp((S-Smax+r*e*Smax)/(r*Smax)));
end

end

Note

This standardized MARRMoT structure is not identical to the original named model. p01... follow exact source order; s01... are fixed initial stores, defaulting to zero. Octave + optim are required. Solver behavior can differ across runtime versions.

Simulation

from basinforge import Basin, get_model

basin = Basin.from_csv("basin.csv", basin_id="A", area_km2=1200,
                       q_unit="m3/s", timestep="daily")
q_mm = get_model("MARRMOT_45").simulate(basin)
q_m3s = basin.to_m3s(q_mm)

Supply your actual data and catchment area; temperature-dependent models require a temperature column. For non-daily models, choose an appropriate warmup in model steps.

See calibration, input requirements, sources and verification limitations.