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 with heating source term (phi) in one dimension on regular domain [a,b]
\r
9 Riemann problemn with ghost cell boundary condition
\r
10 Left : Inlet boundary condition (velocity and temperature imposed)
\r
11 Right : Outlet boundary condition (pressure imposed)
\r
15 State law Stiffened gaz : p = (gamma - 1) * rho * (e - q) - gamma * p0
\r
16 4 choices of parameters gamma and p0 are available :
\r
17 - Lagrange interpolation (with q=0)
\r
18 - Hermite interpolation with reference point at 575K (with q=0)
\r
19 - Hermite interpolation with reference point at 590K (with q=0)
\r
20 - Hermite interpolation with reference point at 617.94K (saturation at 155 bar) with q=0
\r
22 Linearized enthalpy : h = h_sat + cp * (T - T_sat)
\r
23 Values for cp and T_sat parameters are taken at the reference point chosen for the state law
\r
25 To do correct the computation of the time step : lambda_max (maximum eigenvalue) should be computed first)
\r
32 matplotlib.use("Agg")
\r
33 import matplotlib.pyplot as plt
\r
34 import matplotlib.animation as manimation
\r
36 from math import sqrt, atan, pi
\r
37 from numpy import sign
\r
40 #### Initial and boundary condition (T in K, v in m/s, p in Pa)
\r
43 p_outlet = 155.0 * 10**5
\r
45 #initial parameters are determined from boundary conditions
\r
46 p_0 = p_outlet #initial pressure
\r
47 v_0 = v_inlet #initial velocity
\r
48 T_0 = T_inlet #initial temperature
\r
49 ### Heating source term
\r
52 ## Numerical parameter
\r
55 #state law parameter : can be 'Lagrange', 'Hermite590K', 'Hermite617K', or 'FLICA'
\r
56 state_law = "Hermite575K"
\r
58 def state_law_parameters(state_law):
\r
59 #state law Stiffened Gaz : p = (gamma - 1) * rho * e - gamma * p0
\r
68 if state_law == "Lagrange":
\r
69 # reference values for Lagrange interpolation
\r
70 p_ref = 155. * 10**5 #Reference pressure in a REP 900 nuclear power plant
\r
71 p1 = 153. * 10**5 # value of pressure at inlet of a 900 MWe PWR vessel
\r
72 rho_ref = 594.38 #density of water at saturation temperature of 617.94K and 155 bars
\r
73 rho1 = 742.36 # value of density at inlet of a 900 MWe PWR vessel (T1 = 565K)
\r
74 e_ref = 1603.8 * 10**3 #internal energy of water at saturation temperature of 617.94K and 155 bars
\r
75 e1 = 1273.6 * 10**3 # value of internal energy at inlet of a 900 MWe PWR vessel
\r
77 gamma = (p1 - p_ref) / (rho1 * e1 - rho_ref *e_ref) + 1.
\r
78 p0 = - 1. / gamma * ( - (gamma - 1) * rho_ref * e_ref + p_ref)
\r
80 c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))
\r
83 h_sat = 1.63 * 10 ** 6 # saturation enthalpy of water at 155 bars
\r
86 elif state_law == "Hermite617K":
\r
87 # reference values for Hermite interpolation
\r
88 p_ref = 155. * 10**5 #Reference pressure in a REP 900 nuclear power plant
\r
89 T_ref = 617.94 #Reference temperature for interpolation at 617.94K
\r
90 rho_ref = 594.38 #density of water at saturation temperature of 617.94K and 155 bars
\r
91 e_ref = 1603.8 * 10**3 #internal energy of water at saturation temperature of 617.94K and 155 bars
\r
92 h_ref = e_ref + p_ref / rho_ref
\r
93 c_ref = 621.43 #sound speed for water at 155 bars and 617.94K
\r
95 gamma = 1. + c_ref * c_ref / (e_ref + p_ref / rho_ref) # From the sound speed formula
\r
96 p0 = 1. / gamma * ( (gamma - 1) * rho_ref * e_ref - p_ref)
\r
98 c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))
\r
100 cp = 8950. # value at 155 bar and 617.94K
\r
101 h_sat = 1.63 * 10 ** 6 # saturation enthalpy of water at 155 bars
\r
104 elif state_law == 'Hermite590K':
\r
105 # reference values for Hermite interpolation
\r
106 p_ref = 155. * 10**5 #Reference pressure in a REP 900 nuclear power plant
\r
107 T_ref = 590. #Reference temperature for interpolation at 590K
\r
108 rho_ref = 688.3 #density of water at 590K and 155 bars
\r
109 e_ref = 1411.4 * 10**3 #internal energy of water at 590K and 155 bars
\r
110 h_ref = e_ref + p_ref / rho_ref
\r
111 c_ref = 866.29 #sound speed for water at 155 bars and 590K
\r
113 gamma = 1. + c_ref * c_ref / (e_ref + p_ref / rho_ref) # From the sound speed formula
\r
114 p0 = 1. / gamma * ( (gamma - 1) * rho_ref * e_ref - p_ref)
\r
116 c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))
\r
118 cp = 5996.8 # value at 155 bar and 590K
\r
119 h_sat = 1433.9 * 10 ** 3 # saturation enthalpy of water at 155 bars
\r
122 elif state_law == 'Hermite575K':
\r
123 # reference values for Hermite interpolation
\r
124 p_ref = 155 * 10**5 #Reference pressure in a REP 900 nuclear power plant
\r
125 T_ref = 575 #Reference temperature at inlet in a REP 900 nuclear power plant
\r
126 #Remaining values determined using iapws python package
\r
127 rho_ref = 722.66 #density of water at 575K and 155 bars
\r
128 e_ref = 1326552.66 #internal energy of water at 575K and 155 bars
\r
129 h_ref = e_ref + p_ref / rho_ref
\r
130 c_ref = 959.28 #sound speed for water at 155 bars and 575K
\r
132 gamma = 1 + c_ref * c_ref / (e_ref + p_ref / rho_ref) # From the sound speed formula
\r
133 p0 = 1 / gamma * ( (gamma - 1) * rho_ref * e_ref - p_ref)
\r
135 c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))#This is actually c_ref
\r
137 cp = 5504.05 # value at 155 bar and 590K
\r
138 h_sat = h_ref # saturation enthalpy of water at 155 bars
\r
141 raise ValueError("Incorrect value for parameter state_law")
\r
143 def initial_conditions_Riemann_problem(a, b, nx):
\r
144 print("Initial data Riemann problem")
\r
145 dx = (b - a) / nx # space step
\r
146 x = [a + 0.5 * dx + i * dx for i in range(nx)] # array of cell center (1D mesh)
\r
148 p_initial = np.array([ p_0 for xi in x])
\r
149 v_initial = np.array([ v_0 for xi in x])
\r
150 T_initial = np.array([ T_0 for xi in x])
\r
152 rho_initial = p_to_rho_StiffenedGaz(p_initial, T_initial)
\r
153 q_initial = rho_initial * v_initial
\r
154 rho_E_initial = T_to_rhoE_StiffenedGaz(T_initial, rho_initial, q_initial)
\r
156 return rho_initial, q_initial, rho_E_initial, p_initial, v_initial, T_initial
\r
158 def p_to_rho_StiffenedGaz(p_field, T_field):
\r
159 rho_field = (p_field + p0) * gamma / (gamma - 1) * 1. / (h_sat + cp * (T_field - T_sat))
\r
162 def T_to_rhoE_StiffenedGaz(T_field, rho_field, q_field):
\r
163 rho_E_field = 1. / 2. * (q_field) ** 2 / rho_field + p0 + rho_field / gamma * (h_sat + cp * (T_field- T_sat))
\r
166 def rhoE_to_T_StiffenedGaz(rho_field, q_field, rho_E_field):
\r
167 T_field = T_sat + 1 / cp * (gamma * (rho_E_field / rho_field - 1 / 2 * (q_field / rho_field) ** 2) - gamma * p0 / rho_field - h_sat)
\r
170 def rho_to_p_StiffenedGaz(rho_field, q_field, rho_E_field):
\r
171 p_field = (gamma - 1) * (rho_E_field - 1. / 2 * q_field ** 2 / rho_field) - gamma * p0
\r
174 def T_to_E_StiffenedGaz(p_field, T_field, v_field):
\r
175 rho_field = p_to_rho_StiffenedGaz(p_field, T_field)
\r
176 E_field = (p_field + gamma * p0) / ((gamma-1) * rho_field) + 0.5 * v_field **2
\r
179 def dp_drho_e_const_StiffenedGaz( e ):
\r
180 return (gamma-1)*(e-q)
\r
182 def dp_de_rho_const_StiffenedGaz( rho ):
\r
183 return (gamma-1)*rho
\r
185 def sound_speed_StiffenedGaz( h ):
\r
186 return np.sqrt((gamma-1)*(h-q))
\r
188 def rho_h_to_p_StiffenedGaz( rho, h ):
\r
189 return (gamma - 1) * rho * ( h - q ) / gamma - p0
\r
191 def MatRoe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):
\r
192 RoeMat = cdmath.Matrix(3, 3)
\r
196 p_l = rho_to_p_StiffenedGaz(rho_l, q_l, rho_E_l)
\r
197 p_r = rho_to_p_StiffenedGaz(rho_r, q_r, rho_E_r)
\r
198 H_l = rho_E_l / rho_l + p_l / rho_l
\r
199 H_r = rho_E_r / rho_r + p_r / rho_r
\r
202 rho = np.sqrt(rho_l * rho_r)
\r
203 u = (u_l * sqrt(rho_l) + u_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))
\r
204 H = (H_l * sqrt(rho_l) + H_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))
\r
206 p = rho_h_to_p_StiffenedGaz( rho, H - u**2/2. )
\r
207 e = H - p / rho - 1./2 * u**2
\r
208 dp_drho = dp_drho_e_const_StiffenedGaz( e )
\r
209 dp_de = dp_de_rho_const_StiffenedGaz( rho )
\r
214 RoeMat[1, 0] = dp_drho - u ** 2 + dp_de / rho * (u**2/2 - e)
\r
215 RoeMat[1, 1] = 2 * u - u * dp_de / rho
\r
216 RoeMat[1, 2] = dp_de / rho
\r
217 RoeMat[2, 0] = -u * ( -dp_drho + H - dp_de / rho * (u**2/2 - e) )
\r
218 RoeMat[2, 1] = H - dp_de / rho * u ** 2
\r
219 RoeMat[2, 2] = (dp_de / rho +1) * u
\r
224 def Droe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):
\r
225 Droe = cdmath.Matrix(3, 3)
\r
229 p_l = rho_to_p_StiffenedGaz(rho_l, q_l, rho_E_l)
\r
230 p_r = rho_to_p_StiffenedGaz(rho_r, q_r, rho_E_r)
\r
231 H_l = rho_E_l / rho_l + p_l / rho_l
\r
232 H_r = rho_E_r / rho_r + p_r / rho_r
\r
235 rho = np.sqrt(rho_l * rho_r)
\r
236 u = (u_l * sqrt(rho_l) + u_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))
\r
237 H = (H_l * sqrt(rho_l) + H_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))
\r
239 c = sound_speed_StiffenedGaz( H - u**2/2. )
\r
241 lamb = cdmath.Vector(3)
\r
246 r = cdmath.Matrix(3, 3)
\r
252 r[2,1] = H-c**2/(gamma-1)
\r
257 l = cdmath.Matrix(3, 3)
\r
258 l[0,0] = (1./(2*c**2))*(0.5*(gamma-1)*u**2+u*c)
\r
259 l[1,0] = (1./(2*c**2))*(-u*(gamma-1)-c)
\r
260 l[2,0] = (1./(2*c**2))*(gamma-1)
\r
261 l[0,1] = ((gamma-1)/c**2)*(H-u**2)
\r
262 l[1,1] = ((gamma-1)/c**2)*u
\r
263 l[2,1] = -((gamma-1)/c**2)
\r
264 l[0,2] = (1./(2*c**2))*(0.5*(gamma-1)*u**2-u*c)
\r
265 l[1,2] = (1./(2*c**2))*(c-u*(gamma-1))
\r
266 l[2,2] = (1./(2*c**2))*(gamma-1)
\r
268 M1 = cdmath.Matrix(3, 3) #abs(lamb[0])*r[:,0].tensProduct(l[:,0])
\r
269 M2 = cdmath.Matrix(3, 3) #abs(lamb[1])*r[:,1].tensProduct(l[:,1])
\r
270 M3 = cdmath.Matrix(3, 3) #abs(lamb[2])*r[:,2].tensProduct(l[:,2])
\r
273 M1[i,j] = abs(lamb[0])*r[i,0]*l[j,0]
\r
274 M2[i,j] = abs(lamb[1])*r[i,1]*l[j,1]
\r
275 M3[i,j] = abs(lamb[2])*r[i,2]*l[j,2]
\r
282 def jacobianMatricesm(coeff, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):
\r
284 if rho_l < 0 or rho_r < 0:
\r
285 print("rho_l=", rho_l, " rho_r= ", rho_r)
\r
286 raise ValueError("Negative density")
\r
287 if rho_E_l < 0 or rho_E_r < 0:
\r
288 print("rho_E_l=", rho_E_l, " rho_E_r= ", rho_E_r)
\r
289 raise ValueError("Negative total energy")
\r
291 RoeMat = MatRoe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
293 Droe = Droe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
294 return (RoeMat - Droe) * coeff * 0.5
\r
297 def jacobianMatricesp(coeff, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):
\r
298 if rho_l < 0 or rho_r < 0:
\r
299 print("rho_l=", rho_l, " rho_r= ", rho_r)
\r
300 raise ValueError("Negative density")
\r
301 if rho_E_l < 0 or rho_E_r < 0:
\r
302 print("rho_E_l=", rho_E_l, " rho_E_r= ", rho_E_r)
\r
303 raise ValueError("Negative total energy")
\r
305 RoeMat = MatRoe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
306 Droe = Droe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
308 return (RoeMat + Droe) * coeff * 0.5
\r
311 def FillEdges(j, Uk, nbComp, divMat, Rhs, Un, dt, dx, isImplicit):
\r
312 dUi1 = cdmath.Vector(3)
\r
313 dUi2 = cdmath.Vector(3)
\r
314 temp1 = cdmath.Vector(3)
\r
315 temp2 = cdmath.Vector(3)
\r
318 rho_l = Uk[j * nbComp + 0]
\r
319 q_l = Uk[j * nbComp + 1]
\r
320 rho_E_l = Uk[j * nbComp + 2]
\r
321 rho_r = Uk[(j + 1) * nbComp + 0]
\r
322 q_r = Uk[(j + 1) * nbComp + 1]
\r
323 rho_E_r = Uk[(j + 1) * nbComp + 2]
\r
325 Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
326 divMat.addValue(j * nbComp, (j + 1) * nbComp, Am)
\r
327 divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))
\r
329 p_inlet = rho_to_p_StiffenedGaz(Uk[j * nbComp + 0], Uk[j * nbComp + 1], Uk[j * nbComp + 2])# We take p from inside the domain
\r
330 rho_l=p_to_rho_StiffenedGaz(p_inlet, T_inlet) # rho is computed from the temperature BC and the inner pressure
\r
331 #rho_l = Uk[j * nbComp + 0] # We take rho from inside the domain
\r
332 q_l = rho_l * v_inlet # q is imposed by the boundary condition v_inlet
\r
333 rho_E_l = T_to_rhoE_StiffenedGaz(T_inlet, rho_l, q_l) #rhoE is obtained using the two boundary conditions v_inlet and e_inlet
\r
334 rho_r = Uk[j * nbComp + 0]
\r
335 q_r = Uk[j * nbComp + 1]
\r
336 rho_E_r = Uk[j * nbComp + 2]
\r
338 Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
339 divMat.addValue(j * nbComp, j * nbComp, Ap)
\r
342 dUi1[0] = Uk[(j + 1) * nbComp + 0] - Uk[j * nbComp + 0]
\r
343 dUi1[1] = Uk[(j + 1) * nbComp + 1] - Uk[j * nbComp + 1]
\r
344 dUi1[2] = Uk[(j + 1) * nbComp + 2] - Uk[j * nbComp + 2]
\r
347 dUi2[0] = rho_l - Uk[(j ) * nbComp + 0]
\r
348 dUi2[1] = q_l - Uk[(j ) * nbComp + 1]
\r
349 dUi2[2] = rho_E_l - Uk[(j ) * nbComp + 2]
\r
357 elif (j == nx - 1):
\r
358 rho_l = Uk[(j - 1) * nbComp + 0]
\r
359 q_l = Uk[(j - 1) * nbComp + 1]
\r
360 rho_E_l = Uk[(j - 1) * nbComp + 2]
\r
361 rho_r = Uk[j * nbComp + 0]
\r
362 q_r = Uk[j * nbComp + 1]
\r
363 rho_E_r = Uk[j * nbComp + 2]
\r
365 Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
366 divMat.addValue(j * nbComp, j * nbComp, Ap)
\r
367 divMat.addValue(j * nbComp, (j - 1) * nbComp, Ap * (-1.))
\r
369 rho_l = Uk[j * nbComp + 0]
\r
370 q_l = Uk[j * nbComp + 1]
\r
371 rho_E_l = Uk[j * nbComp + 2]
\r
372 rho_r = Uk[(j ) * nbComp + 0] # We take rho inside the domain
\r
373 q_r = Uk[(j ) * nbComp + 1] # We take q from inside the domain
\r
374 rho_E_r = (p_outlet+gamma*p0)/(gamma-1) + 0.5*q_r**2/rho_r # rhoE is obtained using the boundary condition p_outlet
\r
376 Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
377 divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))
\r
380 dUi1[0] = rho_r - Uk[j * nbComp + 0]
\r
381 dUi1[1] = q_r - Uk[j * nbComp + 1]
\r
382 dUi1[2] = rho_E_r - Uk[j * nbComp + 2]
\r
385 dUi2[0] = Uk[(j - 1) * nbComp + 0] - Uk[j * nbComp + 0]
\r
386 dUi2[1] = Uk[(j - 1) * nbComp + 1] - Uk[j * nbComp + 1]
\r
387 dUi2[2] = Uk[(j - 1) * nbComp + 2] - Uk[j * nbComp + 2]
\r
395 if(isImplicit):#implicit scheme, contribution from the Newton scheme residual
\r
396 Rhs[j * nbComp + 0] = -temp1[0] + temp2[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])
\r
397 Rhs[j * nbComp + 1] = -temp1[1] + temp2[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])
\r
398 Rhs[j * nbComp + 2] = -temp1[2] + temp2[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])
\r
399 else:#explicit scheme, contribution from the boundary data the right hand side
\r
400 Rhs[j * nbComp + 0] = -temp1[0] + temp2[0]
\r
401 Rhs[j * nbComp + 1] = -temp1[1] + temp2[1]
\r
402 Rhs[j * nbComp + 2] = -temp1[2] + temp2[2]
\r
404 def FillInnerCell(j, Uk, nbComp, divMat, Rhs, Un, dt, dx, isImplicit):
\r
406 rho_l = Uk[(j - 1) * nbComp + 0]
\r
407 q_l = Uk[(j - 1) * nbComp + 1]
\r
408 rho_E_l = Uk[(j - 1) * nbComp + 2]
\r
409 rho_r = Uk[j * nbComp + 0]
\r
410 q_r = Uk[j * nbComp + 1]
\r
411 rho_E_r = Uk[j * nbComp + 2]
\r
412 Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
414 rho_l = Uk[j * nbComp + 0]
\r
415 q_l = Uk[j * nbComp + 1]
\r
416 rho_E_l = Uk[j * nbComp + 2]
\r
417 rho_r = Uk[(j + 1) * nbComp + 0]
\r
418 q_r = Uk[(j + 1) * nbComp + 1]
\r
419 rho_E_r = Uk[(j + 1) * nbComp + 2]
\r
420 Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
422 divMat.addValue(j * nbComp, (j + 1) * nbComp, Am)
\r
423 divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))
\r
424 divMat.addValue(j * nbComp, j * nbComp, Ap)
\r
425 divMat.addValue(j * nbComp, (j - 1) * nbComp, Ap * (-1.))
\r
428 dUi1 = cdmath.Vector(3)
\r
429 dUi2 = cdmath.Vector(3)
\r
431 dUi1[0] = Uk[(j + 1) * nbComp + 0] - Uk[j * nbComp + 0]
\r
432 dUi1[1] = Uk[(j + 1) * nbComp + 1] - Uk[j * nbComp + 1]
\r
433 dUi1[2] = Uk[(j + 1) * nbComp + 2] - Uk[j * nbComp + 2]
\r
435 dUi2[0] = Uk[(j - 1) * nbComp + 0] - Uk[j * nbComp + 0]
\r
436 dUi2[1] = Uk[(j - 1) * nbComp + 1] - Uk[j * nbComp + 1]
\r
437 dUi2[2] = Uk[(j - 1) * nbComp + 2] - Uk[j * nbComp + 2]
\r
442 Rhs[j * nbComp + 0] = -temp1[0] + temp2[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])
\r
443 Rhs[j * nbComp + 1] = -temp1[1] + temp2[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])
\r
444 Rhs[j * nbComp + 2] = -temp1[2] + temp2[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])
\r
446 Rhs[j * nbComp + 0] = 0
\r
447 Rhs[j * nbComp + 1] = 0
\r
448 Rhs[j * nbComp + 2] = 0
\r
450 def SetPicture(rho_field_Roe, q_field_Roe, h_field_Roe, p_field_Roe, v_field_Roe, T_field_Roe, dx):
\r
451 max_initial_rho = max(rho_field_Roe)
\r
452 min_initial_rho = min(rho_field_Roe)
\r
453 max_initial_q = max(q_field_Roe)
\r
454 min_initial_q = min(q_field_Roe)
\r
455 min_initial_h = min(h_field_Roe)
\r
456 max_initial_h = max(h_field_Roe)
\r
457 max_initial_p = max(p_field_Roe)
\r
458 min_initial_p = min(p_field_Roe)
\r
459 max_initial_v = max(v_field_Roe)
\r
460 min_initial_v = min(v_field_Roe)
\r
461 max_initial_T = max(T_field_Roe)
\r
462 min_initial_T = min(T_field_Roe)
\r
464 fig, ([axDensity, axMomentum, axh],[axPressure, axVitesse, axTemperature]) = plt.subplots(2, 3,sharex=True, figsize=(14,10))
\r
465 plt.gcf().subplots_adjust(wspace = 0.5)
\r
467 lineDensity_Roe, = axDensity.plot([a+0.5*dx + i*dx for i in range(nx)], rho_field_Roe, label='Roe')
\r
468 axDensity.set(xlabel='x (m)', ylabel='Densité (kg/m3)')
\r
469 axDensity.set_xlim(a,b)
\r
470 axDensity.set_ylim(680, 800)
\r
473 lineMomentum_Roe, = axMomentum.plot([a+0.5*dx + i*dx for i in range(nx)], q_field_Roe, label='Roe')
\r
474 axMomentum.set(xlabel='x (m)', ylabel='Momentum (kg/(m2.s))')
\r
475 axMomentum.set_xlim(a,b)
\r
476 axMomentum.set_ylim(3500, 4000)
\r
477 axMomentum.legend()
\r
479 lineh_Roe, = axh.plot([a+0.5*dx + i*dx for i in range(nx)], h_field_Roe, label='Roe')
\r
480 axh.set(xlabel='x (m)', ylabel='h (J/m3)')
\r
482 axh.set_ylim(1.2 * 10**6, 1.5*10**6)
\r
485 linePressure_Roe, = axPressure.plot([a+0.5*dx + i*dx for i in range(nx)], p_field_Roe, label='Roe')
\r
486 axPressure.set(xlabel='x (m)', ylabel='Pression (bar)')
\r
487 axPressure.set_xlim(a,b)
\r
488 axPressure.set_ylim(155, 155.5)
\r
489 axPressure.ticklabel_format(axis='y', style='sci', scilimits=(0,0))
\r
490 axPressure.legend()
\r
492 lineVitesse_Roe, = axVitesse.plot([a+0.5*dx + i*dx for i in range(nx)], v_field_Roe, label='Roe')
\r
493 axVitesse.set(xlabel='x (m)', ylabel='Vitesse (m/s)')
\r
494 axVitesse.set_xlim(a,b)
\r
495 axVitesse.set_ylim(v_0-1, v_0+1)
\r
496 axVitesse.ticklabel_format(axis='y', style='sci', scilimits=(0,0))
\r
499 lineTemperature_Roe, = axTemperature.plot([a+0.5*dx + i*dx for i in range(nx)], T_field_Roe, label='Roe')
\r
500 axTemperature.set(xlabel='x (m)', ylabel='Température (K)')
\r
501 axTemperature.set_xlim(a,b)
\r
502 axTemperature.set_ylim(T_0-10, T_0+30)
\r
503 axTemperature.ticklabel_format(axis='y', style='sci', scilimits=(0,0))
\r
504 axTemperature.legend()
\r
506 return(fig, lineDensity_Roe, lineMomentum_Roe, lineh_Roe, linePressure_Roe, lineVitesse_Roe, lineTemperature_Roe)
\r
509 def EulerSystemRoe(ntmax, tmax, cfl, a, b, nbCells, output_freq, meshName, state_law, isImplicit):
\r
510 state_law_parameters(state_law)
\r
516 isStationary = False
\r
522 # iteration vectors
\r
523 Un_Roe = cdmath.Vector(nbCells * (nbComp))
\r
524 dUn_Roe = cdmath.Vector(nbCells * (nbComp))
\r
525 dUk_Roe = cdmath.Vector(nbCells * (nbComp))
\r
526 Rhs_Roe = cdmath.Vector(nbCells * (nbComp))
\r
528 # Initial conditions
\r
529 print("Construction of the initial condition …")
\r
531 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
532 h_field_Roe = (rho_E_field_Roe + p_field_Roe) / rho_field_Roe - 0.5 * (q_field_Roe / rho_field_Roe) **2
\r
533 p_field_Roe = p_field_Roe * 10 ** (-5)
\r
536 for k in range(nbCells):
\r
537 Un_Roe[k * nbComp + 0] = rho_field_Roe[k]
\r
538 Un_Roe[k * nbComp + 1] = q_field_Roe[k]
\r
539 Un_Roe[k * nbComp + 2] = rho_E_field_Roe[k]
\r
541 divMat_Roe = cdmath.SparseMatrixPetsc(nbCells * nbComp, nbCells * nbComp, (nbVoisinsMax + 1) * nbComp)
\r
544 fig, 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
546 plt.savefig("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "0" + ".png")
\r
550 print("Starting computation of the non linear Euler non isentropic system with Roe scheme …")
\r
551 # STARTING TIME LOOP
\r
552 while (it < ntmax and time <= tmax and not isStationary):
\r
553 dUn_Roe = Un_Roe.deepCopy()
\r
554 Uk_Roe = Un_Roe.deepCopy()
\r
558 while (k_Roe < newton_max and residu_Roe > precision):
\r
559 # STARTING NEWTON LOOP
\r
560 divMat_Roe.zeroEntries() #sets the matrix coefficients to zero
\r
561 for j in range(nbCells):
\r
563 # traitements des bords
\r
565 FillEdges(j, Uk_Roe, nbComp, divMat_Roe, Rhs_Roe, Un_Roe, dt, dx, isImplicit)
\r
566 elif (j == nbCells - 1):
\r
567 FillEdges(j, Uk_Roe, nbComp, divMat_Roe, Rhs_Roe, Un_Roe, dt, dx, isImplicit)
\r
569 # traitement des cellules internes
\r
571 FillInnerCell(j, Uk_Roe, nbComp, divMat_Roe, Rhs_Roe, Un_Roe, dt, dx, isImplicit)
\r
573 Rhs_Roe[j * nbComp + 2] += phi*dt
\r
576 #solving the linear system divMat * dUk = Rhs
\r
577 divMat_Roe.diagonalShift(1.)
\r
578 LS_Roe = cdmath.LinearSolver(divMat_Roe, Rhs_Roe, iterGMRESMax, precision, "GMRES", "LU")
\r
579 dUk_Roe = LS_Roe.solve()
\r
580 vector_residu_Roe = dUk_Roe.maxVector(nbComp)
\r
581 residu_Roe = max(abs(vector_residu_Roe[0])/rho0, abs(vector_residu_Roe[1])/(rho0*v_0), abs(vector_residu_Roe[2])/rhoE0 )
\r
583 dUk_Roe=Rhs_Roe - divMat_Roe*Un_Roe
\r
584 residu_Roe = 0.#Convergence schéma Newton
\r
586 if (isImplicit and (it == 1 or it % output_freq == 0 or it >= ntmax or isStationary or time >= tmax)):
\r
587 print("Residu Newton at iteration ",k_Roe, " : ", residu_Roe)
\r
588 print("Linear system converged in ", LS_Roe.getNumberOfIter(), " GMRES iterations")
\r
590 #updates for Newton loop
\r
593 if (isImplicit and not LS_Roe.getStatus()):
\r
594 print("Linear system did not converge ", LS_Roe.getNumberOfIter(), " GMRES iterations")
\r
595 raise ValueError("No convergence of the linear system")
\r
597 if k_Roe == newton_max:
\r
598 raise ValueError("No convergence of Newton Roe Scheme")
\r
601 Un_Roe = Uk_Roe.deepCopy()
\r
604 #Testing stationarity
\r
605 residu_stat = dUn_Roe.maxVector(nbComp)#On prend le max de chaque composante
\r
606 if (it % output_freq == 0 ):
\r
607 print("Test de stationarité : Un+1-Un= ", max(abs(residu_stat[0])/rho0, abs(residu_stat[1])/(rho0*v_0), abs(residu_stat[2])/rhoE0 ))
\r
609 if ( it>1 and abs(residu_stat[0])/rho0<precision and abs(residu_stat[1])/(rho0*v_0)<precision and abs(residu_stat[2])/rhoE0<precision):
\r
610 isStationary = True
\r
612 for k in range(nbCells):
\r
613 rho_field_Roe[k] = Un_Roe[k * nbComp + 0]
\r
614 q_field_Roe[k] = Un_Roe[k * nbComp + 1]
\r
615 rho_E_field_Roe[k] = Un_Roe[k * nbComp + 2]
\r
617 v_field_Roe = q_field_Roe / rho_field_Roe
\r
618 p_field_Roe = rho_to_p_StiffenedGaz(rho_field_Roe, q_field_Roe, rho_E_field_Roe)
\r
619 T_field_Roe = rhoE_to_T_StiffenedGaz(rho_field_Roe, q_field_Roe, rho_E_field_Roe)
\r
620 h_field_Roe = (rho_E_field_Roe + p_field_Roe) / rho_field_Roe - 0.5 * (q_field_Roe / rho_field_Roe) **2
\r
621 p_field_Roe = p_field_Roe * 10 ** (-5)
\r
623 if( min(p_field_Roe)<0) :
\r
624 raise ValueError("Negative pressure, stopping calculation")
\r
626 #picture and video updates
\r
627 lineDensity_Roe.set_ydata(rho_field_Roe)
\r
628 lineMomentum_Roe.set_ydata(q_field_Roe)
\r
629 lineRhoE_Roe.set_ydata(h_field_Roe)
\r
630 linePressure_Roe.set_ydata(p_field_Roe)
\r
631 lineVitesse_Roe.set_ydata(v_field_Roe)
\r
632 lineTemperature_Roe.set_ydata(T_field_Roe)
\r
638 if (it == 1 or it % output_freq == 0 or it >= ntmax or isStationary or time >= tmax):
\r
640 print("-- Time step : " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
\r
642 print("Temperature gain between inlet and outlet is ", T_field_Roe[nbCells-1]-T_field_Roe[0],"\n")
\r
644 plt.savefig("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "Implicit"+str(isImplicit)+ str(it) + '_time' + str(time) + ".png")
\r
646 print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt)+"\n")
\r
649 print("Maximum number of time steps ntmax= ", ntmax, " reached")
\r
652 elif (isStationary):
\r
653 print("Stationary regime reached at time step ", it, ", t= ", time)
\r
654 print("------------------------------------------------------------------------------------")
\r
655 np.savetxt("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "_rho_Stat.txt", rho_field_Roe, delimiter="\n")
\r
656 np.savetxt("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "_q_Stat.txt", q_field_Roe, delimiter="\n")
\r
657 np.savetxt("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "_rhoE_Stat.txt", rho_E_field_Roe, delimiter="\n")
\r
658 np.savetxt("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "_p_Stat.txt", p_field_Roe, delimiter="\n")
\r
659 plt.savefig("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "Implicit"+str(isImplicit)+"_Stat.png")
\r
662 print("Maximum time Tmax= ", tmax, " reached")
\r
666 def solve(a, b, nx, meshName, meshType, cfl, state_law, isImplicit):
\r
667 print("Simulation of a heated channel in dimension 1 on " + str(nx) + " cells")
\r
668 print("State Law Stiffened Gaz, " + state_law)
\r
669 print("Initial data : ", "constant fields")
\r
670 print("Boundary conditions : ", "Inlet (Left), Outlet (Right)")
\r
671 print("Mesh name : ", meshName, ", ", nx, " cells")
\r
676 EulerSystemRoe(ntmax, tmax, cfl, a, b, nx, output_freq, meshName, state_law, isImplicit)
\r
679 def FillMatrixFromEdges(j, Uk, nbComp, divMat, dt, dx):
\r
682 rho_l = Uk[j * nbComp + 0]
\r
683 q_l = Uk[j * nbComp + 1]
\r
684 rho_E_l = Uk[j * nbComp + 2]
\r
685 rho_r = Uk[(j + 1) * nbComp + 0]
\r
686 q_r = Uk[(j + 1) * nbComp + 1]
\r
687 rho_E_r = Uk[(j + 1) * nbComp + 2]
\r
689 Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
690 divMat.addValue(j * nbComp, (j + 1) * nbComp, Am)
\r
691 divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))
\r
693 p_inlet = rho_to_p_StiffenedGaz(Uk[j * nbComp + 0], Uk[j * nbComp + 1], Uk[j * nbComp + 2])# We take p from inside the domain
\r
694 rho_l=p_to_rho_StiffenedGaz(p_inlet, T_inlet) # rho is computed from the temperature BC and the inner pressure
\r
695 #rho_l = Uk[j * nbComp + 0] # We take rho from inside the domain
\r
696 q_l = rho_l * v_inlet # q is imposed by the boundary condition v_inlet
\r
697 rho_E_l = T_to_rhoE_StiffenedGaz(T_inlet, rho_l, q_l) #rhoE is obtained using the two boundary conditions v_inlet and e_inlet
\r
698 rho_r = Uk[j * nbComp + 0]
\r
699 q_r = Uk[j * nbComp + 1]
\r
700 rho_E_r = Uk[j * nbComp + 2]
\r
702 Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
703 divMat.addValue(j * nbComp, j * nbComp, Ap)
\r
705 elif (j == nx - 1):
\r
706 rho_l = Uk[j * nbComp + 0]
\r
707 q_l = Uk[j * nbComp + 1]
\r
708 rho_E_l = Uk[j * nbComp + 2]
\r
709 rho_r = Uk[(j ) * nbComp + 0] # We take rho inside the domain
\r
710 q_r = Uk[(j ) * nbComp + 1] # We take q from inside the domain
\r
711 rho_E_r = (p_outlet+gamma*p0)/(gamma-1) + 0.5*q_r**2/rho_r # rhoE is obtained using the boundary condition p_outlet
\r
713 Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
714 divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))
\r
716 rho_l = Uk[(j - 1) * nbComp + 0]
\r
717 q_l = Uk[(j - 1) * nbComp + 1]
\r
718 rho_E_l = Uk[(j - 1) * nbComp + 2]
\r
719 rho_r = Uk[j * nbComp + 0]
\r
720 q_r = Uk[j * nbComp + 1]
\r
721 rho_E_r = Uk[j * nbComp + 2]
\r
723 Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
724 divMat.addValue(j * nbComp, j * nbComp, Ap)
\r
725 divMat.addValue(j * nbComp, (j - 1) * nbComp, Ap * (-1.))
\r
728 def FillMatrixFromInnerCell(j, Uk, nbComp, divMat, dt, dx):
\r
730 rho_l = Uk[(j - 1) * nbComp + 0]
\r
731 q_l = Uk[(j - 1) * nbComp + 1]
\r
732 rho_E_l = Uk[(j - 1) * nbComp + 2]
\r
733 rho_r = Uk[j * nbComp + 0]
\r
734 q_r = Uk[j * nbComp + 1]
\r
735 rho_E_r = Uk[j * nbComp + 2]
\r
736 Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
738 rho_l = Uk[j * nbComp + 0]
\r
739 q_l = Uk[j * nbComp + 1]
\r
740 rho_E_l = Uk[j * nbComp + 2]
\r
741 rho_r = Uk[(j + 1) * nbComp + 0]
\r
742 q_r = Uk[(j + 1) * nbComp + 1]
\r
743 rho_E_r = Uk[(j + 1) * nbComp + 2]
\r
744 Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
746 divMat.addValue(j * nbComp, (j + 1) * nbComp, Am)
\r
747 divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))
\r
748 divMat.addValue(j * nbComp, j * nbComp, Ap)
\r
749 divMat.addValue(j * nbComp, (j - 1) * nbComp, Ap * (-1.))
\r
751 def FillRHSFromEdges(j, Uk, nbComp, Rhs, Un, dt, dx, isImplicit):
\r
752 dUi1 = cdmath.Vector(3)
\r
753 dUi2 = cdmath.Vector(3)
\r
754 temp1 = cdmath.Vector(3)
\r
755 temp2 = cdmath.Vector(3)
\r
758 rho_l = Uk[j * nbComp + 0]
\r
759 q_l = Uk[j * nbComp + 1]
\r
760 rho_E_l = Uk[j * nbComp + 2]
\r
761 rho_r = Uk[(j + 1) * nbComp + 0]
\r
762 q_r = Uk[(j + 1) * nbComp + 1]
\r
763 rho_E_r = Uk[(j + 1) * nbComp + 2]
\r
765 Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
767 p_inlet = rho_to_p_StiffenedGaz(Uk[j * nbComp + 0], Uk[j * nbComp + 1], Uk[j * nbComp + 2])# We take p from inside the domain
\r
768 rho_l=p_to_rho_StiffenedGaz(p_inlet, T_inlet) # rho is computed from the temperature BC and the inner pressure
\r
769 #rho_l = Uk[j * nbComp + 0] # We take rho from inside the domain
\r
770 q_l = rho_l * v_inlet # q is imposed by the boundary condition v_inlet
\r
771 rho_E_l = T_to_rhoE_StiffenedGaz(T_inlet, rho_l, q_l) #rhoE is obtained using the two boundary conditions v_inlet and e_inlet
\r
772 rho_r = Uk[j * nbComp + 0]
\r
773 q_r = Uk[j * nbComp + 1]
\r
774 rho_E_r = Uk[j * nbComp + 2]
\r
776 Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
779 dUi1[0] = Uk[(j + 1) * nbComp + 0] - Uk[j * nbComp + 0]
\r
780 dUi1[1] = Uk[(j + 1) * nbComp + 1] - Uk[j * nbComp + 1]
\r
781 dUi1[2] = Uk[(j + 1) * nbComp + 2] - Uk[j * nbComp + 2]
\r
784 dUi2[0] = rho_l - Uk[(j ) * nbComp + 0]
\r
785 dUi2[1] = q_l - Uk[(j ) * nbComp + 1]
\r
786 dUi2[2] = rho_E_l - Uk[(j ) * nbComp + 2]
\r
794 elif (j == nx - 1):
\r
795 rho_l = Uk[(j - 1) * nbComp + 0]
\r
796 q_l = Uk[(j - 1) * nbComp + 1]
\r
797 rho_E_l = Uk[(j - 1) * nbComp + 2]
\r
798 rho_r = Uk[j * nbComp + 0]
\r
799 q_r = Uk[j * nbComp + 1]
\r
800 rho_E_r = Uk[j * nbComp + 2]
\r
802 Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
804 rho_l = Uk[j * nbComp + 0]
\r
805 q_l = Uk[j * nbComp + 1]
\r
806 rho_E_l = Uk[j * nbComp + 2]
\r
807 rho_r = Uk[(j ) * nbComp + 0] # We take rho inside the domain
\r
808 q_r = Uk[(j ) * nbComp + 1] # We take q from inside the domain
\r
809 rho_E_r = (p_outlet+gamma*p0)/(gamma-1) + 0.5*q_r**2/rho_r # rhoE is obtained using the boundary condition p_outlet
\r
811 Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
814 dUi1[0] = rho_r - Uk[j * nbComp + 0]
\r
815 dUi1[1] = q_r - Uk[j * nbComp + 1]
\r
816 dUi1[2] = rho_E_r - Uk[j * nbComp + 2]
\r
819 dUi2[0] = Uk[(j - 1) * nbComp + 0] - Uk[j * nbComp + 0]
\r
820 dUi2[1] = Uk[(j - 1) * nbComp + 1] - Uk[j * nbComp + 1]
\r
821 dUi2[2] = Uk[(j - 1) * nbComp + 2] - Uk[j * nbComp + 2]
\r
830 Rhs[j * nbComp + 0] = -temp1[0] + temp2[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])
\r
831 Rhs[j * nbComp + 1] = -temp1[1] + temp2[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])
\r
832 Rhs[j * nbComp + 2] = -temp1[2] + temp2[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])
\r
833 else:#explicit scheme, contribution from the boundary data the right hand side
\r
834 Rhs[j * nbComp + 0] = -temp1[0] + temp2[0]
\r
835 Rhs[j * nbComp + 1] = -temp1[1] + temp2[1]
\r
836 Rhs[j * nbComp + 2] = -temp1[2] + temp2[2]
\r
838 def FillRHSFromInnerCell(j, Uk, nbComp, Rhs, Un, dt, dx, isImplicit):
\r
840 rho_l = Uk[(j - 1) * nbComp + 0]
\r
841 q_l = Uk[(j - 1) * nbComp + 1]
\r
842 rho_E_l = Uk[(j - 1) * nbComp + 2]
\r
843 rho_r = Uk[j * nbComp + 0]
\r
844 q_r = Uk[j * nbComp + 1]
\r
845 rho_E_r = Uk[j * nbComp + 2]
\r
846 Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
848 rho_l = Uk[j * nbComp + 0]
\r
849 q_l = Uk[j * nbComp + 1]
\r
850 rho_E_l = Uk[j * nbComp + 2]
\r
851 rho_r = Uk[(j + 1) * nbComp + 0]
\r
852 q_r = Uk[(j + 1) * nbComp + 1]
\r
853 rho_E_r = Uk[(j + 1) * nbComp + 2]
\r
854 Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)
\r
856 if(isImplicit):#Contribution to the right hand side if te scheme is implicit
\r
857 dUi1 = cdmath.Vector(3)
\r
858 dUi2 = cdmath.Vector(3)
\r
860 dUi1[0] = Uk[(j + 1) * nbComp + 0] - Uk[j * nbComp + 0]
\r
861 dUi1[1] = Uk[(j + 1) * nbComp + 1] - Uk[j * nbComp + 1]
\r
862 dUi1[2] = Uk[(j + 1) * nbComp + 2] - Uk[j * nbComp + 2]
\r
864 dUi2[0] = Uk[(j - 1) * nbComp + 0] - Uk[j * nbComp + 0]
\r
865 dUi2[1] = Uk[(j - 1) * nbComp + 1] - Uk[j * nbComp + 1]
\r
866 dUi2[2] = Uk[(j - 1) * nbComp + 2] - Uk[j * nbComp + 2]
\r
871 Rhs[j * nbComp + 0] = -temp1[0] + temp2[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])
\r
872 Rhs[j * nbComp + 1] = -temp1[1] + temp2[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])
\r
873 Rhs[j * nbComp + 2] = -temp1[2] + temp2[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])
\r
875 Rhs[j * nbComp + 0] = 0
\r
876 Rhs[j * nbComp + 1] = 0
\r
877 Rhs[j * nbComp + 2] = 0
\r
880 def computeSystemMatrix(a,b,nx, cfl, Uk, isImplicit):
\r
888 divMat = cdmath.SparseMatrixPetsc(nbCells * nbComp, nbCells * nbComp, (nbVoisinsMax + 1) * nbComp)
\r
890 divMat.zeroEntries() #sets the matrix coefficients to zero
\r
891 for j in range(nbCells):
\r
893 # traitements des bords
\r
895 FillMatrixFromEdges(j, Uk, nbComp, divMat, dt, dx)
\r
896 elif (j == nbCells - 1):
\r
897 FillMatrixFromEdges(j, Uk, nbComp, divMat, dt, dx)
\r
898 # traitement des cellules internes
\r
900 FillMatrixFromInnerCell(j, Uk, nbComp, divMat, dt, dx)
\r
903 divMat.diagonalShift(1.) # add one on the diagonal
\r
906 divMat.diagonalShift(1.) # add one on the diagonal
\r
910 def computeRHSVector(a,b,nx, cfl, Uk, Un, isImplicit):
\r
918 Rhs = cdmath.Vector(nbCells * (nbComp))
\r
920 for j in range(nbCells):
\r
922 # traitements des bords
\r
924 FillRHSFromEdges(j, Uk, nbComp, Rhs, Un, dt, dx, isImplicit)
\r
925 elif (j == nbCells - 1):
\r
926 FillRHSFromEdges(j, Uk, nbComp, Rhs, Un, dt, dx, isImplicit)
\r
927 # traitement des cellules internes
\r
929 FillRHSFromInnerCell(j, Uk, nbComp, Rhs, Un, dt, dx, isImplicit)
\r
934 if __name__ == """__main__""":
\r
935 nbComp=3 # number of equations
\r
936 a = 0.# domain is interval [a,b]
\r
937 b = 4.2# domain is interval [a,b]
\r
938 nx = 10# number of cells
\r
939 dx = (b - a) / nx # space step
\r
940 x = [a + 0.5 * dx + i * dx for i in range(nx)] # array of cell center (1D mesh)
\r
941 state_law = "Hermite575K"
\r
942 state_law_parameters(state_law)
\r
943 rho0=p_to_rho_StiffenedGaz(p_0, T_0)
\r
944 rhoE0=T_to_rhoE_StiffenedGaz(T_0, rho0, rho0*v_0)
\r
947 #### initial condition (T in K, v in m/s, p in Pa)
\r
948 p_initial = np.array([ p_outlet for xi in x])
\r
949 v_initial = np.array([ v_inlet for xi in x])
\r
950 T_initial = np.array([ T_inlet for xi in x])
\r
952 rho_field = p_to_rho_StiffenedGaz(p_initial, T_initial)
\r
953 q_field = rho_field * v_initial
\r
954 rho_E_field = rho_field * T_to_E_StiffenedGaz(p_initial, T_initial, v_initial)
\r
956 U = cdmath.Vector(nx * (nbComp))#Inutile à terme mais nécessaire pour le moment
\r
958 for k in range(nx):
\r
959 U[k * nbComp + 0] = rho_field[k]
\r
960 U[k * nbComp + 1] = q_field[k]
\r
961 U[k * nbComp + 2] = rho_E_field[k]
\r
962 print("\n Testing function computeSystemMatrix \n")
\r
964 computeSystemMatrix(a, b, nx, cfl, U,True) #Implicit matrix
\r
965 computeSystemMatrix(a, b, nx, cfl, U,False) #Explicit matrix
\r
967 print("\n Testing function computeRHSVector \n")
\r
969 computeRHSVector(a, b, nx, cfl, U, U,True) #Implicit RHS
\r
970 computeRHSVector(a, b, nx, cfl, U, U,False) #Explicit RHS
\r
972 print("\n Testing function solve (Implicit scheme) \n")
\r
975 solve(a, b, nx, "RegularSquares", "", cfl, state_law, isImplicit)
\r
977 print("\n Testing function solve (Explicit scheme) \n")
\r
980 solve(a, b, nx, "RegularSquares", "", cfl, state_law, isImplicit)
\r