Subversion Repositories public iLand

Rev

Rev 1175 | Rev 1177 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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