예제 #1
0
        /// <summary>
        /// Use the GrazingInputs to initialise the forage object
        /// </summary>
        /// <param name="forage">The forage object</param>
        /// <param name="grazingInput">The grazing inputs</param>
        /// <param name="units">The units</param>
        public void PassGrazingInputs(ForageInfo forage, GrazType.GrazingInputs grazingInput, string units)
        {
            double scaleInput;

            if (units == "kg/ha")                                                     // Convert to kg/ha
            {
                scaleInput = 1.0;
            }
            else if (units == "g/m^2")
            {
                scaleInput = 10.0;
            }
            else
            {
                throw new Exception("Stock: Unit (" + units + ") not recognised");
            }

            if (forage != null)
            {
                forage.SetAvailForage(GrazType.ScaleGrazingInputs(grazingInput, scaleInput));
            }
            else
            {
                throw new Exception("Stock: Forage not recognised");
            }
        }
예제 #2
0
        /// <summary>
        /// Populate the dry matter pool
        /// </summary>
        /// <param name="model">The stock model</param>
        /// <param name="propCode">The property code</param>
        /// <param name="useYoung">For young</param>
        /// <param name="useAll">For all groups</param>
        /// <param name="useTag">For tag number</param>
        /// <param name="poolValues">The DM pool value returned</param>
        /// <returns>True if the propCode is valid</returns>
        public static bool PopulateDMPoolValue(StockList model, int propCode, bool useYoung, bool useAll, bool useTag, ref DMPoolHead[] poolValues)
        {
            int         numPasses;
            AnimalGroup animalGroup;

            GrazType.DM_Pool pool      = new GrazType.DM_Pool();
            GrazType.DM_Pool totalPool = new GrazType.DM_Pool();
            int denom;
            int passIdx, idx;

            bool result = true;

            for (int i = 0; i < poolValues.Length; i++)
            {
                poolValues[i] = new DMPoolHead();
            }

            if (useTag)
            {
                numPasses = poolValues.Length;
            }
            else
            {
                numPasses = 1;
            }

            for (passIdx = 1; passIdx <= numPasses; passIdx++)
            {
                GrazType.ZeroDMPool(ref totalPool);
                denom = 0;

                for (idx = 1; idx <= model.Count(); idx++)
                {
                    if (!useTag || (model.GetTag(idx) == passIdx))
                    {
                        if (!useYoung)
                        {
                            animalGroup = model.At(idx);
                        }
                        else
                        {
                            animalGroup = model.At(idx).Young;
                        }

                        GrazType.ZeroDMPool(ref pool);
                        if (animalGroup != null)
                        {
                            int n = (int)GrazType.TOMElement.n;
                            int p = (int)GrazType.TOMElement.p;
                            int s = (int)GrazType.TOMElement.s;

                            switch (propCode)
                            {
                            case StockProps.prpINTAKE:
                                pool.DM     = animalGroup.AnimalState.DM_Intake.Total;
                                pool.Nu[n]  = animalGroup.AnimalState.CP_Intake.Total / GrazType.N2Protein;
                                pool.Nu[p]  = animalGroup.AnimalState.Phos_Intake.Total;
                                pool.Nu[s]  = animalGroup.AnimalState.Sulf_Intake.Total;
                                pool.AshAlk = (animalGroup.AnimalState.PaddockIntake.AshAlkalinity * animalGroup.AnimalState.PaddockIntake.Biomass)
                                              + (animalGroup.AnimalState.SuppIntake.AshAlkalinity * animalGroup.AnimalState.SuppIntake.Biomass);
                                break;

                            case StockProps.prpINTAKE_PAST:
                                pool.DM     = animalGroup.AnimalState.DM_Intake.Herbage;
                                pool.Nu[n]  = animalGroup.AnimalState.CP_Intake.Herbage / GrazType.N2Protein;
                                pool.Nu[p]  = animalGroup.AnimalState.Phos_Intake.Herbage;
                                pool.Nu[s]  = animalGroup.AnimalState.Sulf_Intake.Herbage;
                                pool.AshAlk = animalGroup.AnimalState.PaddockIntake.AshAlkalinity * animalGroup.AnimalState.PaddockIntake.Biomass;
                                break;

                            case StockProps.prpINTAKE_SUPP:
                                pool.DM     = animalGroup.AnimalState.DM_Intake.Supp;
                                pool.Nu[n]  = animalGroup.AnimalState.CP_Intake.Supp / GrazType.N2Protein;
                                pool.Nu[p]  = animalGroup.AnimalState.Phos_Intake.Supp;
                                pool.Nu[s]  = animalGroup.AnimalState.Sulf_Intake.Supp;
                                pool.AshAlk = animalGroup.AnimalState.SuppIntake.AshAlkalinity * animalGroup.AnimalState.SuppIntake.Biomass;
                                break;

                            case StockProps.prpFAECES:
                                GrazType.AddDMPool(animalGroup.AnimalState.OrgFaeces, pool);
                                GrazType.AddDMPool(animalGroup.AnimalState.InOrgFaeces, pool);
                                break;

                            case StockProps.prpINORG_FAECES:
                                GrazType.AddDMPool(animalGroup.AnimalState.InOrgFaeces, pool);
                                break;

                            default:
                                result = false;
                                break;
                            }
                        }

                        if (!useTag && !useAll)
                        {
                            DMPool2Value(pool, ref poolValues[idx - 1], (propCode == StockProps.prpINORG_FAECES));
                        }
                        else if (animalGroup != null)
                        {
                            GrazType.AddDMPool(GrazType.MultiplyDMPool(pool, animalGroup.NoAnimals), totalPool);
                            denom = denom + animalGroup.NoAnimals;
                        }
                    }
                } // _ loop over animal groups _

                if (useTag || useAll)
                {
                    if (denom > 0)
                    {
                        totalPool = GrazType.PoolFraction(totalPool, 1.0 / denom);
                    }
                    if (useAll)
                    {
                        DMPool2Value(totalPool, ref poolValues[0], (propCode == StockProps.prpINORG_FAECES));
                    }
                    else
                    {
                        DMPool2Value(totalPool, ref poolValues[passIdx - 1], (propCode == StockProps.prpINORG_FAECES));
                    }
                }
            }
            return(result);
        }
