Subversion Repositories public iLand

Rev

Rev 1178 | Rev 1211 | 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"
1162 werner 7
#include <QRectF>
1174 werner 8
class ResourceUnitSpecies; // forward
9
class ResourceUnit; // forward
1111 werner 10
 
11
struct SaplingTree {
1113 werner 12
    SaplingTree() { clear(); }
1111 werner 13
    short unsigned int age;  // number of consectuive years the sapling suffers from dire conditions
1118 werner 14
    short signed int species_index; // index of the species within the resource-unit-species container
1177 werner 15
    unsigned char stress_years; // number of consecutive years that a sapling suffers from stress
1165 werner 16
    unsigned char flags; // flags, e.g. whether sapling stems from sprouting
1111 werner 17
    float height; // height of the sapling in meter
18
    bool is_occupied() const { return height>0.f; }
1118 werner 19
    void clear()  {  age=0; species_index=-1; stress_years=0; flags=0; height=0.f;  }
1177 werner 20
    void setSapling(const float h_m, const int age_yrs, const int species_idx) { height=h_m;
21
                                                                                 age=static_cast<short unsigned int>(age_yrs);
22
                                                                                 stress_years=0;
23
                                                                                 species_index=static_cast<short signed int>(species_idx); }
1165 werner 24
    // flags
25
    bool is_sprout() const { return flags & 1; }
26
    void set_sprout(const bool sprout) {if (sprout) flags |= 1; else flags &= (1 ^ 0xffffff ); }
1174 werner 27
    // get resource unit species of the sapling tree
28
    ResourceUnitSpecies *resourceUnitSpecies(const ResourceUnit *ru);
1111 werner 29
};
30
#define NSAPCELLS 5
31
struct SaplingCell {
32
    enum ECellState { CellInvalid=0, CellFree=1, CellFull=2};
33
    SaplingCell() {
34
        state=CellInvalid;
35
    }
36
    ECellState state;
37
    SaplingTree saplings[NSAPCELLS];
38
    void checkState() { if (state==CellInvalid) return;
1112 werner 39
                        bool free = false;
1111 werner 40
                        for (int i=0;i<NSAPCELLS;++i) {
41
                            // locked for all species, if a sapling of one species >1.3m
1112 werner 42
                            if (saplings[i].height>1.3f) {state = CellFull; return; }
1111 werner 43
                            // locked, if all slots are occupied.
44
                            if (!saplings[i].is_occupied())
45
                                free=true;
46
                        }
47
                        state = free? CellFree : CellFull;
48
                      }
1117 werner 49
    /// get an index to an open slot in the cell, or -1 if all slots are occupied
50
    int free_index() {
51
        for (int i=0;i<NSAPCELLS;++i)
52
            if (!saplings[i].is_occupied())
53
                return i;
54
        return -1;
55
    }
1175 werner 56
    /// count the number of occupied slots on the pixel
57
    int n_occupied() {
58
        int n=0;
59
        for (int i=0;i<NSAPCELLS;++i)
60
            n+=saplings[i].is_occupied();
61
        return n;
62
    }
63
 
1117 werner 64
    /// add a sapling to this cell, return a pointer to the tree on success, or 0 otherwise
65
    SaplingTree *addSapling(const float h_m, const int age_yrs, const int species_idx) {
66
        int idx = free_index();
67
        if (idx==-1)
68
            return 0;
69
        saplings[idx].setSapling(h_m, age_yrs, species_idx);
70
        return &saplings[idx];
71
    }
72
    /// return the maximum height on the pixel
73
    float max_height() { if (state==CellInvalid) return 0.f;
74
                         float h_max = 0.f;
75
                         for (int i=0;i<NSAPCELLS;++i)
76
                             h_max = std::max(saplings[i].height, h_max);
77
                         return h_max;
78
                       }
1178 werner 79
    bool has_new_saplings() { if (state==CellInvalid) return 0.f;
80
                        for (int i=0;i<NSAPCELLS;++i)
81
                            if (saplings[i].is_occupied() && saplings[i].age<2)
82
                                return true;
83
                        return false;
84
    }
1117 werner 85
    /// return the sapling tree of the requested species, or 0
86
    SaplingTree *sapling(int species_index) {
87
        if (state==CellInvalid) return 0;
88
        for (int i=0;i<NSAPCELLS;++i)
89
            if (saplings[i].species_index == species_index)
90
                return &saplings[i];
91
        return 0;
92
    }
1111 werner 93
};
94
class ResourceUnit;
1113 werner 95
class Saplings;
1111 werner 96
 
1117 werner 97
/** The SaplingStat class stores statistics on the resource unit x species level.
98
 */
