Exemple #1
0
        /// <summary>Removes biomass from live and dead biomass pools and send to surface organic matter</summary>
        /// <param name="biomassRemoveType">Name of event that triggered this biomass remove call.</param>
        /// <param name="amount">The fractions of biomass to remove</param>
        /// <param name="Live">Live biomass pool</param>
        /// <param name="Dead">Dead biomass pool</param>
        /// <param name="Removed">The removed pool to add to.</param>
        /// <param name="Detached">The detached pool to add to.</param>
        /// <param name="writeToSummary">Write the biomass removal to summary file?</param>
        /// <returns>The remaining live fraction.</returns>
        public double RemoveBiomass(string biomassRemoveType, OrganBiomassRemovalType amount, 
                                    Biomass Live, Biomass Dead, 
                                    Biomass Removed, Biomass Detached,
                                    bool writeToSummary = true)
        {
            if (amount == null)
                amount = FindDefault(biomassRemoveType);

            double totalFractionToRemove = amount.FractionLiveToRemove + amount.FractionDeadToRemove
                                           + amount.FractionLiveToResidue + amount.FractionDeadToResidue;

            if (totalFractionToRemove > 0.0)
            {
                Biomass detaching;
                double remainingLiveFraction = RemoveBiomassFromLiveAndDead(amount, Live, Dead, out Removed, Detached, out detaching);

                // Add the detaching biomass to surface organic matter model.
                //TODO: theoretically the dead material is different from the live, so it should be added as a separate pool to SurfaceOM
                surfaceOrganicMatter.Add(detaching.Wt * 10, detaching.N * 10, 0.0, plant.CropType, Name);

                if (writeToSummary)
                {
                    double toResidue = (amount.FractionLiveToResidue + amount.FractionDeadToResidue) / totalFractionToRemove * 100;
                    double removedOff = (amount.FractionLiveToRemove + amount.FractionDeadToRemove) / totalFractionToRemove * 100;
                    summary.WriteMessage(this, "Removing " + (totalFractionToRemove * 100).ToString("0.0")
                                             + "% of " + Parent.Name + " Biomass from " + plant.Name
                                             + ".  Of this " + removedOff.ToString("0.0") + "% is removed from the system and "
                                             + toResidue.ToString("0.0") + "% is returned to the surface organic matter");
                }
                return remainingLiveFraction;
            }

            return 1;
        }
 protected void OnSimulationCommencing(object sender, EventArgs e)
 {
     DMDemand = new BiomassPoolType();
     NDemand  = new BiomassPoolType();
     DMSupply = new BiomassSupplyType();
     NSupply  = new BiomassSupplyType();
     potentialDMAllocation = new BiomassPoolType();
     Detached = new Biomass();
     Clear();
 }
Exemple #3
0
 /// <summary>Clears this instance.</summary>
 protected virtual void Clear()
 {
     Live = new Biomass();
     Dead = new Biomass();
     DMSupply.Clear();
     NSupply.Clear();
     DMDemand.Clear();
     NDemand.Clear();
     potentialDMAllocation.Clear();
 }
Exemple #4
0
 private void OnDoDailyInitialisation(object sender, EventArgs e)
 {
     if (Plant.IsAlive)
     {
         Allocated = new PMF.Biomass();
         Senesced  = new Biomass();
         Detached  = new Biomass();
         Removed   = new Biomass();
     }
 }
 protected void OnSimulationCommencing(object sender, EventArgs e)
 {
     Allocated = new PMF.Biomass();
     Senesced  = new Biomass();
     Detached  = new Biomass();
     Removed   = new Biomass();
     NDemand   = new BiomassPoolType();
     DMDemand  = new BiomassPoolType();
     NSupply   = new BiomassSupplyType();
     DMSupply  = new BiomassSupplyType();
 }
Exemple #6
0
        private void SetNSupply(object sender, EventArgs e)
        {
            double  LabileN   = Math.Max(0, StartLive.StorageN - StartLive.StorageWt * MinimumNConc.Value());
            Biomass Senescing = new Biomass();

            GetSenescingLeafBiomass(out Senescing);

            NSupply.Reallocation    = Senescing.StorageN * NReallocationFactor.Value();
            NSupply.Retranslocation = (LabileN - StartNReallocationSupply) * NRetranslocationFactor.Value();
            NSupply.Uptake          = 0.0;
        }
Exemple #7
0
 private void GetSenescingLeafBiomass(out Biomass Senescing)
 {
     Senescing = new Biomass();
     foreach (PerrenialLeafCohort L in Leaves)
     {
         if (L.Age >= LeafResidenceTime.Value())
         {
             Senescing.Add(L.Live);
         }
     }
 }
Exemple #8
0
 protected void OnSimulationCommencing(object sender, EventArgs e)
 {
     startLive = new Biomass();
     Allocated = new Biomass();
     Senesced  = new Biomass();
     Detached  = new Biomass();
     Removed   = new Biomass();
     Live      = new Biomass();
     Dead      = new Biomass();
     Clear();
 }
Exemple #9
0
 public MockOrgan(string name, double liveWt, double deadWt = 0)
 {
     Name = name;
     Live = new Biomass()
     {
         StructuralWt = liveWt
     };
     Dead = new Biomass()
     {
         StructuralWt = deadWt
     };
 }
Exemple #10
0
 private void DetachLeaves(out Biomass Detached)
 {
     Detached = new Biomass();
     foreach (PerrenialLeafCohort L in Leaves)
     {
         if (L.Age >= (LeafResidenceTime.Value() + LeafDetachmentTime.Value()))
         {
             Detached.Add(L.Dead);
         }
     }
     Leaves.RemoveAll(L => L.Age >= (LeafResidenceTime.Value() + LeafDetachmentTime.Value()));
 }
Exemple #11
0
        /// <summary>Removes biomass from organs when harvest, graze or cut events are called.</summary>
        /// <param name="biomassRemoveType">Name of event that triggered this biomass remove call.</param>
        /// <param name="amountToRemove">The fractions of biomass to remove</param>
        virtual public void RemoveBiomass(string biomassRemoveType, OrganBiomassRemovalType amountToRemove)
        {
            Biomass liveAfterRemoval = Live;
            Biomass deadAfterRemoval = Dead;

            biomassRemovalModel.RemoveBiomass(biomassRemoveType, amountToRemove, liveAfterRemoval, deadAfterRemoval, Removed, Detached);

            double remainingLiveFraction = MathUtilities.Divide(liveAfterRemoval.Wt, Live.Wt, 0);
            double remainingDeadFraction = MathUtilities.Divide(deadAfterRemoval.Wt, Dead.Wt, 0);

            cohort.ReduceLeavesUniformly(remainingLiveFraction, remainingDeadFraction);
        }
Exemple #12
0
        private void OnPlantEnding(object sender, EventArgs e)
        {
            Biomass total = Live + Dead;

            if (total.Wt > 0.0)
            {
                Detached.Add(Live);
                Detached.Add(Dead);
                SurfaceOrganicMatter.Add(total.Wt * 10, total.N * 10, 0, Plant.CropType, Name);
            }
            Clear();
        }
