Subversion Repositories public iLand

Rev

Rev 425 | Rev 446 | 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:
387 werner 17
    Species(SpeciesSet *set) { mSet = set; mIndex=set->count(); mSeedDispersal=0; }
391 werner 18
    ~Species();
19
    // maintenance
20
    void setup();
415 werner 21
    void newYear();
391 werner 22
 
226 werner 23
    const SpeciesSet *speciesSet() const { return mSet; }
91 Werner 24
    // properties
391 werner 25
    SeedDispersal *seedDispersal() const { return mSeedDispersal; }
91 Werner 26
    /// @property id 4-character unique identification of the tree species
111 Werner 27
    const QString &id() const { return mId; }
91 Werner 28
    /// the full name (e.g. Picea Abies) of the species
111 Werner 29
    const QString &name() const { return mName; }
145 Werner 30
    int index() const { return mIndex; } ///< unique index of species within current set
179 werner 31
    bool active() const { return true; } ///< active??? todo!
236 werner 32
    int phenologyClass() const { return mPhenologyClass; } ///< phenology class defined in project file. class 0 = evergreen
33
    bool isConiferous() const { return mConiferous; }
34
    bool isEvergreen() const { return mEvergreen; }
415 werner 35
    bool isSeedYear() const { return mIsSeedYear; }
136 Werner 36
 
391 werner 37
 
91 Werner 38
    // calculations: allometries
145 Werner 39
    double biomassFoliage(const double dbh) const;
40
    double biomassWoody(const double dbh) const;
41
    double biomassRoot(const double dbh) const;
42
    double allometricRatio_wf() const { return mWoody_b / mFoliage_b; }
43
    double allometricFractionStem(const double dbh) const;
276 werner 44
    double finerootFoliageRatio() const { return mFinerootFoliageRatio; } ///< ratio of fineroot mass (kg) to foliage mass (kg)
136 Werner 45
 
116 Werner 46
    // turnover rates
145 Werner 47
    double turnoverLeaf() const { return mTurnoverLeaf; }
48
    double turnoverRoot() const { return mTurnoverRoot; }
119 Werner 49
    // hd-values
425 werner 50
    void hdRange(const double dbh, double &rMinHD, double &rMaxHD) const;
125 Werner 51
    // growth
145 Werner 52
    double volumeFactor() const { return mVolumeFactor; } ///< factor for volume calculation: V = factor * D^2*H (incorporates density and the form of the bole)
53
    double density() const { return mWoodDensity; } ///< density of stem wood [kg/m3]
54
    double specificLeafArea() const { return mSpecificLeafArea; }
159 werner 55
    // mortality
56
    double deathProb_intrinsic() const { return mDeathProb_intrinsic; }
308 werner 57
    inline double deathProb_stress(const double &stress_index) const;
169 werner 58
    // aging
425 werner 59
    double aging(const float height, const int age) const;
388 werner 60
    int estimateAge(const float height) const;///< estimate age for a tree with the current age
387 werner 61
    // regeneration
445 werner 62
    void seedProduction(const int age, const QPoint &position_index);
387 werner 63
    void setSeedDispersal(SeedDispersal *seed_dispersal) {mSeedDispersal=seed_dispersal; }
209 werner 64
    // environmental responses
65
    double vpdResponse(const double &vpd) const;
266 werner 66
    inline double temperatureResponse(const double &delayed_temp) const;
209 werner 67
    double nitrogenResponse(const double &availableNitrogen) const { return mSet->nitrogenResponse(availableNitrogen, mRespNitrogenClass); }
236 werner 68
    double canopyConductance() const { return mMaxCanopyConductance; } ///< maximum canopy conductance in m/s
266 werner 69
    inline double soilwaterResponse(const double &psi_kPa) const; ///< input: matrix potential (kPa) (e.g. -15)
274 werner 70
    double lightResponse(const double lightResourceIndex) {return mSet->lightResponse(lightResourceIndex, mLightResponseClass); }
304 werner 71
    double psiMin() const { return mPsiMin; }
445 werner 72
    // parameters for seed dispersal
73
    void treeMigKernel(double &ras1, double &ras2, double &ks) const { ras1=mTM_as1; ras2=mTM_as2; ks=mTM_ks; }
74
    double fecundity_m2() const { return mFecundity_m2; }
75
    double nonSeedYearFraction() const { return mNonSeedYearFraction; }
110 Werner 76
 
136 Werner 77
    const Stamp* stamp(const float dbh, const float height) const { return mLIPs.stamp(dbh, height);}
38 Werner 78
private:
90 Werner 79
    Q_DISABLE_COPY(Species);
136 Werner 80
    // helpers during setup
236 werner 81
    bool boolVar(const QString s) { return mSet->var(s).toBool(); } ///< during setup: get value of variable @p s as a boolean variable.
136 Werner 82
    double doubleVar(const QString s) { return mSet->var(s).toDouble(); }///< during setup: get value of variable @p s as a double.
236 werner 83
    int intVar(const QString s) { return mSet->var(s).toInt(); } ///< during setup: get value of variable @p s as an integer.
136 Werner 84
    QString stringVar(const QString s) { return mSet->var(s).toString(); } ///< during setup: get value of variable @p s as a string.
85
 
91 Werner 86
    SpeciesSet *mSet; ///< ptr. to the "parent" set
136 Werner 87
    StampContainer mLIPs; ///< ptr to the container of the LIP-pattern
91 Werner 88
    QString mId;
89
    QString mName;
111 Werner 90
    int mIndex; ///< internal index within the SpeciesSet
236 werner 91
    bool mConiferous; ///< true if confierous species (vs. broadleaved)
92
    bool mEvergreen; ///< true if evergreen species
