Subversion Repositories public iLand

Rev

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

Rev Author Line No. Line
1
 
1111 werner 2
#ifndef SAPLINGS_H
3
#define SAPLINGS_H
4
 
5
#include "grid.h"
1113 werner 6
#include "snag.h"
1111 werner 7
 
1113 werner 8
 
1111 werner 9
struct SaplingTree {
1113 werner 10
    SaplingTree() { clear(); }
1111 werner 11
    short unsigned int age;  // number of consectuive years the sapling suffers from dire conditions
1118 werner 12
    short signed int species_index; // index of the species within the resource-unit-species container
1111 werner 13
    unsigned char stress_years; // (upper 16bits) + age of sapling (lower 16 bits)
14
    unsigned char flags;
15
    float height; // height of the sapling in meter
16
    bool is_occupied() const { return height>0.f; }
1118 werner 17
    void clear()  {  age=0; species_index=-1; stress_years=0; flags=0; height=0.f;  }
1112 werner 18
    void setSapling(const float h_m, const int age_yrs, const int species_idx) { height=h_m; age=static_cast<short unsigned int>(age_yrs); stress_years=0; species_index=static_cast<short unsigned int>(species_idx); }
1111 werner 19
};
20
#define NSAPCELLS 5
21
struct SaplingCell {
22
    enum ECellState { CellInvalid=0, CellFree=1, CellFull=2};
23
    SaplingCell() {
24
        state=CellInvalid;
25
    }
26
    ECellState state;
27
    SaplingTree saplings[NSAPCELLS];
28
    void checkState() { if (state==CellInvalid) return;
1112 werner 29
                        bool free = false;
1111 werner 30
                        for (int i=0;i<NSAPCELLS;++i) {
31
                            // locked for all species, if a sapling of one species >1.3m
1112 werner 32
                            if (saplings[i].height>1.3f) {state = CellFull; return; }
1111 werner 33
                            // locked, if all slots are occupied.
34
                            if (!saplings[i].is_occupied())
35
                                free=true;
36
                        }
37
                        state = free? CellFree : CellFull;
38
                      }
1117 werner 39
    /// get an index to an open slot in the cell, or -1 if all slots are occupied
40
    int free_index() {
41
        for (int i=0;i<NSAPCELLS;++i)
42
            if (!saplings[i].is_occupied())
43
                return i;
44
        return -1;
45
    }
46
    /// add a sapling to this cell, return a pointer to the tree on success, or 0 otherwise
47
    SaplingTree *addSapling(const float h_m, const int age_yrs, const int species_idx) {
48
        int idx = free_index();
49
        if (idx==-1)
50
            return 0;
51
        saplings[idx].setSapling(h_m, age_yrs, species_idx);
52
        return &saplings[idx];
53
    }
54
    /// return the maximum height on the pixel
55
    float max_height() { if (state==CellInvalid) return 0.f;
56
                         float h_max = 0.f;
57
                         for (int i=0;i<NSAPCELLS;++i)
58
                             h_max = std::max(saplings[i].height, h_max);
59
                         return h_max;
60
                       }
61
    /// return the sapling tree of the requested species, or 0
62
    SaplingTree *sapling(int species_index) {
63
        if (state==CellInvalid) return 0;
64
        for (int i=0;i<NSAPCELLS;++i)
65
            if (saplings[i].species_index == species_index)
66
                return &saplings[i];
67
        return 0;
68
    }
1111 werner 69
};
70
class ResourceUnit;
1113 werner 71
class Saplings;
1111 werner 72
 
1117 werner 73
/** The SaplingStat class stores statistics on the resource unit x species level.
74
 */
1113 werner 75
class SaplingStat
76
{
77
public:
1115 werner 78
    SaplingStat() { clearStatistics(); }
1113 werner 79
    void clearStatistics();
80
    // actions
81
    void addCarbonOfDeadSapling(float dbh) { mDied++; mSumDbhDied+=dbh; }
1111 werner 82
 
1113 werner 83
    // access to statistics
84
    int newSaplings() const { return mAdded; }
85
    int diedSaplings() const { return mDied; }
86
    int livingSaplings() const { return mLiving; } ///< get the number
87
    int recruitedSaplings() const { return mRecruited; }
88
    ///  returns the *represented* (Reineke's Law) number of trees (N/ha) and the mean dbh/height (cm/m)
89
    double livingStemNumber(double &rAvgDbh, double &rAvgHeight, double &rAvgAge) const;
90
 
91
    double averageHeight() const { return mAvgHeight; }
92
    double averageAge() const { return mAvgAge; }
93
    double averageDeltaHPot() const { return mAvgDeltaHPot; }
94
    double averageDeltaHRealized() const { return mAvgHRealized; }
95
    /// return the number of trees represented by one sapling of the current species and given 'height'
96
    double representedStemNumber(float height) const;
97
    // carbon and nitrogen
98
    const CNPair &carbonLiving() const { return mCarbonLiving; } ///< state of the living
99
    const CNPair &carbonGain() const { return mCarbonGain; } ///< state of the living
100
 
101
private:
102
    int mAdded; ///< number of trees added
103
    int mRecruited; ///< number recruited (i.e. grown out of regeneration layer)
104
    int mDied; ///< number of trees died
105
    double mSumDbhDied; ///< running sum of dbh of died trees (used to calculate detritus)
106
    int mLiving; ///< number of trees (cohorts!!!) currently in the regeneration layer
107
    double mAvgHeight; ///< average height of saplings (m)
108
    double mAvgAge; ///< average age of saplings (years)
109
    double mAvgDeltaHPot; ///< average height increment potential (m)
110
    double mAvgHRealized; ///< average realized height increment
111
    CNPair mCarbonLiving;
112
    CNPair mCarbonGain; ///< net growth (kg / ru) of saplings
113
 
114
    friend class Saplings;
115
 
116
};
1117 werner 117
/** The Saplings class the container for the establishment and sapling growth in iLand.
118
 *
119
*/
1111 werner 120
class Saplings
121
{
122
public:
123
    Saplings();
124
    void setup();
125
    // main functions
126
    void establishment(const ResourceUnit *ru);
1113 werner 127
    void saplingGrowth(const ResourceUnit *ru);
128
 
1117 werner 129
    // access
130
    const Grid<SaplingCell> &grid() const { return mGrid; }
131
    SaplingCell *cell(QPoint lif_coords)  { SaplingCell *s=mGrid.ptr(lif_coords.x(), lif_coords.y()); if (s && s->state!=SaplingCell::CellInvalid) return s; else return 0; }
1111 werner 132
    void clearStats() { mAdded=0; mTested=0;}
133
    int saplingsAdded() const { return mAdded; }
134
    int pixelTested() const { return mTested; }
135
 
1113 werner 136
    static void setRecruitmentVariation(const double variation) { mRecruitmentVariation = variation; }
137
    static void updateBrowsingPressure();
138
 
1111 werner 139
private:
1115 werner 140
    bool growSapling(const ResourceUnit *ru, SaplingTree &tree, int isc, float dom_height, float lif_value);
1111 werner 141
    Grid<SaplingCell> mGrid;
142
    int mAdded;
143
    int mTested;
1113 werner 144
    static double mRecruitmentVariation;
145
    static double mBrowsingPressure;
1111 werner 146
};
147
 
148
#endif // SAPLINGS_H