Exemple #13
0
        /// <summary>Removes biomass from live and dead biomass pools, may send to surface organic matter</summary>
        /// <param name="biomassRemoveType">Name of event that triggered this biomass removal call.</param>
        /// <param name="amount">The fractions of biomass to remove</param>
        /// <param name="Live">Live biomass pool</param>
        /// <param name="Dead">Dead biomass pool</param>
        /// <param name="Removed">The removed pool to add to.</param>
        /// <param name="Detached">The detached pool to add to.</param>
        /// <param name="writeToSummary">Write the biomass removal to summary file?</param>
        /// <returns>The remaining live fraction.</returns>
        public double RemoveBiomass(string biomassRemoveType, OrganBiomassRemovalType amount,
                                    Biomass Live, Biomass Dead,
                                    Biomass Removed, Biomass Detached,
                                    bool writeToSummary = true)
        {
            if (amount == null)
            {
                amount = FindDefault(biomassRemoveType);
            }
            else
            {
                CheckRemoveFractions(biomassRemoveType, amount);
            }

            double liveFractionToRemove = amount.FractionLiveToRemove + amount.FractionLiveToResidue;
            double deadFractionToRemove = amount.FractionDeadToRemove + amount.FractionDeadToResidue;

            if (liveFractionToRemove + deadFractionToRemove > 0.0)
            {
                Biomass removing;
                Biomass detaching;
                double  totalBiomass = Live.Wt + Dead.Wt;
                if (totalBiomass > 0)
                {
                    double remainingLiveFraction = RemoveBiomassFromLiveAndDead(amount, Live, Dead, out removing, out detaching);

                    // Add the detaching biomass to total removed and detached
                    Removed.Add(removing);
                    Detached.Add(detaching);

                    // Pass the detaching biomass to surface organic matter model.
                    //TODO: in reality, the dead material is different from the live, so it would be better to add them as separate pools to SurfaceOM
                    surfaceOrganicMatter.Add(detaching.Wt * 10.0, detaching.N * 10.0, 0.0, plant.PlantType, Name);

                    if (writeToSummary)
                    {
                        double totalFractionToRemove = (Removed.Wt + detaching.Wt) * 100.0 / totalBiomass;
                        double toResidue             = detaching.Wt * 100.0 / (Removed.Wt + detaching.Wt);
                        double removedOff            = Removed.Wt * 100.0 / (Removed.Wt + detaching.Wt);
                        summary.WriteMessage(Parent, "Removing " + totalFractionToRemove.ToString("0.0")
                                             + "% of " + Parent.Name.ToLower() + " biomass from " + plant.Name
                                             + ". Of this " + removedOff.ToString("0.0") + "% is removed from the system and "
                                             + toResidue.ToString("0.0") + "% is returned to the surface organic matter.");
                        summary.WriteMessage(Parent, "Removed " + Removed.Wt.ToString("0.0") + " g/m2 of dry matter weight and "
                                             + Removed.N.ToString("0.0") + " g/m2 of N.");
                    }
                    return(remainingLiveFraction);
                }
            }

            return(1.0);
        }
Exemple #14
0
    public override void DoNDemand1Pot(double dltDmPotRue)
    {
        Biomass OldGrowth = Growth;

        Growth.StructuralWt = dltDmPotRue * MathUtility.Divide(Live.Wt, TotalLive.Wt, 0.0);
        Util.Debug("Leaf.Growth.StructuralWt=%f", Growth.StructuralWt);
        Util.CalcNDemand(dltDmPotRue, dltDmPotRue, n_conc_crit, n_conc_max, Growth, Live, Retranslocation.N, 1.0,
                         ref _NDemand, ref NMax);
        Growth.StructuralWt    = 0.0;
        Growth.NonStructuralWt = 0.0;
        Util.Debug("Leaf.NDemand=%f", _NDemand);
        Util.Debug("Leaf.NMax=%f", NMax);
    }
Exemple #15
0
 /// <summary>Clears this instance.</summary>
 private void Clear()
 {
     Live = new Biomass();
     Dead = new Biomass();
     DMSupply.Clear();
     NSupply.Clear();
     DMDemand.Clear();
     NDemand.Clear();
     potentialDMAllocation.Clear();
     Height          = 0;
     LAI             = 0;
     LeafInitialised = false;
 }
Exemple #16
0
        /// <summary>Calculate and return the nitrogen supply (g/m2)</summary>
        public virtual BiomassSupplyType CalculateNitrogenSupply()
        {
            double  LabileN   = Math.Max(0, StartLive.StorageN - StartLive.StorageWt * MinimumNConc.Value());
            Biomass Senescing = new Biomass();

            GetSenescingLeafBiomass(out Senescing);

            nitrogenSupply.Reallocation    = Senescing.StorageN * NReallocationFactor.Value();
            nitrogenSupply.Retranslocation = (LabileN - StartNReallocationSupply) * NRetranslocationFactor.Value();
            nitrogenSupply.Uptake          = 0.0;

            return(nitrogenSupply);
        }
Exemple #17
0
 private void KillLeavesUniformly(double fraction)
 {
     foreach (PerrenialLeafCohort L in Leaves)
     {
         Biomass Loss = new Biomass();
         Loss.SetTo(L.Live);
         Loss.Multiply(fraction);
         L.Dead.Add(Loss);
         L.Live.Subtract(Loss);
         L.AreaDead += L.Area * fraction;
         L.Area     *= (1 - fraction);
     }
 }
Exemple #18
0
 /// <summary>Clears this instance.</summary>
 protected virtual void Clear()
 {
     Live = new Biomass();
     Dead = new Biomass();
     DMSupply.Clear();
     NSupply.Clear();
     DMDemand.Clear();
     NDemand.Clear();
     potentialDMAllocation.Clear();
     Allocated.Clear();
     Senesced.Clear();
     Detached.Clear();
     Removed.Clear();
 }
Exemple #19
0
 protected void OnSimulationCommencing(object sender, EventArgs e)
 {
     DMDemand = new BiomassPoolType();
     DMDemandPriorityFactor            = new BiomassPoolType();
     DMDemandPriorityFactor.Structural = 1.0;
     DMDemandPriorityFactor.Metabolic  = 1.0;
     DMDemandPriorityFactor.Storage    = 1.0;
     NDemand  = new BiomassPoolType();
     DMSupply = new BiomassSupplyType();
     NSupply  = new BiomassSupplyType();
     potentialDMAllocation = new BiomassPoolType();
     Detached = new Biomass();
     Clear();
 }
Exemple #20
0
        protected void OnDoActualPlantGrowth(object sender, EventArgs e)
        {
            if (Plant.IsAlive)
            {
                Biomass Loss = new Biomass();
                Loss.StructuralWt    = Live.StructuralWt * SenescenceRate;
                Loss.NonStructuralWt = Live.NonStructuralWt * SenescenceRate;
                Loss.StructuralN     = Live.StructuralN * SenescenceRate;
                Loss.NonStructuralN  = Live.NonStructuralN * SenescenceRate;

                Live.StructuralWt    -= Loss.StructuralWt;
                Live.NonStructuralWt -= Loss.NonStructuralWt;
                Live.StructuralN     -= Loss.StructuralN;
                Live.NonStructuralN  -= Loss.NonStructuralN;

                Dead.StructuralWt    += Loss.StructuralWt;
                Dead.NonStructuralWt += Loss.NonStructuralWt;
                Dead.StructuralN     += Loss.StructuralN;
                Dead.NonStructuralN  += Loss.NonStructuralN;

                double DetachedFrac = 0;
                if (DetachmentRateFunction != null)
                {
                    DetachedFrac = DetachmentRateFunction.Value;
                }
                if (DetachedFrac > 0.0)
                {
                    double DetachedWt = Dead.Wt * DetachedFrac;
                    double DetachedN  = Dead.N * DetachedFrac;

                    Dead.StructuralWt    *= (1 - DetachedFrac);
                    Dead.StructuralN     *= (1 - DetachedFrac);
                    Dead.NonStructuralWt *= (1 - DetachedFrac);
                    Dead.NonStructuralN  *= (1 - DetachedFrac);
                    Dead.MetabolicWt     *= (1 - DetachedFrac);
                    Dead.MetabolicN      *= (1 - DetachedFrac);

                    if (DetachedWt > 0)
                    {
                        SurfaceOrganicMatter.Add(DetachedWt * 10, DetachedN * 10, 0, Plant.CropType, Name);
                    }
                }

                if (DryMatterContent != null)
                {
                    LiveFWt = Live.Wt / DryMatterContent.Value;
                }
            }
        }
Exemple #21
0
 protected void OnSimulationCommencing(object sender, EventArgs e)
 {
     Live                  = new Biomass();
     Dead                  = new Biomass();
     StartLive             = new Biomass();
     DMDemand              = new BiomassPoolType();
     NDemand               = new BiomassPoolType();
     DMSupply              = new BiomassSupplyType();
     NSupply               = new BiomassSupplyType();
     potentialDMAllocation = new BiomassPoolType();
     Allocated             = new Biomass();
     Senesced              = new Biomass();
     Detached              = new Biomass();
     Removed               = new Biomass();
 }
Exemple #22
0
 /// <summary>Clears this instance.</summary>
 private void Clear()
 {
     Live     = new Biomass();
     Dead     = new Biomass();
     DMDemand = new BiomassPoolType();
     NDemand  = new BiomassPoolType();
     DMSupply = new BiomassSupplyType();
     NSupply  = new BiomassSupplyType();
     potentialDMAllocation = new BiomassPoolType();
     Allocated             = new Biomass();
     Senesced          = new Biomass();
     Detached          = new Biomass();
     Removed           = new Biomass();
     GrowthRespiration = 0;
 }
