Subversion Repositories public iLand

Rev

Rev 276 | Rev 308 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 276 Rev 304
1
Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/species.h':
1
Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/species.h':
2
#ifndef SPECIES_H
2
#ifndef SPECIES_H
3
#define SPECIES_H
3
#define SPECIES_H
4
4
5
5
6
#include "expression.h"
6
#include "expression.h"
7
7
8
#include "speciesset.h"
8
#include "speciesset.h"
9
9
10
class StampContainer; // forwards
10
class StampContainer; // forwards
11
class Stamp;
11
class Stamp;
12
12
13
13
14
class Species
14
class Species
15
{
15
{
16
public:
16
public:
17
    Species(SpeciesSet *set) { mSet = set; mIndex=set->count(); }
17
    Species(SpeciesSet *set) { mSet = set; mIndex=set->count(); }
18
    const SpeciesSet *speciesSet() const { return mSet; }
18
    const SpeciesSet *speciesSet() const { return mSet; }
19
    // properties
19
    // properties
20
    /// @property id 4-character unique identification of the tree species
20
    /// @property id 4-character unique identification of the tree species
21
    const QString &id() const { return mId; }
21
    const QString &id() const { return mId; }
22
    /// the full name (e.g. Picea Abies) of the species
22
    /// the full name (e.g. Picea Abies) of the species
23
    const QString &name() const { return mName; }
23
    const QString &name() const { return mName; }
24
    int index() const { return mIndex; } ///< unique index of species within current set
24
    int index() const { return mIndex; } ///< unique index of species within current set
25
    bool active() const { return true; } ///< active??? todo!
25
    bool active() const { return true; } ///< active??? todo!
26
    int phenologyClass() const { return mPhenologyClass; } ///< phenology class defined in project file. class 0 = evergreen
26
    int phenologyClass() const { return mPhenologyClass; } ///< phenology class defined in project file. class 0 = evergreen
27
    bool isConiferous() const { return mConiferous; }
27
    bool isConiferous() const { return mConiferous; }
28
    bool isEvergreen() const { return mEvergreen; }
28
    bool isEvergreen() const { return mEvergreen; }
29
29
30
    // calculations: allometries
30
    // calculations: allometries
31
    double biomassFoliage(const double dbh) const;
31
    double biomassFoliage(const double dbh) const;
32
    double biomassWoody(const double dbh) const;
32
    double biomassWoody(const double dbh) const;
33
    double biomassRoot(const double dbh) const;
33
    double biomassRoot(const double dbh) const;
34
    double allometricRatio_wf() const { return mWoody_b / mFoliage_b; }
34
    double allometricRatio_wf() const { return mWoody_b / mFoliage_b; }
35
    double allometricFractionStem(const double dbh) const;
35
    double allometricFractionStem(const double dbh) const;
36
    double finerootFoliageRatio() const { return mFinerootFoliageRatio; } ///< ratio of fineroot mass (kg) to foliage mass (kg)
36
    double finerootFoliageRatio() const { return mFinerootFoliageRatio; } ///< ratio of fineroot mass (kg) to foliage mass (kg)
37
37
38
    // turnover rates
38
    // turnover rates
39
    double turnoverLeaf() const { return mTurnoverLeaf; }
39
    double turnoverLeaf() const { return mTurnoverLeaf; }
40
    double turnoverRoot() const { return mTurnoverRoot; }
40
    double turnoverRoot() const { return mTurnoverRoot; }
41
    // hd-values
41
    // hd-values
42
    void hdRange(const double dbh, double &rMinHD, double &rMaxHD);
42
    void hdRange(const double dbh, double &rMinHD, double &rMaxHD);
43
    // growth
43
    // growth
44
    double volumeFactor() const { return mVolumeFactor; } ///< factor for volume calculation: V = factor * D^2*H (incorporates density and the form of the bole)
44
    double volumeFactor() const { return mVolumeFactor; } ///< factor for volume calculation: V = factor * D^2*H (incorporates density and the form of the bole)
45
    double density() const { return mWoodDensity; } ///< density of stem wood [kg/m3]
45
    double density() const { return mWoodDensity; } ///< density of stem wood [kg/m3]
46
    double specificLeafArea() const { return mSpecificLeafArea; }
46
    double specificLeafArea() const { return mSpecificLeafArea; }
47
    // mortality
47
    // mortality
48
    double deathProb_intrinsic() const { return mDeathProb_intrinsic; }
48
    double deathProb_intrinsic() const { return mDeathProb_intrinsic; }
49
    double deathProb_stress() const { return mDeathProb_stress; }
49
    double deathProb_stress() const { return mDeathProb_stress; }
50
    // aging
50
    // aging
51
    double aging(const float height, const int age);
51
    double aging(const float height, const int age);
52
    // environmental responses
52
    // environmental responses
53
    double vpdResponse(const double &vpd) const;
53
    double vpdResponse(const double &vpd) const;
54
    inline double temperatureResponse(const double &delayed_temp) const;
54
    inline double temperatureResponse(const double &delayed_temp) const;
55
    double nitrogenResponse(const double &availableNitrogen) const { return mSet->nitrogenResponse(availableNitrogen, mRespNitrogenClass); }
55
    double nitrogenResponse(const double &availableNitrogen) const { return mSet->nitrogenResponse(availableNitrogen, mRespNitrogenClass); }
56
    double canopyConductance() const { return mMaxCanopyConductance; } ///< maximum canopy conductance in m/s
56
    double canopyConductance() const { return mMaxCanopyConductance; } ///< maximum canopy conductance in m/s
57
    inline double soilwaterResponse(const double &psi_kPa) const; ///< input: matrix potential (kPa) (e.g. -15)
57
    inline double soilwaterResponse(const double &psi_kPa) const; ///< input: matrix potential (kPa) (e.g. -15)
58
    double lightResponse(const double lightResourceIndex) {return mSet->lightResponse(lightResourceIndex, mLightResponseClass); }
58
    double lightResponse(const double lightResourceIndex) {return mSet->lightResponse(lightResourceIndex, mLightResponseClass); }
59
    double psiMax() const { return mPsiMax; }
-
 
-
 
59
    double psiMin() const { return mPsiMin; }
60
60
61
    const Stamp* stamp(const float dbh, const float height) const { return mLIPs.stamp(dbh, height);}
61
    const Stamp* stamp(const float dbh, const float height) const { return mLIPs.stamp(dbh, height);}
62
    // maintenance
62
    // maintenance
63
    void setup();
63
    void setup();
64
private:
64
private:
65
    Q_DISABLE_COPY(Species);
65
    Q_DISABLE_COPY(Species);
66
    QMutex mMutex;
66
    QMutex mMutex;
67
    // helpers during setup
67
    // helpers during setup
68
    bool boolVar(const QString s) { return mSet->var(s).toBool(); } ///< during setup: get value of variable @p s as a boolean variable.
68
    bool boolVar(const QString s) { return mSet->var(s).toBool(); } ///< during setup: get value of variable @p s as a boolean variable.
69
    double doubleVar(const QString s) { return mSet->var(s).toDouble(); }///< during setup: get value of variable @p s as a double.
69
    double doubleVar(const QString s) { return mSet->var(s).toDouble(); }///< during setup: get value of variable @p s as a double.
70
    int intVar(const QString s) { return mSet->var(s).toInt(); } ///< during setup: get value of variable @p s as an integer.
70
    int intVar(const QString s) { return mSet->var(s).toInt(); } ///< during setup: get value of variable @p s as an integer.
71
    QString stringVar(const QString s) { return mSet->var(s).toString(); } ///< during setup: get value of variable @p s as a string.
71
    QString stringVar(const QString s) { return mSet->var(s).toString(); } ///< during setup: get value of variable @p s as a string.
72
72
73
    SpeciesSet *mSet; ///< ptr. to the "parent" set
73
    SpeciesSet *mSet; ///< ptr. to the "parent" set
74
    StampContainer mLIPs; ///< ptr to the container of the LIP-pattern
74
    StampContainer mLIPs; ///< ptr to the container of the LIP-pattern
75
    QString mId;
75
    QString mId;
76
    QString mName;
76
    QString mName;
77
    int mIndex; ///< internal index within the SpeciesSet
77
    int mIndex; ///< internal index within the SpeciesSet
78
    bool mConiferous; ///< true if confierous species (vs. broadleaved)
78
    bool mConiferous; ///< true if confierous species (vs. broadleaved)
79
    bool mEvergreen; ///< true if evergreen species
79
    bool mEvergreen; ///< true if evergreen species
80
    // biomass allometries:
80
    // biomass allometries:
81
    double mFoliage_a, mFoliage_b;  ///< allometry (biomass = a * dbh^b) for foliage
81
    double mFoliage_a, mFoliage_b;  ///< allometry (biomass = a * dbh^b) for foliage
82
    double mWoody_a, mWoody_b; ///< allometry (biomass = a * dbh^b) for woody compartments aboveground
82
    double mWoody_a, mWoody_b; ///< allometry (biomass = a * dbh^b) for woody compartments aboveground
83
    double mRoot_a, mRoot_b; ///< allometry (biomass = a * dbh^b) for roots (compound, fine and coarse roots as one pool)
83
    double mRoot_a, mRoot_b; ///< allometry (biomass = a * dbh^b) for roots (compound, fine and coarse roots as one pool)
84
    double mBranch_a, mBranch_b; ///< allometry (biomass = a * dbh^b) for branches
84
    double mBranch_a, mBranch_b; ///< allometry (biomass = a * dbh^b) for branches
85
85
86
    double mSpecificLeafArea; ///< conversion factor from kg OTS to m2 LeafArea
86
    double mSpecificLeafArea; ///< conversion factor from kg OTS to m2 LeafArea
87
    // turnover rates
87
    // turnover rates
88
    double mTurnoverLeaf; ///< yearly turnover rate leafs
88
    double mTurnoverLeaf; ///< yearly turnover rate leafs
89
    double mTurnoverRoot; ///< yearly turnover rate root
89
    double mTurnoverRoot; ///< yearly turnover rate root
90
    double mFinerootFoliageRatio; ///< ratio of fineroot mass (kg) to foliage mass (kg)
90
    double mFinerootFoliageRatio; ///< ratio of fineroot mass (kg) to foliage mass (kg)
91
    // height-diameter-relationships
91
    // height-diameter-relationships
92
    Expression mHDlow; ///< minimum HD-relation as f(d) (open grown tree)
92
    Expression mHDlow; ///< minimum HD-relation as f(d) (open grown tree)
93
    Expression mHDhigh; ///< maximum HD-relation as f(d)
93
    Expression mHDhigh; ///< maximum HD-relation as f(d)
94
    // stem density and taper
94
    // stem density and taper
95
    double mWoodDensity; ///< density of the wood [kg/m3]
95
    double mWoodDensity; ///< density of the wood [kg/m3]
96
    double mFormFactor; ///< taper form factor of the stem [-] used for volume / stem-mass calculation calculation
96
    double mFormFactor; ///< taper form factor of the stem [-] used for volume / stem-mass calculation calculation
97
    double mVolumeFactor; ///< factor for volume calculation
97
    double mVolumeFactor; ///< factor for volume calculation
98
    // mortality
98
    // mortality
99
    double mDeathProb_intrinsic;  ///< prob. of intrinsic death per year [0..1]
99
    double mDeathProb_intrinsic;  ///< prob. of intrinsic death per year [0..1]
100
    double mDeathProb_stress; ///< max. prob. of death per year when tree suffering maximum stress
100
    double mDeathProb_stress; ///< max. prob. of death per year when tree suffering maximum stress
101
    // Aging
101
    // Aging
102
    double mMaximumAge; ///< maximum age of species (years)
102
    double mMaximumAge; ///< maximum age of species (years)
103
    double mMaximumHeight; ///< maximum height of species (m) for aging
103
    double mMaximumHeight; ///< maximum height of species (m) for aging
104
    Expression mAging;
104
    Expression mAging;
105
    // environmental responses
105
    // environmental responses
106
    double mRespVpdExponent; ///< exponent in vpd response calculation (Mäkela 2008)
106
    double mRespVpdExponent; ///< exponent in vpd response calculation (Mäkela 2008)
107
    double mRespTempMin; ///< temperature response calculation offset
107
    double mRespTempMin; ///< temperature response calculation offset
108
    double mRespTempMax; ///< temperature response calculation: saturation point for temp. response
108
    double mRespTempMax; ///< temperature response calculation: saturation point for temp. response
109
    double mRespNitrogenClass; ///< nitrogen response class (1..3). fractional values (e.g. 1.2) are interpolated.
109
    double mRespNitrogenClass; ///< nitrogen response class (1..3). fractional values (e.g. 1.2) are interpolated.
110
    double mPsiMax; ///< maximum water potential (MPa), i.e. wilting point (is below zero!)
-
 
-
 
110
    double mPsiMin; ///< minimum water potential (MPa), i.e. wilting point (is below zero!)
111
    // water
111
    // water
112
    double mMaxCanopyConductance; ///< maximum canopy conductance for transpiration (m/s)
112
    double mMaxCanopyConductance; ///< maximum canopy conductance for transpiration (m/s)
113
    int mPhenologyClass;
113
    int mPhenologyClass;
114
    double mLightResponseClass; ///< light response class (1..5) (1=shade intolerant)
114
    double mLightResponseClass; ///< light response class (1..5) (1=shade intolerant)
115
};
115
};
116
116
117
117
118
// inlined functions...
118
// inlined functions...
119
inline void Species::hdRange(const double dbh, double &rLowHD, double &rHighHD)
119
inline void Species::hdRange(const double dbh, double &rLowHD, double &rHighHD)
120
{
120
{
121
    QMutexLocker m(&mMutex); // serialize access
121
    QMutexLocker m(&mMutex); // serialize access
122
    rLowHD = mHDlow.calculate(dbh);
122
    rLowHD = mHDlow.calculate(dbh);
123
    rHighHD = mHDhigh.calculate(dbh);
123
    rHighHD = mHDhigh.calculate(dbh);
124
}
124
}
125
/** vpdResponse calculates response on vpd.
125
/** vpdResponse calculates response on vpd.
126
    Input: vpd [kPa]*/
