diff --git a/Source/moja.modules.cbm/include/moja/modules/cbm/peatlandspinupnext.h b/Source/moja.modules.cbm/include/moja/modules/cbm/peatlandspinupnext.h index 762a474a..1526ee49 100644 --- a/Source/moja.modules.cbm/include/moja/modules/cbm/peatlandspinupnext.h +++ b/Source/moja.modules.cbm/include/moja/modules/cbm/peatlandspinupnext.h @@ -11,135 +11,139 @@ #include "moja/modules/cbm/peatlands.h" namespace moja { -namespace modules { -namespace cbm { - - /* - After regular spinup procedure, this class is called to quicly build up the peat DOM pools. - This class is implemented based on R-code - */ - class CBM_API PeatlandSpinupNext : public CBMModuleBase { - public: - PeatlandSpinupNext() : CBMModuleBase() { } - virtual ~PeatlandSpinupNext() = default; - - void configure(const DynamicObject& config) override; - void subscribe(NotificationCenter& notificationCenter) override; - - void doLocalDomainInit() override; - //void doTimingInit() override; - void doPrePostDisturbanceEvent() override; - - private: - const flint::IPool* _softwoodMerch; - const flint::IPool* _softwoodOther; - const flint::IPool* _softwoodFoliage; - const flint::IPool* _softwoodCoarseRoots; - const flint::IPool* _softwoodFineRoots; - const flint::IPool* _softwoodStemSnag; - const flint::IPool* _softwoodBranchSnag; - - const flint::IPool* _hardwoodMerch; - const flint::IPool* _hardwoodOther; - const flint::IPool* _hardwoodFoliage; - const flint::IPool* _hardwoodCoarseRoots; - const flint::IPool* _hardwoodFineRoots; - const flint::IPool* _hardwoodStemSnag; - const flint::IPool* _hardwoodBranchSnag; - - const flint::IPool* _softwoodStem; - const flint::IPool* _hardwoodStem; - - const flint::IPool* _woodyFoliageLive; - const flint::IPool* _woodyStemsBranchesLive; - const flint::IPool* _woodyRootsLive; - const flint::IPool* _sedgeFoliageLive; - const flint::IPool* _sedgeRootsLive; - const flint::IPool* _featherMossLive; - const flint::IPool* _sphagnumMossLive; - - const flint::IPool* _woodyFoliageDead; - const flint::IPool* _woodyFineDead; - const flint::IPool* _woodyCoarseDead; - const flint::IPool* _woodyRootsDead; - const flint::IPool* _sedgeFoliageDead; - const flint::IPool* _sedgeRootsDead; - const flint::IPool* _feathermossDead; - const flint::IPool* _acrotelm_o; - const flint::IPool* _catotelm_a; - const flint::IPool* _acrotelm_a; - const flint::IPool* _catotelm_o; - - const flint::IPool* _atmosphere; - - const flint::IVariable* _turnoverRates; - - double _softwoodFoliageFallRate{ 0 }; - double _hardwoodFoliageFallRate{ 0 }; - double _stemAnnualTurnOverRate{ 0 }; - double _stemSnagTurnoverRate{ 0 }; - double _softwoodBranchTurnOverRate{ 0 }; - double _hardwoodBranchTurnOverRate{ 0 }; - double _coarseRootTurnProp{ 0 }; - double _fineRootTurnProp{ 0 }; - double _otherToBranchSnagSplit{ 0 }; - double _branchSnagTurnoverRate{ 0 }; - - - int smallTreeOn{ 0 }; - double smallTreeFoliageRemoval{ 0 }; - double smallTreeFineRootRemoval{ 0 }; - double smallTreeCoarseRootRemoval{ 0 }; - double smallTreeOtherRemovalToWFD{ 0 }; - double smallTreeBranchSnagRemoval{ 0 }; - double smallTreeStemSnagRemoval{ 0 }; - - int largeTreeOn{ 0 }; - double largeTreeFoliageRemoval{ 0 }; - double largeTreeFineRootRemoval{ 0 }; - double largeTreeCoarseRootRemoval{ 0 }; - double largeTreeOtherRemovalToWFD{ 0 }; - double largeTreeBranchSnagRemoval{ 0 }; - double largeTreeStemSnagRemoval{ 0 }; - - double meanAnnualTemperature{ 0 }; - double f_r{ 1 }; - double f_fr{ 1 }; - - // decay parameters associated to this peatland unit - std::shared_ptr decayParas; - - // turnover parameters associated to this peatland unit - std::shared_ptr turnoverParas; - - // the growth parameters associated to this peatland unit - std::shared_ptr growthParas; - - // the peatland fire parameter - std::shared_ptr fireParas; - - void getTreeTurnoverRate(Peatlands peatlandId); - - void getAndUpdateParameter(); - - void getNonOpenPeatlandRemovals(Peatlands peatlandId); - - void populatePeatlandDeadPoolsV1(); - - void populatePeatlandDeadPoolsV2(); - - void populatePeatlandDeadPoolsV3(); - - void getCurrentDeadPoolValues(); - - void resetSlowPools(); - - inline double modifyQ10(double baseQ10Para) { - return (pow(baseQ10Para, 0.1 * (meanAnnualTemperature - 10))); - }; - }; - -}}} // namespace moja::modules::cbm + namespace modules { + namespace cbm { + + /* + After regular spinup procedure, this class is called to quicly build up the peat DOM pools. + This class is implemented based on R-code + */ + class CBM_API PeatlandSpinupNext : public CBMModuleBase { + public: + PeatlandSpinupNext() : CBMModuleBase() { } + virtual ~PeatlandSpinupNext() = default; + + void configure(const DynamicObject& config) override; + void subscribe(NotificationCenter& notificationCenter) override; + + void doLocalDomainInit() override; + //void doTimingInit() override; + void doPrePostDisturbanceEvent() override; + + private: + const flint::IPool* _softwoodMerch; + const flint::IPool* _softwoodOther; + const flint::IPool* _softwoodFoliage; + const flint::IPool* _softwoodCoarseRoots; + const flint::IPool* _softwoodFineRoots; + const flint::IPool* _softwoodStemSnag; + const flint::IPool* _softwoodBranchSnag; + + const flint::IPool* _hardwoodMerch; + const flint::IPool* _hardwoodOther; + const flint::IPool* _hardwoodFoliage; + const flint::IPool* _hardwoodCoarseRoots; + const flint::IPool* _hardwoodFineRoots; + const flint::IPool* _hardwoodStemSnag; + const flint::IPool* _hardwoodBranchSnag; + + const flint::IPool* _softwoodStem; + const flint::IPool* _hardwoodStem; + + const flint::IPool* _woodyFoliageLive; + const flint::IPool* _woodyStemsBranchesLive; + const flint::IPool* _woodyRootsLive; + const flint::IPool* _sedgeFoliageLive; + const flint::IPool* _sedgeRootsLive; + const flint::IPool* _featherMossLive; + const flint::IPool* _sphagnumMossLive; + + const flint::IPool* _woodyFoliageDead; + const flint::IPool* _woodyFineDead; + const flint::IPool* _woodyCoarseDead; + const flint::IPool* _woodyRootsDead; + const flint::IPool* _sedgeFoliageDead; + const flint::IPool* _sedgeRootsDead; + const flint::IPool* _feathermossDead; + const flint::IPool* _acrotelm_o; + const flint::IPool* _catotelm_a; + const flint::IPool* _acrotelm_a; + const flint::IPool* _catotelm_o; + + const flint::IPool* _atmosphere; + + const flint::IVariable* _turnoverRates; + + double _softwoodFoliageFallRate{ 0 }; + double _hardwoodFoliageFallRate{ 0 }; + double _stemAnnualTurnOverRate{ 0 }; + double _stemSnagTurnoverRate{ 0 }; + double _softwoodBranchTurnOverRate{ 0 }; + double _hardwoodBranchTurnOverRate{ 0 }; + double _coarseRootTurnProp{ 0 }; + double _fineRootTurnProp{ 0 }; + double _otherToBranchSnagSplit{ 0 }; + double _branchSnagTurnoverRate{ 0 }; + + + int smallTreeOn{ 0 }; + double smallTreeFoliageRemoval{ 0 }; + double smallTreeFineRootRemoval{ 0 }; + double smallTreeCoarseRootRemoval{ 0 }; + double smallTreeOtherRemovalToWFD{ 0 }; + double smallTreeBranchSnagRemoval{ 0 }; + double smallTreeStemSnagRemoval{ 0 }; + + int largeTreeOn{ 0 }; + double largeTreeFoliageRemoval{ 0 }; + double largeTreeFineRootRemoval{ 0 }; + double largeTreeCoarseRootRemoval{ 0 }; + double largeTreeOtherRemovalToWFD{ 0 }; + double largeTreeBranchSnagRemoval{ 0 }; + double largeTreeStemSnagRemoval{ 0 }; + + double meanAnnualTemperature{ 0 }; + double f_r{ 1 }; + double f_fr{ 1 }; + + // decay parameters associated to this peatland unit + std::shared_ptr decayParas; + + // turnover parameters associated to this peatland unit + std::shared_ptr turnoverParas; + + // the growth parameters associated to this peatland unit + std::shared_ptr growthParas; + + // the peatland fire parameter + std::shared_ptr fireParas; + + void getTreeTurnoverRate(Peatlands peatlandId); + + void getAndUpdateParameter(); + + void getNonOpenPeatlandRemovals(Peatlands peatlandId); + + //void populatePeatlandDeadPoolsV1(); + + //void populatePeatlandDeadPoolsV2(); + + void populatePeatlandDeadPoolsV3(); + + void getCurrentDeadPoolValues(); + + void resetSlowPools(); + + void loadPeatlandInitialPoolValues(const DynamicObject& data); + + inline double modifyQ10(double baseQ10Para) { + return (pow(baseQ10Para, 0.1 * (meanAnnualTemperature - 10))); + }; + }; + + } + } +} // namespace moja::modules::cbm #endif // MOJA_MODULES_CBM_PLDECAY_H_ diff --git a/Source/moja.modules.cbm/include/moja/modules/cbm/peatlandspinupturnovermodule.h b/Source/moja.modules.cbm/include/moja/modules/cbm/peatlandspinupturnovermodule.h index 1c450ed9..914a05cf 100644 --- a/Source/moja.modules.cbm/include/moja/modules/cbm/peatlandspinupturnovermodule.h +++ b/Source/moja.modules.cbm/include/moja/modules/cbm/peatlandspinupturnovermodule.h @@ -35,7 +35,6 @@ namespace moja { void doWaterTableFlux(); bool _isInitialPoolLoaded{ false }; - void loadPeatlandInitialPoolValues(const DynamicObject& data); }; } } diff --git a/Source/moja.modules.cbm/src/cbmspinupsequencer.cpp b/Source/moja.modules.cbm/src/cbmspinupsequencer.cpp index f1e868ab..560a03f1 100644 --- a/Source/moja.modules.cbm/src/cbmspinupsequencer.cpp +++ b/Source/moja.modules.cbm/src/cbmspinupsequencer.cpp @@ -422,6 +422,39 @@ namespace moja { _smallTreeAge->reset_value(); _age->reset_value(); + // in case of loading initial peat pool value, just simulate to grow/turnover/decay firstly + // and then fire the spinup next event to load and replace the peat pool value + auto loadPeatInitialPool = _landUnitData->getVariable("load_peatpool_initials")->value(); + if (loadPeatInitialPool) { + int startYear = timing->startDate().year(); // Simulation start year. + int minimumPeatlandWoodyAge = fireReturnIntervalValue; // Set the default regrow year. + + if (lastFireYearValue < 0) { // No last fire year record. + minimumPeatlandWoodyAge = fireReturnIntervalValue; + } + else if (startYear - lastFireYearValue < 0) { // Fire occurred after simulation. + minimumPeatlandWoodyAge = startYear - lastFireYearValue + fireReturnIntervalValue; + } + else { // Fire occurred before simulation. + minimumPeatlandWoodyAge = startYear - lastFireYearValue; + } + + // Regrow to minimum peatland woody age. + if (peatlandFireRegrowValue) { + if (_standAge > 0) { + //for forest peatland, just regrow to initial stand age + minimumPeatlandWoodyAge = _standAge; + } + fireSpinupSequenceEvent(notificationCenter, luc, minimumPeatlandWoodyAge, false); + } + + //if loading initial pool value is preferred, skip rest spinup procedure + //post a special pre-disturbance signal to trigger peatland spinup next call + //to load initial peat pool value (acrotelm_o, catotelm_a) + notificationCenter.postNotification(moja::signals::PrePostDisturbanceEvent); + return; + } + // in production/removal mode, only run one rotation, // and use live biomass value at minimum spinup time steps(200) peatlandMaxRotationValue = 1; diff --git a/Source/moja.modules.cbm/src/cbmtransitionrulesmodule.cpp b/Source/moja.modules.cbm/src/cbmtransitionrulesmodule.cpp index e6bb7c99..94914992 100644 --- a/Source/moja.modules.cbm/src/cbmtransitionrulesmodule.cpp +++ b/Source/moja.modules.cbm/src/cbmtransitionrulesmodule.cpp @@ -1,6 +1,6 @@ /** * @file -* The CBMTransitionRulesModule module is responsible for transitioning each pixel’s age +* The CBMTransitionRulesModule module is responsible for transitioning each pixel’s age * and classifier set to the same or new values following a disturbance event, * as well as applying any regeneration delay which will prevent the stand from growing for a number of years after a disturbance. * *******************************/ @@ -18,12 +18,12 @@ namespace moja { namespace modules { namespace cbm { - /** - * Subscribe to signals LocalDomainInit,DisturbanceEvent,TimingInit and TimingShutdown. - * - * @param notificationCenter NotificationCenter& - * @return void - * ************************/ + /** + * Subscribe to signals LocalDomainInit,DisturbanceEvent,TimingInit and TimingShutdown. + * + * @param notificationCenter NotificationCenter& + * @return void + * ************************/ void CBMTransitionRulesModule::subscribe(NotificationCenter& notificationCenter) { notificationCenter.subscribe(signals::LocalDomainInit, &CBMTransitionRulesModule::onLocalDomainInit, *this); notificationCenter.subscribe(signals::TimingInit, &CBMTransitionRulesModule::onTimingInit, *this); @@ -31,29 +31,29 @@ namespace moja { notificationCenter.subscribe(signals::DisturbanceEvent, &CBMTransitionRulesModule::onDisturbanceEvent, *this); } - /** - * Initialise CBMTransitionRulesModule._gcId,CBMTransitionRulesModule._spuId,CBMTransitionRulesModule._age, \n - * CBMTransitionRulesModule._cset,CBMTransitionRulesModule._regenDelay,CBMTransitionRulesModule._softwoodMerch, \n - * CBMTransitionRulesModule._softwoodFoliage,CBMTransitionRulesModule._softwoodOther,CBMTransitionRulesModule._softwoodCoarseRoots, \n - * CBMTransitionRulesModule._softwoodFineRoots,CBMTransitionRulesModule._hardwoodMerch,CBMTransitionRulesModule._hardwoodFoliage, \n - * CBMTransitionRulesModule._hardwoodOther,CBMTransitionRulesModule._hardwoodCoarseRoots and CBMTransitionRulesModule._hardwoodFineRoots. \n - * If _landUnitData has variable "transition_rules_matches", assign CBMTransitionRulesModule._transitionRuleMatches as "transition_rule_matches" in _landUnitData and \n - * CBMTransitionRulesModule._allowMatchingRules as true. \n - * Assign a constant variable transitionRules as "transition_rules" value in _landUnitData. \n - * If transitionRules is a vector, \n - * for each transitionRuleData in transitionRules, create a TransitionRule object using transitionRuleData as a parameter and \n - * assign the index TransitionRule object Id in CBMTransitionRulesModule._transitions as the TransitionRule object. \n - * else, create a TransitionRule object using a dynamic object of transitionRules and \n - * assign the index TransistionRule object Id in CBMTransitionRulesModule._transitions as the TransitionRule object. \n - * Assign a constant variable transitionRuleClassifiers as "transition_rule_classifiers" value in _landUnitData. \n - * if transitionRuleClassifers is not empty,check if transitionRuleClassifiers is a vector and \n - * for each transitionRule in transitionRuleClassifiers, \n - * add classifier using "classifer_name" and "classifer_value" in transistionRule to index transitionRule id in CBMTransitionRulesModule._transitions. \n - * if transistionRuleClassifiers is not a vector, \n - * add classifier using "classifer_name" and "classifer_value" in transistionRuleClassifers to index transitionRuleClassifers id in CBMTransitionRulesModule._transitions. - * - * @return void - * ************************/ + /** + * Initialise CBMTransitionRulesModule._gcId,CBMTransitionRulesModule._spuId,CBMTransitionRulesModule._age, \n + * CBMTransitionRulesModule._cset,CBMTransitionRulesModule._regenDelay,CBMTransitionRulesModule._softwoodMerch, \n + * CBMTransitionRulesModule._softwoodFoliage,CBMTransitionRulesModule._softwoodOther,CBMTransitionRulesModule._softwoodCoarseRoots, \n + * CBMTransitionRulesModule._softwoodFineRoots,CBMTransitionRulesModule._hardwoodMerch,CBMTransitionRulesModule._hardwoodFoliage, \n + * CBMTransitionRulesModule._hardwoodOther,CBMTransitionRulesModule._hardwoodCoarseRoots and CBMTransitionRulesModule._hardwoodFineRoots. \n + * If _landUnitData has variable "transition_rules_matches", assign CBMTransitionRulesModule._transitionRuleMatches as "transition_rule_matches" in _landUnitData and \n + * CBMTransitionRulesModule._allowMatchingRules as true. \n + * Assign a constant variable transitionRules as "transition_rules" value in _landUnitData. \n + * If transitionRules is a vector, \n + * for each transitionRuleData in transitionRules, create a TransitionRule object using transitionRuleData as a parameter and \n + * assign the index TransitionRule object Id in CBMTransitionRulesModule._transitions as the TransitionRule object. \n + * else, create a TransitionRule object using a dynamic object of transitionRules and \n + * assign the index TransistionRule object Id in CBMTransitionRulesModule._transitions as the TransitionRule object. \n + * Assign a constant variable transitionRuleClassifiers as "transition_rule_classifiers" value in _landUnitData. \n + * if transitionRuleClassifers is not empty,check if transitionRuleClassifiers is a vector and \n + * for each transitionRule in transitionRuleClassifiers, \n + * add classifier using "classifer_name" and "classifer_value" in transistionRule to index transitionRule id in CBMTransitionRulesModule._transitions. \n + * if transistionRuleClassifiers is not a vector, \n + * add classifier using "classifer_name" and "classifer_value" in transistionRuleClassifers to index transitionRuleClassifers id in CBMTransitionRulesModule._transitions. + * + * @return void + * ************************/ void CBMTransitionRulesModule::doLocalDomainInit() { _gcId = _landUnitData->getVariable("growth_curve_id"); _spuId = _landUnitData->getVariable("spatial_unit_id"); @@ -118,7 +118,7 @@ namespace moja { /** * Assign CBMTransitionRulesModule._regenDelay value as 0 and \n * CBMTransitionRulesModule._standSpuId as CBMTransitionRulesModule._spuId value. - * + * * @return void * ************************/ void CBMTransitionRulesModule::doTimingInit() { @@ -127,7 +127,7 @@ namespace moja { /** * Assign CBMTransitionRulesModule._regenDelay value as 0. - * + * * @return void * ************************/ void CBMTransitionRulesModule::doTimingShutdown() { @@ -137,7 +137,7 @@ namespace moja { * If CBMTransitionRulesModule._transitionRuleMatches value contains parameter disturbanceType, * return the index disturbanceType in CBMTransitionRulesModule._transitionRuleMatches. * else return -1. - * + * * @param disturbanceType string * @return int * ************************/ @@ -152,7 +152,7 @@ namespace moja { * if CBMTransitionRulesModule._allowMatchingRules and transitionRuleId are both equal to -1, \n * Invoke findTransitionRule() using "disturbance" of parameter n as a parameter and assign the value to transitionRuleId. * Assign transition as transitionRuleId of CBMTransitionRulesModule._transitions value. \n - * Assign CBMTransitionRulesModule._regenDelay value as transition CBMTransitionRulesModule._regenDelay. \n + * Assign CBMTransitionRulesModule._regenDelay value as transition CBMTransitionRulesModule._regenDelay. \n * Assign cset as CBMTransitionRulesModule._cset value. * For each classifer in transition CBMTransitionRulesModule._classifers, \n * if the second element of classifer is not equal to "?", Assign first element of classifer of cset as second element of classifier. \n @@ -165,7 +165,7 @@ namespace moja { * Assign CBMTransitionRulesModule._age value as newAge. \n * else if resetType is equal to AgeResetType::Yield, invoke findYieldCurveAge() and assign the value to integer variable newAge. \n * Assign CBMTransitionRulesModule._age value as newAge. - * + * * @exception Simulation Error : Handles error during simulation. * @param n DynamicVar * @return void @@ -192,7 +192,7 @@ namespace moja { << flint::ModuleName(metaData().moduleName) << flint::ErrorCode(0)); } - + auto transition = _transitions.at(transitionRuleId); _regenDelay->set_value(transition.regenDelay()); @@ -247,7 +247,7 @@ namespace moja { * For each iteration in ageCarbonCurve, check if ageCarbonCurve is greater than standBiomass and \n * assign matchingAge as the index. * return matchingAge. - * + * * @return int * ************************/ int CBMTransitionRulesModule::findYieldCurveAge() { @@ -277,7 +277,6 @@ namespace moja { break; } } - return matchingAge; } @@ -285,7 +284,7 @@ namespace moja { * Assign double variable totalAgBiomass as 0.0 \n * for each pool in the array,add the pool value to totalAgBiomass. \n * return totalAgBiomass. - * + * * @return double * ************************/ double CBMTransitionRulesModule::calculateBiomass() { @@ -300,7 +299,7 @@ namespace moja { /** * Constructor. - * + * * Initialise TransitionRule._Id, TransitionRule._resetAge and CBMTransitionRulesModule._regenDelay. \n * if parameter data does not contain "reset_type", \n * assign TransitionRule._resetType as AgeResetType::Absolute. \n @@ -309,7 +308,7 @@ namespace moja { * else if resetType is equal to "relative", assign TransitionRule._resetType as AgeResetType::Relative. \n * else if resetType is equal to "yield", assign TransitionRule._resetType as AgeResetType::Yield. \n * else print out a log error. - * + * * @param data DynamicObject& * ************************/ TransitionRule::TransitionRule(const DynamicObject& data) { diff --git a/Source/moja.modules.cbm/src/peatlandspinupnext.cpp b/Source/moja.modules.cbm/src/peatlandspinupnext.cpp index a7f8b8ff..2a749d5f 100644 --- a/Source/moja.modules.cbm/src/peatlandspinupnext.cpp +++ b/Source/moja.modules.cbm/src/peatlandspinupnext.cpp @@ -114,42 +114,49 @@ namespace moja { //get the current peatland ID auto& peatland_class = _landUnitData->getVariable("peatland_class")->value(); auto peatlandId = peatland_class.isEmpty() ? -1 : peatland_class.convert(); - bool runPeatland = peatlandId > 0; + bool runPeatland = peatlandId > 0; if (runPeatland) { - double defaultMAT = _landUnitData->getVariable("default_mean_annual_temperature")->value(); + auto loadPeatInitialPool = _landUnitData->getVariable("load_peatpool_initials")->value(); + if (loadPeatInitialPool) { + const auto& peatlandInitials = _landUnitData->getVariable("peatland_initial_stocks")->value(); + loadPeatlandInitialPoolValues(peatlandInitials.extract()); + } + else { + double defaultMAT = _landUnitData->getVariable("default_mean_annual_temperature")->value(); - auto matVal = _landUnitData->getVariable("mean_annual_temperature")->value(); - meanAnnualTemperature = matVal.isEmpty() ? defaultMAT - : matVal.type() == typeid(TimeSeries) ? matVal.extract().value() - : matVal.convert(); + auto matVal = _landUnitData->getVariable("mean_annual_temperature")->value(); + meanAnnualTemperature = matVal.isEmpty() ? defaultMAT + : matVal.type() == typeid(TimeSeries) ? matVal.extract().value() + : matVal.convert(); - // get fire return interval - auto fireReturnInterval = _landUnitData->getVariable("fire_return_interval")->value(); - int defaultFRI = _landUnitData->getVariable("default_fire_return_interval")->value(); - f_r = fireReturnInterval.isEmpty() ? defaultFRI : fireReturnInterval.convert(); - f_fr = 1.0 / f_r; + // get fire return interval + auto fireReturnInterval = _landUnitData->getVariable("fire_return_interval")->value(); + int defaultFRI = _landUnitData->getVariable("default_fire_return_interval")->value(); + f_r = fireReturnInterval.isEmpty() ? defaultFRI : fireReturnInterval.convert(); + f_fr = 1.0 / f_r; - // get turnover parameter for treed and forested peatland - getTreeTurnoverRate(Peatlands(peatlandId)); + // get turnover parameter for treed and forested peatland + getTreeTurnoverRate(Peatlands(peatlandId)); - // get related parameters - getAndUpdateParameter(); + // get related parameters + getAndUpdateParameter(); - // get small tree and forest turnover amount (removals) - getNonOpenPeatlandRemovals(Peatlands(peatlandId)); + // get small tree and forest turnover amount (removals) + getNonOpenPeatlandRemovals(Peatlands(peatlandId)); - // get current carbon values in slow pools - getCurrentDeadPoolValues(); + // get current carbon values in slow pools + getCurrentDeadPoolValues(); - // reset slow pools - resetSlowPools(); + // reset slow pools + resetSlowPools(); - // transfer carbon between pools - int spinupFactor = _landUnitData->getVariable("peatland_spinup_factor")->value(); - if (spinupFactor > 0) { - // buildup the peat pools when factor is set either 8000 or 10000 - populatePeatlandDeadPoolsV3(); + // transfer carbon between pools + int spinupFactor = _landUnitData->getVariable("peatland_spinup_factor")->value(); + if (spinupFactor > 0) { + // buildup the peat pools when factor is set either 8000 or 10000 + populatePeatlandDeadPoolsV3(); + } } } } @@ -448,6 +455,25 @@ namespace moja { _landUnitData->applyOperations(); } + void PeatlandSpinupNext::loadPeatlandInitialPoolValues(const DynamicObject& data) { + auto init = _landUnitData->createStockOperation(); + + auto acPoolInitial = 0; + auto caPoolInitial = 0; + try { + acPoolInitial = data["acrotelm"]; + caPoolInitial = data["catotelm"]; + } + catch (Exception e) {//do nothing, incase of no value + } + + init->addTransfer(_atmosphere, _acrotelm_o, acPoolInitial) + ->addTransfer(_atmosphere, _catotelm_a, caPoolInitial); + + _landUnitData->submitOperation(init); + _landUnitData->applyOperations(); + } + /* // second version of spinup next procedure void PeatlandSpinupNext::populatePeatlandDeadPoolsV2() { diff --git a/Source/moja.modules.cbm/src/peatlandspinupturnovermodule.cpp b/Source/moja.modules.cbm/src/peatlandspinupturnovermodule.cpp index 5114c85f..95f76ac6 100644 --- a/Source/moja.modules.cbm/src/peatlandspinupturnovermodule.cpp +++ b/Source/moja.modules.cbm/src/peatlandspinupturnovermodule.cpp @@ -74,7 +74,6 @@ namespace moja { /** * Set PeatlandSpinupTurnOverModule._runPeatland to false, PeatlandSpinupTurnOverModule._appliedAnnualWTD is only valid in forward run, reset it for spinup \n - * If value of variable "load_peatpool_initials" in _landUnitData is not null, invoke PeatlandSpinupTurnOverModule.loadPeatlandInitialPoolValues() \n * If the value of "peatland_class" in _landUnitData is not empty, set PeatlandSpinupTurnOverModule._runPeatland to true \n * assign turnoverParas a shared pointer of PeatlandGrowthParameters and set it to "peatland_turnover_parameters" in _landUnitData \n * assign growthParas a shared pointer of PeatlandGrowthParameters ans set it to "peatland_growth_parameters" in _landUnitData \n @@ -92,13 +91,6 @@ namespace moja { //applied_annual_wtd is only valid in forward run, reset it for spinup _appliedAnnualWTD->reset_value(); - //load initial peat pool values if it is enabled - auto loadInitialFlag = _landUnitData->getVariable("load_peatpool_initials")->value(); - if (loadInitialFlag) { - const auto& peatlandInitials = _landUnitData->getVariable("peatland_initial_stocks")->value(); - loadPeatlandInitialPoolValues(peatlandInitials.extract()); - } - auto& peatland_class = _landUnitData->getVariable("peatland_class")->value(); _peatlandId = peatland_class.isEmpty() ? -1 : peatland_class.convert(); @@ -225,7 +217,7 @@ namespace moja { peatlandWaterTableFlux->addTransfer(_catotelm_a, _catotelm_o, fluxAmount); } } - else if (currentAwtd > longtermWtd&& previousAwtd > longtermWtd) { + else if (currentAwtd > longtermWtd && previousAwtd > longtermWtd) { if (currentAwtd >= previousAwtd) { //Acrotelm_O -> Acrotelm_A if (fluxAmount > aoPoolValue) fluxAmount = aoPoolValue; @@ -263,26 +255,6 @@ namespace moja { _landUnitData->submitOperation(peatlandWaterTableFlux); _landUnitData->applyOperations(); } - - /** - * Invoke createStockOperation() on _landUnitData \n - * Add transfers from source PeatlandSpinupTurnOverModule._atmosphere to sink PeatlandSpinupTurnOverModule._acrotelm_o, - * transfer amount is value "acrotelm" in parameter data, source PeatlandSpinupTurnOverModule._atmosphere to sink PeatlandSpinupTurnOverModule._catotelm_o, - * transfer amount is value "catotelm" in parameter data \n - * Submit the operation to _landUnitData, invoke submitOperation() and applyOperations() on _landUnitData - * - * @param data const DynamicObject& - * @return void - */ - void PeatlandSpinupTurnOverModule::loadPeatlandInitialPoolValues(const DynamicObject& data) { - auto init = _landUnitData->createStockOperation(); - - init->addTransfer(_atmosphere, _acrotelm_o, data["acrotelm"]) - ->addTransfer(_atmosphere, _catotelm_a, data["catotelm"]); - - _landUnitData->submitOperation(init); - _landUnitData->applyOperations(); - } } } } \ No newline at end of file diff --git a/Source/moja.modules.cbm/src/peatlandturnovermodule.cpp b/Source/moja.modules.cbm/src/peatlandturnovermodule.cpp index 81d57f14..f953b42c 100644 --- a/Source/moja.modules.cbm/src/peatlandturnovermodule.cpp +++ b/Source/moja.modules.cbm/src/peatlandturnovermodule.cpp @@ -72,7 +72,6 @@ namespace moja { /** * Set PeatlandTurnoverModule._runPeatland and PeatlandTurnoverModule._modifiersFullyAppplied to false, PeatlandTurnoverModule._appliedAnnualWTD is reset \n - * If value of variable "load_peatpool_initials" in _landUnitData is not null, invoke PeatlandTurnoverModule.loadPeatlandInitialPoolValues() \n * If the value of "peatland_class" in _landUnitData is not empty, * assign turnoverParas a shared pointer of PeatlandGrowthParameters and set it to "peatland_turnover_parameters" in _landUnitData \n * assign growthParas a shared pointer of PeatlandGrowthParameters ans set it to "peatland_growth_parameters" in _landUnitData \n @@ -301,7 +300,7 @@ namespace moja { peatlandWaterTableFlux->addTransfer(_catotelm_a, _catotelm_o, fluxAmount); } } - else if (currentAwtd > longtermWtd&& previousAwtd > longtermWtd) { + else if (currentAwtd > longtermWtd && previousAwtd > longtermWtd) { if (currentAwtd >= previousAwtd) { //Acrotelm_O -> Acrotelm_A if (fluxAmount > aoPoolValue) fluxAmount = aoPoolValue;