Exemple #23
0
 void Initialise()
 {
     Senescing       = new Biomass();
     Retranslocation = new Biomass();
     Growth          = new Biomass();
     Detaching       = new Biomass();
     GreenRemoved    = new Biomass();
     SenescedRemoved = new Biomass();
     LeafNo          = new double[max_node];
     LeafNoSen       = new double[max_node];
     LeafArea        = new double[max_node];
     if (CO2 != 350 && (TEModifier == null || NConcCriticalModifier == null))
     {
         throw new Exception("CO2 isn't at the default level, and model: " + Plant.Name + " has no CO2 parameterisations.");
     }
 }
Exemple #24
0
 public override void OnSow(SowPlant2Type Sow)
 {
     SowingInfo = Sow;
     if (LayerLive == null)
     {
         LayerLive = new Biomass[dlayer.Length];
         LayerDead = new Biomass[dlayer.Length];
         for (int i = 0; i < dlayer.Length; i++)
         {
             LayerLive[i] = new Biomass();
             LayerDead[i] = new Biomass();
         }
     }
     DeltaNO3 = new double[dlayer.Length];
     DeltaNH4 = new double[dlayer.Length];
 }
Exemple #25
0
    /// <summary>
    /// Remove some dm. The fraction removed is calculation and put into the RemovedPool so that
    /// later one it can be removed from the actual Pool in the update routine.
    /// Routine was called giveDMGreenRemoved and giveDMSenescedRemoved in old Plant.
    /// </summary>
    internal static Biomass RemoveDM(double delta, Biomass Pool, string OrganName)
    {
        double  fraction    = MathUtility.Divide(delta, Pool.Wt, 0.0);
        Biomass RemovedPool = Pool * fraction;

        double error_margin = 1.0e-6f;

        if (delta > Pool.Wt + error_margin)
        {
            string msg;
            msg  = "Attempting to remove more green " + OrganName + " biomass than available:-\r\n";
            msg += "Removing -" + delta.ToString() + " (g/m2) from " + Pool.Wt.ToString() + " (g/m2) available.";
            throw new Exception(msg);
        }
        return(RemovedPool);
    }
Exemple #26
0
        private Biomass DetachLeaves()
        {
            Detached = new Biomass();
            double LRT = LeafResidenceTime.Value();
            double LDT = LeafDetachmentTime.Value();

            foreach (PerrenialLeafCohort L in Leaves)
            {
                if (L.Age >= (LRT + LDT))
                {
                    Detached.Add(L.Dead);
                }
            }
            Leaves.RemoveAll(L => L.Age >= (LRT + LDT));
            return(Detached);
        }
Exemple #27
0
        /// <summary>Removes biomass from live and dead biomass pools and send to soil</summary>
        /// <param name="biomassRemoveType">Name of event that triggered this biomass remove call.</param>
        /// <param name="removal">The fractions of biomass to remove</param>
        /// <param name="Live">Live biomass pool</param>
        /// <param name="Dead">Dead biomass pool</param>
        /// <param name="Removed">The removed pool to add to.</param>
        /// <param name="Detached">The detached pool to add to.</param>
        public void RemoveBiomassToSoil(string biomassRemoveType, OrganBiomassRemovalType removal,
                                        Biomass[] Live, Biomass[] Dead,
                                        Biomass Removed, Biomass Detached)
        {
            if (removal == null)
            {
                removal = FindDefault(biomassRemoveType);
            }

            //NOTE: roots don't have dead biomass
            double totalFractionToRemove = removal.FractionLiveToRemove + removal.FractionLiveToResidue;

            if (totalFractionToRemove > 0)
            {
                //NOTE: at the moment Root has no Dead pool
                FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[Live.Length];
                double remainingFraction      = 1.0 - (removal.FractionLiveToResidue + removal.FractionLiveToRemove);
                for (int layer = 0; layer < Live.Length; layer++)
                {
                    Biomass removing;
                    Biomass detaching;
                    double  remainingLiveFraction = RemoveBiomassFromLiveAndDead(removal, Live[layer], Dead[layer], out removing, out detaching);

                    // Add the detaching biomass to total removed and detached
                    Removed.Add(removing);
                    Detached.Add(detaching);

                    // Pass the detaching biomass to surface organic matter model.
                    FOMType fom = new FOMType();
                    fom.amount = (float)(detaching.Wt * 10);
                    fom.N      = (float)(detaching.N * 10);
                    fom.C      = (float)(0.40 * detaching.Wt * 10);
                    fom.P      = 0.0;
                    fom.AshAlk = 0.0;

                    FOMLayerLayerType Layer = new FOMLayerLayerType();
                    Layer.FOM        = fom;
                    Layer.CNR        = 0.0;
                    Layer.LabileP    = 0.0;
                    FOMLayers[layer] = Layer;
                }
                FOMLayerType FomLayer = new FOMLayerType();
                FomLayer.Type  = plant.PlantType;
                FomLayer.Layer = FOMLayers;
                IncorpFOM.Invoke(FomLayer);
            }
        }
Exemple #28
0
    public static void CalcNDemand(double dltDm, double dltDmPotRue, double n_conc_crit, double n_conc_max,
                                   Biomass Growth, Biomass Green, double RetranslocationN,
                                   double n_deficit_uptake_fraction,
                                   ref double NDemand, ref double NMax)
    {
        double part_fract = MathUtility.Divide(Growth.Wt, dltDm, 0.0);
        double dlt_dm_pot = dltDmPotRue * part_fract;             // potential dry weight increase (g/m^2)

        dlt_dm_pot = MathUtility.Constrain(dlt_dm_pot, 0.0, dltDmPotRue);

        if (Green.Wt > 0.0)
        {
            // get N demands due to difference between
            // actual N concentrations and critical N concentrations
            double N_crit      = Green.Wt * n_conc_crit;        // critical N amount (g/m^2)
            double N_potential = Green.Wt * n_conc_max;         // maximum N uptake potential (g/m^2)

            // retranslocation is -ve for outflows
            double N_demand_old = N_crit                           // demand for N by old biomass (g/m^2)
                                  - (Green.N + RetranslocationN);
            if (N_demand_old > 0.0)                                // Don't allow demand to satisfy all deficit
            {
                N_demand_old *= n_deficit_uptake_fraction;
            }

            double N_max_old = N_potential                      // N required by old biomass to reach  N_conc_max  (g/m^2)
                               - (Green.N + RetranslocationN);
            if (N_max_old > 0.0)
            {
                N_max_old *= n_deficit_uptake_fraction;             // Don't allow demand to satisfy all deficit
            }
            // get potential N demand (critical N) of potential growth
            double N_demand_new = dlt_dm_pot * n_conc_crit;      // demand for N by new growth (g/m^2)
            double N_max_new    = dlt_dm_pot * n_conc_max;       // N required by new growth to reach N_conc_max  (g/m^2)

            NDemand = N_demand_old + N_demand_new;
            NMax    = N_max_old + N_max_new;

            NDemand = MathUtility.Constrain(NDemand, 0.0, double.MaxValue);
            NMax    = MathUtility.Constrain(NMax, 0.0, double.MaxValue);
        }
        else
        {
            NDemand = NMax = 0.0;
        }
    }
 protected void OnSimulationCommencing(object sender, EventArgs e)
 {
     Live     = new Biomass();
     Dead     = new Biomass();
     DMDemand = new BiomassPoolType();
     DMDemandPriorityFactor            = new BiomassPoolType();
     DMDemandPriorityFactor.Structural = 1.0;
     DMDemandPriorityFactor.Metabolic  = 1.0;
     DMDemandPriorityFactor.Storage    = 1.0;
     NDemand   = new BiomassPoolType();
     DMSupply  = new BiomassSupplyType();
     NSupply   = new BiomassSupplyType();
     Allocated = new Biomass();
     Senesced  = new Biomass();
     Detached  = new Biomass();
     Removed   = new Biomass();
 }
Exemple #30
0
 /// <summary>Clears this instance.</summary>
 protected void Clear()
 {
     Height = 0;
     StartNRetranslocationSupply     = 0;
     StartNReallocationSupply        = 0;
     PotentialDMAllocation           = 0;
     PotentialStructuralDMAllocation = 0;
     PotentialMetabolicDMAllocation  = 0;
     StructuralDMDemand = 0;
     StorageDMDemand    = 0;
     LiveFWt            = 0;
     dryMatterDemand.Clear();
     dryMatterSupply.Clear();
     nitrogenDemand.Clear();
     nitrogenSupply.Clear();
     Detached = new Biomass();
 }
