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