Rev 1104 | Rev 1217 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | |||
671 | 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 | |||
587 | werner | 21 | #include "carbonout.h" |
22 | #include "model.h" |
||
23 | #include "resourceunit.h" |
||
24 | #include "snag.h" |
||
25 | #include "soil.h" |
||
26 | |||
27 | CarbonOut::CarbonOut() |
||
28 | { |
||
29 | setName("Carbon and nitrogen pools above and belowground per RU/yr", "carbon"); |
||
1157 | werner | 30 | setDescription("Carbon and nitrogen pools (C and N) per resource unit / year and/or by landsacpe/year. "\ |
31 | "On resource unit level, the outputs contain aggregated above ground pools (kg/ha) " \ |
||
32 | "and below ground pools (kg/ha). \n " \ |
||
33 | "For landscape level outputs, all variables are scaled to kg/ha stockable area. "\ |
||
34 | "The area column contains the stockable area (per resource unit / landscape) and can be used to scale to values to the actual value. \n " \ |
||
35 | "You can use the 'condition' to control if the output should be created for the current year(see also dynamic stand output).\n" \ |
||
36 | "The 'conditionRU' can be used to suppress resource-unit-level details; eg. specifying 'in(year,100,200,300)' limits output on reosurce unit level to the years 100,200,300 " \ |
||
37 | "(leaving 'conditionRU' blank enables details per default)."); |
||
587 | werner | 38 | columns() << OutputColumn::year() << OutputColumn::ru() << OutputColumn::id() |
1157 | werner | 39 | << OutputColumn("area_ha", "total stockable area of the resource unit (ha)", OutDouble) |
40 | << OutputColumn("stem_c", "Stem carbon kg/ha", OutDouble) |
||
41 | << OutputColumn("stem_n", "Stem nitrogen kg/ha", OutDouble) |
||
42 | << OutputColumn("branch_c", "branches carbon kg/ha", OutDouble) |
||
43 | << OutputColumn("branch_n", "branches nitrogen kg/ha", OutDouble) |
||
44 | << OutputColumn("foliage_c", "Foliage carbon kg/ha", OutDouble) |
||
45 | << OutputColumn("foliage_n", "Foliage nitrogen kg/ha", OutDouble) |
||
46 | << OutputColumn("coarseRoot_c", "coarse root carbon kg/ha", OutDouble) |
||
47 | << OutputColumn("coarseRoot_n", "coarse root nitrogen kg/ha", OutDouble) |
||
48 | << OutputColumn("fineRoot_c", "fine root carbon kg/ha", OutDouble) |
||
49 | << OutputColumn("fineRoot_n", "fine root nitrogen kg/ha", OutDouble) |
||
50 | << OutputColumn("regeneration_c", "total carbon in regeneration layer (h<4m) kg/ha", OutDouble) |
||
51 | << OutputColumn("regeneration_n", "total nitrogen in regeneration layer (h<4m) kg/ha", OutDouble) |
||
52 | << OutputColumn("snags_c", "standing dead wood carbon kg/ha", OutDouble) |
||
53 | << OutputColumn("snags_n", "standing dead wood nitrogen kg/ha", OutDouble) |
||
54 | << OutputColumn("snagsOther_c", "branches and coarse roots of standing dead trees, carbon kg/ha", OutDouble) |
||
55 | << OutputColumn("snagsOther_n", "branches and coarse roots of standing dead trees, nitrogen kg/ha", OutDouble) |
||
592 | werner | 56 | << OutputColumn("downedWood_c", "downed woody debris (yR), carbon kg/ha", OutDouble) |
57 | << OutputColumn("downedWood_n", "downed woody debris (yR), nitrogen kg/ga", OutDouble) |
||
58 | << OutputColumn("litter_c", "soil litter (yl), carbon kg/ha", OutDouble) |
||
59 | << OutputColumn("litter_n", "soil litter (yl), nitrogen kg/ha", OutDouble) |
||
60 | << OutputColumn("soil_c", "soil organic matter (som), carbon kg/ha", OutDouble) |
||
61 | << OutputColumn("soil_n", "soil organic matter (som), nitrogen kg/ha", OutDouble); |
||
587 | werner | 62 | |
63 | |||
64 | } |
||
65 | |||
66 | void CarbonOut::setup() |
||
67 | { |
||
837 | werner | 68 | // use a condition for to control execuation for the current year |
69 | QString condition = settings().value(".condition", ""); |
||
70 | mCondition.setExpression(condition); |
||
1157 | werner | 71 | |
72 | condition = settings().value(".conditionRU", ""); |
||
73 | mConditionDetails.setExpression(condition); |
||
74 | |||
587 | werner | 75 | } |
76 | |||
77 | |||
78 | void CarbonOut::exec() |
||
79 | { |
||
80 | Model *m = GlobalSettings::instance()->model(); |
||
837 | werner | 81 | |
1157 | werner | 82 | // global condition |
83 | if (!mCondition.isEmpty() && mCondition.calculate(GlobalSettings::instance()->currentYear())==0.) |
||
84 | return; |
||
85 | |||
86 | bool ru_level = true; |
||
87 | // switch off details if this is indicated in the conditionRU option |
||
88 | if (!mConditionDetails.isEmpty() && mConditionDetails.calculate(GlobalSettings::instance()->currentYear())==0.) |
||
89 | ru_level = false; |
||
90 | |||
91 | |||
92 | QVector<double> v(23, 0.); // 8 data values |
||
93 | QVector<double>::iterator vit; |
||
94 | |||
587 | werner | 95 | foreach(ResourceUnit *ru, m->ruList()) { |
734 | werner | 96 | if (ru->id()==-1 || !ru->snag()) |
587 | werner | 97 | continue; // do not include if out of project area |
1157 | werner | 98 | |
587 | werner | 99 | const StandStatistics &s = ru->statistics(); |
1157 | werner | 100 | int ru_count = 0; |
101 | double area_factor = ru->stockableArea() / cRUArea; // conversion factor from real area to per ha values |
||
102 | if (ru_level) { |
||
103 | *this << currentYear() << ru->index() << ru->id() << area_factor; // keys |
||
104 | // biomass from trees (scaled to 1ha already) |
||
587 | werner | 105 | |
1157 | werner | 106 | *this << s.cStem() << s.nStem() // stem |
107 | << s.cBranch() << s.nBranch() // branch |
||
108 | << s.cFoliage() << s.nFoliage() // foliage |
||
109 | << s.cCoarseRoot() << s.nCoarseRoot() // coarse roots |
||
110 | << s.cFineRoot() << s.nFineRoot(); // fine roots |
||
587 | werner | 111 | |
1157 | werner | 112 | // biomass from regeneration |
113 | *this << s.cRegeneration() << s.nRegeneration(); |
||
587 | werner | 114 | |
1157 | werner | 115 | // biomass from standing dead wood |
116 | *this << ru->snag()->totalSWD().C / area_factor << ru->snag()->totalSWD().N / area_factor // snags |
||
117 | << ru->snag()->totalOtherWood().C/area_factor << ru->snag()->totalOtherWood().N / area_factor; // snags, other (branch + coarse root) |
||
587 | werner | 118 | |
1157 | werner | 119 | // biomass from soil (convert from t/ha -> kg/ha) |
120 | *this << ru->soil()->youngRefractory().C*1000. << ru->soil()->youngRefractory().N*1000. // wood |
||
121 | << ru->soil()->youngLabile().C*1000. << ru->soil()->youngLabile().N*1000. // litter |
||
122 | << ru->soil()->oldOrganicMatter().C*1000. << ru->soil()->oldOrganicMatter().N*1000.; // soil |
||
123 | |||
124 | writeRow(); |
||
125 | } |
||
126 | // landscape level statistics |
||
127 | |||
128 | ++ru_count; |
||
129 | vit = v.begin(); |
||
130 | *vit++ += area_factor; |
||
131 | // carbon pools aboveground are in kg/resource unit, e.g., the sum of stem-carbon of all trees, so no scaling required |
||
132 | *vit++ += s.cStem() * area_factor; *vit++ += s.nStem()* area_factor; |
||
133 | *vit++ += s.cBranch() * area_factor; *vit++ += s.nBranch()* area_factor; |
||
134 | *vit++ += s.cFoliage() * area_factor; *vit++ += s.nFoliage()* area_factor; |
||
135 | *vit++ += s.cCoarseRoot() * area_factor; *vit++ += s.nCoarseRoot()* area_factor; |
||
136 | *vit++ += s.cFineRoot() * area_factor; *vit++ += s.nFineRoot()* area_factor; |
||
137 | // regen |
||
138 | *vit++ += s.cRegeneration(); *vit++ += s.nRegeneration(); |
||
139 | // standing dead wood |
||
140 | *vit++ += ru->snag()->totalSWD().C ; *vit++ += ru->snag()->totalSWD().N ; |
||
141 | *vit++ += ru->snag()->totalOtherWood().C ; *vit++ += ru->snag()->totalOtherWood().N ; |
||
142 | // biomass from soil (converstion to kg/ha), and scale with fraction of stockable area |
||
143 | *vit++ += ru->soil()->youngRefractory().C*area_factor * 1000.; *vit++ += ru->soil()->youngRefractory().N*area_factor * 1000.; |
||
144 | *vit++ += ru->soil()->youngLabile().C*area_factor * 1000.; *vit++ += ru->soil()->youngLabile().N*area_factor * 1000.; |
||
145 | *vit++ += ru->soil()->oldOrganicMatter().C*area_factor * 1000.; *vit++ += ru->soil()->oldOrganicMatter().N*area_factor * 1000.; |
||
146 | |||
587 | werner | 147 | } |
1157 | werner | 148 | // write landscape sums |
149 | double total_stockable_area = v[0]; // convert to ha of stockable area |
||
150 | *this << currentYear() << -1 << -1; // keys |
||
151 | *this << v[0]; // stockable area [m2] |
||
152 | for (int i=1;i<v.size();++i) |
||
153 | *this << v[i] / total_stockable_area; |
||
154 | writeRow(); |
||
587 | werner | 155 | |
156 | } |
||
157 |