Exemple #31
0
 protected void OnSimulationCommencing(object sender, EventArgs e)
 {
     startLive             = new Biomass();
     DMDemand              = new BiomassPoolType();
     NDemand               = new BiomassPoolType();
     DMSupply              = new BiomassSupplyType();
     NSupply               = new BiomassSupplyType();
     potentialDMAllocation = new BiomassPoolType();
     Allocated             = new Biomass();
     Senesced              = new Biomass();
     Detached              = new Biomass();
     Removed               = new Biomass();
     Height          = 0.0;
     LAI             = 0.0;
     leafInitialised = false;
     Clear();
 }
        //---------------------------------------------------------------------

        // Event handler when a cohort is killed by an age-only disturbance.
        public void CohortKilledByAgeOnlyDisturbance(object                 sender,
                                                     Biomass.DeathEventArgs eventArgs)
        {
            // If this plug-in is not running, then some base disturbance
            // plug-in killed the cohort.
            if (! running)
                return;

            SiteVars.BiomassRemoved[eventArgs.Site] += eventArgs.Cohort.Biomass;
        }
        //---------------------------------------------------------------------

        // Event handler when a cohort is killed by an age-only disturbance.
        public static void CohortKilledByAgeOnlyDisturbance(object                 sender,
                                                     Biomass.DeathEventArgs eventArgs)
        {

            // If this plug-in is not running, then some base disturbance
            // plug-in killed the cohort.
            if (! running)
                return;

            // If this plug-in is running, then the age-only disturbance must
            // be a cohort-selector from Base Harvest.

            int reduction = eventArgs.Cohort.Biomass;
            SiteVars.BiomassRemoved[eventArgs.Site] += reduction;

            //UI.WriteLine("Cohort Biomass removed={0:0.0}; Total Killed={1:0.0}.", reduction, SiteVars.BiomassRemoved[eventArgs.Site]);
            //SiteVars.CohortsPartiallyDamaged[eventArgs.Site]++;
        }
        //---------------------------------------------------------------------
        // This method replaces the delegate method.  It is called every year when
        // ACT_ANPP is calculated, for each cohort.  Therefore, this method is operating at
        // an ANNUAL time step and separate from the normal extension time step.

        public static double DefoliateCohort(Biomass.ICohort cohort, Site site, int siteBiomass)
        {

            //UI.WriteLine("   Calculating insect defoliation...");

            int sppIndex = cohort.Species.Index;
            double totalDefoliation = 0.0;

            foreach(IInsect insect in manyInsect)
            {
                if(!insect.ActiveOutbreak)
                    continue;

                double defoliation = 0.0;
                double weightedDefoliation = 0.0;
                int suscIndex = insect.SppTable[sppIndex].Susceptibility - 1;

                if (suscIndex < 0) suscIndex = 0;

                // Get the Neighborhood GrowthReduction Density
                double meanNeighborhoodDefoliation = 0.0;
                int neighborCnt = 0;

                // If it is the first year, the neighborhood growth reduction
                // will have been initialized in Outbreak.InitializeDefoliationPatches

                if(insect.NeighborhoodDefoliation[site] > 0)
                {
                    //UI.WriteLine("   First Year of Defoliation:  Using initial patch defo={0:0.00}.", SiteVars.NeighborhoodDefoliation[site]);
                    meanNeighborhoodDefoliation = insect.NeighborhoodDefoliation[site];
                }

                // If not the first year, calculate mean neighborhood defoliation based on the
                // previous year.
                else
                {
                    double sumNeighborhoodDefoliation = 0.0;

                    //UI.WriteLine("Look at the Neighbors... ");
                    foreach (RelativeLocation relativeLoc in insect.Neighbors)
                    {
                        Site neighbor = site.GetNeighbor(relativeLoc);
                        if (neighbor != null && neighbor.IsActive)
                        {
                            neighborCnt++;

                            // The previous year...
                            //if(SiteVars.DefoliationByYear[neighbor].ContainsKey(Model.Core.CurrentTime - 1))
                            //    sumNeighborhoodDefoliation += SiteVars.DefoliationByYear[neighbor][Model.Core.CurrentTime - 1];
                            sumNeighborhoodDefoliation += insect.LastYearDefoliation[neighbor];
                        }
                    }

                    if(neighborCnt > 0.0)
                        meanNeighborhoodDefoliation = sumNeighborhoodDefoliation / (double) neighborCnt;

                }  //endif

                if(meanNeighborhoodDefoliation > 1.0 || meanNeighborhoodDefoliation < 0)
                {
                    UI.WriteLine("MeanNeighborhoodDefoliation={0}; NeighborCnt={1}.", meanNeighborhoodDefoliation, neighborCnt);
                    throw new ApplicationException("Error: Mean Neighborhood GrowthReduction is not between 1.0 and 0.0");
                }

                // First assume that there are no neighbors whatsoever:
                DistributionType dist = insect.SusceptibleTable[suscIndex].Distribution_0.Name;
                double value1 = insect.SusceptibleTable[suscIndex].Distribution_0.Value1;
                double value2 = insect.SusceptibleTable[suscIndex].Distribution_0.Value2;

                if(meanNeighborhoodDefoliation <= 1.0 && meanNeighborhoodDefoliation >= 0.8)
                {
                    dist = insect.SusceptibleTable[suscIndex].Distribution_80.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_80.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_80.Value2;
                }
                else if(meanNeighborhoodDefoliation < 0.8 && meanNeighborhoodDefoliation >= 0.6)
                {
                    dist = insect.SusceptibleTable[suscIndex].Distribution_60.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_60.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_60.Value2;
                }
                else if(meanNeighborhoodDefoliation < 0.6 && meanNeighborhoodDefoliation >= 0.4)
                {
                    dist = insect.SusceptibleTable[suscIndex].Distribution_40.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_40.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_40.Value2;
                }
                else if(meanNeighborhoodDefoliation < 0.4 && meanNeighborhoodDefoliation >= 0.2)
                {
                    dist = insect.SusceptibleTable[suscIndex].Distribution_20.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_20.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_20.Value2;
                }
                else if(meanNeighborhoodDefoliation < 0.2 && meanNeighborhoodDefoliation >= 0.0)
                {
                    dist = insect.SusceptibleTable[suscIndex].Distribution_0.Name;
                    value1 = insect.SusceptibleTable[suscIndex].Distribution_0.Value1;
                    value2 = insect.SusceptibleTable[suscIndex].Distribution_0.Value2;
                }

                // Next, ensure that all cohorts of the same susceptibility class
                // receive the same level of defoliation.

                if(insect.HostDefoliationByYear[site].ContainsKey(Model.Core.CurrentTime))
                {
                    if(insect.HostDefoliationByYear[site][Model.Core.CurrentTime][suscIndex] <= 0.00000000)
                    {
                        defoliation = Distribution.GenerateRandomNum(dist, value1, value2);
                        insect.HostDefoliationByYear[site][Model.Core.CurrentTime][suscIndex] = defoliation;
                    }
                    else
                        defoliation = insect.HostDefoliationByYear[site][Model.Core.CurrentTime][suscIndex];
                }
                else
                {
                    insect.HostDefoliationByYear[site].Add(Model.Core.CurrentTime, new Double[3]{0.0, 0.0, 0.0});
                    defoliation = Distribution.GenerateRandomNum(dist, value1, value2);
                    insect.HostDefoliationByYear[site][Model.Core.CurrentTime][suscIndex] = defoliation;
                }


                // Alternatively, allow defoliation to vary even among cohorts and species with
                // the same susceptibility.
                //defoliation = Distribution.GenerateRandomNum(dist, value1, value2);

                if(defoliation > 1.0 || defoliation < 0)
                {
                    UI.WriteLine("DEFOLIATION TOO BIG or SMALL:  {0}, {1}, {2}, {3}.", dist, value1, value2, defoliation);
                    throw new ApplicationException("Error: New defoliation is not between 1.0 and 0.0");
                }

                //UI.WriteLine("Cohort age={0}, species={1}, suscIndex={2}, defoliation={3}.", cohort.Age, cohort.Species.Name, (suscIndex -1), defoliation);
                
                // For first insect in a given year, actual defoliation equals the potential defoliation drawn from insect distributions.
                if (totalDefoliation == 0.0)
                {
                    weightedDefoliation = (defoliation * ((double)cohort.Biomass / (double)siteBiomass));
                    //UI.WriteLine("Cohort age={0}, species={1}, suscIndex={2}, cohortDefoliation={3}.", cohort.Age, cohort.Species.Name, (suscIndex+1), cohortDefoliation);
                }
                // For second insect in a given year, actual defoliation can only be as high as the amount of canopy foliage left by first insect.
                // This change makes sure next year's neighborhoodDefoliation will reflect actual defoliation, rather than "potential" defoliation.
                // It should also ensure that the sum of defoliation maps for all insects adds up to 1 for a given year.
                else
                {
                    weightedDefoliation = (Math.Min((1 - totalDefoliation), defoliation) * ((double)cohort.Biomass / (double)siteBiomass));
                }

                insect.ThisYearDefoliation[site] += weightedDefoliation;

                if (insect.ThisYearDefoliation[site] > 1.0) // Weighted defoliation cannot exceed 100% of site biomass.
                    insect.ThisYearDefoliation[site] = 1.0;

                //Put in error statement to see if sum of weighted defoliation is ever over 1.
                if (insect.ThisYearDefoliation[site] > 1.0 || insect.ThisYearDefoliation[site] < 0)
                {
                    UI.WriteLine("Site Weighted Defoliation = {0:0.000000}.  Site R/C={1}/{2}.  Last Weighted Defoliation = {3}.", insect.ThisYearDefoliation[site], site.Location.Row, site.Location.Column, weightedDefoliation);
                    throw new ApplicationException("Error: Site Weighted Defoliation is not between 1.0 and 0.0");
                }
                totalDefoliation += defoliation; // Is totalDefoliation getting used anywhere else? Or an orphan?
            }

            if(totalDefoliation > 1.0)  // Cannot exceed 100% defoliation, comment out to see if it ever does.
                totalDefoliation = 1.0;

            if(totalDefoliation > 1.0 || totalDefoliation < 0)
            {
                UI.WriteLine("Cohort Total Defoliation = {0:0.00}.  Site R/C={1}/{2}.", totalDefoliation, site.Location.Row, site.Location.Column);
                throw new ApplicationException("Error: Total Defoliation is not between 1.0 and 0.0");
            }


            return totalDefoliation;

        }
