Subversion Repositories public iLand

Rev

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