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