/// <summary>
 ///
 /// </summary>
 public override void Simulate()
 {
     try
     {
         if (CurrentCrop != null)
         {
             if (UseLAIModel())
             {
                 if (CurrentCrop.GetInFallow())
                 {
                     TryAndPlantNewCrop();
                 }
                 else if (CurrentCrop.IsGrowing())
                 {
                     CurrentCrop.Simulate();
                 }
             }
             else
             {
                 CurrentCrop.Simulate();
             }
             ++DaysSinceHarvest;
             TotalTranspiration      = CurrentCrop.TotalTranspiration;
             TotalEvapotranspiration = CurrentCrop.TotalTranspiration + Sim.SoilController.SoilEvap;
             UpdateCropWaterBalanceParameters();
         }
     }
     catch (Exception e)
     {
         throw new Exception(e.Message);
     }
 }
示例#2
0
 /// <summary>
 ///
 /// </summary>
 public override void Simulate()
 {
     try
     {
         if (CurrentCrop != null)
         {
             if (UseLAIModel())
             {
                 if (CurrentCrop.GetInFallow())
                 {
                     TryAndPlantNewCrop();
                 }
                 else if (CurrentCrop.IsGrowing())
                 {
                     CurrentCrop.Simulate();
                 }
             }
             else
             {
                 CurrentCrop.Simulate();
             }
             ++days_since_harvest;
             total_transpiration      = CurrentCrop.total_transpiration;
             total_evapotranspiration = CurrentCrop.total_transpiration + sim.out_WatBal_SoilEvap_mm;
             UpdateCropWaterBalanceParameters();
         }
     }
     catch (Exception e)
     {
         throw new Exception(e.Message);
     }
 }
示例#3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="crop"></param>
 /// <returns></returns>
 public bool CanPlantCrop(VegObjectController crop)
 {
     // Here are a few notes to try and get your head around the logic here.
     // First of all check to see if we leave left sufficient gap between this new
     // rotation and the previous rotation of this crop.
     // Case 1:
     // First test to see if this is the CurrentCrop.
     // If so, then make sure that we HAVENT exceeded max rotation count. Then we must
     // see if actually meet the planting criteria. If any of these fail, then return
     // "false" so that we can test another crop. Otherwise return "true" to tell the
     // sim to replant the CurrentCrop
     // Case 2:
     // If this is NOT the CurrentCrop - we had better first check that the CurrentCrop
     // is still expected to be in rotation. Then check to see that the sowing criteria
     // has been met. Return "true" if all good, otherwise return "false" so we can test
     // another crop. If we run out of crops, then the CurrentCrop stays in fallow.
     if (crop.IsSequenceCorrect() && crop.DoesCropMeetSowingCriteria())
     {
         if (crop == CurrentCrop)
         {
             return(crop.IsCropUnderMaxContinuousRotations());
         }
         else if (CurrentCrop.HasCropHadSufficientContinuousRotations())
         {
             return(crop.HasCropBeenAbsentForSufficientYears(sim.today));
         }
     }
     return(false);
 }
 /// <summary>
 ///
 /// </summary>
 public void CalculateTotalResidue()
 {
     //TODO: Make the crop residue function more generic -- remove type condition
     if (CurrentCrop != null && CurrentCrop.GetType() == typeof(LAIVegObjectController))
     {
         TotalCropResidue  = 0;
         TotalResidueCover = 0;
         LAIVegObjectController crop = (LAIVegObjectController)CurrentCrop;
         TotalResidueCover = crop.ResidueCover;
         crop.CalculateResidue();
         int count = ChildControllers.Count;
         for (int i = 1; i < count; ++i)
         {
             int index = GetCropIndex(crop) + 1;
             if (index == count)
             {
                 index = 0;
             }
             crop = (LAIVegObjectController)ChildControllers[index];
             TotalResidueCover = Math.Min(1.0, TotalResidueCover + crop.ResidueCover * (1 - TotalResidueCover));
         }
         for (int i = 0; i < count; ++i)
         {
             TotalCropResidue += ((VegObjectController)ChildControllers[i]).ResidueAmount;
         }
     }
     else
     {
         TotalCropResidue  = ((VegObjectController)ChildControllers[0]).CropResidue;
         TotalResidueCover = ((VegObjectController)ChildControllers[0]).ResidueCover;
     }
     TotalResidueCoverPercent = TotalResidueCover * 100.0;
 }
示例#5
0
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public double CalcFallowSoilWater()
 {
     if (CurrentCrop != null)
     {
         return(CurrentCrop.CalcFallowSoilWater());
     }
     return(0);
 }
示例#6
0
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public bool InFallow()
 {
     if (CurrentCrop != null)
     {
         return(CurrentCrop.GetInFallow());
     }
     return(true);
 }
