Пример #1
0
        /// <summary>
        /// Retrieves soil types from ApSoil
        /// Configures any missing crop ll, kl values
        /// </summary>
        /// <param name="simulation"></param>
        /// <param name="apsoilService"></param>
        /// <returns></returns>
        public static void DoSoils(AusFarmSpec simulation)
        {
            APSOIL.Service apsoilService = null;
            Soil           soil;

            for (int i = 0; i < simulation.OnFarmSoilTypes.Count; i++)
            {
                FarmSoilType soilType = simulation.OnFarmSoilTypes[i];
                soil = soilType.SoilDescr;
                if (soil == null)
                {
                    // Look for a <SoilName> and if found go get the soil from the Apsoil web service.
                    if (apsoilService == null)
                    {
                        apsoilService = new APSOIL.Service();
                    }
                    string soilXml = apsoilService.SoilXML(soilType.SoilPath);
                    if (soilXml == string.Empty)
                    {
                        throw new Exception("Cannot find soil: " + soilType.SoilPath);
                    }

                    soil = SoilUtilities.FromXML(soilXml);
                }

                // Other crop types not listed here will have their ll, kll, xf values calculated later

                // Remove any initwater nodes.
                soil.InitialWater = null;

                foreach (Sample sample in soil.Samples)
                {
                    CheckSample(soil, sample);
                }

                // get rid of <soiltype> from the soil
                // this is necessary because NPD uses this field and puts in really long
                // descriptive classifications. Soiln2 bombs with an FString internal error.
                soil.SoilType = "";

                // Set the soil name to 'soil'
                //soil.Name = "Soil";
                soilType.SoilDescr = soil;  //store the changed description
            }
        }
