Subversion Repositories public iLand

Rev

Rev 1112 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1
 
1111 werner 2
#include "global.h"
3
#include "saplings.h"
4
 
5
#include "globalsettings.h"
6
#include "model.h"
7
#include "resourceunit.h"
8
#include "resourceunitspecies.h"
9
#include "establishment.h"
10
#include "species.h"
11
#include "seeddispersal.h"
12
 
13
 
14
Saplings::Saplings()
15
{
16
 
17
}
18
 
19
void Saplings::setup()
20
{
21
    mGrid.setup(GlobalSettings::instance()->model()->grid()->metricRect(), GlobalSettings::instance()->model()->grid()->cellsize());
22
 
23
    // mask out out-of-project areas
24
    HeightGrid *hg = GlobalSettings::instance()->model()->heightGrid();
25
    for (int i=0;i<mGrid.count();++i) {
26
        if (!hg->valueAtIndex(mGrid.index5(i)).isValid())
27
            mGrid[i].state = SaplingCell::CellInvalid;
28
        else
29
            mGrid[i].state = SaplingCell::CellFree;
30
    }
31
 
32
 
33
}
34
 
35
void Saplings::establishment(const ResourceUnit *ru)
36
{
37
    Grid<float> &seedmap =  const_cast<Grid<float>& > (ru->ruSpecies().first()->species()->seedDispersal()->seedMap() );
38
    HeightGrid *height_grid = GlobalSettings::instance()->model()->heightGrid();
39
    FloatGrid *lif_grid = GlobalSettings::instance()->model()->grid();
40
 
41
    QPoint iseedmap =  seedmap.indexAt(ru->boundingBox().topLeft()) ;
42
    QPoint imap =  mGrid.indexAt(ru->boundingBox().topLeft());
43
 
44
    int species_idx = irandom(0, ru->ruSpecies().size()-1);
45
    for (int s_idx = 0; s_idx<ru->ruSpecies().size(); ++s_idx) {
46
 
47
        // start from a random species (and cycle through the available species)
48
        species_idx = ++species_idx % ru->ruSpecies().size();
49
 
50
        ResourceUnitSpecies *rus = ru->ruSpecies()[species_idx];
51
        // check if there are seeds of the given species on the resource unit
52
        float seeds = 0.f;
53
        for (int iy=0;iy<5;++iy) {
54
            float *p = seedmap.ptr(iseedmap.x(), iseedmap.y());
55
            for (int ix=0;ix<5;++ix)
56
                seeds += *p++;
57
        }
58
        // if there are no seeds: no need to do more
59
        if (seeds==0.f)
60
            continue;
61
 
62
        // calculate the abiotic environment (TACA)
63
        rus->establishment().calculateAbioticEnvironment();
64
        double abiotic_env = rus->establishment().abioticEnvironment();
65
        if (abiotic_env==0.)
66
            continue;
67
 
68
        // loop over all 2m cells on this resource unit
69
        SaplingCell *s;
70
        int isc = 0; // index on 2m cell
71
        for (int iy=0; iy<cPxPerRU; ++iy) {
72
            s = mGrid.ptr(imap.x(), imap.y()+iy); // ptr to the row
73
            isc = mGrid.index(imap.x(), imap.y()+iy);
74
 
75
            for (int ix=0;ix<cPxPerRU; ++ix, ++s, ++isc, ++mTested) {
76
                if (s->state == SaplingCell::CellFree) {
77
                    bool viable = true;
78
                    // is a sapling of the current species already on the pixel?
79
                    // * test for sapling height already in cell state
80
                    // * test for grass-cover already in cell state
81
                    int i_occupied = -1;
82
                    for (int i=0;i<NSAPCELLS;++i) {
83
                        if (!s->saplings[i].is_occupied() && i_occupied<0)
84
                            i_occupied=i;
85
                        if (s->saplings[i].species_index == species_idx) {
86
                            viable = false;
87
                        }
88
                    }
89
 
90
                    if (viable) {
91
                        // grass cover?
92
                        DBG_IF(i_occupied<0, "establishment", "invalid value i_occupied<0");
93
                        float seed_map_value = seedmap[seedmap.index10(isc)];
94
                        if (seed_map_value==0.f)
95
                            continue;
96
                        const HeightGridValue &hgv = (*height_grid)[height_grid->index5(isc)];
97
                        float lif_value = (*lif_grid)[isc];
98
                        double lif_corrected = rus->species()->speciesSet()->LRIcorrection(lif_value, 4. / hgv.height);
99
                        // check for the combination of seed availability and light on the forest floor
100
                         if (drandom() < seed_map_value*lif_corrected*abiotic_env ) {
101
                             // ok, lets add a sapling at the given position
102
                             s->saplings[i_occupied].setSapling(0.05f, 1, species_idx);
103
                             s->checkState();
104
                             mAdded++;
105
 
106
                         }
107
 
108
                    }
109
 
110
                }
111
            }
112
        }
113
 
114
    }
115
 
116
}