示例#7
0
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public double GetPotentialSoilEvaporation()
 {
     if (CurrentCrop != null)
     {
         return(CurrentCrop.GetPotentialSoilEvaporation());
     }
     return(0);
 }
示例#8
0
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public bool IsPlanting()
 {
     if (CurrentCrop != null)
     {
         return(CurrentCrop.GetIsPlanting());
     }
     return(false);
 }
示例#9
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="current"></param>
 /// <returns></returns>
 public double GetCropCoverIfLAIModel(double current)
 {
     if (CurrentCrop.GetType() == typeof(LAIVegObjectController))
     {
         return(CurrentCrop.crop_cover);
         //LAI Model uses cover from the end of the previous day
         //whereas Cover model predefines at the start of the day
     }
     return(current);
 }
示例#10
0
 /// <summary>
 ///
 /// </summary>
 public void ResetAnyParametersIfRequired()
 {
     try
     {
         if (CurrentCrop != null)
         {
             CurrentCrop.ResetCropParametersAfterHarvest();
         }
     }
     catch (Exception e)
     {
         throw new Exception(e.Message);
     }
 }
示例#11
0
 internal bool IsPlanting()
 {
     try
     {
         if (CurrentCrop != null)
         {
             return(CurrentCrop.GetIsPlanting());
         }
     }
     catch (Exception ex)
     {
         throw ErrorLogger.CreateException(ex);
     }
     return(false);
 }
示例#12
0
 internal double CalcFallowSoilWater()
 {
     try
     {
         if (CurrentCrop != null)
         {
             return(CurrentCrop.CalcFallowSoilWater());
         }
     }
     catch (Exception ex)
     {
         throw ErrorLogger.CreateException(ex);
     }
     return(0);
 }
示例#13
0
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public double GetTotalCover()
 {
     if (CurrentCrop != null)
     {
         if (CurrentCrop.GetType() == typeof(LAIVegObjectController))
         {
             return(Math.Min(1.0, CurrentCrop.crop_cover + sim.total_residue_cover * (1 - CurrentCrop.crop_cover)));
         }
         else
         {
             return(CurrentCrop.GetTotalCover());
         }
     }
     return(0);
 }
示例#14
0
 internal double GetPotentialSoilEvaporation()
 {
     try
     {
         if (CurrentCrop != null)
         {
             return(CurrentCrop.GetPotentialSoilEvaporation());
         }
     }
     catch (Exception ex)
     {
         throw ErrorLogger.CreateException(ex);
     }
     return(0);
 }
示例#15
0
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public double GetTotalCover()
 {
     if (CurrentCrop != null)
     {
         if (CurrentCrop.GetType() == typeof(LAIVegObjectController))
         {
             return(Math.Min(1.0, CurrentCrop.CropCover + Sim.SoilController.TotalResidueCover * (1 - CurrentCrop.CropCover)));
         }
         else
         {
             return(CurrentCrop.GetTotalCover());
         }
     }
     return(0);
 }
示例#16
0
 internal bool InFallow()
 {
     try
     {
         if (CurrentCrop != null)
         {
             return(CurrentCrop.GetInFallow());
         }
     }
     catch (Exception ex)
     {
         throw ErrorLogger.CreateException(ex);
     }
     return(true);
 }
 public void TryModelVegetation()
 {
     try
     {
         if (VegetationModules != null)
         {
             if (CurrentCrop != null)
             {
                 if (UseLAIModel())
                 {
                     if (CurrentCrop.GetInFallow())
                     {
                         foreach (var crop in SortedVegetationModules)
                         {
                             if (CanPlantCrop(crop))
                             {
                                 crop.Plant();
                                 if (IrrigationModule != null)
                                 {
                                     IrrigationModule.FirstIrrigation = true;
                                 }
                                 return;
                             }
                         }
                     }
                     else if (CurrentCrop.IsGrowing())
                     {
                         CurrentCrop.Simulate();
                     }
                 }
                 else
                 {
                     CurrentCrop.Simulate();
                 }
                 ++DaysSinceHarvest;
                 TotalTranspiration      = CurrentCrop.TotalTranspiration;
                 TotalEvapotranspiration = CurrentCrop.TotalTranspiration + SoilModule.SoilEvap;
                 //UpdateCropWaterBalanceParameters();
             }
         }
     }
     catch (Exception ex)
     {
         throw ErrorLogger.CreateException(ex);
     }
 }
示例#18
0
 internal double GetCropCoverIfLAIModel(double current)
 {
     try
     {
         if (CurrentCrop != null)
         {
             if (CurrentCrop.GetType() == typeof(HowLeakyEngineModule_LAIVeg))
             {
                 return(CurrentCrop.CropCover);
                 //LAI Model uses cover from the end of the previous day
                 //whereas Cover model predefines at the start of the day
             }
         }
     }
     catch (Exception ex)
     {
         throw ErrorLogger.CreateException(ex);
     }
     return(current);
 }
