/****************************************************************************** * spot.c in ~/r.spread.fast * * This function is for wildfire spread simulation only. * It 1) is an inverse square distance randomization of the maximum * spotting distance; * * | p(X) * | * |* * |* * | * | * * | 1 * | * p(X) = --- (0 <= X <= max_dist) * | * X^2 * | * * | * * | * * | * * | * * | * * | * * |______________________________********_______ X * ^ * max_dist * * 2) the maximum spotting distance is derived from simplification of * Chase (1984); * 3) the landing firebrand may ignite spread based on fine fuel * moisture dictated probability simplified from Rothermel (1983); * 4) spotting travel time is proportional to but slower than windspeed; * 5) there is an elapsed time to reach equilibium rate of spread (ROS). * This elapsed time is proportional to the ROS. * Refs: * Chase, C. H., 1984, Spotting distance from wind-driven surface fires -- * ententions of equations for pocket calculators, US Forest Service, Res. * Note INT-346, Ogden, Uhta, 27 p. * Rothermel, R. C., 1983, How to predict the spread and intensity of forest * and range fires. US Forest Service, Gen. Tech. Rep. INT-143. Ogden, * Utha, 161 p. ******************************************************************************/ #include #include #include #include "cmd_line.h" #include "costHa.h" #include "cell_ptrHa.h" #include "local_proto.h" #ifndef PI #define PI M_PI #endif #define DATA(map, r, c) (map)[(r) * ncols + (c)] /*#define DEBUG*/ void spot (struct costHa *pres_cell, int dir/* direction of forward ROS */) { extern CELL *map_max; /* max ROS (cm/min) */ extern CELL *map_spotdist; /* max spotting distance (m) */ extern CELL *map_velocity; /* midflame windspeed (ft/min)*/ extern CELL *map_mois; /* fuel moisture (%) */ /* extern float PI;*/ extern int nrows, ncols; extern struct Cell_head window; float spot_cost; /* spotting travel time (min) */ float min_cost; /* min cumulative time (min) */ float U; /* wind speed at 6m (m/min) */ float Te; /* time to reach max ROS (min)*/ int land_dist; /* stochastic landing dist (m)*/ int land_distc; /* land_dist in cell counts */ int row, col; /* Find the (cell) location spotting might reach */ land_dist = pick_dist(DATA(map_spotdist, pres_cell->row, pres_cell->col)); #ifdef DEBUG printf ("pres_cell(%d, %d): land_dist=%d\n", pres_cell->row, pres_cell->col, land_dist); #endif land_distc = land_dist/(window.ns_res/100); /* 100 fac due to cm */ if (land_distc < 2) /* no need for adjacent cells */ return; row = pres_cell->row - land_distc*cos((dir%360)*PI/180) + 0.5; col = pres_cell->col + land_distc*sin((dir%360)*PI/180) + 0.5; if ( row < 0 || row >= nrows) /* outside the region */ return; if ( col < 0 || col >= ncols) /* outside the region */ return; if (DATA(map_max, row, col) <= 0) /* a barrier*/ return; /* check if ignitable based on probs. modified from Rothermel (1983) */ if (DATA(map_mois, row, col) > 17) /* too wet*/ return; #ifdef DEBUG printf (" pre pick_ignite(): land_distc(%d, %d)=%d dir=%d PI=%.2f (dir\%360)*PI/180=%.2f\n", row, col, land_distc, dir, PI, (dir%360)*PI/180); #endif if (pick_ignite(DATA(map_mois, row, col)) == 0) /* not success */ return; #ifdef DEBUG printf (" post pick_ignite(): land_distc(%d, %d)=%d \n", row, col, land_distc); #endif /* travel time by spotting */ U =0.305*DATA(map_velocity, pres_cell->row, pres_cell->col); /*NOTE: use value at midflame*/ spot_cost = land_dist/U; /* elapsed time to reach the max ROS, proportional to ROS */ Te = DATA(map_max, pres_cell->row, pres_cell->col)/1000 + 1; /* cumulative travel time since start */ min_cost = pres_cell->min_cost + spot_cost + Te; /* update it to the to_cell */ #ifdef DEBUG printf (" min_cost=%.2f: pres=%.2f spot=%.2f Te=%.2f\n", min_cost, pres_cell->min_cost, spot_cost, Te); #endif update (pres_cell, row, col, (double)dir, min_cost); }