1113 werner 99
class SaplingStat
100
{
101
public:
1115 werner 102
    SaplingStat() { clearStatistics(); }
1113 werner 103
    void clearStatistics();
1176 werner 104
    /// calculate statistics (and carbon flows) for the saplings of species 'species' on 'ru'.
1177 werner 105
    void calculate(const Species *species, ResourceUnit *ru);
1113 werner 106
    // actions
1160 werner 107
    void addCarbonOfDeadSapling(float dbh) { mDied++; mSumDbhDied+=dbh;  }
1111 werner 108
 
1113 werner 109
    // access to statistics
110
    int newSaplings() const { return mAdded; }
111
    int diedSaplings() const { return mDied; }
1177 werner 112
    int livingCohorts() const { return mLiving; } ///< get the number of cohorts
113
    double livingSaplings() const { return mLivingSaplings; }
114
    double livingSaplingsSmall() const { return mLivingSmallSaplings; }
1113 werner 115
    int recruitedSaplings() const { return mRecruited; }
116
    ///  returns the *represented* (Reineke's Law) number of trees (N/ha) and the mean dbh/height (cm/m)
1162 werner 117
    double livingStemNumber(const Species *species, double &rAvgDbh, double &rAvgHeight, double &rAvgAge) const;
1113 werner 118
 
119
    double averageHeight() const { return mAvgHeight; }
120
    double averageAge() const { return mAvgAge; }
121
    double averageDeltaHPot() const { return mAvgDeltaHPot; }
122
    double averageDeltaHRealized() const { return mAvgHRealized; }
123
    // carbon and nitrogen
124
    const CNPair &carbonLiving() const { return mCarbonLiving; } ///< state of the living
125
    const CNPair &carbonGain() const { return mCarbonGain; } ///< state of the living
126
 
127
private:
1177 werner 128
    int mAdded; ///< number of tree cohorts added
129
    int mRecruited; ///< number of cohorts recruited (i.e. grown out of regeneration layer)
130
    int mDied; ///< number of tree cohorts died
1113 werner 131
    double mSumDbhDied; ///< running sum of dbh of died trees (used to calculate detritus)
132
    int mLiving; ///< number of trees (cohorts!!!) currently in the regeneration layer
1177 werner 133
    double mLivingSaplings; ///< number of individual trees in the regen layer (using Reinekes R), with h>1.3m
134
    double mLivingSmallSaplings; ///< number of individual trees of cohorts < 1.3m height
1113 werner 135
    double mAvgHeight; ///< average height of saplings (m)
136
    double mAvgAge; ///< average age of saplings (years)
137
    double mAvgDeltaHPot; ///< average height increment potential (m)
138
    double mAvgHRealized; ///< average realized height increment
1175 werner 139
    CNPair mCarbonLiving; ///< kg Carbon (kg/ru) of saplings
1113 werner 140
    CNPair mCarbonGain; ///< net growth (kg / ru) of saplings
141
 
142
    friend class Saplings;
143
 
144
};
1117 werner 145
/** The Saplings class the container for the establishment and sapling growth in iLand.
146
 *
147
*/
1111 werner 148
class Saplings
149
{
150
public:
151
    Saplings();
152
    void setup();
1178 werner 153
    void calculateInitialStatistics(const ResourceUnit *ru);
1111 werner 154
    // main functions
155
    void establishment(const ResourceUnit *ru);
1113 werner 156
    void saplingGrowth(const ResourceUnit *ru);
157
 
1117 werner 158
    // access
1162 werner 159
    /// return the SaplingCell (i.e. container for the ind. saplings) for the given 2x2m coordinates
160
    /// if 'only_valid' is true, then 0 is returned if no living saplings are on the cell
161
    /// 'rRUPtr' is a pointer to a RU-ptr: if provided, a pointer to the resource unit is stored
162
    SaplingCell *cell(QPoint lif_coords, bool only_valid=true, ResourceUnit **rRUPtr=0);
163
    /// clear/kill all saplings within the rectangle given by 'rectangle'.
1165 werner 164
    /// If 'remove_biomass' is true, then the biomass is extracted (e.g. burnt), otherwise they are moved to soil
1162 werner 165
    void clearSaplings(const QRectF &rectangle, const bool remove_biomass);
1165 werner 166
    /// clear all saplings on a given cell 's' (if 'remove_biomass' is true: biomass removed from system (e.g. burnt))
167
    void clearSaplings(SaplingCell *s, ResourceUnit *ru, const bool remove_biomass);
1111 werner 168
 
1165 werner 169
    /// generate vegetative offspring from 't' (sprouts)
170
    int addSprout(const Tree *t);
171
 
1113 werner 172
    static void setRecruitmentVariation(const double variation) { mRecruitmentVariation = variation; }
173
    static void updateBrowsingPressure();
174
 
1111 werner 175
private:
1177 werner 176
    bool growSapling(const ResourceUnit *ru, SaplingCell &scell, SaplingTree &tree, int isc, float dom_height, float lif_value, int cohorts_on_px);
1159 werner 177
    //Grid<SaplingCell> mGrid;
1113 werner 178
    static double mRecruitmentVariation;
179
    static double mBrowsingPressure;
1111 werner 180
};
181
 
182
#endif // SAPLINGS_H