示例#1
0
        /// <summary>
        /// Return the removal
        /// </summary>
        /// <param name="forage">The forage</param>
        /// <param name="units">The units</param>
        /// <returns>The grazing outputs/consumed</returns>
        public GrazType.GrazingOutputs ReturnRemoval(ForageInfo forage, string units)
        {
            double area;
            double scale;
            int    idxClass;
            int    idxSpecies;
            int    idxRipe;

            GrazType.GrazingOutputs result = new GrazType.GrazingOutputs();

            if (forage != null)
            {
                result = forage.RemovalKG;
                area   = forage.InPaddock.Area;
            }
            else
            {
                result = new GrazType.GrazingOutputs();
                area   = 0.0;
            }

            if (area > 0.0)
            {
                if (units == "kg")
                {
                    scale = 1.0;
                }
                else if (units == "g/m^2")
                {
                    scale = 0.10 / area;
                }
                else if (units == "kg/ha")
                {
                    scale = 1.0 / area;
                }
                else
                {
                    throw new Exception("Stock: Unit (" + units + ") not recognised");
                }

                if (scale != 1.0)
                {
                    for (idxClass = 1; idxClass <= GrazType.DigClassNo; idxClass++)
                    {
                        result.Herbage[idxClass] = scale * result.Herbage[idxClass];
                    }
                    for (idxSpecies = 1; idxSpecies <= GrazType.MaxPlantSpp; idxSpecies++)
                    {
                        for (idxRipe = GrazType.UNRIPE; idxRipe <= GrazType.RIPE; idxRipe++)
                        {
                            result.Seed[idxSpecies, idxRipe] = scale * result.Seed[idxSpecies, idxRipe];
                        }
                    }
                }
            }
            return(result);
        }
示例#2
0
        /// <summary>
        /// The herbage is removed from the plant/agpasture
        /// </summary>
        public void RemoveHerbageFromPlant()
        {
            string chemType  = string.Empty;
            int    forageIdx = 0;

            ForageInfo forage = this.ForageByIndex(forageIdx);

            while (forage != null)
            {
                double area = forage.InPaddock.Area;
                GrazType.GrazingOutputs removed = forage.RemovalKG;

                // total the amount removed kg/ha
                double totalRemoved = 0.0;
                for (int i = 0; i < removed.Herbage.Length; i++)
                {
                    totalRemoved += removed.Herbage[i];
                }
                double propnRemoved = Math.Min(1.0, (totalRemoved / area) / (forage.TotalLive + forage.TotalDead + GrazType.Ungrazeable * 10.0)); //  calculations in kg /ha, needs more checking, would be good to use a variable for the unit conversion on ungrazeable

                // calculations of proportions each organ of the total plant removed (in the native units)
                double totalDM = 0;
                foreach (IOrganDamage organ in ForageObj.Organs)
                {
                    if (organ.IsAboveGround && (organ.Live.Wt + organ.Dead.Wt) > 0)
                    {
                        totalDM += organ.Live.Wt + organ.Dead.Wt;
                    }
                }
                double amountRemoved  = 0;
                double amountToRemove = propnRemoved * totalDM;
                foreach (IOrganDamage organ in ForageObj.Organs)
                {
                    if (organ.IsAboveGround && (organ.Live.Wt + organ.Dead.Wt) > 0)
                    {
                        double propnOfPlantDM        = (organ.Live.Wt + organ.Dead.Wt) / totalDM;
                        double amountOfOrganToRemove = propnOfPlantDM * amountToRemove;
                        double prpnOfOrganToRemove   = amountOfOrganToRemove / (organ.Live.Wt + organ.Dead.Wt);
                        prpnOfOrganToRemove = Math.Min(prpnOfOrganToRemove, 1.0);
                        PMF.OrganBiomassRemovalType removal = new PMF.OrganBiomassRemovalType();
                        removal.FractionDeadToRemove = prpnOfOrganToRemove;
                        removal.FractionLiveToRemove = prpnOfOrganToRemove;
                        ForageObj.RemoveBiomass(organ.Name, "Graze", removal);

                        amountRemoved += amountOfOrganToRemove;
                    }
                }
                if (!APSIM.Shared.Utilities.MathUtilities.FloatsAreEqual(amountRemoved, amountToRemove))
                {
                    throw new Exception("Mass balance check fail in Stock. The amount of biomass removed from the plant does not equal the amount of forage the animals consumed.");
                }

                forageIdx++;
                forage = this.ForageByIndex(forageIdx);
            }
        }
