Subversion Repositories public iLand

Rev

Rev 1220 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/********************************************************************************************
**    iLand - an individual based forest landscape and disturbance model
**    http://iland.boku.ac.at
**    Copyright (C) 2009-  Werner Rammer, Rupert Seidl
**
**    This program is free software: you can redistribute it and/or modify
**    it under the terms of the GNU General Public License as published by
**    the Free Software Foundation, either version 3 of the License, or
**    (at your option) any later version.
**
**    This program is distributed in the hope that it will be useful,
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**    GNU General Public License for more details.
**
**    You should have received a copy of the GNU General Public License
**    along with this program.  If not, see <http://www.gnu.org/licenses/>.
********************************************************************************************/

#include "waterout.h"
#include "output.h"
#include "model.h"
#include "watercycle.h"
#include "resourceunit.h"
#include "climate.h"

WaterOut::WaterOut()
{
    setName("Water output", "water");
    setDescription("Annual water cycle output on resource unit/landscape unit.\n" \
                   "The output includes annual averages of precipitation, evapotranspiration, water excess, " \
                   "snow cover, and radiation input. The spatial resolution is landscape averages and/or resource unit level (i.e. 100m pixels). " \
                   "Landscape level averages are indicated by -1 for the 'ru' and 'index' columns.\n\n" \
                   "You can specify a 'condition' to limit output execution to specific years (variable 'year'). " \
                   "The 'conditionRU' can be used to suppress resource-unit-level details; eg. specifying 'in(year,100,200,300)' limits output on reosurce unit level to the years 100,200,300 " \
                   "(leaving 'conditionRU' blank enables details per default).");
    columns() << OutputColumn::year() << OutputColumn::ru() << OutputColumn::id()
              << OutputColumn("stocked_area", "area (ha/ha) which is stocked (covered by crowns, absorbing radiation)", OutDouble)
              << OutputColumn("stockable_area", "area (ha/ha) which is stockable (and within the project area)", OutDouble)
              << OutputColumn("precipitation_mm", "Annual precipitation sum (mm)", OutDouble)
              << OutputColumn("et_mm", "Evapotranspiration (mm)", OutDouble)
              << OutputColumn("excess_mm", "annual sum of water loss due to lateral outflow/groundwater flow (mm)", OutDouble)
              << OutputColumn("snowcover_days", "days with snowcover >0mm", OutInteger)
              << OutputColumn("total_radiation", "total incoming radiation over the year (MJ/m2), sum of data in climate input)", OutDouble)
              << OutputColumn("radiation_snowcover", "sum of radiation input (MJ/m2) for days with snow cover", OutInteger);


}

void WaterOut::exec()
{
    Model *m = GlobalSettings::instance()->model();

    // global condition
    if (!mCondition.isEmpty() && mCondition.calculate(GlobalSettings::instance()->currentYear())==0.)
        return;

    bool ru_level = true;
    // switch off details if this is indicated in the conditionRU option
    if (!mConditionDetails.isEmpty() && mConditionDetails.calculate(GlobalSettings::instance()->currentYear())==0.)
        ru_level = false;


    double ru_count = 0.;
    int snow_days = 0;
    double et=0., excess=0., rad=0., snow_rad=0., p=0.;
    double stockable=0., stocked=0.;
    foreach(ResourceUnit *ru, m->ruList()) {
        if (ru->id()==-1)
            continue; // do not include if out of project area

        const WaterCycle *wc = ru->waterCycle();
        if (ru_level) {
            *this << currentYear() << ru->index() << ru->id();
            *this << ru->stockedArea()/cRUArea << ru->stockableArea()/cRUArea;
            *this << ru->climate()->annualPrecipitation();
            *this << wc->mTotalET << wc->mTotalExcess;
            *this << wc->mSnowDays;
            *this << ru->climate()->totalRadiation() << wc->mSnowRad;
            writeRow();
        }
        ++ru_count;
        stockable+=ru->stockableArea(); stocked+=ru->stockedArea();
        p+=ru->climate()->annualPrecipitation();
        et+=wc->mTotalET; excess+=wc->mTotalExcess; snow_days+=wc->mSnowDays;
        rad+=ru->climate()->totalRadiation();
        snow_rad+=wc->mSnowRad;

    }
    // write landscape sums
    if (ru_count==0.)
        return;
    *this << currentYear() << -1 << -1; // codes -1/-1 for landscape level
    *this << stocked/ru_count/cRUArea << stockable/ru_count/cRUArea;
    *this << p / ru_count; // mean precip
    *this << et / ru_count;
    *this << excess / ru_count;
    *this << snow_days / ru_count;
    *this << rad / ru_count << snow_rad / ru_count;
    writeRow();


}

void WaterOut::setup()
{
    // use a condition for to control execuation for the current year
    QString condition = settings().value(".condition", "");
    mCondition.setExpression(condition);

    condition = settings().value(".conditionRU", "");
    mConditionDetails.setExpression(condition);


}