126
    Input: vpd [kPa]*/
127
inline double Species::vpdResponse(const double &vpd) const
127
inline double Species::vpdResponse(const double &vpd) const
128
{
128
{
129
    return exp(mRespVpdExponent * vpd);
129
    return exp(mRespVpdExponent * vpd);
130
}
130
}
131
131
132
/** temperatureResponse calculates response on delayed daily temperature.
132
/** temperatureResponse calculates response on delayed daily temperature.
133
    Input: average temperature [°C]
133
    Input: average temperature [°C]
134
    Note: slightly different from Mäkela 2008: the maximum parameter (Sk) in iLand is interpreted as the absolute
134
    Note: slightly different from Mäkela 2008: the maximum parameter (Sk) in iLand is interpreted as the absolute
135
          temperature yielding a response of 1; in Mäkela 2008, Sk is the width of the range (relative to the lower threhold)
135
          temperature yielding a response of 1; in Mäkela 2008, Sk is the width of the range (relative to the lower threhold)
136
*/
136
*/
137
inline double Species::temperatureResponse(const double &delayed_temp) const
137
inline double Species::temperatureResponse(const double &delayed_temp) const
138
{
138
{
139
    double x = qMax(delayed_temp-mRespTempMin, 0.);
139
    double x = qMax(delayed_temp-mRespTempMin, 0.);
140
    x = qMin(x/(mRespTempMax-mRespTempMin), 1.);
140
    x = qMin(x/(mRespTempMax-mRespTempMin), 1.);
141
    return x;
141
    return x;
142
}
142
}
143
/** soilwaterResponse is a function of the current matrix potential of the soil.
143
/** soilwaterResponse is a function of the current matrix potential of the soil.
144

144

145
  */
145
  */
146
inline double Species::soilwaterResponse(const double &psi_kPa) const
146
inline double Species::soilwaterResponse(const double &psi_kPa) const
147
{
147
{
148
    const double psi_mpa = psi_kPa / 1000.; // convert to MPa
148
    const double psi_mpa = psi_kPa / 1000.; // convert to MPa
149
    double result = limit( 1. - psi_mpa / mPsiMax, 0., 1.);
-
 
-
 
149
    double result = limit( 1. - psi_mpa / mPsiMin, 0., 1.);
150
    return result;
150
    return result;
151
}
151
}
152
152
153
#endif // SPECIES_H
153
#endif // SPECIES_H
154
 
154