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