Rev 1174 | Rev 1176 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1174 | Rev 1175 | ||
---|---|---|---|
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 | #ifndef SAPLINGS_H
|
2 | #ifndef SAPLINGS_H
|
3 | #define SAPLINGS_H
|
3 | #define SAPLINGS_H
|
4 | 4 | ||
5 | #include "grid.h"
|
5 | #include "grid.h"
|
6 | #include "snag.h"
|
6 | #include "snag.h"
|
7 | #include <QRectF>
|
7 | #include <QRectF>
|
8 | class ResourceUnitSpecies; // forward |
8 | class ResourceUnitSpecies; // forward |
9 | class ResourceUnit; // forward |
9 | class ResourceUnit; // forward |
10 | 10 | ||
11 | struct SaplingTree { |
11 | struct SaplingTree { |
12 | SaplingTree() { clear(); } |
12 | SaplingTree() { clear(); } |
13 | short unsigned int age; // number of consectuive years the sapling suffers from dire conditions |
13 | short unsigned int age; // number of consectuive years the sapling suffers from dire conditions |
14 | short signed int species_index; // index of the species within the resource-unit-species container |
14 | short signed int species_index; // index of the species within the resource-unit-species container |
15 | unsigned char stress_years; // (upper 16bits) + age of sapling (lower 16 bits) |
15 | unsigned char stress_years; // (upper 16bits) + age of sapling (lower 16 bits) |
16 | unsigned char flags; // flags, e.g. whether sapling stems from sprouting |
16 | unsigned char flags; // flags, e.g. whether sapling stems from sprouting |
17 | float height; // height of the sapling in meter |
17 | float height; // height of the sapling in meter |
18 | bool is_occupied() const { return height>0.f; } |
18 | bool is_occupied() const { return height>0.f; } |
19 | void clear() { age=0; species_index=-1; stress_years=0; flags=0; height=0.f; } |
19 | void clear() { age=0; species_index=-1; stress_years=0; flags=0; height=0.f; } |
20 | void setSapling(const float h_m, const int age_yrs, const int species_idx) { height=h_m; age=static_cast<short unsigned int>(age_yrs); stress_years=0; species_index=static_cast<short signed int>(species_idx); } |
20 | void setSapling(const float h_m, const int age_yrs, const int species_idx) { height=h_m; age=static_cast<short unsigned int>(age_yrs); stress_years=0; species_index=static_cast<short signed int>(species_idx); } |
21 | // flags
|
21 | // flags
|
22 | bool is_sprout() const { return flags & 1; } |
22 | bool is_sprout() const { return flags & 1; } |
23 | void set_sprout(const bool sprout) {if (sprout) flags |= 1; else flags &= (1 ^ 0xffffff ); } |
23 | void set_sprout(const bool sprout) {if (sprout) flags |= 1; else flags &= (1 ^ 0xffffff ); } |
24 | // get resource unit species of the sapling tree
|
24 | // get resource unit species of the sapling tree
|
25 | ResourceUnitSpecies *resourceUnitSpecies(const ResourceUnit *ru); |
25 | ResourceUnitSpecies *resourceUnitSpecies(const ResourceUnit *ru); |
26 | }; |
26 | }; |
27 | #define NSAPCELLS 5
|
27 | #define NSAPCELLS 5
|
28 | struct SaplingCell { |
28 | struct SaplingCell { |
29 | enum ECellState { CellInvalid=0, CellFree=1, CellFull=2}; |
29 | enum ECellState { CellInvalid=0, CellFree=1, CellFull=2}; |
30 | SaplingCell() { |
30 | SaplingCell() { |
31 | state=CellInvalid; |
31 | state=CellInvalid; |
32 | }
|
32 | }
|
33 | ECellState state;
|
33 | ECellState state;
|
34 | SaplingTree saplings[NSAPCELLS]; |
34 | SaplingTree saplings[NSAPCELLS]; |
35 | void checkState() { if (state==CellInvalid) return; |
35 | void checkState() { if (state==CellInvalid) return; |
36 | bool free = false; |
36 | bool free = false; |
37 | for (int i=0;i<NSAPCELLS;++i) { |
37 | for (int i=0;i<NSAPCELLS;++i) { |
38 | // locked for all species, if a sapling of one species >1.3m
|
38 | // locked for all species, if a sapling of one species >1.3m
|
39 | if (saplings[i].height>1.3f) {state = CellFull; return; } |
39 | if (saplings[i].height>1.3f) {state = CellFull; return; } |
40 | // locked, if all slots are occupied.
|
40 | // locked, if all slots are occupied.
|
41 | if (!saplings[i].is_occupied()) |
41 | if (!saplings[i].is_occupied()) |
42 | free=true; |
42 | free=true; |
43 | }
|
43 | }
|
44 | state = free? CellFree : CellFull; |
44 | state = free? CellFree : CellFull; |
45 | }
|
45 | }
|
46 | /// get an index to an open slot in the cell, or -1 if all slots are occupied
|
46 | /// get an index to an open slot in the cell, or -1 if all slots are occupied
|
47 | int free_index() { |
47 | int free_index() { |
48 | for (int i=0;i<NSAPCELLS;++i) |
48 | for (int i=0;i<NSAPCELLS;++i) |
49 | if (!saplings[i].is_occupied()) |
49 | if (!saplings[i].is_occupied()) |
50 | return i; |
50 | return i; |
51 | return -1; |
51 | return -1; |
52 | }
|
52 | }
|
- | 53 | /// count the number of occupied slots on the pixel
|
|
- | 54 | int n_occupied() { |
|
- | 55 | int n=0; |
|
- | 56 | for (int i=0;i<NSAPCELLS;++i) |
|
- | 57 | n+=saplings[i].is_occupied(); |
|
- | 58 | return n; |
|
- | 59 | }
|
|
- | 60 | ||
53 | /// add a sapling to this cell, return a pointer to the tree on success, or 0 otherwise
|
61 | /// add a sapling to this cell, return a pointer to the tree on success, or 0 otherwise
|
54 | SaplingTree *addSapling(const float h_m, const int age_yrs, const int species_idx) { |
62 | SaplingTree *addSapling(const float h_m, const int age_yrs, const int species_idx) { |
55 | int idx = free_index(); |
63 | int idx = free_index(); |
56 | if (idx==-1) |
64 | if (idx==-1) |
57 | return 0; |
65 | return 0; |
58 | saplings[idx].setSapling(h_m, age_yrs, species_idx); |
66 | saplings[idx].setSapling(h_m, age_yrs, species_idx); |
59 | return &saplings[idx]; |
67 | return &saplings[idx]; |
60 | }
|
68 | }
|
61 | /// return the maximum height on the pixel
|
69 | /// return the maximum height on the pixel
|
62 | float max_height() { if (state==CellInvalid) return 0.f; |
70 | float max_height() { if (state==CellInvalid) return 0.f; |
63 | float h_max = 0.f; |
71 | float h_max = 0.f; |
64 | for (int i=0;i<NSAPCELLS;++i) |
72 | for (int i=0;i<NSAPCELLS;++i) |
65 | h_max = std::max(saplings[i].height, h_max); |
73 | h_max = std::max(saplings[i].height, h_max); |
66 | return h_max; |
74 | return h_max; |
67 | }
|
75 | }
|
68 | /// return the sapling tree of the requested species, or 0
|
76 | /// return the sapling tree of the requested species, or 0
|
69 | SaplingTree *sapling(int species_index) { |
77 | SaplingTree *sapling(int species_index) { |
70 | if (state==CellInvalid) return 0; |
78 | if (state==CellInvalid) return 0; |
71 | for (int i=0;i<NSAPCELLS;++i) |
79 | for (int i=0;i<NSAPCELLS;++i) |
72 | if (saplings[i].species_index == species_index) |
80 | if (saplings[i].species_index == species_index) |
73 | return &saplings[i]; |
81 | return &saplings[i]; |
74 | return 0; |
82 | return 0; |
75 | }
|
83 | }
|
76 | }; |
84 | }; |
77 | class ResourceUnit; |
85 | class ResourceUnit; |
78 | class Saplings; |
86 | class Saplings; |
79 | 87 | ||
80 | /** The SaplingStat class stores statistics on the resource unit x species level.
|
88 | /** The SaplingStat class stores statistics on the resource unit x species level.
|
81 | */
|
89 | */
|
82 | class SaplingStat
|
90 | class SaplingStat
|
83 | {
|
91 | {
|
84 | public: |
92 | public: |
85 | SaplingStat() { clearStatistics(); } |
93 | SaplingStat() { clearStatistics(); } |
86 | void clearStatistics(); |
94 | void clearStatistics(); |
87 | void calculate(const Species *species, ResourceUnit *ru); |
- | |
- | 95 | void calculate(const Species *species, ResourceUnit *ru, double cohorts_per_area); |
|
88 | // actions
|
96 | // actions
|
89 | void addCarbonOfDeadSapling(float dbh) { mDied++; mSumDbhDied+=dbh; } |
97 | void addCarbonOfDeadSapling(float dbh) { mDied++; mSumDbhDied+=dbh; } |
90 | 98 | ||
91 | // access to statistics
|
99 | // access to statistics
|
92 | int newSaplings() const { return mAdded; } |
100 | int newSaplings() const { return mAdded; } |
93 | int diedSaplings() const { return mDied; } |
101 | int diedSaplings() const { return mDied; } |
94 | int livingSaplings() const { return mLiving; } ///< get the number |
102 | int livingSaplings() const { return mLiving; } ///< get the number |
95 | int recruitedSaplings() const { return mRecruited; } |
103 | int recruitedSaplings() const { return mRecruited; } |
96 | /// returns the *represented* (Reineke's Law) number of trees (N/ha) and the mean dbh/height (cm/m)
|
104 | /// returns the *represented* (Reineke's Law) number of trees (N/ha) and the mean dbh/height (cm/m)
|
97 | double livingStemNumber(const Species *species, double &rAvgDbh, double &rAvgHeight, double &rAvgAge) const; |
105 | double livingStemNumber(const Species *species, double &rAvgDbh, double &rAvgHeight, double &rAvgAge) const; |
98 | 106 | ||
99 | double averageHeight() const { return mAvgHeight; } |
107 | double averageHeight() const { return mAvgHeight; } |
100 | double averageAge() const { return mAvgAge; } |
108 | double averageAge() const { return mAvgAge; } |
101 | double averageDeltaHPot() const { return mAvgDeltaHPot; } |
109 | double averageDeltaHPot() const { return mAvgDeltaHPot; } |
102 | double averageDeltaHRealized() const { return mAvgHRealized; } |
110 | double averageDeltaHRealized() const { return mAvgHRealized; } |
103 | // carbon and nitrogen
|
111 | // carbon and nitrogen
|
104 | const CNPair &carbonLiving() const { return mCarbonLiving; } ///< state of the living |
112 | const CNPair &carbonLiving() const { return mCarbonLiving; } ///< state of the living |
105 | const CNPair &carbonGain() const { return mCarbonGain; } ///< state of the living |
113 | const CNPair &carbonGain() const { return mCarbonGain; } ///< state of the living |
106 | 114 | ||
107 | private: |
115 | private: |
108 | int mAdded; ///< number of trees added |
116 | int mAdded; ///< number of trees added |
109 | int mRecruited; ///< number recruited (i.e. grown out of regeneration layer) |
117 | int mRecruited; ///< number recruited (i.e. grown out of regeneration layer) |
110 | int mDied; ///< number of trees died |
118 | int mDied; ///< number of trees died |
111 | double mSumDbhDied; ///< running sum of dbh of died trees (used to calculate detritus) |
119 | double mSumDbhDied; ///< running sum of dbh of died trees (used to calculate detritus) |
112 | int mLiving; ///< number of trees (cohorts!!!) currently in the regeneration layer |
120 | int mLiving; ///< number of trees (cohorts!!!) currently in the regeneration layer |
- | 121 | double mLivingSaplings; ///< number of individual trees in the regen layer (using Reinekes R) |
|
113 | double mAvgHeight; ///< average height of saplings (m) |
122 | double mAvgHeight; ///< average height of saplings (m) |
114 | double mAvgAge; ///< average age of saplings (years) |
123 | double mAvgAge; ///< average age of saplings (years) |
115 | double mAvgDeltaHPot; ///< average height increment potential (m) |
124 | double mAvgDeltaHPot; ///< average height increment potential (m) |
116 | double mAvgHRealized; ///< average realized height increment |
125 | double mAvgHRealized; ///< average realized height increment |
117 | CNPair mCarbonLiving;
|
- | |
- | 126 | CNPair mCarbonLiving; ///< kg Carbon (kg/ru) of saplings |
|
118 | CNPair mCarbonGain; ///< net growth (kg / ru) of saplings |
127 | CNPair mCarbonGain; ///< net growth (kg / ru) of saplings |
119 | 128 | ||
120 | friend class Saplings; |
129 | friend class Saplings; |
121 | 130 | ||
122 | }; |
131 | }; |
123 | /** The Saplings class the container for the establishment and sapling growth in iLand.
|
132 | /** The Saplings class the container for the establishment and sapling growth in iLand.
|
124 | *
|
133 | *
|
125 | */
|
134 | */
|
126 | class Saplings
|
135 | class Saplings
|
127 | {
|
136 | {
|
128 | public: |
137 | public: |
129 | Saplings(); |
138 | Saplings(); |
130 | void setup(); |
139 | void setup(); |
131 | // main functions
|
140 | // main functions
|
132 | void establishment(const ResourceUnit *ru); |
141 | void establishment(const ResourceUnit *ru); |
133 | void saplingGrowth(const ResourceUnit *ru); |
142 | void saplingGrowth(const ResourceUnit *ru); |
134 | 143 | ||
135 | // access
|
144 | // access
|
136 | /// return the SaplingCell (i.e. container for the ind. saplings) for the given 2x2m coordinates
|
145 | /// return the SaplingCell (i.e. container for the ind. saplings) for the given 2x2m coordinates
|
137 | /// if 'only_valid' is true, then 0 is returned if no living saplings are on the cell
|
146 | /// if 'only_valid' is true, then 0 is returned if no living saplings are on the cell
|
138 | /// 'rRUPtr' is a pointer to a RU-ptr: if provided, a pointer to the resource unit is stored
|
147 | /// 'rRUPtr' is a pointer to a RU-ptr: if provided, a pointer to the resource unit is stored
|
139 | SaplingCell *cell(QPoint lif_coords, bool only_valid=true, ResourceUnit **rRUPtr=0); |
148 | SaplingCell *cell(QPoint lif_coords, bool only_valid=true, ResourceUnit **rRUPtr=0); |
140 | /// clear/kill all saplings within the rectangle given by 'rectangle'.
|
149 | /// clear/kill all saplings within the rectangle given by 'rectangle'.
|
141 | /// If 'remove_biomass' is true, then the biomass is extracted (e.g. burnt), otherwise they are moved to soil
|
150 | /// If 'remove_biomass' is true, then the biomass is extracted (e.g. burnt), otherwise they are moved to soil
|
142 | void clearSaplings(const QRectF &rectangle, const bool remove_biomass); |
151 | void clearSaplings(const QRectF &rectangle, const bool remove_biomass); |
143 | /// clear all saplings on a given cell 's' (if 'remove_biomass' is true: biomass removed from system (e.g. burnt))
|
152 | /// clear all saplings on a given cell 's' (if 'remove_biomass' is true: biomass removed from system (e.g. burnt))
|
144 | void clearSaplings(SaplingCell *s, ResourceUnit *ru, const bool remove_biomass); |
153 | void clearSaplings(SaplingCell *s, ResourceUnit *ru, const bool remove_biomass); |
145 | 154 | ||
146 | /// generate vegetative offspring from 't' (sprouts)
|
155 | /// generate vegetative offspring from 't' (sprouts)
|
147 | int addSprout(const Tree *t); |
156 | int addSprout(const Tree *t); |
148 | 157 | ||
149 | static void setRecruitmentVariation(const double variation) { mRecruitmentVariation = variation; } |
158 | static void setRecruitmentVariation(const double variation) { mRecruitmentVariation = variation; } |
150 | static void updateBrowsingPressure(); |
159 | static void updateBrowsingPressure(); |
151 | 160 | ||
152 | private: |
161 | private: |
153 | bool growSapling(const ResourceUnit *ru, SaplingCell &scell, SaplingTree &tree, int isc, float dom_height, float lif_value); |
162 | bool growSapling(const ResourceUnit *ru, SaplingCell &scell, SaplingTree &tree, int isc, float dom_height, float lif_value); |
154 | //Grid<SaplingCell> mGrid;
|
163 | //Grid<SaplingCell> mGrid;
|
155 | static double mRecruitmentVariation; |
164 | static double mRecruitmentVariation; |
156 | static double mBrowsingPressure; |
165 | static double mBrowsingPressure; |
157 | }; |
166 | }; |
158 | 167 | ||
159 | #endif // SAPLINGS_H
|
168 | #endif // SAPLINGS_H
|
160 | 169 |