1 function [t,phi]=prop_ls(phi0,time0,time1,vx,vy,r,dx,dy,spread_rate)
\r
2 % a jm/mkim version of propagate
\r
3 % follows Osher-Fedkiw and Mitchell toolbox
\r
5 % phi level function out
\r
6 % phi0 level function in
\r
7 % time0 starting time
\r
9 % vx component x of velocity field, passed to spread_rate
\r
10 % vy component y of velocity field, passed to spread_rate
\r
11 % r propagation speed in normal direction
\r
12 % dx mesh step in x direction
\r
13 % dy mesh step in y direction
\r
17 phi=phi0; % allocate level function
\r
19 t=time0; % current time
\r
34 while t<time1-tol & istep < msteps
\r
36 % one-sided differences
\r
37 [diffLx,diffRx,diffLy,diffRy,diffCx,diffCy]=get_diff(phi,dx,dy);
\r
38 % gradient of level function is the normal direction
\r
39 scale=sqrt(diffCx.*diffCx+diffCy.*diffCy+eps);
\r
42 % propagation speed
\r
43 %speed=spread_rate(r,vx,vy,nvx,nvy,scale);
\r
45 speed=vx.*nvx + vy.*nvy;
\r
47 % to recover advection vv and spread r, transition between:
\r
48 % r = 0 & (normal,v) > const*speed => vv=speed*v/(normal,v) & rr=0
\r
49 % speed >> (normal,v) => vv=0 & rr=speed
\r
50 nvv = nvx .* vx + nvy .* vy;
\r
54 dt=min(min(dx./max(abs(speed.*nvx),eps)))+min(min(dy./max(abs(speed.*nvy),eps)));
\r
55 dt=min(time1-t,0.5*dt)
\r
56 % locations back on characteristics, in mesh index coordinates
\r
57 [xii,yii]=meshgrid(1:m,1:n);
\r
58 xinc=dt.*speed.*nvx./dx;
\r
60 yinc=dt.*speed.*nvy./dy;
\r
62 phi_new=interp2(xii,yii,phi,xi,yi);
\r
63 phi=min(phi_new,phi);
\r
70 %no_wind_cases=sum(sum(1-a))
\r
72 corr = a .* speed ./ nvv
\r
76 vvx = vx;vvy= vy;rr=r; % all original, if r=0 pure upwinding
\r
78 rr = speed; vvx=0*vx; vvy=0*vy; % all in normal speed, Godunov meth.
\r
81 error('unknown split')
\r
83 % Godunov scheme for normal motion
\r
84 flowLx=(diffLx>=0 & diffCx>=0);
\r
85 flowRx=(diffRx<=0 & diffCx<0);
\r
86 diff2x=diffLx.*flowLx + diffRx.*flowRx; %
\r
87 flowLy=(diffLy>=0 & diffCy>=0);
\r
88 flowRy=(diffRy<=0 & diffCy<0);
\r
89 diff2y=diffLy.*flowLy + diffRy.*flowRy; %
\r
90 grad=sqrt(diff2x.*diff2x + diff2y.*diff2y);
\r
92 %tbound_n(1)=max(abs(r.*sqrt(diff2x(nz)))./grad(nz))/dx; % time step bnd
\r
93 %tbound_n(2)=max(abs(r.*sqrt(diff2y(nz)))./grad(nz))/dy;
\r
94 tbound_np=rr.*(abs(diff2x)./dx+abs(diff2y)./dy); % pointwise time step bnd
\r
95 tbound_n=max(tbound_np(nz)./abs(grad(nz))); % worst case
\r
96 tend_n =-rr.*grad; % the result, tendency
\r
97 % standard upwinding for advection
\r
98 tend_a=-(diffLx.*max(vvx,0)+diffRx.*min(vvx,0)+...
\r
99 diffLy.*max(vvy,0)+diffRy.*min(vvy,0));
\r
100 tbound_ax=max(abs(vvx(:)))/dx;
\r
101 tbound_ay=max(abs(vvy(:)))/dy;
\r
102 % complete right-hand side
\r
103 tend=tend_n + tend_a;
\r
104 % complete time step bound
\r
105 tbound = 1/(tbound_n+tbound_ax+tbound_ay+eps);
\r
106 % decide on timestep
\r
107 dt=min(time1-t,0.5*tbound);
\r
108 % trailing edge correction - do not allow fireline to go backwards
\r
115 fprintf('prop_ls: %g steps from %g to %g, split %s\n',istep,time0,t,split)
\r
116 end % of the function prop_ls
\r