コード例 #1
0
        //---------------------------------------------------------------------

        public static DataRow GenerateSeasonWindData(ISeasonParameters season)
        {
            int weatherRandomizer = PlugIn.WeatherRandomizer;
            //string seasonName = season.NameOfSeason.ToString();
            //string ecoName = fire_region.Name;
            //int weatherBin = 0;

            int seasonStart = season.StartDay;
            int seasonEnd   = season.EndDay;

            string selectString = "Day >= " + seasonStart + " AND Day <= " + seasonEnd;

            DataRow[] rows = PlugIn.WindDataTable.Select(selectString);

            if (rows.Length > 0)
            {
                int     newRandNum = (int)(Math.Round(PlugIn.ModelCore.GenerateUniform() * (rows.Length - 1)));
                DataRow weatherRow = rows[newRandNum];

                return(weatherRow);
            }
            else
            {
                return(null);
            }
        }
コード例 #2
0
        //---------------------------------------------------------------------

        public static int GenerateWindSpeed(ISeasonParameters season)
        {
            double windSpeed = 0.0;
            windSpeed = GenerateRandomNum(season.WSVDist, season.WSVP1, season.WSVP2);
            if(windSpeed < 0) windSpeed = 0;
            
            return (int) windSpeed;
        }
コード例 #3
0
        //---------------------------------------------------------------------

        public static int GenerateFineFuelMoistureCode(ISeasonParameters season)
        {
            double ffmc = 0.0;
            ffmc = GenerateRandomNum(season.FFMCDist, season.FFMCP1, season.FFMCP2);
            if(ffmc < 0) ffmc = 0;
            if(ffmc > 100) ffmc = 100;
            
            return (int) ffmc;
        }
コード例 #4
0
        //---------------------------------------------------------------------

        public static ISeasonParameters GenerateSeason(ISeasonParameters[] seasons)
        {
            double randNum = PlugIn.ModelCore.GenerateUniform();
            double bottom = 0.0;
            double top = 0.0;
            foreach (ISeasonParameters season in seasons)
            {
                top += season.FireProbability;
                if(randNum >= bottom && randNum <= top)
                    return season;
                bottom += season.FireProbability;
            }
            return null;
        }
コード例 #5
0
        //---------------------------------------------------------------------

        public static ISeasonParameters GetSeason(ISeasonParameters[] seasons, int day)
        {
            ISeasonParameters theSeason = seasons[0];
            foreach (ISeasonParameters season in seasons)
            {
                if (season.NameOfSeason == SeasonName.Spring && day < season.StartDay)
                {
                    string mesg = string.Format("Error: The fire day {0} is before the beginning of spring", day);
                    throw new System.ApplicationException(mesg);
                }

                if (day < season.EndDay)
                    theSeason = season;
            }
            return theSeason;
        }
コード例 #6
0
        //---------------------------------------------------------------------

        private Event(ActiveSite initiationSite, ISeasonParameters fireSeason, SizeType fireSizeType)
        {
            this.initiationSite = initiationSite;
            this.sitesInEvent   = new int[FireRegions.Dataset.Count];
            //PlugIn.ModelCore.UI.WriteLine("   initialzing siteInEvent ...");

            foreach (IFireRegion fire_region in FireRegions.Dataset)
            {
                this.sitesInEvent[fire_region.Index] = 0;
            }
            this.cohortsKilled     = 0;
            this.eventSeverity     = 0;
            this.totalSitesDamaged = 0;
            this.lengthB           = 0.0;
            this.lengthA           = 0.0;
            this.lengthD           = 0.0;
            IFireRegion eco = SiteVars.FireRegion[initiationSite];

            this.initiationFireRegion = eco;
            this.maxFireParameter     = ComputeSize(eco.MeanSize, eco.StandardDeviation, eco.MaxSize); //fireSizeType);
            this.sizeBin    = ComputeSizeBin(eco.MeanSize, eco.StandardDeviation, this.maxFireParameter);
            this.fireSeason = fireSeason;                                                              //Weather.GenerateSeason(seasons);
            System.Data.DataRow weatherRow = Weather.GenerateDataRow(this.fireSeason, eco, this.sizeBin);

            this.windSpeed            = Weather.GenerateWindSpeed(weatherRow);
            this.fineFuelMoistureCode = Weather.GenerateFineFuelMoistureCode(weatherRow);
            this.buildUpIndex         = Weather.GenerateBuildUpIndex(weatherRow);
            this.windDirection        = Weather.GenerateWindDirection(weatherRow);
            this.foliarMC             = Weather.GenerateFMC(this.fireSeason, eco);


            //PlugIn.ModelCore.UI.WriteLine();

            /*PlugIn.ModelCore.UI.WriteLine("   New Fire Event Data:  WSV={0}, FFMC={1}, BUI={2}, foliarMC={3}, windDirection={4}, Season={5}, FireRegion={6}, SizeBin = {7}.",
             *              this.windSpeed,
             *              this.fineFuelMoistureCode,
             *              this.buildUpIndex,
             *              this.foliarMC,
             *              this.windDirection,
             *              this.fireSeason.NameOfSeason,
             *              this.initiationFireRegion.Name,
             *              this.sizeBin
             *              );*/
        }
コード例 #7
0
        //---------------------------------------------------------------------

        public static ISeasonParameters GetSeason(ISeasonParameters[] seasons, int day)
        {
            ISeasonParameters theSeason = seasons[0];

            foreach (ISeasonParameters season in seasons)
            {
                if (season.NameOfSeason == SeasonName.Spring && day < season.StartDay)
                {
                    string mesg = string.Format("Error: The fire day {0} is before the beginning of spring", day);
                    throw new System.ApplicationException(mesg);
                }

                if (day < season.EndDay)
                {
                    theSeason = season;
                }
            }
            return(theSeason);
        }
コード例 #8
0
        //---------------------------------------------------------------------

        public static int GenerateFMC(ISeasonParameters season, IFireRegion fire_region)
        {
            int FMC = 0;

            if (season.NameOfSeason == SeasonName.Spring)
            {
                if (PlugIn.ModelCore.GenerateUniform() < fire_region.SpringFMCHiProp)
                {
                    FMC = fire_region.SpringFMCHi;
                }
                else
                {
                    FMC = fire_region.SpringFMCLo;
                }
            }
            if (season.NameOfSeason == SeasonName.Summer)
            {
                if (PlugIn.ModelCore.GenerateUniform() < fire_region.SummerFMCHiProp)
                {
                    FMC = fire_region.SummerFMCHi;
                }
                else
                {
                    FMC = fire_region.SummerFMCLo;
                }
            }
            if (season.NameOfSeason == SeasonName.Fall)
            {
                if (PlugIn.ModelCore.GenerateUniform() < fire_region.FallFMCHiProp)
                {
                    FMC = fire_region.FallFMCHi;
                }
                else
                {
                    FMC = fire_region.FallFMCLo;
                }
            }
            return(FMC);
        }