예제 #3
0
        /// <summary>
        /// Populate the dry matter pool
        /// </summary>
        /// <param name="Model"></param>
        /// <param name="iCode"></param>
        /// <param name="bUseYoung"></param>
        /// <param name="bUseAll"></param>
        /// <param name="bUseTag"></param>
        /// <param name="aValue"></param>
        /// <returns></returns>
        public static bool PopulateDMPoolValue(TStockList Model, int iCode, bool bUseYoung, bool bUseAll, bool bUseTag, ref TDMPoolHead[] aValue)
        {
            int          iNoPasses;
            TAnimalGroup aGroup;

            GrazType.DM_Pool Pool      = new GrazType.DM_Pool();
            GrazType.DM_Pool TotalPool = new GrazType.DM_Pool();
            int iDenom;
            int iPass, Idx;

            bool Result = true;

            for (int i = 0; i < aValue.Length; i++)
            {
                aValue[i] = new TDMPoolHead();
            }

            if (bUseTag)
            {
                iNoPasses = aValue.Length;
            }
            else
            {
                iNoPasses = 1;
            }

            for (iPass = 1; iPass <= iNoPasses; iPass++)
            {
                GrazType.ZeroDMPool(ref TotalPool);
                iDenom = 0;

                for (Idx = 1; Idx <= Model.Count(); Idx++)
                {
                    if (!bUseTag || (Model.getTag(Idx) == iPass))
                    {
                        if (!bUseYoung)
                        {
                            aGroup = Model.At(Idx);
                        }
                        else
                        {
                            aGroup = Model.At(Idx).Young;
                        }

                        GrazType.ZeroDMPool(ref Pool);
                        if (aGroup != null)
                        {
                            int N = (int)GrazType.TOMElement.N;
                            int P = (int)GrazType.TOMElement.P;
                            int S = (int)GrazType.TOMElement.S;

                            switch (iCode)
                            {
                            case StockProps.prpINTAKE:
                                Pool.DM     = aGroup.AnimalState.DM_Intake.Total;
                                Pool.Nu[N]  = aGroup.AnimalState.CP_Intake.Total / GrazType.N2Protein;
                                Pool.Nu[P]  = aGroup.AnimalState.Phos_Intake.Total;
                                Pool.Nu[S]  = aGroup.AnimalState.Sulf_Intake.Total;
                                Pool.AshAlk = aGroup.AnimalState.PaddockIntake.AshAlkalinity * aGroup.AnimalState.PaddockIntake.Biomass
                                              + aGroup.AnimalState.SuppIntake.AshAlkalinity * aGroup.AnimalState.SuppIntake.Biomass;
                                break;

                            case StockProps.prpINTAKE_PAST:
                                Pool.DM     = aGroup.AnimalState.DM_Intake.Herbage;
                                Pool.Nu[N]  = aGroup.AnimalState.CP_Intake.Herbage / GrazType.N2Protein;
                                Pool.Nu[P]  = aGroup.AnimalState.Phos_Intake.Herbage;
                                Pool.Nu[S]  = aGroup.AnimalState.Sulf_Intake.Herbage;
                                Pool.AshAlk = aGroup.AnimalState.PaddockIntake.AshAlkalinity * aGroup.AnimalState.PaddockIntake.Biomass;
                                break;

                            case StockProps.prpINTAKE_SUPP:
                                Pool.DM     = aGroup.AnimalState.DM_Intake.Supp;
                                Pool.Nu[N]  = aGroup.AnimalState.CP_Intake.Supp / GrazType.N2Protein;
                                Pool.Nu[P]  = aGroup.AnimalState.Phos_Intake.Supp;
                                Pool.Nu[S]  = aGroup.AnimalState.Sulf_Intake.Supp;
                                Pool.AshAlk = aGroup.AnimalState.SuppIntake.AshAlkalinity * aGroup.AnimalState.SuppIntake.Biomass;
                                break;

                            case StockProps.prpFAECES:
                                GrazType.AddDMPool(aGroup.AnimalState.OrgFaeces, Pool);
                                GrazType.AddDMPool(aGroup.AnimalState.InOrgFaeces, Pool);
                                break;

                            case StockProps.prpINORG_FAECES:
                                GrazType.AddDMPool(aGroup.AnimalState.InOrgFaeces, Pool);
                                break;

                            default:
                                Result = false;
                                break;
                            }
                        }

                        if (!bUseTag && !bUseAll)
                        {
                            DMPool2Value(Pool, aValue[Idx - 1], (iCode == StockProps.prpINORG_FAECES));
                        }
                        else if (aGroup != null)
                        {
                            GrazType.AddDMPool(GrazType.MultiplyDMPool(Pool, aGroup.NoAnimals), TotalPool);
                            iDenom = iDenom + aGroup.NoAnimals;
                        }
                    }
                } //_ loop over animal groups _

                if (bUseTag || bUseAll)
                {
                    if (iDenom > 0)
                    {
                        TotalPool = GrazType.PoolFraction(TotalPool, 1.0 / iDenom);
                    }
                    if (bUseAll)
                    {
                        DMPool2Value(TotalPool, aValue[0], (iCode == StockProps.prpINORG_FAECES));
                    }
                    else
                    {
                        DMPool2Value(TotalPool, aValue[iPass - 1], (iCode == StockProps.prpINORG_FAECES));
                    }
                }
            }
            return(Result);
        }
