Subversion Repositories public iLand

Rev

Rev 1118 | Rev 1159 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1118 Rev 1157
Line 65... Line 65...
65
    mSpeciesSet = 0;
65
    mSpeciesSet = 0;
66
    mClimate = 0;
66
    mClimate = 0;
67
    mPixelCount=0;
67
    mPixelCount=0;
68
    mStockedArea = 0;
68
    mStockedArea = 0;
69
    mStockedPixelCount = 0;
69
    mStockedPixelCount = 0;
-
 
70
    mStockableArea = 0;
70
    mAggregatedWLA = 0.;
71
    mAggregatedWLA = 0.;
71
    mAggregatedLA = 0.;
72
    mAggregatedLA = 0.;
72
    mAggregatedLR = 0.;
73
    mAggregatedLR = 0.;
73
    mEffectiveArea = 0.;
74
    mEffectiveArea = 0.;
74
    mLRI_modification = 0.;
75
    mLRI_modification = 0.;
Line 263... Line 264...
263
        // estimate stocked area based on crown projections
264
        // estimate stocked area based on crown projections
264
        double crown_area = 0.;
265
        double crown_area = 0.;
265
        for (int i=0;i<mTrees.count();++i)
266
        for (int i=0;i<mTrees.count();++i)
266
            crown_area += mTrees.at(i).isDead() ? 0. : mTrees.at(i).stamp()->reader()->crownArea();
267
            crown_area += mTrees.at(i).isDead() ? 0. : mTrees.at(i).stamp()->reader()->crownArea();
267
268
268
        qDebug() << "crown area: lai" << leafAreaIndex() << "stocked area (pixels)" << mStockedArea << " area (crown)" << crown_area;
-
 
269
        if (leafAreaIndex()<2.) {
-
 
270
            mStockedArea = crown_area;
-
 
-
 
269
        if (logLevelDebug())
-
 
270
            qDebug() << "crown area: lai" << leafAreaIndex() << "stocked area (pixels)" << mStockedArea << " area (crown)" << crown_area;
-
 
271
        if (leafAreaIndex()<1.) {
-
 
272
            mStockedArea = std::min(crown_area, mStockedArea);
271
        } else {
273
        } else {
272
274
273
            double px_frac = leafAreaIndex()-2.; // 0 at LAI=2, 1 at LAI=3
-
 
274
            mStockedArea = mStockedArea * px_frac + crown_area * (1. - px_frac);
-
 
-
 
275
            double px_frac = (leafAreaIndex()-1.)/2.; // 0 at LAI=1, 1 at LAI=3
-
 
276
            mStockedArea = mStockedArea * px_frac + std::min(crown_area, mStockedArea) * (1. - px_frac);
275
        }
277
        }
276
        if (mStockedArea==0.)
278
        if (mStockedArea==0.)
277
            return;
279
            return;
278
    }
280
    }
279
281
Line 305... Line 307...
305
    if (ru_lai < 1.)
307
    if (ru_lai < 1.)
306
        ru_lai = 1.;
308
        ru_lai = 1.;
307
    // note: LAIFactors are only 1 if sum of LAI is > 1. (see WaterCycle)
309
    // note: LAIFactors are only 1 if sum of LAI is > 1. (see WaterCycle)
308
    for (i=mRUSpecies.constBegin(); i!=iend; ++i) {
310
    for (i=mRUSpecies.constBegin(); i!=iend; ++i) {
309
        double lai_factor = (*i)->statistics().leafAreaIndex() / ru_lai;
311
        double lai_factor = (*i)->statistics().leafAreaIndex() / ru_lai;
310
        DBGMODE(
-
 
311
        if (lai_factor > 1.)
-
 
312
            qDebug() << "LAI factor > 1";
-
 
313
        );
-
 
-
 
312
-
 
313
        //DBGMODE(
-
 
314
        if (lai_factor > 1.) {
-
 
315
                        const ResourceUnitSpecies* rus=*i;
-
 
316
                        qDebug() << "LAI factor > 1: species ru-index:" << rus->species()->name() << rus->ru()->index();
-
 
317
                    }
-
 
318
        //);
314
        (*i)->setLAIfactor( lai_factor );
319
        (*i)->setLAIfactor( lai_factor );
315
    }
320
    }
316
321
317
    // soil water model - this determines soil water contents needed for response calculations
322
    // soil water model - this determines soil water contents needed for response calculations
318
    {
323
    {
319
    mWater->run();
324
    mWater->run();
320
    }
325
    }
321
326
322
    // invoke species specific calculation (3PG)
327
    // invoke species specific calculation (3PG)
