1 function result=perimeter_in(long,lat,fire_area,wrfout,time_now,time,interval,count);
3 % Volodymyr Kondratenko July 19 2013
5 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8 % long,lat longtitude and latitude converted to meters
9 % fire_area fire map,[0,1] array, where 0- not
10 % burning area, >0 burning area, 1 - area that was burnt
11 % wrfout name of the wrfout file, that is being used to read ros
12 % time_now the perimeter time (s)
13 % time update the wind every count time steps
14 % interval time step in wrfout in seconds
15 % count update the wind every count time steps
16 % JM NEVER CHANGE INPUT VARIABLES
19 % Final Matrix of times of ignition will be printed to 'output_tign.txt' % JM use save tign instead, create tign.mat
27 % JM algorithm state is stored in arrays A D C
29 % A contains rows [i,j] of indices of nodes not burning that have at least one burning neighbor
30 % and time of ignition > time_now
32 % Reading Rate of spread
33 ros=read_data_from_wrfout(wrfout,time); % JM should be read_ros_from_wrfout
35 % Getting matrix A from the initial tign_g, where
36 A=get_perim_from_initial_tign(fire_area);
37 % Computing 4d array of distances between a point and its 8 neighbors
38 distance=get_distances(long,lat);
39 % JM do not change this later, use adjustment array instead if you must
41 % Computing 4d array of differences of tign (delta_tign) between a point
43 [delta_tign]=get_delta_tign(distance,ros);
46 % Everything outside of the burning area is set to time_now,
49 tign_in=(fire_area(:,:)==0).*time_now; %Should I use |a-b|<eps ? %JM never test reals on equality
51 % D - if D[i,j]=1, then the neighbors of the point [i,j]
52 % will be updated only in the next timestep (only after we update ros)
57 sprintf('size of A- %i',size(A,1))
58 for istep=1:max(size(tign_in)),
65 str= sprintf('%f -- How long does it take to run step %i',time_toc,istep-1);
67 contour(tign_in(2:end-1,2:end-1));drawnow
68 [tign_in,distance,A,D]=tign_update(tign_in,A,D,delta_tign,time_now,distance,interval,ros);
69 %%% [tign_in,distance,A,D]=tign_update(tign_in,A,D,delta_tign,time_now,distance,interval,ros);
71 contour(tign_in(2:end-1,2:end-1));title(sprintf('step %i',istep)),drawnow
73 changed=sum(tign_in(:)~=tign_last(:));
75 sprintf('%s \n step %i inside tign changed at %i points \n %f -- norm of the difference',str,istep,changed,norm(tign_in-tign_last))
76 sprintf('size of A- %i',size(A,1))
77 % % % if (size(A,1)==0)
78 % % % if (time-count)>0
79 % % % 'getting new ros'
81 % % % [A(:,1),A(:,2)]=find(D>0);
82 % % % sprintf('size of A- %i',size(A,1))
84 % % % time_now=time_now-count*interval
86 % % % ros=read_data_from_wrfout(wrfout,time);
87 % % % delta_tign=get_delta_tign(distance,ros);
89 % % % elseif (time-count)<0
99 fid = fopen('output_tign.txt', 'w');
100 dlmwrite('output_tign.txt', result, 'delimiter', '\t','precision', '%.4f');
104 'did not find fixed point inside'
108 %%% function [tign,distance,A,D]=tign_update(tign,A,D,delta_tign,time_now,distance,interval,ros)
109 function [tign,distance,A,D]=tign_update(tign,A,D,delta_tign,time_now,distance,interval,ros)
111 % A - set of points whose neighbors will be updated
112 % C - if C[i,j]=1, then the neighbors of the point [i,j]
113 % will be updated in the next iteration within the same timestep
114 % D - if D[i,j]=1, then the neighbors of the point [i,j]
115 % will be updated only in the next timestep (only after we update ros)
122 if (tign(A(i,1)+dx,A(i,2)+dy)<time_now)==1
123 tign_new=tign(A(i,1),A(i,2))-0.5*(delta_tign(A(i,1)+dx,A(i,2)+dy,-dx+2,-dy+2)+delta_tign(A(i,1),A(i,2),2-dx,2-dy));
124 if (tign(A(i,1)+dx,A(i,2)+dy)<tign_new)&&(tign_new<=time_now)
125 tign(A(i,1)+dx,A(i,2)+dy)=tign_new;
126 C(A(i,1)+dx,A(i,2)+dy)=1;
128 if (time_now-tign_new>interval)
132 % if (time_now-tign_new<interval)
135 % D(A(i,1),A(i,2))=1;
138 % % % if (time_now-tign_new<interval)
139 % % % tign(A(i,1)+dx,A(i,2)+dy)=tign_new;
140 % % % C(A(i,1)+dx,A(i,2)+dy)=1;
142 % % % distance(A(i,1),A(i,2),2-dx,2-dy)=distance(A(i,1),A(i,2),2-dx,2-dy)-interval*ros(A(i,1),A(i,2),2-dx,2-dy);
143 % % % distance(A(i,1)+dx,A(i,2)+dy,2-dx,2-dy)=distance(A(i,1)+dx,A(i,2)+dy,2-dx,2-dy)-interval*ros(A(i,1)+dx,A(i,2)+dy,2-dx,2-dy);
144 % % % D(A(i,1)+dx,A(i,2)+dy)=1;
154 [A(:,1),A(:,2)]=find(C>0);
157 function distance=get_distances(long,lat)
158 % computing 4d array of distances between a point and its 8 neighbors
161 % long(i,j), lat(i,j) geographical coordinates of node [i,j], i=1:m, j=1:n, [m,n]=size(long)=size(lat)
164 % distance(i+1,j+1,a+2,b+2) = geographical distance between node [i,j] and [i+a,j+b] , a,b=-1:1
166 distance=zeros(size(long,1),size(long,2),3,3);
168 for i=2:size(long,1)-1
169 for j=2:size(long,2)-1
172 % distance between node [i,j] and [i+a,j+b]
173 distance(i,j,a+2,b+2)=sqrt((long(i+a,j+b,1)-long(i,j,1))^2+ ...
174 (lat(i+a,j+b,1)-lat(i,j,1))^2);
179 % note that distance(i,i,...) makes no sense if i=2,m+1 or j=2,n+1 in the direction to the outside
181 % some ideas to look at
182 % maybe use mirroring?
183 % maybe keep numbering [i,j] always same as original outside of routines?
184 % now need to remember which array is shifted and bordered by zeros and which one is not
185 % if I was doing it: keep distance size (m,n,3,3) but not compute distance(1,1,...) etc
186 % and keep it zero, same with delta_tign, etc.
191 % maybe get_delta_tign ?
193 function delta_tign=get_delta_tign(distance,ros)
194 % computing 4d array of differences of tign (delta_tign) between a point and its 8 neighbors
196 % distance(i+1,j+1,a+2,b+2) geographical distance between nodes [i,j] and [i+a,j+b]
198 % ros(i,j,a+2,b+2) rate of spread at node [i,j] in the direction towards [i+a,j+b]
201 % delta_tign(i,j,a+2,b+2) time the fire takes to propagate from [i,j] to [i+a,j+b]
203 delta_tign=zeros(size(distance));
205 for i=2:size(delta_tign,1)-1
206 for j=2:size(delta_tign,2)-1
209 delta_tign(i,j,a+2,b+2)=distance(i,j,a+2,b+2)/ros(i-1,j-1,a+2,b+2);
217 function A=get_perim_from_initial_tign(fire_area);
221 % A rows [i,j] of indices of nodes not burning that have at least one
225 for i=2:size(fire_area,1)-1
226 for j=2:size(fire_area,2)-1
227 % if (i,j) is not burning
228 if (fire_area(i,j)==0)
229 % if any neighbor is not burning
230 if (any(any(fire_area(i-1:i+1,j-1:j+1)>0))==1)
241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258 function result=perimeter_in_2(long,lat,ros,time_now,bound,wrfout,interval,count)
260 % Volodymyr Kondratenko December 8 2012
262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
264 % The function creates the initial matrix of times of ignitions
265 % given the perimeter and time of ignition at the points of the perimeter and
266 % is using wind and terrain gradient in its calculations
267 % Input: We get it after reading the data using function read_file_perimeter.m
269 % long FXLONG*UNIT_FXLONG, longtitude coordinates of the mesh converted into meters
270 % lat FXLAT*UNIT_FXLAT, latitude coordinates of the mesh converted into meters
271 % uf,vf horizontal wind velocity vectors of the points of the mesh
272 % dzdxf,dzdyf terrain gradient of the points of the mesh
273 % time_now time of ignition on the fireline (fire perimeter)
274 % bound set of ordered points of the fire perimeter 1st=last
275 % bound(i,1)-horisontal; bound(i,1)-vertical coordinate
277 % Output: Matrix of time of ignition
281 %addpath('../../other/Matlab/util1_jan');
282 %addpath('../../other/Matlab/netcdf');
284 fuels % This function is needed to create fuel variable, that contains all the characteristics
285 % types of fuel, this function lies in the same folder where you run the main_function.m
286 % (where is it originally located/can be created?)
290 bnd_size=size(bound);
294 %tign=zeros(n,m); % "time of ignition matrix" of the nodes
295 %A=zeros(n,m); % flag matrix of the nodes, A(i,j)=1 if the time of ignition of the
296 % point (i,j) was updated at least once
299 % IN - matrix, that shows, whether the point is inside (IN(x,y)>0) the burning region
300 % or outside (IN(x,y)<0)
301 % ON - matrix that, shows whether the point is on the boundary or not
302 % Both matrices evaluated using "polygon", coefficients are multiplied by
303 % 10^6, because the function looses acuracy when it deals with decimals
311 [IN,ON] = inpolygon(long1,lat1,xv,yv);
315 [delta_tign]=delta_tign_calculation(long,lat,ros);
317 % Calculates needed variables for rate of fire spread calculation
319 %%%%%%% First part %%%%%%%
320 % Set everything inside to time_now and update the tign of the points outside
322 % Initializing flag matrix A and time of ignition (tign)
323 % Extending the boundaries, in order to speed up the algorythm
326 % A contains coordinates of the points that were updated during the last
329 IN_ext=(2)*ones(n+2,m+2);
330 IN_ext(2:n+1,2:m+1)=IN(:,:,1);
333 % Set all the points outside to time_now and update the points inside
335 % Initializing flag matrix A and time of ignition (tign)
336 % Extending the boundaries, in order to speed up the algorythm
342 if sum(sum(IN_ext(i-1:i+1,j-1:j+1)))>0
349 tign_in=zeros(n+2,m+2);
350 tign_in(2:n+1,2:m+1)=(1-IN(:,:,1)).*time_now;
354 % The algorithm stops when the matrix converges (tign_old-tign==0) or if the amount of iterations
355 % % reaches the max(size()) of the mesh
359 for istep=1:max(size(tign_in)),
361 % The matrix of tign converged
368 str= sprintf('%f -- How long does it take to run step %i',time_toc,istep-1);
371 if ((time_old-max(max(tign_in(A(:,1),A(:,2)))))>=(count*interval))&&((time-count)>0)
373 sprintf('time_old= %f',time_old)
374 sprintf('tign_in(A(1,1),A(1,2))= %f',tign_in(A(1,1),A(1,2)))
375 sprintf('min(min(tign_in(A(:,1),A(:,2))))= %f',min(min(tign_in(A(:,1),A(:,2)))))
376 sprintf('max(max(tign_in(A(:,1),A(:,2))))= %f',max(max(tign_in(A(:,1),A(:,2)))))
377 sprintf('time_old-max(max(tign_in(A(:,1),A(:,2)))= %f',time_old-max(max(tign_in(A(:,1),A(:,2)))))
379 count1=mod(time_old-max(max(tign_in(A(:,1),A(:,2)))),count*interval)
380 time_old=time_old-count1*interval
382 ros=read_data_from_wrfout(wrfout,size(long,1),size(long,2),time);
383 delta_tign=delta_tign_calculation(long,lat,ros);
387 % tign_update - updates the tign of the points
388 [tign_in,A,C]=tign_update(tign_in,A,IN_ext,delta_tign,time_now);
389 % when it is outside the last parameter is 0, inside 1
390 changed=sum(tign_in(:)~=tign_last(:));
397 sprintf('%s \n step %i inside tign changed at %i points \n %f -- norm of the difference',str,istep,changed,norm(tign_in-tign_last))
398 sprintf('size of A- %i',size(A,1))
401 %final_tign(2:n+1,2:m+1)=(IN(:,:,1)>0).*tign_in(2:n+1,2:m+1)+(IN(:,:,1)==0).*tign(2:n+1,2:m+1);
402 result=final_tign(2:n+1,2:m+1);
404 fid = fopen('output_tign.txt', 'w');
405 dlmwrite('output_tign.txt', result, 'delimiter', '\t','precision', '%.4f');
409 'did not find fixed point inside'