Peano
Loading...
Searching...
No Matches
plotSolution.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2
3
22
23
24import matplotlib
25
26matplotlib.use("Agg")
27
28import matplotlib.pyplot as plt
29from scipy import stats
30from scipy.special import gamma as Gamma
31import numpy as np
32import sys
33
35
36
37"""
38!
39Computes the analytical solution of the 3D Sedov blast wave.
40The script works for a given initial box and dumped energy and computes the
41solution at a later time t.
42
43
44python3 plotSolution.py time
45
46where:
47@param time_step_sim : time to plot solution of
48"""
49
50
51if len(sys.argv) < 2:
52 time = 0.05
53else:
54 time = float(sys.argv[1])
55
56# -------------------------
57# Extract data
58# -------------------------
59
60pvdfile = "particles.pvd"
61reader = ParticleVTUReader(pvdfile=pvdfile, snapshot_time=time)
62partData = reader.load()
63time = reader.get_snapshot_time()
64boxsize = 1.0
65
66x = partData.x[:, 0] - 0.5 * boxsize
67y = partData.x[:, 1] - 0.5 * boxsize
68z = partData.x[:, 2] - 0.5 * boxsize
69vel_x = partData.v[:, 0]
70vel_y = partData.v[:, 1]
71vel_z = partData.v[:, 2]
72pressure = partData.pressure
73density = partData.density
74mass = partData.mass
75energy = partData.u
76
77r = np.sqrt(x**2 + y**2 + z**2)
78v_r = (x * vel_x + y * vel_y + z * vel_z) / r
79
80
81# -------------------------
82# Get analytical solution
83# -------------------------
84
85
86def calc_a(g, nu=3):
87 """
88 exponents of the polynomials of the sedov solution
89 g - the polytropic gamma
90 nu - the dimension
91 """
92 a = [0] * 8
93
94 a[0] = 2.0 / (nu + 2)
95 a[2] = (1 - g) / (2 * (g - 1) + nu)
96 a[3] = nu / (2 * (g - 1) + nu)
97 a[5] = 2 / (g - 2)
98 a[6] = g / (2 * (g - 1) + nu)
99
100 a[1] = (((nu + 2) * g) / (2.0 + nu * (g - 1.0))) * (
101 (2.0 * nu * (2.0 - g)) / (g * (nu + 2.0) ** 2) - a[2]
102 )
103 a[4] = a[1] * (nu + 2) / (2 - g)
104 a[7] = (2 + nu * (g - 1)) * a[1] / (nu * (2 - g))
105 return a
106
107
108def calc_beta(v, g, nu=3):
109 """
110 beta values for the sedov solution (coefficients of the polynomials of the similarity variables)
111 v - the similarity variable
112 g - the polytropic gamma
113 nu- the dimension
114 """
115
116 beta = (
117 (nu + 2)
118 * (g + 1)
119 * np.array(
120 (
121 0.25,
122 (g / (g - 1)) * 0.5,
123 -(2 + nu * (g - 1))
124 / 2.0
125 / ((nu + 2) * (g + 1) - 2 * (2 + nu * (g - 1))),
126 -0.5 / (g - 1),
127 ),
128 )
129 )
130
131 beta = np.outer(beta, v)
132
133 beta += (g + 1) * np.array(
134 (
135 0.0,
136 -1.0 / (g - 1),
137 (nu + 2) / ((nu + 2) * (g + 1) - 2.0 * (2 + nu * (g - 1))),
138 1.0 / (g - 1),
139 ),
140 ).reshape((4, 1))
141
142 return beta
143
144
145def sedov(t, E0, rho0, g, n=1000, nu=3):
146 """
147 solve the sedov problem
148 t - the time
149 E0 - the initial energy
150 rho0 - the initial density
151 n - number of points (10000)
152 nu - the dimension
153 g - the polytropic gas gamma
154 """
155 # the similarity variable
156 v_min = 2.0 / ((nu + 2) * g)
157 v_max = 4.0 / ((nu + 2) * (g + 1))
158
159 v = v_min + np.arange(n) * (v_max - v_min) / (n - 1.0)
160
161 a = calc_a(g, nu)
162 beta = calc_beta(v, g=g, nu=nu)
163 lbeta = np.log(beta)
164
165 r = np.exp(-a[0] * lbeta[0] - a[2] * lbeta[1] - a[1] * lbeta[2])
166 rho = ((g + 1.0) / (g - 1.0)) * np.exp(
167 a[3] * lbeta[1] + a[5] * lbeta[3] + a[4] * lbeta[2]
168 )
169 p = np.exp(
170 nu * a[0] * lbeta[0] + (a[5] + 1) * lbeta[3] + (a[4] - 2 * a[1]) * lbeta[2]
171 )
172 u = beta[0] * r * 4.0 / ((g + 1) * (nu + 2))
173 p *= 8.0 / ((g + 1) * (nu + 2) * (nu + 2))
174
175 # we have to take extra care at v=v_min, since this can be a special point.
176 # It is not a singularity, however, the gradients of our variables (wrt v) are.
177 # r -> 0, u -> 0, rho -> 0, p-> constant
178
179 u[0] = 0.0
180 rho[0] = 0.0
181 r[0] = 0.0
182 p[0] = p[1]
183
184 # volume of an n-sphere
185 vol = (np.pi ** (nu / 2.0) / Gamma(nu / 2.0 + 1)) * np.power(r, nu)
186
187 # note we choose to evaluate the integral in this way because the
188 # volumes of the first few elements (i.e near v=vmin) are shrinking
189 # very slowly, so we dramatically improve the error convergence by
190 # finding the volumes exactly. This is most important for the
191 # pressure integral, as this is on the order of the volume.
192
193 # (dimensionless) energy of the model solution
194 de = rho * u * u * 0.5 + p / (g - 1)
195 # integrate (trapezium rule)
196 q = np.inner(de[1:] + de[:-1], np.diff(vol)) * 0.5
197
198 # the factor to convert to this particular problem
199 fac = (q * (t**nu) * rho0 / E0) ** (-1.0 / (nu + 2))
200
201 # shock speed
202 shock_speed = fac * (2.0 / (nu + 2))
203 rho_s = ((g + 1) / (g - 1)) * rho0
204 r_s = shock_speed * t * (nu + 2) / 2.0
205 p_s = (2.0 * rho0 * shock_speed * shock_speed) / (g + 1)
206 u_s = (2.0 * shock_speed) / (g + 1)
207
208 r *= fac * t
209 u *= fac
210 p *= fac * fac * rho0
211 rho *= rho0
212 return r, p, rho, u, r_s, p_s, rho_s, u_s, shock_speed
213
214
215# Parameters
216rho_0 = 1.0 # Background Density
217P_0 = 1.0e-6 # Background Pressure
218E_0 = 1.0 # Energy of the explosion
219gas_gamma = 5.0 / 3.0 # Gas polytropic index
220
221# The main properties of the solution
222r_s, P_s, rho_s, v_s, r_shock, _, _, _, _ = sedov(time, E_0, rho_0, gas_gamma, 1000, 3)
223
224# Append points for after the shock
225r_s = np.insert(r_s, np.size(r_s), [r_shock, r_shock * 3])
226rho_s = np.insert(rho_s, np.size(rho_s), [rho_0, rho_0])
227P_s = np.insert(P_s, np.size(P_s), [P_0, P_0])
228v_s = np.insert(v_s, np.size(v_s), [0, 0])
229
230# Additional arrays
231u_s = P_s / (rho_s * (gas_gamma - 1.0)) # internal energy
232# s_s = P_s / rho_s**gas_gamma # entropic function
233
234
235# -------------------------
236# Plot, plot, plot!
237# -------------------------
238
239sim_props = {
240 "marker": ".",
241 "ms": 4,
242 "markeredgecolor": "none",
243 "alpha": 0.4,
244 "zorder": -1,
245 "rasterized": True,
246 "linestyle": "none",
247}
248solution_props = {
249 "linestyle": "--",
250 "color": "C1",
251 "alpha": 0.8,
252 "linewidth": 2.0,
253}
254
255
256fig = plt.figure(figsize=(7.0, 7.0))
257fig.suptitle(f"t={time}")
258
259ax1 = fig.add_subplot(2, 2, 1)
260ax2 = fig.add_subplot(2, 2, 2)
261ax3 = fig.add_subplot(2, 2, 3)
262ax4 = fig.add_subplot(2, 2, 4)
263
264ax1.plot(r, v_r, **sim_props)
265ax1.plot(r_s, v_s, **solution_props)
266ax1.set_ylabel(r"Radial velocity $v_r$")
267ax1.set_ylim(-0.2, 3.8)
268
269ax2.plot(r, density, **sim_props)
270ax2.plot(r_s, rho_s, **solution_props)
271ax2.set_ylabel(r"Density $\rho$")
272ax2.set_ylim(-0.2, 5.2)
273
274ax3.plot(r, pressure, **sim_props)
275ax3.plot(r_s, P_s, **solution_props)
276ax3.set_ylabel(r"Pressure $p$")
277ax3.set_ylim(-1.0, 12.5)
278
279ax4.plot(r, energy, **sim_props)
280ax4.plot(r_s, u_s, **solution_props)
281ax4.set_ylabel(r"Internal Energy $u$")
282ax4.set_ylim(-2.0, 22)
283
284for ax in fig.axes:
285 ax.tick_params(direction="in", top=True, right=True)
286 ax.set_xlim(0, 1.3 * r_shock)
287 ax.set_xlabel(r"Radius $r$")
288
289plt.tight_layout()
290fname = f"sedov_profile-{time:.4f}.png"
291fig.savefig(fname)
292print("Saved", fname)
Reads in particle fields from a single .vtu file, or all .vtu at a given snapshot time specified in t...
calc_beta(v, g, nu=3)
beta values for the sedov solution (coefficients of the polynomials of the similarity variables) v - ...
calc_a(g, nu=3)
exponents of the polynomials of the sedov solution g - the polytropic gamma nu - the dimension
Definition sedov.py:1