Пример #2
0
        /// <summary>Do all soil related settings.</summary>
        /// <param name="simulation">The specification to use</param>
        /// <param name="workingFolder">The folder where files shoud be created.</param>
        private static void DoSoil(APSIMSpecification simulation, string workingFolder)
        {
            Soil soil;

            if (simulation.Soil == null)
            {
                if (simulation.SoilPath.StartsWith("<Soil"))
                {
                    // Soil and Landscape grid
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(simulation.SoilPath);
                    soil = XmlUtilities.Deserialise(doc.DocumentElement, typeof(Soil)) as Soil;
                }
                else if (simulation.SoilPath.StartsWith("http"))
                {
                    // Soil and Landscape grid
                    string xml;
                    using (var client = new WebClient())
                    {
                        xml = client.DownloadString(simulation.SoilPath);
                    }
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(xml);
                    List <XmlNode> soils = XmlUtilities.ChildNodes(doc.DocumentElement, "Soil");
                    if (soils.Count == 0)
                    {
                        throw new Exception("Cannot find soil in Soil and Landscape Grid");
                    }
                    soil = XmlUtilities.Deserialise(soils[0], typeof(Soil)) as Soil;
                }
                else
                {
                    // Apsoil web service.
                    APSOIL.Service apsoilService = new APSOIL.Service();
                    string         soilXml       = apsoilService.SoilXML(simulation.SoilPath.Replace("\r\n", ""));
                    if (soilXml == string.Empty)
                    {
                        throw new Exception("Cannot find soil: " + simulation.SoilPath);
                    }
                    soil = SoilUtilities.FromXML(soilXml);
                }
            }
            else
            {
                // Just use the soil we already have
                soil = simulation.Soil;
            }

            // Make sure we have a soil crop parameterisation. If not then try creating one
            // based on wheat.
            Sow sowing = YieldProphetUtility.GetCropBeingSown(simulation.Management);

            string[] cropNames = soil.Water.Crops.Select(c => c.Name).ToArray();
            if (cropNames.Length == 0)
            {
                throw new Exception("Cannot find any crop parameterisations in soil: " + simulation.SoilPath);
            }

            if (sowing != null && !StringUtilities.Contains(cropNames, sowing.Crop))
            {
                SoilCrop wheat = soil.Water.Crops.Find(c => c.Name.Equals("wheat", StringComparison.InvariantCultureIgnoreCase));
                if (wheat == null)
                {
                    // Use the first crop instead.
                    wheat = soil.Water.Crops[0];
                }

                SoilCrop newSoilCrop = new SoilCrop();
                newSoilCrop.Name      = sowing.Crop;
                newSoilCrop.Thickness = wheat.Thickness;
                newSoilCrop.LL        = wheat.LL;
                newSoilCrop.KL        = wheat.KL;
                newSoilCrop.XF        = wheat.XF;
                soil.Water.Crops.Add(newSoilCrop);
            }

            // Remove any initwater nodes.
            soil.InitialWater = null;

            // Transfer the simulation samples to the soil
            if (simulation.Samples != null)
            {
                soil.Samples = simulation.Samples;
            }

            if (simulation.InitTotalWater != 0)
            {
                soil.InitialWater = new InitialWater();
                soil.InitialWater.PercentMethod = InitialWater.PercentMethodEnum.FilledFromTop;

                double pawc;
                if (sowing == null || sowing.Crop == null)
                {
                    pawc = MathUtilities.Sum(PAWC.OfSoilmm(soil));
                    soil.InitialWater.RelativeTo = "LL15";
                }
                else
                {
                    SoilCrop crop = soil.Water.Crops.Find(c => c.Name.Equals(sowing.Crop, StringComparison.InvariantCultureIgnoreCase));
                    pawc = MathUtilities.Sum(PAWC.OfCropmm(soil, crop));
                    soil.InitialWater.RelativeTo = crop.Name;
                }

                soil.InitialWater.FractionFull = Convert.ToDouble(simulation.InitTotalWater) / pawc;
            }

            if (simulation.InitTotalNitrogen != 0)
            {
                // Add in a sample.
                Sample nitrogenSample = new Sample();
                nitrogenSample.Name = "NitrogenSample";
                soil.Samples.Add(nitrogenSample);
                nitrogenSample.Thickness = new double[] { 150, 150, 3000 };
                nitrogenSample.NO3Units  = Nitrogen.NUnitsEnum.kgha;
                nitrogenSample.NH4Units  = Nitrogen.NUnitsEnum.kgha;
                nitrogenSample.NO3       = new double[] { 6.0, 2.1, 0.1 };
                nitrogenSample.NH4       = new double[] { 0.5, 0.1, 0.1 };
                nitrogenSample.OC        = new double[] { double.NaN, double.NaN, double.NaN };
                nitrogenSample.EC        = new double[] { double.NaN, double.NaN, double.NaN };
                nitrogenSample.PH        = new double[] { double.NaN, double.NaN, double.NaN };

                double Scale = Convert.ToDouble(simulation.InitTotalNitrogen) / MathUtilities.Sum(nitrogenSample.NO3);
                nitrogenSample.NO3 = MathUtilities.Multiply_Value(nitrogenSample.NO3, Scale);
            }

            // Add in soil temperature. Needed for Aflatoxin risk.
            soil.SoilTemperature = new SoilTemperature();
            soil.SoilTemperature.BoundaryLayerConductance = 15;
            soil.SoilTemperature.Thickness = new double[] { 2000 };
            soil.SoilTemperature.InitialSoilTemperature = new double[] { 22 };
            if (soil.Analysis.ParticleSizeClay == null)
            {
                soil.Analysis.ParticleSizeClay = MathUtilities.CreateArrayOfValues(60, soil.Analysis.Thickness.Length);
            }
            InFillMissingValues(soil.Analysis.ParticleSizeClay);

            foreach (Sample sample in soil.Samples)
            {
                CheckSample(soil, sample, sowing);
            }

            Defaults.FillInMissingValues(soil);

            // Correct the CONA / U parameters depending on LAT/LONG
            CorrectCONAU(simulation, soil, workingFolder);

            // get rid of <soiltype> from the soil
            // this is necessary because NPD uses this field and puts in really long
            // descriptive classifications. Soiln2 bombs with an FString internal error.
            soil.SoilType = null;

            // Set the soil name to 'soil'
            soil.Name = "Soil";

            simulation.Soil = soil;
        }