Subversion Repositories public iLand

Rev

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