323
    for (i=mRUSpecies.constBegin(); i!=iend; ++i) {
328
    for (i=mRUSpecies.constBegin(); i!=iend; ++i) {
-
 
329
        //DBGMODE(
-
 
330
        if ((*i)->LAIfactor() > 1.) {
-
 
331
                    const ResourceUnitSpecies* rus=*i;
-
 
332
                    qDebug() << "LAI factor > 1: species ru-index value:" << rus->species()->name() << rus->ru()->index() << rus->LAIfactor();
-
 
333
                    }
-
 
334
        //);
324
        (*i)->calculate(); // CALCULATE 3PG
335
        (*i)->calculate(); // CALCULATE 3PG
325
        if (logLevelInfo() &&  (*i)->LAIfactor()>0)
336
        if (logLevelInfo() &&  (*i)->LAIfactor()>0)
326
            qDebug() << "ru" << mIndex << "species" << (*i)->species()->id() << "LAIfraction" << (*i)->LAIfactor() << "raw_gpp_m2"
337
            qDebug() << "ru" << mIndex << "species" << (*i)->species()->id() << "LAIfraction" << (*i)->LAIfactor() << "raw_gpp_m2"
327
                     << (*i)->prod3PG().GPPperArea() << "area:" << productiveArea() << "gpp:"
338
                     << (*i)->prod3PG().GPPperArea() << "area:" << productiveArea() << "gpp:"
328
                     << productiveArea()*(*i)->prod3PG().GPPperArea()
339
                     << productiveArea()*(*i)->prod3PG().GPPperArea()
Line 367... Line 378...
367
        mRUSpecies[i]->updateGWL(); // get sum of dead trees (died + removed)
378
        mRUSpecies[i]->updateGWL(); // get sum of dead trees (died + removed)
368
        mRUSpecies[i]->statistics().calculate(); // calculate the living (and add removed volume to gwl)
379
        mRUSpecies[i]->statistics().calculate(); // calculate the living (and add removed volume to gwl)
369
        mStatistics.add(mRUSpecies[i]->statistics());
380
        mStatistics.add(mRUSpecies[i]->statistics());
370
    }
381
    }
371
    mStatistics.calculate(); // aggreagte on stand level
382
    mStatistics.calculate(); // aggreagte on stand level
-
 
383
-
 
384
    // update carbon flows
-
 
385
    if (soil() && GlobalSettings::instance()->model()->settings().carbonCycleEnabled) {
-
 
386
        double area_factor = stockableArea() / cRUArea; //conversion factor
-
 
387
        mUnitVariables.carbonUptake = statistics().npp() * biomassCFraction;
-
 
388
        mUnitVariables.carbonUptake += statistics().nppSaplings() * biomassCFraction;
-
 
389
-
 
390
        double to_atm = snag()->fluxToAtmosphere().C / area_factor; // from snags, kgC/ha
-
 
391
        to_atm += soil()->fluxToAtmosphere().C *cRUArea/10.; // soil: t/ha -> t/m2 -> kg/ha
-
 
392
        mUnitVariables.carbonToAtm = to_atm;
-
 
393
-
 
394
        double to_dist = snag()->fluxToDisturbance().C / area_factor;
-
 
395
        to_dist += soil()->fluxToDisturbance().C * cRUArea/10.;
-
 
396
        double to_harvest = snag()->fluxToExtern().C / area_factor;
-
 
397
-
 
398
        mUnitVariables.NEP = mUnitVariables.carbonUptake - to_atm - to_dist - to_harvest; // kgC/ha
-
 
399
-
 
400
        // incremental values....
-
 
401
        mUnitVariables.cumCarbonUptake += mUnitVariables.carbonUptake;
-
 
402
        mUnitVariables.cumCarbonToAtm += mUnitVariables.carbonToAtm;
-
 
403
        mUnitVariables.cumNEP += mUnitVariables.NEP;
-
 
404
-
 
405
    }
372
406
373
}
407
}
374
408
375
void ResourceUnit::addTreeAgingForAllTrees()
409
void ResourceUnit::addTreeAgingForAllTrees()
376
{
410
{
Line 411... Line 445...
411
}
445
}
412
446
413
/** recreate statistics. This is necessary after events that changed the structure
447
/** recreate statistics. This is necessary after events that changed the structure
414
    of the stand *after* the growth of trees (where stand statistics are updated).
448
    of the stand *after* the growth of trees (where stand statistics are updated).
415
    An example is after disturbances.  */
449
    An example is after disturbances.  */
416
void ResourceUnit::recreateStandStatistics()
-
 
-
 
450
void ResourceUnit::recreateStandStatistics(bool recalculate_stats)
417
{
451
{
418
    for (int i=0;i<mRUSpecies.count();i++) {
452
    for (int i=0;i<mRUSpecies.count();i++) {
419
        mRUSpecies[i]->statistics().clear();
453
        mRUSpecies[i]->statistics().clear();
420
    }
454
    }
421
    foreach(const Tree &t, mTrees) {
455
    foreach(const Tree &t, mTrees) {
422
        resourceUnitSpecies(t.species()).statistics().add(&t, 0);
456
        resourceUnitSpecies(t.species()).statistics().add(&t, 0);
423
    }
457
    }
424
    for (int i=0;i<mRUSpecies.count();i++) {
-
 
425
        mRUSpecies[i]->statistics().calculate();
-
 
-
 
458
-
 
459
    if (recalculate_stats) {
-
 
460
        for (int i=0;i<mRUSpecies.count();i++) {
-
 
461
            mRUSpecies[i]->statistics().calculate();
-
 
462
        }
426
    }
463
    }
427
}
464
}
428
465
429
void ResourceUnit::setSaplingHeightMap(float *map_pointer)
466
void ResourceUnit::setSaplingHeightMap(float *map_pointer)
430
{
467
{
Line 467... Line 504...
467
        rus->changeSapling().clearSaplings(pixel_rect, remove_from_soil);
504
        rus->changeSapling().clearSaplings(pixel_rect, remove_from_soil);
468
    }
505
    }
469
506
470
}
507
}
471
508
472
float ResourceUnit::saplingHeightForInit(const QPoint &position) const
-
 
-
 
509
double ResourceUnit::saplingHeightForInit(const QPoint &position) const
473
{
510
{
474
    double maxh = 0.;
511
    double maxh = 0.;
475
    foreach(ResourceUnitSpecies* rus, mRUSpecies)
512
    foreach(ResourceUnitSpecies* rus, mRUSpecies)
476
        maxh = qMax(maxh, rus->sapling().heightAt(position));
513
        maxh = qMax(maxh, rus->sapling().heightAt(position));
477
    return maxh;
514
    return maxh;