4 #===============================================================================================================================
5 # Name : Résolution VF de l'équation de la chaleur 1D \partial_t u = d \partial_xx u avec conditions aux limites périodiques
6 # Author : Michaël Ndjinga
7 # Copyright : CEA Saclay 2019
8 # Description : Maillage 1D régulier
9 # Création et sauvegarde du champ résultant et des figures
10 # Génération d'une video sauvegardée dans un fichier .mp4
11 #================================================================================================================================
14 from math import sin, pi, ceil
18 import matplotlib.pyplot as plt
19 import matplotlib.animation as manimation
21 from copy import deepcopy
23 def HeatEquation1DExplicit(nx,cfl):
24 print "Simulation of 1D heat equation with an explicit scheme"
26 ##################### Simulation parameters
27 a = 0.0 # space domain : a <= x <= b
29 dx = (b - a) / nx #space step
31 d = 1. # thermal diffusivity
32 tmax = (b-a)/d # runs the simulation for 0 <= t <= tMax
33 dt = cfl * dx *dx/ (2*d)
36 x=[a+0.5*dx + i*dx for i in range(nx)] # array of cell center (1D mesh)
38 ########################## Initial data
40 u_initial = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85) for xi in x];# to be used with a=0, b=1
41 u = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85) for xi in x];# to be used with a=0, b=1
43 max_initial=max(u_initial)
44 min_initial=min(u_initial)
45 total_var_initial = np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)])
52 FFMpegWriter = manimation.writers['ffmpeg']
53 metadata = dict(title="Explicit scheme for heat equation", artist = "CEA Saclay", comment="CFL="+str(cfl)+", Stable if CFL<1")
54 writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
55 with writer.saving(plt.figure(), "HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+".mp4", ntmax):
56 ########################### Postprocessing initialisation
62 plt.ylim( min_initial - 0.1*(max_initial-min_initial), max_initial + 0.1*(max_initial-min_initial) )
63 plt.title("Explicit scheme for the heat equation, CFL="+str(cfl))
64 line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
66 print("Starting time loop")
67 print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
68 np.savetxt( "HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
70 plt.savefig("HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.png")
72 ############################# Time loop
73 while (it < ntmax and time <= tmax):
76 u[i] = un[i] + d * dt / (dx*dx) * (un[(i+1)%nx] -2*un[i] + un[(i-1)%nx])/2
82 assert max(u) <= max_initial
83 assert min(u) >= min_initial
84 assert np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) <= total_var_initial
89 if (it % output_freq == 0):
90 print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
91 np.savetxt( "HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
92 plt.savefig("HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
95 print "Exact solution minimum : ", min(u_initial), "Numerical solution minimum : ", min(u)
96 print "Exact solution maximum : ", max(u_initial), "Numerical solution maximum : ", max(u)
97 print "Exact solution variation : ", np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ", np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)])
98 print "l1 numerical error : ", dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
100 print("Simulation of heat equation with explicit scheme done.")
102 #return min, max, total variation and l1 error
103 return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
106 if __name__ == """__main__""":
107 if len(sys.argv) >2 :
108 nx = int(sys.argv[1])
109 cfl = float(sys.argv[2])
110 HeatEquation1DExplicit(nx,cfl)
112 nx = 50 # number of cells
113 cfl = 1 # c*dt/(2*dx) <= CFL
114 HeatEquation1DExplicit(nx,cfl)