1 #!/usr/bin/env python3
\r
5 Created on Mon Aug 30 2021
\r
6 @author: Michael NDJINGA, Katia Ait Ameur, Coraline Mounier
\r
8 Euler system without source term in one dimension on regular domain [a,b]
\r
9 Riemann problemn with ghost cell boundary condition
\r
10 Left and right: Neumann boundary condition
\r
14 State law Stiffened gaz : p = (gamma - 1) * rho * (e - q) - gamma * p0
\r
15 4 choices of parameters gamma and p0 are available :
\r
16 - Lagrange interpolation (with q=0)
\r
17 - Hermite interpolation with reference point at 575K (with q=0)
\r
18 - Hermite interpolation with reference point at 590K (with q=0)
\r
19 - Hermite interpolation with reference point at 617.94K (saturation at 155 bar) with q=0
\r
21 Linearized enthalpy : h = h_sat + cp * (T - T_sat)
\r
22 Values for cp and T_sat parameters are taken at the reference point chosen for the state law
\r
24 To do correct the computation of the time step : lambda_max (maximum eigenvalue) should be computed first)
\r
31 matplotlib.use("Agg")
\r
32 import matplotlib.pyplot as plt
\r
33 import matplotlib.animation as manimation
\r
35 from math import sqrt, atan, pi
\r
36 from numpy import sign
\r
39 ## Numerical parameter
\r
42 #state law parameter : can be 'Lagrange', 'Hermite590K', 'Hermite617K', or 'FLICA'
\r
43 state_law = "Hermite590K"
\r
45 #indicates with test case is simulated to compare with FLICA5 results
\r
46 #num_test = 0 means there are no FLICA5 results given here
\r
49 #def state_law_parameters(state_law):
\r
50 #state law Stiffened Gaz : p = (gamma - 1) * rho * e - gamma * p0
\r
59 if state_law == "Lagrange":
\r
60 # reference values for Lagrange interpolation
\r
61 p_ref = 155. * 10**5 #Reference pressure in a REP 900 nuclear power plant
\r
62 p1 = 153. * 10**5 # value of pressure at inlet of a 900 MWe PWR vessel
\r
63 rho_ref = 594.38 #density of water at saturation temperature of 617.94K and 155 bars
\r
64 rho1 = 742.36 # value of density at inlet of a 900 MWe PWR vessel (T1 = 565K)
\r
65 e_ref = 1603.8 * 10**3 #internal energy of water at saturation temperature of 617.94K and 155 bars
\r
66 e1 = 1273.6 * 10**3 # value of internal energy at inlet of a 900 MWe PWR vessel
\r
68 gamma = (p1 - p_ref) / (rho1 * e1 - rho_ref *e_ref) + 1.
\r
69 p0 = - 1. / gamma * ( - (gamma - 1) * rho_ref * e_ref + p_ref)
\r
71 c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))
\r
74 h_sat = 1.63 * 10 ** 6 # saturation enthalpy of water at 155 bars
\r
77 elif state_law == "Hermite617K":
\r
78 # reference values for Hermite interpolation
\r
79 p_ref = 155. * 10**5 #Reference pressure in a REP 900 nuclear power plant
\r
80 T_ref = 617.94 #Reference temperature for interpolation at 617.94K
\r
81 rho_ref = 594.38 #density of water at saturation temperature of 617.94K and 155 bars
\r
82 e_ref = 1603.8 * 10**3 #internal energy of water at saturation temperature of 617.94K and 155 bars
\r
83 h_ref = e_ref + p_ref / rho_ref
\r
84 c_ref = 621.43 #sound speed for water at 155 bars and 617.94K
\r
86 gamma = 1. + c_ref * c_ref / (e_ref + p_ref / rho_ref) # From the sound speed formula
\r
87 p0 = 1. / gamma * ( (gamma - 1) * rho_ref * e_ref - p_ref)
\r
89 c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))
\r
91 cp = 8950. # value at 155 bar and 617.94K
\r
92 h_sat = 1.63 * 10 ** 6 # saturation enthalpy of water at 155 bars
\r
95 elif state_law == 'Hermite590K':
\r
96 # reference values for Hermite interpolation
\r
97 p_ref = 155. * 10**5 #Reference pressure in a REP 900 nuclear power plant
\r
98 T_ref = 590. #Reference temperature for interpolation at 590K
\r
99 rho_ref = 688.3 #density of water at 590K and 155 bars
\r
100 e_ref = 1411.4 * 10**3 #internal energy of water at 590K and 155 bars
\r
101 h_ref = e_ref + p_ref / rho_ref
\r
102 c_ref = 866.29 #sound speed for water at 155 bars and 590K
\r
104 gamma = 1. + c_ref * c_ref / (e_ref + p_ref / rho_ref) # From the sound speed formula
\r
105 p0 = 1. / gamma * ( (gamma - 1) * rho_ref * e_ref - p_ref)
\r
107 c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))
\r
109 cp = 5996.8 # value at 155 bar and 590K
\r
110 h_sat = 1433.9 * 10 ** 3 # saturation enthalpy of water at 155 bars
\r
113 elif state_law == 'Hermite575K':
\r
114 # reference values for Hermite interpolation
\r
115 p_ref = 155 * 10**5 #Reference pressure in a REP 900 nuclear power plant
\r
116 T_ref = 575 #Reference temperature at inlet in a REP 900 nuclear power plant
\r
117 #Remaining values determined using iapws python package
\r
118 rho_ref = 722.66 #density of water at 575K and 155 bars
\r
119 e_ref = 1326552.66 #internal energy of water at 575K and 155 bars
\r
120 h_ref = e_ref + p_ref / rho_ref
\r
121 c_ref = 959.28 #sound speed for water at 155 bars and 575K
\r
123 gamma = 1 + c_ref * c_ref / (e_ref + p_ref / rho_ref) # From the sound speed formula
\r
124 p0 = 1 / gamma * ( (gamma - 1) * rho_ref * e_ref - p_ref)
\r
126 c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))#This is actually c_ref
\r
128 cp = 5504.05 # value at 155 bar and 590K
\r
129 h_sat = h_ref # saturation enthalpy of water at 155 bars
\r
132 raise ValueError("Incorrect value for parameter state_law")
\r
135 #initial parameters for Riemann problem (p in Pa, v in m/s, T in K)
\r
136 p_L = 155. * 10**5
\r
143 T_L = (h_L - h_sat ) / cp + T_sat
\r
144 T_R = (h_R - h_sat ) / cp + T_sat
\r
146 def initial_conditions_Riemann_problem(a, b, nx):
\r
147 print("Initial data Riemann problem")
\r
148 dx = (b - a) / nx # space step
\r
149 x = [a + 0.5 * dx + i * dx for i in range(nx)] # array of cell center (1D mesh)
\r
151 p_initial = np.array([ (xi < (a + b) / 2) * p_L + (xi >= (a + b) / 2) * p_R for xi in x])
\r
152 v_initial = np.array([ (xi < (a + b) / 2) * v_L + (xi >= (a + b) / 2) * v_R for xi in x])
\r
153 T_initial = np.array([ (xi < (a + b) / 2) * T_L + (xi >= (a + b) / 2) * T_R for xi in x])
\r
155 rho_initial = p_to_rho_StiffenedGaz(p_initial, T_initial)
\r
156 q_initial = rho_initial * v_initial
\r
157 rho_E_initial = T_to_rhoE_StiffenedGaz(T_initial, rho_initial, q_initial)
\r
159 return rho_initial, q_initial, rho_E_initial, p_initial, v_initial, T_initial
\r
161 def rho_to_p_StiffenedGaz(rho_field, q_field, rho_E_field):
\r
162 p_field = (gamma - 1) * ( rho_E_field - 1. / 2 * q_field ** 2 / rho_field - rho_field * q) - gamma * p0
\r
166 def p_to_rho_StiffenedGaz(p_field, T_field):
\r
167 rho_field = (p_field + p0) * gamma / (gamma - 1) * 1 / (h_sat + cp * (T_field - T_sat) - q)
\r
171 def T_to_rhoE_StiffenedGaz(T_field, rho_field, q_field):
\r
172 rho_E_field = 1 / 2 * (q_field) ** 2 / rho_field + p0 + rho_field / gamma * (h_sat + cp * (T_field- T_sat) + (gamma - 1) * q)
\r
176 def rhoE_to_T_StiffenedGaz(rho_field, q_field, rho_E_field):
\r
177 T_field = T_sat + 1 / cp * (gamma * (rho_E_field / rho_field - 1 / 2 * (q_field / rho_field) ** 2) - gamma * p0 / rho_field - (gamma - 1) * q - h_sat)
\r
180 def dp_drho_e_const_StiffenedGaz( e ):
\r
181 return (gamma-1)*(e-q)
\r
183 def dp_de_rho_const_StiffenedGaz( rho ):
\r
184 return (gamma-1)*rho
\r
186 def sound_speed_StiffenedGaz( h ):
\r
187 return np.sqrt((gamma-1)*(h-q))
\r
189 def rho_h_to_p_StiffenedGaz( rho, h ):
\r
190 return (gamma - 1) * rho * ( h - q ) / gamma - p0
\r
192 def MatRoe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):
\r
193 RoeMat = cdmath.Matrix(3, 3)
\r
197 p_l = rho_to_p_StiffenedGaz(rho_l, q_l, rho_E_l)
\r
198 p_r = rho_to_p_StiffenedGaz(rho_r, q_r, rho_E_r)
\r
199 H_l = rho_E_l / rho_l + p_l / rho_l
\r
200 H_r = rho_E_r / rho_r + p_r / rho_r
\r
203 rho = np.sqrt(rho_l * rho_r)
\r
204 u = (u_l * sqrt(rho_l) + u_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))
\r
205 H = (H_l * sqrt(rho_l) + H_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))
\r
207 p = rho_h_to_p_StiffenedGaz( rho, H - u**2/2. )
\r
208 e = H - p / rho - 1./2 * u**2
\r
209 dp_drho = dp_drho_e_const_StiffenedGaz( e )
\r
210 dp_de = dp_de_rho_const_StiffenedGaz( rho )
\r
215 RoeMat[1, 0] = dp_drho - u ** 2 + dp_de / rho * (u**2/2 - e)
\r
216 RoeMat[1, 1] = 2 * u - u * dp_de / rho
\r
217 RoeMat[1, 2] = dp_de / rho
\r
218 RoeMat[2, 0] = -u * ( -dp_drho + H - dp_de / rho * (u**2/2 - e) )
\r
219 RoeMat[2, 1] = H - dp_de / rho * u ** 2
\r
220 RoeMat[2, 2] = (dp_de / rho +1) * u
\r
225 def Droe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):
\r
226 Droe = cdmath.Matrix(3, 3)
\r
230 p_l = rho_to_p_StiffenedGaz(rho_l, q_l, rho_E_l)
\r
231 p_r = rho_to_p_StiffenedGaz(rho_r, q_r, rho_E_r)
\r
232 H_l = rho_E_l / rho_l + p_l / rho_l
\r
233 H_r = rho_E_r / rho_r + p_r / rho_r
\r
236 rho = np.sqrt(rho_l * rho_r)
\r
237 u = (u_l * sqrt(rho_l) + u_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))
\r
238 H = (H_l * sqrt(rho_l) + H_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))
\r
240 c = sound_speed_StiffenedGaz( H - u**2/2. )
\r
242 lamb = cdmath.Vector(3)
\r
247 r = cdmath.Matrix(3, 3)
\r
253 r[2,1] = H-c**2/(gamma-1)
\r
258 l = cdmath.Matrix(3, 3)
\r
259 l[0,0] = (1./(2*c**2))*(0.5*(gamma-1)*u**2+u*c)
\r
260 l[1,0] = (1./(2*c**2))*(-u*(gamma-1)-c)
\r
261 l[2,0] = (1./(2*c**2))*(gamma-1)
\r
262 l[0,1] = ((gamma-1)/c**2)*(H-u**2)
\r
263 l[1,1] = ((gamma-1)/c**2)*u
\r
264 l[2,1] = -((gamma-1)/c**2)
\r
265 l[0,2] = (1./(2*c**2))*(0.5*(gamma-1)*u**2-u*c)
\r
266 l[1,2] = (1./(2*c**2))*(c-u*(gamma-1))
\r
267 l[2,2] = (1./(2*c**2))*(gamma-1)
\r
269 M1 = cdmath.Matrix(3, 3) #abs(lamb[0])*r[:,0].tensProduct(l[:,0])
\r
270 M2 = cdmath.Matrix(3, 3) #abs(lamb[1])*r[:,1].tensProduct(l[:,1])
\r
271 M3 = cdmath.Matrix(3, 3) #abs(lamb[2])*r[:,2].tensProduct(l[:,2])
\r
274 M1[i,j] = abs(lamb[0])*r[i,0]*l[j,0]
\r
275 M2[i,j] = abs(lamb[1])*r[i,1]*l[j,1]
\r
276 M3[i,j] = abs(lamb[2])*r[i,2]*l[j,2]
\r
283 def jacobianMatricesm(coeff, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):
\r
285 if rho_l < 0 or rho_r < 0:
\r
286 print("rho_l=", rho_l, " rho_r= ", rho_r)
\r
287 raise ValueError("Negative density")
\r
288 if rho_E_l < 0 or rho_E_r < 0:
\r
289 print("rho_E_l=", rho_E_l, " rho_E_r= ", rho_E_r)
\r
290 raise ValueError("Negative total energy")
\r
292 RoeMat = MatRoe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
294 Droe = Droe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
295 return (RoeMat - Droe) * coeff * 0.5
\r
298 def jacobianMatricesp(coeff, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):
\r
299 if rho_l < 0 or rho_r < 0:
\r
300 print("rho_l=", rho_l, " rho_r= ", rho_r)
\r
301 raise ValueError("Negative density")
\r
302 if rho_E_l < 0 or rho_E_r < 0:
\r
303 print("rho_E_l=", rho_E_l, " rho_E_r= ", rho_E_r)
\r
304 raise ValueError("Negative total energy")
\r
306 RoeMat = MatRoe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
307 Droe = Droe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
309 return (RoeMat + Droe) * coeff * 0.5
\r
312 def FillEdges(j, Uk, nbComp, divMat, Rhs, Un, dt, dx, isImplicit):
\r
313 dUi = cdmath.Vector(3)
\r
316 rho_l = Uk[j * nbComp + 0]
\r
317 q_l = Uk[j * nbComp + 1]
\r
318 rho_E_l = Uk[j * nbComp + 2]
\r
319 rho_r = Uk[(j + 1) * nbComp + 0]
\r
320 q_r = Uk[(j + 1) * nbComp + 1]
\r
321 rho_E_r = Uk[(j + 1) * nbComp + 2]
\r
323 Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
324 divMat.addValue(j * nbComp, (j + 1) * nbComp, Am)
\r
325 divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))
\r
327 dUi[0] = Uk[(j + 1) * nbComp + 0] - Uk[j * nbComp + 0]
\r
328 dUi[1] = Uk[(j + 1) * nbComp + 1] - Uk[j * nbComp + 1]
\r
329 dUi[2] = Uk[(j + 1) * nbComp + 2] - Uk[j * nbComp + 2]
\r
333 Rhs[j * nbComp + 0] = -temp[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])
\r
334 Rhs[j * nbComp + 1] = -temp[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])
\r
335 Rhs[j * nbComp + 2] = -temp[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])
\r
337 elif (j == nx - 1):
\r
338 rho_l = Uk[(j - 1) * nbComp + 0]
\r
339 q_l = Uk[(j - 1) * nbComp + 1]
\r
340 rho_E_l = Uk[(j - 1) * nbComp + 2]
\r
341 rho_r = Uk[j * nbComp + 0]
\r
342 q_r = Uk[j * nbComp + 1]
\r
343 rho_E_r = Uk[j * nbComp + 2]
\r
345 Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
346 divMat.addValue(j * nbComp, j * nbComp, Ap)
\r
347 divMat.addValue(j * nbComp, (j - 1) * nbComp, Ap * (-1.))
\r
349 dUi[0] = Uk[(j - 1) * nbComp + 0] - Uk[j * nbComp + 0]
\r
350 dUi[1] = Uk[(j - 1) * nbComp + 1] - Uk[j * nbComp + 1]
\r
351 dUi[2] = Uk[(j - 1) * nbComp + 2] - Uk[j * nbComp + 2]
\r
356 Rhs[j * nbComp + 0] = temp[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])
\r
357 Rhs[j * nbComp + 1] = temp[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])
\r
358 Rhs[j * nbComp + 2] = temp[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])
\r
360 def FillInnerCell(j, Uk, nbComp, divMat, Rhs, Un, dt, dx, isImplicit):
\r
362 rho_l = Uk[(j - 1) * nbComp + 0]
\r
363 q_l = Uk[(j - 1) * nbComp + 1]
\r
364 rho_E_l = Uk[(j - 1) * nbComp + 2]
\r
365 rho_r = Uk[j * nbComp + 0]
\r
366 q_r = Uk[j * nbComp + 1]
\r
367 rho_E_r = Uk[j * nbComp + 2]
\r
368 Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
370 rho_l = Uk[j * nbComp + 0]
\r
371 q_l = Uk[j * nbComp + 1]
\r
372 rho_E_l = Uk[j * nbComp + 2]
\r
373 rho_r = Uk[(j + 1) * nbComp + 0]
\r
374 q_r = Uk[(j + 1) * nbComp + 1]
\r
375 rho_E_r = Uk[(j + 1) * nbComp + 2]
\r
376 Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
378 divMat.addValue(j * nbComp, (j + 1) * nbComp, Am)
\r
379 divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))
\r
380 divMat.addValue(j * nbComp, j * nbComp, Ap)
\r
381 divMat.addValue(j * nbComp, (j - 1) * nbComp, Ap * (-1.))
\r
382 dUi1 = cdmath.Vector(3)
\r
383 dUi2 = cdmath.Vector(3)
\r
384 dUi1[0] = Uk[(j + 1) * nbComp + 0] - Uk[j * nbComp + 0]
\r
385 dUi1[1] = Uk[(j + 1) * nbComp + 1] - Uk[j * nbComp + 1]
\r
386 dUi1[2] = Uk[(j + 1) * nbComp + 2] - Uk[j * nbComp + 2]
\r
388 dUi2[0] = Uk[(j - 1) * nbComp + 0] - Uk[j * nbComp + 0]
\r
389 dUi2[1] = Uk[(j - 1) * nbComp + 1] - Uk[j * nbComp + 1]
\r
390 dUi2[2] = Uk[(j - 1) * nbComp + 2] - Uk[j * nbComp + 2]
\r
395 Rhs[j * nbComp + 0] = -temp1[0] + temp2[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])
\r
396 Rhs[j * nbComp + 1] = -temp1[1] + temp2[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])
\r
397 Rhs[j * nbComp + 2] = -temp1[2] + temp2[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])
\r
399 def SetPicture(rho_field_Roe, q_field_Roe, h_field_Roe, p_field_Roe, v_field_Roe, T_field_Roe, dx):
\r
400 max_initial_rho = max(rho_field_Roe)
\r
401 min_initial_rho = min(rho_field_Roe)
\r
402 max_initial_q = max(q_field_Roe)
\r
403 min_initial_q = min(q_field_Roe)
\r
404 min_initial_h = min(h_field_Roe)
\r
405 max_initial_h = max(h_field_Roe)
\r
406 max_initial_p = max(p_field_Roe)
\r
407 min_initial_p = min(p_field_Roe)
\r
408 max_initial_v = max(v_field_Roe)
\r
409 min_initial_v = min(v_field_Roe)
\r
410 max_initial_T = max(T_field_Roe)
\r
411 min_initial_T = min(T_field_Roe)
\r
413 fig, ([axDensity, axMomentum, axRhoE],[axPressure, axVitesse, axTemperature]) = plt.subplots(2, 3,sharex=True, figsize=(14,10))
\r
414 plt.gcf().subplots_adjust(wspace = 0.5)
\r
416 lineDensity_Roe, = axDensity.plot([a+0.5*dx + i*dx for i in range(nx)], rho_field_Roe, label='Roe')
\r
417 axDensity.set(xlabel='x (m)', ylabel='Densité (kg/m3)')
\r
418 axDensity.set_xlim(a,b)
\r
419 #axDensity.set_ylim(min_initial_rho - 0.1 * (max_initial_rho - min_initial_rho), 700.)
\r
420 axDensity.set_ylim(657, 660.5)
\r
423 lineMomentum_Roe, = axMomentum.plot([a+0.5*dx + i*dx for i in range(nx)], q_field_Roe, label='Roe')
\r
424 axMomentum.set(xlabel='x (m)', ylabel='Momentum (kg/(m2.s))')
\r
425 axMomentum.set_xlim(a,b)
\r
426 #axMomentum.set_ylim(min_initial_q - 0.1*(max_initial_q-min_initial_q), max_initial_q * 2.5)
\r
427 axMomentum.set_ylim(-50, 500)
\r
428 axMomentum.legend()
\r
430 lineRhoE_Roe, = axRhoE.plot([a+0.5*dx + i*dx for i in range(nx)], h_field_Roe, label='Roe')
\r
431 axRhoE.set(xlabel='x (m)', ylabel='h (J/m3)')
\r
432 axRhoE.set_xlim(a,b)
\r
433 #axRhoE.set_ylim(min_initial_h - 0.05*abs(min_initial_h), max_initial_h + 0.5*(max_initial_h-min_initial_h))
\r
434 axRhoE.set_ylim(1.495 * 10**6, 1.5*10**6)
\r
437 linePressure_Roe, = axPressure.plot([a+0.5*dx + i*dx for i in range(nx)], p_field_Roe, label='Roe')
\r
438 axPressure.set(xlabel='x (m)', ylabel='Pression (bar)')
\r
439 axPressure.set_xlim(a,b)
\r
440 #axPressure.set_ylim(min_initial_p - 0.05*abs(min_initial_p), max_initial_p + 0.5*(max_initial_p-min_initial_p))
\r
441 axPressure.set_ylim(149, 156)
\r
442 axPressure.ticklabel_format(axis='y', style='sci', scilimits=(0,0))
\r
443 axPressure.legend()
\r
445 lineVitesse_Roe, = axVitesse.plot([a+0.5*dx + i*dx for i in range(nx)], v_field_Roe, label='Roe')
\r
446 axVitesse.set(xlabel='x (m)', ylabel='Vitesse (m/s)')
\r
447 axVitesse.set_xlim(a,b)
\r
448 #axVitesse.set_ylim(min_initial_v - 0.05*abs(min_initial_v), 15)
\r
449 axVitesse.set_ylim(-0.5, 1)
\r
450 axVitesse.ticklabel_format(axis='y', style='sci', scilimits=(0,0))
\r
453 lineTemperature_Roe, = axTemperature.plot([a+0.5*dx + i*dx for i in range(nx)], T_field_Roe, label='Roe')
\r
454 axTemperature.set(xlabel='x (m)', ylabel='Température (K)')
\r
455 axTemperature.set_xlim(a,b)
\r
456 #axTemperature.set_ylim(min_initial_T - 0.005*abs(min_initial_T), 604)
\r
457 axTemperature.set_ylim(600, 601)
\r
458 axTemperature.ticklabel_format(axis='y', style='sci', scilimits=(0,0))
\r
459 axTemperature.legend()
\r
461 return(fig, lineDensity_Roe, lineMomentum_Roe, lineRhoE_Roe, linePressure_Roe, lineVitesse_Roe, lineTemperature_Roe, lineDensity_Roe, lineMomentum_Roe, lineRhoE_Roe, linePressure_Roe, lineVitesse_Roe, lineTemperature_Roe)
\r
464 def EulerSystemRoe(ntmax, tmax, cfl, a, b, nbCells, output_freq, meshName, state_law):
\r
465 #state_law_parameters(state_law)
\r
471 isStationary = False
\r
478 # iteration vectors
\r
479 Un_Roe = cdmath.Vector(nbCells * (nbComp))
\r
480 dUn_Roe = cdmath.Vector(nbCells * (nbComp))
\r
481 dUk_Roe = cdmath.Vector(nbCells * (nbComp))
\r
482 Rhs_Roe = cdmath.Vector(nbCells * (nbComp))
\r
484 # Initial conditions
\r
485 print("Construction of the initial condition …")
\r
487 rho_field_Roe, q_field_Roe, rho_E_field_Roe, p_field_Roe, v_field_Roe, T_field_Roe = initial_conditions_Riemann_problem(a, b, nx)
\r
488 h_field_Roe = (rho_E_field_Roe + p_field_Roe) / rho_field_Roe - 0.5 * (q_field_Roe / rho_field_Roe) **2
\r
489 p_field_Roe = p_field_Roe * 10 ** (-5)
\r
492 for k in range(nbCells):
\r
493 Un_Roe[k * nbComp + 0] = rho_field_Roe[k]
\r
494 Un_Roe[k * nbComp + 1] = q_field_Roe[k]
\r
495 Un_Roe[k * nbComp + 2] = rho_E_field_Roe[k]
\r
497 divMat_Roe = cdmath.SparseMatrixPetsc(nbCells * nbComp, nbCells * nbComp, (nbVoisinsMax + 1) * nbComp)
\r
500 fig, lineDensity, lineMomentum, lineRhoE, linePressure, lineVitesse, lineTemperature, lineDensity_Roe, lineMomentum_Roe, lineRhoE_Roe, linePressure_Roe, lineVitesse_Roe, lineTemperature_Roe = SetPicture( rho_field_Roe, q_field_Roe, h_field_Roe, p_field_Roe, v_field_Roe, T_field_Roe, dx)
\r
503 FFMpegWriter = manimation.writers['ffmpeg']
\r
504 metadata = dict(title="Roe scheme for the 1D Euler system", artist="CEA Saclay", comment="Shock tube")
\r
505 writer = FFMpegWriter(fps=10, metadata=metadata, codec='h264')
\r
506 with writer.saving(fig, "1DEuler_complet_RP_Roe" + ".mp4", ntmax):
\r
507 writer.grab_frame()
\r
508 plt.savefig("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "0" + ".png")
\r
509 np.savetxt( "EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_rho" + "0" + ".txt", rho_field_Roe, delimiter="\n")
\r
510 np.savetxt( "EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_q" + "0" + ".txt", q_field_Roe, delimiter="\n")
\r
514 print("Starting computation of the non linear Euler non isentropic system with Roe scheme …")
\r
515 # STARTING TIME LOOP
\r
516 while (it < ntmax and time <= tmax and not isStationary):
\r
517 dUn_Roe = Un_Roe.deepCopy()
\r
518 Uk_Roe = Un_Roe.deepCopy()
\r
522 while (k_Roe < newton_max and residu_Roe > precision):
\r
523 # STARTING NEWTON LOOP
\r
524 divMat_Roe.zeroEntries() #sets the matrix coefficients to zero
\r
525 for j in range(nbCells):
\r
527 # traitements des bords
\r
529 FillEdges(j, Uk_Roe, nbComp, divMat_Roe, Rhs_Roe, Un_Roe, dt, dx, isImplicit)
\r
530 elif (j == nbCells - 1):
\r
531 FillEdges(j, Uk_Roe, nbComp, divMat_Roe, Rhs_Roe, Un_Roe, dt, dx, isImplicit)
\r
533 # traitement des cellules internes
\r
535 FillInnerCell(j, Uk_Roe, nbComp, divMat_Roe, Rhs_Roe, Un_Roe, dt, dx, isImplicit)
\r
537 #solving the linear system divMat * dUk = Rhs
\r
540 divMat_Roe.diagonalShift(1.)
\r
541 LS_Roe = cdmath.LinearSolver(divMat_Roe, Rhs_Roe, iterGMRESMax, precision, "GMRES", "LU")
\r
542 dUk_Roe = LS_Roe.solve()
\r
543 residu_Roe = dUk_Roe.norm()
\r
545 dUk_Roe=Rhs_Roe - divMat_Roe*Un_Roe
\r
546 residu_Roe = 0.#Convergence schéma Newton
\r
548 if (isImplicit and (it == 1 or it % output_freq == 0 or it >= ntmax or isStationary or time >= tmax)):
\r
549 print("Residu Newton : ", residu_Roe)
\r
550 print("Linear system converged in ", LS_Roe.getNumberOfIter(), " GMRES iterations")
\r
552 #updates for Newton loop
\r
555 if (isImplicit and not LS_Roe.getStatus()):
\r
556 print("Linear system did not converge ", LS_Roe.getNumberOfIter(), " GMRES iterations")
\r
557 raise ValueError("No convergence of the linear system")
\r
559 if k_Roe == newton_max:
\r
560 raise ValueError("No convergence of Newton Roe Scheme")
\r
563 Un_Roe = Uk_Roe.deepCopy()
\r
565 if (dUn_Roe.norm()<precision):
\r
566 isStationary = True
\r
568 for k in range(nbCells):
\r
569 rho_field_Roe[k] = Un_Roe[k * nbComp + 0]
\r
570 q_field_Roe[k] = Un_Roe[k * nbComp + 1]
\r
571 rho_E_field_Roe[k] = Un_Roe[k * nbComp + 2]
\r
573 v_field_Roe = q_field_Roe / rho_field_Roe
\r
574 p_field_Roe = rho_to_p_StiffenedGaz(rho_field_Roe, q_field_Roe, rho_E_field_Roe)
\r
575 T_field_Roe = rhoE_to_T_StiffenedGaz(rho_field_Roe, q_field_Roe, rho_E_field_Roe)
\r
576 h_field_Roe = (rho_E_field_Roe + p_field_Roe) / rho_field_Roe - 0.5 * (q_field_Roe / rho_field_Roe) **2
\r
577 p_field_Roe = p_field_Roe * 10 ** (-5)
\r
579 if( min(p_field_Roe)<0) :
\r
580 raise ValueError("Negative pressure, stopping calculation")
\r
582 #picture and video updates
\r
583 lineDensity_Roe.set_ydata(rho_field_Roe)
\r
584 lineMomentum_Roe.set_ydata(q_field_Roe)
\r
585 lineRhoE_Roe.set_ydata(h_field_Roe)
\r
586 linePressure_Roe.set_ydata(p_field_Roe)
\r
587 lineVitesse_Roe.set_ydata(v_field_Roe)
\r
588 lineTemperature_Roe.set_ydata(T_field_Roe)
\r
590 writer.grab_frame()
\r
596 if (it == 1 or it % output_freq == 0 or it >= ntmax or isStationary or time >= tmax):
\r
598 print("-- Time step : " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
\r
600 plt.savefig("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + str(it) + '_time' + str(time) + ".png")
\r
602 print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
\r
604 print("Maximum number of time steps ntmax= ", ntmax, " reached")
\r
607 elif (isStationary):
\r
608 print("Stationary regime reached at time step ", it, ", t= ", time)
\r
609 print("------------------------------------------------------------------------------------")
\r
610 np.savetxt("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_rho_Stat.txt", rho_field_Roe, delimiter="\n")
\r
611 np.savetxt("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_q_Stat.txt", q_field_Roe, delimiter="\n")
\r
612 np.savetxt("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_rhoE_Stat.txt", rho_E_field_Roe, delimiter="\n")
\r
613 np.savetxt("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_p_Stat.txt", p_field_Roe, delimiter="\n")
\r
614 plt.savefig("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_Stat.png")
\r
617 print("Maximum time Tmax= ", tmax, " reached")
\r
621 def solve(a, b, nx, meshName, meshType, cfl, state_law):
\r
622 print("Resolution of the Euler System in dimension 1 on " + str(nx) + " cells")
\r
623 print("State Law Stiffened Gaz, " + state_law)
\r
624 print("Initial data : ", "Riemann problem")
\r
625 print("Boundary conditions : ", "Neumann")
\r
626 print("Mesh name : ", meshName, ", ", nx, " cells")
\r
631 EulerSystemRoe(ntmax, tmax, cfl, a, b, nx, output_freq, meshName, state_law)
\r
635 if __name__ == """__main__""":
\r
640 #state_law = "Hermite590K"
\r
641 #state_law_parameters(state_law)
\r
642 solve(a, b, nx, "RegularSquares", "", cfl, state_law)
\r