Exemple #1
0
        /// <summary>Adds a given amount of detached root material (DM and N) to the soil's FOM pool.</summary>
        /// <param name="amountDM">The DM amount to send (kg/ha)</param>
        /// <param name="amountN">The N amount to send (kg/ha)</param>
        public override void DetachBiomass(double amountDM, double amountN)
        {
            if (amountDM + amountN > 0.0)
            {
                FOMLayerLayerType[] FOMdataLayer = new FOMLayerLayerType[nLayers];
                for (int layer = 0; layer < nLayers; layer++)
                {
                    FOMType fomData = new FOMType();
                    fomData.amount = amountDM * FractionWt[layer];
                    fomData.N      = amountN * FractionWt[layer];
                    fomData.C      = amountDM * CarbonFractionInDM * FractionWt[layer];
                    fomData.P      = 0.0; // P not considered here
                    fomData.AshAlk = 0.0; // Ash not considered here

                    FOMLayerLayerType layerData = new FOMLayerLayerType();
                    layerData.FOM     = fomData;
                    layerData.CNR     = 0.0; // not used here
                    layerData.LabileP = 0.0; // not used here

                    FOMdataLayer[layer] = layerData;
                }

                FOMLayerType FOMData = new FOMLayerType();
                FOMData.Type  = speciesName;
                FOMData.Layer = FOMdataLayer;
                nutrientModel.DoIncorpFOM(FOMData);
            }
        }
Exemple #2
0
        /// <summary>Adds a given amount of detached root material (DM and N) to the soil's FOM pool, per layer.</summary>
        /// <param name="amountDM">The DM amount to detach (kg/ha).</param>
        /// <param name="amountN">The N amount to detach (kg/ha).</param>
        public void DetachBiomass(double[] amountDM, double[] amountN)
        {
            if (amountDM.Sum() + amountN.Sum() > 0.0)
            {
                FOMLayerLayerType[] FOMdataLayer = new FOMLayerLayerType[dmByLayer.Length];
                for (int layer = 0; layer < dmByLayer.Length; layer++)
                {
                    FOMType fomData = new FOMType();
                    fomData.amount = amountDM[layer];
                    fomData.N      = amountN[layer];
                    fomData.C      = fomData.amount * carbonFractionInDM;
                    fomData.P      = 0.0; // P not considered here
                    fomData.AshAlk = 0.0; // Ash not considered here

                    FOMLayerLayerType layerData = new FOMLayerLayerType();
                    layerData.FOM     = fomData;
                    layerData.CNR     = 0.0; // not used here
                    layerData.LabileP = 0.0; // not used here

                    FOMdataLayer[layer] = layerData;
                }

                FOMLayerType FOMData = new FOMLayerType();
                FOMData.Type  = species.Name;
                FOMData.Layer = FOMdataLayer;
                nutrient.DoIncorpFOM(FOMData);
            }
        }
Exemple #3
0
    public override void OnEndCrop()
    {
        FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[dlayer.Length];

        for (int layer = 0; layer < dlayer.Length; layer++)
        {
            double DM = (LayerLive[layer].Wt + LayerDead[layer].Wt) * 10.0;
            double N  = (LayerLive[layer].N + LayerDead[layer].N) * 10.0;

            FOMType fom = new FOMType();
            fom.amount = (float)DM;
            fom.N      = (float)N;
            fom.C      = (float)(0.40 * DM);
            fom.P      = 0;
            fom.AshAlk = 0;

            FOMLayerLayerType Layer = new FOMLayerLayerType();
            Layer.FOM     = fom;
            Layer.CNR     = 0;
            Layer.LabileP = 0;

            FOMLayers[layer] = Layer;
        }
        FOMLayerType FomLayer = new FOMLayerType();

        FomLayer.Type  = Plant.CropType;
        FomLayer.Layer = FOMLayers;
        IncorpFOM.Invoke(FomLayer);
    }