Exemple #35
0
        private void OnSimulationCommencing(object sender, EventArgs e)
        {
            SwimIsPresent = swim3 > 0;
            if (SwimIsPresent)
                Summary.WriteMessage(this, "Using SWIM3 for Soil Water Uptake.");

            Senescing = new Biomass();
            Retranslocation = new Biomass();
            Growth = new Biomass();
            Detaching = new Biomass();
            GreenRemoved = new Biomass();
            SenescedRemoved = new Biomass();

            dlt_sw_dep = new double[Soil.Thickness.Length];
            sw_avail = new double[Soil.Thickness.Length];
            sw_avail_pot = new double[Soil.Thickness.Length];
            sw_supply = new double[Soil.Thickness.Length];

            dlt_no3gsm = new double[Soil.Thickness.Length];
            dlt_nh4gsm = new double[Soil.Thickness.Length];
            no3gsm_uptake_pot = new double[Soil.Thickness.Length];
            nh4gsm_uptake_pot = new double[Soil.Thickness.Length];
            dltRootLength = new double[Soil.Thickness.Length];
            dltRootLengthSenesced = new double[Soil.Thickness.Length];
            dltRootLengthDead = new double[Soil.Thickness.Length];
            no3gsm_min = new double[Soil.Thickness.Length];
            nh4gsm_min = new double[Soil.Thickness.Length];
            RootLength = new double[Soil.Thickness.Length];
            RootLengthSenesced = new double[Soil.Thickness.Length];

            SoilCrop soilCrop = Soil.Crop(Plant.Name) as SoilCrop;
            ll = soilCrop.LL;
            kl = soilCrop.KL;
            xf = soilCrop.XF;
            DULmm = MathUtilities.Multiply(Soil.DUL, Soil.Thickness);

            ll_dep = MathUtilities.Multiply(ll, Soil.Thickness);
            Util.ZeroArray(no3gsm_min);
            Util.ZeroArray(nh4gsm_min);
        }
        //---------------------------------------------------------------------
        // This method replaces the delegate method.  It is called every year when
        // ACT_ANPP is calculated, for each cohort.  Therefore, this method is operating at
        // an ANNUAL time step and separate from the normal extension time step.

        public static double ReduceCohortGrowth(Biomass.ICohort cohort, Site site, int siteBiomass)
        {
            //UI.WriteLine("   Calculating cohort growth reduction due to insect defoliation...");

            double summaryGrowthReduction = 0.0;

            int sppIndex = cohort.Species.Index;

            foreach(IInsect insect in PlugIn.ManyInsect)
            {
                if(!insect.ActiveOutbreak)
                    continue;

                int suscIndex = insect.SppTable[sppIndex].Susceptibility - 1;
                //if (suscIndex < 0) suscIndex = 0;

                int yearBack = 0;
                double annualDefoliation = 0.0;

                if(insect.HostDefoliationByYear[site].ContainsKey(Model.Core.CurrentTime - yearBack))
                {
                    //UI.WriteLine("Host Defoliation By Year:  Time={0}, suscIndex={1}, spp={2}.", (Model.Core.CurrentTime - yearBack), suscIndex+1, cohort.Species.Name);
                    annualDefoliation += insect.HostDefoliationByYear[site][Model.Core.CurrentTime - yearBack][suscIndex];
                }
                double cumulativeDefoliation = annualDefoliation;

                while(annualDefoliation > 0)
                {
                    yearBack++;
                    annualDefoliation = 0.0;
                    if(insect.HostDefoliationByYear[site].ContainsKey(Model.Core.CurrentTime - yearBack))
                    {
                        //UI.WriteLine("Host Defoliation By Year:  Time={0}, suscIndex={1}, spp={2}.", (Model.Core.CurrentTime - yearBack), suscIndex+1, cohort.Species.Name);
                        annualDefoliation = insect.HostDefoliationByYear[site][Model.Core.CurrentTime - yearBack][suscIndex];
                        cumulativeDefoliation += annualDefoliation;
                    }
                }

                double slope = insect.SppTable[sppIndex].GrowthReduceSlope;
                double intercept = insect.SppTable[sppIndex].GrowthReduceIntercept;


                double growthReduction = 1.0 - (cumulativeDefoliation * slope + intercept);

                double weightedGD = (growthReduction * ((double) cohort.Biomass / (double) siteBiomass));
                //Below looks like it should be multiplied by weightedGD above, but it isn't?? CHECK!
                summaryGrowthReduction += growthReduction;
                //UI.WriteLine("Time={0}, Spp={1}, SummaryGrowthReduction={2:0.00}.", Model.Core.CurrentTime,cohort.Species.Name, summaryGrowthReduction);

            }
            if (summaryGrowthReduction > 1.0)  // Cannot exceed 100%
                summaryGrowthReduction = 1.0;

            if(summaryGrowthReduction > 1.0 || summaryGrowthReduction < 0)
            {
                UI.WriteLine("Cohort Total Growth Reduction = {0:0.00}.  Site R/C={1}/{2}.", summaryGrowthReduction, site.Location.Row, site.Location.Column);
                throw new ApplicationException("Error: Total Growth Reduction is not between 1.0 and 0.0");
            }

            return summaryGrowthReduction;
        }
Exemple #37
0
        /// <summary>Disposes the detached material.</summary>
        /// <param name="BiomassToDisposeOf">The biomass to dispose of.</param>
        /// <param name="RootLength">Length of the root.</param>
        private void DisposeDetachedMaterial(Biomass BiomassToDisposeOf, double[] RootLength)
        {
            if (BiomassToDisposeOf.Wt > 0.0)
            {
                // DM
                double[] dlt_dm_incorp = RootDist(BiomassToDisposeOf.Wt * Conversions.gm2kg / Conversions.sm2ha, RootLength);

                // Nitrogen
                double[] dlt_N_incorp = RootDist(BiomassToDisposeOf.N * Conversions.gm2kg / Conversions.sm2ha, RootLength);

                // Phosporous
                //double[] dlt_P_incorp = RootDist(BiomassToDisposeOf.P * Conversions.gm2kg / Conversions.sm2ha);

                FOMLayerType IncorpFOMData = new FOMLayerType();
                IncorpFOMData.Type = Plant.CropType;
                Util.Debug("Root.IncorpFOM.Type=%s", IncorpFOMData.Type.ToLower());
                IncorpFOMData.Layer = new FOMLayerLayerType[dlt_dm_incorp.Length];
                for (int i = 0; i != dlt_dm_incorp.Length; i++)
                {
                    IncorpFOMData.Layer[i] = new FOMLayerLayerType();
                    IncorpFOMData.Layer[i].FOM = new FOMType();
                    IncorpFOMData.Layer[i].FOM.amount = (float)dlt_dm_incorp[i];
                    IncorpFOMData.Layer[i].FOM.N = (float)dlt_N_incorp[i];
                    //IncorpFOMData.Layer[i].FOM.P = (float)dlt_P_incorp[i];
                    IncorpFOMData.Layer[i].FOM.C = (float)0.0;
                    IncorpFOMData.Layer[i].FOM.AshAlk = (float)0.0;
                    IncorpFOMData.Layer[i].CNR = 0;
                    IncorpFOMData.Layer[i].LabileP = 0;
                    Util.Debug("Root.IncorpFOM.FOM.amount=%f2", IncorpFOMData.Layer[i].FOM.amount);
                    Util.Debug("Root.IncorpFOM.FOM.N=%f", IncorpFOMData.Layer[i].FOM.N);

                }
                IncorpFOM.Invoke(IncorpFOMData);
            }
            else
            {
                // no roots to incorporate
            }
        }
