Subversion Repositories public iLand

Rev

Rev 1221 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
671 werner 1
/********************************************************************************************
2
**    iLand - an individual based forest landscape and disturbance model
3
**    http://iland.boku.ac.at
4
**    Copyright (C) 2009-  Werner Rammer, Rupert Seidl
5
**
6
**    This program is free software: you can redistribute it and/or modify
7
**    it under the terms of the GNU General Public License as published by
8
**    the Free Software Foundation, either version 3 of the License, or
9
**    (at your option) any later version.
10
**
11
**    This program is distributed in the hope that it will be useful,
12
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
**    GNU General Public License for more details.
15
**
16
**    You should have received a copy of the GNU General Public License
17
**    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
********************************************************************************************/
19
 
247 werner 20
/** @class SpeciesResponse
697 werner 21
  @ingroup core
248 werner 22
    Environmental responses relevant for production of a tree species on resource unit level.
226 werner 23
    SpeciesResponse combines data from different sources and converts information about the environment
24
    into responses of a species. The spatial level is the "ResourceUnit", where homogenetiy of environmental factors
25
    is assumed. The temporal aggregation depends on the factor, but usually, the daily environmental data is
26
    aggregated to monthly response values (which subsequently are used during 3PG production).
27
 Sources are:
28
    - vapour pressure deficit (dryness of atmosphere): directly from climate data (daily)
737 werner 29
    - soil water status (dryness of soil)(daily)
226 werner 30
    - temperature: directly from climate data (daily)
31
    - phenology: @sa Phenology, combines several sources (quasi-monthly)
32
    - CO2: @sa SpeciesSet::co2Response() based on ambient CO2 level (climate data), nitrogen and soil water responses (yearly)
33
    - nitrogen: based on the amount of available nitrogen (yearly)
193 werner 34
*/
35
#include "speciesresponse.h"
36
 
37
#include "resourceunit.h"
38
#include "species.h"
39
#include "resourceunitspecies.h"
208 werner 40
#include "climate.h"
226 werner 41
#include "model.h"
255 werner 42
#include "watercycle.h"
808 werner 43
#include "debugtimer.h"
193 werner 44
 
45
SpeciesResponse::SpeciesResponse()
46
{
209 werner 47
    mSpecies=0;
48
    mRu=0;
193 werner 49
}
209 werner 50
void SpeciesResponse::clear()
193 werner 51
{
52
    for (int i=0;i<12;i++)
328 werner 53
        mCO2Response[i]=mSoilWaterResponse[i]=mTempResponse[i]=mRadiation[i]=mUtilizableRadiation[i]=mVpdResponse[i]=0.;
193 werner 54
 
436 werner 55
    mNitrogenResponse = 0.;
56
    mTotalRadiation = 0.;
802 werner 57
    mTotalUtilizeableRadiation = 0.;
209 werner 58
 
193 werner 59
}
209 werner 60
void SpeciesResponse::setup(ResourceUnitSpecies *rus)
61
{
62
    mSpecies = rus->species();
63
    mRu = rus->ru();
64
    clear();
65
}
193 werner 66
 
367 werner 67
/// calculate responses for VPD and Soil Water. Return the minimum of those responses
68
/// @param psi_kPa psi of the soil in kPa
69
/// @param vpd vapor pressure deficit in kPa
70
/// @return minimum of soil water and vpd response
71
void SpeciesResponse::soilAtmosphereResponses(const double psi_kPa, const double vpd, double &rMinResponse) const
72
{
73
    double water_resp = mSpecies->soilwaterResponse(psi_kPa);
74
    double vpd_resp = mSpecies->vpdResponse( vpd );
75
    rMinResponse = qMin(water_resp, vpd_resp);
76
}
77
 
78
 
