Subversion Repositories public iLand

Rev

Rev 975 | Rev 1044 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1
 
671 werner 2
/********************************************************************************************
3
**    iLand - an individual based forest landscape and disturbance model
4
**    http://iland.boku.ac.at
5
**    Copyright (C) 2009-  Werner Rammer, Rupert Seidl
6
**
7
**    This program is free software: you can redistribute it and/or modify
8
**    it under the terms of the GNU General Public License as published by
9
**    the Free Software Foundation, either version 3 of the License, or
10
**    (at your option) any later version.
11
**
12
**    This program is distributed in the hope that it will be useful,
13
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
**    GNU General Public License for more details.
16
**
17
**    You should have received a copy of the GNU General Public License
18
**    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
********************************************************************************************/
20
 
3 Werner 21
#ifndef TREE_H
22
#define TREE_H
23
#include <QPointF>
24
 
83 Werner 25
#include "grid.h"
158 werner 26
// forwards
90 Werner 27
class Species;
38 Werner 28
class Stamp;
187 iland 29
class ResourceUnit;
151 iland 30
struct HeightGridValue;
159 werner 31
struct TreeGrowthData;
264 werner 32
class TreeOut;
3 Werner 33
 
34
class Tree
35
{
36
public:
141 Werner 37
    // lifecycle
3 Werner 38
    Tree();
885 werner 39
    void setup(); ///< calculates initial values for biomass pools etc. after dimensions are set.
141 Werner 40
 
41
    // access to properties
885 werner 42
    int id() const { return mId; } ///< numerical unique ID of the tree
43
    int age() const { return mAge; } ///< the tree age (years)
156 werner 44
    /// @property position The tree does not store the floating point coordinates but only the index of pixel on the LIF grid
45
    const QPointF position() const { Q_ASSERT(mGrid!=0); return mGrid->cellCenterPoint(mPositionIndex); }
544 werner 46
    const QPoint positionIndex() const { return mPositionIndex; }
158 werner 47
    const Species* species() const { Q_ASSERT(mRU!=0); return mSpecies; } ///< pointer to the tree species of the tree.
187 iland 48
    const ResourceUnit *ru() const { Q_ASSERT(mRU!=0); return mRU; } ///< pointer to the ressource unit the tree belongs to.
158 werner 49
 
234 werner 50
    // properties
51
    float dbh() const { return mDbh; } ///< dimater at breast height in cm
52
    float height() const { return mHeight; } ///< tree height in m
53
    float lightResourceIndex() const { return mLRI; } ///< LRI of the tree (updated during readStamp())
54
    float leafArea() const { return mLeafArea; } ///< leaf area (m2) of the tree
158 werner 55
    double volume() const; ///< volume (m3) of stem volume based on geometry and density calculated on the fly.
180 werner 56
    double basalArea() const; ///< basal area of the tree at breast height in m2
158 werner 57
    bool isDead() const { return flag(Tree::TreeDead); } ///< returns true if the tree is already dead.
407 werner 58
    float crownRadius() const; ///< fetch crown radius (m) from the attached stamp
449 werner 59
    // biomass properties
60
    float biomassFoliage() const { return mFoliageMass; } ///< mass (kg) of foliage
476 werner 61
    float biomassBranch() const;  ///< mass (kg) of branches
449 werner 62
    float biomassFineRoot() const { return mFineRootMass; } ///< mass (kg) of fine roots
63
    float biomassCoarseRoot() const { return mCoarseRootMass; } ///< mass (kg) of coarse roots
64
    float biomassStem() const { return mWoodyMass; } ///< mass (kg) of stem
667 werner 65
    double barkThickness() const; ///< thickness of the bark (cm)
1010 werner 66
    float stressIndex() const { return mStressIndex; } ///< the scalar stress rating (0..1)
449 werner 67
 
158 werner 68
    // actions
904 werner 69
    enum TreeRemovalType { TreeDeath, TreeHarvest, TreeDisturbance};
713 werner 70
    /// the tree dies (is killed)
71
    void die(TreeGrowthData *d=0);
564 werner 72
    /// remove the tree (management). removalFractions for tree compartments: if 0: all biomass stays in the system, 1: all is "removed"
73
    /// default values: all biomass remains in the forest (i.e.: kill()).
74
    void remove(double removeFoliage=0., double removeBranch=0., double removeStem=0. );
713 werner 75
    /// remove the tree due to an special event (disturbance)
76
    /// the part of the biomass that goes not to soil/snags is removed (e.g. fire)
77
    /// @param stem_to_soil_fraction (0..1) of stem biomass that is routed to the soil
78
    /// @param stem_to_snag_fraction (0..1) of the stem biomass continues as standing dead
79
    /// @param branch_to_soil_fraction (0..1) of branch biomass that is routed to the soil
80
    /// @param branch_to_snag_fraction (0..1) of the branch biomass continues as standing dead
81
    /// @param foliage_to_soil_fraciton (0..1) fraction of biomass that goes directly to the soil. The rest (1.-fraction) is removed.
82
    void removeDisturbance(const double stem_to_soil_fraction, const double stem_to_snag_fraction,
83
                           const double branch_to_soil_fraction, const double branch_to_snag_fraction,
84
                           const double foliage_to_soil_fraction);
85
 
158 werner 86
    void enableDebugging(const bool enable=true) {setFlag(Tree::TreeDebugging, enable); }
668 werner 87
    /// removes fractions (0..1) for foliage, branches, stem from a tree, e.g. due to a fire.
88
    /// values of "0" remove nothing, "1" removes the full compartent.
903 werner 89
    void removeBiomassOfTree(const double removeFoliageFraction, const double removeBranchFraction, const double removeStemFraction);
158 werner 90
 
91
    // setters for initialization
92
    void setNewId() { mId = m_nextId++; } ///< force a new id for this object (after copying trees)
247 werner 93
    void setId(const int id) { mId = id; } ///< set a spcific ID (if provided in stand init file).
156 werner 94
    void setPosition(const QPointF pos) { Q_ASSERT(mGrid!=0); mPositionIndex = mGrid->indexAt(pos); }
287 werner 95
    void setPosition(const QPoint posIndex) { mPositionIndex = posIndex; }
106 Werner 96
    void setDbh(const float dbh) { mDbh=dbh; }
975 werner 97
    void setHeight(const float height);
106 Werner 98
    void setSpecies(Species *ts) { mSpecies=ts; }
187 iland 99
    void setRU(ResourceUnit *ru) { mRU = ru; }
388 werner 100
    void setAge(const int age, const float treeheight);
158 werner 101
 
885 werner 102
    // management flags (used by ABE management system)
103
    void markForHarvest(bool do_mark) { setFlag(Tree::MarkForHarvest, do_mark);}
104
    bool isMarkedForHarvest() const { return flag(Tree::MarkForHarvest);}
105
    void markForCut(bool do_mark) { setFlag(Tree::MarkForCut, do_mark);}
106
    bool isMarkedForCut() const { return flag(Tree::MarkForCut);}
107
    void markCropTree(bool do_mark) { setFlag(Tree::MarkCropTree, do_mark);}
108
    bool isMarkedAsCropTree() const { return flag(Tree::MarkCropTree);}
951 werner 109
    void markCropCompetitor(bool do_mark) { setFlag(Tree::MarkCropCompetitor, do_mark);}
110
    bool isMarkedAsCropCompetitor() const { return flag(Tree::MarkCropCompetitor);}
885 werner 111
 
107 Werner 112
    // grid based light-concurrency functions
158 werner 113
    void applyLIP(); ///< apply LightInfluencePattern onto the global grid
187 iland 114
    void readLIF(); ///< calculate the lightResourceIndex with multiplicative approach
107 Werner 115
    void heightGrid(); ///< calculate the height grid
39 Werner 116
 
158 werner 117
    void applyLIP_torus(); ///< apply LightInfluencePattern on a closed 1ha area
118
    void readLIF_torus(); ///< calculate LRI from a closed 1ha area
119
    void heightGrid_torus(); ///< calculate the height grid
155 werner 120
 
251 werner 121
    void calcLightResponse(); ///< calculate light response
107 Werner 122
    // growth, etc.
158 werner 123
    void grow(); ///< main growth function to update the tree state.
107 Werner 124
 
125
    // static functions
151 iland 126
    static void setGrid(FloatGrid* gridToStamp, Grid<HeightGridValue> *dominanceGrid);
40 Werner 127
    // statistics
128
    static void resetStatistics();
145 Werner 129
    static int statPrints() { return m_statPrint; }
130
    static int statCreated() { return m_statCreated; }
40 Werner 131
 
135 Werner 132
    QString dump();
145 Werner 133
    void dumpList(QList<QVariant> &rTargetList);
733 werner 134
    const Stamp *stamp() const { return mStamp; } ///< TODO: only for debugging purposes
135 Werner 135
 
3 Werner 136
private:
110 Werner 137
    // helping functions
159 werner 138
    void partitioning(TreeGrowthData &d); ///< split NPP into various plant pools.
158 werner 139
    double relative_height_growth(); ///< estimate height growth based on light status.
159 werner 140
    void grow_diameter(TreeGrowthData &d); ///< actual growth of the tree's stem.
141
    void mortality(TreeGrowthData &d); ///< main function that checks whether trees is to die
904 werner 142
    void recordRemovedVolume(TreeRemovalType reason); ///< record the removed volume in the height grid
159 werner 143
 
107 Werner 144
    // state variables
169 werner 145
    int mId; ///< unique ID of tree
146
    int mAge; ///< age of tree in years
125 Werner 147
    float mDbh; ///< diameter at breast height [cm]
148
    float mHeight; ///< tree height [m]
156 werner 149
    QPoint mPositionIndex; ///< index of the trees position on the basic LIF grid
107 Werner 150
    // biomass compartements
149 werner 151
    float mLeafArea; ///< m2 leaf area
152
    float mOpacity; ///< multiplier on LIP weights, depending on leaf area status (opacity of the crown)
885 werner 153
    float mFoliageMass; ///< kg of foliage (dry)
154
    float mWoodyMass; ///< kg biomass of aboveground stem biomass
155
    float mFineRootMass; ///< kg biomass of fine roots (linked to foliage mass)
156
    float mCoarseRootMass; ///< kg biomass of coarse roots (allometric equation)
116 Werner 157
    // production relevant
885 werner 158
    float mNPPReserve; ///< NPP reserve pool [kg] - stores a part of assimilates for use in less favorable years
187 iland 159
    float mLRI; ///< resulting lightResourceIndex
212 werner 160
    float mLightResponse; ///< light response used for distribution of biomass on RU level
159 werner 161
    // auxiliary
125 Werner 162
    float mDbhDelta; ///< diameter growth [cm]
159 werner 163
    float mStressIndex; ///< stress index (used for mortality)
164
 
187 iland 165
    // Stamp, Species, Resource Unit
106 Werner 166
    const Stamp *mStamp;
167
    Species *mSpecies;
187 iland 168
    ResourceUnit *mRU;
107 Werner 169
 
157 werner 170
    // various flags
171
    int mFlags;
885 werner 172
    /// (binary coded) tree flags
173
    enum Flags { TreeDead=1, TreeDebugging=2,
174
                 MarkForCut=256, // mark tree for being cut down
175
                 MarkForHarvest=512, // mark tree for being harvested
951 werner 176
                 MarkCropTree=1024, // mark as crop tree
177
                 MarkCropCompetitor=2048 // mark as competitor for a crop tree
885 werner 178
               };
179
    /// set a Flag 'flag' to the value 'value'.
157 werner 180
    void setFlag(const Tree::Flags flag, const bool value) { if (value) mFlags |= flag; else mFlags &= (flag ^ 0xffffff );}
885 werner 181
    /// set a number of flags (need to be constructed by or'ing flags together) at the same time to the Boolean value 'value'.
182
    void setFlag(const int flag, const bool value) { if (value) mFlags |= flag; else mFlags &= (flag ^ 0xffffff );}
183
    /// retrieve the value of the flag 'flag'.
157 werner 184
    bool flag(const Tree::Flags flag) const { return mFlags & flag; }
139 Werner 185
 
117 Werner 186
    // special functions
157 werner 187
    bool isDebugging() { return flag(Tree::TreeDebugging); }
135 Werner 188
 
107 Werner 189
    // static data
106 Werner 190
    static FloatGrid *mGrid;
151 iland 191
    static Grid<HeightGridValue> *mHeightGrid;
53 Werner 192
 
40 Werner 193
    // statistics
194
    static int m_statPrint;
48 Werner 195
    static int m_statAboveZ;
105 Werner 196
    static int m_statCreated;
40 Werner 197
    static int m_nextId;
148 iland 198
 
199
    // friends
200
    friend class TreeWrapper;
180 werner 201
    friend class StandStatistics;
264 werner 202
    friend class TreeOut;
675 werner 203
    friend class Snapshot;
3 Werner 204
};
205
 
257 werner 206
/// internal data structure which is passed between function and to statistics
207
struct TreeGrowthData
208
{
261 werner 209
    double NPP; ///< total NPP (kg)
210
    double NPP_above; ///< NPP aboveground (kg) (NPP - fraction roots), no consideration of tree senescence
257 werner 211
    double NPP_stem;  ///< NPP used for growth of stem (dbh,h)
212
    double stress_index; ///< stress index used for mortality calculation
262 werner 213
    TreeGrowthData(): NPP(0.), NPP_above(0.), NPP_stem(0.) {}
257 werner 214
};
3 Werner 215
#endif // TREE_H