4 #===============================================================================================================================
5 # Name : Résolution VF de l'équation du Burgers 1D \partial_t u + 1/2 \partial_x u^2 = 0
6 # Author : Michaël Ndjinga
7 # Copyright : CEA Saclay 2019
8 # Description : Comparaison des schémas Upwind et de Godunov explicite sur un maillage 1D régulier
9 # Donnée initiale discontinue générant une onde de raréfaction
10 # Conditions aux limites de Neumann
11 # Conclusion : le schéma Upwind n'est pas entropique, contrairement au schéma de Godunov
12 # Création et sauvegarde du champ résultant et des figures
13 # Génération d'une video sauvegardée dans un fichier .mp4
14 #================================================================================================================================
18 from copy import deepcopy
21 import matplotlib.pyplot as plt
22 import matplotlib.animation as manimation
24 def Flux_upwind(u_l, u_r):
30 flux = (0.5*u_l*u_l + 0.5*u_r*u_r)/2
34 def Flux_Godunov(u_l, u_r):
37 elif (u_l<0 and 0<u_r):
40 flux = min(0.5*u_l*u_l,0.5*u_r*u_r);
42 flux = max(0.5*u_l*u_l,0.5*u_r*u_r);
47 print( "Simulation of 1D Burgers' equation with upwind and godunov explicit schemes" )
49 ##################### Simulation parameters
50 a = -1. # space domain : a <= x <= b
53 dx = (b - a) / nx #space step
55 tmax = 4 # runs the simulation for 0 <= t <= tMax
59 x=[a+0.5*dx + i*dx for i in range(nx)] # array of cell center (1D mesh)
61 ########################## Initial data
62 u_initial = [ (xi<(a+b)/2)*(-1) + (xi>(a+b)/2)*(1.) for xi in x]
63 u_upwind = [ (xi<(a+b)/2)*(-1) + (xi>(a+b)/2)*(1.) for xi in x]
64 u_godunov = [ (xi<(a+b)/2)*(-1) + (xi>(a+b)/2)*(1.) for xi in x]
65 u_exact = [ (xi<(a+b)/2)*(-1) + (xi>(a+b)/2)*(1.) for xi in x]
70 max_initial=max(u_initial)
71 min_initial=min(u_initial)
78 FFMpegWriter = manimation.writers['ffmpeg']
79 metadata = dict(title="Finite volumes schemes for Burgers equation", artist = "CEA Saclay", comment="Rarefaction wave")
80 writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
81 with writer.saving(plt.figure(), "1DBurgersEquation_FV"+".mp4", ntmax):
82 ########################### Postprocessing initialisation
87 plt.ylim( min_initial - 0.1*(max_initial-min_initial), max_initial + 0.5*(max_initial-min_initial) )
88 plt.title('Finite volume schemes for Burgers equation')
89 line1, = plt.plot(x, u_upwind, label='Conservative (Upwind) scheme') #new picture for video # Returns a tuple of line objects, thus the comma
90 line2, = plt.plot(x, u_godunov, label='Conservative (Godunov) scheme') #new picture for video # Returns a tuple of line objects, thus the comma
91 line3, = plt.plot(x, u_exact, label='Exact solution') #new picture for video # Returns a tuple of line objects, thus the comma
94 print("Starting time loop")
95 print("-- Iter: " + str(it) + ", Time: " + str(time) )
96 np.savetxt("BurgersEquation_FV_Upwind_ResultField_0" +".txt", u_upwind, delimiter="\n")
97 np.savetxt("BurgersEquation_FV_Godunov_ResultField_0"+".txt", u_godunov, delimiter="\n")
98 np.savetxt("BurgersEquation_FV_Exact_ResultField_0"+".txt", u_exact, delimiter="\n")
100 plt.savefig("BurgersEquation_FV_Rarefaction_ResultField_0"+".png")
102 ############################# Time loop
103 while (it < ntmax and time <= tmax):
104 upw = max(np.abs(u_upwind))
107 for i in range(0,nx):
109 flux_iminus = 0.5*u_upwind[0]*u_upwind[0]#Flux at the left Neumann boundary
111 flux_iplus = 0.5*u_upwind[nx-1]*u_upwind[nx-1]#Flux at the right Neumann boundary
113 flux_iplus = Flux_upwind(u_upwind[i],u_upwind[i+1])
115 Unp1[i] = u_upwind[i] - dt/dx*(flux_iplus-flux_iminus);
116 flux_iminus = flux_iplus;
119 for i in range(0,nx):
121 flux_iminus = 0.5*u_godunov[0]*u_godunov[0]#Flux at the left Neumann boundary
123 flux_iplus = 0.5*u_godunov[nx-1]*u_godunov[nx-1]#Flux at the right Neumann boundary
125 flux_iplus = Flux_Godunov(u_godunov[i],u_godunov[i+1])
127 Unp1_godunov[i] = u_godunov[i] - dt/dx*(flux_iplus-flux_iminus);
128 flux_iminus = flux_iplus;
129 u_godunov = Unp1_godunov
134 u_exact = [ (xi<-time)*(-1) + (xi>time)*(1.) + (-time<=xi and xi<=time)*(xi/time) for xi in x]
137 line1.set_ydata(u_upwind)
138 line2.set_ydata(u_godunov)
139 line3.set_ydata(u_exact)
142 if (it % output_freq == 0):
143 print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
144 np.savetxt( "BurgersEquation_Upwind_ResultField_" +str(it)+".txt", u_upwind, delimiter="\n")
145 np.savetxt( "BurgersEquation_Godunov_ResultField_"+str(it)+".txt", u_godunov, delimiter="\n")
146 np.savetxt( "BurgersEquation_Exact_ResultField_"+str(it)+".txt", u_exact, delimiter="\n")
147 plt.savefig("BurgersEquation_FV_Rarefaction_ResultField_"+str(it)+".png")
150 print("Simulation of rarefaction wave on Burgers' equation with finite volume schemes done.")
154 if __name__ == """__main__""":