123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /******************************************************************************
- * 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 <stdio.h>
- #include <math.h>
- #include <grass/gis.h>
- #include <grass/raster.h>
- #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)]
- 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));
- G_debug(1, "pres_cell(%d, %d): land_dist=%d", pres_cell->row,
- pres_cell->col, land_dist);
- 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;
- G_debug(1,
- " pre pick_ignite(): land_distc(%d, %d)=%d dir=%d PI=%.2f (dir%%360)*PI/180=%.2f",
- row, col, land_distc, dir, PI, (dir % 360) * PI / 180);
- if (pick_ignite(DATA(map_mois, row, col)) == 0) /* not success */
- return;
- G_debug(1, " post pick_ignite(): land_distc(%d, %d)=%d ",
- row, col, land_distc);
- /* 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 */
- G_debug(1, " min_cost=%.2f: pres=%.2f spot=%.2f Te=%.2f",
- min_cost, pres_cell->min_cost, spot_cost, Te);
- update(pres_cell, row, col, (double)dir, min_cost);
- }
|