Exemple #4
0
        private void OnPlantEnding(object sender, EventArgs e)
        {
            if (sender == Plant)
            {
                FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[Soil.Thickness.Length];

                for (int layer = 0; layer < Soil.Thickness.Length; layer++)
                {
                    double DM = (LayerLive[layer].Wt + LayerDead[layer].Wt) * 10.0;
                    double N  = (LayerLive[layer].N + LayerDead[layer].N) * 10.0;

                    FOMType fom = new FOMType();
                    fom.amount = (float)DM;
                    fom.N      = (float)N;
                    fom.C      = (float)(0.40 * DM);
                    fom.P      = 0;
                    fom.AshAlk = 0;

                    FOMLayerLayerType Layer = new FOMLayerLayerType();
                    Layer.FOM     = fom;
                    Layer.CNR     = 0;
                    Layer.LabileP = 0;

                    FOMLayers[layer] = Layer;
                }
                FOMLayerType FomLayer = new FOMLayerType();
                FomLayer.Type  = Plant.CropType;
                FomLayer.Layer = FOMLayers;
                IncorpFOM.Invoke(FomLayer);
            }
        }
Exemple #5
0
    public override void DoActualGrowth()
    {
        base.DoActualGrowth();

        // Do Root Front Advance
        int    RootLayer = LayerIndex(Depth);
        double TEM       = (TemperatureEffect == null)? 1: TemperatureEffect.Value;

        Depth = Depth + RootFrontVelocity.Value * xf[RootLayer] * TEM;
        if (!(MaximumRootDepth == null))
        {
            Depth = Math.Min(Depth, MaximumRootDepth.Value);
        }
        double MaxDepth = 0;

        for (int i = 0; i < dlayer.Length; i++)
        {
            if (xf[i] > 0)
            {
                MaxDepth += dlayer[i];
            }
        }

        Depth = Math.Min(Depth, MaxDepth);

        // Do Root Senescence
        FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[dlayer.Length];

        for (int layer = 0; layer < dlayer.Length; layer++)
        {
            double DM = LayerLive[layer].Wt * _SenescenceRate * 10.0;
            double N  = LayerLive[layer].StructuralN * _SenescenceRate * 10.0;
            LayerLive[layer].StructuralWt    *= (1.0 - _SenescenceRate);
            LayerLive[layer].NonStructuralWt *= (1.0 - _SenescenceRate);
            LayerLive[layer].StructuralN     *= (1.0 - _SenescenceRate);
            LayerLive[layer].NonStructuralN  *= (1.0 - _SenescenceRate);



            FOMType fom = new FOMType();
            fom.amount = (float)DM;
            fom.N      = (float)N;
            fom.C      = (float)(0.40 * DM);
            fom.P      = 0;
            fom.AshAlk = 0;

            FOMLayerLayerType Layer = new FOMLayerLayerType();
            Layer.FOM     = fom;
            Layer.CNR     = 0;
            Layer.LabileP = 0;

            FOMLayers[layer] = Layer;
        }
        FOMLayerType FomLayer = new FOMLayerType();

        FomLayer.Type  = Plant.CropType;
        FomLayer.Layer = FOMLayers;
        IncorpFOM.Invoke(FomLayer);
    }
Exemple #6
0
        private void OnDoActualPlantGrowth(object sender, EventArgs e)
        {
            if (Plant.IsAlive)
            {
                // Do Root Front Advance
                int    RootLayer = LayerIndex(Depth);
                double TEM       = (TemperatureEffect == null) ? 1 : TemperatureEffect.Value;

                Depth = Depth + RootFrontVelocity.Value * soilCrop.XF[RootLayer] * TEM;
                double MaxDepth = 0;
                for (int i = 0; i < Soil.Thickness.Length; i++)
                {
                    if (soilCrop.XF[i] > 0)
                    {
                        MaxDepth += Soil.Thickness[i];
                    }
                }

                Depth = Math.Min(Depth, MaxDepth);

                // Do Root Senescence
                FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[Soil.Thickness.Length];

                for (int layer = 0; layer < Soil.Thickness.Length; layer++)
                {
                    double DM = LayerLive[layer].Wt * _SenescenceRate * 10.0;
                    double N  = LayerLive[layer].StructuralN * _SenescenceRate * 10.0;
                    LayerLive[layer].StructuralWt    *= (1.0 - _SenescenceRate);
                    LayerLive[layer].NonStructuralWt *= (1.0 - _SenescenceRate);
                    LayerLive[layer].StructuralN     *= (1.0 - _SenescenceRate);
                    LayerLive[layer].NonStructuralN  *= (1.0 - _SenescenceRate);



                    FOMType fom = new FOMType();
                    fom.amount = (float)DM;
                    fom.N      = (float)N;
                    fom.C      = (float)(0.40 * DM);
                    fom.P      = 0;
                    fom.AshAlk = 0;

                    FOMLayerLayerType Layer = new FOMLayerLayerType();
                    Layer.FOM     = fom;
                    Layer.CNR     = 0;
                    Layer.LabileP = 0;

                    FOMLayers[layer] = Layer;
                }
                FOMLayerType FomLayer = new FOMLayerType();
                FomLayer.Type  = Plant.CropType;
                FomLayer.Layer = FOMLayers;
                IncorpFOM.Invoke(FomLayer);
            }
        }
