PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/standalone/matlab/prop_ls_cir.m

http://github.com/jbeezley/wrf-fire
Objective C | 117 lines | 112 code | 5 blank | 0 comment | 6 complexity | 7c2e4c36b3544b23ccb6cb514c4411f4 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. istep=0;
  20. msteps=1000;
  21. diffLx=zeros(m,n);
  22. diffLy=zeros(m,n);
  23. diffRx=zeros(m,n);
  24. diffRy=zeros(m,n);
  25. method='godunov'
  26. split='spread';
  27. % split='wind';
  28. % split = 'orig';
  29. % time loop
  30. while t<time1-tol & istep < msteps
  31. istep=istep+1;
  32. % one-sided differences
  33. [diffLx,diffRx,diffLy,diffRy,diffCx,diffCy]=get_diff(phi,dx,dy);
  34. % gradient of level function is the normal direction
  35. scale=sqrt(diffCx.*diffCx+diffCy.*diffCy+eps);
  36. nvx=diffCx./scale;
  37. nvy=diffCy./scale;
  38. % propagation speed
  39. %speed=spread_rate(r,vx,vy,nvx,nvy,scale);
  40. %
  41. speed=vx.*nvx + vy.*nvy;
  42. speed=max(speed,0);
  43. % to recover advection vv and spread r, transition between:
  44. % r = 0 & (normal,v) > const*speed => vv=speed*v/(normal,v) & rr=0
  45. % speed >> (normal,v) => vv=0 & rr=speed
  46. nvv = nvx .* vx + nvy .* vy;
  47. % the CIR method
  48. switch method
  49. case 'cir'
  50. dt=min(min(dx./max(abs(speed.*nvx),eps)))+min(min(dy./max(abs(speed.*nvy),eps)));
  51. dt=min(time1-t,0.5*dt)
  52. % locations back on characteristics, in mesh index coordinates
  53. [xii,yii]=meshgrid(1:m,1:n);
  54. xinc=dt.*speed.*nvx./dx;
  55. xi = xii - xinc;
  56. yinc=dt.*speed.*nvy./dy;
  57. yi = yii - yinc;
  58. phi_new=interp2(xii,yii,phi,xi,yi);
  59. phi=min(phi_new,phi);
  60. case 'godunov'
  61. switch split
  62. case 'wind'
  63. a=2*nvv>speed;
  64. nvv(a==0)=1;
  65. ! a=zeros(size(a));
  66. %no_wind_cases=sum(sum(1-a))
  67. rr=speed.*(1-a);
  68. corr = a .* speed ./ nvv
  69. vvx = vx .* corr;
  70. vvy = vy .* corr;
  71. case 'orig'
  72. vvx = vx;vvy= vy;rr=r; % all original, if r=0 pure upwinding
  73. case 'spread'
  74. rr = speed; vvx=0*vx; vvy=0*vy; % all in normal speed, Godunov meth.
  75. % vvx=vx;vvy=vy;
  76. otherwise
  77. error('unknown split')
  78. end
  79. % Godunov scheme for normal motion
  80. flowLx=(diffLx>=0 & diffCx>=0);
  81. flowRx=(diffRx<=0 & diffCx<0);
  82. diff2x=diffLx.*flowLx + diffRx.*flowRx; %
  83. flowLy=(diffLy>=0 & diffCy>=0);
  84. flowRy=(diffRy<=0 & diffCy<0);
  85. diff2y=diffLy.*flowLy + diffRy.*flowRy; %
  86. grad=sqrt(diff2x.*diff2x + diff2y.*diff2y);
  87. nz=find(grad);
  88. %tbound_n(1)=max(abs(r.*sqrt(diff2x(nz)))./grad(nz))/dx; % time step bnd
  89. %tbound_n(2)=max(abs(r.*sqrt(diff2y(nz)))./grad(nz))/dy;
  90. tbound_np=rr.*(abs(diff2x)./dx+abs(diff2y)./dy); % pointwise time step bnd
  91. tbound_n=max(tbound_np(nz)./abs(grad(nz))); % worst case
  92. tend_n =-rr.*grad; % the result, tendency
  93. % standard upwinding for advection
  94. tend_a=-(diffLx.*max(vvx,0)+diffRx.*min(vvx,0)+...
  95. diffLy.*max(vvy,0)+diffRy.*min(vvy,0));
  96. tbound_ax=max(abs(vvx(:)))/dx;
  97. tbound_ay=max(abs(vvy(:)))/dy;
  98. % complete right-hand side
  99. tend=tend_n + tend_a;
  100. % complete time step bound
  101. tbound = 1/(tbound_n+tbound_ax+tbound_ay+eps);
  102. % decide on timestep
  103. dt=min(time1-t,0.5*tbound);
  104. % trailing edge correction - do not allow fireline to go backwards
  105. tend=min(tend,0);
  106. % advance
  107. phi=phi+dt*tend;
  108. end
  109. t=t+dt;
  110. end
  111. fprintf('prop_ls: %g steps from %g to %g, split %s\n',istep,time0,t,split)
  112. end % of the function prop_ls