Rev 287 | Rev 385 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | |||
3 | Werner | 2 | #ifndef TREE_H |
3 | #define TREE_H |
||
4 | #include <QPointF> |
||
5 | |||
83 | Werner | 6 | #include "grid.h" |
158 | werner | 7 | // forwards |
90 | Werner | 8 | class Species; |
38 | Werner | 9 | class Stamp; |
187 | iland | 10 | class ResourceUnit; |
151 | iland | 11 | struct HeightGridValue; |
159 | werner | 12 | struct TreeGrowthData; |
264 | werner | 13 | class TreeOut; |
3 | Werner | 14 | |
15 | class Tree |
||
16 | { |
||
17 | public: |
||
141 | Werner | 18 | // lifecycle |
3 | Werner | 19 | Tree(); |
141 | Werner | 20 | void setup(); |
21 | |||
22 | // access to properties |
||
145 | Werner | 23 | int id() const { return mId; } |
169 | werner | 24 | int age() const { return mAge; } |
156 | werner | 25 | /// @property position The tree does not store the floating point coordinates but only the index of pixel on the LIF grid |
26 | const QPointF position() const { Q_ASSERT(mGrid!=0); return mGrid->cellCenterPoint(mPositionIndex); } |
||
158 | werner | 27 | const Species* species() const { Q_ASSERT(mRU!=0); return mSpecies; } ///< pointer to the tree species of the tree. |
187 | iland | 28 | const ResourceUnit *ru() const { Q_ASSERT(mRU!=0); return mRU; } ///< pointer to the ressource unit the tree belongs to. |
158 | werner | 29 | |
234 | werner | 30 | // properties |
31 | float dbh() const { return mDbh; } ///< dimater at breast height in cm |
||
32 | float height() const { return mHeight; } ///< tree height in m |
||
33 | float lightResourceIndex() const { return mLRI; } ///< LRI of the tree (updated during readStamp()) |
||
34 | float leafArea() const { return mLeafArea; } ///< leaf area (m2) of the tree |
||
158 | werner | 35 | double volume() const; ///< volume (m3) of stem volume based on geometry and density calculated on the fly. |
180 | werner | 36 | double basalArea() const; ///< basal area of the tree at breast height in m2 |
158 | werner | 37 | bool isDead() const { return flag(Tree::TreeDead); } ///< returns true if the tree is already dead. |
38 | // actions |
||
277 | werner | 39 | void die(TreeGrowthData *d=0); ///< kills the tree. |
278 | werner | 40 | void remove(); ///< remove the tree (management) |
158 | werner | 41 | void enableDebugging(const bool enable=true) {setFlag(Tree::TreeDebugging, enable); } |
42 | |||
43 | // setters for initialization |
||
44 | void setNewId() { mId = m_nextId++; } ///< force a new id for this object (after copying trees) |
||
247 | werner | 45 | void setId(const int id) { mId = id; } ///< set a spcific ID (if provided in stand init file). |
156 | werner | 46 | void setPosition(const QPointF pos) { Q_ASSERT(mGrid!=0); mPositionIndex = mGrid->indexAt(pos); } |
287 | werner | 47 | void setPosition(const QPoint posIndex) { mPositionIndex = posIndex; } |
106 | Werner | 48 | void setDbh(const float dbh) { mDbh=dbh; } |
49 | void setHeight(const float height) { mHeight=height; } |
||
50 | void setSpecies(Species *ts) { mSpecies=ts; } |
||
187 | iland | 51 | void setRU(ResourceUnit *ru) { mRU = ru; } |
381 | werner | 52 | void setAge(const int age, const bool isRealAge) { mAge = age; setFlag(Tree::TreeHasRealAge,isRealAge);} |
158 | werner | 53 | |
107 | Werner | 54 | // grid based light-concurrency functions |
158 | werner | 55 | void applyLIP(); ///< apply LightInfluencePattern onto the global grid |
187 | iland | 56 | void readLIF(); ///< calculate the lightResourceIndex with multiplicative approach |
107 | Werner | 57 | void heightGrid(); ///< calculate the height grid |
39 | Werner | 58 | |
158 | werner | 59 | void applyLIP_torus(); ///< apply LightInfluencePattern on a closed 1ha area |
60 | void readLIF_torus(); ///< calculate LRI from a closed 1ha area |
||
61 | void heightGrid_torus(); ///< calculate the height grid |
||
155 | werner | 62 | |
251 | werner | 63 | void calcLightResponse(); ///< calculate light response |
107 | Werner | 64 | // growth, etc. |
158 | werner | 65 | void grow(); ///< main growth function to update the tree state. |
107 | Werner | 66 | |
67 | // static functions |
||
151 | iland | 68 | static void setGrid(FloatGrid* gridToStamp, Grid<HeightGridValue> *dominanceGrid); |
40 | Werner | 69 | // statistics |
70 | static void resetStatistics(); |
||
145 | Werner | 71 | static int statPrints() { return m_statPrint; } |
72 | static int statCreated() { return m_statCreated; } |
||
40 | Werner | 73 | |
135 | Werner | 74 | QString dump(); |
145 | Werner | 75 | void dumpList(QList<QVariant> &rTargetList); |
135 | Werner | 76 | |
3 | Werner | 77 | private: |
110 | Werner | 78 | // helping functions |
159 | werner | 79 | void partitioning(TreeGrowthData &d); ///< split NPP into various plant pools. |
158 | werner | 80 | double relative_height_growth(); ///< estimate height growth based on light status. |
159 | werner | 81 | void grow_diameter(TreeGrowthData &d); ///< actual growth of the tree's stem. |
82 | void mortality(TreeGrowthData &d); ///< main function that checks whether trees is to die |
||
83 | |||
107 | Werner | 84 | // state variables |
169 | werner | 85 | int mId; ///< unique ID of tree |
86 | int mAge; ///< age of tree in years |
||
125 | Werner | 87 | float mDbh; ///< diameter at breast height [cm] |
88 | float mHeight; ///< tree height [m] |
||
156 | werner | 89 | QPoint mPositionIndex; ///< index of the trees position on the basic LIF grid |
107 | Werner | 90 | // biomass compartements |
149 | werner | 91 | float mLeafArea; ///< m2 leaf area |
92 | float mOpacity; ///< multiplier on LIP weights, depending on leaf area status (opacity of the crown) |
||
136 | Werner | 93 | float mFoliageMass; // kg |
94 | float mWoodyMass; // kg |
||
276 | werner | 95 | float mFineRootMass; // kg |
96 | float mCoarseRootMass; // kg |
||
116 | Werner | 97 | // production relevant |
98 | float mNPPReserve; // kg |
||
187 | iland | 99 | float mLRI; ///< resulting lightResourceIndex |
212 | werner | 100 | float mLightResponse; ///< light response used for distribution of biomass on RU level |
159 | werner | 101 | // auxiliary |
125 | Werner | 102 | float mDbhDelta; ///< diameter growth [cm] |
159 | werner | 103 | float mStressIndex; ///< stress index (used for mortality) |
104 | |||
187 | iland | 105 | // Stamp, Species, Resource Unit |
106 | Werner | 106 | const Stamp *mStamp; |
107 | Species *mSpecies; |
||
187 | iland | 108 | ResourceUnit *mRU; |
107 | Werner | 109 | |
157 | werner | 110 | // various flags |
111 | int mFlags; |
||
381 | werner | 112 | enum Flags { TreeDead=1, TreeDebugging=2, TreeHasRealAge }; |
157 | werner | 113 | void setFlag(const Tree::Flags flag, const bool value) { if (value) mFlags |= flag; else mFlags &= (flag ^ 0xffffff );} |
114 | bool flag(const Tree::Flags flag) const { return mFlags & flag; } |
||
139 | Werner | 115 | |
117 | Werner | 116 | // special functions |
157 | werner | 117 | bool isDebugging() { return flag(Tree::TreeDebugging); } |
135 | Werner | 118 | |
107 | Werner | 119 | // static data |
106 | Werner | 120 | static FloatGrid *mGrid; |
151 | iland | 121 | static Grid<HeightGridValue> *mHeightGrid; |
53 | Werner | 122 | |
40 | Werner | 123 | // statistics |
124 | static int m_statPrint; |
||
48 | Werner | 125 | static int m_statAboveZ; |
105 | Werner | 126 | static int m_statCreated; |
40 | Werner | 127 | static int m_nextId; |
148 | iland | 128 | |
129 | // friends |
||
130 | friend class TreeWrapper; |
||
180 | werner | 131 | friend class StandStatistics; |
264 | werner | 132 | friend class TreeOut; |
3 | Werner | 133 | }; |
134 | |||
257 | werner | 135 | /// internal data structure which is passed between function and to statistics |
136 | struct TreeGrowthData |
||
137 | { |
||
261 | werner | 138 | double NPP; ///< total NPP (kg) |
139 | double NPP_above; ///< NPP aboveground (kg) (NPP - fraction roots), no consideration of tree senescence |
||
257 | werner | 140 | double NPP_stem; ///< NPP used for growth of stem (dbh,h) |
141 | double stress_index; ///< stress index used for mortality calculation |
||
262 | werner | 142 | TreeGrowthData(): NPP(0.), NPP_above(0.), NPP_stem(0.) {} |
257 | werner | 143 | }; |
3 | Werner | 144 | #endif // TREE_H |