Rev 1221 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1221 | Rev 1222 | ||
---|---|---|---|
1 | Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/saplings.h': |
1 | Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/saplings.h': |
2 | /********************************************************************************************
|
2 | /********************************************************************************************
|
3 | ** iLand - an individual based forest landscape and disturbance model
|
3 | ** iLand - an individual based forest landscape and disturbance model
|
4 | ** http://iland.boku.ac.at
|
4 | ** http://iland.boku.ac.at
|
5 | ** Copyright (C) 2009- Werner Rammer, Rupert Seidl
|
5 | ** Copyright (C) 2009- Werner Rammer, Rupert Seidl
|
6 | **
|
6 | **
|
7 | ** This program is free software: you can redistribute it and/or modify
|
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
|
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
|
9 | ** the Free Software Foundation, either version 3 of the License, or
|
10 | ** (at your option) any later version.
|
10 | ** (at your option) any later version.
|
11 | **
|
11 | **
|
12 | ** This program is distributed in the hope that it will be useful,
|
12 | ** This program is distributed in the hope that it will be useful,
|
13 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 | ** GNU General Public License for more details.
|
15 | ** GNU General Public License for more details.
|
16 | **
|
16 | **
|
17 | ** You should have received a copy of the GNU General Public License
|
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/>.
|
18 | ** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19 | ********************************************************************************************/
|
19 | ********************************************************************************************/
|
20 | #ifndef SAPLINGS_H
|
20 | #ifndef SAPLINGS_H
|
21 | #define SAPLINGS_H
|
21 | #define SAPLINGS_H
|
22 | 22 | ||
23 | #include "grid.h"
|
23 | #include "grid.h"
|
24 | #include "snag.h"
|
24 | #include "snag.h"
|
25 | #include <QRectF>
|
25 | #include <QRectF>
|
26 | class ResourceUnitSpecies; // forward |
26 | class ResourceUnitSpecies; // forward |
27 | class ResourceUnit; // forward |
27 | class ResourceUnit; // forward |
28 | 28 | ||
29 | struct SaplingTree { |
29 | struct SaplingTree { |
30 | SaplingTree() { clear(); } |
30 | SaplingTree() { clear(); } |
31 | short unsigned int age; // number of consectuive years the sapling suffers from dire conditions |
31 | short unsigned int age; // number of consectuive years the sapling suffers from dire conditions |
32 | short signed int species_index; // index of the species within the resource-unit-species container |
32 | short signed int species_index; // index of the species within the resource-unit-species container |
33 | unsigned char stress_years; // number of consecutive years that a sapling suffers from stress |
33 | unsigned char stress_years; // number of consecutive years that a sapling suffers from stress |
34 | unsigned char flags; // flags, e.g. whether sapling stems from sprouting |
34 | unsigned char flags; // flags, e.g. whether sapling stems from sprouting |
35 | float height; // height of the sapling in meter |
35 | float height; // height of the sapling in meter |
36 | bool is_occupied() const { return height>0.f; } |
36 | bool is_occupied() const { return height>0.f; } |
37 | void clear() { age=0; species_index=-1; stress_years=0; flags=0; height=0.f; } |
37 | void clear() { age=0; species_index=-1; stress_years=0; flags=0; height=0.f; } |
38 | void setSapling(const float h_m, const int age_yrs, const int species_idx) { height=h_m; |
38 | void setSapling(const float h_m, const int age_yrs, const int species_idx) { height=h_m; |
39 | age=static_cast<short unsigned int>(age_yrs); |
39 | age=static_cast<short unsigned int>(age_yrs); |
40 | stress_years=0; |
40 | stress_years=0; |
41 | species_index=static_cast<short signed int>(species_idx); } |
41 | species_index=static_cast<short signed int>(species_idx); } |
42 | // flags
|
42 | // flags
|
43 | bool is_sprout() const { return flags & 1; } |
43 | bool is_sprout() const { return flags & 1; } |
44 | void set_sprout(const bool sprout) {if (sprout) flags |= 1; else flags &= (1 ^ 0xffffff ); } |
44 | void set_sprout(const bool sprout) {if (sprout) flags |= 1; else flags &= (1 ^ 0xffffff ); } |
45 | // get resource unit species of the sapling tree
|
45 | // get resource unit species of the sapling tree
|
46 | ResourceUnitSpecies *resourceUnitSpecies(const ResourceUnit *ru); |
46 | ResourceUnitSpecies *resourceUnitSpecies(const ResourceUnit *ru); |
47 | }; |
47 | }; |
48 | #define NSAPCELLS 5
|
48 | #define NSAPCELLS 5
|
49 | struct SaplingCell { |
49 | struct SaplingCell { |
50 | enum ECellState { CellInvalid=0, CellFree=1, CellFull=2}; |
50 | enum ECellState { CellInvalid=0, CellFree=1, CellFull=2}; |
51 | SaplingCell() { |
51 | SaplingCell() { |
52 | state=CellInvalid; |
52 | state=CellInvalid; |
53 | }
|
53 | }
|
54 | ECellState state;
|
54 | ECellState state;
|
55 | SaplingTree saplings[NSAPCELLS]; |
55 | SaplingTree saplings[NSAPCELLS]; |
56 | void checkState() { if (state==CellInvalid) return; |
56 | void checkState() { if (state==CellInvalid) return; |
57 | bool free = false; |
57 | bool free = false; |
58 | for (int i=0;i<NSAPCELLS;++i) { |
58 | for (int i=0;i<NSAPCELLS;++i) { |
59 | // locked for all species, if a sapling of one species >1.3m
|
59 | // locked for all species, if a sapling of one species >1.3m
|
60 | if (saplings[i].height>1.3f) {state = CellFull; return; } |
60 | if (saplings[i].height>1.3f) {state = CellFull; return; } |
61 | // locked, if all slots are occupied.
|
61 | // locked, if all slots are occupied.
|
62 | if (!saplings[i].is_occupied()) |
62 | if (!saplings[i].is_occupied()) |
63 | free=true; |
63 | free=true; |
64 | }
|
64 | }
|
65 | state = free? CellFree : CellFull; |
65 | state = free? CellFree : CellFull; |
66 | }
|
66 | }
|
67 | /// get an index to an open slot in the cell, or -1 if all slots are occupied
|
67 | /// get an index to an open slot in the cell, or -1 if all slots are occupied
|
68 | int free_index() { |
68 | int free_index() { |
69 | for (int i=0;i<NSAPCELLS;++i) |
69 | for (int i=0;i<NSAPCELLS;++i) |
70 | if (!saplings[i].is_occupied()) |
70 | if (!saplings[i].is_occupied()) |
71 | return i; |
71 | return i; |
72 | return -1; |
72 | return -1; |
73 | }
|
73 | }
|
74 | /// count the number of occupied slots on the pixel
|
74 | /// count the number of occupied slots on the pixel
|
75 | int n_occupied() { |
75 | int n_occupied() { |
76 | int n=0; |
76 | int n=0; |
77 | for (int i=0;i<NSAPCELLS;++i) |
77 | for (int i=0;i<NSAPCELLS;++i) |
78 | n+=saplings[i].is_occupied(); |
78 | n+=saplings[i].is_occupied(); |
79 | return n; |
79 | return n; |
80 | }
|
80 | }
|
81 | 81 | ||
82 | /// add a sapling to this cell, return a pointer to the tree on success, or 0 otherwise
|
82 | /// add a sapling to this cell, return a pointer to the tree on success, or 0 otherwise
|
83 | SaplingTree *addSapling(const float h_m, const int age_yrs, const int species_idx) { |
83 | SaplingTree *addSapling(const float h_m, const int age_yrs, const int species_idx) { |
84 | int idx = free_index(); |
84 | int idx = free_index(); |
85 | if (idx==-1) |
85 | if (idx==-1) |
86 | return 0; |
86 | return 0; |
87 | saplings[idx].setSapling(h_m, age_yrs, species_idx); |
87 | saplings[idx].setSapling(h_m, age_yrs, species_idx); |
88 | return &saplings[idx]; |
88 | return &saplings[idx]; |
89 | }
|
89 | }
|
90 | /// return the maximum height on the pixel
|
90 | /// return the maximum height on the pixel
|
91 | float max_height() { if (state==CellInvalid) return 0.f; |
91 | float max_height() { if (state==CellInvalid) return 0.f; |
92 | float h_max = 0.f; |
92 | float h_max = 0.f; |
93 | for (int i=0;i<NSAPCELLS;++i) |
93 | for (int i=0;i<NSAPCELLS;++i) |
94 | h_max = std::max(saplings[i].height, h_max); |
94 | h_max = std::max(saplings[i].height, h_max); |
95 | return h_max; |
95 | return h_max; |
96 | }
|
96 | }
|
97 | bool has_new_saplings() { if (state==CellInvalid) return 0.f; |
97 | bool has_new_saplings() { if (state==CellInvalid) return 0.f; |
98 | for (int i=0;i<NSAPCELLS;++i) |
98 | for (int i=0;i<NSAPCELLS;++i) |
99 | if (saplings[i].is_occupied() && saplings[i].age<2) |
99 | if (saplings[i].is_occupied() && saplings[i].age<2) |
100 | return true; |
100 | return true; |
101 | return false; |
101 | return false; |
102 | }
|
102 | }
|
103 | /// return the sapling tree of the requested species, or 0
|
103 | /// return the sapling tree of the requested species, or 0
|
104 | SaplingTree *sapling(int species_index) { |
104 | SaplingTree *sapling(int species_index) { |
105 | if (state==CellInvalid) return 0; |
105 | if (state==CellInvalid) return 0; |
106 | for (int i=0;i<NSAPCELLS;++i) |
106 | for (int i=0;i<NSAPCELLS;++i) |
107 | if (saplings[i].species_index == species_index) |
107 | if (saplings[i].species_index == species_index) |
108 | return &saplings[i]; |
108 | return &saplings[i]; |
109 | return 0; |
109 | return 0; |
110 | }
|
110 | }
|
111 | }; |
111 | }; |
112 | class ResourceUnit; |
112 | class ResourceUnit; |
113 | class Saplings; |
113 | class Saplings; |
114 | 114 | ||
115 | /** The SaplingStat class stores statistics on the resource unit x species level.
|
115 | /** The SaplingStat class stores statistics on the resource unit x species level.
|
116 | */
|
116 | */
|
117 | class SaplingStat
|
117 | class SaplingStat
|
118 | {
|
118 | {
|
119 | public: |
119 | public: |
120 | SaplingStat() { clearStatistics(); } |
120 | SaplingStat() { clearStatistics(); } |
121 | void clearStatistics(); |
121 | void clearStatistics(); |
122 | /// calculate statistics (and carbon flows) for the saplings of species 'species' on 'ru'.
|
122 | /// calculate statistics (and carbon flows) for the saplings of species 'species' on 'ru'.
|
123 | void calculate(const Species *species, ResourceUnit *ru); |
123 | void calculate(const Species *species, ResourceUnit *ru); |
124 | // actions
|
124 | // actions
|
125 | void addCarbonOfDeadSapling(float dbh) { mDied++; mSumDbhDied+=dbh; } |
125 | void addCarbonOfDeadSapling(float dbh) { mDied++; mSumDbhDied+=dbh; } |
126 | 126 | ||
127 | // access to statistics
|
127 | // access to statistics
|
128 | int newSaplings() const { return mAdded; } |
128 | int newSaplings() const { return mAdded; } |
129 | int diedSaplings() const { return mDied; } |
129 | int diedSaplings() const { return mDied; } |
130 | int livingCohorts() const { return mLiving; } ///< get the number of cohorts |
130 | int livingCohorts() const { return mLiving; } ///< get the number of cohorts |
131 | double livingSaplings() const { return mLivingSaplings; } |
131 | double livingSaplings() const { return mLivingSaplings; } |
132 | double livingSaplingsSmall() const { return mLivingSmallSaplings; } |
132 | double livingSaplingsSmall() const { return mLivingSmallSaplings; } |
133 | int recruitedSaplings() const { return mRecruited; } |
133 | int recruitedSaplings() const { return mRecruited; } |
134 | /// returns the *represented* (Reineke's Law) number of trees (N/ha) and the mean dbh/height (cm/m)
|
134 | /// returns the *represented* (Reineke's Law) number of trees (N/ha) and the mean dbh/height (cm/m)
|
135 | double livingStemNumber(const Species *species, double &rAvgDbh, double &rAvgHeight, double &rAvgAge) const; |
135 | double livingStemNumber(const Species *species, double &rAvgDbh, double &rAvgHeight, double &rAvgAge) const; |
136 | 136 | ||
137 | double averageHeight() const { return mAvgHeight; } |
137 | double averageHeight() const { return mAvgHeight; } |
138 | double averageAge() const { return mAvgAge; } |
138 | double averageAge() const { return mAvgAge; } |
139 | double averageDeltaHPot() const { return mAvgDeltaHPot; } |
139 | double averageDeltaHPot() const { return mAvgDeltaHPot; } |
140 | double averageDeltaHRealized() const { return mAvgHRealized; } |
140 | double averageDeltaHRealized() const { return mAvgHRealized; } |
141 | // carbon and nitrogen
|
141 | // carbon and nitrogen
|
142 | const CNPair &carbonLiving() const { return mCarbonLiving; } ///< state of the living |
142 | const CNPair &carbonLiving() const { return mCarbonLiving; } ///< state of the living |
143 | const CNPair &carbonGain() const { return mCarbonGain; } ///< state of the living |
143 | const CNPair &carbonGain() const { return mCarbonGain; } ///< state of the living |
144 | 144 | ||
145 | private: |
145 | private: |
146 | int mAdded; ///< number of tree cohorts added |
146 | int mAdded; ///< number of tree cohorts added |
147 | int mRecruited; ///< number of cohorts recruited (i.e. grown out of regeneration layer) |
147 | int mRecruited; ///< number of cohorts recruited (i.e. grown out of regeneration layer) |
148 | int mDied; ///< number of tree cohorts died |
148 | int mDied; ///< number of tree cohorts died |
149 | double mSumDbhDied; ///< running sum of dbh of died trees (used to calculate detritus) |
149 | double mSumDbhDied; ///< running sum of dbh of died trees (used to calculate detritus) |
150 | int mLiving; ///< number of trees (cohorts!!!) currently in the regeneration layer |
150 | int mLiving; ///< number of trees (cohorts!!!) currently in the regeneration layer |
151 | double mLivingSaplings; ///< number of individual trees in the regen layer (using Reinekes R), with h>1.3m |
151 | double mLivingSaplings; ///< number of individual trees in the regen layer (using Reinekes R), with h>1.3m |
152 | double mLivingSmallSaplings; ///< number of individual trees of cohorts < 1.3m height |
152 | double mLivingSmallSaplings; ///< number of individual trees of cohorts < 1.3m height |
153 | double mAvgHeight; ///< average height of saplings (m) |
153 | double mAvgHeight; ///< average height of saplings (m) |
154 | double mAvgAge; ///< average age of saplings (years) |
154 | double mAvgAge; ///< average age of saplings (years) |
155 | double mAvgDeltaHPot; ///< average height increment potential (m) |
155 | double mAvgDeltaHPot; ///< average height increment potential (m) |
156 | double mAvgHRealized; ///< average realized height increment |
156 | double mAvgHRealized; ///< average realized height increment |
157 | CNPair mCarbonLiving; ///< kg Carbon (kg/ru) of saplings |
157 | CNPair mCarbonLiving; ///< kg Carbon (kg/ru) of saplings |
158 | CNPair mCarbonGain; ///< net growth (kg / ru) of saplings |
158 | CNPair mCarbonGain; ///< net growth (kg / ru) of saplings |
159 | 159 | ||
160 | friend class Saplings; |
160 | friend class Saplings; |
161 | 161 | ||
162 | }; |
162 | }; |
163 | /** The Saplings class the container for the establishment and sapling growth in iLand.
|
163 | /** The Saplings class the container for the establishment and sapling growth in iLand.
|
164 | *
|
164 | *
|
165 | */
|
165 | */
|
166 | class Saplings
|
166 | class Saplings
|
167 | {
|
167 | {
|
168 | public: |
168 | public: |
169 | Saplings(); |
169 | Saplings(); |
170 | void setup(); |
170 | void setup(); |
171 | void calculateInitialStatistics(const ResourceUnit *ru); |
171 | void calculateInitialStatistics(const ResourceUnit *ru); |
172 | // main functions
|
172 | // main functions
|
173 | void establishment(const ResourceUnit *ru); |
173 | void establishment(const ResourceUnit *ru); |
174 | void saplingGrowth(const ResourceUnit *ru); |
174 | void saplingGrowth(const ResourceUnit *ru); |
175 | 175 | ||
176 | // access
|
176 | // access
|
177 | /// return the SaplingCell (i.e. container for the ind. saplings) for the given 2x2m coordinates
|
177 | /// return the SaplingCell (i.e. container for the ind. saplings) for the given 2x2m coordinates
|
178 | /// if 'only_valid' is true, then 0 is returned if no living saplings are on the cell
|
178 | /// if 'only_valid' is true, then 0 is returned if no living saplings are on the cell
|
179 | /// 'rRUPtr' is a pointer to a RU-ptr: if provided, a pointer to the resource unit is stored
|
179 | /// 'rRUPtr' is a pointer to a RU-ptr: if provided, a pointer to the resource unit is stored
|
180 | SaplingCell *cell(QPoint lif_coords, bool only_valid=true, ResourceUnit **rRUPtr=0); |
180 | SaplingCell *cell(QPoint lif_coords, bool only_valid=true, ResourceUnit **rRUPtr=0); |
181 | /// clear/kill all saplings within the rectangle given by 'rectangle'.
|
181 | /// clear/kill all saplings within the rectangle given by 'rectangle'.
|
182 | /// If 'remove_biomass' is true, then the biomass is extracted (e.g. burnt), otherwise they are moved to soil
|
182 | /// If 'remove_biomass' is true, then the biomass is extracted (e.g. burnt), otherwise they are moved to soil
|
183 | void clearSaplings(const QRectF &rectangle, const bool remove_biomass); |
183 | void clearSaplings(const QRectF &rectangle, const bool remove_biomass); |
184 | /// clear all saplings on a given cell 's' (if 'remove_biomass' is true: biomass removed from system (e.g. burnt))
|
184 | /// clear all saplings on a given cell 's' (if 'remove_biomass' is true: biomass removed from system (e.g. burnt))
|
185 | void clearSaplings(SaplingCell *s, ResourceUnit *ru, const bool remove_biomass); |
185 | void clearSaplings(SaplingCell *s, ResourceUnit *ru, const bool remove_biomass); |
186 | 186 | ||
187 | /// generate vegetative offspring from 't' (sprouts)
|
187 | /// generate vegetative offspring from 't' (sprouts)
|
188 | int addSprout(const Tree *t); |
188 | int addSprout(const Tree *t); |
189 | 189 | ||
190 | static void setRecruitmentVariation(const double variation) { mRecruitmentVariation = variation; } |
190 | static void setRecruitmentVariation(const double variation) { mRecruitmentVariation = variation; } |
191 | static void updateBrowsingPressure(); |
191 | static void updateBrowsingPressure(); |
192 | 192 | ||
193 | private: |
193 | private: |
194 | bool growSapling(const ResourceUnit *ru, SaplingCell &scell, SaplingTree &tree, int isc, float dom_height, float lif_value, int cohorts_on_px); |
194 | bool growSapling(const ResourceUnit *ru, SaplingCell &scell, SaplingTree &tree, int isc, float dom_height, float lif_value, int cohorts_on_px); |
195 | //Grid<SaplingCell> mGrid;
|
195 | //Grid<SaplingCell> mGrid;
|
196 | static double mRecruitmentVariation; |
196 | static double mRecruitmentVariation; |
197 | static double mBrowsingPressure; |
197 | static double mBrowsingPressure; |
198 | }; |
198 | }; |
199 | 199 | ||
200 | 200 | ||
201 | /** SaplingCellRunner is a helper class to access all SaplingCell that
|
201 | /** SaplingCellRunner is a helper class to access all SaplingCell that
|
202 | * are located on a given "stand" (in the stand grid)
|
202 | * are located on a given "stand" (in the stand grid)
|
203 | */
|
203 | */
|
204 | class MapGrid; // forward |
204 | class MapGrid; // forward |
205 | class SaplingCellRunner
|
205 | class SaplingCellRunner
|
206 | {
|
206 | {
|
207 | public: |
207 | public: |
208 | SaplingCellRunner(const int stand_id, const MapGrid *stand_grid=0); |
208 | SaplingCellRunner(const int stand_id, const MapGrid *stand_grid=0); |
209 | ~SaplingCellRunner(); |
209 | ~SaplingCellRunner(); |
210 | SaplingCell *next(); |
210 | SaplingCell *next(); |
211 | ResourceUnit *ru() const { return mRU; } |
211 | ResourceUnit *ru() const { return mRU; } |
212 | QPointF currentCoord() const; |
212 | QPointF currentCoord() const; |
213 | private: |
213 | private: |
214 | GridRunner<float> *mRunner; |
214 | GridRunner<float> *mRunner; |
215 | ResourceUnit *mRU; |
215 | ResourceUnit *mRU; |
216 | const MapGrid *mStandGrid; |
216 | const MapGrid *mStandGrid; |
217 | int mStandId; |
217 | int mStandId; |
218 | }; |
218 | }; |
219 | 219 | ||
220 | #endif // SAPLINGS_H
|
220 | #endif // SAPLINGS_H
|
221 | 221 |