//---------------------------------------------------------------------
        // Generates new climate parameters at an annual time step.
        //
        public static void GenerateNewClimate(int year, int years)
        {
            //PlugIn.ModelCore.Log.WriteLine("   Generating new climate for simulation year {0}.", year);

            AnnualClimateArray = new Ecoregions.AuxParm<AnnualClimate[]>(PlugIn.ModelCore.Ecoregions);

            // Issues with this approach:  Each ecoregion will have unique variability associated with
            // temperature and precipitation.  In reality, we expect some regional synchronicity.  An
            // easy-ish solution would be to use the same random number in combination with standard
            // deviations for all ecoregions.  The converse problem is over synchronization of climate, but
            // that would certainly be preferrable over smaller regions.

            foreach(IEcoregion ecoregion in PlugIn.ModelCore.Ecoregions)
            {
                if(ActiveSiteCount[ecoregion] > 0)
                {
                    AnnualClimate[] tempClimate = new AnnualClimate[years];

                    for (int y = 0; y < years; y++)
                    {

                        int actualYear = year + y;

                        if(Climate.AllData.ContainsKey(actualYear))
                        {
                            Climate.TimestepData = Climate.AllData[actualYear];
                            //PlugIn.ModelCore.Log.WriteLine("  Changing TimestepData:  Yr={0}, Eco={1}.", actualYear, ecoregion.Name);
                            //PlugIn.ModelCore.Log.WriteLine("  Changing TimestepData:  AllData  Jan Ppt = {0:0.00}.", Climate.AllData[actualYear][ecoregion.Index,0].AvgPpt);
                            //PlugIn.ModelCore.Log.WriteLine("  Changing TimestepData:  Timestep Jan Ppt = {0:0.00}.", Climate.TimestepData[ecoregion.Index,0].AvgPpt);
                        }

                        tempClimate[y] = new AnnualClimate(ecoregion.Index, actualYear, Latitude[ecoregion]);

                    }

                    AnnualClimateArray[ecoregion] = tempClimate;
                }
            }
        }
        //---------------------------------------------------------------------
        // Generates new climate parameters at an annual time step.
        //
        public static void GenerateNewClimate(int year, int years)
        {
            //PlugIn.ModelCore.UI.WriteLine("   Generating new climate for simulation year {0}.", year);

            AnnualClimateArray = new Ecoregions.AuxParm<AnnualClimate[]>(PlugIn.ModelCore.Ecoregions);

            foreach(IEcoregion ecoregion in PlugIn.ModelCore.Ecoregions)
            {
                if(ecoregion.Active)
                {
                    AnnualClimate[] tempClimate = new AnnualClimate[years];

                    for (int y = 0; y < years; y++)
                    {

                        int actualYear = year + y;

                        if(Climate.AllData.ContainsKey(actualYear))
                        {
                            Climate.TimestepData = Climate.AllData[actualYear];
                            //PlugIn.ModelCore.UI.WriteLine("  Changing TimestepData:  Yr={0}, Eco={1}.", actualYear, ecoregion.Name);
                            //PlugIn.ModelCore.UI.WriteLine("  Changing TimestepData:  AllData  Jan Ppt = {0:0.00}.", Climate.AllData[actualYear][ecoregion.Index,0].AvgPpt);
                            //PlugIn.ModelCore.UI.WriteLine("  Changing TimestepData:  Timestep Jan Ppt = {0:0.00}.", Climate.TimestepData[ecoregion.Index,0].AvgPpt);
                        }

                        AnnualClimate.AnnualClimateInitialize();  // Synchronizes temperature and precipitation deviation across ecoregions.
                        tempClimate[y] = new AnnualClimate(ecoregion, actualYear, Latitude[ecoregion]);

                    }

                    AnnualClimateArray[ecoregion] = tempClimate;
                }
            }
        }
        //---------------------------------------------------------------------------
        public static double CalculateAnnualActualEvapotranspiration(AnnualClimate annualClimate, double fieldCapacity)
        {
            // field capacity input as cm
            // variable with xVariableName indicate conversion to mm

            double xFieldCap = fieldCapacity * 10.0;

            double waterAvail = 0.0;
            double actualET = 0.0;
            double oldWaterAvail = 0.0;
            double accPotWaterLoss = 0.0;

            for(int month = 0; month < 12; month++)
            {

                double monthlyRain = annualClimate.MonthlyPrecip[month];
                double potentialET = annualClimate.MonthlyPET[month];


                //Calc potential water loss this month
                double potWaterLoss = monthlyRain - potentialET;

                //If monthlyRain doesn't satisfy potentialET, add this month's potential
                //water loss to accumulated water loss from soil
                if (potWaterLoss < 0.0)
                {
                    accPotWaterLoss += potWaterLoss;
                    double xAccPotWaterLoss = accPotWaterLoss * 10.0;

                    //Calc water retained in soil given so much accumulated potential
                    //water loss Pastor and Post. 1984.  Can. J. For. Res. 14:466:467.

                    waterAvail = fieldCapacity *
                                 System.Math.Exp((.000461 - 1.10559 / xFieldCap) * (-1.0 * xAccPotWaterLoss));

                    if (waterAvail < 0.0)
                        waterAvail = 0.0;

                    //changeSoilMoisture - during this month
                    double changeSoilMoisture = waterAvail - oldWaterAvail;

                    //Calc actual evapotranspiration (AET) if soil water is drawn down
                    actualET += (monthlyRain - changeSoilMoisture);
                }

                //If monthlyRain satisfies potentialET, don't draw down soil water
                else
                {
                    waterAvail = oldWaterAvail + potWaterLoss;
                    if (waterAvail >= fieldCapacity)
                        waterAvail = fieldCapacity;

                    double changeSoilMoisture = waterAvail - oldWaterAvail;

                    //If soil partially recharged, reduce accumulated potential
                    //water loss accordingly
                    accPotWaterLoss += changeSoilMoisture;

                    //If soil completely recharged, reset accumulated potential
                    //water loss to zero
                    if (waterAvail >= fieldCapacity)
                        accPotWaterLoss = 0.0;

                    //If soil water is not drawn upon, add potentialET to AET
                    actualET += potentialET;
                }

                oldWaterAvail = waterAvail;
            }

            return actualET;
        }
        //---------------------------------------------------------------------------
        public static double CalculateAnnualActualEvapotranspiration(AnnualClimate annualClimate, double fieldCapacity)
        {
            // field capacity input as cm
            // variable with xVariableName indicate conversion to mm

            double xFieldCap = fieldCapacity * 10.0;

            double waterAvail      = 0.0;
            double actualET        = 0.0;
            double oldWaterAvail   = 0.0;
            double accPotWaterLoss = 0.0;

            for (int month = 0; month < 12; month++)
            {
                double monthlyRain = annualClimate.MonthlyPrecip[month];
                double potentialET = annualClimate.MonthlyPET[month];


                //Calc potential water loss this month
                double potWaterLoss = monthlyRain - potentialET;

                //If monthlyRain doesn't satisfy potentialET, add this month's potential
                //water loss to accumulated water loss from soil
                if (potWaterLoss < 0.0)
                {
                    accPotWaterLoss += potWaterLoss;
                    double xAccPotWaterLoss = accPotWaterLoss * 10.0;

                    //Calc water retained in soil given so much accumulated potential
                    //water loss Pastor and Post. 1984.  Can. J. For. Res. 14:466:467.

                    waterAvail = fieldCapacity *
                                 System.Math.Exp((.000461 - 1.10559 / xFieldCap) * (-1.0 * xAccPotWaterLoss));

                    if (waterAvail < 0.0)
                    {
                        waterAvail = 0.0;
                    }

                    //changeSoilMoisture - during this month
                    double changeSoilMoisture = waterAvail - oldWaterAvail;

                    //Calc actual evapotranspiration (AET) if soil water is drawn down
                    actualET += (monthlyRain - changeSoilMoisture);
                }

                //If monthlyRain satisfies potentialET, don't draw down soil water
                else
                {
                    waterAvail = oldWaterAvail + potWaterLoss;
                    if (waterAvail >= fieldCapacity)
                    {
                        waterAvail = fieldCapacity;
                    }

                    double changeSoilMoisture = waterAvail - oldWaterAvail;

                    //If soil partially recharged, reduce accumulated potential
                    //water loss accordingly
                    accPotWaterLoss += changeSoilMoisture;

                    //If soil completely recharged, reset accumulated potential
                    //water loss to zero
                    if (waterAvail >= fieldCapacity)
                    {
                        accPotWaterLoss = 0.0;
                    }

                    //If soil water is not drawn upon, add potentialET to AET
                    actualET += potentialET;
                }

                oldWaterAvail = waterAvail;
            }

            return(actualET);
        }