Exemple #7
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 #8
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 #9
0
    private void DoRootGrowth(double Allocation)
    {
        int RootLayer = LayerIndex(RootDepth);

        RootDepth = RootDepth + RootFrontVelocity.Value * xf[RootLayer];
        RootDepth = Math.Min(MaximumRootDepth, RootDepth);
        RootDepth = Math.Min(MathUtility.Sum(dlayer), RootDepth);

        // Calculate Root Activity Values for water and nitrogen
        double[] RAw      = new double[dlayer.Length];
        double[] RAn      = new double[dlayer.Length];
        double   TotalRAw = 0;
        double   TotalRAn = 0;

        for (int layer = 0; layer < dlayer.Length; layer++)
        {
            if (layer <= LayerIndex(RootDepth))
            {
                if (Roots[layer].Mass > 0)
                {
                    RAw[layer] = SWUptake[layer] / Roots[layer].Mass
                                 * dlayer[layer]
                                 * RootProportion(layer, RootDepth);
                    RAw[layer] = Math.Max(RAw[layer], 1e-20); // Make sure small numbers to avoid lack of info for partitioning

                    RAn[layer] = NUptake[layer] / Roots[layer].Mass
                                 * dlayer[layer]
                                 * RootProportion(layer, RootDepth);
                    RAn[layer] = Math.Max(RAw[layer], 1e-10); // Make sure small numbers to avoid lack of info for partitioning
                }
                else if (layer > 0)
                {
                    RAw[layer] = RAw[layer - 1];
                    RAn[layer] = RAn[layer - 1];
                }
                else
                {
                    RAw[layer] = 0;
                    RAn[layer] = 0;
                }
            }
            TotalRAw += RAw[layer];
            TotalRAn += RAn[layer];
        }
        double allocated = 0;

        for (int layer = 0; layer < dlayer.Length; layer++)
        {
            if (TotalRAw > 0)
            {
                Roots[layer].Mass += Allocation * RAw[layer] / TotalRAw;
            }
            else if (Allocation > 0)
            {
                throw new Exception("Error trying to partition root biomass");
            }
            allocated += Allocation * RAw[layer] / TotalRAw;
        }



        // Do Root Senescence
        FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[dlayer.Length];

        for (int layer = 0; layer < dlayer.Length; layer++)
        {
            double Fr = RootSenescenceRate.Value;
            double DM = Roots[layer].Mass * Fr * 10.0;
            double N  = Roots[layer].N * Fr * 10.0;
            Roots[layer].Mass   *= (1.0 - Fr);
            Roots[layer].N      *= (1.0 - Fr);
            Roots[layer].Length *= (1.0 - Fr);


            FOMType fom = new FOMType();
            fom.amount = (float)DM;
            fom.N      = (float)N;
            fom.C      = (float)(0.44 * DM);
            fom.P      = 0;
            fom.AshAlk = 0;

            FOMLayerLayerType Layer = new FOMLayerLayerType();
            Layer.FOM     = fom;
            Layer.CNR     = 0;
            Layer.LabileP = 0;

            FOMLayers[layer] = Layer;
        }
        FOMLayerType FomLayer = new FOMLayerType();

        FomLayer.Type  = Crop_Type;
        FomLayer.Layer = FOMLayers;
        IncorpFOM.Invoke(FomLayer);
    }