Subversion Repositories public iLand

Rev

Rev 191 | Rev 210 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 191 Rev 209
Line 62... Line 62...
62
    } // while query.next()
62
    } // while query.next()
63
    qDebug() << "loaded" << mSpecies.count() << "active species:";
63
    qDebug() << "loaded" << mSpecies.count() << "active species:";
64
    qDebug() << mSpecies.keys();
64
    qDebug() << mSpecies.keys();
65
65
66
    mSetupQuery = 0;
66
    mSetupQuery = 0;
-
 
67
-
 
68
    // setup nitrogen response
-
 
69
    XmlHelper resp(xml.node("model.species.nitrogenResponseClasses"));
-
 
70
    if (!resp.isValid())
-
 
71
        throw IException("model.species.nitrogenResponseClasses not present!");
-
 
72
    mNitrogen_1a = resp.valueDouble("class_1_a");
-
 
73
    mNitrogen_1b = resp.valueDouble("class_1_b");
-
 
74
    mNitrogen_2a = resp.valueDouble("class_2_a");
-
 
75
    mNitrogen_2b = resp.valueDouble("class_2_b");
-
 
76
    mNitrogen_3a = resp.valueDouble("class_3_a");
-
 
77
    mNitrogen_3b = resp.valueDouble("class_3_b");
-
 
78
    if (mNitrogen_1a*mNitrogen_1b*mNitrogen_2a*mNitrogen_2b*mNitrogen_3a*mNitrogen_3b == 0)
-
 
79
        throw IException("at least one parameter of model.species.nitrogenResponseClasses is not valid (value=0)!");
-
 
80
-
 
81
    // setup CO2 response
-
 
82
    XmlHelper co2(xml.node("model.species.CO2Response"));
-
 
83
    mCO2base = co2.valueDouble("baseConcentration");
-
 
84
    mCO2comp = co2.valueDouble("compensationPoint");
-
 
85
    mCO2beta0 = co2.valueDouble("beta0");
-
 
86
    mCO2p0 = co2.valueDouble("p0");
-
 
87
    if (mCO2base*mCO2comp*(mCO2base-mCO2comp)*mCO2beta0*mCO2p0==0)
-
 
88
        throw IException("at least one parameter of model.species.CO2Response is not valid!");
-
 
89
67
    return mSpecies.count();
90
    return mSpecies.count();
68
91
69
}
92
}
70
/** retrieves variables from the datasource available during the setup of species.
93
/** retrieves variables from the datasource available during the setup of species.
71
  */
94
  */
Line 79... Line 102...
79
    throw IException(QString("SpeciesSet: variable not set: %1").arg(varName));
102
    throw IException(QString("SpeciesSet: variable not set: %1").arg(varName));
80
    //throw IException(QString("load species parameter: field %1 not found!").arg(varName));
103
    //throw IException(QString("load species parameter: field %1 not found!").arg(varName));
81
    // lookup in defaults
104
    // lookup in defaults
82
    //qDebug() << "variable" << varName << "not found - using default.";
105
    //qDebug() << "variable" << varName << "not found - using default.";
83
    //return GlobalSettings::instance()->settingDefaultValue(varName);
106
    //return GlobalSettings::instance()->settingDefaultValue(varName);
-
 
107
}
-
 
108
-
 
109
inline double SpeciesSet::nitrogenResponse(const double &availableNitrogen, const double &NA, const double &NB) const
-
 
110
{
-
 
111
    if (availableNitrogen<=NB)
-
 
112
        return 0;
-
 
113
    double x = 1. - exp(NA * (availableNitrogen-NB));
-
 
114
    return x;
-
 
115
}
-
 
116
-
 
117
/// calculate nitrogen response for a given amount of available nitrogen and a respone class
-
 
118
/// for fractional values, the response value is interpolated between the fixedly defined classes (1,2,3)
-
 
119
double SpeciesSet::nitrogenResponse(const double availableNitrogen, const double &responseClass) const
-
 
120
{
-
 
121
    double value1, value2, value3;
-
 
122
    if (responseClass>2.) {
-
 
123
        if (responseClass==3.)
-
 
124
            return nitrogenResponse(availableNitrogen, mNitrogen_3a, mNitrogen_3b);
-
 
125
        else {
-
 
126
            // interpolate between 2 and 3
-
 
127
            value2 = nitrogenResponse(availableNitrogen, mNitrogen_2a, mNitrogen_2b);
-
 
128
            value3 = nitrogenResponse(availableNitrogen, mNitrogen_3a, mNitrogen_3b);
-
 
129
            return value2 + (responseClass-2)*(value3-value2);
-
 
130
        }
-
 
131
    }
-
 
132
    if (responseClass==2)
-
 
133
        return nitrogenResponse(availableNitrogen, mNitrogen_2a, mNitrogen_2b);
-
 
134
    if (responseClass==1)
-
 
135
        return nitrogenResponse(availableNitrogen, mNitrogen_1a, mNitrogen_1b);
-
 
136
    // last ressort: interpolate between 1 and 2
-
 
137
    value1 = nitrogenResponse(availableNitrogen, mNitrogen_1a, mNitrogen_1b);
-
 
138
    value2 = nitrogenResponse(availableNitrogen, mNitrogen_2a, mNitrogen_2b);
-
 
139
    return value1 + (responseClass-1)*(value2-value1);
-
 
140
}
-
 
141
-
 
142
/** calculation for the CO2 response for the ambientCO2 for the water- and nitrogen responses given.
-
 
143
    The calculation follows Friedlingsstein 1995 (see also links to equations in code)
-
 
144
*/
-
 
145
double SpeciesSet::co2Response(const double ambientCO2, const double nitrogenResponse, const double soilWaterResponse) const
-
 
146
{
-
 
147
    double co2_water = 2. - soilWaterResponse;
-
 
148
    double beta = mCO2beta0 * co2_water * nitrogenResponse;
-
 
149
-
 
150
    double r =1. +  M_LN2 * beta; // NPP increase for a doubling of atmospheric CO2 (Eq. 17)
-
 
151
-
 
152
    // fertilization function (cf. Farquhar, 1980) based on Michaelis-Menten expressions
-
 
153
    double deltaC = mCO2base - mCO2comp;
-
 
154
    double K2 = ((2*mCO2base - mCO2comp) - r*deltaC ) / ((r-1.)*deltaC*(2*mCO2base - mCO2comp)); // Eq. 16
-
 
155
    double K1 = (1. + K2*deltaC) / deltaC;
-
 
156
-
 
157
    double response = mCO2p0 * K1*(ambientCO2 - mCO2comp) / (1 + K2*(ambientCO2-mCO2comp)); // Eq. 16
-
 
158
    return response;
-
 
159
84
}
160
}