Rev 1002 | Rev 1040 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1002 | Rev 1017 | ||
---|---|---|---|
1 | Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/resourceunit.h': |
1 | Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/resourceunit.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 | 20 | ||
21 | #ifndef RESOURCEUNIT_H
|
21 | #ifndef RESOURCEUNIT_H
|
22 | #define RESOURCEUNIT_H
|
22 | #define RESOURCEUNIT_H
|
23 | 23 | ||
24 | #include "tree.h"
|
24 | #include "tree.h"
|
25 | #include "resourceunitspecies.h"
|
25 | #include "resourceunitspecies.h"
|
26 | #include "standstatistics.h"
|
26 | #include "standstatistics.h"
|
27 | #include <QtCore/QVector>
|
27 | #include <QtCore/QVector>
|
28 | #include <QtCore/QRectF>
|
28 | #include <QtCore/QRectF>
|
29 | class SpeciesSet; |
29 | class SpeciesSet; |
30 | class Climate; |
30 | class Climate; |
31 | class WaterCycle; |
31 | class WaterCycle; |
32 | class Snag; |
32 | class Snag; |
33 | class Soil; |
33 | class Soil; |
34 | 34 | ||
35 | struct ResourceUnitVariables
|
35 | struct ResourceUnitVariables
|
36 | {
|
36 | {
|
37 | double nitrogenAvailable; ///< nitrogen content (kg/m2/year) |
37 | double nitrogenAvailable; ///< nitrogen content (kg/m2/year) |
38 | }; |
38 | }; |
39 | 39 | ||
40 | class ResourceUnit
|
40 | class ResourceUnit
|
41 | {
|
41 | {
|
42 | public: |
42 | public: |
43 | ResourceUnit(const int index); |
43 | ResourceUnit(const int index); |
44 | ~ResourceUnit(); |
44 | ~ResourceUnit(); |
45 | // setup/maintenance
|
45 | // setup/maintenance
|
46 | void setup(); ///< setup operations after the creation of the model space. |
46 | void setup(); ///< setup operations after the creation of the model space. |
47 | void setSpeciesSet(SpeciesSet *set); |
47 | void setSpeciesSet(SpeciesSet *set); |
48 | void setClimate(Climate* climate) { mClimate = climate; } |
48 | void setClimate(Climate* climate) { mClimate = climate; } |
49 | void setBoundingBox(const QRectF &bb); |
49 | void setBoundingBox(const QRectF &bb); |
50 | void setID(const int id) { mID = id; } |
50 | void setID(const int id) { mID = id; } |
51 | 51 | ||
52 | // access to elements
|
52 | // access to elements
|
53 | const Climate *climate() const { return mClimate; } ///< link to the climate on this resource unit |
53 | const Climate *climate() const { return mClimate; } ///< link to the climate on this resource unit |
54 | SpeciesSet *speciesSet() const { return mSpeciesSet; } ///< get SpeciesSet this RU links to. |
54 | SpeciesSet *speciesSet() const { return mSpeciesSet; } ///< get SpeciesSet this RU links to. |
55 | const WaterCycle *waterCycle() const { return mWater; } ///< water model of the unit |
55 | const WaterCycle *waterCycle() const { return mWater; } ///< water model of the unit |
56 | Snag *snag() const { return mSnag; } ///< access the snag object |
56 | Snag *snag() const { return mSnag; } ///< access the snag object |
57 | Soil *soil() const { return mSoil; } ///< access the soil model |
57 | Soil *soil() const { return mSoil; } ///< access the soil model |
58 | 58 | ||
59 | ResourceUnitSpecies &resourceUnitSpecies(const Species *species); ///< get RU-Species-container of @p species from the RU |
59 | ResourceUnitSpecies &resourceUnitSpecies(const Species *species); ///< get RU-Species-container of @p species from the RU |
60 | const QList<ResourceUnitSpecies*> &ruSpecies() const { return mRUSpecies; } |
60 | const QList<ResourceUnitSpecies*> &ruSpecies() const { return mRUSpecies; } |
61 | QVector<Tree> &trees() { return mTrees; } ///< reference to the tree list. |
61 | QVector<Tree> &trees() { return mTrees; } ///< reference to the tree list. |
62 | const QVector<Tree> &constTrees() const { return mTrees; } ///< reference to the (const) tree list. |
62 | const QVector<Tree> &constTrees() const { return mTrees; } ///< reference to the (const) tree list. |
63 | Tree *tree(const int index) { return &(mTrees[index]);} ///< get pointer to a tree |
63 | Tree *tree(const int index) { return &(mTrees[index]);} ///< get pointer to a tree |
64 | const ResourceUnitVariables &resouceUnitVariables() const { return mUnitVariables; } ///< access to variables that are specific to resourceUnit (e.g. nitrogenAvailable) |
64 | const ResourceUnitVariables &resouceUnitVariables() const { return mUnitVariables; } ///< access to variables that are specific to resourceUnit (e.g. nitrogenAvailable) |
65 | const StandStatistics &statistics() const {return mStatistics; } |
65 | const StandStatistics &statistics() const {return mStatistics; } |
66 | 66 | ||
67 | // properties
|
67 | // properties
|
68 | int index() const { return mIndex; } |
68 | int index() const { return mIndex; } |
69 | int id() const { return mID; } |
69 | int id() const { return mID; } |
70 | const QRectF &boundingBox() const { return mBoundingBox; } |
70 | const QRectF &boundingBox() const { return mBoundingBox; } |
71 | const QPoint &cornerPointOffset() const { return mCornerCoord; } |
71 | const QPoint &cornerPointOffset() const { return mCornerCoord; } |
72 | double area() const { return mPixelCount*100; } ///< get the |
72 | double area() const { return mPixelCount*100; } ///< get the resource unit area in m2 |
73 | double stockedArea() const { return mStockedArea; } ///< get the stocked area in m2 |
73 | double stockedArea() const { return mStockedArea; } ///< get the stocked area in m2 |
74 | double stockableArea() const { return mStockableArea; } ///< total stockable area in m2 |
74 | double stockableArea() const { return mStockableArea; } ///< total stockable area in m2 |
75 | double productiveArea() const { return mEffectiveArea; } ///< TotalArea - Unstocked Area - loss due to BeerLambert (m2) |
75 | double productiveArea() const { return mEffectiveArea; } ///< TotalArea - Unstocked Area - loss due to BeerLambert (m2) |
76 | double leafAreaIndex() const { return stockableArea()?mAggregatedLA / stockableArea():0.; } ///< Total Leaf Area Index |
76 | double leafAreaIndex() const { return stockableArea()?mAggregatedLA / stockableArea():0.; } ///< Total Leaf Area Index |
77 | double leafArea() const { return mAggregatedLA; } ///< total leaf area of resource unit (m2) |
77 | double leafArea() const { return mAggregatedLA; } ///< total leaf area of resource unit (m2) |
78 | double interceptedArea(const double LA, const double LightResponse) { return mEffectiveArea_perWLA * LA * LightResponse; } |
78 | double interceptedArea(const double LA, const double LightResponse) { return mEffectiveArea_perWLA * LA * LightResponse; } |
79 | const double &LRImodifier() const { return mLRI_modification; } |
79 | const double &LRImodifier() const { return mLRI_modification; } |
80 | double averageAging() const { return mAverageAging; } ///< leaf area weighted average aging |
80 | double averageAging() const { return mAverageAging; } ///< leaf area weighted average aging |
81 | 81 | ||
82 | // actions
|
82 | // actions
|
83 | Tree &newTree(); ///< returns a modifiable reference to a free space inside the tree-vector. should be used for tree-init. |
83 | Tree &newTree(); ///< returns a modifiable reference to a free space inside the tree-vector. should be used for tree-init. |
84 | int newTreeIndex(); ///< returns the index of a newly inserted tree |
84 | int newTreeIndex(); ///< returns the index of a newly inserted tree |
85 | void cleanTreeList(); ///< remove dead trees from the tree storage. |
85 | void cleanTreeList(); ///< remove dead trees from the tree storage. |
86 | void treeDied() { mHasDeadTrees = true; } ///< sets the flag that indicates that the resource unit contains dead trees |
86 | void treeDied() { mHasDeadTrees = true; } ///< sets the flag that indicates that the resource unit contains dead trees |
87 | bool hasDiedTrees() const { return mHasDeadTrees; } ///< if true, the resource unit has dead trees and needs maybe some cleanup |
87 | bool hasDiedTrees() const { return mHasDeadTrees; } ///< if true, the resource unit has dead trees and needs maybe some cleanup |
88 | /// addWLA() is called by each tree to aggregate the total weighted leaf area on a unit
|
88 | /// addWLA() is called by each tree to aggregate the total weighted leaf area on a unit
|
89 | void addWLA(const float LA, const float LRI) { mAggregatedWLA += LA*LRI; mAggregatedLA += LA; } |
89 | void addWLA(const float LA, const float LRI) { mAggregatedWLA += LA*LRI; mAggregatedLA += LA; } |
90 | void addLR(const float LA, const float LightResponse) { mAggregatedLR += LA*LightResponse; } |
90 | void addLR(const float LA, const float LightResponse) { mAggregatedLR += LA*LightResponse; } |
91 | /// function that distributes effective interception area according to the weight of Light response and LeafArea of the indivudal (@sa production())
|
91 | /// function that distributes effective interception area according to the weight of Light response and LeafArea of the indivudal (@sa production())
|
92 | void calculateInterceptedArea(); |
92 | void calculateInterceptedArea(); |
93 | void addTreeAging(const double leaf_area, const double aging_factor) { mAverageAging += leaf_area*aging_factor; } ///< aggregate the tree aging values (weighted by leaf area) |
93 | void addTreeAging(const double leaf_area, const double aging_factor) { mAverageAging += leaf_area*aging_factor; } ///< aggregate the tree aging values (weighted by leaf area) |
94 | void addTreeAgingForAllTrees(); ///< calculate average tree aging for all trees of a RU. Used directly after stand initialization. |
94 | void addTreeAgingForAllTrees(); ///< calculate average tree aging for all trees of a RU. Used directly after stand initialization. |
95 | // stocked area calculation
|
95 | // stocked area calculation
|
96 | void countStockedPixel(bool pixelIsStocked) { mPixelCount++; if (pixelIsStocked) mStockedPixelCount++; } |
96 | void countStockedPixel(bool pixelIsStocked) { mPixelCount++; if (pixelIsStocked) mStockedPixelCount++; } |
97 | void createStandStatistics(); ///< helping function to create an initial state for stand statistics |
97 | void createStandStatistics(); ///< helping function to create an initial state for stand statistics |
98 | void recreateStandStatistics(); ///< re-build stand statistics after some change happened to the resource unit |
98 | void recreateStandStatistics(); ///< re-build stand statistics after some change happened to the resource unit |
99 | void setStockableArea(const double area) { mStockableArea = area; } ///< set stockable area (m2) |
99 | void setStockableArea(const double area) { mStockableArea = area; } ///< set stockable area (m2) |
100 | // sapling growth: the height map is per resource unit and holds the maximum height of saplings for each LIF-pixel and all species
|
100 | // sapling growth: the height map is per resource unit and holds the maximum height of saplings for each LIF-pixel and all species
|
101 | // the map itself is a local variable and only filled temporarily.
|
101 | // the map itself is a local variable and only filled temporarily.
|
102 | void setSaplingHeightMap(float *map_pointer); ///< set (temporal) storage for sapling-height-map |
102 | void setSaplingHeightMap(float *map_pointer); ///< set (temporal) storage for sapling-height-map |
103 | /// returns maximum sapling height at point given by point-index (LIF-index).
|
103 | /// returns maximum sapling height at point given by point-index (LIF-index).
|
104 | /// you must call setSaplingHeightMap() with a valid map before.
|
104 | /// you must call setSaplingHeightMap() with a valid map before.
|
105 | float saplingHeightAt(const QPoint &position) const { |
105 | float saplingHeightAt(const QPoint &position) const { |
106 | Q_ASSERT(mSaplingHeightMap); |
106 | Q_ASSERT(mSaplingHeightMap); |
107 | int pixel_index = cPxPerRU*(position.x()-mCornerCoord.x())+(position.y()-mCornerCoord.y()); |
107 | int pixel_index = cPxPerRU*(position.x()-mCornerCoord.x())+(position.y()-mCornerCoord.y()); |
108 | float h = mSaplingHeightMap[pixel_index]; |
108 | float h = mSaplingHeightMap[pixel_index]; |
109 | return h; |
109 | return h; |
110 | }
|
110 | }
|
111 | /// access to the internal sapling height map pointer
|
111 | /// access to the internal sapling height map pointer
|
112 | const float *saplingHeightMapPointer() const {return mSaplingHeightMap; } |
112 | const float *saplingHeightMapPointer() const {return mSaplingHeightMap; } |
113 | /// return maximum sapling height at point 'position' (LIF-index). This call is slower but works witout a prior call
|
113 | /// return maximum sapling height at point 'position' (LIF-index). This call is slower but works witout a prior call
|
114 | /// to setSaplingHeightMap().
|
114 | /// to setSaplingHeightMap().
|
115 | float saplingHeightForInit(const QPoint &position) const; |
115 | float saplingHeightForInit(const QPoint &position) const; |
116 | /// set the height of the sapling map to the maximum of current value and 'height'.
|
116 | /// set the height of the sapling map to the maximum of current value and 'height'.
|
117 | void setMaxSaplingHeightAt(const QPoint &position, const float height); |
117 | void setMaxSaplingHeightAt(const QPoint &position, const float height); |
118 | /// clear all saplings of all species on a given position (after recruitment)
|
118 | /// clear all saplings of all species on a given position (after recruitment)
|
119 | void clearSaplings(const QPoint &position); |
119 | void clearSaplings(const QPoint &position); |
120 | /// kill all saplings within a given rect
|
120 | /// kill all saplings within a given rect
|
121 | void clearSaplings(const QRectF pixel_rect, const bool remove_from_soil); |
121 | void clearSaplings(const QRectF pixel_rect, const bool remove_from_soil); |
122 | // snag / snag dynamics
|
122 | // snag / snag dynamics
|
123 | // snag dynamics, soil carbon and nitrogen cycle
|
123 | // snag dynamics, soil carbon and nitrogen cycle
|
124 | void snagNewYear() { if (snag()) snag()->newYear(); } ///< clean transfer pools |
124 | void snagNewYear() { if (snag()) snag()->newYear(); } ///< clean transfer pools |
125 | void calculateCarbonCycle(); ///< calculate snag dynamics at the end of a year |
125 | void calculateCarbonCycle(); ///< calculate snag dynamics at the end of a year |
126 | // model flow
|
126 | // model flow
|
127 | void newYear(); ///< reset values for a new simulation year |
127 | void newYear(); ///< reset values for a new simulation year |
128 | // LIP/LIF-cylcle -> Model
|
128 | // LIP/LIF-cylcle -> Model
|
129 | void production(); ///< called after the LIP/LIF calc, before growth of individual trees. Production (3PG), Water-cycle |
129 | void production(); ///< called after the LIP/LIF calc, before growth of individual trees. Production (3PG), Water-cycle |
130 | void beforeGrow(); ///< called before growth of individuals |
130 | void beforeGrow(); ///< called before growth of individuals |
131 | // the growth of individuals -> Model
|
131 | // the growth of individuals -> Model
|
132 | void afterGrow(); ///< called after the growth of individuals |
132 | void afterGrow(); ///< called after the growth of individuals |
133 | void yearEnd(); ///< called at the end of a year (after regeneration??) |
133 | void yearEnd(); ///< called at the end of a year (after regeneration??) |
134 | 134 | ||
135 | private: |
135 | private: |
136 | int mIndex; ///< internal index |
136 | int mIndex; ///< internal index |
137 | int mID; ///< ID provided by external stand grid |
137 | int mID; ///< ID provided by external stand grid |
138 | bool mHasDeadTrees; ///< flag that indicates if currently dead trees are in the tree list |
138 | bool mHasDeadTrees; ///< flag that indicates if currently dead trees are in the tree list |
139 | Climate *mClimate; ///< pointer to the climate object of this RU |
139 | Climate *mClimate; ///< pointer to the climate object of this RU |
140 | SpeciesSet *mSpeciesSet; ///< pointer to the species set for this RU |
140 | SpeciesSet *mSpeciesSet; ///< pointer to the species set for this RU |
141 | WaterCycle *mWater; ///< link to the Soil water calculation engine |
141 | WaterCycle *mWater; ///< link to the Soil water calculation engine |
142 | Snag *mSnag; ///< ptr to snag storage / dynamics |
142 | Snag *mSnag; ///< ptr to snag storage / dynamics |
143 | Soil *mSoil; ///< ptr to CN dynamics soil submodel |
143 | Soil *mSoil; ///< ptr to CN dynamics soil submodel |
144 | QList<ResourceUnitSpecies*> mRUSpecies; ///< data for this ressource unit per species |
144 | QList<ResourceUnitSpecies*> mRUSpecies; ///< data for this ressource unit per species |
145 | QVector<Tree> mTrees; ///< storage container for tree individuals |
145 | QVector<Tree> mTrees; ///< storage container for tree individuals |
146 | QRectF mBoundingBox; ///< bounding box (metric) of the RU |
146 | QRectF mBoundingBox; ///< bounding box (metric) of the RU |
147 | QPoint mCornerCoord; ///< coordinates on the LIF grid of the upper left corner of the RU |
147 | QPoint mCornerCoord; ///< coordinates on the LIF grid of the upper left corner of the RU |
148 | double mAggregatedLA; ///< sum of leafArea |
148 | double mAggregatedLA; ///< sum of leafArea |
149 | double mAggregatedWLA; ///< sum of lightResponse * LeafArea for all trees |
149 | double mAggregatedWLA; ///< sum of lightResponse * LeafArea for all trees |
150 | double mAggregatedLR; ///< sum of lightresponse*LA of the current unit |
150 | double mAggregatedLR; ///< sum of lightresponse*LA of the current unit |
151 | double mEffectiveArea; ///< total "effective" area per resource unit, i.e. area of RU - non-stocked - beerLambert-loss |
151 | double mEffectiveArea; ///< total "effective" area per resource unit, i.e. area of RU - non-stocked - beerLambert-loss |
152 | double mEffectiveArea_perWLA; ///< |
152 | double mEffectiveArea_perWLA; ///< |
153 | double mLRI_modification; |
153 | double mLRI_modification; |
154 | double mAverageAging; ///< leaf-area weighted average aging f this species on this RU. |
154 | double mAverageAging; ///< leaf-area weighted average aging f this species on this RU. |
155 | float *mSaplingHeightMap; ///< pointer to array that holds max-height for each 2x2m pixel. Note: this information is not persistent |
155 | float *mSaplingHeightMap; ///< pointer to array that holds max-height for each 2x2m pixel. Note: this information is not persistent |
156 | 156 | ||
157 | int mPixelCount; ///< count of (Heightgrid) pixels thare are inside the RU |
157 | int mPixelCount; ///< count of (Heightgrid) pixels thare are inside the RU |
158 | int mStockedPixelCount; ///< count of pixels that are stocked with trees |
158 | int mStockedPixelCount; ///< count of pixels that are stocked with trees |
159 | double mStockedArea; ///< size of stocked area |
159 | double mStockedArea; ///< size of stocked area |
160 | double mStockableArea; ///< area of stockable area (defined by project setup) |
160 | double mStockableArea; ///< area of stockable area (defined by project setup) |
161 | StandStatistics mStatistics; ///< aggregate values on stand value |
161 | StandStatistics mStatistics; ///< aggregate values on stand value |
162 | ResourceUnitVariables mUnitVariables;
|
162 | ResourceUnitVariables mUnitVariables;
|
163 | 163 | ||
164 | friend class RUWrapper; |
164 | friend class RUWrapper; |
165 | }; |
165 | }; |
166 | 166 | ||
167 | 167 | ||
168 | #endif // RESOURCEUNIT_H
|
168 | #endif // RESOURCEUNIT_H
|
169 | 169 |