136 Werner 93
    // biomass allometries:
94
    double mFoliage_a, mFoliage_b;  ///< allometry (biomass = a * dbh^b) for foliage
95
    double mWoody_a, mWoody_b; ///< allometry (biomass = a * dbh^b) for woody compartments aboveground
96
    double mRoot_a, mRoot_b; ///< allometry (biomass = a * dbh^b) for roots (compound, fine and coarse roots as one pool)
97
    double mBranch_a, mBranch_b; ///< allometry (biomass = a * dbh^b) for branches
98
 
110 Werner 99
    double mSpecificLeafArea; ///< conversion factor from kg OTS to m2 LeafArea
116 Werner 100
    // turnover rates
101
    double mTurnoverLeaf; ///< yearly turnover rate leafs
102
    double mTurnoverRoot; ///< yearly turnover rate root
276 werner 103
    double mFinerootFoliageRatio; ///< ratio of fineroot mass (kg) to foliage mass (kg)
119 Werner 104
    // height-diameter-relationships
105
    Expression mHDlow; ///< minimum HD-relation as f(d) (open grown tree)
106
    Expression mHDhigh; ///< maximum HD-relation as f(d)
125 Werner 107
    // stem density and taper
108
    double mWoodDensity; ///< density of the wood [kg/m3]
109
    double mFormFactor; ///< taper form factor of the stem [-] used for volume / stem-mass calculation calculation
110
    double mVolumeFactor; ///< factor for volume calculation
159 werner 111
    // mortality
112
    double mDeathProb_intrinsic;  ///< prob. of intrinsic death per year [0..1]
113
    double mDeathProb_stress; ///< max. prob. of death per year when tree suffering maximum stress
169 werner 114
    // Aging
115
    double mMaximumAge; ///< maximum age of species (years)
116
    double mMaximumHeight; ///< maximum height of species (m) for aging
214 werner 117
    Expression mAging;
209 werner 118
    // environmental responses
119
    double mRespVpdExponent; ///< exponent in vpd response calculation (Mäkela 2008)
120
    double mRespTempMin; ///< temperature response calculation offset
121
    double mRespTempMax; ///< temperature response calculation: saturation point for temp. response
122
    double mRespNitrogenClass; ///< nitrogen response class (1..3). fractional values (e.g. 1.2) are interpolated.
304 werner 123
    double mPsiMin; ///< minimum water potential (MPa), i.e. wilting point (is below zero!)
236 werner 124
    // water
125
    double mMaxCanopyConductance; ///< maximum canopy conductance for transpiration (m/s)
226 werner 126
    int mPhenologyClass;
274 werner 127
    double mLightResponseClass; ///< light response class (1..5) (1=shade intolerant)
387 werner 128
    // regeneration
129
    SeedDispersal *mSeedDispersal; ///< link to the seed dispersal map of the species
445 werner 130
    int mMaturityYears; ///< a tree produces seeds if it is older than this parameter
415 werner 131
    double mSeedYearProbability; ///< probability that a year is a seed year (=1/avg.timespan between seedyears)
132
    bool mIsSeedYear; ///< true, if current year is a seed year. see also:
445 werner 133
    double mNonSeedYearFraction;  ///< fraction of the seed production in non-seed-years
134
    // regeneration - seed dispersal
135
    double mFecundity_m2; ///< "surviving seeds" (cf. Moles et al) per m2, see also http://iland.boku.ac.at/fecundity
136
    double mTM_as1; ///< seed dispersal paramaters (treemig)
137
    double mTM_as2; ///< seed dispersal paramaters (treemig)
138
    double mTM_ks; ///< seed dispersal paramaters (treemig)
139
 
38 Werner 140
};
141
 
40 Werner 142
 
119 Werner 143
// inlined functions...
425 werner 144
inline void Species::hdRange(const double dbh, double &rLowHD, double &rHighHD) const
119 Werner 145
{
146
    rLowHD = mHDlow.calculate(dbh);
147
    rHighHD = mHDhigh.calculate(dbh);
148
}
209 werner 149
/** vpdResponse calculates response on vpd.
150
    Input: vpd [kPa]*/
151
inline double Species::vpdResponse(const double &vpd) const
152
{
153
    return exp(mRespVpdExponent * vpd);
154
}
119 Werner 155
 
209 werner 156
/** temperatureResponse calculates response on delayed daily temperature.
157
    Input: average temperature [°C]
158
    Note: slightly different from Mäkela 2008: the maximum parameter (Sk) in iLand is interpreted as the absolute
159
          temperature yielding a response of 1; in Mäkela 2008, Sk is the width of the range (relative to the lower threhold)
160
*/
161
inline double Species::temperatureResponse(const double &delayed_temp) const
162
{
163
    double x = qMax(delayed_temp-mRespTempMin, 0.);
164
    x = qMin(x/(mRespTempMax-mRespTempMin), 1.);
165
    return x;
166
}
266 werner 167
/** soilwaterResponse is a function of the current matrix potential of the soil.
209 werner 168
 
266 werner 169
  */
170
inline double Species::soilwaterResponse(const double &psi_kPa) const
171
{
172
    const double psi_mpa = psi_kPa / 1000.; // convert to MPa
304 werner 173
    double result = limit( 1. - psi_mpa / mPsiMin, 0., 1.);
266 werner 174
    return result;
175
}
176
 
308 werner 177
/** calculate probabilty of death based on the current stress index. */
178
inline double Species::deathProb_stress(const double &stress_index) const
179
{
180
    if (stress_index==0)
181
        return 0.;
182
    double result = 1. - exp(-mDeathProb_stress*stress_index);
183
    return result;
184
}
185
 
90 Werner 186
#endif // SPECIES_H