Exemple #38
0
        /// <summary>Removes biomass from live and dead biomass pools</summary>
        /// <param name="amount">The fractions of biomass to remove</param>
        /// <param name="Live">Live biomass pool</param>
        /// <param name="Dead">Dead biomass pool</param>
        /// <param name="Removed">The removed pool to add to.</param>
        /// <param name="Detached">The detached pool to add to.</param>
        /// <param name="detaching">The amount of detaching material</param>
        private static double RemoveBiomassFromLiveAndDead(OrganBiomassRemovalType amount, Biomass Live, Biomass Dead, out Biomass Removed, Biomass Detached, out Biomass detaching)
        {
            double remainingLiveFraction = 1.0 - (amount.FractionLiveToResidue + amount.FractionLiveToRemove);
            double remainingDeadFraction = 1.0 - (amount.FractionDeadToResidue + amount.FractionDeadToRemove);

            detaching = Live * amount.FractionLiveToResidue + Dead * amount.FractionDeadToResidue;
            Removed = Live * amount.FractionLiveToRemove + Dead * amount.FractionDeadToRemove;
            Detached.Add(detaching);

            Live.Multiply(remainingLiveFraction);
            Dead.Multiply(remainingDeadFraction);
            return remainingLiveFraction;
        }
Exemple #39
0
 private void OnSimulationCommencing(object sender, EventArgs e)
 {
     Senescing = new Biomass();
     Retranslocation = new Biomass();
     Growth = new Biomass();
     Detaching = new Biomass();
     GreenRemoved = new Biomass();
     SenescedRemoved = new Biomass();
     LeafNo = new double[max_node];
     LeafNoSen = new double[max_node];
     LeafArea = new double[max_node];
     if (CO2 != 350 && (TEModifier == null || NConcCriticalModifier == null))
         throw new Exception("CO2 isn't at the default level, and model: " + Plant.Name + " has no CO2 parameterisations.");
 }
Exemple #40
0
        /// <summary>Removes biomass from live and dead biomass pools and send to soil</summary>
        /// <param name="biomassRemoveType">Name of event that triggered this biomass remove call.</param>
        /// <param name="removal">The fractions of biomass to remove</param>
        /// <param name="Live">Live biomass pool</param>
        /// <param name="Dead">Dead biomass pool</param>
        /// <param name="Removed">The removed pool to add to.</param>
        /// <param name="Detached">The detached pool to add to.</param>
        public void RemoveBiomassToSoil(string biomassRemoveType, OrganBiomassRemovalType removal,
                                        Biomass[] Live, Biomass[] Dead,
                                        Biomass Removed, Biomass Detached)
        {
            if (removal == null)
                removal = FindDefault(biomassRemoveType);

            //NOTE: roots don't have dead biomass
            double totalFractionToRemove = removal.FractionLiveToRemove + removal.FractionLiveToResidue;

            if (totalFractionToRemove > 0)
            {
                //NOTE: at the moment Root has no Dead pool
                FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[Live.Length];
                double remainingFraction = 1.0 - (removal.FractionLiveToResidue + removal.FractionLiveToRemove);
                for (int layer = 0; layer < Live.Length; layer++)
                {
                    Biomass detaching;
                    double remainingLiveFraction = RemoveBiomassFromLiveAndDead(removal, Live[layer], Dead[layer], out Removed, Detached, out detaching);

                    FOMType fom = new FOMType();
                    fom.amount = (float)(detaching.Wt * 10);
                    fom.N = (float)(detaching.N * 10);
                    fom.C = (float)(0.40 * detaching.Wt * 10);
                    fom.P = 0.0;
                    fom.AshAlk = 0.0;

                    FOMLayerLayerType Layer = new FOMLayerLayerType();
                    Layer.FOM = fom;
                    Layer.CNR = 0.0;
                    Layer.LabileP = 0.0;
                    FOMLayers[layer] = Layer;
                }
                FOMLayerType FomLayer = new FOMLayerType();
                FomLayer.Type = plant.CropType;
                FomLayer.Layer = FOMLayers;
                IncorpFOM.Invoke(FomLayer);
            }
        }
Exemple #41
0
        /// <summary>Called when [end crop].</summary>
        public void OnEndCrop()
        {
            NewCropType Crop = new NewCropType();
            Crop.crop_type = CropType;
            Crop.sender = Name;
            if (CropEnding != null)
                CropEnding.Invoke(Crop);

            if (PlantEnding != null)
                PlantEnding.Invoke(this, new ModelArgs() { Model = this });

            // Keep track of some variables for reporting.
            Biomass AboveGroundBiomass = new Biomass(AboveGround);
            Biomass BelowGroundBiomass = new Biomass(BelowGround);

            // Call each organ's OnHarvest. They fill a BiomassRemoved structure. We then publish a
            // BiomassRemoved event.
            BiomassRemovedType BiomassRemovedData = new BiomassRemovedType();
            foreach (Organ1 Organ in Organ1s)
                Organ.OnEndCrop(BiomassRemovedData);
            BiomassRemovedData.crop_type = CropType;
            BiomassRemoved.Invoke(BiomassRemovedData);

            string message = string.Format("Organic matter from crop to surface organic matter:-\r\n" +
                                           "  DM tops  (kg/ha) = {0,10:F1}\r\n" +
                                           "  DM roots (kg/ha) = {1,10:F1}\r\n" +
                                           "  N  tops  (kg/ha) = {0,10:F2}\r\n" +
                                           "  N  roots (lh/ha) = {1,10:F2}",
                     AboveGroundBiomass.Wt, BelowGroundBiomass.Wt,
                     AboveGroundBiomass.N, BelowGroundBiomass.N);
            Summary.WriteMessage(this, message);

            cultivarDefinition.Unapply();
            SowingData = null;
        }
Exemple #42
0
        /// <summary>Clears this instance.</summary>
        protected override void Clear()
        {
            base.Clear();
            Uptake = null;
            DeltaNH4 = null;
            DeltaNO3 = null;
            _SenescenceRate = 0;
            Length = 0;
            Depth = 0;

            if (LayerLive == null || LayerLive.Length == 0)
            {
                LayerLive = new Biomass[Soil.Thickness.Length];
                LayerDead = new Biomass[Soil.Thickness.Length];
                for (int i = 0; i < Soil.Thickness.Length; i++)
                {
                    LayerLive[i] = new Biomass();
                    LayerDead[i] = new Biomass();
                }
            }
            else
            {
                for (int i = 0; i < Soil.Thickness.Length; i++)
                {
                    LayerLive[i].Clear();
                    LayerDead[i].Clear();
                }
            }

            DeltaNO3 = new double[Soil.Thickness.Length];
            DeltaNH4 = new double[Soil.Thickness.Length];
        }