示例#19
0
 internal void CalculateTotalResidue()
 {
     try
     {
         //TODO: Make the crop residue function more generic -- remove type condition
         if (CurrentCrop != null && CurrentCrop.GetType() == typeof(HowLeakyEngineModule_LAIVeg))
         {
             TotalCropResidue  = 0;
             TotalResidueCover = 0;
             HowLeakyEngineModule_LAIVeg crop = (HowLeakyEngineModule_LAIVeg)CurrentCrop;
             TotalResidueCover = crop.ResidueCover;
             crop.CalculateResidue();
             int count = VegetationModules.Count;
             for (int i = 1; i < count; ++i)
             {
                 int index = GetCropIndex(crop) + 1;
                 if (index == count)
                 {
                     index = 0;
                 }
                 crop = (HowLeakyEngineModule_LAIVeg)VegetationModules[index];
                 TotalResidueCover = Math.Min(1.0, TotalResidueCover + crop.ResidueCover * (1 - TotalResidueCover));
             }
             for (int i = 0; i < count; ++i)
             {
                 TotalCropResidue += ((HowLeakyEngineModule_LAIVeg)VegetationModules[i]).ResidueAmount;
             }
         }
         else
         {
             TotalCropResidue  = VegetationModules[0].CropResidue;
             TotalResidueCover = VegetationModules[0].ResidueCover;
         }
         TotalResidueCoverPercent = TotalResidueCover * 100.0;
     }
     catch (Exception ex)
     {
         throw ErrorLogger.CreateException(ex);
     }
 }
示例#20
0
 internal double GetTotalCover()
 {
     try
     {
         if (CurrentCrop != null)
         {
             if (CurrentCrop.GetType() == typeof(HowLeakyEngineModule_LAIVeg))
             {
                 return(Math.Min(1.0, CurrentCrop.CropCover + SoilModule.TotalResidueCover * (1 - CurrentCrop.CropCover)));
             }
             else
             {
                 return(CurrentCrop.GetTotalCover());
             }
         }
     }
     catch (Exception ex)
     {
         throw ErrorLogger.CreateException(ex);
     }
     return(0);
 }
示例#21
0
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public bool UseLAIModel()
 {
     return(CurrentCrop.GetType() == typeof(LAIVegObjectController)); //FIXME
 }
