Subversion Repositories public iLand

Rev

Rev 802 | Rev 1104 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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