spot.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /******************************************************************************
  2. * spot.c in ~/r.spread.fast
  3. *
  4. * This function is for wildfire spread simulation only.
  5. * It 1) is an inverse square distance randomization of the maximum
  6. * spotting distance;
  7. *
  8. * | p(X)
  9. * |
  10. * |*
  11. * |*
  12. * |
  13. * | *
  14. * | 1
  15. * | * p(X) = --- (0 <= X <= max_dist)
  16. * | * X^2
  17. * | *
  18. * | *
  19. * | *
  20. * | *
  21. * | *
  22. * | *
  23. * | *
  24. * |______________________________********_______ X
  25. * ^
  26. * max_dist
  27. *
  28. * 2) the maximum spotting distance is derived from simplification of
  29. * Chase (1984);
  30. * 3) the landing firebrand may ignite spread based on fine fuel
  31. * moisture dictated probability simplified from Rothermel (1983);
  32. * 4) spotting travel time is proportional to but slower than windspeed;
  33. * 5) there is an elapsed time to reach equilibium rate of spread (ROS).
  34. * This elapsed time is proportional to the ROS.
  35. * Refs:
  36. * Chase, C. H., 1984, Spotting distance from wind-driven surface fires --
  37. * ententions of equations for pocket calculators, US Forest Service, Res.
  38. * Note INT-346, Ogden, Uhta, 27 p.
  39. * Rothermel, R. C., 1983, How to predict the spread and intensity of forest
  40. * and range fires. US Forest Service, Gen. Tech. Rep. INT-143. Ogden,
  41. * Utha, 161 p.
  42. ******************************************************************************/
  43. #include <stdio.h>
  44. #include <math.h>
  45. #include <grass/gis.h>
  46. #include <grass/raster.h>
  47. #include "cmd_line.h"
  48. #include "costHa.h"
  49. #include "cell_ptrHa.h"
  50. #include "local_proto.h"
  51. #ifndef PI
  52. #define PI M_PI
  53. #endif
  54. #define DATA(map, r, c) (map)[(r) * ncols + (c)]
  55. void spot(struct costHa *pres_cell, int dir /* direction of forward ROS */ )
  56. {
  57. extern CELL *map_max; /* max ROS (cm/min) */
  58. extern CELL *map_spotdist; /* max spotting distance (m) */
  59. extern CELL *map_velocity; /* midflame windspeed (ft/min) */
  60. extern CELL *map_mois; /* fuel moisture (%) */
  61. /* extern float PI; */
  62. extern int nrows, ncols;
  63. extern struct Cell_head window;
  64. float spot_cost; /* spotting travel time (min) */
  65. float min_cost; /* min cumulative time (min) */
  66. float U; /* wind speed at 6m (m/min) */
  67. float Te; /* time to reach max ROS (min) */
  68. int land_dist; /* stochastic landing dist (m) */
  69. int land_distc; /* land_dist in cell counts */
  70. int row, col;
  71. /* Find the (cell) location spotting might reach */
  72. land_dist = pick_dist(DATA(map_spotdist, pres_cell->row, pres_cell->col));
  73. G_debug(1, "pres_cell(%d, %d): land_dist=%d", pres_cell->row,
  74. pres_cell->col, land_dist);
  75. land_distc = land_dist / (window.ns_res / 100); /* 100 fac due to cm */
  76. if (land_distc < 2) /* no need for adjacent cells */
  77. return;
  78. row = pres_cell->row - land_distc * cos((dir % 360) * PI / 180) + 0.5;
  79. col = pres_cell->col + land_distc * sin((dir % 360) * PI / 180) + 0.5;
  80. if (row < 0 || row >= nrows) /* outside the region */
  81. return;
  82. if (col < 0 || col >= ncols) /* outside the region */
  83. return;
  84. if (DATA(map_max, row, col) <= 0) /* a barrier */
  85. return;
  86. /* check if ignitable based on probs. modified from Rothermel (1983) */
  87. if (DATA(map_mois, row, col) > 17) /* too wet */
  88. return;
  89. G_debug(1,
  90. " pre pick_ignite(): land_distc(%d, %d)=%d dir=%d PI=%.2f (dir%%360)*PI/180=%.2f",
  91. row, col, land_distc, dir, PI, (dir % 360) * PI / 180);
  92. if (pick_ignite(DATA(map_mois, row, col)) == 0) /* not success */
  93. return;
  94. G_debug(1, " post pick_ignite(): land_distc(%d, %d)=%d ",
  95. row, col, land_distc);
  96. /* travel time by spotting */
  97. U = 0.305 * DATA(map_velocity, pres_cell->row, pres_cell->col);
  98. /*NOTE: use value at midflame */
  99. spot_cost = land_dist / U;
  100. /* elapsed time to reach the max ROS, proportional to ROS */
  101. Te = DATA(map_max, pres_cell->row, pres_cell->col) / 1000 + 1;
  102. /* cumulative travel time since start */
  103. min_cost = pres_cell->min_cost + spot_cost + Te;
  104. /* update it to the to_cell */
  105. G_debug(1, " min_cost=%.2f: pres=%.2f spot=%.2f Te=%.2f",
  106. min_cost, pres_cell->min_cost, spot_cost, Te);
  107. update(pres_cell, row, col, (double)dir, min_cost);
  108. }