示例#22
0
    public void OnProcess()
    {
        //set up data table
        int NumLayers = 0;

        AllRootSystems.Rows.Clear();
        foreach (Paddock p in paddock.ChildPaddocks)
        {
            foreach (Component c in p.Crops)
            {
                string PlantStatus;
                if (!c.Get("plant_status", out PlantStatus))
                {
                    throw new Exception("Could not find plant_status for crop :" + c.Name);
                }

                if (PlantStatus != "out")                        //if crop is not in ground, we don't care about it
                {
                    if (c.GetObject("RootSystem", ref RootData)) //crop has a RootData structre
                    {
                        Dictionary <string, double> SWStrength = CalcSWSourceStrength(RootData);
                        foreach (RootSystemZoneType zone in RootData.Zone) //add each zone to the table
                        {
                            AllRootSystems.Rows.Add(zone.ZoneName, c.Name, RootData.SWDemand, SWStrength, zone, true);
                        }
                        NumLayers = RootData.Zone[0].kl.Length;
                    }
                    else //crop does not have RootData structure, so make one.
                    {
                        Dictionary <string, double> SWStrength = new Dictionary <string, double>();
                        RootData                  = new RootSystemType();
                        RootData.Zone             = new RootSystemZoneType[1];
                        RootData.Zone[0]          = new RootSystemZoneType();
                        RootData.Zone[0].ZoneName = p.Name;
                        RootData.Zone[0].ZoneArea = 1;
                        if (!c.Get("sw_demand", out RootData.SWDemand))
                        {
                            throw new Exception("Could not get sw_demand for crop " + c.Name);
                        }
                        if (!c.Get("root_depth", out RootData.Zone[0].RootDepth))
                        {
                            throw new Exception("Could not get root_depth for crop " + c.Name);
                        }
                        if (!c.Get("ll", out RootData.Zone[0].ll))
                        {
                            throw new Exception("Could not get ll for crop " + c.Name);
                        }
                        if (!c.Get("kl", out RootData.Zone[0].kl))
                        {
                            throw new Exception("Could not get kl for crop " + c.Name);
                        }
                        SoilWat = (Component)p.LinkByType("SoilWat");
                        SWStrength.Add(p.Name, 1);
                        if (!SoilWat.Get("dlayer", out RootData.Zone[0].dlayer))
                        {
                            throw new Exception("Could not get dlayer for paddock " + p.Name);
                        }
                        AllRootSystems.Rows.Add(RootData.Zone[0].ZoneName, c.Name, RootData.SWDemand, SWStrength, RootData.Zone[0], true);
                        NumLayers = RootData.Zone[0].kl.Length;
                    }
                }
            }
        }
        //use LINQ to extract the paddocks for processing
        IEnumerable <string> paddockNames = AllRootSystems.AsEnumerable().Select <DataRow, string>(name => (string)name.ItemArray[0]).Distinct();

        //do water allocation for each paddock
        foreach (string PaddockName in paddockNames)
        {
            IEnumerable <DataRow> RootZones = AllRootSystems.AsEnumerable().Where(row => row.ItemArray[0].Equals(PaddockName));
            Paddock   p          = (Paddock)paddock.LinkByName(PaddockName);
            Component fieldProps = (Component)p.LinkByName("FieldProps");
            double    fieldArea;
            if (fieldProps == null || !fieldProps.Get("fieldArea", out fieldArea))
            {
                throw new Exception("Could not find FieldProps component in field " + PaddockName);
            }

            Component Soil = (Component)p.LinkByType("SoilWat");
            double[]  SWDep;
            double[]  dlayer;
            Soil.Get("dlayer", out dlayer);
            Soil.Get("sw_dep", out SWDep);
            double[] CropSWDemand = new double[RootZones.Count()];
            for (int i = 0; i < RootZones.Count(); i++) //get demand for all crops in paddock using relative SW strength
            {
                Dictionary <string, double> PaddockSWDemands = (Dictionary <string, double>)RootZones.ToArray()[i].ItemArray[3];
                CropSWDemand[i] = PaddockSWDemands[p.Name] * (double)RootZones.ToArray()[i].ItemArray[2];
            }
            double[,] RelKLStrength      = CalcRelKLStrength(RootZones, CropSWDemand);
            double[,] RelSWLayerStrength = CalcRelSWLayerStrength(RootZones, SWDep, NumLayers);
            double[,] SWSupply           = CalcSWSupply(RootZones, SWDep, NumLayers);

            double[,] LayerUptake = new double[RootZones.Count(), NumLayers];
            double[] LastCropSWDemand;
            double[,] LastSWSupply;

            int count = 0;
            do
            {
                count++;
                LastCropSWDemand = CropSWDemand;
                LastSWSupply     = SWSupply;

                for (int i = 0; i < RootZones.Count(); i++) //get as much water as possible for the layer using relative kl strengths
                {
                    RootSystemZoneType Zone = (RootSystemZoneType)RootZones.ToArray()[i].ItemArray[4];
                    for (int j = 0; j < NumLayers; j++)
                    {
                        if (MathUtility.Sum(CropSWDemand) < MathUtility.Sum(SWSupply))
                        {
                            LayerUptake[i, j] = CropSWDemand[i] * RelSWLayerStrength[i, j];
                        }
                        else
                        {
                            LayerUptake[i, j] = SWSupply[i, j] * RelKLStrength[j, i] * RootProportion(j, Zone.RootDepth, dlayer);
                        }

                        if (LayerUptake[i, j] < 0)
                        {
                            throw new Exception("Layer uptake should not be negative");
                        }
                    }
                }

                DenseMatrix Uptake = DenseMatrix.OfArray(LayerUptake);
                Paddock     CurrentPaddock;
                Component   CurrentCrop;
                for (int i = 0; i < RootZones.Count(); i++) //subtract taken water from the supply and demand
                {
                    CurrentPaddock   = (Paddock)p.LinkByName((string)RootZones.ToArray()[i].ItemArray[0]);
                    CurrentCrop      = (Component)CurrentPaddock.LinkByName((string)RootZones.ToArray()[i].ItemArray[1]);
                    CropSWDemand[i] -= Uptake.Row(i).Sum();
                    if (CurrentCrop != null && CurrentCrop.Name.ToLower().Equals("maize"))
                    {
                        CurrentCrop.Set("arb_water_uptake", Uptake.Row(i).ToArray());
                    }
                    for (int j = 0; j < NumLayers; j++)
                    {
                        SWSupply[i, j] -= LayerUptake[i, j];
                    }
                }

                //subtract from soil water
                for (int j = 0; j < Uptake.ColumnCount; j++)
                {
                    SWDep[j] -= Uptake.Column(j).Sum() / fieldArea;
                }

                Soil.Set("sw_dep", SWDep);
            } while (MathUtility.Sum(LastCropSWDemand) != MathUtility.Sum(CropSWDemand) && MathUtility.Sum(LastSWSupply) != MathUtility.Sum(SWSupply));
        }
    }
示例#23
0
 public bool UseLAIModel()
 {
     return(CurrentCrop.GetType() == typeof(HowLeakyEngineModule_LAIVeg));
 }