Lezione del 10 maggio 2007¶
Metodi Numerici per l’equazione del trasporto lineare
Programma che implementa vari solutori per l’equazione del trasporto lineare:
File LagenSolver.m
:open:
1%
2% A selection of 8 schemes for the linear advection equation
3%
4% Name of program: LagenSolver
5%
6% Purpose: to solve the linear advection equation with constant
7% coefficient by a selection of 8 schemes, namely:
8%
9% The Godunov first-order upwind scheme
10% The Toro-Billett first-order upwind scheme
11% The Lax-Friedrichs scheme (first-order centred)
12% The FORCE scheme (first-order centred)
13% The Godunov first-order centred scheme
14% The Lax-Wendroff scheme (second order, oscillatory)
15% The Fromm scheme (second order, oscillatory)
16% The Warming-Beam scheme (second order, oscillatory)
17%
18% Programer: Enrico Bertolazzi
19% (based on the Fortran NUMERICA lib of prof. E. F. Toro )
20%
21% Last revision: 10st May 2007
22%
23% Theory is found in Chaps. 5, 7 and 13 of Reference 1
24% and in original references therein
25%
26% 1. E. F. Toro, "Riemann Solvers and Numerical Methods for Fluid Dynamics"
27% Springer-Verlag, 1997
28% Second Edition, 1999
29%
30% This program is transaled in MATLAB from the NUMERICA library:
31%
32% NUMERICA
33% A Library of Source Codes for Teaching,
34% Research and Applications,
35% by E. F. Toro
36% Published by NUMERITEK LTD,
37% Website: www.numeritek.coM
38%
39%
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43%
44% PURPOSE:
45%
46% solve the linear advection problem
47%
48% u (t,x) + a u (t,x) = 0 t > 0, -1 <= x <= 1
49% t x
50%
51% u(0,x) = u0(x) -1 <= x <= 1
52%
53% INPUT:
54% PRB A Structure describing the problem with fields
55% problem = an integer selectiong the numerical flux used
56% 1 - The Godunov first-order upwind scheme
57% 2 - The Toro-Billett first-order upwind scheme
58% 3 - The Lax-Friedrichs scheme (first-order centred)
59% 4 - The FORCE scheme (first-order centred)
60% 5 - The Godunov first-order centred scheme
61% 6 - The Lax-Wendroff scheme (second order, oscillatory)
62% 7 - The Fromm scheme (second order, oscillatory)
63% 8 - The Warming-Beam scheme (second order, oscillatory)
64% init = an integer selectiong the initial data used
65% 1 - square wave
66% 2 - smooth wave
67% Ncells = number of cell discretizing [-1,1] the domain of the problems
68% CFL = time step advancing CFL ratio
69% a = speed of the signal of the PDE
70% StepTime = solution is saved every StepTime
71% FinalTime = solution is computed up to FinalTime
72%
73% OUTPUT:
74% X = the cell boundary of the subdivided interval [-1,1]; X(1) = -1,..., X(N) = 1
75% UFRAMES = matrix with the frames of the computed solution. UFRAMES(i,:) is the solution
76% at time level i-th
77% TFRAMES = vector with the time frames. TFRAMES(i) the time of the computed frame UFRAMES(i,:).
78%
79% Example of use
80%
81% PRB . problem = 1 % select Godunov first-order upwind scheme
82% PRB . init = 1 % select square wave for initial data
83% PRB . Ncells = 100 % select 100 cell inteval subdivision
84% PRB . CFL = 0.9 % advance with DT do not excede 0.9 * CFL
85% PRB . a = 0.1 % speed of teh signal
86% PRB . StepTime = 0.5 % save the frame every 0.5 second
87% PRB . FinalTime = 3 % compute the solution op to 3 second
88%
89% call the solver
90% [X,UFRAMES,TFRAMES] = LagenSolver(PRB) ;
91%
92% plot the solution al frame n. 30
93% plot( X, UFRAMES(30,:) );
94%
95function [X,UFRAMES,TFRAMES] = LagenSolver(PRB)
96 N = PRB.Ncells ;
97 % Initial conditions are set up
98 switch( PRB . init )
99 case 1
100 [X,U,DX] = InitSquare(N) ;
101 case 2
102 [X,U,DX] = InitSmooth(N) ;
103 end
104 % maximum speed
105 SMAX = abs(PRB.a) ;
106
107 k = 1 ;
108 Time = 0 ;
109 NextTime = PRB.StepTime ;
110
111 % save initial frame
112 UFRAMES(k,:) = U ;
113 TFRAMES(k) = Time ;
114
115 % Time marching procedure
116 for i=1:1000
117
118 % Boundary conditions are cyclic so we set ciclycally the vectors
119 ULL = [ U(N-1), U(N), U(1:N-1) ] ;
120 UL = [ U(N), U ] ;
121 UR = [ U, U(1) ] ;
122 URR = [ U(2:N), U(1), U(2) ] ;
123
124 % Courant-Friedrichs-Lewy (CFL) condition imposed
125 DT = PRB.CFL*DX/SMAX ;
126 Time = Time + DT ;
127
128 % adjust time step if necessary to match the time grid
129 if Time >= NextTime
130 % reduce DT in order to match NextTime
131 DT = DT - ( Time - NextTime ) ;
132 Time = NextTime ;
133 NextTime = NextTime + PRB.StepTime ;
134 k = -k ; % mark solution to be saved
135 end
136
137 % Intercell numerical fluxes are computed.
138 switch( PRB . problem )
139 case 0
140 FLUX = Centered (UL, UR, PRB.a, DT, DX ) ;
141 case 1
142 FLUX = Godunov (UL, UR, PRB.a, DT, DX ) ;
143 case 2
144 FLUX = ToroBillet (ULL, UL, UR, URR, PRB.a, DT, DX ) ;
145 case 3
146 FLUX = LaxFriedrichs (UL, UR, PRB.a, DT, DX ) ;
147 case 4
148 FLUX = Force (UL, UR, PRB.a, DT, DX ) ;
149 case 5
150 FLUX = GodunovCentered (UL, UR, PRB.a, DT, DX ) ;
151 case 6
152 FLUX = Richtmyer (UL, UR, PRB.a, DT, DX ) ;
153 case 7
154 FLUX = Fromm (ULL, UL, UR, URR, PRB.a, DT, DX ) ;
155 case 8
156 FLUX = WarmingBeam (ULL, UL, UR, URR, PRB.a, DT, DX ) ;
157 end
158 % Solution is updated according to conservative formula
159 U = U + (DT/DX) .* (FLUX(1:N) - FLUX(2:N+1)) ;
160
161 % if k < 0 solution must be saved
162 if k < 0
163 k = -k+1 ;
164 UFRAMES(k,:) = U ;
165 TFRAMES(k) = Time ;
166 end
167
168 if Time >= PRB.FinalTime
169 break ;
170 end
171 end
172end
173
174%
175% Purpose: to set initial conditions for solution U
176%
177function [X,U,DX] = InitSmooth(N)
178 % Calculate mesh size DX
179 DX = 2.0/N ;
180 % Initialise arrays (index 1,2 and IDIM+3, IDIM+4 are used for "ghost cells")
181 % smooth profile
182 X = [-1+DX/2:DX:1-DX/2] ;
183 U = exp( -8 .* X .^ 2 ) ;
184end
185%
186function [X,U,DX] = InitSquare(N)
187 % Calculate mesh size DX
188 DX = 2.0/N ;
189 N3 = floor(N/3) ;
190 M = N - N3 - N3 ;
191 % Initialise arrays
192 X = [-1+DX/2:DX:1-DX/2] ;
193 U = [zeros(1,N3) ones(1,M) zeros(1,N3) ] ;
194end
195
196%
197%
198% positioning of the variables
199%
200% U(1) U(2) U(3) U(N)
201% +------+------+------+------+------+- +------+
202% | | | | | | ... | |
203% F(1) F(2) F(3) F(N) F(N+1)
204%
205% U(i) is the cell average allocated to center of the cell i.
206% F(i) is the flux at the interface between cells i end cell i-1.
207
208
209% Purpose: to compute intercell fluxes as left and right average: CANNOT WORK
210%
211function F = Centered(UL,UR,a,DT,DX)
212 F = (a/2) .* (UL+UR) ;
213end
214% Purpose: to compute intercell fluxes according to the
215% Godunov first order upwind method
216%
217function F = Godunov(UL,UR,a,DT,DX)
218 % the flux at interface i is computed
219 if a > 0
220 % using the left state
221 F = a .* UL ;
222 else
223 % using the right state
224 F = a .* UR ;
225 end
226end
227%
228% Purpose: to compute intercell fluxes according to the
229% Toro-Billett first order CFL-2 scheme
230% See Eq. 13.22, Chapter 13, Ref. 1
231function [FLUX] = ToroBillet(ULL,UL,UR,URR,a,DT,DX)
232 CFLNUM = a*DT/DX ;
233 if ( abs(CFLNUM) <= 1 )
234 % Conventional Godunov upwind flux
235 FLUX = Godunov(UL,UR,a,DT,DX) ;
236 else
237 if a > 0
238 % Information travels from the left
239 cfll = ((CFLNUM - 1)/CFLNUM) * a ;
240 cfl = (1.0/CFLNUM) * a ;
241 FLUX = cfll * ULL + cfl * UL ;
242 else
243 % Information travels from the right
244 cfrr = ((CFLNUM + 1)/CFLNUM) * a ;
245 cfr = -(1.0/CFLNUM) * a ;
246 FLUX = cfl * UL + cfr * UR ;
247 end
248 end
249end
250
251% Purpose: to compute intercell fluxes according to the
252% Lax-Friedrichs method
253% See Eq. 5.77, Chapter 5, Ref. 1
254function [FLUX] = LaxFriedrichs(UL,UR,a,DT,DX)
255 CFLNUM = a*DT/DX ;
256 FLUX = 0.5 .* ( a .* (UL+UR) + (DX/DT) * (UL-UR) ) ;
257end
258
259% Purpose: to compute intercell fluxes according to the
260% Force method
261% See Eq. 7.32, Chapter 7, Ref. 1
262function [FLUX] = Force(UL,UR,a,DT,DX)
263 CFLNUM = a*DT/DX ;
264 % Compute Lax-Friedrichs flux
265 FluxLF = 0.5 .* ( a .* (UL+UR) + (DX/DT) * ( UL-UR ) ) ;
266 % Compute Richtmyer flux
267 FluxR = 0.5 .* a .* ( (UL + UR) + (DT/DX) .* a .* ( UL - UR ) ) ;
268 % Compute Force flux
269 FLUX = 0.5*(FluxLF + FluxR) ;
270end
271
272% Purpose: to compute intercell fluxes according to the
273% Godunov first order upwind method
274% See Eq. 13.73, Chapter 13, Ref. 1
275function FLUX = GodunovCentered(UL,UR,a,DT,DX)
276 CFLNUM = a*DT/DX ;
277 FLUX = 0.5 .* a .* ( (1+2*CFLNUM) * UL + ( 1-2*CFLNUM) * UR ) ;
278end
279
280% Purpose: to compute intercell fluxes according to the
281% Richtmyer method, or two step Lax-Wendroff method
282% See Eq. 5.79, Chapter 5, Ref. 1
283function FLUX = Richtmyer(UL,UR,a,DT,DX)
284 FLUX = 0.5 .* a .* ( (UL + UR) + (DT/DX) .* a .* ( UL - UR ) ) ;
285end
286
287% Purpose: to compute intercell fluxes according to the
288% Fromm first order upwind method
289% See Eq. 13.35, Chapter 13, Ref. 1
290function FLUX = Fromm(ULL,UL,UR,URR,a,DT,DX)
291 CFLNUM = a*DT/DX ;
292 if ( a > 0 )
293 FLUX = a .* (UL + 0.25 .* (1-CFLNUM) .* (UR - ULL)) ;
294 else
295 FLUX = a .* (UR - 0.25 .* (1+CFLNUM) .* (URR - UR)) ;
296 end
297end
298
299% Purpose: to compute intercell fluxes according to the
300% Warming-Beam method
301% See Eq. 13.21, Chapter 13, Ref. 1
302function FLUX = WarmingBeam(ULL,UL,UR,URR,a,DT,DX)
303 CFLNUM = a*DT/DX ;
304 if ( a > 0 )
305 FLUX = 0.5 .* a .* ( (3-CFLNUM) .* UL - (1-CFLNUM) .* ULL );
306 else
307 FLUX = 0.5 .* a .* ( (3+CFLNUM) .* UR - (1+CFLNUM) .* URR );
308 end
309end
Programma driver per verificare il codice:
File LagenExample.m
:open:
1PRB . problem = 8 ; % select Godunov first-order upwind scheme
2PRB . init = 1 ; % select square wave for initial data
3PRB . Ncells = 100 ; % select 100 cell inteval subdivision
4PRB . CFL = 0.49 ; % advance with DT do not excede 0.9 * CFL
5PRB . a = 0.25 ; % speed of the signal
6PRB . StepTime = 1 ; % save the frame every 0.5 second
7PRB . FinalTime = 200 ; % compute the solution op to 3 second
8% call the solver
9[X,UFRAMES,TFRAMES] = LagenSolver(PRB) ;
10% generate movie of the solution
11LagenMovie(X,UFRAMES,TFRAMES) ;
12
13% plot the solution al frame n. 4
14%[,N] = size(TFRAMES) ;
15%plot( X, UFRAMES(N,:) );
Programma driver che permette di generare un filmato avi della soluzione:
File LagenMovie.m
:open:
1function aviobj = LagenMovie(X,UFRAMES,TFRAMES)
2 [dummy,nframes] = size(TFRAMES) ;
3 aviobj = avifile('example.avi')
4 rect = [100 100 612 612] ;
5 fig = figure('position',rect) ;
6 set(fig,'DoubleBuffer','on');
7 axis manual ;
8 title('Lagen Movie');
9 for i=1:nframes
10 clc;
11 plot(X, UFRAMES(i,:),'-ob','MarkerFaceColor','r');
12 axis([-1 1 -0.5 1.5]);
13 aviobj = addframe(aviobj,getframe(fig));
14 end
15 aviobj = close(aviobj);
16end
Soluzione esatta per fare confronti:
File LagenExactSquare.m
:open:
1%
2%
3function [X,U] = LagenExactSquare(N,TIME,SPEEDA)
4 % Calculate mesh size DX
5 DX = 2.0/N ;
6 X = [-1+DX/2-TIME*SPEEDA:DX:1-DX/2-TIME*SPEEDA] ;
7 % put the solution in [-1..1]
8 U = zeros(1,N) ;
9 for i=1:N
10 while ( X(i) < -1 )
11 X(i) = X(i) + 2 ;
12 end ;
13 while ( X(i) > 1 )
14 X(i) = X(i) - 2 ;
15 end ;
16 if X(i) >= -1/3.0 && X(i) <= 1/3.0
17 U(i) = 1 ;
18 end
19 end
20 % smooth profile
21 X = [-1+DX/2:DX:1-DX/2] ;
22end
File LagenExactSmooth.m
:open:
1%
2% Purpose: to set initial conditions for solution U and
3% initialise other variables.
4%
5% Variables:
6%
7% U Array for numerical solution
8%
9function [X,U] = LagenExactSmooth(N,TIME,SPEEDA)
10 % Calculate mesh size DX
11 DX = 2.0/N ;
12 X = [-1+DX/2-TIME*SPEEDA:DX:1-DX/2-TIME*SPEEDA] ;
13 % put the solution in [-1..1]
14 for i=1:N
15 while ( X(i) < -1 )
16 X(i) = X(i) + 2 ;
17 end ;
18 while ( X(i) > 1 )
19 X(i) = X(i) - 2 ;
20 end ;
21 end
22 % smooth profile
23 U = exp( -8 .* X .^ 2 ) ;
24 X = [-1+DX/2:DX:1-DX/2] ;
25end