Subversion Repositories public iLand

Rev

Rev 1221 | 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/>.
********************************************************************************************/


#ifndef SAPLING_H
#define SAPLING_H
#include <QtCore/QVector>
#include <QtCore/QPoint>
#include <bitset>
#include "grid.h"
#include "snag.h"
#include "model.h"
/// SaplingTreeOld holds information of a sapling (which represents N trees). Emphasis is on efficient storage.
class SaplingTreeOld {
public:
    SaplingTreeOld() { pixel=0; age.age=0; age.stress_years=0; height=0.05f; }
    bool isValid() const {return pixel!=0; }
    float *pixel; // pointer to the lifpixel the sapling lives on, set to 0 if sapling died/removed
    QPoint coords() const { return GlobalSettings::instance()->model()->grid()->indexOf(pixel); }
    struct  { // packed two 16bit to a 32 bit integer
        short unsigned int age;  // number of consectuive years the sapling suffers from dire conditions
        short unsigned int stress_years; // (upper 16bits) + age of sapling (lower 16 bits)
    } age;
    float height; // height of the sapling in meter
private:
};

class ResourceUnitSpecies; // forward
class Species;

/// saplings from 5cm to 4m
class Sapling
{
public:
    // maintenance
    Sapling();
    void setup(ResourceUnitSpecies *masterRUS) { mRUS = masterRUS; }
    void cleanupStorage(); // maintenance operation - remove dead/recruited trees from vector
    void clearStatistics();
    void newYear() { clearStatistics(); }
    void clear() { mSaplingTrees.clear(); mSapBitset.reset(); }
    static void setRecruitmentVariation(const double variation) { mRecruitmentVariation = variation; }
    static void updateBrowsingPressure();

    // access
    const QVector<SaplingTreeOld> &saplings() const {return mSaplingTrees; }
    // actions
    void calculateGrowth(); ///< perform growth + mortality + recruitment of all saplings of this RU and species
    /// add a new sapling at 'pos_lif' (i.e. QPoint with LIF-coordiantes) and with (optionally) 'height' (m) and 'age' (years)
    /// Returns the index of the newly added sapling.
    int addSapling(const QPoint &pos_lif, const float height=0.05f, const int age=1);
    /// clear (either remove or kill) a specific sapling
    void clearSapling(SaplingTreeOld &tree, const bool remove);
    void clearSapling(int index, const bool remove);
    void clearSaplings(const QPoint &position); ///< clear  saplings on a given position (after recruitment)
    void clearSaplings(const QRectF &rectangle, const bool remove_biomass); ///< clear  saplings within a given rectangle
    bool hasSapling(const QPoint &position) const; ///< return true if sapling is present at position
    double heightAt(const QPoint &position) const; ///< return the height at given position or 0 if position is not occupied
    // access to statistics
    int newSaplings() const { return mAdded; }
    int diedSaplings() const { return mDied; }
    int livingSaplings() const { return mLiving; } ///< get the number
    int recruitedSaplings() const { return mRecruited; }
    double livingStemNumber(double &rAvgDbh, double &rAvgHeight, double &rAvgAge) const; ///< returns the *represented* (Reineke's Law) number of trees (N/ha) and the mean dbh/height (cm/m)
    double averageHeight() const { return mAvgHeight; }
    double averageAge() const { return mAvgAge; }
    double averageDeltaHPot() const { return mAvgDeltaHPot; }
    double averageDeltaHRealized() const { return mAvgHRealized; }
    /// return the number of trees represented by one sapling of the current species and given 'height'
    double representedStemNumber(float height) const;
    // carbon and nitrogen
    const CNPair &carbonLiving() const { return mCarbonLiving; } ///< state of the living
    const CNPair &carbonGain() const { return mCarbonGain; } ///< state of the living
    // output maps
    void fillMaxHeightGrid(Grid<float> &grid) const;
    const std::bitset<cPxPerRU*cPxPerRU> &presentPositions() const { return mSapBitset; }
private:
    bool growSapling(SaplingTreeOld &tree, const double f_env_yr, Species* species);
    void setBit(const QPoint &pos_index, bool value);
    ResourceUnitSpecies *mRUS;
    QVector<SaplingTreeOld> mSaplingTrees;
    std::bitset<cPxPerRU*cPxPerRU> mSapBitset;
    int mAdded; ///< number of trees added
    int mRecruited; ///< number recruited (i.e. grown out of regeneration layer)
    int mDied; ///< number of trees died
    double mSumDbhDied; ///< running sum of dbh of died trees (used to calculate detritus)
    int mLiving; ///< number of trees (cohorts!!!) currently in the regeneration layer
    double mAvgHeight; ///< average height of saplings (m)
    double mAvgAge; ///< average age of saplings (years)
    double mAvgDeltaHPot; ///< average height increment potential (m)
    double mAvgHRealized; ///< average realized height increment
    static double mRecruitmentVariation; ///< defines range of random variation for recruited trees
    static double mBrowsingPressure; ///< scalar for the browsing pressure
    CNPair mCarbonLiving;
    CNPair mCarbonGain; ///< net growth (kg / ru) of saplings


    friend class Snapshot;
};

#endif // SAPLING_H