Exemple #43
0
        protected void OnDoPotentialPlantGrowth(object sender, EventArgs e)
        {
            if (Plant.IsEmerged)
            {
                SenescenceRate = 0;
                if (SenescenceRateFunction != null) //Default of zero means no senescence
                    SenescenceRate = SenescenceRateFunction.Value;
                _StructuralFraction = 1;
                if (StructuralFraction != null) //Default of 1 means all biomass is structural
                    _StructuralFraction = StructuralFraction.Value;
                InitialWt = 0; //Default of zero means no initial Wt
                if (InitialWtFunction != null)
                    InitialWt = InitialWtFunction.Value;
                InitStutFraction = 1.0; //Default of 1 means all initial DM is structural
                if (InitialStructuralFraction != null)
                    InitStutFraction = InitialStructuralFraction.Value;

                //Initialise biomass and nitrogen
                if (Live.Wt == 0)
                {
                    Live.StructuralWt = InitialWt * InitStutFraction;
                    Live.NonStructuralWt = InitialWt * (1 - InitStutFraction);
                    Live.StructuralN = Live.StructuralWt * MinimumNConc.Value;
                    Live.NonStructuralN = (InitialWt * MaximumNConc.Value) - Live.StructuralN;
                }

                StartLive = Live;
                StartNReallocationSupply = NSupply.Reallocation;
                StartNRetranslocationSupply = NSupply.Retranslocation;
            }
        }
Exemple #44
0
        protected void OnDoActualPlantGrowth(object sender, EventArgs e)
        {
            if (Plant.IsAlive)
            {
                Biomass Loss = new Biomass();
                Loss.StructuralWt = Live.StructuralWt * mySenescenceRate;
                Loss.NonStructuralWt = Live.NonStructuralWt * mySenescenceRate;
                Loss.StructuralN = Live.StructuralN * mySenescenceRate;
                Loss.NonStructuralN = Live.NonStructuralN * mySenescenceRate;

                Live.StructuralWt -= Loss.StructuralWt;
                Live.NonStructuralWt -= Loss.NonStructuralWt;
                Live.StructuralN -= Loss.StructuralN;
                Live.NonStructuralN -= Loss.NonStructuralN;

                Dead.StructuralWt += Loss.StructuralWt;
                Dead.NonStructuralWt += Loss.NonStructuralWt;
                Dead.StructuralN += Loss.StructuralN;
                Dead.NonStructuralN += Loss.NonStructuralN;

                double DetachedFrac = 0;
                if (DetachmentRateFunction != null)
                    DetachedFrac = DetachmentRateFunction.Value;
                if (DetachedFrac > 0.0)
                {
                    double detachingWt = Dead.Wt * DetachedFrac;
                    double detachingN = Dead.N * DetachedFrac;

                    Dead.StructuralWt *= (1 - DetachedFrac);
                    Dead.StructuralN *= (1 - DetachedFrac);
                    Dead.NonStructuralWt *= (1 - DetachedFrac);
                    Dead.NonStructuralN *= (1 - DetachedFrac);
                    Dead.MetabolicWt *= (1 - DetachedFrac);
                    Dead.MetabolicN *= (1 - DetachedFrac);

                    if (detachingWt > 0.0)
                    {
                        DetachedWt += detachingWt;
                        DetachedN += detachingN;
                        SurfaceOrganicMatter.Add(detachingWt * 10, detachingN * 10, 0, Plant.CropType, Name);
                    }
                }

                MaintenanceRespiration = 0;
                //Do Maintenance respiration
                if (MaintenanceRespirationFunction != null)
                {
                    MaintenanceRespiration += Live.MetabolicWt * MaintenanceRespirationFunction.Value;
                    Live.MetabolicWt *= (1 - MaintenanceRespirationFunction.Value);
                    MaintenanceRespiration += Live.NonStructuralWt * MaintenanceRespirationFunction.Value;
                    Live.NonStructuralWt *= (1 - MaintenanceRespirationFunction.Value);
                }

                if (DryMatterContent != null)
                    LiveFWt = Live.Wt / DryMatterContent.Value;
            }
        }
Exemple #45
0
        protected void OnDoPotentialPlantGrowth(object sender, EventArgs e)
        {
            if (Plant.IsEmerged)
            {
                if (MicroClimatePresent == false)
                    throw new Exception(this.Name + " is trying to calculate water demand but no MicroClimate module is present.  Include a microclimate node in your zone");

                Detached.Clear();
                FRGR = FRGRFunction.Value;
                LAI = LAIFunction.Value;
                Height = HeightFunction.Value;
                LAIDead = LaiDeadFunction.Value;

                //Initialise biomass and nitrogen

                Leaves.Add(new PerrenialLeafCohort());
                if (Leaves.Count == 1)
                    AddNewLeafMaterial(StructuralWt: InitialWtFunction.Value,
                                       NonStructuralWt: 0,
                                       StructuralN: InitialWtFunction.Value * MinimumNConc.Value,
                                       NonStructuralN: InitialWtFunction.Value * (MaximumNConc.Value - MinimumNConc.Value));

                foreach (PerrenialLeafCohort L in Leaves)
                    L.Age++;

                StartLive = Live;
                StartNReallocationSupply = NSupply.Reallocation;
                StartNRetranslocationSupply = NSupply.Retranslocation;
            }
        }
        //---------------------------------------------------------------------

        // Event handler when a cohort is killed by an age-only disturbance.
        public void CohortKilledByAgeOnlyDisturbance(object                 sender,
                                                     Biomass.DeathEventArgs eventArgs)
        {
            // If this plug-in is not running, then some base disturbance
            // plug-in killed the cohort.
            if (! running)
                return;

            // If this plug-in is running, then the age-only disturbance must
            // be a cohort-selector from Base Harvest.
            SiteVars.BiomassRemoved[eventArgs.Site] += (int) (eventArgs.Cohort.LeafBiomass + eventArgs.Cohort.WoodBiomass);
            }
Exemple #47
0
        /// <summary>Does the potential growth.</summary>
        /// <param name="TT">The tt.</param>
        /// <param name="LeafCohortParameters">The leaf cohort parameters.</param>
        public virtual void DoPotentialGrowth(double TT, Models.PMF.Organs.Leaf.LeafCohortParameters LeafCohortParameters)
        {
            //Reduce leaf Population in Cohort due to plant mortality
            double StartPopulation = CohortPopulation;
            if (Structure.ProportionPlantMortality > 0)
            {
                CohortPopulation -= CohortPopulation * Structure.ProportionPlantMortality;
            }
            //Reduce leaf Population in Cohort  due to branch mortality
            if ((Structure.ProportionBranchMortality > 0) && (CohortPopulation > Structure.MainStemPopn))  //Ensure we there are some branches.
            {
                double deltaPopn = Math.Min(CohortPopulation * Structure.ProportionBranchMortality, CohortPopulation - Structure.MainStemPopn); //Ensure we are not killing more branches that the cohort has.
                CohortPopulation -= CohortPopulation * Structure.ProportionBranchMortality;
            }
            double PropnStemMortality = (StartPopulation - CohortPopulation) / StartPopulation;

            //Calculate Accumulated Stress Factor for reducing potential leaf size
            if (IsNotAppeared && (LeafCohortParameters.CellDivisionStress != null))
            {
                CellDivisionStressDays += 1;
                CellDivisionStressAccumulation += LeafCohortParameters.CellDivisionStress.Value;
                //FIXME HEB  The limitation below should be used to avoid zero values for maximum leaf size.
                //CellDivisionStressFactor = Math.Max(CellDivisionStressAccumulation / CellDivisionStressDays, 0.01);
                CellDivisionStressFactor = CellDivisionStressAccumulation / CellDivisionStressDays;
            }

            if (IsAppeared)
            {
                // The following line needs to be CHANGED!!!!!!
                //Leaf.CurrentRank = Rank - 1; //Set currentRank variable in parent leaf for use in experssion functions
                //Acellerate thermal time accumulation if crop is water stressed.
                double _ThermalTime;
                if ((LeafCohortParameters.DroughtInducedSenAcceleration != null) && (IsFullyExpanded))
                    _ThermalTime = TT * LeafCohortParameters.DroughtInducedSenAcceleration.Value;
                else _ThermalTime = TT;

                //Leaf area growth parameters
                DeltaPotentialArea = PotentialAreaGrowthFunction(_ThermalTime); //Calculate delta leaf area in the absence of water stress
                DeltaWaterConstrainedArea = DeltaPotentialArea * LeafCohortParameters.ExpansionStress.Value; //Reduce potential growth for water stress

                CoverAbove = Leaf.CoverAboveCohort(Rank); // Calculate cover above leaf cohort (unit??? FIXME-EIT)
                if (LeafCohortParameters.ShadeInducedSenescenceRate != null)
                    ShadeInducedSenRate = LeafCohortParameters.ShadeInducedSenescenceRate.Value;
                SenescedFrac = FractionSenescing(_ThermalTime, PropnStemMortality);

                // Doing leaf mass growth in the cohort
                Biomass LiveBiomass = new Biomass(Live);

                //Set initial leaf status values
                LeafStartArea = LiveArea;
                LiveStart = new Biomass(Live);

                //If the model allows reallocation of senescent DM do it.
                if ((DMReallocationFactor > 0) && (SenescedFrac > 0))
                {
                    // DM to reallocate.

                    LeafStartMetabolicDMReallocationSupply = LiveStart.MetabolicWt * SenescedFrac * DMReallocationFactor;
                    LeafStartNonStructuralDMReallocationSupply = LiveStart.NonStructuralWt * SenescedFrac * DMReallocationFactor;

                    LeafStartDMReallocationSupply = LeafStartMetabolicDMReallocationSupply + LeafStartNonStructuralDMReallocationSupply;
                    LiveBiomass.MetabolicWt -= LeafStartMetabolicDMReallocationSupply;
                    LiveBiomass.NonStructuralWt -= LeafStartNonStructuralDMReallocationSupply;

                }
                else
                {
                    LeafStartMetabolicDMReallocationSupply = LeafStartNonStructuralDMReallocationSupply = LeafStartDMReallocationSupply = 0;
                }

                LeafStartDMRetranslocationSupply = LiveBiomass.NonStructuralWt * DMRetranslocationFactor;
                //Nretranslocation is that which occurs before uptake (senessed metabolic N and all non-structuralN)
                LeafStartMetabolicNReallocationSupply = SenescedFrac * LiveBiomass.MetabolicN * NReallocationFactor;
                LeafStartNonStructuralNReallocationSupply = SenescedFrac * LiveBiomass.NonStructuralN * NReallocationFactor;
                //Retranslocated N is only that which occurs after N uptake. Both Non-structural and metabolic N are able to be retranslocated but metabolic N will only be moved if remobilisation of non-structural N does not meet demands
                LeafStartMetabolicNRetranslocationSupply = Math.Max(0.0, (LiveBiomass.MetabolicN * NRetranslocationFactor) - LeafStartMetabolicNReallocationSupply);
                LeafStartNonStructuralNRetranslocationSupply = Math.Max(0.0, (LiveBiomass.NonStructuralN * NRetranslocationFactor) - LeafStartNonStructuralNReallocationSupply);
                LeafStartNReallocationSupply = NReallocationSupply;
                LeafStartNRetranslocationSupply = NRetranslocationSupply;

                //zero locals variables
                //StructuralDMDemand = 0;
                //MetabolicDMDemand = 0;
                //StructuralNDemand = 0;
                //MetabolicNDemand = 0;
                //NonStructuralNDemand = 0;
                PotentialStructuralDMAllocation = 0;
                PotentialMetabolicDMAllocation = 0;
                DMRetranslocated = 0;
                MetabolicNReallocated = 0;
                NonStructuralNReallocated = 0;
                MetabolicWtReallocated = 0;
                NonStructuralWtReallocated = 0;
                MetabolicNRetranslocated = 0;
                NonStructuralNRetrasnlocated = 0;
                MetabolicNAllocation = 0;
                StructuralDMAllocation = 0;
                MetabolicDMAllocation = 0;
            }
        }
