Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
SWIFT
SWIFTsim
Commits
596f2c23
Commit
596f2c23
authored
Aug 11, 2016
by
Matthieu Schaller
Browse files
Added the 2D Sedov test-case
parent
9dff8f4c
Changes
8
Hide whitespace changes
Inline
Side-by-side
examples/GreshoVortex/plotSolution.py
View file @
596f2c23
...
...
@@ -93,7 +93,7 @@ git = sim["Code"].attrs["Git Revision"]
pos
=
sim
[
"/PartType0/Coordinates"
][:,:]
x
=
pos
[:,
0
]
-
boxSize
/
2
y
=
pos
[:,
1
]
-
boxSize
/
2
y
=
pos
[:,
1
]
-
boxSize
/
2
vel
=
sim
[
"/PartType0/Velocities"
][:,:]
r
=
sqrt
(
x
**
2
+
y
**
2
)
v_r
=
(
x
*
vel
[:,
0
]
+
y
*
vel
[:,
1
])
/
r
...
...
examples/GreshoVortex/run.sh
View file @
596f2c23
#!/bin/bash
# Generate the initial conditions if they are not present.
if
[
!
-e
glass_128.hdf5
]
if
[
!
-e
glass
Plane
_128.hdf5
]
then
echo
"Fetching initial glass file for the Gresho-Chan vortex example..."
./getGlass.sh
...
...
examples/SedovBlast_2D/getGlass.sh
0 → 100755
View file @
596f2c23
#!/bin/bash
wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassPlane_128.hdf5
examples/SedovBlast_2D/makeIC.py
0 → 100644
View file @
596f2c23
###############################################################################
# This file is part of SWIFT.
# Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import
h5py
import
random
from
numpy
import
*
# Generates a swift IC file for the Sedov blast test in a periodic cubic box
# Parameters
gamma
=
5.
/
3.
# Gas adiabatic index
rho0
=
1.
# Background density
P0
=
1.e-6
# Background pressure
E0
=
1.
# Energy of the explosion
N_inject
=
21
# Number of particles in which to inject energy
fileName
=
"sedov.hdf5"
#L = 101
#---------------------------------------------------
glass
=
h5py
.
File
(
"glassPlane_128.hdf5"
,
"r"
)
# Read particle positions and h from the glass
pos
=
glass
[
"/PartType0/Coordinates"
][:,:]
h
=
glass
[
"/PartType0/SmoothingLength"
][:]
*
0.3
numPart
=
size
(
h
)
vol
=
1.
# Generate extra arrays
v
=
zeros
((
numPart
,
3
))
ids
=
linspace
(
1
,
numPart
,
numPart
)
m
=
zeros
(
numPart
)
u
=
zeros
(
numPart
)
r
=
zeros
(
numPart
)
for
i
in
range
(
numPart
):
r
[
i
]
=
sqrt
((
pos
[
i
,
0
]
-
0.5
)
**
2
+
(
pos
[
i
,
1
]
-
0.5
)
**
2
)
m
[
i
]
=
rho0
*
vol
/
numPart
u
[
i
]
=
P0
/
(
rho0
*
(
gamma
-
1
))
# Make the central particle detonate
index
=
argsort
(
r
)
u
[
index
[
0
:
N_inject
]]
=
E0
/
(
N_inject
*
m
[
0
])
#--------------------------------------------------
#File
file
=
h5py
.
File
(
fileName
,
'w'
)
# Header
grp
=
file
.
create_group
(
"/Header"
)
grp
.
attrs
[
"BoxSize"
]
=
[
1.
,
1.
,
1.0
]
grp
.
attrs
[
"NumPart_Total"
]
=
[
numPart
,
0
,
0
,
0
,
0
,
0
]
grp
.
attrs
[
"NumPart_Total_HighWord"
]
=
[
0
,
0
,
0
,
0
,
0
,
0
]
grp
.
attrs
[
"NumPart_ThisFile"
]
=
[
numPart
,
0
,
0
,
0
,
0
,
0
]
grp
.
attrs
[
"Time"
]
=
0.0
grp
.
attrs
[
"NumFilesPerSnapshot"
]
=
1
grp
.
attrs
[
"MassTable"
]
=
[
0.0
,
0.0
,
0.0
,
0.0
,
0.0
,
0.0
]
grp
.
attrs
[
"Flag_Entropy_ICs"
]
=
0
#Runtime parameters
grp
=
file
.
create_group
(
"/RuntimePars"
)
grp
.
attrs
[
"PeriodicBoundariesOn"
]
=
1
#Units
grp
=
file
.
create_group
(
"/Units"
)
grp
.
attrs
[
"Unit length in cgs (U_L)"
]
=
1.
grp
.
attrs
[
"Unit mass in cgs (U_M)"
]
=
1.
grp
.
attrs
[
"Unit time in cgs (U_t)"
]
=
1.
grp
.
attrs
[
"Unit current in cgs (U_I)"
]
=
1.
grp
.
attrs
[
"Unit temperature in cgs (U_T)"
]
=
1.
#Particle group
grp
=
file
.
create_group
(
"/PartType0"
)
grp
.
create_dataset
(
'Coordinates'
,
data
=
pos
,
dtype
=
'd'
)
grp
.
create_dataset
(
'Velocities'
,
data
=
v
,
dtype
=
'f'
)
grp
.
create_dataset
(
'Masses'
,
data
=
m
,
dtype
=
'f'
)
grp
.
create_dataset
(
'SmoothingLength'
,
data
=
h
,
dtype
=
'f'
)
grp
.
create_dataset
(
'InternalEnergy'
,
data
=
u
,
dtype
=
'f'
)
grp
.
create_dataset
(
'ParticleIDs'
,
data
=
ids
,
dtype
=
'L'
)
file
.
close
()
examples/SedovBlast_2D/plotSolution.py
0 → 100644
View file @
596f2c23
###############################################################################
# This file is part of SWIFT.
# Copyright (c) 2015 Bert Vandenbroucke (bert.vandenbroucke@ugent.be)
# Matthieu Schaller (matthieu.schaller@durham.ac.uk)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
# Computes the analytical solution of the 3D Sedov blast wave.
# The script works for a given initial box and dumped energy and computes the solution at a later time t.
# Parameters
rho_0
=
1.
# Background Density
P_0
=
1.e-6
# Background Pressure
E_0
=
1.
# Energy of the explosion
gas_gamma
=
5.
/
3.
# Gas polytropic index
# ---------------------------------------------------------------
# Don't touch anything after this.
# ---------------------------------------------------------------
import
matplotlib
matplotlib
.
use
(
"Agg"
)
from
pylab
import
*
import
h5py
# Plot parameters
params
=
{
'axes.labelsize'
:
10
,
'axes.titlesize'
:
10
,
'font.size'
:
12
,
'legend.fontsize'
:
12
,
'xtick.labelsize'
:
10
,
'ytick.labelsize'
:
10
,
'text.usetex'
:
True
,
'figure.figsize'
:
(
9.90
,
6.45
),
'figure.subplot.left'
:
0.045
,
'figure.subplot.right'
:
0.99
,
'figure.subplot.bottom'
:
0.05
,
'figure.subplot.top'
:
0.99
,
'figure.subplot.wspace'
:
0.15
,
'figure.subplot.hspace'
:
0.12
,
'lines.markersize'
:
6
,
'lines.linewidth'
:
3.
,
'text.latex.unicode'
:
True
}
rcParams
.
update
(
params
)
rc
(
'font'
,
**
{
'family'
:
'sans-serif'
,
'sans-serif'
:[
'Times'
]})
snap
=
int
(
sys
.
argv
[
1
])
# Read the simulation data
sim
=
h5py
.
File
(
"sedov_%03d.hdf5"
%
snap
,
"r"
)
boxSize
=
sim
[
"/Header"
].
attrs
[
"BoxSize"
][
0
]
time
=
sim
[
"/Header"
].
attrs
[
"Time"
][
0
]
scheme
=
sim
[
"/HydroScheme"
].
attrs
[
"Scheme"
]
kernel
=
sim
[
"/HydroScheme"
].
attrs
[
"Kernel function"
]
neighbours
=
sim
[
"/HydroScheme"
].
attrs
[
"Kernel target N_ngb"
]
eta
=
sim
[
"/HydroScheme"
].
attrs
[
"Kernel eta"
]
git
=
sim
[
"Code"
].
attrs
[
"Git Revision"
]
pos
=
sim
[
"/PartType0/Coordinates"
][:,:]
x
=
pos
[:,
0
]
-
boxSize
/
2
y
=
pos
[:,
1
]
-
boxSize
/
2
vel
=
sim
[
"/PartType0/Velocities"
][:,:]
r
=
sqrt
(
x
**
2
+
y
**
2
)
v_r
=
(
x
*
vel
[:,
0
]
+
y
*
vel
[:,
1
])
/
r
u
=
sim
[
"/PartType0/InternalEnergy"
][:]
S
=
sim
[
"/PartType0/Entropy"
][:]
P
=
sim
[
"/PartType0/Pressure"
][:]
rho
=
sim
[
"/PartType0/Density"
][:]
from
scipy.special
import
gamma
as
Gamma
from
numpy
import
*
def
calc_a
(
g
,
nu
=
3
):
"""
exponents of the polynomials of the sedov solution
g - the polytropic gamma
nu - the dimension
"""
a
=
[
0
]
*
8
a
[
0
]
=
2.0
/
(
nu
+
2
)
a
[
2
]
=
(
1
-
g
)
/
(
2
*
(
g
-
1
)
+
nu
)
a
[
3
]
=
nu
/
(
2
*
(
g
-
1
)
+
nu
)
a
[
5
]
=
2
/
(
g
-
2
)
a
[
6
]
=
g
/
(
2
*
(
g
-
1
)
+
nu
)
a
[
1
]
=
(((
nu
+
2
)
*
g
)
/
(
2.0
+
nu
*
(
g
-
1.0
))
)
*
(
(
2.0
*
nu
*
(
2.0
-
g
))
/
(
g
*
(
nu
+
2.0
)
**
2
)
-
a
[
2
])
a
[
4
]
=
a
[
1
]
*
(
nu
+
2
)
/
(
2
-
g
)
a
[
7
]
=
(
2
+
nu
*
(
g
-
1
))
*
a
[
1
]
/
(
nu
*
(
2
-
g
))
return
a
def
calc_beta
(
v
,
g
,
nu
=
3
):
"""
beta values for the sedov solution (coefficients of the polynomials of the similarity variables)
v - the similarity variable
g - the polytropic gamma
nu- the dimension
"""
beta
=
(
nu
+
2
)
*
(
g
+
1
)
*
array
((
0.25
,
(
g
/
(
g
-
1
))
*
0.5
,
-
(
2
+
nu
*
(
g
-
1
))
/
2.0
/
((
nu
+
2
)
*
(
g
+
1
)
-
2
*
(
2
+
nu
*
(
g
-
1
))),
-
0.5
/
(
g
-
1
)),
dtype
=
float64
)
beta
=
outer
(
beta
,
v
)
beta
+=
(
g
+
1
)
*
array
((
0.0
,
-
1.0
/
(
g
-
1
),
(
nu
+
2
)
/
((
nu
+
2
)
*
(
g
+
1
)
-
2.0
*
(
2
+
nu
*
(
g
-
1
))),
1.0
/
(
g
-
1
)),
dtype
=
float64
).
reshape
((
4
,
1
))
return
beta
def
sedov
(
t
,
E0
,
rho0
,
g
,
n
=
1000
,
nu
=
3
):
"""
solve the sedov problem
t - the time
E0 - the initial energy
rho0 - the initial density
n - number of points (10000)
nu - the dimension
g - the polytropic gas gamma
"""
# the similarity variable
v_min
=
2.0
/
((
nu
+
2
)
*
g
)
v_max
=
4.0
/
((
nu
+
2
)
*
(
g
+
1
))
v
=
v_min
+
arange
(
n
)
*
(
v_max
-
v_min
)
/
(
n
-
1.0
)
a
=
calc_a
(
g
,
nu
)
beta
=
calc_beta
(
v
,
g
=
g
,
nu
=
nu
)
lbeta
=
log
(
beta
)
r
=
exp
(
-
a
[
0
]
*
lbeta
[
0
]
-
a
[
2
]
*
lbeta
[
1
]
-
a
[
1
]
*
lbeta
[
2
])
rho
=
((
g
+
1.0
)
/
(
g
-
1.0
))
*
exp
(
a
[
3
]
*
lbeta
[
1
]
+
a
[
5
]
*
lbeta
[
3
]
+
a
[
4
]
*
lbeta
[
2
])
p
=
exp
(
nu
*
a
[
0
]
*
lbeta
[
0
]
+
(
a
[
5
]
+
1
)
*
lbeta
[
3
]
+
(
a
[
4
]
-
2
*
a
[
1
])
*
lbeta
[
2
])
u
=
beta
[
0
]
*
r
*
4.0
/
((
g
+
1
)
*
(
nu
+
2
))
p
*=
8.0
/
((
g
+
1
)
*
(
nu
+
2
)
*
(
nu
+
2
))
# we have to take extra care at v=v_min, since this can be a special point.
# It is not a singularity, however, the gradients of our variables (wrt v) are.
# r -> 0, u -> 0, rho -> 0, p-> constant
u
[
0
]
=
0.0
;
rho
[
0
]
=
0.0
;
r
[
0
]
=
0.0
;
p
[
0
]
=
p
[
1
]
# volume of an n-sphere
vol
=
(
pi
**
(
nu
/
2.0
)
/
Gamma
(
nu
/
2.0
+
1
))
*
power
(
r
,
nu
)
# note we choose to evaluate the integral in this way because the
# volumes of the first few elements (i.e near v=vmin) are shrinking
# very slowly, so we dramatically improve the error convergence by
# finding the volumes exactly. This is most important for the
# pressure integral, as this is on the order of the volume.
# (dimensionless) energy of the model solution
de
=
rho
*
u
*
u
*
0.5
+
p
/
(
g
-
1
)
# integrate (trapezium rule)
q
=
inner
(
de
[
1
:]
+
de
[:
-
1
],
diff
(
vol
))
*
0.5
# the factor to convert to this particular problem
fac
=
(
q
*
(
t
**
nu
)
*
rho0
/
E0
)
**
(
-
1.0
/
(
nu
+
2
))
# shock speed
shock_speed
=
fac
*
(
2.0
/
(
nu
+
2
))
rho_s
=
((
g
+
1
)
/
(
g
-
1
))
*
rho0
r_s
=
shock_speed
*
t
*
(
nu
+
2
)
/
2.0
p_s
=
(
2.0
*
rho0
*
shock_speed
*
shock_speed
)
/
(
g
+
1
)
u_s
=
(
2.0
*
shock_speed
)
/
(
g
+
1
)
r
*=
fac
*
t
u
*=
fac
p
*=
fac
*
fac
*
rho0
rho
*=
rho0
return
r
,
p
,
rho
,
u
,
r_s
,
p_s
,
rho_s
,
u_s
,
shock_speed
r_s
,
P_s
,
rho_s
,
v_s
,
r_shock
,
_
,
_
,
_
,
_
=
sedov
(
time
,
E_0
,
rho_0
,
gas_gamma
,
1000
,
2
)
# Append points for after the shock
r_s
=
np
.
insert
(
r_s
,
np
.
size
(
r_s
),
[
r_shock
,
r_shock
*
1.5
])
rho_s
=
np
.
insert
(
rho_s
,
np
.
size
(
rho_s
),
[
rho_0
,
rho_0
])
P_s
=
np
.
insert
(
P_s
,
np
.
size
(
P_s
),
[
P_0
,
P_0
])
v_s
=
np
.
insert
(
v_s
,
np
.
size
(
v_s
),
[
0
,
0
])
# Additional arrays
u_s
=
P_s
/
(
rho_s
*
(
gas_gamma
-
1.
))
#internal energy
s_s
=
P_s
/
rho_s
**
gas_gamma
# entropic function
# Plot the interesting quantities
figure
()
# Velocity profile --------------------------------
subplot
(
231
)
plot
(
r
,
v_r
,
'.'
,
color
=
'r'
,
ms
=
1.
)
plot
(
r_s
,
v_s
,
'--'
,
color
=
'k'
,
alpha
=
0.8
,
lw
=
1.2
)
xlabel
(
"${
\\
rm{Radius}}~r$"
,
labelpad
=
0
)
ylabel
(
"${
\\
rm{Radial~velocity}}~v_r$"
,
labelpad
=
0
)
xlim
(
0
,
1.3
*
r_shock
)
ylim
(
-
0.2
,
3.8
)
# Density profile --------------------------------
subplot
(
232
)
plot
(
r
,
rho
,
'.'
,
color
=
'r'
,
ms
=
1.
)
plot
(
r_s
,
rho_s
,
'--'
,
color
=
'k'
,
alpha
=
0.8
,
lw
=
1.2
)
xlabel
(
"${
\\
rm{Radius}}~r$"
,
labelpad
=
0
)
ylabel
(
"${
\\
rm{Density}}~
\\
rho$"
,
labelpad
=
2
)
xlim
(
0
,
1.3
*
r_shock
)
ylim
(
-
0.2
,
5.2
)
# Pressure profile --------------------------------
subplot
(
233
)
plot
(
r
,
P
,
'.'
,
color
=
'r'
,
ms
=
1.
)
plot
(
r_s
,
P_s
,
'--'
,
color
=
'k'
,
alpha
=
0.8
,
lw
=
1.2
)
xlabel
(
"${
\\
rm{Radius}}~r$"
,
labelpad
=
0
)
ylabel
(
"${
\\
rm{Pressure}}~P$"
,
labelpad
=
0
)
xlim
(
0
,
1.3
*
r_shock
)
ylim
(
-
1
,
12.5
)
# Internal energy profile -------------------------
subplot
(
234
)
plot
(
r
,
u
,
'.'
,
color
=
'r'
,
ms
=
1.
)
plot
(
r_s
,
u_s
,
'--'
,
color
=
'k'
,
alpha
=
0.8
,
lw
=
1.2
)
xlabel
(
"${
\\
rm{Radius}}~r$"
,
labelpad
=
0
)
ylabel
(
"${
\\
rm{Internal~Energy}}~u$"
,
labelpad
=
0
)
xlim
(
0
,
1.3
*
r_shock
)
ylim
(
0
,
120
)
# Entropy profile ---------------------------------
subplot
(
235
)
plot
(
r
,
S
,
'.'
,
color
=
'r'
,
ms
=
1.
)
plot
(
r_s
,
s_s
,
'--'
,
color
=
'k'
,
alpha
=
0.8
,
lw
=
1.2
)
xlabel
(
"${
\\
rm{Radius}}~r$"
,
labelpad
=
0
)
ylabel
(
"${
\\
rm{Entropy}}~S$"
,
labelpad
=-
5
)
xlim
(
0
,
1.3
*
r_shock
)
ylim
(
0
,
1000
)
# Information -------------------------------------
subplot
(
236
,
frameon
=
False
)
text
(
-
0.49
,
0.9
,
"Sedov blast with $
\\
gamma=%.3f$ in 2D at $t=%.2f$"
%
(
gas_gamma
,
time
),
fontsize
=
10
)
text
(
-
0.49
,
0.8
,
"Background $
\\
rho_0=%.2f$"
%
(
rho_0
),
fontsize
=
10
)
text
(
-
0.49
,
0.7
,
"Energy injected $E_0=%.2f$"
%
(
E_0
),
fontsize
=
10
)
plot
([
-
0.49
,
0.1
],
[
0.62
,
0.62
],
'k-'
,
lw
=
1
)
text
(
-
0.49
,
0.5
,
"$
\\
textsc{Swift}$ %s"
%
git
,
fontsize
=
10
)
text
(
-
0.49
,
0.4
,
scheme
,
fontsize
=
10
)
text
(
-
0.49
,
0.3
,
kernel
,
fontsize
=
10
)
text
(
-
0.49
,
0.2
,
"$%.2f$ neighbours ($
\\
eta=%.3f$)"
%
(
neighbours
,
eta
),
fontsize
=
10
)
xlim
(
-
0.5
,
0.5
)
ylim
(
0
,
1
)
xticks
([])
yticks
([])
savefig
(
"Sedov.png"
,
dpi
=
200
)
examples/SedovBlast_2D/run.sh
0 → 100755
View file @
596f2c23
#!/bin/bash
# Generate the initial conditions if they are not present.
if
[
!
-e
glassPlane_128.hdf5
]
then
echo
"Fetching initial glass file for the Sedov blast example..."
./getGlass.sh
fi
if
[
!
-e
sedov.hdf5
]
then
echo
"Generating initial conditions for the Sedov blast example..."
python makeIC.py
fi
# Run SWIFT
../swift
-s
-t
1 sedov.yml
# Plot the solution
python plotSolution.py 5
examples/SedovBlast_2D/sedov.py
0 → 100755
View file @
596f2c23
###############################################################################
# This file is part of SWIFT.
# Copyright (c) 2015 Bert Vandenbroucke (bert.vandenbroucke@ugent.be)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import
numpy
as
np
import
scipy.integrate
as
integrate
import
scipy.optimize
as
optimize
import
os
# Calculate the analytical solution of the Sedov-Taylor shock wave for a given
# number of dimensions, gamma and time. We assume dimensionless units and a
# setup with constant density 1, pressure and velocity 0. An energy 1 is
# inserted in the center at t 0.
#
# The solution is a self-similar shock wave, which was described in detail by
# Sedov (1959). We follow his notations and solution method.
#
# The position of the shock at time t is given by
# r2 = (E/rho1)^(1/(2+nu)) * t^(2/(2+nu))
# the energy E is related to the inserted energy E0 by E0 = alpha*E, with alpha
# a constant which has to be calculated by imposing energy conservation.
#
# The density for a given radius at a certain time is determined by introducing
# the dimensionless position coordinate lambda = r/r2. The density profile as
# a function of lambda is constant in time and given by
# rho = rho1 * R(V, gamma, nu)
# and
# V = V(lambda, gamma, nu)
#
# The function V(lambda, gamma, nu) is found by solving a differential equation
# described in detail in Sedov (1959) chapter 4, section 5. Alpha is calculated
# from the integrals in section 11 of the same chapter.
#
# Numerically, the complete solution requires the use of 3 quadratures and 1
# root solver, which are implemented using the GNU Scientific Library (GSL).
# Since some quadratures call functions that themselves contain quadratures,
# the problem is highly non-linear and complex and takes a while to converge.
# Therefore, we tabulate the alpha values and profile values the first time
# a given set of gamma and nu values is requested and reuse these tabulated
# values.
#
# Reference:
# Sedov (1959): Sedov, L., Similitude et dimensions en mecanique (7th ed.;
# Moscou: Editions Mir) - french translation of the original
# book from 1959.
# dimensionless variable z = gamma*P/R as a function of V (and gamma and nu)
# R is a dimensionless density, while P is a dimensionless pressure
# z is hence a sort of dimensionless sound speed
# The expression below corresponds to eq. 11.9 in Sedov (1959), chapter 4
def
_z
(
V
,
gamma
,
nu
):
if
V
==
2.
/
(
nu
+
2.
)
/
gamma
:
return
0.
else
:
return
(
gamma
-
1.
)
*
V
*
V
*
(
V
-
2.
/
(
2.
+
nu
))
/
2.
/
(
2.
/
(
2.
+
nu
)
/
gamma
-
V
)
# differential equation that needs to be solved to obtain lambda for a given V
# corresponds to eq. 5.11 in Sedov (1959), chapter 4 (omega = 0)
def
_dlnlambda_dV
(
V
,
gamma
,
nu
):
nom
=
_z
(
V
,
gamma
,
nu
)
-
(
V
-
2.
/
(
nu
+
2.
))
*
(
V
-
2.
/
(
nu
+
2.
))
denom
=
V
*
(
V
-
1.
)
*
(
V
-
2.
/
(
nu
+
2.
))
+
nu
*
(
2.
/
(
nu
+
2.
)
/
gamma
-
V
)
*
_z
(
V
,
gamma
,
nu
)
return
nom
/
denom
# dimensionless variable lambda = r/r2 as a function of V (and gamma and nu)
# found by solving differential equation 5.11 in Sedov (1959), chapter 4
# (omega = 0)
def
_lambda
(
V
,
gamma
,
nu
):
if
V
==
2.
/
(
nu
+
2.
)
/
gamma
:
return
0.
else
:
V0
=
4.
/
(
nu
+
2.
)
/
(
gamma
+
1.
)
integral
,
err
=
integrate
.
quad
(
_dlnlambda_dV
,
V
,
V0
,
(
gamma
,
nu
),
limit
=
8000
)
return
np
.
exp
(
-
integral
)
# dimensionless variable R = rho/rho1 as a function of V (and gamma and nu)
# found by inverting eq. 5.12 in Sedov (1959), chapter 4 (omega = 0)
# the integration constant C is found by inserting the R, V and z values
# at the shock wave, where lambda is 1. These correspond to eq. 11.8 in Sedov
# (1959), chapter 4.
def
_R
(
V
,
gamma
,
nu
):
if
V
==
2.
/
(
nu
+
2.
)
/
gamma
:
return
0.
else
:
C
=
8.
*
gamma
*
(
gamma
-
1.
)
/
(
nu
+
2.
)
/
(
nu
+
2.
)
/
(
gamma
+
1.
)
/
(
gamma
+
1.
)
\
*
((
gamma
-
1.
)
/
(
gamma
+
1.
))
**
(
gamma
-
2.
)
\
*
(
4.
/
(
nu
+
2.
)
/
(
gamma
+
1.
)
-
2.
/
(
nu
+
2.
))
lambda1
=
_lambda
(
V
,
gamma
,
nu
)
lambda5
=
lambda1
**
(
nu
+
2
)
return
(
_z
(
V
,
gamma
,
nu
)
*
(
V
-
2.
/
(
nu
+
2.
))
*
lambda5
/
C
)
**
(
1.
/
(
gamma
-
2.
))
# function of which we need to find the zero point to invert lambda(V)
def
_lambda_min_lambda
(
V
,
lambdax
,
gamma
,
nu
):
return
_lambda
(
V
,
gamma
,
nu
)
-
lambdax
# dimensionless variable V = v*t/r as a function of lambda (and gamma and nu)
# found by inverting the function lamdba(V) which is found by solving
# differential equation 5.11 in Sedov (1959), chapter 4 (omega = 0)
# the invertion is done by searching the zero point of the function
# lambda_min_lambda defined above
def
_V_inv
(
lambdax
,
gamma
,
nu
):
if
lambdax
==
0.
:
return
2.
/
(
2.
+
nu
)
/
gamma
;
else
:
return
optimize
.
brentq
(
_lambda_min_lambda
,
2.
/
(
nu
+
2.
)
/
gamma
,
4.
/
(
nu
+
2.
)
/
(
gamma
+
1.
),
(
lambdax
,
gamma
,
nu
))
# integrand of the first integral in eq. 11.24 in Sedov (1959), chapter 4
def
_integrandum1
(
lambdax
,
gamma
,
nu
):
V
=
_V_inv
(
lambdax
,
gamma
,
nu
)
if
nu
==
2
:
return
_R
(
V
,
gamma
,
nu
)
*
V
**
2
*
lambdax
**
3
else
:
return
_R
(
V
,
gamma
,
nu
)
*
V
**
2
*
lambdax
**
4
# integrand of the second integral in eq. 11.24 in Sedov (1959), chapter 4
def
_integrandum2
(
lambdax
,
gamma
,
nu
):
V
=
_V_inv
(
lambdax
,
gamma
,
nu
)
if
V
==
2.
/
(
nu
+
2.
)
/
gamma
:
P
=
0.
else
:
P
=
_z
(
V
,
gamma
,
nu
)
*
_R
(
V
,
gamma
,
nu
)
/
gamma
if
nu
==
2
:
return
P
*
lambdax
**
3
else
:
return
P
*
lambdax
**
4
# calculate alpha = E0/E
# this corresponds to eq. 11.24 in Sedov (1959), chapter 4
def
get_alpha
(
gamma
,
nu
):
integral1
,
err1
=
integrate
.
quad
(
_integrandum1
,
0.
,
1.
,
(
gamma
,
nu
))
integral2
,
err2
=
integrate
.
quad
(
_integrandum2
,
0.
,
1.
,
(
gamma
,
nu
))
if
nu
==
2
:
return
np
.
pi
*
integral1
+
2.
*
np
.
pi
/
(
gamma
-
1.
)
*
integral2
else
:
return
2.
*
np
.
pi
*
integral1
+
4.
*
np
.
pi
/
(
gamma
-
1.
)
*
integral2
# get the analytical solution for the Sedov-Taylor blastwave given an input
# energy E, adiabatic index gamma, and number of dimensions nu, at time t and
# with a maximal outer region radius maxr
def
get_analytical_solution
(
E
,
gamma
,
nu
,
t
,
maxr
=
1.
):
# we check for the existance of a datafile with precomputed alpha and
# profile values
# if it does not exist, we calculate it here and write it out
# calculation of alpha and the profile takes a while...
lvec
=
np
.
zeros
(
1000
)
Rvec
=
np
.
zeros
(
1000
)
fname
=
"sedov_profile_gamma_{gamma}_nu_{nu}.dat"
.
format
(
gamma
=
gamma
,
nu
=
nu
)
if
os
.
path
.
exists
(
fname
):
file
=
open
(
fname
,
"r"
)
lines
=
file
.
readlines
()
alpha
=
float
(
lines
[
0
])
for
i
in
range
(
len
(
lines
)
-
1
):
data
=
lines
[
i
+
1
].
split
()
lvec
[
i
]
=
float
(
data
[
0
])
Rvec
[
i
]
=
float
(
data
[
1
])