PageRenderTime 40ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/standalone/matlab/prop_ls.m

http://github.com/jbeezley/wrf-fire
Objective C | 101 lines | 97 code | 4 blank | 0 comment | 5 complexity | f44d87530438ca04ba413631d8039309 MD5 | raw file
Possible License(s): AGPL-1.0
  1. function [t,phi]=prop_ls(phi0,time0,time1,vx,vy,r,dx,dy,spread_rate)
  2. % a jm/mkim version of propagate
  3. % follows Osher-Fedkiw and Mitchell toolbox
  4. % phi level function out
  5. % phi0 level function in
  6. % time0 starting time
  7. % time1 end time
  8. % vx component x of velocity field, passed to spread_rate
  9. % vy component y of velocity field, passed to spread_rate
  10. % r propagation speed in normal direction
  11. % dx mesh step in x direction
  12. % dy mesh step in y direction
  13. %
  14. % initialize
  15. phi=phi0; % allocate level function
  16. [m,n]=size(phi);
  17. t=time0; % current time
  18. tol=300*eps;
  19. split='spread';
  20. % split='wind';
  21. % split = 'orig';
  22. istep=0;
  23. msteps=1000;
  24. diffLx=zeros(m,n);
  25. diffLy=zeros(m,n);
  26. diffRx=zeros(m,n);
  27. diffRy=zeros(m,n);
  28. % time loop
  29. while t<time1-tol & istep < msteps
  30. istep=istep+1;
  31. % one-sided differences
  32. [diffLx,diffRx,diffLy,diffRy,diffCx,diffCy]=get_diff(phi,dx,dy);
  33. % gradient of level function is the normal direction
  34. scale=sqrt(diffCx.*diffCx+diffCy.*diffCy+eps);
  35. nvx=diffCx./scale;
  36. nvy=diffCy./scale;
  37. % propagation speed
  38. speed=spread_rate(r,vx,vy,nvx,nvy,scale);
  39. speed=max(speed,0);
  40. % to recover advection vv and spread r, transition between:
  41. % r = 0 & (normal,v) > const*speed => vv=speed*v/(normal,v) & rr=0
  42. % speed >> (normal,v) => vv=0 & rr=speed
  43. nvv = nvx .* vx + nvy .* vy;
  44. switch split
  45. case 'wind'
  46. a=2*nvv>speed;
  47. nvv(a==0)=1;
  48. ! a=zeros(size(a));
  49. %no_wind_cases=sum(sum(1-a))
  50. rr=speed.*(1-a);
  51. corr = a .* speed ./ nvv
  52. vvx = vx .* corr;
  53. vvy = vy .* corr;
  54. case 'orig'
  55. vvx = vx;vvy= vy;rr=r; % all original, if r=0 pure upwinding
  56. case 'spread'
  57. rr = speed; vvx=0*vx; vvy=0*vy; % all in normal speed, Godunov meth.
  58. % vvx=vx;vvy=vy;
  59. otherwise
  60. error('unknown split')
  61. end
  62. % Godunov scheme for normal motion
  63. flowLx=(diffLx>=0 & diffCx>=0);
  64. flowRx=(diffRx<=0 & diffCx<0);
  65. diff2x=diffLx.*flowLx + diffRx.*flowRx; %
  66. flowLy=(diffLy>=0 & diffCy>=0);
  67. flowRy=(diffRy<=0 & diffCy<0);
  68. diff2y=diffLy.*flowLy + diffRy.*flowRy; %
  69. grad=sqrt(diff2x.*diff2x + diff2y.*diff2y);
  70. nz=find(grad);
  71. %tbound_n(1)=max(abs(r.*sqrt(diff2x(nz)))./grad(nz))/dx; % time step bnd
  72. %tbound_n(2)=max(abs(r.*sqrt(diff2y(nz)))./grad(nz))/dy;
  73. tbound_np=rr.*(abs(diff2x)./dx+abs(diff2y)./dy); % pointwise time step bnd
  74. tbound_n=max(tbound_np(nz)./abs(grad(nz))); % worst case
  75. tend_n =-rr.*grad; % the result, tendency
  76. % standard upwinding for advection
  77. tend_a=-(diffLx.*max(vvx,0)+diffRx.*min(vvx,0)+...
  78. diffLy.*max(vvy,0)+diffRy.*min(vvy,0));
  79. tbound_ax=max(abs(vvx(:)))/dx;
  80. tbound_ay=max(abs(vvy(:)))/dy;
  81. % complete right-hand side
  82. tend=tend_n + tend_a;
  83. % complete time step bound
  84. tbound = 1/(tbound_n+tbound_ax+tbound_ay+eps);
  85. % decide on timestep
  86. dt=min(time1-t,0.5*tbound);
  87. % trailing edge correction - do not allow fireline to go backwards
  88. %tt=max(dx,dy);
  89. %ins=find(phi<=-0);
  90. %tend(ins)=min(tend(ins),0);
  91. tend=min(tend,0);
  92. % advance
  93. phi=phi+dt*tend;
  94. t=t+dt;
  95. end
  96. fprintf('prop_ls: %g steps from %g to %g, split %s\n',istep,time0,t,split)
  97. end % of the function prop_ls