Rev 671 | Rev 698 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 671 | Rev 697 | ||
---|---|---|---|
1 | Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/production3pg.cpp': |
1 | Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/core/production3pg.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 | #include "global.h"
|
21 | #include "global.h"
|
22 | #include "production3pg.h"
|
22 | #include "production3pg.h"
|
23 | 23 | ||
24 | #include "resourceunit.h"
|
24 | #include "resourceunit.h"
|
25 | #include "species.h"
|
25 | #include "species.h"
|
26 | #include "speciesresponse.h"
|
26 | #include "speciesresponse.h"
|
27 | #include "model.h"
|
27 | #include "model.h"
|
28 | 28 | ||
29 | Production3PG::Production3PG() |
29 | Production3PG::Production3PG() |
30 | {
|
30 | {
|
31 | mResponse=0; |
31 | mResponse=0; |
32 | mEnvYear = 0.; |
32 | mEnvYear = 0.; |
33 | }
|
33 | }
|
34 | 34 | ||
35 | /**
|
35 | /**
|
36 | This is based on the utilizable photosynthetic active radiation.
|
36 | This is based on the utilizable photosynthetic active radiation.
|
37 | @sa http://iland.boku.ac.at/primary+production
|
37 | @sa http://iland.boku.ac.at/primary+production
|
38 | The resulting radiation is MJ/m2 */
|
38 | The resulting radiation is MJ/m2 */
|
39 | inline double Production3PG::calculateUtilizablePAR(const int month) const |
39 | inline double Production3PG::calculateUtilizablePAR(const int month) const |
40 | {
|
40 | {
|
41 | // calculate the available radiation. This is done at SpeciesResponse-Level
|
41 | // calculate the available radiation. This is done at SpeciesResponse-Level
|
42 | // see Equation (3)
|
42 | // see Equation (3)
|
43 | // multiplicative approach: responses are averaged one by one and multiplied on a monthly basis
|
43 | // multiplicative approach: responses are averaged one by one and multiplied on a monthly basis
|
44 | // double response = mResponse->absorbedRadiation()[month] *
|
44 | // double response = mResponse->absorbedRadiation()[month] *
|
45 | // mResponse->vpdResponse()[month] *
|
45 | // mResponse->vpdResponse()[month] *
|
46 | // mResponse->soilWaterResponse()[month] *
|
46 | // mResponse->soilWaterResponse()[month] *
|
47 | // mResponse->tempResponse()[month];
|
47 | // mResponse->tempResponse()[month];
|
48 | // minimum approach: for each day the minimum aof vpd, temp, soilwater is calculated, then averaged for each month
|
48 | // minimum approach: for each day the minimum aof vpd, temp, soilwater is calculated, then averaged for each month
|
49 | //double response = mResponse->absorbedRadiation()[month] *
|
49 | //double response = mResponse->absorbedRadiation()[month] *
|
50 | // mResponse->minimumResponses()[month];
|
50 | // mResponse->minimumResponses()[month];
|
51 | double response = mResponse->utilizableRadiation()[month]; |
51 | double response = mResponse->utilizableRadiation()[month]; |
52 | 52 | ||
53 | return response; |
53 | return response; |
54 | }
|
54 | }
|
55 | /** calculate the alphac (=photosynthetic efficiency) for the given month.
|
55 | /** calculate the alphac (=photosynthetic efficiency) for the given month.
|
56 | this is based on a global efficiency, and modified per species.
|
56 | this is based on a global efficiency, and modified per species.
|
57 | epsilon is in gC/MJ Radiation
|
57 | epsilon is in gC/MJ Radiation
|
58 | */
|
58 | */
|
59 | inline double Production3PG::calculateEpsilon(const int month) const |
59 | inline double Production3PG::calculateEpsilon(const int month) const |
60 | {
|
60 | {
|
61 | double epsilon = Model::settings().epsilon; // maximum radiation use efficiency |
61 | double epsilon = Model::settings().epsilon; // maximum radiation use efficiency |
62 | epsilon *= mResponse->nitrogenResponse() * |
62 | epsilon *= mResponse->nitrogenResponse() * |
63 | mResponse->co2Response()[month]; |
63 | mResponse->co2Response()[month]; |
64 | return epsilon; |
64 | return epsilon; |
65 | }
|
65 | }
|
66 | 66 | ||
67 | inline double Production3PG::abovegroundFraction() const |
67 | inline double Production3PG::abovegroundFraction() const |
68 | {
|
68 | {
|
69 | double utilized_frac = 1.; |
69 | double utilized_frac = 1.; |
70 | if (Model::settings().usePARFractionBelowGroundAllocation) { |
70 | if (Model::settings().usePARFractionBelowGroundAllocation) { |
71 | utilized_frac = mResponse->totalUtilizedRadiation() / mResponse->yearlyRadiation(); |
71 | utilized_frac = mResponse->totalUtilizedRadiation() / mResponse->yearlyRadiation(); |
72 | }
|
72 | }
|
73 | double harsh = 1 - 0.8/(1 + 2.5 * mResponse->nitrogenResponse() * utilized_frac); |
73 | double harsh = 1 - 0.8/(1 + 2.5 * mResponse->nitrogenResponse() * utilized_frac); |
74 | return harsh; |
74 | return harsh; |
75 | }
|
75 | }
|
76 | 76 | ||
77 | void Production3PG::clear() |
77 | void Production3PG::clear() |
78 | {
|
78 | {
|
79 | for (int i=0;i<12;i++) { |
79 | for (int i=0;i<12;i++) { |
80 | mGPP[i] = 0.; mUPAR[i]=0.; |
80 | mGPP[i] = 0.; mUPAR[i]=0.; |
81 | }
|
81 | }
|
82 | mEnvYear = 0.; |
82 | mEnvYear = 0.; |
83 | }
|
83 | }
|
84 | 84 | ||
85 | /** calculate the GPP
|
- | |
- | 85 | /** calculate the stand-level NPP
|
|
- | 86 | @ingroup core
|
|
- | 87 | Standlevel (i.e. ResourceUnit-level) production (NPP) following the 3PG approach from Landsberg and Waring.
|
|
86 | @sa http://iland.boku.ac.at/primary+production */
|
88 | @sa http://iland.boku.ac.at/primary+production */
|
87 | double Production3PG::calculate() |
89 | double Production3PG::calculate() |
88 | {
|
90 | {
|
89 | Q_ASSERT(mResponse!=0); |
91 | Q_ASSERT(mResponse!=0); |
90 | // Radiation: sum over all days of each month with foliage
|
92 | // Radiation: sum over all days of each month with foliage
|
91 | double year_raw_gpp = 0.; |
93 | double year_raw_gpp = 0.; |
92 | clear(); |
94 | clear(); |
93 | double utilizable_rad, epsilon; |
95 | double utilizable_rad, epsilon; |
94 | // conversion from gC to kg Biomass: C/Biomass=0.5
|
96 | // conversion from gC to kg Biomass: C/Biomass=0.5
|
95 | const double gC_to_kg_biomass = 1. / (biomassCFraction * 1000.); |
97 | const double gC_to_kg_biomass = 1. / (biomassCFraction * 1000.); |
96 | for (int i=0;i<12;i++) { |
98 | for (int i=0;i<12;i++) { |
97 | utilizable_rad = calculateUtilizablePAR(i); // utilizable radiation of the month times ... (MJ/m2) |
99 | utilizable_rad = calculateUtilizablePAR(i); // utilizable radiation of the month times ... (MJ/m2) |
98 | epsilon = calculateEpsilon(i); // ... photosynthetic efficiency ... (gC/MJ) |
100 | epsilon = calculateEpsilon(i); // ... photosynthetic efficiency ... (gC/MJ) |
99 | mUPAR[i] = utilizable_rad ; |
101 | mUPAR[i] = utilizable_rad ; |
100 | mGPP[i] =utilizable_rad * epsilon * gC_to_kg_biomass; // ... results in GPP of the month kg Biomass/m2 (converted from gC/m2) |
102 | mGPP[i] =utilizable_rad * epsilon * gC_to_kg_biomass; // ... results in GPP of the month kg Biomass/m2 (converted from gC/m2) |
101 | year_raw_gpp += mGPP[i]; // kg Biomass/m2 |
103 | year_raw_gpp += mGPP[i]; // kg Biomass/m2 |
102 | }
|
104 | }
|
103 | 105 | ||
104 | // calculate f_env,yr: see http://iland.boku.ac.at/sapling+growth+and+competition
|
106 | // calculate f_env,yr: see http://iland.boku.ac.at/sapling+growth+and+competition
|
105 | double f_sum = 0.; |
107 | double f_sum = 0.; |
106 | for (int i=0;i<12;i++) |
108 | for (int i=0;i<12;i++) |
107 | f_sum += mGPP[i] / gC_to_kg_biomass; // == uAPar * epsilon_eff |
109 | f_sum += mGPP[i] / gC_to_kg_biomass; // == uAPar * epsilon_eff |
108 | 110 | ||
109 | // the factor f_ref: parameter that scales response values to the range 0..1 (1 for best growth conditions) (species parameter)
|
111 | // the factor f_ref: parameter that scales response values to the range 0..1 (1 for best growth conditions) (species parameter)
|
110 | const double perf_factor = mResponse->species()->saplingGrowthParameters().referenceRatio; |
112 | const double perf_factor = mResponse->species()->saplingGrowthParameters().referenceRatio; |
111 | // f_env,yr=(uapar*epsilon_eff) / (APAR * epsilon_0 * fref)
|
113 | // f_env,yr=(uapar*epsilon_eff) / (APAR * epsilon_0 * fref)
|
112 | mEnvYear = f_sum / (Model::settings().epsilon * mResponse->yearlyRadiation() * perf_factor); |
114 | mEnvYear = f_sum / (Model::settings().epsilon * mResponse->yearlyRadiation() * perf_factor); |
113 | if (mEnvYear > 1.) { |
115 | if (mEnvYear > 1.) { |
114 | qDebug() << "ERROR: fEnvYear > 1 for " << mResponse->species()->id() << mEnvYear << "f_sum, epsilon, yearlyRad, perf_factor" << f_sum << Model::settings().epsilon << mResponse->yearlyRadiation() << perf_factor; |
116 | qDebug() << "ERROR: fEnvYear > 1 for " << mResponse->species()->id() << mEnvYear << "f_sum, epsilon, yearlyRad, perf_factor" << f_sum << Model::settings().epsilon << mResponse->yearlyRadiation() << perf_factor; |
115 | mEnvYear = 1.; |
117 | mEnvYear = 1.; |
116 | }
|
118 | }
|
117 | 119 | ||
118 | // calculate fraction for belowground biomass
|
120 | // calculate fraction for belowground biomass
|
119 | mRootFraction = 1. - abovegroundFraction(); |
121 | mRootFraction = 1. - abovegroundFraction(); |
120 | 122 | ||
121 | // global value set?
|
123 | // global value set?
|
122 | double dbg = GlobalSettings::instance()->settings().paramValue("gpp_per_year",0); |
124 | double dbg = GlobalSettings::instance()->settings().paramValue("gpp_per_year",0); |
123 | if (dbg) { |
125 | if (dbg) { |
124 | year_raw_gpp = dbg; |
126 | year_raw_gpp = dbg; |
125 | mRootFraction = 0.4; |
127 | mRootFraction = 0.4; |
126 | }
|
128 | }
|
127 | 129 | ||
128 | // year GPP/rad: kg Biomass/m2
|
130 | // year GPP/rad: kg Biomass/m2
|
129 | mGPPperArea = year_raw_gpp; |
131 | mGPPperArea = year_raw_gpp; |
130 | return mGPPperArea; // yearly GPP in kg Biomass/m2 |
132 | return mGPPperArea; // yearly GPP in kg Biomass/m2 |
131 | }
|
133 | }
|
132 | 134 |