Main Page   Compound List   File List   Compound Members   File Members  

HFire.c

Go to the documentation of this file.
00001 
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 
00028 #include "HFire.h"
00029 
00030 /* configuration routines headers */
00031 #include "FireConfig.h"
00032 #include "FireProp.h"
00033 
00034 /* fire code headers */
00035 #include "CellState.h"
00036 #include "FireEnv.h"
00037 #include "FireExport.h"
00038 #include "FireTimer.h"
00039 #include "FireYear.h"
00040 #include "FuelsRegrowth.h"
00041 #include "StandAge.h"
00042 #include "Ignition.h"
00043 #include "Extinction.h"
00044 #include "EightNbr.h"
00045 #include "FuelModel.h"
00046 #include "Roth1972.h"
00047 
00048 /* support code headers */
00049 #include "IntXY.h"
00050 #include "DblXYZ.h"
00051 #include "FltTwoDArray.h"
00052 #include "ByteTwoDArray.h"
00053 #include "GridData.h"
00054 #include "List.h"
00055 #include "ChHashTable.h"
00056 #include "NLIBRand.h"
00057 #include "Err.h"
00058     
00059 void QuitFatal(char * emessage) {
00060     if ( emessage != NULL ) {
00061         fprintf(stderr, "%s", emessage);
00062         }
00063     
00064     fprintf(stderr, "\n FATAL ERROR. Program Aborting.\n");
00065         
00066     exit(1);
00067     }
00068 
00069 void TimeStamp(FireTimer * ft, char * message)  {
00070     int mt = 0;
00071     
00072     if ( ft != NULL )   {   
00073         mt = FIRE_TIMER_GET_MILITARY_TIME(ft);
00074         if ( message == NULL )  {
00075             fprintf(stdout, "SIM TIME... YR: %d MO: %02d DY: %02d HR: %04d SEC: %d \n", ft->sim_cur_yr,
00076                                             ft->sim_cur_mo, ft->sim_cur_dy, mt, ft->sim_cur_secs);
00077             }
00078         else    {
00079             fprintf(stdout, "%s... YR: %d MO: %02d DY: %02d HR: %04d SEC: %d \n", message,
00080                                             ft->sim_cur_yr, ft->sim_cur_mo, ft->sim_cur_dy, mt, ft->sim_cur_secs);
00081             }
00082         }
00083     return;
00084     }
00085             
00086 int main(int argc, char * argv[]) {
00087     /* argc     = number of arguments (should be 2) */
00088     /* argv[0]  = "name of executable" */
00089     /* argv[1]  = "configuration file name" */
00090     /* argv[2]  = NULL */
00091 
00092     /*VARIABLE DECLARATION*/
00093     ChHashTable * proptbl       = NULL;                                     /* simulation properties read from file */
00094     GridData    * elev          = NULL;                                     /* elev spatial data */
00095     GridData    * slope         = NULL;                                     /* slope spatial data */
00096     GridData    * aspect        = NULL;                                     /* aspect spatial data */
00097     GridData    * std_age       = NULL;                                     /* stand age spatial data */
00098     GridData    * fuels         = NULL;                                     /* fuels spatial data */
00099     FireTimer   * ft            = NULL;                                     /* stores simulation time */
00100     FireEnv     * fe            = NULL;                                     /* table of function ptrs for env vars */
00101     List        * fmlist        = NULL;                                     /* list of FuelModels */
00102     ChHashTable * fmtble        = NULL;                                     /* table of FuelModels */   
00103     FireExport  * fex           = NULL;                                     /* wrapper for program export */
00104 
00105     int i, j;                                                               /* spatial row and col */
00106         
00107     int domain_rows, domain_cols;                                           /* simulation domain size */
00108     
00109     float cellsz;                                                           /* simulation cell resolution */
00110     
00111     List * brn_cells_list       = NULL;                                     /* list xy coords of burning cells */
00112     
00113     ListElmt * lel              = NULL;                                     /* ptr to single element in list */
00114     
00115     double * rwx, * rwy;                                                    /* stores real world xy coord pair */
00116     
00117     IntXY * cell                = NULL;                                     /* stores cell index i,j */
00118     
00119     FuelModel * fm              = NULL;                                     /* ptr to FuelModel */
00120     
00121     double cell_elev, nbr_elev;                                             /* stores cell and nbr elevation */
00122     
00123     double cell_slope;                                                      /* stores cell slope */
00124     
00125     double cell_aspect;                                                     /* stores cell aspect */
00126     
00127     double d1hfm, d10hfm, d100hfm;                                          /* dead fuel moisture */
00128     
00129     double lhfm, lwfm;                                                      /* live fuel moisture */
00130     
00131     double cell_waz;                                                        /* stores cell wind azimuth */
00132     
00133     double cell_wsp;                                                        /* stores cell wind speed */
00134     
00135     int cell_fm_num;                                                        /* stores cell fm number */
00136     
00137     int cell_az;                                                            /* stores cell azimuth */
00138     
00139     int num_brn_nbr;                                                        /* stores num of burning nbr cells */
00140     
00141     int nbr_i, nbr_j;                                                       /* stores nbr cell index i,j */
00142 
00143     int timestep, exp_secs, iter_secs;                                      /* stores time related vars */
00144 
00145     FireYear * fyr              = NULL;                                     /* ids of burned cells */
00146     
00147     CellState * cs              = NULL;                                     /* current state of cell wrt fire */
00148             
00149     ByteTwoDArray * hrs_brn     = NULL;                                     /* hours cell has been burning */
00150     
00151     FltTwoDArray * fract_brn    = NULL;                                     /* fraction of distance fire must travel to cell center */
00152     
00153     FltTwoDArray * fract_iter   = NULL;                                     /* fastest fraction burned any one iteration */
00154     
00155     double fpmros, mpsros;                                                  /* rate of sprd, ENGLISH and METRIC */
00156     
00157     double dist2ctr, disttrvl;                                              /* distance btwn cells fire has traveled */
00158     
00159     double fracttrvl, fractover;                                            /* fraction of distance btwn cells fire has traveled */
00160     
00161     KeyVal * entry              = NULL;                                     /* vals returned from Hash Table */
00162     
00163     void (*RandInit)(long int seed) = randinit;                             /* rng seed function from NLIBRand.h */ 
00164     
00165     char status_msg[HFIRE_DEFAULT_STATUS_LINE_LENGTH] = {'\0'};
00166 
00167     /*VARIABLE INITIALIZATION*/ 
00168     if ( argc != 2 )    {
00169         printf("Usage: %s <configuration filename> \n", argv[0]);
00170         return 0;
00171         }
00172 
00173     if ( InitPropsFromFireConfig(&proptbl, argv[1]) )   {
00174         QuitFatal(NULL);
00175         }
00176     FireConfigDumpPropsToStream(proptbl, stdout);
00177             
00178     if ( InitRothFuelModelListFromProps(proptbl, &fmlist) ) {
00179         QuitFatal(NULL);
00180         }
00181     FireConfigDumpFuelModelListToStream(fmlist, stdout);
00182                         
00183     if ( InitGridsFromPropsFireConfig(proptbl, &elev, &slope, &aspect)
00184             ||  InitFireTimerFromPropsFireConfig(proptbl, &ft)
00185             ||  InitFuelModelHashTableFromFuelModelListFireConfig(fmlist, &fmtble) 
00186             ||  InitStandAgeFromPropsFireConfig(proptbl, elev, &std_age)
00187             ||  InitFireEnvFromPropsFireConfig(proptbl, &fe)
00188             ||  InitRandNumGenFromPropsFireConfig(proptbl, randinit)    )   {
00189         QuitFatal(NULL);
00190         }
00191     
00192     if ( (fex = InitFireExport(proptbl)) == NULL )  {
00193         QuitFatal(NULL);
00194         }
00195     FIRE_EXPORT_SET_FIRE_TIMER(fex, ft);
00196     FIRE_EXPORT_SET_STAND_AGE(fex, std_age);
00197     
00198     if ( ChHashTableRetrieve(proptbl, GetFireProp(PROP_SIMTSSEC), (void *)&entry) ) {
00199         ERR_ERROR_CONTINUE("Unable to retrieve SIMULATION_TIMESTEP_SECS property.\n", ERR_EINVAL);
00200         QuitFatal(NULL);
00201         }   
00202     timestep = atoi(entry->val);    
00203     
00204     /*SIMULATION LOOP*/
00205     /* new year */
00206     while( !FireTimerIsSimTimeExpired(ft) ) {
00207         /* advance timer to start of fire season */
00208         ft->sim_cur_mo = ft->sim_start_mo;
00209         ft->sim_cur_dy = ft->sim_start_dy;
00210         ft->sim_cur_hr = ft->sim_start_hr;
00211         
00212         /* signal user */
00213         TimeStamp(ft, "START SIM YEAR");
00214         
00215         /* allocate data structures */
00216         
00217         /* initialize fuels to be used during this year of simulation */
00218         if ( fe->GetFuelsRegrowthFromProps(proptbl, std_age, &fuels) )  {
00219             QuitFatal(NULL);
00220             }
00221         FIRE_EXPORT_SET_FUELS(fex, fuels);
00222         
00223         /* get dimensions of fuels */           
00224         domain_rows = fuels->ghdr->nrows; 
00225         domain_cols = fuels->ghdr->ncols;   
00226         cellsz      = fuels->ghdr->cellsize;
00227     
00228         /* initialize a fire year structure for year in simulation */                
00229         fyr = InitFireYearFuels(ft->sim_cur_yr, fuels, fmtble);
00230         FIRE_EXPORT_SET_FIRE_YEAR(fex, fyr);
00231         
00232         /* initialize a cell state structure for year in simulation */
00233         cs = InitCellStateFuels(fuels, fmtble);
00234                         
00235         /* initialize a hours burned structure for year in simulation */
00236         hrs_brn = InitByteTwoDArraySizeIniValue(domain_rows, domain_cols, 0);
00237         
00238         /* initialize a fraction burned structure for year in simulation */
00239         fract_brn = InitFltTwoDArraySizeIniValue(domain_rows, domain_cols, HFIRE_FRACT_ZERO);
00240         
00241         /* initialize a fraction burned iter structure for year in simulation */
00242         fract_iter = InitFltTwoDArraySizeIniValue(domain_rows, domain_cols, HFIRE_FRACT_ZERO);
00243                 
00244         /* ensure all structures properly initialized */
00245         if ( fyr == NULL || cs == NULL || hrs_brn == NULL || fract_brn == NULL || fract_iter == NULL )  {
00246             QuitFatal(NULL);
00247             }
00248                 
00249         /* new timestep */
00250         while( !FireTimerIsSimCurYearTimeExpired(ft) )  {
00251             /* determine if ignition occurs and, if so, ignition location */
00252             if ( fe->IsIgnitionNowFromProps(proptbl) )  {
00253                 if ( fe->GetIgnitionLocFromProps(proptbl, fyr, &brn_cells_list) )   {
00254                     QuitFatal(NULL);
00255                     }
00256                 for( lel = LIST_HEAD(brn_cells_list); lel != NULL; lel = LIST_GET_NEXT_ELMT(lel) )  {
00257                     rwx = LIST_GET_DATA(lel);
00258                     lel = LIST_GET_NEXT_ELMT(lel);
00259                     rwy = LIST_GET_DATA(lel);
00260                     CellStateSetCellStateRealWorld(cs, *rwx, *rwy, EnumHasFireCellState);
00261                     FireYearSetCellNewFireIDRealWorld(fyr, *rwx, *rwy);
00262                     FireExportIgLocsTxtFile(proptbl, *rwx, *rwy, ft);
00263                     }
00264                 FreeList(brn_cells_list);
00265                 }
00266     
00267             /* inner loop meant to adaptively size exp_secs until one timestep has been exhausted */
00268             for(exp_secs = 0; exp_secs < timestep; exp_secs += iter_secs)   {
00269                 /* reset size of current iteration to zero */
00270                 iter_secs = timestep + 1;
00271     
00272                 /* initialize list of burning cells */
00273                 brn_cells_list  = InitListEmpty(FreeIntXY);
00274                                     
00275                 /* (1) find time expired this timestep, minimum iter_secs = cellsize / max mpsros */
00276                 for(i = 0; i < domain_rows; i++)    {
00277                     for(j = 0; j < domain_cols; j++)    {
00278                         /* zero the fraction burned this iteration structure */
00279                         FLTTWODARRAY_SET_DATA(fract_iter, i, j, HFIRE_FRACT_ZERO);
00280                         /* find max mpsros for all currently burning cells */
00281                         if ( BYTETWODARRAY_GET_DATA(cs->state, i, j) == EnumHasFireCellState )  {
00282                             /* immediately skip over boundary cells */
00283                             if ( i == 0 || j == 0 || i == (domain_rows - 1) || j == (domain_cols - 1) ) {
00284                                 continue;
00285                                 }
00286                             /* retrieve spatial attribute data */
00287                             GRID_DATA_GET_DATA(slope, i, j, cell_slope);
00288                             GRID_DATA_GET_DATA(aspect, i, j, cell_aspect);                                                                  
00289                             GRID_DATA_GET_DATA(fuels, i, j, cell_fm_num);
00290                             /* retrieve fuel model attribute data */
00291                             if ( ChHashTableRetrieve(fmtble, &cell_fm_num, (void *)&fm) )   {
00292                                 QuitFatal(NULL);
00293                                 }
00294                             /* retrieve Santa Ana time-dependent attributes */
00295                             if ( IsSantaAnaNowFromProps(proptbl, ft->sim_cur_yr, ft->sim_cur_mo, ft->sim_cur_dy) )  {
00296                                 if ( GetSantaAnaEnvFromProps(proptbl, ft->sim_cur_mo, ft->sim_cur_dy, ft->sim_cur_hr,
00297                                     &cell_waz, UNITS_FT_TO_M(fm->rfm->fdepth), &cell_wsp, &d1hfm, &d10hfm, &d100hfm) )  {
00298                                     QuitFatal(NULL);
00299                                     }
00300                                 cell_wsp = UNITS_MPSEC_TO_FTPMIN(cell_wsp);                                 
00301                                 }
00302                             /* retrieve non Santa Ana time-dependent attributes */
00303                             else    {
00304                                 if ( fe->GetDeadFuelMoistFromProps(proptbl, ft->sim_cur_mo, ft->sim_cur_dy, ft->sim_cur_hr,
00305                                                 i, j, &d1hfm, &d10hfm, &d100hfm) )  {
00306                                     QuitFatal(NULL);
00307                                     }
00308                                 if ( fe->GetWindAzimuthFromProps(proptbl, ft->sim_cur_mo, ft->sim_cur_dy, ft->sim_cur_hr,
00309                                                 i, j, &cell_waz) )  {
00310                                     QuitFatal(NULL);
00311                                     }
00312                                 if ( fe->GetWindSpeedMpsFromProps(proptbl, UNITS_FT_TO_M(fm->rfm->fdepth),
00313                                                 ft->sim_cur_mo, ft->sim_cur_dy, ft->sim_cur_hr, i, j, &cell_wsp) )  {
00314                                     QuitFatal(NULL);
00315                                     }
00316                                 cell_wsp = UNITS_MPSEC_TO_FTPMIN(cell_wsp); 
00317                                 }
00318                             /* retrieve live fuel moisture */
00319                             if ( fe->GetLiveFuelMoistFromProps(proptbl, ft->sim_cur_yr, ft->sim_cur_mo, ft->sim_cur_dy, 
00320                                         i, j, &lhfm, &lwfm) )   {
00321                                 QuitFatal(NULL);
00322                                 }
00323                             /* calculate max mpsros */                          
00324                             if ( Roth1972FireSpreadNoWindNoSlope(fm->rfm, d1hfm, d10hfm, d100hfm, lhfm, lwfm) 
00325                                 || Roth1972FireSpreadWindSlopeMax(fm->rfm, cell_wsp, cell_waz, cell_slope, cell_aspect) )   {
00326                                 QuitFatal(NULL);
00327                                 }
00328                             fpmros = fm->rfm->rp->ros_max;
00329                             mpsros = UNITS_FTPMIN_TO_MPSEC(fpmros);
00330                             /* test if iter_secs is the minimum */
00331                             if ( (cellsz / mpsros) < iter_secs )    {
00332                                 iter_secs = cellsz / mpsros;
00333                                 }                                                           
00334                             /* add cell to list of all burning cells */
00335                             lel = LIST_TAIL(brn_cells_list);
00336                             ListInsertNext(brn_cells_list, lel, InitIntXY(j,i));
00337                             }
00338                         }
00339                     }
00340     
00341                 /* (2) increment timestep according to iter_secs */
00342                 if ( LIST_SIZE(brn_cells_list) > 0 )    {
00343                     /* when a cell is burning at least one full second must always expire */
00344                     if ( iter_secs < 1 )    {
00345                         iter_secs = 1;
00346                         }
00347                     /* truncate to timestep if necessary */
00348                     if ( iter_secs + exp_secs > timestep )  {
00349                         iter_secs = timestep - exp_secs;
00350                         }
00351                     }
00352                 else    {
00353                     /* nothing is burning */
00354                     TimeStamp(ft, "NO CELLS BURNING");
00355                     FreeList(brn_cells_list);
00356                     break;
00357                     }
00358                 
00359                 /* (3) apply changes during iter_secs, advance fire distance = mpsros * iter_secs */
00360                 for( lel = LIST_HEAD(brn_cells_list); lel != NULL; lel = LIST_GET_NEXT_ELMT(lel) )  {
00361                     cell = LIST_GET_DATA(lel);                                  
00362                     i = cell->y;
00363                     j = cell->x;
00364                     /* retrieve spatial attribute data */
00365                     GRID_DATA_GET_DATA(elev, i, j, cell_elev);              
00366                     GRID_DATA_GET_DATA(slope, i, j, cell_slope);
00367                     GRID_DATA_GET_DATA(aspect, i, j, cell_aspect);                                                                  
00368                     GRID_DATA_GET_DATA(fuels, i, j, cell_fm_num);
00369                     /* retrieve fuel model attribute data */
00370                     if ( ChHashTableRetrieve(fmtble, &cell_fm_num, (void *)&fm) )   {
00371                         QuitFatal(NULL);
00372                         }
00373                     /* retrieve Santa Ana time-dependent attributes */
00374                     if ( IsSantaAnaNowFromProps(proptbl, ft->sim_cur_yr, ft->sim_cur_mo, ft->sim_cur_dy) )  {
00375                         if ( GetSantaAnaEnvFromProps(proptbl, ft->sim_cur_mo, ft->sim_cur_dy, ft->sim_cur_hr,
00376                             &cell_waz, UNITS_FT_TO_M(fm->rfm->fdepth), &cell_wsp, &d1hfm, &d10hfm, &d100hfm) )  {
00377                             QuitFatal(NULL);
00378                             }
00379                         cell_wsp = UNITS_MPSEC_TO_FTPMIN(cell_wsp);
00380                         }
00381                     /* retrieve non Santa Ana time-dependent attributes */
00382                     else    {
00383                         if ( fe->GetDeadFuelMoistFromProps(proptbl, ft->sim_cur_mo, ft->sim_cur_dy, ft->sim_cur_hr,
00384                                         i, j, &d1hfm, &d10hfm, &d100hfm) )  {
00385                             QuitFatal(NULL);
00386                             }
00387                         if ( fe->GetWindAzimuthFromProps(proptbl, ft->sim_cur_mo, ft->sim_cur_dy, ft->sim_cur_hr,
00388                                         i, j, &cell_waz) )  {
00389                             QuitFatal(NULL);
00390                             }
00391                         if ( fe->GetWindSpeedMpsFromProps(proptbl, UNITS_FT_TO_M(fm->rfm->fdepth),
00392                                         ft->sim_cur_mo, ft->sim_cur_dy, ft->sim_cur_hr, i, j, &cell_wsp) )  {
00393                             QuitFatal(NULL);
00394                             }
00395                         cell_wsp = UNITS_MPSEC_TO_FTPMIN(cell_wsp); 
00396                         }
00397                     /* retrieve live fuel moisture */
00398                     if ( fe->GetLiveFuelMoistFromProps(proptbl, ft->sim_cur_yr, ft->sim_cur_mo, ft->sim_cur_dy, 
00399                                 i, j, &lhfm, &lwfm) )   {
00400                         QuitFatal(NULL);
00401                         }                       
00402                     /* counter to determine number of burning neighbors */
00403                     num_brn_nbr = 0;
00404                     /* intiate fire spread pipeline for fuel model number at i,j */
00405                     if ( Roth1972FireSpreadNoWindNoSlope(fm->rfm, d1hfm, d10hfm, d100hfm, lhfm, lwfm) 
00406                         || Roth1972FireSpreadWindSlopeMax(fm->rfm, cell_wsp, cell_waz, cell_slope, cell_aspect) )   {
00407                         QuitFatal(NULL);
00408                         }
00409                     fpmros = fm->rfm->rp->ros_max;
00410                     mpsros = UNITS_FTPMIN_TO_MPSEC(fpmros);
00411                     /* extinguish the cell if ros insufficient */                   
00412                     if ( UpdateExtinctionROS(proptbl, i, j, mpsros, cs, hrs_brn) )  {
00413                         /* cell extinguished */
00414                         FLTTWODARRAY_SET_DATA(fract_brn, i, j, HFIRE_FRACT_ZERO);
00415                         FLTTWODARRAY_SET_DATA(fract_iter, i, j, HFIRE_FRACT_ZERO);                      
00416                         continue;
00417                         }
00418                     /* iterate through all neighboring azimuths spreading fire */                           
00419                     for (cell_az = 0; cell_az < EIGHTNBR_NUM_NBR_CELLS; cell_az++)      {
00420                         nbr_i = EIGHTNBR_ROW_INDEX_AT_AZIMUTH(i, cell_az);
00421                         nbr_j = EIGHTNBR_COL_INDEX_AT_AZIMUTH(j, cell_az);
00422                         /* immediately skip over boundary cells */
00423                         if ( nbr_i == 0 || nbr_j == 0 || nbr_i == (domain_rows - 1) || nbr_j == (domain_cols - 1) ) {
00424                             num_brn_nbr++;
00425                             continue;
00426                             }   
00427                         /* if cell has fire then it is already in brn_cells_list */
00428                         if ( BYTETWODARRAY_GET_DATA(cs->state, nbr_i, nbr_j) != EnumNoFireCellState )   {
00429                             num_brn_nbr++;
00430                             continue;
00431                             }
00432                         /* determine how far fire spreads, get mpsros at azimuth */             
00433                         if ( Roth1972FireSpreadGetAtAzimuth(fm->rfm, EIGHTNBR_AZIMUTH_AS_DBL(cell_az)) )    {
00434                             QuitFatal(NULL);
00435                             }
00436                         fpmros = fm->rfm->rp->ros_any;
00437                         mpsros = UNITS_FTPMIN_TO_MPSEC(fpmros);
00438                         /* get distance fire traveled */
00439                         disttrvl = mpsros * iter_secs;
00440                         /* get terrain distance (xyz) to cell center */
00441                         GRID_DATA_GET_DATA(elev, nbr_i, nbr_j, nbr_elev);
00442                         if ( dxyzCalcDist(j * cellsz, i * cellsz, cell_elev, 
00443                                             nbr_j * cellsz, nbr_i * cellsz, nbr_elev, &dist2ctr) )  {
00444                             QuitFatal(NULL);
00445                             }
00446                         /* convert absolute distance to fraction of pathway */
00447                         fracttrvl = disttrvl / dist2ctr;
00448                         /* apply distance to fract_brn array */
00449                         if ( FLTTWODARRAY_GET_DATA(fract_brn, nbr_i, nbr_j) <= HFIRE_FRACT_ZERO )   {
00450                             FLTTWODARRAY_SET_DATA(fract_brn, nbr_i, nbr_j, fracttrvl);
00451                             }
00452                         /* only replace new fraction when larger than any other fraction this iteration */
00453                         else if ( fracttrvl > FLTTWODARRAY_GET_DATA(fract_iter, nbr_i, nbr_j) ) {
00454                             /* subtract the old fract */
00455                             FLTTWODARRAY_SET_DATA(fract_brn, nbr_i, nbr_j, (FLTTWODARRAY_GET_DATA(fract_brn, nbr_i, nbr_j) - FLTTWODARRAY_GET_DATA(fract_iter, nbr_i, nbr_j)));
00456                             /* replace with new fract */
00457                             FLTTWODARRAY_SET_DATA(fract_brn, nbr_i, nbr_j, (FLTTWODARRAY_GET_DATA(fract_brn, nbr_i, nbr_j) + fracttrvl));
00458                             FLTTWODARRAY_SET_DATA(fract_iter, nbr_i, nbr_j, fracttrvl);                         
00459                             }
00460                         /* fraction traveled smaller than max this timestep */
00461                         else    {
00462                             continue;
00463                             }
00464                         /* determine if cell center reached, if so set cell to burning state */
00465                         fractover = FLTTWODARRAY_GET_DATA(fract_brn, nbr_i, nbr_j) - 1.0;
00466                         if ( fractover > 1.0 )  {
00467                             /* set new cell state */
00468                             BYTETWODARRAY_SET_DATA(cs->state, nbr_i, nbr_j, EnumHasFireCellState);
00469                             /* increment has fire neighbor count */
00470                             num_brn_nbr++;
00471                             /* assign new burning cell id same as center cell id */
00472                             INTTWODARRAY_SET_DATA(fyr->id, nbr_i, nbr_j, INTTWODARRAY_GET_DATA(fyr->id, i, j));
00473                             /* apply overflow to nbr */
00474                             nbr_i = EIGHTNBR_ROW_INDEX_AT_AZIMUTH(nbr_i, cell_az);
00475                             nbr_j = EIGHTNBR_COL_INDEX_AT_AZIMUTH(nbr_j, cell_az);                          
00476                             if ( BYTETWODARRAY_GET_DATA(cs->state, nbr_i, nbr_j) == EnumNoFireCellState )   {
00477                                 if ( FLTTWODARRAY_GET_DATA(fract_brn, nbr_i, nbr_j) <= HFIRE_FRACT_ZERO )   {
00478                                     FLTTWODARRAY_SET_DATA(fract_brn, nbr_i, nbr_j, fractover);
00479                                     }
00480                                 else if ( fractover > FLTTWODARRAY_GET_DATA(fract_iter, nbr_i, nbr_j) ) {
00481                                     /* subtract the old fract */
00482                                     FLTTWODARRAY_SET_DATA(fract_brn, nbr_i, nbr_j, (FLTTWODARRAY_GET_DATA(fract_brn, nbr_i, nbr_j) - FLTTWODARRAY_GET_DATA(fract_iter, nbr_i, nbr_j)));
00483                                     /* replace with new fract */
00484                                     FLTTWODARRAY_SET_DATA(fract_brn, nbr_i, nbr_j, (FLTTWODARRAY_GET_DATA(fract_brn, nbr_i, nbr_j) + fractover));
00485                                     FLTTWODARRAY_SET_DATA(fract_iter, nbr_i, nbr_j, fractover); 
00486                                     }
00487                                 }
00488                             }
00489                         }
00490                     /* determine whether this cell consumed */
00491                     if ( num_brn_nbr >= EIGHTNBR_NUM_NBR_CELLS )    {
00492                         BYTETWODARRAY_SET_DATA(cs->state, i, j, EnumConsumedCellState);
00493                         }
00494                     }
00495                 
00496                 /* (4) cleanup for one cycle through adaptive timestep */
00497                 FreeList(brn_cells_list);
00498                 sprintf(status_msg, "T_exp: %d T_adapt: %d", exp_secs, iter_secs);
00499                 TimeStamp(ft, status_msg);
00500                 }
00501             
00502             /* increment simulation clock */
00503             FireTimerIncrementSeconds(ft, timestep);
00504             
00505             /* increment cell extinction clock */
00506             if ( UpdateExtinctionHOURS(proptbl, ft->sim_cur_mo, ft->sim_cur_dy, ft->sim_cur_hr, cs, hrs_brn) )  {
00507                 QuitFatal(NULL);
00508                 }
00509     
00510             /* export data */
00511             if ( FireExportSpatialData(proptbl, fex) )  {
00512                 QuitFatal(NULL);
00513                 }
00514     
00515             /* signal user */
00516             TimeStamp(ft, NULL);
00517             
00518             /* end of timestep */
00519             }
00520 
00521         /* export data */
00522         if ( FireExportSpatialData(proptbl, fex) )  {
00523             QuitFatal(NULL);
00524             }
00525 
00526         /* increment stand age */
00527         IncrementStandAge(fyr, std_age);    
00528         
00529         /* free memory for short-term (yearly) data structures */
00530         FreeGridData(fuels);        
00531         FreeFireYear(fyr);
00532         FreeCellState(cs);
00533         FreeByteTwoDArray(hrs_brn);
00534         FreeFltTwoDArray(fract_brn);        
00535         FreeFltTwoDArray(fract_iter);       
00536 
00537         /* signal user */
00538         TimeStamp(ft, "END SIM YEAR");
00539                         
00540         /* increment simulation clock */
00541         ft->sim_cur_yr += 1;
00542             
00543         /* end of year */
00544         }
00545     
00546     /* CLEANUP */
00547     FreeFireExport(fex);
00548     FreeFireEnv(fe);
00549     FreeGridData(std_age);
00550     FreeChHashTable(fmtble);
00551     FreeFireTimer(ft);
00552     FreeGridData(aspect);
00553     FreeGridData(slope);
00554     FreeGridData(elev);
00555     FreeList(fmlist);
00556     FreeChHashTable(proptbl);   
00557     return 0;
00558     }
00559 
00560 /* end of HFire.c */

Generated at Fri Jun 22 00:46:51 2001 for HFire by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000