예제 #4
0
        /// <summary>
        /// Copies a Plant/AgPasture object biomass organs into GrazingInputs object
        /// This object may then get scaled to kg/ha
        /// </summary>
        /// <param name="forageObj">The forage object - a Plant/AgPasture component</param>
        /// <returns>The grazing inputs</returns>
        private GrazType.GrazingInputs Crop2GrazingInputs(IPlantDamage forageObj)
        {
            GrazType.GrazingInputs result = new GrazType.GrazingInputs();
            GrazType.zeroGrazingInputs(ref result);

            result.TotalGreen = 0;
            result.TotalDead  = 0;

            double totalDMD = 0;
            double totalN   = 0;
            double nConc;
            double meanDMD;
            double dmd;

            // calculate the green available based on the total green in this paddock
            double greenPropn = 0;

            // ** should really take into account the height ratio here e.g. Params.HeightRatio
            if (this.PastureGreenDM > GrazType.Ungrazeable)
            {
                greenPropn = 1.0 - (GrazType.Ungrazeable / this.PastureGreenDM);
            }

            // calculate the total live and dead biomass
            foreach (IOrganDamage biomass in forageObj.Organs)
            {
                if (biomass.IsAboveGround)
                {
                    if (biomass.Live.Wt > 0 || biomass.Dead.Wt > 0)
                    {
                        result.TotalGreen += (greenPropn * biomass.Live.Wt);   // g/m^2
                        result.TotalDead  += biomass.Dead.Wt;

                        // we can find the dmd of structural, assume storage and metabolic are 100% digestible
                        dmd       = (biomass.Live.DMDOfStructural * greenPropn * biomass.Live.StructuralWt) + (1 * greenPropn * biomass.Live.StorageWt) + (1 * greenPropn * biomass.Live.MetabolicWt); // storage and metab are 100% dmd
                        dmd      += ((biomass.Dead.DMDOfStructural * biomass.Dead.StructuralWt) + (1 * biomass.Dead.StorageWt) + (1 * biomass.Dead.MetabolicWt));
                        totalDMD += dmd;
                        totalN   += (greenPropn * biomass.Live.N) + (biomass.Dead.Wt > 0 ? biomass.Dead.N : 0); // g/m^2
                    }
                }
            }

            // TODO: Improve this routine
            double availDM = result.TotalGreen + result.TotalDead;

            if (availDM > 0)
            {
                meanDMD = totalDMD / availDM; // calc the average dmd for the plant
                nConc   = totalN / availDM;   // N conc
                // get the dmd distribution
                double[] dmdPropns;           // = new double[GrazType.DigClassNo + 1];

                // green 0.85-0.45, dead 0.70-0.30
                dmdPropns = ForageInfo.CalcDMDDistribution(meanDMD, 0.85, 0.45);    // FIX ME: the DMD ranges should be organ- and development-specific values

                for (int idx = 1; idx <= GrazType.DigClassNo; idx++)
                {
                    result.Herbage[idx].Biomass       = dmdPropns[idx] * availDM;
                    result.Herbage[idx].CrudeProtein  = nConc * GrazType.N2Protein;
                    result.Herbage[idx].Digestibility = GrazType.ClassDig[idx];
                    result.Herbage[idx].Degradability = Math.Min(0.90, result.Herbage[idx].Digestibility + 0.10);
                    result.Herbage[idx].HeightRatio   = 1;
                    result.Herbage[idx].PhosContent   = 0;    // N * 0.05?
                    result.Herbage[idx].SulfContent   = 0;    // N * 0.07?
                    result.Herbage[idx].AshAlkalinity = 0.70; // TODO: use a modelled value
                }

                if (forageObj is IPlant plant)
                {
                    switch (plant.PlantType)
                    {
                    case "AGPLucerne":
                    case "AGPRedClover":
                    case "AGPWhiteClover":
                        result.LegumePropn = 1;
                        break;

                    default:
                        result.LegumePropn = 0;
                        break;
                    }
                }

                result.SelectFactor = 0;    // TODO: set from Plant model value

                // TODO: Store any seed pools
            }

            return(result);
        }