Rev 1033 | Rev 1157 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | |||
1033 | werner | 2 | /******************************************************************************************** |
3 | ** iLand - an individual based forest landscape and disturbance model |
||
4 | ** http://iland.boku.ac.at |
||
5 | ** Copyright (C) 2009- Werner Rammer, Rupert Seidl |
||
6 | ** |
||
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 |
||
9 | ** the Free Software Foundation, either version 3 of the License, or |
||
10 | ** (at your option) any later version. |
||
11 | ** |
||
12 | ** This program is distributed in the hope that it will be useful, |
||
13 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
15 | ** GNU General Public License for more details. |
||
16 | ** |
||
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/>. |
||
19 | ********************************************************************************************/ |
||
20 | |||
21 | |||
111 | Werner | 22 | #include "global.h" |
189 | iland | 23 | #include "resourceunitspecies.h" |
111 | Werner | 24 | |
25 | #include "species.h" |
||
189 | iland | 26 | #include "resourceunit.h" |
468 | werner | 27 | #include "model.h" |
496 | werner | 28 | #include "watercycle.h" |
808 | werner | 29 | #include "debugtimer.h" |
376 | werner | 30 | |
458 | werner | 31 | /** @class ResourceUnitSpecies |
697 | werner | 32 | @ingroup core |
458 | werner | 33 | The class contains data available at ResourceUnit x Species scale. |
34 | Data stored is either statistical (i.e. number of trees per species) or used |
||
468 | werner | 35 | within the model (e.g. fraction of utilizable Radiation). |
36 | Important submodules are: |
||
37 | * 3PG production (Production3PG) |
||
38 | * Establishment |
||
39 | * Growth and Recruitment of Saplings |
||
40 | * Snag dynamics |
||
458 | werner | 41 | */ |
468 | werner | 42 | ResourceUnitSpecies::~ResourceUnitSpecies() |
43 | { |
||
44 | } |
||
440 | werner | 45 | |
376 | werner | 46 | double ResourceUnitSpecies::leafArea() const |
47 | { |
||
48 | // Leaf area of the species: |
||
49 | // total leaf area on the RU * fraction of leafarea |
||
50 | return mLAIfactor * ru()->leafAreaIndex(); |
||
51 | } |
||
52 | |||
235 | werner | 53 | void ResourceUnitSpecies::setup(Species *species, ResourceUnit *ru) |
54 | { |
||
55 | mSpecies = species; |
||
56 | mRU = ru; |
||
57 | mResponse.setup(this); |
||
58 | m3PG.setResponse(&mResponse); |
||
440 | werner | 59 | mEstablishment.setup(ru->climate(), this); |
452 | werner | 60 | mSapling.setup(this); |
235 | werner | 61 | mStatistics.setResourceUnitSpecies(this); |
277 | werner | 62 | mStatisticsDead.setResourceUnitSpecies(this); |
278 | werner | 63 | mStatisticsMgmt.setResourceUnitSpecies(this); |
440 | werner | 64 | |
277 | werner | 65 | mRemovedGrowth = 0.; |
438 | werner | 66 | mLastYear = -1; |
468 | werner | 67 | |
235 | werner | 68 | } |
111 | Werner | 69 | |
70 | |||
440 | werner | 71 | void ResourceUnitSpecies::calculate(const bool fromEstablishment) |
226 | werner | 72 | { |
936 | werner | 73 | |
438 | werner | 74 | if (mLastYear == GlobalSettings::instance()->currentYear()) |
75 | return; |
||
76 | |||
936 | werner | 77 | // if *not* called from establishment, clear the species-level-stats |
518 | werner | 78 | if (!fromEstablishment) |
79 | statistics().clear(); |
||
513 | werner | 80 | |
936 | werner | 81 | if (mLAIfactor>0. || fromEstablishment==true) { |
496 | werner | 82 | // execute the water calculation... |
83 | if (fromEstablishment) |
||
84 | const_cast<WaterCycle*>(mRU->waterCycle())->run(); // run the water sub model (only if this has not be done already) |
||
626 | werner | 85 | DebugTimer rst("response+3pg"); |
496 | werner | 86 | mResponse.calculate();// calculate environmental responses per species (vpd, temperature, ...) |
87 | m3PG.calculate();// production of NPP |
||
513 | werner | 88 | mLastYear = GlobalSettings::instance()->currentYear(); // mark this year as processed |
369 | werner | 89 | } else { |
90 | // if no LAI is present, then just clear the respones. |
||
91 | mResponse.clear(); |
||
92 | m3PG.clear(); |
||
93 | } |
||
226 | werner | 94 | } |
277 | werner | 95 | |
96 | |||
97 | void ResourceUnitSpecies::updateGWL() |
||
98 | { |
||
99 | // removed growth is the running sum of all removed |
||
100 | // tree volume. the current "GWL" therefore is current volume (standing) + mRemovedGrowth. |
||
936 | werner | 101 | // important: statisticsDead() and statisticsMgmt() need to calculate() before -> volume() is already scaled to ha |
278 | werner | 102 | mRemovedGrowth+=statisticsDead().volume() + statisticsMgmt().volume(); |
277 | werner | 103 | } |
440 | werner | 104 | |
863 | werner | 105 | void ResourceUnitSpecies::calculateEstablishment() |
440 | werner | 106 | { |
1005 | werner | 107 | //DebugTimer t("to remove"); |
440 | werner | 108 | mEstablishment.calculate(); |
1005 | werner | 109 | //qDebug() << species()->id() << t.elapsed() << mEstablishment.avgSeedDensity() << mEstablishment.numberEstablished()<< "new"; |
442 | werner | 110 | //DBGMODE( |
111 | if (GlobalSettings::instance()->isDebugEnabled(GlobalSettings::dEstablishment)) { |
||
112 | DebugList &out = GlobalSettings::instance()->debugList(ru()->index(), GlobalSettings::dEstablishment); |
||
113 | // establishment details |
||
605 | werner | 114 | out << mSpecies->id() << ru()->index() << ru()->id(); |
442 | werner | 115 | out << mEstablishment.avgSeedDensity(); |
116 | out << mEstablishment.TACAminTemp() << mEstablishment.TACAchill() << mEstablishment.TACAfrostFree() << mEstablishment.TACgdd(); |
||
117 | out << mEstablishment.TACAfrostDaysAfterBudBirst() << mEstablishment.abioticEnvironment(); |
||
118 | out << m3PG.fEnvYear() << mEstablishment.avgLIFValue() << mEstablishment.numberEstablished(); |
||
466 | werner | 119 | out << mSapling.livingSaplings() << mSapling.averageHeight() << mSapling.averageAge() << mSapling.averageDeltaHPot() << mSapling.averageDeltaHRealized(); |
471 | werner | 120 | out << mSapling.newSaplings() << mSapling.diedSaplings() << mSapling.recruitedSaplings() << mSpecies->saplingGrowthParameters().referenceRatio; |
442 | werner | 121 | } |
122 | //); // DBGMODE() |
||
440 | werner | 123 | |
442 | werner | 124 | |
440 | werner | 125 | if ( logLevelDebug() ) |
126 | qDebug() << "establishment of RU" << mRU->index() << "species" << species()->id() |
||
127 | << "seeds density:" << mEstablishment.avgSeedDensity() |
||
128 | << "abiotic environment:" << mEstablishment.abioticEnvironment() |
||
129 | << "f_env,yr:" << m3PG.fEnvYear() |
||
130 | << "N(established):" << mEstablishment.numberEstablished(); |
||
131 | |||
132 | } |
||
450 | werner | 133 | |
134 | void ResourceUnitSpecies::calclulateSaplingGrowth() |
||
135 | { |
||
136 | mSapling.calculateGrowth(); |
||
137 | } |
||
453 | werner | 138 | |
139 | void ResourceUnitSpecies::visualGrid(Grid<float> &grid) const |
||
140 | { |
||
564 | werner | 141 | mSapling.fillMaxHeightGrid(grid); |
453 | werner | 142 | } |
462 | werner | 143 | |
475 | werner | 144 |