コード例 #9
0
        //---------------------------------------------------------------------

        public static DataTable ReadWeatherFile(string path, IDynamicInputRecord[] regionRecords, ISeasonParameters[] seasonParms)
        {
            PlugIn.ModelCore.UI.WriteLine("   Loading Weather Data...");

            CSVParser weatherParser = new CSVParser();

            DataTable weatherTable = weatherParser.ParseToDataTable(path);

            int recordCount = 0;
            for (int i = 0; i <= 2; i++)
            {
                string seasName = seasonParms[i].NameOfSeason.ToString();


                foreach (IDynamicInputRecord fire_region in regionRecords)
                {
                    string ecoName = fire_region.Name;
                    //PlugIn.ModelCore.Log.WriteLine("Read Weather File:  Season={0}, FireRegion={1}.", seasName, ecoName);

                    string selectText = ("FireRegion = '" + ecoName + "' AND Season = '" + seasName + "'");
                    //PlugIn.ModelCore.Log.WriteLine("Read Weather File SelectText = {0}.", selectText);

                    DataRow[] foundRows = weatherTable.Select(selectText);

                    if (foundRows.Length == 0)
                    {
                        selectText = ("FireRegion = 'All' AND Season = '" + seasName + "'");
                        foundRows = weatherTable.Select(selectText);
                    }
                    if ((foundRows.Length == 0) && (seasonParms[i].FireProbability > 0) && (fire_region.EcoIgnitionNum > 0))
                    {
                        PlugIn.ModelCore.UI.WriteLine("WARNING (Ln 430): FireRegion " + ecoName + ", Season " + seasName + " has fire probability > 0, but 0 weather records.  Using alternate season.");
                        if (seasName == "Spring")
                        {
                            selectText = ("FireRegion = '" + ecoName + "' AND Season = 'Summer'");
                            //PlugIn.ModelCore.Log.WriteLine("Read Weather File SelectText = {0}.", selectText);
                            foundRows = weatherTable.Select(selectText);

                            if (foundRows.Length == 0)
                            {
                                selectText = ("FireRegion = '" + ecoName + "' AND Season = 'Fall'");
                                //PlugIn.ModelCore.Log.WriteLine("Read Weather File SelectText = {0}.", selectText);
                                foundRows = weatherTable.Select(selectText);
                            }
                            if (foundRows.Length == 0)
                            {
                                PlugIn.ModelCore.UI.WriteLine("WARNING (Ln 445): FireRegion " + ecoName + " has fire probability > 0, but 0 weather records.  No fires will occur in this fire region.");
                        
                            }

                        }
                        if (seasName == "Fall")
                        {
                            selectText = ("FireRegion = '" + ecoName + "' AND Season = 'Summer'");
                            //PlugIn.ModelCore.Log.WriteLine("Read Weather File SelectText = {0}.", selectText);
                            foundRows = weatherTable.Select(selectText);

                            if (foundRows.Length == 0)
                            {
                                selectText = ("FireRegion = '" + ecoName + "' AND Season = 'Spring'");
                                //PlugIn.ModelCore.Log.WriteLine("Read Weather File SelectText = {0}.", selectText);
                                foundRows = weatherTable.Select(selectText);
                            }
                            if (foundRows.Length == 0)
                            {
                                PlugIn.ModelCore.UI.WriteLine("WARNING (Ln 464): FireRegion " + ecoName + " has fire probability > 0, but 0 weather records.  No fires will occur in this fire region.");

                            }

                        }
                        if (seasName == "Summer")
                        {
                            if (PlugIn.ModelCore.GenerateUniform() >= 0.5)
                            {
                                selectText = ("FireRegion = '" + ecoName + "' AND Season = 'Spring'");
                                //PlugIn.ModelCore.Log.WriteLine("Read Weather File SelectText = {0}.", selectText);
                                foundRows = weatherTable.Select(selectText);

                                if (foundRows.Length == 0)
                                {
                                    selectText = ("FireRegion = '" + ecoName + "' AND Season = 'Fall'");
                                    //PlugIn.ModelCore.Log.WriteLine("Read Weather File SelectText = {0}.", selectText);
                                    foundRows = weatherTable.Select(selectText);
                                }
                                if (foundRows.Length == 0)
                                {
                                    PlugIn.ModelCore.UI.WriteLine("WARNING (Ln 485): FireRegion " + ecoName + " has fire probability > 0, but 0 weather records.  No fires will occur in this fire region.");

                                }
                            }
                            else
                            {
                                selectText = ("FireRegion = '" + ecoName + "' AND Season = 'Fall'");
                                //PlugIn.ModelCore.Log.WriteLine("Read Weather File SelectText = {0}.", selectText);
                                foundRows = weatherTable.Select(selectText);

                                if (foundRows.Length == 0)
                                {
                                    selectText = ("FireRegion = '" + ecoName + "' AND Season = 'Spring'");
                                    //PlugIn.ModelCore.Log.WriteLine("Read Weather File SelectText = {0}.", selectText);
                                    foundRows = weatherTable.Select(selectText);
                                }
                                if (foundRows.Length == 0)
                                {
                                    PlugIn.ModelCore.UI.WriteLine("WARNING (Ln 503): FireRegion " + ecoName + " has fire probability > 0, but 0 weather records.  No fires will occur in this fire region.");

                                }
                            }

                        }

                        
                    }
                    if(foundRows.Length > 0)
                    {
                        //Input validation
                        double WSV, FFMC, BUI;
                        int WINDDIR, FWIBIN;
                        for(int j = 0; j < foundRows.Length; j ++) //weatherDataSet.Tables["Table"].Rows)
                        {
                            DataRow myDataRow = foundRows[j];

                            //WSV = (double)myDataRow["WSV"];
                            WSV = Convert.ToDouble(myDataRow["WSV"]);
                            //Console.WriteLine("WSV:  {0}", WSV);
                            if (WSV < 0.0)
                            {
                                throw new System.ApplicationException("Error: Wind Speed < 0:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            FFMC = Convert.ToDouble(myDataRow["FFMC"]);
                            //Console.WriteLine("FFMC:  {0}", FFMC);
                            if (FFMC < 0.0)
                            {
                                throw new System.ApplicationException("Error: FFMC < 0:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            else if (FFMC > 100.0)
                            {
                                throw new System.ApplicationException("Error: FFMC > 100:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            BUI = Convert.ToDouble(myDataRow["BUI"]);
                            //Console.WriteLine("BUI:  {0}", BUI);
                            if (BUI < 0.0)
                            {
                                throw new System.ApplicationException("Error: BUI < 0:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            WINDDIR = (int) myDataRow["WindDir"];
                            //Console.WriteLine("WindDir:  {0}", WINDDIR);
                            if (WINDDIR < 0)
                            {
                                throw new System.ApplicationException("Error: WINDDIR < 0:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            else if (WINDDIR > 360)
                            {
                                throw new System.ApplicationException("Error: WINDDIR > 360:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            FWIBIN = (int) myDataRow["FWIBin"];
                            //Console.WriteLine("FWIBIN:  {0}", FWIBIN);
                            if (FWIBIN < 1)
                            {
                                throw new System.ApplicationException("Error: FWIBIN < 1:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            else if (FWIBIN > 5)
                            {
                                throw new System.ApplicationException("Error: FWIBIN > 5:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                        }

                    }

                   

                    if(seasName == "Fall")
                    {
                    fire_region.FallRecords = recordCount;
                    }
                    else if (seasName == "Spring")
                    {
                        fire_region.SpringRecords = recordCount;
                    }
                    else if (seasName == "Summer")
                    {
                        fire_region.SummerRecords = recordCount;
                    }
                }
            }

            return weatherTable;
        }
コード例 #10
0
        //---------------------------------------------------------------------

        public static int GenerateBuildUpIndex(ISeasonParameters season)
        {
            double bui = 0.0;
            bui = GenerateRandomNum(season.BUIDist, season.BUIP1, season.BUIP2);
            if(bui < 0) bui = 0;
            if(bui > 200) bui = 200;
            
            return (int) bui;
        }
コード例 #11
0
        public static double InitialRateOfSpread(int fuelIndex, double ISI, 
                                                int PC, int PH, int PDF,
                                                ISeasonParameters season)
        {   

            FuelTypeCode siteFuelType = (FuelTypeCode) fuelIndex;
            
            //UI.WriteLine("Fuel Type Code = {0}.", siteFuelType.ToString());
            
            double RSI = 0.0;  
            
            if (siteFuelType == FuelTypeCode.C1 ||
                siteFuelType == FuelTypeCode.C2 ||
                siteFuelType == FuelTypeCode.C3 ||
                siteFuelType == FuelTypeCode.C4 ||
                siteFuelType == FuelTypeCode.C5 ||
                siteFuelType == FuelTypeCode.C6 ||
                siteFuelType == FuelTypeCode.C7)
            {
                double a = Event.fuelTypeParms[fuelIndex].A;
                double b = Event.fuelTypeParms[fuelIndex].B;
                double c = Event.fuelTypeParms[fuelIndex].C;
                
                double percentHard = (double) PH / 100.0;
                double percentConi = (double) PC / 100.0;
                
                RSI = CalculateRSI(a, b, c, ISI);
                
                if(PH > 0)
                {
                    double RSIconifer = RSI;
                    int dIndex = (int) FuelTypeCode.D1;
                    double RSIdecid = CalculateRSI(Event.fuelTypeParms[dIndex].A, Event.fuelTypeParms[dIndex].B, Event.fuelTypeParms[dIndex].C, ISI);
                
                    if(season.LeafStatus == LeafOnOff.LeafOn) 
                        RSI = (percentHard * RSIconifer) + (0.2 * percentHard * RSIdecid);
                    else 
                        RSI = (percentConi * RSIconifer) + (percentHard * RSIdecid);

                    //UI.WriteLine("Calculating ROSi for a MIXED type. PH={0}, PC={1}, LeafStatus={2}.", PH, PC, season.LeafStatus);
                    //UI.WriteLine("  RSIcon={0:0.0}, RSIdecid={1:0.0}, RSImix={2:0.000}.", RSIconifer, RSIdecid, RSI);
                    
                }
            }
                
            if( siteFuelType == FuelTypeCode.D1 ||
                siteFuelType == FuelTypeCode.S1 ||
                siteFuelType == FuelTypeCode.S2 ||
                siteFuelType == FuelTypeCode.S3)
            {
                //UI.WriteLine("Calculating ROSi for a DECIDUOUS or SLASH type.");

                double a = Event.fuelTypeParms[fuelIndex].A;
                double b = Event.fuelTypeParms[fuelIndex].B;
                double c = Event.fuelTypeParms[fuelIndex].C;
                    
                RSI = CalculateRSI(a, b, c, ISI);

                if(siteFuelType == FuelTypeCode.D1 && season.LeafStatus == LeafOnOff.LeafOn)
                    RSI *= 0.2;

            }
  /*
            if(siteFuelType == FuelTypeCode.M2)
            {

                int cIndex = (int) FuelTypeCode.C2;
                int dIndex = (int) FuelTypeCode.D1;
                
                double RSI_c2 = CalculateRSI(Event.fuelTypeParms[cIndex].A, Event.fuelTypeParms[cIndex].B, Event.fuelTypeParms[cIndex].C, ISI);
                double RSI_d1 = CalculateRSI(Event.fuelTypeParms[dIndex].A, Event.fuelTypeParms[dIndex].B, Event.fuelTypeParms[dIndex].C, ISI);
                
                RSI = ((PC/100 * RSI_c2) + (0.2 * PH/100 * RSI_d1));
            }
*/            
            if(PH > 0 && PDF > 0)
            {
                double a, b, c;
                if(season.LeafStatus == LeafOnOff.LeafOff)
                {
                    a = 170 * System.Math.Exp(-35 / PDF);
                    b = 0.082 * System.Math.Exp(-36 / PDF);
                    c = 1.698 - 0.00303 * PDF;
                } else 
                {
                    a = 170 * System.Math.Exp(-35 / PDF);
                    b = 0.0404;
                    c = 3.02 * System.Math.Exp(-0.00714 * PDF);
                }
                RSI = CalculateRSI(a, b, c, ISI);
            }
            /*
            if(siteFuelType == FuelTypeCode.M4)
            {
                double a = 170 * System.Math.Exp(-35 / PDF);
                double b = 0.0404;
                double c = 3.02 * System.Math.Exp(-0.00714 * PDF);
                
                RSI = CalculateRSI(a, b, c, ISI);
            }
            
            if(siteFuelType == FuelTypeCode.O1a || siteFuelType == FuelTypeCode.O1b)
            {
                double a = Event.fuelTypeParms[fuelIndex].A;
                double b = Event.fuelTypeParms[fuelIndex].B;
                double c = Event.fuelTypeParms[fuelIndex].C;
                
                double CF = (0.02 * percentCuring) - 1.0;
                RSI = CalculateRSI(a, b, c, ISI) * CF;
            }*/

            if(siteFuelType == FuelTypeCode.O1a)
            {
                double a, b, c;
                int percentCuring = season.PercentCuring;
                
                if(season.NameOfSeason == SeasonName.Spring)
                {
                    a = Event.fuelTypeParms[(int) FuelTypeCode.O1a].A;
                    b = Event.fuelTypeParms[(int) FuelTypeCode.O1a].B;
                    c = Event.fuelTypeParms[(int) FuelTypeCode.O1a].C;
                } else 
                {
                    a = Event.fuelTypeParms[(int) FuelTypeCode.O1b].A;
                    b = Event.fuelTypeParms[(int) FuelTypeCode.O1b].B;
                    c = Event.fuelTypeParms[(int) FuelTypeCode.O1b].C;
                }
                
                double CF = (0.02 * percentCuring) - 1.0;
                RSI = CalculateRSI(a, b, c, ISI);
                if(percentCuring > 50) 
                    RSI *= CF;
                else
                    RSI = 0;
            }
            
            if(siteFuelType == FuelTypeCode.NoFuel)
            {
                return 0;
            }

            
            return RSI;
        }
コード例 #12
0
        //---------------------------------------------------------------------

        public static DataRow GenerateDataRow(ISeasonParameters season, IFireRegion fire_region, int sizeBin)
        {
            int    weatherRandomizer = PlugIn.WeatherRandomizer;
            string seasonName        = season.NameOfSeason.ToString();
            string ecoName           = fire_region.Name;
            int    weatherBin        = 0;

            if (weatherRandomizer == 0)
            {
                weatherBin = sizeBin;
            }
            else
            {
                // First, tally the available bins and assign a probability based on their size
                // (number of records).
                // Bins can only be 1 - 5.

                int minBin = (int)System.Math.Max(1, sizeBin - weatherRandomizer);
                int maxBin = (int)System.Math.Min(5, sizeBin + weatherRandomizer);

                double[] binProbability = new double[maxBin - minBin + 1];
                int[]    binCount       = new int[maxBin - minBin + 1];
                int      binSum         = 0;

                for (int bin = minBin; bin <= maxBin; bin++)
                {
                    string    selectString = "FWIBin = '" + bin + "' AND Season = '" + seasonName + "' AND Ecoregion = '" + ecoName + "'";
                    DataRow[] rows         = PlugIn.WeatherDataTable.Select(selectString);
                    if (rows.Length == 0)
                    {
                        selectString = "FWIBin = '" + bin + "' AND Season = '" + seasonName + "' AND Ecoregion = 'All'";
                        rows         = PlugIn.WeatherDataTable.Select(selectString);
                    }

                    int numRecs = rows.Length;

                    binCount[bin - minBin] = numRecs;
                    binSum += numRecs;
                }

                for (int bin = minBin; bin <= maxBin; bin++)
                {
                    binProbability[bin - minBin] = (double)binCount[bin - minBin] / (double)binSum;
                }

                // Now randomly select from the available bins:
                double randomBinNum = PlugIn.ModelCore.GenerateUniform();

                double minProb = 0.0;
                double maxProb = 0.0;

                for (int bin = minBin; bin <= maxBin; bin++)
                {
                    maxProb += binProbability[bin - minBin];
                    if (randomBinNum >= minProb && randomBinNum < maxProb)
                    {
                        weatherBin = bin;
                        break;
                    }
                    else
                    {
                        minProb = binProbability[bin - minBin];
                    }
                }
            }
            if (weatherBin == 0)
            {
                weatherBin = sizeBin;
            }
            //throw new System.ApplicationException("No Weather Bin randomly selected. FireRegion = "+ecoName+", Season = "+seasonName+", sizeBin = "+sizeBin);

            int rowCount  = 0;
            int loopCount = 0;
            int firstDir  = 0;

            DataRow[] foundRows = null;

            if (PlugIn.ModelCore.GenerateUniform() >= 0.5)
            {
                firstDir = 1;  // Direction (+ or -) to check first if target bin is not available (+1 or -1)
            }
            else
            {
                firstDir = -1;
            }
            while (rowCount == 0)
            {
                string selectString = "FWIBin = '" + weatherBin + "' AND Season = '" + seasonName + "' AND Ecoregion = '" + ecoName + "'";
                foundRows = PlugIn.WeatherDataTable.Select(selectString);
                rowCount  = foundRows.Length;

                if (rowCount == 0)
                {
                    selectString = "FWIBin = '" + weatherBin + "' AND Season = '" + seasonName + "' AND Ecoregion = 'All'";
                    foundRows    = PlugIn.WeatherDataTable.Select(selectString);
                    rowCount     = foundRows.Length;
                }

                if (rowCount == 0)
                {
                    //PlugIn.ModelCore.UI.WriteLine("   weatherBin "+weatherBin+" Not Found.  Using alternate weatherBin.");
                    if (sizeBin == 5)
                    {
                        weatherBin = weatherBin - 1;
                    }
                    else if (sizeBin == 1)
                    {
                        weatherBin = weatherBin + 1;
                    }
                    else
                    {
                        if (loopCount == 0)
                        {
                            weatherBin = sizeBin + firstDir;
                        }
                        else if (loopCount == 1)
                        {
                            weatherBin = sizeBin - firstDir;
                        }
                        else if (loopCount == 2)
                        {
                            weatherBin = sizeBin + (firstDir * 2);
                        }
                        else if (loopCount == 3)
                        {
                            weatherBin = sizeBin - (firstDir * 2);
                        }
                        else if (loopCount == 4)
                        {
                            weatherBin = sizeBin + (firstDir * 3);
                        }
                        else if (loopCount == 5)
                        {
                            weatherBin = sizeBin - (firstDir * 3);
                        }
                        else if (loopCount == 6)
                        {
                            weatherBin = sizeBin + (firstDir * 4);
                        }
                        else
                        {
                            weatherBin = sizeBin - (firstDir * 4);
                        }
                    }
                    loopCount++;
                    if (loopCount > 100)
                    {
                        PlugIn.ModelCore.UI.WriteLine("   No Weather Rows Selected");
                        throw new System.ApplicationException("No Weather Row could be selected. Ecoregion = " + ecoName + ", Season = " + seasonName + ", sizeBin = " + sizeBin);
                    }
                }
            }
            int     newRandNum = (int)(Math.Round(PlugIn.ModelCore.GenerateUniform() * (rowCount - 1)));
            DataRow weatherRow = foundRows[newRandNum];

            return(weatherRow);
        }
コード例 #13
0
        private static double CalculateWSE(int fuelIndex, double RSF, double f_F, int PC, ISeasonParameters season)
        {
            FuelTypeCode siteFuelType = (FuelTypeCode) fuelIndex;
            double ISF, WSE;
            double a = Event.fuelTypeParms[fuelIndex].A;
            double b = Event.fuelTypeParms[fuelIndex].B;
            double c = Event.fuelTypeParms[fuelIndex].C;
            if (siteFuelType == FuelTypeCode.O1a)
            {
                double CF = (0.02 * season.PercentCuring) - 1;

                ISF = Math.Log(1 - Math.Pow((RSF/(CF * a)),(1/c)))/(-1 * b);
            }
            else
            {
                ISF = Math.Log(1 - Math.Pow((RSF / ( a)), (1 / c))) / (-1 * b);
            }
            WSE = Math.Log(ISF / (0.208 * f_F)) / 0.05039;
            return WSE;
        }
コード例 #14
0
        //---------------------------------------------------------------------

        public Parameters(int               timestep,
                          SizeType          fireSizeType,
                          bool              buildUpIndex,
                          ISeasonParameters[]  seasonParameters,
                          IWindDirectionParameters[]  windDirectionParameters,
                          IFuelTypeParameters[]  fuelTypeParameters,
                          IDamageTable[]    damages,
                          string            mapNameTemplate,
                          string            logFileName,
                          string            summaryLogFileName)
        {
            this.timestep = timestep;
            this.fireSizeType = fireSizeType;
            this.buildUpIndex = buildUpIndex;
            this.seasonParameters = seasonParameters;
            this.windDirectionParameters = windDirectionParameters;
            this.fuelTypeParameters = fuelTypeParameters;
            this.damages = damages;
            this.mapNamesTemplate = mapNameTemplate;
            this.logFileName = logFileName;
            this.summaryLogFileName = summaryLogFileName;
        }
コード例 #15
0
        //---------------------------------------------------------------------

        public static int GenerateFoliarMoistureContent(ISeasonParameters season, IEcoregion ecoregion)
        {
            double bui = 0.0;
            bui = GenerateRandomNum(season.BUIDist, season.BUIP1, season.BUIP2);
            if(bui < 0) bui = 0;
            if(bui > 200) bui = 200;
            
            return (int) bui;
        }
コード例 #16
0
        //---------------------------------------------------------------------

        public static DataRow GenerateDataRow(ISeasonParameters season, IDynamicInputRecord fire_region, int sizeBin)
        {

            int weatherRandomizer = PlugIn.WeatherRandomizer;
            string seasonName = season.NameOfSeason.ToString();
            string ecoName = fire_region.Name;
            int weatherBin = 0;

            if(weatherRandomizer == 0)
                weatherBin = sizeBin;
            else
            {
                if (weatherRandomizer == 4)
                {
                    weatherBin = -1;
                }
                else
                {
                    // First, tally the available bins and assign a probability based on their size
                    // (number of records).
                    // Bins can only be 1 - 5.

                    int minBin = (int)System.Math.Max(1, sizeBin - weatherRandomizer);
                    int maxBin = (int)System.Math.Min(5, sizeBin + weatherRandomizer);

                    double[] binProbability = new double[maxBin - minBin + 1];
                    int[] binCount = new int[maxBin - minBin + 1];
                    int binSum = 0;

                    for (int bin = minBin; bin <= maxBin; bin++)
                    {
                        string selectString = "FWIBin = '" + bin + "' AND Season = '" + seasonName + "' AND FireRegion = '" + ecoName + "'";
                        DataRow[] rows = PlugIn.WeatherDataTable.Select(selectString);
                        if (rows.Length == 0)
                        {
                            selectString = "FWIBin = '" + bin + "' AND Season = '" + seasonName + "' AND FireRegion = 'All'";
                            rows = PlugIn.WeatherDataTable.Select(selectString);
                        }

                        int numRecs = rows.Length;

                        binCount[bin - minBin] = numRecs;
                        binSum += numRecs;
                    }

                    for (int bin = minBin; bin <= maxBin; bin++)
                        binProbability[bin - minBin] = (double)binCount[bin - minBin] / (double)binSum;

                    // Now randomly select from the available bins:
                    double randomBinNum = PlugIn.ModelCore.GenerateUniform();

                    double minProb = 0.0;
                    double maxProb = 0.0;

                    for (int bin = minBin; bin <= maxBin; bin++)
                    {
                        maxProb += binProbability[bin - minBin];
                        if (randomBinNum >= minProb && randomBinNum < maxProb)
                        {
                            weatherBin = bin;
                            break;
                        }
                        else
                        {
                            minProb = binProbability[bin - minBin];
                        }
                    }
                }
            }
            if(weatherBin == 0)
                weatherBin = sizeBin;
                //throw new System.ApplicationException("No Weather Bin randomly selected. FireRegion = "+ecoName+", Season = "+seasonName+", sizeBin = "+sizeBin);

            int rowCount = 0;
            int loopCount = 0;
            int firstDir = 0;
            DataRow[] foundRows = null;

            string seasonOrig = seasonName;

            if (PlugIn.ModelCore.GenerateUniform() >= 0.5)
                firstDir = 1;  // Direction (+ or -) to check first if target bin is not available (+1 or -1)
            else
                firstDir = -1;
            while (rowCount == 0)
            {
                string selectString = "FWIBin = '" + weatherBin + "' AND Season = '" + seasonName + "' AND FireRegion = '" + ecoName + "'";
                if (weatherBin == -1)
                {
                    selectString = "Season = '" + seasonName + "' AND FireRegion = '" + ecoName + "'";
                }
               
                foundRows = PlugIn.WeatherDataTable.Select(selectString);
                rowCount = foundRows.Length;

                if (rowCount == 0)
                {
                    selectString = "FWIBin = '" + weatherBin + "' AND Season = '" + seasonName + "' AND FireRegion = 'All'";
                    {
                        selectString = "Season = '" + seasonName + "' AND FireRegion = 'All'";
                    }
                    foundRows = PlugIn.WeatherDataTable.Select(selectString);
                    rowCount = foundRows.Length;
                }

                if (rowCount == 0)
                {
                    //PlugIn.ModelCore.Log.WriteLine("   weatherBin "+weatherBin+" Not Found.  Using alternate weatherBin.");
                    if (sizeBin == 5)
                        weatherBin = weatherBin - 1;
                    else if (sizeBin == 1)
                        weatherBin = weatherBin + 1;
                    else
                    {
                        if (loopCount == 0)
                            weatherBin = sizeBin + firstDir;
                        else if (loopCount == 1)
                            weatherBin = sizeBin - firstDir;
                        else if (loopCount == 2)
                            weatherBin = sizeBin + (firstDir * 2);
                        else if (loopCount == 3)
                            weatherBin = sizeBin - (firstDir * 2);
                        else if (loopCount == 4)
                            weatherBin = sizeBin + (firstDir * 3);
                        else if (loopCount == 5)
                            weatherBin = sizeBin - (firstDir * 3);
                        else if (loopCount == 6)
                            weatherBin = sizeBin + (firstDir * 4);
                        else
                            weatherBin = sizeBin - (firstDir * 4);
                    }
                    loopCount ++;
                    if (loopCount > 100)
                    {

                        PlugIn.ModelCore.UI.WriteLine("   No Weather Rows Selected.  Using alternate season.");
                        if (seasonOrig == "Spring" || seasonOrig == "Fall")
                            seasonName = "Summer";
                        else // Summer
                        {
                            if (firstDir == 1)
                            {
                                seasonName = "Spring";
                            }
                            else
                            {
                                seasonName = "Fall";
                            }
                        }
                        
                    }
                    if (loopCount > 200)
                    {

                        PlugIn.ModelCore.UI.WriteLine("   No Weather Rows Selected.  Using alternate season 2.");
                        if (seasonOrig == "Spring")
                            seasonName = "Fall";
                        else
                            if (seasonOrig == "Fall")
                                seasonName = "Spring";
                            else // Summer
                            {
                                if (firstDir == 1)
                                {
                                    seasonName = "Fall";
                                }
                                else
                                {
                                    seasonName = "Spring";
                                }
                            }

                    }
                    if (loopCount > 300)
                    {
                        PlugIn.ModelCore.UI.WriteLine("WARNING (Ln 350): FireRegion " + ecoName + " has fire probability > 0, but 0 weather records.  No fires will occur in this fire region.");
                        break;
                    }

                }
            }
            if (rowCount > 0)
            {
                int newRandNum = (int)(Math.Round(PlugIn.ModelCore.GenerateUniform() * (rowCount - 1)));
                DataRow weatherRow = foundRows[newRandNum];

                return weatherRow;
            }
            else
            {
                return null;
            }
        }
コード例 #17
0
        //---------------------------------------------------------------------

        private Event(ActiveSite initiationSite, ISeasonParameters[] seasons, IWindDirectionParameters[] windDirs)
        {
            this.initiationSite = initiationSite;
            this.sitesInEvent = new int[Ecoregions.Dataset.Count];
            foreach(IEcoregion ecoregion in Ecoregions.Dataset)
                this.sitesInEvent[ecoregion.Index] = 0;
            this.cohortsKilled = 0;
            this.eventSeverity = 0;
            this.totalSitesDamaged = 0;
            this.lengthB = 0.0;
            this.lengthA = 0.0;
            this.lengthD = 0.0;
            
            this.fireSeason           = Weather.GenerateSeason(seasons);
            this.windSpeed            = Weather.GenerateWindSpeed(this.fireSeason);
            this.fineFuelMoistureCode = Weather.GenerateFineFuelMoistureCode(this.fireSeason);
            this.buildUpIndex         = Weather.GenerateBuildUpIndex(this.fireSeason);

            IWindDirectionParameters windDir = windDirs[(int) this.fireSeason.NameOfSeason];
            this.windDirection        = Weather.GenerateWindDirection(windDir);

            

        }
コード例 #18
0
        //---------------------------------------------------------------------

        public static void Initialize(ISeasonParameters[] seasons, 
                                      IFuelTypeParameters[] fuelTypeParameters,
                                      IDamageTable[]    damages)
        {
            double totalSeasonFireProb = 0.0;
            foreach(ISeasonParameters season in seasons)
                totalSeasonFireProb += season.FireProbability;
            if (totalSeasonFireProb != 1.0)
                throw new System.ApplicationException("Error: Season Probabilities don't add to 1.0");
            Event.fuelTypeParms = fuelTypeParameters;
            Event.damages = damages;

            cohorts = Model.Core.SuccessionCohorts as ILandscapeCohorts;
            if (cohorts == null)
                throw new System.ApplicationException("Error: Cohorts don't support age-cohort interface");
        }
コード例 #19
0
        //---------------------------------------------------------------------
        public static Event Initiate(ActiveSite site,
                                     int timestep,
                                     SizeType fireSizeType,
                                     bool bui,
                                     ISeasonParameters[] seasons,
                                     double severityCalibrate)
        {
            //Adjust ignition probability (measured on an annual basis) for the
            //user determined fire time step.
            int fuelIndex = SiteVars.CFSFuelType[site];

            double initProb = FuelTypeParms[fuelIndex].InitiationProbability;

            //If mixed type, need to use weighted average initProb
            if (FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Conifer && SiteVars.PercentHardwood[site] > 0) //Mixed type
            {
                double decidInitProb;
                int    decidFuelIndex = SiteVars.DecidFuelType[site];
                if (decidFuelIndex > 0)
                {
                    decidInitProb = FuelTypeParms[decidFuelIndex].InitiationProbability;
                    initProb      = (initProb * SiteVars.PercentConifer[site] + decidInitProb * SiteVars.PercentHardwood[site]) / 100;
                }
            }

            //The initial site must exceed the probability of initiation and
            //have a severity > 0 and exceed the ignition threshold:
            double randomNum = PlugIn.ModelCore.GenerateUniform();

            ISeasonParameters fireSeason = Weather.GenerateSeason(seasons);

            if (SiteVars.PercentDeadFir[site] > 0) // If M3 or M4 type, use initProb if greater
            {
                if (SiteVars.PercentConifer[site] == 100 ||
                    fireSeason.LeafStatus == LeafOnOff.LeafOff)
                {
                    //find the fuelindex with surfacefuel M3
                    foreach (FuelType listFuel in FuelTypeParms)
                    {
                        if (listFuel.SurfaceFuel == SurfaceFuelType.M3)
                        {
                            if (listFuel.InitiationProbability > initProb) //Only use M3 initprob if > c-type
                            {
                                initProb = listFuel.InitiationProbability;
                            }
                        }
                    }
                }
                else
                {
                    //find the fuel index with surfacefuel M4
                    foreach (FuelType listFuel in FuelTypeParms)
                    {
                        if (listFuel.SurfaceFuel == SurfaceFuelType.M4)
                        {
                            if (listFuel.InitiationProbability > initProb) //Only use M4 initprob if > c-type
                            {
                                initProb = listFuel.InitiationProbability;
                            }
                        }
                    }
                }
            }
            if (randomNum <= initProb)
            {
                if (isDebugEnabled)
                {
                    PlugIn.ModelCore.UI.WriteLine("   Generating a new fire event...");
                }

                Event fireEvent = new Event(site, fireSeason, fireSizeType); //Must create event to determine season


                // Test that adequate weather data was retrieved:
                if (fireEvent.windSpeed == 0 && fireEvent.fineFuelMoistureCode == 0 && fireEvent.buildUpIndex == 0)
                {
                    PlugIn.ModelCore.UI.WriteLine("   No weather data available:  {0}; fire_region = {1}.", fireEvent.fireSeason.NameOfSeason, fireEvent.initiationFireRegion.Name);
                    return(null);
                }

                if (fireEvent.FireSeason.PercentCuring == 0 && FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Open)
                {
                    return(null);
                }

                if (!fireEvent.Spread(site, fireSizeType, bui, severityCalibrate))
                {
                    return(null);
                }
                else
                {
                    return(fireEvent);
                }
            }
            else
            {
                if (isDebugEnabled)
                {
                    PlugIn.ModelCore.UI.WriteLine("   Fire Event failed to initiate due to fuel type initiation probability");
                }
                //return null;
            }
            return(null);
        }
コード例 #20
0
        private static double CalculateWSE(int fuelIndex, double RSF, double f_F, /*int PC,*/ ISeasonParameters season)
        {
            //FuelTypeCode siteFuelType = (FuelTypeCode) fuelIndex;
            double ISF, WSE;
            double a = Event.FuelTypeParms[fuelIndex].A;
            double b = Event.FuelTypeParms[fuelIndex].B;
            double c = Event.FuelTypeParms[fuelIndex].C;

            if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Open)
            //siteFuelType == FuelTypeCode.O1a)
            {
                double CF = (0.02 * season.PercentCuring) - 1;

                ISF = Math.Log(1 - Math.Pow((RSF / (CF * a)), (1 / c))) / (-1 * b);
            }
            else
            {
                ISF = Math.Log(1 - Math.Pow((RSF / (a)), (1 / c))) / (-1 * b);
            }
            WSE = Math.Log(ISF / (0.208 * f_F)) / 0.05039;
            return(WSE);
        }
コード例 #21
0
        private static List <int> CalculateSlopeEffect(int windSpeed, int windDirection,
                                                       Site site, double RSZ, double f_F,
                                                       ISeasonParameters season)
        {
            List <int> siteWindList = new List <int>();

            if ((SiteVars.GroundSlope[site] == 0) || (RSZ == 0))
            {
                siteWindSpeed     = windSpeed;
                siteWindDirection = windDirection;
                //nothing is changed
            }
            else
            {
                //FuelTypeCode siteFuelType = (FuelTypeCode)SiteVars.CFSFuelType[site]; ;

                //Walk through the equations from FBP:

                double SF = 0;
                if (SiteVars.GroundSlope[site] > 60)
                {
                    SF = CalculateSF(60);  //FBP 39 has a max slope of 60%
                }
                else
                {
                    SF = CalculateSF(SiteVars.GroundSlope[site]); //FBP 39
                }
                double RSF = RSZ * SF;                            //FBP 40

                double ISF = 0.0;
                double a, b, c;
                int    fuelIndex = SiteVars.CFSFuelType[site];

                if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Open)
                //(siteFuelType == FuelTypeCode.O1a)
                {
                    int    percentCuring = season.PercentCuring;
                    double CF            = (0.02 * percentCuring) - 1.0;
                    if (season.NameOfSeason == SeasonName.Spring)
                    {
                        a = 190;    //Event.FuelTypeParms[(int)FuelTypeCode.O1a].A;
                        b = 0.0310; //Event.FuelTypeParms[(int)FuelTypeCode.O1a].B;
                        c = 1.4;    //Event.FuelTypeParms[(int)FuelTypeCode.O1a].C;
                    }
                    else
                    {
                        a = 250;    //Event.FuelTypeParms[(int)FuelTypeCode.O1b].A;
                        b = 0.0350; //Event.FuelTypeParms[(int)FuelTypeCode.O1b].B;
                        c = 1.7;    //Event.FuelTypeParms[(int)FuelTypeCode.O1b].C;
                    }

                    ISF = Math.Log((1 - Math.Pow((RSF / (CF * a)), (1 / c)))) / (-1 * b); //FBP 43
                }
                else
                {
                    a = Event.FuelTypeParms[fuelIndex].A;
                    b = Event.FuelTypeParms[fuelIndex].B;
                    c = Event.FuelTypeParms[fuelIndex].C;

                    if (SiteVars.PercentDeadFir[site] > 0)
                    {
                        int PDF = SiteVars.PercentDeadFir[site];
                        if ((SiteVars.PercentHardwood[site] > 0) && (season.LeafStatus == LeafOnOff.LeafOn)) //M-4
                        {
                            a = 140 * System.Math.Exp((-1) * 35.5 / (double)PDF);
                            b = 0.0404;
                            c = 3.02 * System.Math.Exp((-1) * 0.00714 * (double)PDF);
                        }

                        else //M-3
                        {
                            a = 170 * System.Math.Exp((-1) * 35 / (double)PDF);
                            b = 0.082 * System.Math.Exp((-1) * 36 / (double)PDF);
                            c = 1.698 - (0.00303 * (double)PDF);
                        }
                        ISF = Math.Log((1 - Math.Pow((RSF / a), (1 / c)))) / (-1 * b); //FBP 41
                    }

                    else if ((SiteVars.PercentHardwood[site] > 0) && (SiteVars.PercentConifer[site] > 0))
                    {
                        int PC = SiteVars.PercentConifer[site];
                        ISF = Math.Log((1 - Math.Pow(((100 - RSF) / (PC * a)), (1 / c)))) / (-1 * b); //FBP 42
                    }
                    else
                    {
                        ISF = Math.Log((1 - Math.Pow((RSF / a), (1 / c)))) / (-1 * b); //FBP 41
                    }
                }
                double WSE = (Math.Log((ISF) / (.208 * f_F))) / (0.05039);                //FBP 43: The effect the % slope would have on ROS if it were a wind speed
                double WAZ = (double)windDirection * Math.PI / 180;                       //wind direction/azimuth in radians
                double SAZ = (double)SiteVars.UphillSlopeAzimuth[site] * Math.PI / 180;   //uphill slope azimuth in radians

                double WSX = ((double)windSpeed * Math.Sin(WAZ)) + (WSE * Math.Sin(SAZ)); //FBP 47
                double WSY = ((double)windSpeed * Math.Cos(WAZ)) + (WSE * Math.Cos(SAZ)); //FBP 48


                double WSV = Math.Sqrt(Math.Pow(WSX, 2) + Math.Pow(WSY, 2));  //FBP 49
                siteWindSpeed = (int)WSV;

                double RAZ = Math.Acos(WSY / WSV); //FBP 50
                RAZ = RAZ * 180 / Math.PI;         // net wind direction radians to degrees

                if (WSX < 0)
                {
                    RAZ = 360 - RAZ;
                }
                siteWindDirection = (int)RAZ;
                if (siteWindSpeed < 0 || siteWindDirection < 0)
                {
                }
            }
            siteWindList.Add(siteWindSpeed);
            siteWindList.Add(siteWindDirection);
            SiteVars.SiteWindSpeed[site]     = (ushort)siteWindSpeed;
            SiteVars.SiteWindDirection[site] = (ushort)siteWindDirection;

            return(siteWindList);
        }
コード例 #22
0
        private static double CalculateTravelTime(Site site, Site firesource, Event fireEvent, bool buildUp)
        {
            if (!site.IsActive || !firesource.IsActive)
            {
                throw new ApplicationException("Either site or fire source are not active.");
            }

            //Calculate Fire regime size adjustment:
            IFireRegion fire_region = SiteVars.FireRegion[site];
            double      FRUA        = fire_region.MeanSize;

            fire_region = SiteVars.FireRegion[firesource];
            FRUA        = FRUA / fire_region.MeanSize;


            int        fuelIndex = SiteVars.CFSFuelType[site];
            int        percentConifer = SiteVars.PercentConifer[site];
            int        percentHardwood = SiteVars.PercentHardwood[site];
            int        percentDeadFir = SiteVars.PercentDeadFir[site];
            List <int> siteWindList = new List <int>();
            int        siteWindSpeed, siteWindDirection;

            //PlugIn.ModelCore.UI.WriteLine("         Fuel Type Code = {0}.", temp.ToString());

            ISeasonParameters season = fireEvent.FireSeason;

            double f_F = Weather.CalculateFuelMoistureEffect(fireEvent.FFMC);
            double ISZ = 0.208 * f_F;  //No wind
            double RSZ = FuelEffects.InitialRateOfSpread(ISZ, season, site);

            if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.ConiferPlantation)//SurfaceFuel == SurfaceFuelType.C6)
            {
                double FME = (Math.Pow((1.5 - (0.00275 * fireEvent.FMC)), 4) / (460 + (25.9 * fireEvent.FMC))) * 1000;
                double RSC = FuelEffects.CalculateRSI(60, 0.0497, 1, ISZ) * (FME / 0.778);
                double CSI = 0.001 * Math.Pow(7, 1.5) * Math.Pow((460 + 25.9 * fireEvent.FMC), 1.5);
                double SFC = FireSeverity.SurfaceFuelConsumption(fuelIndex, fireEvent.FFMC, fireEvent.BuildUpIndex, percentHardwood, percentDeadFir);
                double RSO = CSI / (300 * SFC);
                double CFB = 0;
                if (RSZ > RSO)
                {
                    CFB = 1 - Math.Exp(-0.23 * (RSZ - RSO));
                }
                RSZ = RSZ + (CFB * (RSC - RSZ));
            }
            double BE = 0;

            siteWindList = CalculateSlopeEffect(fireEvent.WindSpeed, fireEvent.WindDirection, site, RSZ, f_F, season);
            if (siteWindList.Count > 0)
            {
                siteWindSpeed     = siteWindList[0];
                siteWindDirection = siteWindList[1];
            }
            else
            {
                siteWindSpeed     = fireEvent.WindSpeed;
                siteWindDirection = fireEvent.WindDirection;
            }

            double f_backW = Weather.CalculateBackWindEffect(siteWindSpeed);
            double f_W     = Weather.CalculateWindEffect(siteWindSpeed);

            double ISI = 0.208 * f_F * f_W;

            SiteVars.ISI[site] = ISI;

            double BISI = 0.208 * f_F * f_backW;

            double BROSi = FuelEffects.InitialRateOfSpread(BISI, season, site);
            double ROSi  = FuelEffects.InitialRateOfSpread(ISI, season, site);

            if (ROSi == 0)
            {
                SiteVars.RateOfSpread[site] = 0;
                SiteVars.AdjROS[site]       = 0;
                return(Double.PositiveInfinity);
            }
            else
            {
                BROSi *= FRUA;
                ROSi  *= FRUA;

                if (buildUp)
                {
                    if (SiteVars.PercentDeadFir[site] > 0) //either criteria indicates a DEAD FIR type
                    {
                        BE = Math.Exp(50 * Math.Log(0.80) * ((1 / (double)fireEvent.BuildUpIndex) - (1 / (double)50)));
                    }
                    else
                    {
                        BE = Math.Exp(50.0 * Math.Log(Event.FuelTypeParms[fuelIndex].Q) * ((1.0 / (double)fireEvent.BuildUpIndex) - (1 / (double)Event.FuelTypeParms[fuelIndex].BUI)));
                    }
                }
                else
                {
                    BE = 1;
                }
                ROSi  *= BE;
                BROSi *= BE;
                SiteVars.RateOfSpread[site] = ROSi;

                double LB = CalculateLengthBreadthRatio(siteWindSpeed, fuelIndex);

                double FROSi = (ROSi + BROSi) / (LB * 2.0);//        (FBP; 89)

                double alpha = siteWindDirection * (-1);
                double A     = FROSi;
                double B     = A * LB; //fireEvent.LB;
                double C     = B - BROSi;

                //  Equations below for e, p, b, c, a utlize the polar equation
                //  for an ellipse, given at:
                //  http://www.du.edu/~jcalvert/math/ellipse.htm
                //  Note that a and b are switched from those defined in these equations
                //  so that they will fit in Finney's equation below

                double e     = Math.Sqrt((double)1 - (Math.Pow(((double)1 / LB), 2)));                   //e = Eccentricity
                double dist  = CellDistanceBetweenSites(site, firesource) * PlugIn.ModelCore.CellLength; //dist = r in Calvert's equation
                double r     = ROSi;
                double time  = 0;
                double index = 1;

                if (dist != 0)
                {
                    double beta = BetaRand(firesource, site, alpha);         // Beta = angle between wind direction, site
                    double p    = dist * (1 + e * Math.Cos(Math.PI - beta)); // p = semi-latus rectum = dist from focus to ellipse perimeter perpendicular to major axis
                    double b    = p / (1 - (e * e));                         // b = half major axis (a in Calvert's equations)
                    double a    = b * Math.Sqrt(1 - (e * e));                // a = half minor axis (b in Calvert's equations)
                    double c    = e * b;                                     // c = dist between focus and center

                    // New (10/22/2007) equations to get r
                    // a, b, c, and dist are real distances in m
                    time = (b + c) / ROSi;  // Calculate the time it would take to travel the distance of b+c if ROSi was the rate
                    r    = dist / time;     // Calculate the ROS given the distance to the cell and the time

                    //++++++++++
                    // This is a better way to make adjustments to account for randomization of angles
                    // These equations were derived in MathCad (Beta_Adjust.xmcd)
                    // See rationale for adjustments in Randomization Summary.doc

                    index = 1;
                    if (beta < 0)
                    {
                        beta = (Math.PI * 2) + beta;
                    }
                    double L2 = LB * LB;

                    double partA = L2 * Math.Pow(((L2 - 1) / L2), 0.5);

                    double partB = (-2) * (Math.Atan(Math.Tan(((0.5) * beta) + ((0.0625) * (Math.PI))) * Math.Pow((2 * L2 + 2 * L2 * Math.Pow(((LB - 1) * ((LB + 1) / L2)), (0.5)) - 1), (0.5))));

                    double partC = (((-1) * (L2)) + (partA * Math.Cos(beta)) - (partA) + (Math.Cos(beta) * L2) - (Math.Cos(beta))) / (Math.Pow(((2 * L2) + (2 * partA) - 1), (0.5)));

                    double partD = (2) * (Math.Atan(((double)1 / (Math.Tan(((0.5) * beta) + ((0.4375) * (Math.PI))))) * Math.Pow((2 * L2 + 2 * L2 * Math.Pow(((LB - 1) * ((LB + 1) / L2)), (0.5)) - 1), (0.5))));
                    if ((((beta + 0.125 * Math.PI) >= Math.PI) && ((beta - 0.125 * Math.PI) >= Math.PI)) || (((beta + 0.125 * Math.PI) <= Math.PI) && ((beta - 0.125 * Math.PI) <= Math.PI)))
                    {
                        index = 4 * (partB * partC - partD * partC) / Math.PI;

                        //Console.WriteLine("Beta = {0}; LB = {1}; partA = {2}; partB = {3}, partC = {4}, partD = {5}; Index = {6}", Beta, LB, partA, partB, partC, partD, index);
                    }
                    else
                    {
                        double indexA  = ((-1) * Math.PI * partC - partD * partC) / (Math.PI * ((double)9 / (double)8) - beta);
                        double indexB  = (partB * partC - Math.PI * partC) / (beta - Math.PI * ((double)7 / (double)8));
                        double weightA = (Math.PI - (beta - 0.125 * Math.PI)) / (0.25 * Math.PI);
                        double weightB = ((beta + 0.125 * Math.PI) - Math.PI) / (0.25 * Math.PI);
                        index = indexA * weightA + indexB * weightB;
                        //Console.WriteLine("Beta = {0}; IndexA = {1}; weightA = {2}; IndexB = {3}; weightB = {4}; Index = {5}", Beta, indexA, weightA, indexB, weightB, index);
                    }
                    r = r * (1 / index);
                    //++++++++++
                }
                if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.ConiferPlantation) //(int)FuelTypeCode.C6)
                {
                    double FME = (Math.Pow((1.5 - (0.00275 * fireEvent.FMC)), 4) / (460 + (25.9 * fireEvent.FMC))) * 1000;
                    double RSC = FuelEffects.CalculateRSI(60, 0.0497, 1, ISI) * (FME / 0.778);
                    double CSI = 0.001 * Math.Pow(7, 1.5) * Math.Pow((460 + 25.9 * fireEvent.FMC), 1.5);
                    double SFC = FireSeverity.SurfaceFuelConsumption(fuelIndex, fireEvent.FFMC, fireEvent.BuildUpIndex, percentHardwood, percentDeadFir);
                    double RSO = CSI / (300 * SFC);
                    double CFB = 0;
                    if (r > RSO)
                    {
                        CFB = 1 - Math.Exp(-0.23 * (r - RSO));
                    }
                    r = r + (CFB * (RSC - r));
                }


                //-----Added by BRM-----
                SiteVars.AdjROS[site] = r;
                //----------

                //PlugIn.ModelCore.UI.WriteLine("      FROSi = {0}, BROSi = {1}.", FROSi, BROSi);
                //PlugIn.ModelCore.UI.WriteLine("      beta = {0:0.00}, theta = {1:0.00}, alpha = {2:0.00}, Travel time = {3:0.000000}.", beta, theta, alpha, 1/r);
                //PlugIn.ModelCore.UI.WriteLine("      Travel time = {0:0.000000}.  R = {1}.", 1/r, r);
                if (site == firesource)
                {
                    double rate = 1.0 / r;                                  //units = minutes / meter
                    double cost = rate * PlugIn.ModelCore.CellLength / 2.0; //units = minutes
                    return(cost);
                }
                else
                {
                    double rate = 1.0 / r;                            //units = minutes / meter
                    double cost = rate * PlugIn.ModelCore.CellLength; //units = minutes
                    //if (cost < 1)
                    //   PlugIn.ModelCore.UI.WriteLine("Travel time < 1 min");
                    return(cost);
                }
            }
        }
コード例 #23
0
        // ---------------------------------------------------------------------
        // This method calculates the initial rate of spread for a specific site.
        // See below for the method that estimates the initial rate of spread for a broad area.

        public static double InitialRateOfSpread(double ISI, ISeasonParameters season, Site site)
        {
            int fuelIndex = SiteVars.CFSFuelType[site];
            int PC        = SiteVars.PercentConifer[site];
            int PH        = SiteVars.PercentHardwood[site];
            int PDF       = SiteVars.PercentDeadFir[site];

            //PlugIn.ModelCore.UI.WriteLine("Fuel Type Code = {0}.", siteFuelType.ToString());

            double RSI = 0.0;

            if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Conifer ||
                Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.ConiferPlantation)
            {
                double a = Event.FuelTypeParms[fuelIndex].A;
                double b = Event.FuelTypeParms[fuelIndex].B;
                double c = Event.FuelTypeParms[fuelIndex].C;

                double percentHard = (double)PH / 100.0;
                double percentConi = (double)PC / 100.0;

                RSI = CalculateRSI(a, b, c, ISI);


                if (PDF > 0)
                {
                    if (PH > 0 && season.LeafStatus == LeafOnOff.LeafOn) //M-4
                    {
                        a = 140 * Math.Exp((-1) * 35.5 / (double)PDF);
                        b = 0.0404;
                        c = 3.02 * Math.Exp((-1) * 0.00714 * (double)PDF);
                    }
                    else  //M-3
                    {
                        a = 170 * Math.Exp((-1) * 35 / (double)PDF);
                        b = 0.082 * Math.Exp((-1) * 36 / (double)PDF);
                        c = 1.698 - (0.00303 * PDF);
                    }
                    double MRSI = CalculateRSI(a, b, c, ISI);
                    if (MRSI > RSI)
                    {
                        RSI = MRSI;
                    }
                }

                // These are the classic MIXED CONIFER + DECIDUOUS
                else if (PH > 0)
                {
                    double RSIconifer = RSI;
                    int    dIndex     = SiteVars.DecidFuelType[site]; //(int)FuelTypeCode.D1;
                    double RSIdecid   = CalculateRSI(Event.FuelTypeParms[dIndex].A, Event.FuelTypeParms[dIndex].B, Event.FuelTypeParms[dIndex].C, ISI);

                    if (season.LeafStatus == LeafOnOff.LeafOn)  //M-2
                    {
                        RSI = ((1 - percentHard) * RSIconifer) + (0.2 * percentHard * RSIdecid);
                    }
                    else  //M-1
                    {
                        RSI = ((1 - percentHard) * RSIconifer) + (percentHard * RSIdecid);
                    }

                    //PlugIn.ModelCore.UI.WriteLine("Calculating ROSi for a MIXED type. PH={0}, PC={1}, LeafStatus={2}.", PH, PC, season.LeafStatus);
                    //PlugIn.ModelCore.UI.WriteLine("  RSIcon={0:0.0}, RSIdecid={1:0.0}, RSImix={2:0.000}.", RSIconifer, RSIdecid, RSI);
                }
            }


            if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Open)
            //siteFuelType == FuelTypeCode.O1a)
            {
                double a, b, c;
                int    percentCuring = season.PercentCuring;

                if (season.NameOfSeason == SeasonName.Spring) //O1a
                {
                    a = 190;                                  //Event.FuelTypeParms[(int)FuelTypeCode.O1a].A;
                    b = 0.0310;                               //Event.FuelTypeParms[(int)FuelTypeCode.O1a].B;
                    c = 1.4;                                  //Event.FuelTypeParms[(int)FuelTypeCode.O1a].C;
                }
                else                                          //O1b
                {
                    a = 250;                                  //Event.FuelTypeParms[(int)FuelTypeCode.O1b].A;
                    b = 0.0350;                               //Event.FuelTypeParms[(int)FuelTypeCode.O1b].B;
                    c = 1.7;                                  //Event.FuelTypeParms[(int)FuelTypeCode.O1b].C;
                }

                double CF = (0.02 * percentCuring) - 1.0;
                RSI = CalculateRSI(a, b, c, ISI);
                if (percentCuring > 50)
                {
                    RSI *= CF;
                }
                else
                {
                    RSI = 0;
                }
                if (PDF > 0)
                {
                    if (season.LeafStatus == LeafOnOff.LeafOn) //M-4
                    {
                        a = 140 * Math.Exp((-1) * 35.5 / (double)PDF);
                        b = 0.0404;
                        c = 3.02 * Math.Exp((-1) * 0.00714 * (double)PDF);
                    }
                    else //M-3
                    {
                        a = 170 * (Math.Exp(((-1) * 35) / (double)PDF));
                        b = 0.082 * (Math.Exp(((-1) * 36) / (double)PDF));
                        c = 1.698 - (0.00303 * (double)PDF);
                    }
                    double MRSI = CalculateRSI(a, b, c, ISI);
                    if (MRSI > RSI)
                    {
                        RSI = MRSI;
                    }
                }
            }

            if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.NoFuel || fuelIndex == 0)
            //siteFuelType == FuelTypeCode.NoFuel)
            {
                if (PDF > 0)
                {
                    double a = 0, b = 0, c = 0;
                    if (season.LeafStatus == LeafOnOff.LeafOn) //M-4
                    {
                        a = 140 * Math.Exp((-1) * 35.5 / (double)PDF);
                        b = 0.0404;
                        c = 3.02 * Math.Exp((-1) * 0.00714 * (double)PDF);
                    }
                    else //M-3
                    {
                        a = 170 * (Math.Exp(((-1) * 35) / (double)PDF));
                        b = 0.082 * (Math.Exp(((-1) * 36) / (double)PDF));
                        c = 1.698 - (0.00303 * (double)PDF);
                    }
                    RSI = CalculateRSI(a, b, c, ISI);
                }

                else
                {
                    return(0);
                }
            }

            if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Slash ||
                Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Deciduous)
            {
                //PlugIn.ModelCore.UI.WriteLine("Calculating ROSi for a DECIDUOUS or SLASH type.");

                double a = Event.FuelTypeParms[fuelIndex].A;
                double b = Event.FuelTypeParms[fuelIndex].B;
                double c = Event.FuelTypeParms[fuelIndex].C;

                RSI = CalculateRSI(a, b, c, ISI);

                if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Deciduous &&
                    season.LeafStatus == LeafOnOff.LeafOn)
                {
                    //if(siteFuelType == FuelTypeCode.D1 && season.LeafStatus == LeafOnOff.LeafOn)
                    RSI *= 0.2;
                }

                if (PDF > 0)
                {
                    if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Deciduous &&
                        season.LeafStatus == LeafOnOff.LeafOn)     //M-4
                    //siteFuelType == FuelTypeCode.D1)
                    {
                        a = 140 * Math.Exp((-1) * 35.5 / (double)PDF);
                        b = 0.0404;
                        c = 3.02 * Math.Exp((-1) * 0.00714 * (double)PDF);
                    }
                    else //M-3
                    {
                        a = 170 * (Math.Exp(((-1) * 35) / (double)PDF));
                        b = 0.082 * (Math.Exp(((-1) * 36) / (double)PDF));
                        c = 1.698 - (0.00303 * (double)PDF);
                    }
                    double MRSI = CalculateRSI(a, b, c, ISI);
                    if (MRSI > RSI)
                    {
                        RSI = MRSI;
                    }
                }
            }


            return(RSI);
        }
コード例 #24
0
        //---------------------------------------------------------------------
        public static Event Initiate(ActiveSite site,
                                     int        timestep,
                                     SizeType   fireSizeType, 
                                     bool       bui,
                                     ISeasonParameters[] seasons, 
                                     IWindDirectionParameters[] windDirs)
        {

            
            //Adjust ignition probability (measured on an annual basis) for the 
            //user determined fire time step.
            int fuelIndex = SiteVars.CFSFuelType[site];
            //-----Edited by BRM-----
            //double initProb = fuelTypeParms[fuelIndex].InitiationProbability * timestep;
            double initProb = fuelTypeParms[fuelIndex].InitiationProbability;
            //---------

            //The initial site must exceed the probability of initiation and
            //have a severity > 0 and exceed the ignition threshold:
            if (Util.Random.GenerateUniform() <= initProb)
            {
                Event FireEvent = new Event(site, seasons, windDirs);
                
                if(!FireEvent.Spread(site, fireSizeType, bui))
                    return null;
                else 
                    return FireEvent;
            }
            
            return null;
        }
コード例 #25
0
        private static List<int> CalculateSlopeEffect(int windSpeed, int windDirection, 
                                                Site site, double RSZ, double f_F,
                                                ISeasonParameters season)
        {
            List<int> siteWindList = new List<int>();
            if (SiteVars.GroundSlope[site] == 0)
            {
                siteWindSpeed = windSpeed;
                siteWindDirection = windDirection;
                //nothing is changed
            }
            else
            {
                FuelTypeCode siteFuelType = (FuelTypeCode)SiteVars.CFSFuelType[site]; ;

                //Walk through the equations from FBP:

               
                double SF = CalculateSF(SiteVars.GroundSlope[site]);  //FBP 39

                double RSF = RSZ * SF;  //FBP 40

                double ISF = 0.0;
                double a, b, c;
                int fuelIndex = SiteVars.CFSFuelType[site];

                if (siteFuelType == FuelTypeCode.O1a)
                {
                    int percentCuring = season.PercentCuring;
                    double CF = (0.02 * percentCuring) - 1.0;
                    if (season.NameOfSeason == SeasonName.Spring)
                    {
                        a = Event.fuelTypeParms[(int)FuelTypeCode.O1a].A;
                        b = Event.fuelTypeParms[(int)FuelTypeCode.O1a].B;
                        c = Event.fuelTypeParms[(int)FuelTypeCode.O1a].C;
                    }
                    else
                    {
                        a = Event.fuelTypeParms[(int)FuelTypeCode.O1b].A;
                        b = Event.fuelTypeParms[(int)FuelTypeCode.O1b].B;
                        c = Event.fuelTypeParms[(int)FuelTypeCode.O1b].C;
                    }

                    ISF = Math.Log((1 - Math.Pow((RSF / (CF * a)), (1 / c)))) / (-1 * b); //FBP 43
                }
                else
                {
                    a = Event.fuelTypeParms[fuelIndex].A;
                    b = Event.fuelTypeParms[fuelIndex].B;
                    c = Event.fuelTypeParms[fuelIndex].C;

                    if (SiteVars.PercentHardwood[site] > 0)
                    {
                        int PC = SiteVars.PercentConifer[site];
                        ISF = Math.Log((1 - Math.Pow(((100 - RSF) / (PC * a)), (1 / c)))) / (-1 * b); //FBP 42
                    }
                    else
                    {
                        ISF = Math.Log((1 - Math.Pow(((RSF) / (a)), (1 / c)))) / (-1 * b); //FBP 41
                    }
                }
                double WSE = (Math.Log((ISF) / (.208 * f_F))) / (0.05039); //FBP 43: The effect the % slope would have on ROS if it were a wind speed
                double WAZ = windDirection * Math.PI / 180;  //wind direction/azimuth in radians
                double SAZ = SiteVars.UphillSlopeAzimuth[site] * Math.PI / 180;  //uphill slope azimuth in radians
                
                double WSX = (windSpeed * Math.Sin(WAZ)) + (WSE * Math.Sin(SAZ));  //FBP 47 
                double WSY = (windSpeed * Math.Cos(WAZ)) + (WSE * Math.Cos(SAZ));  //FBP 48

                 
                double WSV = Math.Sqrt(Math.Pow(WSX, 2) + Math.Pow(WSY, 2));  //FBP 49
                siteWindSpeed = (int)WSV;

                double RAZ = Math.Acos(WSY / WSV);  //FBP 50

                if (WSX < 0) RAZ = 360 - RAZ;
                siteWindDirection = (int)RAZ;
            }
            siteWindList.Add(siteWindSpeed);
            siteWindList.Add(siteWindDirection);
            SiteVars.SiteWindSpeed[site] = (ushort)siteWindSpeed;
            SiteVars.SiteWindDirection[site] = (ushort)siteWindDirection;

            return siteWindList;
            
            
            
        }
コード例 #26
0
        //---------------------------------------------------------------------

        public static DataRow GenerateSeasonWindData(ISeasonParameters season) 
        {

            int weatherRandomizer = PlugIn.WeatherRandomizer;
            //string seasonName = season.NameOfSeason.ToString();
            //string ecoName = fire_region.Name;
            //int weatherBin = 0;

            int seasonStart = season.StartDay;
            int seasonEnd = season.EndDay;

            string selectString = "Day >= " + seasonStart + " AND Day <= " + seasonEnd;
            DataRow[] rows = PlugIn.WindDataTable.Select(selectString);

            if (rows.Length > 0)
            {
                int newRandNum = (int)(Math.Round(PlugIn.ModelCore.GenerateUniform() * (rows.Length - 1)));
                DataRow weatherRow = rows[newRandNum];

                return weatherRow;
            }
            else
            {
                return null;
            }
        }
コード例 #27
0
        //---------------------------------------------------------------------

        public static int GenerateFMC(ISeasonParameters season, IDynamicInputRecord fire_region)
        {

            int FMC = 0;
            if (season.NameOfSeason == SeasonName.Spring)
            {
                if (PlugIn.ModelCore.GenerateUniform() < fire_region.SpringFMCHiProp)
                    FMC = fire_region.SpringFMCHi;
                else
                    FMC = fire_region.SpringFMCLo;
            }
            if (season.NameOfSeason == SeasonName.Summer)
            {
                if (PlugIn.ModelCore.GenerateUniform() < fire_region.SummerFMCHiProp)
                    FMC = fire_region.SummerFMCHi;
                else
                    FMC = fire_region.SummerFMCLo;
            }
            if (season.NameOfSeason == SeasonName.Fall)
            {
                if (PlugIn.ModelCore.GenerateUniform() < fire_region.FallFMCHiProp)
                    FMC = fire_region.FallFMCHi;
                else
                    FMC = fire_region.FallFMCLo;
            }
            return FMC;
        }
コード例 #28
0
        //---------------------------------------------------------------------

        public static DataTable ReadWeatherFile(string path, List<IFireRegion> ecoDataSet, ISeasonParameters[] seasonParms)
        {
            UI.WriteLine("   Dynamic Fire: Loading Weather Data...");

            CSVParser weatherParser = new CSVParser();

            DataTable weatherTable = weatherParser.ParseToDataTable(path);

            int recordCount = 0;
            for (int i = 0; i <= 2; i++)
            {
                string seasName = seasonParms[i].NameOfSeason.ToString();


                foreach (IFireRegion fire_region in ecoDataSet)
                {
                    string ecoName = fire_region.Name;
                    //UI.WriteLine("Read Weather File:  Season={0}, FireRegion={1}.", seasName, ecoName);

                    string selectText = ("Ecoregion = '" + ecoName + "' AND Season = '" + seasName + "'");
                    //UI.WriteLine("Read Weather File SelectText = {0}.", selectText);

                    DataRow[] foundRows = weatherTable.Select(selectText);

                    if (foundRows.Length == 0)
                    {
                        selectText = ("Ecoregion = 'All' AND Season = '" + seasName + "'");
                        foundRows = weatherTable.Select(selectText);
                    }

                    if(foundRows.Length > 0)
                    {
                        //Input validation
                        double WSV, FFMC, BUI;
                        int WINDDIR, FWIBIN;
                        for(int j = 0; j < foundRows.Length; j ++) //weatherDataSet.Tables["Table"].Rows)
                        {
                            DataRow myDataRow = foundRows[j];

                            WSV = (double) myDataRow["WSV"];
                            //Console.WriteLine("WSV:  {0}", WSV);
                            if (WSV < 0.0)
                            {
                                throw new System.ApplicationException("Error: Wind Speed < 0:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            FFMC = (double) myDataRow["FFMC"];
                            //Console.WriteLine("FFMC:  {0}", FFMC);
                            if (FFMC < 0.0)
                            {
                                throw new System.ApplicationException("Error: FFMC < 0:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            else if (FFMC > 100.0)
                            {
                                throw new System.ApplicationException("Error: FFMC > 100:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            BUI = (double) myDataRow["BUI"];
                            //Console.WriteLine("BUI:  {0}", BUI);
                            if (BUI < 0.0)
                            {
                                throw new System.ApplicationException("Error: BUI < 0:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            WINDDIR = (int) myDataRow["WindDir"];
                            //Console.WriteLine("WindDir:  {0}", WINDDIR);
                            if (WINDDIR < 0)
                            {
                                throw new System.ApplicationException("Error: WINDDIR < 0:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            else if (WINDDIR > 360)
                            {
                                throw new System.ApplicationException("Error: WINDDIR > 360:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            FWIBIN = (int) myDataRow["FWIBin"];
                            //Console.WriteLine("FWIBIN:  {0}", FWIBIN);
                            if (FWIBIN < 1)
                            {
                                throw new System.ApplicationException("Error: FWIBIN < 1:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                            else if (FWIBIN > 5)
                            {
                                throw new System.ApplicationException("Error: FWIBIN > 5:  FireRegion = " + ecoName + "; Season = " + seasName);
                            }
                        }

                    }

                    if ((foundRows.Length == 0) && (seasonParms[i].FireProbability > 0) && (fire_region.EcoIgnitionNum > 0))
                    {
                        throw new System.ApplicationException("Error: Ecoregion " + ecoName + ", Season " + seasName + " has fire probability > 0, but 0 weather records");
                    }

                    if(seasName == "Fall")
                    {
                    fire_region.FallRecords = recordCount;
                    }
                    else if (seasName == "Spring")
                    {
                        fire_region.SpringRecords = recordCount;
                    }
                    else if (seasName == "Summer")
                    {
                        fire_region.SummerRecords = recordCount;
                    }
                }
            }

            return weatherTable;
        }
コード例 #29
0
        // ---------------------------------------------------------------------
        // This method calculates the initial rate of spread for a specific site.
        // See below for the method that estimates the initial rate of spread for a broad area.
        
        public static double InitialRateOfSpread(double ISI, ISeasonParameters season, Site site, bool secondRegionMap)
        {   

            
            int fuelIndex = SiteVars.CFSFuelType[site];
            if (secondRegionMap)
                fuelIndex = SiteVars.CFSFuelType2[site];
            int PC = SiteVars.PercentConifer[site];
            int PH = SiteVars.PercentHardwood[site];
            int PDF = SiteVars.PercentDeadFir[site];
            
            //PlugIn.ModelCore.Log.WriteLine("Fuel Type Code = {0}.", siteFuelType.ToString());
            
            double RSI = 0.0;  
            
            //if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Conifer ||
                //Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.ConiferPlantation)
            if (Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.C1 ||
                Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.C2 ||
                Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.C3 ||
                Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.C4 ||
                Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.C5 ||
                Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.C6 ||
                Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.C7)
            {
                double a = Event.FuelTypeParms[fuelIndex].A;
                double b = Event.FuelTypeParms[fuelIndex].B;
                double c = Event.FuelTypeParms[fuelIndex].C;
                
                double percentHard = (double) PH / 100.0;
                double percentConi = (double) PC / 100.0;
                
                RSI = CalculateRSI(a, b, c, ISI);
                

                if (PDF > 0)
                {
                    if (PH > 0 && season.LeafStatus == LeafOnOff.LeafOn) //M-4
                    {
                        a = 140 * Math.Exp((-1) * 35.5 / (double) PDF);
                        b = 0.0404;
                        c = 3.02 * Math.Exp((-1) * 0.00714 * (double) PDF);
                    }
                    else  //M-3
                    {
                        a = 170 * Math.Exp((-1) * 35 / (double) PDF);
                        b = 0.082 * Math.Exp((-1) * 36 / (double)PDF);
                        c = 1.698 - (0.00303 * PDF);
                    }
                    double MRSI = CalculateRSI(a, b, c, ISI);
                    if (MRSI > RSI)
                        RSI = MRSI;
                }
                
                // These are the classic MIXED CONIFER + DECIDUOUS
                else if (PH > 0)
                {
                    double RSIconifer = RSI;
                    int dIndex = SiteVars.DecidFuelType[site]; //(int)FuelTypeCode.D1;
                    double RSIdecid = CalculateRSI(Event.FuelTypeParms[dIndex].A, Event.FuelTypeParms[dIndex].B, Event.FuelTypeParms[dIndex].C, ISI);

                    if (season.LeafStatus == LeafOnOff.LeafOn)  //M-2
                    {
                        RSI = ((1 - percentHard) * RSIconifer) + (0.2 * percentHard * RSIdecid);
                    }
                    else  //M-1
                    {
                        RSI = ((1 - percentHard) * RSIconifer) + (percentHard * RSIdecid);
                    }

                    //PlugIn.ModelCore.Log.WriteLine("Calculating ROSi for a MIXED type. PH={0}, PC={1}, LeafStatus={2}.", PH, PC, season.LeafStatus);
                    //PlugIn.ModelCore.Log.WriteLine("  RSIcon={0:0.0}, RSIdecid={1:0.0}, RSImix={2:0.000}.", RSIconifer, RSIdecid, RSI);

                }
            }
                

            //if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Open)
            if (Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.O1a || Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.O1b)
            //siteFuelType == FuelTypeCode.O1a)
            {
                double a, b, c;
                int percentCuring = season.PercentCuring;
                
                if(season.NameOfSeason == SeasonName.Spring)  //O1a
                {
                    a = 190; //Event.FuelTypeParms[(int)FuelTypeCode.O1a].A;
                    b = 0.0310; //Event.FuelTypeParms[(int)FuelTypeCode.O1a].B;
                    c = 1.4; //Event.FuelTypeParms[(int)FuelTypeCode.O1a].C;
                }
                else   //O1b
                {
                    a = 250; //Event.FuelTypeParms[(int)FuelTypeCode.O1b].A;
                    b = 0.0350; //Event.FuelTypeParms[(int)FuelTypeCode.O1b].B;
                    c = 1.7; //Event.FuelTypeParms[(int)FuelTypeCode.O1b].C;
                }
                
                double CF = (0.02 * percentCuring) - 1.0;
                RSI = CalculateRSI(a, b, c, ISI);
                if(percentCuring > 50) 
                    RSI *= CF;
                else
                    RSI = 0;
                if (PDF > 0)
                {
                    if (season.LeafStatus == LeafOnOff.LeafOn) //M-4
                    {
                        a = 140 * Math.Exp((-1) * 35.5 / (double)PDF);
                        b = 0.0404;
                        c = 3.02 * Math.Exp((-1) * 0.00714 * (double)PDF);
                    }
                    else //M-3
                    {
                        a = 170 * (Math.Exp(((-1) * 35) / (double)PDF));
                        b = 0.082 * (Math.Exp(((-1) * 36) / (double)PDF));
                        c = 1.698 - (0.00303 * (double)PDF);
                    }
                    double MRSI = CalculateRSI(a, b, c, ISI);
                    if (MRSI > RSI)
                        RSI = MRSI;
                }
            }
            
            //if(Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.NoFuel || fuelIndex == 0)
            if (Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.NoFuel || fuelIndex == 0)
            //siteFuelType == FuelTypeCode.NoFuel)
            {
                if (PDF > 0)
                {
                    double a=0, b=0, c=0;
                    if (season.LeafStatus == LeafOnOff.LeafOn) //M-4
                    {
                        a = 140 * Math.Exp((-1) * 35.5 / (double)PDF);
                        b = 0.0404;
                        c = 3.02 * Math.Exp((-1) * 0.00714 * (double)PDF);
                    }
                    else //M-3
                    {
                        a = 170 * (Math.Exp(((-1) * 35) / (double)PDF));
                        b = 0.082 * (Math.Exp(((-1) * 36) / (double)PDF));
                        c = 1.698 - (0.00303 * (double)PDF);
                    }
                    RSI = CalculateRSI(a, b, c, ISI);
                }

                else
                {
                    return 0;
                }
            }

            //if( Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Slash || 
                //Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Deciduous)
            if (Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.S1 ||
                Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.S2 ||
                Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.S3 ||
                Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.D1)
            {
                //PlugIn.ModelCore.Log.WriteLine("Calculating ROSi for a DECIDUOUS or SLASH type.");

                double a = Event.FuelTypeParms[fuelIndex].A;
                double b = Event.FuelTypeParms[fuelIndex].B;
                double c = Event.FuelTypeParms[fuelIndex].C;
                    
                RSI = CalculateRSI(a, b, c, ISI);

                //if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Deciduous 
                if(Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.D1 
                    && season.LeafStatus == LeafOnOff.LeafOn)
                //if(siteFuelType == FuelTypeCode.D1 && season.LeafStatus == LeafOnOff.LeafOn)
                    RSI *= 0.2;
                
                if (PDF > 0)
                {
                    //if (Event.FuelTypeParms[fuelIndex].BaseFuel == BaseFuelType.Deciduous
                    if (Event.FuelTypeParms[fuelIndex].SurfaceFuel == SurfaceFuelType.D1 
                        && season.LeafStatus == LeafOnOff.LeafOn)  //M-4
                    //siteFuelType == FuelTypeCode.D1) 
                    {
                        a = 140 * Math.Exp((-1) * 35.5 / (double) PDF);
                        b = 0.0404;
                        c = 3.02 * Math.Exp((-1) * 0.00714 * (double) PDF);
                    }
                    else //M-3
                    {
                        a = 170 * (Math.Exp(((-1) * 35) / (double) PDF));
                        b = 0.082 * (Math.Exp(((-1) * 36 )/ (double) PDF));
                        c = 1.698 - (0.00303 * (double) PDF);
                    }
                    double MRSI = CalculateRSI(a, b, c, ISI);
                    if (MRSI > RSI)
                        RSI = MRSI;
                }
            }

            
            return RSI;
        }
コード例 #30
0
        //---------------------------------------------------------------------

        public static int GenerateFMC(ISeasonParameters season, IFireRegion fire_region)
        {

            int FMC = 0;
            if (season.NameOfSeason == SeasonName.Spring)
            {
                if (Util.Random.GenerateUniform() < fire_region.SpringFMCHiProp)
                    FMC = fire_region.SpringFMCHi;
                else
                    FMC = fire_region.SpringFMCLo;
            }
            if (season.NameOfSeason == SeasonName.Summer)
            {
                if (Util.Random.GenerateUniform() < fire_region.SummerFMCHiProp)
                    FMC = fire_region.SummerFMCHi;
                else
                    FMC = fire_region.SummerFMCLo;
            }
            if (season.NameOfSeason == SeasonName.Fall)
            {
                if (Util.Random.GenerateUniform() < fire_region.FallFMCHiProp)
                    FMC = fire_region.FallFMCHi;
                else
                    FMC = fire_region.FallFMCLo;
            }
            return FMC;
        }