示例#3
0
        /// <summary>
        /// The herbage is removed from the plant/agpasture
        /// </summary>
        public void RemoveHerbageFromPlant()
        {
            string chemType  = string.Empty;
            int    forageIdx = 0;

            ForageInfo forage = this.ForageByIndex(forageIdx);

            while (forage != null)
            {
                double area = forage.InPaddock.Area;
                GrazType.GrazingOutputs removed = forage.RemovalKG;

                // total the amount removed kg/ha
                double totalRemoved = 0.0;
                for (int i = 0; i < removed.Herbage.Length; i++)
                {
                    totalRemoved += removed.Herbage[i];
                }
                double propnRemoved = Math.Min(1.0, (totalRemoved / area) / (forage.TotalLive + forage.TotalDead + GrazType.Ungrazeable * 10.0)); //  calculations in kg /ha, needs more checking, would be good to use a variable for the unit conversion on ungrazeable

                // calculations of proportions each organ of the total plant removed (in the native units)
                double totalDM = 0;
                foreach (IOrganDamage organ in ForageObj.Organs)
                {
                    if (organ.IsAboveGround && (organ.Live.Wt + organ.Dead.Wt) > 0)
                    {
                        totalDM += organ.Live.Wt + organ.Dead.Wt;
                    }
                }

                foreach (IOrganDamage organ in ForageObj.Organs)
                {
                    if (organ.IsAboveGround && (organ.Live.Wt + organ.Dead.Wt) > 0)
                    {
                        double propnOfPlantDM = (organ.Live.Wt + organ.Dead.Wt) / totalDM;
                        double prpnToRemove   = propnRemoved * propnOfPlantDM;
                        prpnToRemove = Math.Min(prpnToRemove, 1.0);
                        PMF.OrganBiomassRemovalType removal = new PMF.OrganBiomassRemovalType();
                        removal.FractionDeadToRemove = prpnToRemove;
                        removal.FractionLiveToRemove = prpnToRemove;
                        ForageObj.RemoveBiomass(organ.Name, "Graze", removal);
                    }
                }

                forageIdx++;
                forage = this.ForageByIndex(forageIdx);
            }
        }
示例#4
0
        /// <summary>
        /// The herbage is removed from the plant/agpasture
        /// </summary>
        public void RemoveHerbageFromPlant()
        {
            string chemType  = string.Empty;
            int    forageIdx = 0;

            ForageInfo forage = this.ForageByIndex(forageIdx);

            while (forage != null)
            {
                double area = forage.InPaddock.Area;
                GrazType.GrazingOutputs removed = forage.RemovalKG;

                // total the amount removed kg/ha
                double totalRemoved = 0.0;
                for (int i = 0; i < removed.Herbage.Length; i++)
                {
                    totalRemoved += removed.Herbage[i];
                }
                double propnRemoved = Math.Min(1.0, (totalRemoved / area) / (forage.TotalLive + forage.TotalDead + GrazType.Ungrazeable * 10.0)); //  calculations in kg /ha, needs more checking, would be good to use a variable for the unit conversion on ungrazeable

                // calculations of proportions each organ of the total plant removed (in the native units)
                double totalDM      = ForageObj.Material.Sum(m => m.Total.Wt);
                double consumableDM = ForageObj.Material.Sum(m => m.Consumable.Wt);

                double amountRemoved  = 0;
                double amountToRemove = propnRemoved * consumableDM;
                var    liveMaterial   = ForageObj.Material.Where(m => m.IsLive).ToList();
                foreach (var live in liveMaterial)
                {
                    // Find corresponding dead material
                    var dead = ForageObj.Material.FirstOrDefault(m => !m.IsLive && m.Name == live.Name);
                    if (dead == null)
                    {
                        throw new Exception($"Cannot find dead material for {live.Name}.");
                    }

                    if (live.Total.Wt + dead.Total.Wt > 0)
                    {
                        double propnOfPlantDM        = (live.Total.Wt + dead.Total.Wt) / totalDM;
                        double amountOfOrganToRemove = propnOfPlantDM * amountToRemove;
                        double prpnOfOrganToRemove   = amountOfOrganToRemove / (live.Total.Wt + dead.Total.Wt);
                        prpnOfOrganToRemove = Math.Min(prpnOfOrganToRemove, 1.0);
                        PMF.OrganBiomassRemovalType removal = new PMF.OrganBiomassRemovalType();
                        removal.FractionDeadToRemove = prpnOfOrganToRemove;
                        removal.FractionLiveToRemove = prpnOfOrganToRemove;
                        ForageObj.RemoveBiomass(live.Name, removal);

                        amountRemoved += amountOfOrganToRemove;
                    }
                }
                if (liveMaterial.Count == 0)
                {
                    var deadMaterial = ForageObj.Material.Where(m => !m.IsLive).ToList();
                    foreach (var dead in deadMaterial)
                    {
                        // This can happen for surface organic matter which only has dead material.
                        double propnOfPlantDM        = dead.Total.Wt / totalDM;
                        double amountOfOrganToRemove = propnOfPlantDM * amountToRemove;
                        double prpnOfOrganToRemove   = MathUtilities.Divide(amountOfOrganToRemove, dead.Total.Wt, 0);
                        prpnOfOrganToRemove = Math.Min(prpnOfOrganToRemove, 1.0);
                        PMF.OrganBiomassRemovalType removal = new PMF.OrganBiomassRemovalType();
                        removal.FractionDeadToRemove = prpnOfOrganToRemove;
                        ForageObj.RemoveBiomass(dead.Name, removal);

                        amountRemoved += amountOfOrganToRemove;
                    }
                }

                if (!APSIM.Shared.Utilities.MathUtilities.FloatsAreEqual(amountRemoved, amountToRemove))
                {
                    throw new Exception("Mass balance check fail in Stock. The amount of biomass removed from the plant does not equal the amount of forage the animals consumed.");
                }

                forageIdx++;
                forage = this.ForageByIndex(forageIdx);
            }
        }