Rev 1221 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
671 | werner | 1 | /******************************************************************************************** |
2 | ** iLand - an individual based forest landscape and disturbance model |
||
3 | ** http://iland.boku.ac.at |
||
4 | ** Copyright (C) 2009- Werner Rammer, Rupert Seidl |
||
5 | ** |
||
6 | ** This program is free software: you can redistribute it and/or modify |
||
7 | ** it under the terms of the GNU General Public License as published by |
||
8 | ** the Free Software Foundation, either version 3 of the License, or |
||
9 | ** (at your option) any later version. |
||
10 | ** |
||
11 | ** This program is distributed in the hope that it will be useful, |
||
12 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
14 | ** GNU General Public License for more details. |
||
15 | ** |
||
16 | ** You should have received a copy of the GNU General Public License |
||
17 | ** along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
18 | ********************************************************************************************/ |
||
19 | |||
646 | werner | 20 | #ifndef FIREMODULE_H |
21 | #define FIREMODULE_H |
||
22 | |||
23 | #include "grid.h" |
||
24 | #include "layeredgrid.h" |
||
667 | werner | 25 | #include "expression.h" |
646 | werner | 26 | |
27 | class WaterCycleData; |
||
28 | class ResourceUnit; |
||
29 | class FireModule; |
||
665 | werner | 30 | class FireOut; |
646 | werner | 31 | |
649 | werner | 32 | /** FireRUData contains data items for resource units. |
697 | werner | 33 | @ingroup firemodule |
646 | werner | 34 | Data items include: |
35 | * parameters (KBDIref, ...) |
||
36 | * fuel values |
||
37 | */ |
||
649 | werner | 38 | class FireRUData |
646 | werner | 39 | { |
40 | public: |
||
663 | werner | 41 | FireRUData(): mKBDIref(0.), mRefMgmt(0.), mRefAnnualPrecipitation(0.), mKBDI(0.) { fireRUStats.clear(); } |
646 | werner | 42 | void setup(); |
649 | werner | 43 | bool enabled() const { return mRefMgmt>0.; } |
44 | void reset() { mKBDI = 0.; } |
||
45 | double kbdi() const { return mKBDI; } |
||
757 | werner | 46 | double baseIgnitionProbability() const { return mBaseIgnitionProb; } |
646 | werner | 47 | // access data |
662 | werner | 48 | struct { |
49 | int fire_id; |
||
50 | // statistics for: |
||
51 | int n_trees_died; ///< number of trees that are killed |
||
52 | int n_trees; ///< number of trees that are on burning cells |
||
53 | int n_cells; ///< number of burning cells |
||
54 | double died_basal_area; ///< basal area (m2) of died trees |
||
680 | werner | 55 | double basal_area; ///< basal area (m2) of all trees on burning pixels |
56 | double fuel_ff; ///< average fuel fine material (kg/ha) |
||
57 | double fuel_dwd; ///< average fuel dead wood (kg/ha) |
||
662 | werner | 58 | double crown_kill; ///< average crown kill percent |
693 | werner | 59 | double avg_dbh; ///< average dbh (arithmetic mean) and limited to threshold |
662 | werner | 60 | // enter() can be called multiple times |
61 | void enter(const int this_fire_id) { |
||
62 | if (fire_id!=this_fire_id) { |
||
63 | fire_id = this_fire_id; |
||
64 | // clear all stats |
||
65 | n_trees_died = n_trees = n_cells = 0; |
||
693 | werner | 66 | died_basal_area = basal_area = fuel_ff = fuel_dwd = crown_kill = avg_dbh = 0.; |
662 | werner | 67 | } |
68 | } |
||
69 | // call once after fire is finished |
||
70 | void calculate(const int this_fire_id) { |
||
71 | if (fire_id==this_fire_id) { |
||
72 | // calculate averages |
||
73 | if (n_cells>0) { |
||
74 | crown_kill /= double(n_cells); |
||
680 | werner | 75 | fuel_ff /= double(n_cells); |
76 | fuel_dwd /= double(n_cells); |
||
693 | werner | 77 | avg_dbh /= double(n_cells); |
662 | werner | 78 | } |
79 | } |
||
80 | } |
||
663 | werner | 81 | void clear() { fire_id=-1; enter(0);} |
662 | werner | 82 | } fireRUStats; |
646 | werner | 83 | private: |
84 | // parameters |
||
85 | double mKBDIref; ///< reference value for KBDI drought index |
||
86 | double mRefMgmt; ///< r_mgmt (fire suppression value) |
||
654 | werner | 87 | double mRefLand; ///< fixed multiplier for the fire spread probabilites (e.g. for riparian land) [0..1], default 1 |
646 | werner | 88 | double mRefAnnualPrecipitation; ///< mean annual precipitation (mm) |
654 | werner | 89 | double mFireReturnInterval; ///< mean fire return interval (yrs) |
90 | double mAverageFireSize; ///< mean average fire size (m2) |
||
680 | werner | 91 | double mMinFireSize; ///< minimum fire size (m2) |
92 | double mMaxFireSize; ///< maximum fire size (m2) |
||
654 | werner | 93 | double mBaseIgnitionProb; ///< ignition probabilty for r_climate = r_mgmt = 1 (value is for the prob. for a cell, e.g. 20x20m) |
94 | double mFireExtinctionProb; ///< gives the probabilty that a fire extincts on a pixel without having a chance to spread further |
||
646 | werner | 95 | // variables |
96 | double mKBDI; ///< Keetch Byram Drought Index (0..800, in 1/100 inch of water) |
||
97 | |||
98 | friend class FireModule; // allow access to member values |
||
99 | friend class FireLayers; |
||
100 | }; |
||
101 | |||
697 | werner | 102 | /** Helper class manage and visualize data layers related to fire. |
103 | @ingroup firemodule |
||
104 | */ |
||
649 | werner | 105 | class FireLayers: public LayeredGrid<FireRUData> { |
646 | werner | 106 | public: |
649 | werner | 107 | void setGrid(const Grid<FireRUData> &grid) { mGrid = &grid; } |
108 | double value(const FireRUData& data, const int index) const; |
||
1014 | werner | 109 | const QVector<LayeredGridBase::LayerElement> &names(); |
110 | private: |
||
111 | QVector<LayeredGridBase::LayerElement> mNames; |
||
646 | werner | 112 | }; |
697 | werner | 113 | /** FireModule is the main class of the fire sub module. |
114 | @ingroup firemodule |
||
115 | FireModule holds all the relevant data/actions for the iLand fire module. |
||
667 | werner | 116 | See http://iland.boku.ac.at/wildfire and http://iland.boku.ac.at/fire+module |
117 | |||
646 | werner | 118 | The fire module has conceptually three parts that stand more or less on its own: |
119 | * Fire ignition |
||
120 | * Fire spread |
||
121 | * Fire severity/effect |
||
122 | */ |
||
123 | class FireModule |
||
124 | { |
||
125 | public: |
||
126 | FireModule(); |
||
127 | /// the setup function sets up the grids and parameters used for the fire module. |
||
128 | /// this should be called when the main model is already created. |
||
129 | void setup(); ///< general setup |
||
130 | void setup(const ResourceUnit *ru); ///< setup for a specific resource unit |
||
761 | werner | 131 | static double cellsize() { return 20.; } |
646 | werner | 132 | |
133 | // actions |
||
651 | werner | 134 | /// main function that is executed yearly (called by the plugin) |
135 | /// performs the major processes (ignition, spread, fire effect) |
||
649 | werner | 136 | void run(); |
651 | werner | 137 | /// called yearly from the plugin to perform some |
138 | /// cleanup. |
||
649 | werner | 139 | void yearBegin(); |
651 | werner | 140 | /// called from the plugin to perform calculations (drought indices) |
141 | /// during the water cycle routine. |
||
646 | werner | 142 | void calculateDroughtIndex(const ResourceUnit *resource_unit, const WaterCycleData *water_data); |
651 | werner | 143 | |
144 | // main fire functions |
||
757 | werner | 145 | /// calculate the start and starting point of a possible fire. return: burnt area (-1 if nothing burnt) |
146 | double ignition(bool only_ignite = false); |
||
651 | werner | 147 | /// spread a fire starting from 'start_point' (index of the 20m grid) |
674 | werner | 148 | void spread(const QPoint &start_point, const bool prescribed = false); |
651 | werner | 149 | void severity(); |
150 | |||
654 | werner | 151 | // helper functions |
696 | werner | 152 | int fireId() const { return mFireId; } ///< return the ID of the last fire event |
757 | werner | 153 | double fireX() const { return fireStats.startpoint.x(); } ///< coordinates of the ignition point |
154 | double fireY() const { return fireStats.startpoint.y(); } ///< coordinates of the ignition point |
||
654 | werner | 155 | void testSpread(); |
757 | werner | 156 | double prescribedIgnition(const double x_m, const double y_m, const double firesize, const double windspeed, const double winddirection); |
654 | werner | 157 | |
646 | werner | 158 | private: |
650 | werner | 159 | /// estimate fire size from a distribution |
680 | werner | 160 | double calculateFireSize(const FireRUData *data); |
651 | werner | 161 | |
162 | // functions for the cellular automata |
||
650 | werner | 163 | void probabilisticSpread(const QPoint &start_point); |
651 | werner | 164 | /// calculates the probabibilty of spreading the fire from \p pixel_from to \p pixel_to. |
165 | /// the \p direction provides encodes the cardinal direction. |
||
654 | werner | 166 | void calculateSpreadProbability(const FireRUData &fire_data, const double height, const float *pixel_from, float *pixel_to, const int direction); |
650 | werner | 167 | |
654 | werner | 168 | /// calc the effect of slope on the fire spread |
169 | double calcSlopeFactor(const double slope) const; |
||
170 | |||
171 | /// calc the effect of wind on the fire spread |
||
172 | double calcWindFactor(const double direction) const; |
||
662 | werner | 173 | |
680 | werner | 174 | /// calculate the "severity", i.e. burn individual trees within the pixels |
662 | werner | 175 | bool burnPixel(const QPoint &pos, FireRUData &ru_data); |
680 | werner | 176 | /// calculate statistics, burn snags, soil of the resource units |
177 | void afterFire(); |
||
178 | |||
662 | werner | 179 | int mFireId; ///< running id of a fire event |
654 | werner | 180 | // parameters |
656 | werner | 181 | double mFireSizeSigma; ///< parameter of the log-normal distribution to derive fire size |
654 | werner | 182 | double mWindSpeedMin; |
183 | double mWindSpeedMax; |
||
184 | double mWindDirection; |
||
185 | double mCurrentWindSpeed; |
||
186 | double mCurrentWindDirection; |
||
674 | werner | 187 | double mPrescribedFiresize; // fire size from javascript |
667 | werner | 188 | // fuel parameters |
189 | double mFuelkFC1; ///< params (Schumacher 2006) to calculate amount of fuel |
||
190 | double mFuelkFC2; |
||
191 | double mFuelkFC3; |
||
192 | // crown kill |
||
193 | double mCrownKillkCK1; ///< parameter to calculate fraction of crowns killed by the fire (Schumacher) |
||
194 | double mCrownKillkCK2; |
||
195 | double mCrownKillDbh; ///< dbh threshold (cm) for crown kill calculation |
||
196 | Expression mMortalityFormula; ///< formula to calculate mortality caused by fire |
||
197 | double *mFormula_bt; |
||
198 | double *mFormula_ck; |
||
668 | werner | 199 | double mBurnSoilBiomass; ///< fraction of soil biomass that is to be removed when burning |
200 | double mBurnStemFraction; ///< fraction of stem biomass burned by fire (if a tree dies) |
||
201 | double mBurnBranchFraction; ///< fraction of branch biomass burned by fire (if a tree dies) |
||
202 | double mBurnFoliageFraction; ///< fraction of foliage biomass burned by fire (if a tree dies) |
||
203 | |||
680 | werner | 204 | bool mOnlyFireSimulation; ///< if true, trees/snags etc. are not really affected by fire |
696 | werner | 205 | // event handler |
206 | QString mAfterFireEvent; ///< javascript event after fire |
||
680 | werner | 207 | |
646 | werner | 208 | // data |
662 | werner | 209 | Grid<FireRUData> mRUGrid; ///< grid with data values per resource unit |
210 | Grid<float> mGrid; ///< fire grid (20x20m) |
||
646 | werner | 211 | FireLayers mFireLayers; |
212 | // functions |
||
649 | werner | 213 | FireRUData &data(const ResourceUnit *ru); ///< get ref to data element (FireData) |
646 | werner | 214 | |
665 | werner | 215 | // statistics |
216 | struct { |
||
217 | int iterations; |
||
218 | int fire_size_plan_m2; |
||
219 | int fire_size_realized_m2; |
||
690 | werner | 220 | double fire_psme_total; ///< psme (doug fir) on burning pixels (m2 basal area) |
221 | double fire_psme_died; ///< psme (doug fir) that died during the fire (based on m2) |
||
665 | werner | 222 | QPointF startpoint; |
223 | } fireStats; |
||
224 | friend class FireOut; |
||
680 | werner | 225 | friend class FireScript; |
665 | werner | 226 | |
646 | werner | 227 | }; |
228 | |||
229 | #endif // FIREMODULE_H |