193 werner 79
/// Main function that calculates monthly / annual species responses
80
void SpeciesResponse::calculate()
81
{
626 werner 82
    DebugTimer tpg("SpeciesResponse::calculate");
193 werner 83
 
209 werner 84
    clear(); // reset values
226 werner 85
 
86
    // calculate yearly responses
255 werner 87
    const WaterCycle *water = mRu->waterCycle();
226 werner 88
    const Phenology &pheno = mRu->climate()->phenology(mSpecies->phenologyClass());
89
    int veg_begin = pheno.vegetationPeriodStart();
90
    int veg_end = pheno.vegetationPeriodEnd();
91
 
300 werner 92
    // yearly response
93
    const double nitrogen = mRu->resouceUnitVariables().nitrogenAvailable;
94
    // Nitrogen response: a yearly value based on available nitrogen
95
    mNitrogenResponse = mSpecies->nitrogenResponse( nitrogen );
343 werner 96
    const double ambient_co2 = mRu->climate()->begin()->co2; // CO2 level of first day of year (co2 is static)
300 werner 97
 
327 werner 98
    double water_resp, vpd_resp, temp_resp, min_resp;
99
    double  utilizeable_radiation;
226 werner 100
    int doy=0;
328 werner 101
    int month;
102
    const ClimateDay *end = mRu->climate()->end();
327 werner 103
    for (const ClimateDay *day=mRu->climate()->begin(); day!=end; ++day) {
328 werner 104
        month = day->month - 1;
327 werner 105
        // environmental responses
106
        water_resp = mSpecies->soilwaterResponse(water->psi_kPa(doy));
107
        vpd_resp = mSpecies->vpdResponse( day->vpd );
108
        temp_resp = mSpecies->temperatureResponse(day->temp_delayed);
328 werner 109
        mSoilWaterResponse[month] += water_resp;
110
        mTempResponse[month] += temp_resp;
111
        mVpdResponse[month] += vpd_resp;
802 werner 112
        mRadiation[month] += day->radiation;
273 werner 113
 
327 werner 114
        if (doy>=veg_begin && doy<=veg_end) {
115
            // environmental responses for the day
116
            // combine responses
273 werner 117
            min_resp = qMin(qMin(vpd_resp, temp_resp), water_resp);
327 werner 118
            // calculate utilizable radiation, Eq. 4, http://iland.boku.ac.at/primary+production
119
            utilizeable_radiation = day->radiation * min_resp;
802 werner 120
 
327 werner 121
        } else {
122
            utilizeable_radiation = 0.; // no utilizable radiation outside of vegetation period
329 werner 123
            min_resp = 0.;
208 werner 124
        }
328 werner 125
        mUtilizableRadiation[month]+= utilizeable_radiation;
327 werner 126
        doy++;
329 werner 127
        //DBGMODE(
128
            if (GlobalSettings::instance()->isDebugEnabled(GlobalSettings::dDailyResponses)) {
129
                DebugList &out = GlobalSettings::instance()->debugList(day->id(), GlobalSettings::dDailyResponses);
130
                // climatic variables
605 werner 131
                out << mSpecies->id() << day->id() << mRu->index() << mRu->id(); // date << day->temperature << day->vpd << day->preciptitation << day->radiation;
329 werner 132
                out << water_resp << temp_resp << vpd_resp << day->radiation << utilizeable_radiation;
133
            }
134
        //); // DBGMODE()
135
 
327 werner 136
    }
436 werner 137
    mTotalRadiation = mRu->climate()->totalRadiation();
327 werner 138
    // monthly values
139
    for (int i=0;i<12;i++) {
328 werner 140
        double days = mRu->climate()->days(i);
802 werner 141
        mTotalUtilizeableRadiation += mUtilizableRadiation[i];
328 werner 142
        mSoilWaterResponse[i]/=days;
143
        mTempResponse[i]/=days;
144
        mVpdResponse[i]/=days;
327 werner 145
        mCO2Response[i] = mSpecies->speciesSet()->co2Response(ambient_co2,
300 werner 146
                                                           mNitrogenResponse,
327 werner 147
                                                           mSoilWaterResponse[i]);
209 werner 148
    }
255 werner 149
 
209 werner 150
}
193 werner 151
 
208 werner 152