Subversion Repositories public iLand

Rev

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/standstatistics.cpp':
1
Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/standstatistics.cpp':
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
/** @class StandStatistics
21
/** @class StandStatistics
22
  @ingroup tools
22
  @ingroup tools
23
  Collects information on stand level for each tree species.
23
  Collects information on stand level for each tree species.
24
  Call clear() to clear the statistics, then call add() for each tree and finally calculate().
24
  Call clear() to clear the statistics, then call add() for each tree and finally calculate().
25
  To aggregate on a higher level, use add() for each StandStatistics object to include, and then
25
  To aggregate on a higher level, use add() for each StandStatistics object to include, and then
26
  calculate() on the higher level.
26
  calculate() on the higher level.
27
  Todo-List for new items:
27
  Todo-List for new items:
28
  - add a member variable and a getter
28
  - add a member variable and a getter
29
  - add to "add(Tree)" and "calculate()"
29
  - add to "add(Tree)" and "calculate()"
30
  - add to "add(StandStatistics)" as well!
30
  - add to "add(StandStatistics)" as well!
31
  */
31
  */
32
#include "standstatistics.h"
32
#include "standstatistics.h"
33
#include "tree.h"
33
#include "tree.h"
34
#include "resourceunit.h"
34
#include "resourceunit.h"
35
#include "resourceunitspecies.h"
35
#include "resourceunitspecies.h"
36
//#include "sapling.h"
36
//#include "sapling.h"
37
#include "saplings.h"
37
#include "saplings.h"
38
#include "species.h"
38
#include "species.h"
39
39
40
void StandStatistics::clear()
40
void StandStatistics::clear()
41
{
41
{
42
    // reset all values
42
    // reset all values
43
    mCount = 0;
43
    mCount = 0;
44
    mSumDbh=mSumHeight = mAverageDbh=mAverageHeight =0.;
44
    mSumDbh=mSumHeight = mAverageDbh=mAverageHeight =0.;
45
    mSumBasalArea = mSumVolume = mGWL = 0.;
45
    mSumBasalArea = mSumVolume = mGWL = 0.;
46
    mLeafAreaIndex = 0.;
46
    mLeafAreaIndex = 0.;
47
    mNPP = mNPPabove = 0.;
47
    mNPP = mNPPabove = 0.;
48
    mNPPsaplings = 0.;
48
    mNPPsaplings = 0.;
49
    mCohortCount = mSaplingCount = 0;
49
    mCohortCount = mSaplingCount = 0;
50
    mAverageSaplingAge = 0.;
50
    mAverageSaplingAge = 0.;
51
    mSumSaplingAge = 0.;
51
    mSumSaplingAge = 0.;
52
    mCStem=0., mCFoliage=0., mCBranch=0., mCCoarseRoot=0., mCFineRoot=0.;
52
    mCStem=0., mCFoliage=0., mCBranch=0., mCCoarseRoot=0., mCFineRoot=0.;
53
    mNStem=0., mNFoliage=0., mNBranch=0., mNCoarseRoot=0., mNFineRoot=0.;
53
    mNStem=0., mNFoliage=0., mNBranch=0., mNCoarseRoot=0., mNFineRoot=0.;
54
    mCRegeneration=0., mNRegeneration=0.;
54
    mCRegeneration=0., mNRegeneration=0.;
55
55
56
}
56
}
57
57
58
void StandStatistics::clearOnlyTrees()
58
void StandStatistics::clearOnlyTrees()
59
{
59
{
60
    // reset only those values that are directly accumulated from trees
60
    // reset only those values that are directly accumulated from trees
61
    mCount = 0;
61
    mCount = 0;
62
    mSumDbh=mSumHeight = mAverageDbh=mAverageHeight =0.;
62
    mSumDbh=mSumHeight = mAverageDbh=mAverageHeight =0.;
63
    mSumBasalArea = mSumVolume = mGWL = 0.;
63
    mSumBasalArea = mSumVolume = mGWL = 0.;
64
    mLeafAreaIndex = 0.;
64
    mLeafAreaIndex = 0.;
65
    /*mNPP = mNPPabove = 0.;
65
    /*mNPP = mNPPabove = 0.;
66
    mNPPsaplings = 0.;
66
    mNPPsaplings = 0.;
67
    mCohortCount = mSaplingCount = 0;
67
    mCohortCount = mSaplingCount = 0;
68
    mAverageSaplingAge = 0.;
68
    mAverageSaplingAge = 0.;
69
    mSumSaplingAge = 0.;*/
69
    mSumSaplingAge = 0.;*/
70
    mCStem=0., mCFoliage=0., mCBranch=0., mCCoarseRoot=0., mCFineRoot=0.;
70
    mCStem=0., mCFoliage=0., mCBranch=0., mCCoarseRoot=0., mCFineRoot=0.;
71
    mNStem=0., mNFoliage=0., mNBranch=0., mNCoarseRoot=0., mNFineRoot=0.;
71
    mNStem=0., mNFoliage=0., mNBranch=0., mNCoarseRoot=0., mNFineRoot=0.;
72
    /*mCRegeneration=0., mNRegeneration=0.;*/
72
    /*mCRegeneration=0., mNRegeneration=0.;*/
73
73
74
}
74
}
75
75
76
void StandStatistics::addBiomass(const double biomass, const double CNRatio, double *C, double *N)
76
void StandStatistics::addBiomass(const double biomass, const double CNRatio, double *C, double *N)
77
{
77
{
78
    *C+=biomass*biomassCFraction;
78
    *C+=biomass*biomassCFraction;
79
    *N+=biomass*biomassCFraction/CNRatio;
79
    *N+=biomass*biomassCFraction/CNRatio;
80
}
80
}
81
81
82
void StandStatistics::add(const Tree *tree, const TreeGrowthData *tgd)
82
void StandStatistics::add(const Tree *tree, const TreeGrowthData *tgd)
83
{
83
{
84
    mCount++;
84
    mCount++;
85
    mSumDbh+=tree->dbh();
85
    mSumDbh+=tree->dbh();
86
    mSumHeight+=tree->height();
86
    mSumHeight+=tree->height();
87
    mSumBasalArea+=tree->basalArea();
87
    mSumBasalArea+=tree->basalArea();
88
    mSumVolume += tree->volume();
88
    mSumVolume += tree->volume();
89
    mLeafAreaIndex += tree->leafArea(); // warning: sum of leafarea!
89
    mLeafAreaIndex += tree->leafArea(); // warning: sum of leafarea!
90
    if (tgd) {
90
    if (tgd) {
91
        mNPP += tgd->NPP;
91
        mNPP += tgd->NPP;
92
        mNPPabove += tgd->NPP_above;
92
        mNPPabove += tgd->NPP_above;
93
    }
93
    }
94
    // carbon and nitrogen pools
94
    // carbon and nitrogen pools
95
    addBiomass(tree->biomassStem(), tree->species()->cnWood(), &mCStem, &mNStem);
95
    addBiomass(tree->biomassStem(), tree->species()->cnWood(), &mCStem, &mNStem);
96
    addBiomass(tree->biomassBranch(), tree->species()->cnWood(), &mCBranch, &mNBranch);
96
    addBiomass(tree->biomassBranch(), tree->species()->cnWood(), &mCBranch, &mNBranch);
97
    addBiomass(tree->biomassFoliage(), tree->species()->cnFoliage(), &mCFoliage, &mNFoliage);
97
    addBiomass(tree->biomassFoliage(), tree->species()->cnFoliage(), &mCFoliage, &mNFoliage);
98
    addBiomass(tree->biomassFineRoot(), tree->species()->cnFineroot(), &mCFineRoot, &mNFineRoot);
98
    addBiomass(tree->biomassFineRoot(), tree->species()->cnFineroot(), &mCFineRoot, &mNFineRoot);
99
    addBiomass(tree->biomassCoarseRoot(), tree->species()->cnWood(), &mCCoarseRoot, &mNCoarseRoot);
99
    addBiomass(tree->biomassCoarseRoot(), tree->species()->cnWood(), &mCCoarseRoot, &mNCoarseRoot);
100
}
100
}
101
101
102
// note: mRUS = 0 for aggregated statistics
102
// note: mRUS = 0 for aggregated statistics
103
void StandStatistics::calculate()
103
void StandStatistics::calculate()
104
{
104
{
105
    if (mCount>0.) {
105
    if (mCount>0.) {
106
        mAverageDbh = mSumDbh / mCount;
106
        mAverageDbh = mSumDbh / mCount;
107
        mAverageHeight = mSumHeight / mCount;
107
        mAverageHeight = mSumHeight / mCount;
108
        if (mRUS && mRUS->ru()->stockableArea()>0.)
108
        if (mRUS && mRUS->ru()->stockableArea()>0.)
109
            mLeafAreaIndex /= mRUS->ru()->stockableArea(); // convert from leafarea to LAI
109
            mLeafAreaIndex /= mRUS->ru()->stockableArea(); // convert from leafarea to LAI
110
    }
110
    }
111
    if (mCohortCount)
111
    if (mCohortCount)
112
        mAverageSaplingAge = mSumSaplingAge / double(mCohortCount);
112
        mAverageSaplingAge = mSumSaplingAge / double(mCohortCount);
113
113
114
    // scale values to per hectare if resource unit <> 1ha
114
    // scale values to per hectare if resource unit <> 1ha
115
    // note: do this only on species-level (avoid double scaling)
115
    // note: do this only on species-level (avoid double scaling)
116
    if (mRUS) {
116
    if (mRUS) {
117
        double area_factor =  cRUArea / mRUS->ru()->stockableArea();
117
        double area_factor =  cRUArea / mRUS->ru()->stockableArea();
118
        if (area_factor!=1.) {
118
        if (area_factor!=1.) {
119
            mCount = mCount * area_factor;
119
            mCount = mCount * area_factor;
120
            mSumBasalArea *= area_factor;
120
            mSumBasalArea *= area_factor;
121
            mSumVolume *= area_factor;
121
            mSumVolume *= area_factor;
122
            mSumDbh *= area_factor;
122
            mSumDbh *= area_factor;
123
            mNPP *= area_factor;
123
            mNPP *= area_factor;
124
            mNPPabove *= area_factor;
124
            mNPPabove *= area_factor;
125
            mNPPsaplings *= area_factor;
125
            mNPPsaplings *= area_factor;
126
            //mGWL *= area_factor;
126
            //mGWL *= area_factor;
127
            mCohortCount *= area_factor;
127
            mCohortCount *= area_factor;
128
            mSaplingCount *= area_factor;
128
            mSaplingCount *= area_factor;
129
            //double mCStem, mCFoliage, mCBranch, mCCoarseRoot, mCFineRoot;
129
            //double mCStem, mCFoliage, mCBranch, mCCoarseRoot, mCFineRoot;
130
            //double mNStem, mNFoliage, mNBranch, mNCoarseRoot, mNFineRoot;
130
            //double mNStem, mNFoliage, mNBranch, mNCoarseRoot, mNFineRoot;
131
            //double mCRegeneration, mNRegeneration;
131
            //double mCRegeneration, mNRegeneration;
132
            mCStem *= area_factor; mNStem *= area_factor;
132
            mCStem *= area_factor; mNStem *= area_factor;
133
            mCFoliage *= area_factor; mNFoliage *= area_factor;
133
            mCFoliage *= area_factor; mNFoliage *= area_factor;
134
            mCBranch *= area_factor; mNBranch *= area_factor;
134
            mCBranch *= area_factor; mNBranch *= area_factor;
135
            mCCoarseRoot *= area_factor; mNCoarseRoot *= area_factor;
135
            mCCoarseRoot *= area_factor; mNCoarseRoot *= area_factor;
136
            mCFineRoot *= area_factor; mNFineRoot *= area_factor;
136
            mCFineRoot *= area_factor; mNFineRoot *= area_factor;
137
            mCRegeneration *= area_factor; mNRegeneration *= area_factor;
137
            mCRegeneration *= area_factor; mNRegeneration *= area_factor;
138
138
139
        }
139
        }
140
        mGWL = mSumVolume + mRUS->removedVolume(); // removedVolume: per ha, SumVolume now too
140
        mGWL = mSumVolume + mRUS->removedVolume(); // removedVolume: per ha, SumVolume now too
141
    }
141
    }
142
}
142
}
143
143
144
void StandStatistics::add(const StandStatistics &stat)
144
void StandStatistics::add(const StandStatistics &stat)
145
{
145
{
146
    mCount+=stat.mCount;
146
    mCount+=stat.mCount;
147
    mSumBasalArea+=stat.mSumBasalArea;
147
    mSumBasalArea+=stat.mSumBasalArea;
148
    mSumDbh+=stat.mSumDbh;
148
    mSumDbh+=stat.mSumDbh;
149
    mSumHeight+=stat.mSumHeight;
149
    mSumHeight+=stat.mSumHeight;
150
    mSumVolume+=stat.mSumVolume;
150
    mSumVolume+=stat.mSumVolume;
151
    mLeafAreaIndex += stat.mLeafAreaIndex;
151
    mLeafAreaIndex += stat.mLeafAreaIndex;
152
    mNPP += stat.mNPP;
152
    mNPP += stat.mNPP;
153
    mNPPabove += stat.mNPPabove;
153
    mNPPabove += stat.mNPPabove;
154
    mNPPsaplings += stat.mNPPsaplings;
154
    mNPPsaplings += stat.mNPPsaplings;
155
    mGWL+=stat.mGWL;
155
    mGWL+=stat.mGWL;
156
    // regeneration
156
    // regeneration
157
    mCohortCount += stat.mCohortCount;
157
    mCohortCount += stat.mCohortCount;
158
    mSaplingCount += stat.mSaplingCount;
158
    mSaplingCount += stat.mSaplingCount;
159
    mSumSaplingAge += stat.mSumSaplingAge;
159
    mSumSaplingAge += stat.mSumSaplingAge;
160
    // carbon/nitrogen pools
160
    // carbon/nitrogen pools
161
    mCStem += stat.mCStem; mNStem += stat.mNStem;
161
    mCStem += stat.mCStem; mNStem += stat.mNStem;
162
    mCBranch += stat.mCBranch; mNBranch += stat.mNBranch;
162
    mCBranch += stat.mCBranch; mNBranch += stat.mNBranch;
163
    mCFoliage += stat.mCFoliage; mNFoliage += stat.mNFoliage;
163
    mCFoliage += stat.mCFoliage; mNFoliage += stat.mNFoliage;
164
    mCFineRoot += stat.mCFineRoot; mNFineRoot += stat.mNFineRoot;
164
    mCFineRoot += stat.mCFineRoot; mNFineRoot += stat.mNFineRoot;
165
    mCCoarseRoot += stat.mCCoarseRoot; mNCoarseRoot += stat.mNCoarseRoot;
165
    mCCoarseRoot += stat.mCCoarseRoot; mNCoarseRoot += stat.mNCoarseRoot;
166
    mCRegeneration += stat.mCRegeneration; mNRegeneration += stat.mNRegeneration;
166
    mCRegeneration += stat.mCRegeneration; mNRegeneration += stat.mNRegeneration;
167
167
168
}
168
}
169
169
170
void StandStatistics::addAreaWeighted(const StandStatistics &stat, const double weight)
170
void StandStatistics::addAreaWeighted(const StandStatistics &stat, const double weight)
171
{
171
{
172
    // aggregates that are not scaled to hectares
172
    // aggregates that are not scaled to hectares
173
    mCount+=stat.mCount * weight;
173
    mCount+=stat.mCount * weight;
174
    mSumBasalArea+=stat.mSumBasalArea * weight;
174
    mSumBasalArea+=stat.mSumBasalArea * weight;
175
    mSumDbh+=stat.mSumDbh * weight;
175
    mSumDbh+=stat.mSumDbh * weight;
176
    mSumHeight+=stat.mSumHeight * weight;
176
    mSumHeight+=stat.mSumHeight * weight;
177
    mSumVolume+=stat.mSumVolume * weight;
177
    mSumVolume+=stat.mSumVolume * weight;
178
    // averages that are scaled to per hectare need to be scaled
178
    // averages that are scaled to per hectare need to be scaled
179
    mAverageDbh+=stat.mAverageDbh * weight;
179
    mAverageDbh+=stat.mAverageDbh * weight;
180
    mAverageHeight+=stat.mAverageHeight * weight;
180
    mAverageHeight+=stat.mAverageHeight * weight;
181
    mAverageSaplingAge+=stat.mAverageSaplingAge * weight;
181
    mAverageSaplingAge+=stat.mAverageSaplingAge * weight;
182
    mLeafAreaIndex += stat.mLeafAreaIndex * weight;
182
    mLeafAreaIndex += stat.mLeafAreaIndex * weight;
183
183
184
    mNPP += stat.mNPP * weight;
184
    mNPP += stat.mNPP * weight;
185
    mNPPabove += stat.mNPPabove * weight;
185
    mNPPabove += stat.mNPPabove * weight;
186
    mNPPsaplings += stat.mNPPsaplings * weight;
186
    mNPPsaplings += stat.mNPPsaplings * weight;
187
    mGWL+=stat.mGWL * weight;
187
    mGWL+=stat.mGWL * weight;
188
    // regeneration
188
    // regeneration
189
    mCohortCount += stat.mCohortCount * weight;
189
    mCohortCount += stat.mCohortCount * weight;
190
    mSaplingCount += stat.mSaplingCount * weight;
190
    mSaplingCount += stat.mSaplingCount * weight;
191
    mSumSaplingAge += stat.mSumSaplingAge * weight;
191
    mSumSaplingAge += stat.mSumSaplingAge * weight;
192
    // carbon/nitrogen pools
192
    // carbon/nitrogen pools
193
    mCStem += stat.mCStem * weight; mNStem += stat.mNStem * weight;
193
    mCStem += stat.mCStem * weight; mNStem += stat.mNStem * weight;
194
    mCBranch += stat.mCBranch * weight; mNBranch += stat.mNBranch * weight;
194
    mCBranch += stat.mCBranch * weight; mNBranch += stat.mNBranch * weight;
195
    mCFoliage += stat.mCFoliage * weight; mNFoliage += stat.mNFoliage * weight;
195
    mCFoliage += stat.mCFoliage * weight; mNFoliage += stat.mNFoliage * weight;
196
    mCFineRoot += stat.mCFineRoot * weight; mNFineRoot += stat.mNFineRoot * weight;
196
    mCFineRoot += stat.mCFineRoot * weight; mNFineRoot += stat.mNFineRoot * weight;
197
    mCCoarseRoot += stat.mCCoarseRoot * weight; mNCoarseRoot += stat.mNCoarseRoot * weight;
197
    mCCoarseRoot += stat.mCCoarseRoot * weight; mNCoarseRoot += stat.mNCoarseRoot * weight;
198
    mCRegeneration += stat.mCRegeneration * weight; mNRegeneration += stat.mNRegeneration * weight;
198
    mCRegeneration += stat.mCRegeneration * weight; mNRegeneration += stat.mNRegeneration * weight;
199
199
200
}
200
}
201
201
202
202
203
203
204
void StandStatistics::add(const SaplingStat *sapling)
204
void StandStatistics::add(const SaplingStat *sapling)
205
{
205
{
206
    mCohortCount += sapling->livingCohorts();
206
    mCohortCount += sapling->livingCohorts();
207
    mSaplingCount += sapling->livingSaplings(); // saplings with height >1.3m
207
    mSaplingCount += sapling->livingSaplings(); // saplings with height >1.3m
208
208
209
    mSumSaplingAge += sapling->averageAge() * sapling->livingCohorts();
209
    mSumSaplingAge += sapling->averageAge() * sapling->livingCohorts();
210
210
211
    mCRegeneration += sapling->carbonLiving().C;
211
    mCRegeneration += sapling->carbonLiving().C;
212
    mNRegeneration += sapling->carbonLiving().N;
212
    mNRegeneration += sapling->carbonLiving().N;
213
213
214
    mNPPsaplings += sapling->carbonGain().C / biomassCFraction;
214
    mNPPsaplings += sapling->carbonGain().C / biomassCFraction;
215
215
216
}
216
}
217
217
218
void SystemStatistics::writeOutput()
218
void SystemStatistics::writeOutput()
219
{
219
{
220
    if (GlobalSettings::instance()->isDebugEnabled(GlobalSettings::dPerformance)) {
220
    if (GlobalSettings::instance()->isDebugEnabled(GlobalSettings::dPerformance)) {
221
        DebugList &out = GlobalSettings::instance()->debugList(0, GlobalSettings::dPerformance);
221
        DebugList &out = GlobalSettings::instance()->debugList(0, GlobalSettings::dPerformance);
222
        out << treeCount << saplingCount << newSaplings << tManagement
222
        out << treeCount << saplingCount << newSaplings << tManagement
223
            << tApplyPattern << tReadPattern << tTreeGrowth
223
            << tApplyPattern << tReadPattern << tTreeGrowth
224
            << tSeedDistribution  << tEstablishment << tSapling
224
            << tSeedDistribution  << tEstablishment << tSapling
225
            << tCarbonCycle << tWriteOutput << tTotalYear;
225
            << tCarbonCycle << tWriteOutput << tTotalYear;
226
    }
226
    }
227
}
227
}
228
228
229
229
230
 
230