Exemple #48
0
            /// <summary>Clears this instance.</summary>
            public void Clear()
            {
                Uptake = null;
                NitUptake = null;
                DeltaNO3 = new double[soil.Thickness.Length];
                DeltaNH4 = new double[soil.Thickness.Length];

                Length = 0.0;
                Depth = 0.0;

                if (LayerLive == null || LayerLive.Length == 0)
                {
                    LayerLive = new Biomass[soil.Thickness.Length];
                    LayerDead = new Biomass[soil.Thickness.Length];
                    for (int i = 0; i < soil.Thickness.Length; i++)
                    {
                        LayerLive[i] = new Biomass();
                        LayerDead[i] = new Biomass();
                    }
                }
                else
                {
                    for (int i = 0; i < soil.Thickness.Length; i++)
                    {
                        LayerLive[i].Clear();
                        LayerDead[i].Clear();
                    }
                }
            }
Exemple #49
0
 private void DetachLeaves(out Biomass Detached)
 {
     Detached = new Biomass();
     foreach (PerrenialLeafCohort L in Leaves)
         if (L.Age >= (LeafResidenceTime.Value+ LeafDetachmentTime.Value))
             Detached.Add(L.Dead);
     Leaves.RemoveAll(L => L.Age >= (LeafResidenceTime.Value + LeafDetachmentTime.Value));
 }
Exemple #50
0
 private void KillLeavesUniformly(double fraction)
 {
     foreach (PerrenialLeafCohort L in Leaves)
     {
         Biomass Loss = new Biomass();
         Loss.SetTo(L.Live);
         Loss.Multiply(fraction);
         L.Dead.Add(Loss);
         L.Live.Subtract(Loss);
     }
 }
Exemple #51
0
 private void GetSenescingLeafBiomass(out Biomass Senescing)
 {
     Senescing = new Biomass();
     foreach (PerrenialLeafCohort L in Leaves)
         if (L.Age >= LeafResidenceTime.Value)
             Senescing.Add(L.Live);
 }
Exemple #52
0
        protected void OnDoPotentialPlantGrowth(object sender, EventArgs e)
        {
            if (Plant.IsEmerged)
            {
                mySenescenceRate = 0;
                if (SenescenceRate != null) //Default of zero means no senescence
                    mySenescenceRate = SenescenceRate.Value;

                //Initialise biomass and nitrogen
                if (Live.Wt == 0)
                {
                    Live.StructuralWt = InitialWtFunction.Value;
                    Live.NonStructuralWt = 0.0;
                    Live.StructuralN = Live.StructuralWt * MinimumNConc.Value;
                    Live.NonStructuralN = (InitialWtFunction.Value * MaximumNConc.Value) - Live.StructuralN;
                }

                StartLive = Live;
                StartNReallocationSupply = NSupply.Reallocation;
                StartNRetranslocationSupply = NSupply.Retranslocation;
            }
        }
Exemple #53
0
 protected void OnSimulationCommencing(object sender, EventArgs e)
 {
     Detached = new Biomass();
     Removed = new Biomass();
     Clear();
 }
Exemple #54
0
 private void OnSimulationCommencing(object sender, EventArgs e)
 {
     Senescing = new Biomass();
     Retranslocation = new Biomass();
     Growth = new Biomass();
     Detaching = new Biomass();
     GreenRemoved = new Biomass();
     SenescedRemoved = new Biomass();
 }
Exemple #55
0
        protected void OnDoActualPlantGrowth(object sender, EventArgs e)
        {
            if (Plant.IsAlive)
            {
                Biomass Loss = new Biomass();
                Loss.StructuralWt = Live.StructuralWt * SenescenceRate;
                Loss.NonStructuralWt = Live.NonStructuralWt * SenescenceRate;
                Loss.StructuralN = Live.StructuralN * SenescenceRate;
                Loss.NonStructuralN = Live.NonStructuralN * SenescenceRate;

                Live.StructuralWt -= Loss.StructuralWt;
                Live.NonStructuralWt -= Loss.NonStructuralWt;
                Live.StructuralN -= Loss.StructuralN;
                Live.NonStructuralN -= Loss.NonStructuralN;

                Dead.StructuralWt += Loss.StructuralWt;
                Dead.NonStructuralWt += Loss.NonStructuralWt;
                Dead.StructuralN += Loss.StructuralN;
                Dead.NonStructuralN += Loss.NonStructuralN;

                double DetachedFrac = 0;
                if (DetachmentRateFunction != null)
                    DetachedFrac = DetachmentRateFunction.Value;
                if (DetachedFrac > 0.0)
                {
                    double DetachedWt = Dead.Wt * DetachedFrac;
                    double DetachedN = Dead.N * DetachedFrac;

                    Dead.StructuralWt *= (1 - DetachedFrac);
                    Dead.StructuralN *= (1 - DetachedFrac);
                    Dead.NonStructuralWt *= (1 - DetachedFrac);
                    Dead.NonStructuralN *= (1 - DetachedFrac);
                    Dead.MetabolicWt *= (1 - DetachedFrac);
                    Dead.MetabolicN *= (1 - DetachedFrac);

                    if (DetachedWt > 0)
                        SurfaceOrganicMatter.Add(DetachedWt * 10, DetachedN * 10, 0, Plant.CropType, Name);
                }

                if ((DryMatterContent != null) && (Live.Wt != 0))
                    LiveFWt = Live.Wt / DryMatterContent.Value;
            }
        }