makeIC.py 6.99 KB
Newer Older
1
###############################################################################
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# This file is part of SWIFT.
# Copyright (c) 2016 John A. Regan (john.a.regan@durham.ac.uk)
#                    Tom Theuns (tom.theuns@durham.ac.uk)
#               2017 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
#                    Bert Vandenbroucke (bert.vandenbroucke@gmail.com)
#
# 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/>.
#
##############################################################################
22
23
24

import h5py
import sys
25
import numpy as np
26
27
28
import math
import random

29
# Generates a disc-patch in hydrostatic equilibrium
30
31
32
33
34
35
36
37
38
39
40
41
#
# See Creasey, Theuns & Bower, 2013, MNRAS, Volume 429, Issue 3, p.1922-1948
#
#
# Disc parameters are: surface density  -- sigma
#                      scale height -- b
#                      gas adiabatic index -- gamma
#
# Problem parameters are: Ratio height/width of the box -- z_factor
#                         Size of the patch -- side_length

# Parameters of the gas disc
42
surface_density = 10.
43
44
45
46
scale_height    = 100.
gas_gamma       = 5./3.

# Parameters of the problem
47
x_factor        = 2
48
49
50
side_length     = 400.

# File
51
fileName = "Disc-Patch.hdf5"
52
53

####################################################################
54
55

# physical constants in cgs
56
NEWTON_GRAVITY_CGS  = 6.67408e-8
57
SOLAR_MASS_IN_CGS   = 1.9885e33
58
59
60
61
PARSEC_IN_CGS       = 3.08567758149e18
PROTON_MASS_IN_CGS  = 1.672621898e-24
BOLTZMANN_IN_CGS    = 1.38064852e-16
YEAR_IN_CGS         = 3.15569252e7
62
63

# choice of units
64
65
66
67
68
unit_length_in_cgs   =   (PARSEC_IN_CGS)
unit_mass_in_cgs     =   (SOLAR_MASS_IN_CGS)
unit_velocity_in_cgs =   (1e5)
unit_time_in_cgs     =   unit_length_in_cgs / unit_velocity_in_cgs

69
print "UnitMass_in_cgs:     %.5e"%unit_mass_in_cgs
70
71
72
73
74
75
print "UnitLength_in_cgs:   %.5e"%unit_length_in_cgs
print "UnitVelocity_in_cgs: %.5e"%unit_velocity_in_cgs
print "UnitTime_in_cgs:     %.5e"%unit_time_in_cgs
print ""

# Derived units
76
77
const_G  = NEWTON_GRAVITY_CGS * unit_mass_in_cgs * unit_time_in_cgs**2 * \
           unit_length_in_cgs**-3
78
const_mp = PROTON_MASS_IN_CGS * unit_mass_in_cgs**-1
79
80
const_kb = BOLTZMANN_IN_CGS * unit_mass_in_cgs**-1 * unit_length_in_cgs**-2 * \
           unit_time_in_cgs**2
81
82

print "--- Some constants [internal units] ---"
83
84
85
print "G_Newton:    %.5e"%const_G
print "m_proton:    %.5e"%const_mp
print "k_boltzmann: %.5e"%const_kb
86
87
88
print ""

# derived quantities
89
90
91
92
93
94
95
temp       = math.pi * const_G * surface_density * scale_height * const_mp / \
             const_kb
u_therm    = const_kb * temp / ((gas_gamma-1) * const_mp)
v_disp     = math.sqrt(2 * u_therm)
soundspeed = math.sqrt(u_therm / (gas_gamma * (gas_gamma-1.)))
t_dyn      = math.sqrt(scale_height / (const_G * surface_density))
t_cross    = scale_height / soundspeed
96

97
98
99
100
101
102
103
104
105
106
107
108
print "--- Properties of the gas [internal units] ---"
print "Gas temperature:     %.5e"%temp
print "Gas thermal_energy:  %.5e"%u_therm
print "Dynamical time:      %.5e"%t_dyn
print "Sound crossing time: %.5e"%t_cross
print "Gas sound speed:     %.5e"%soundspeed
print "Gas 3D vel_disp:     %.5e"%v_disp
print ""

# Problem properties
boxSize_x = side_length
boxSize_y = boxSize_x
109
110
boxSize_z = boxSize_x
boxSize_x *= x_factor
111
volume = boxSize_x * boxSize_y * boxSize_z
112
113
M_tot = boxSize_y * boxSize_z * surface_density * \
        math.tanh(boxSize_x / (2. * scale_height))
114
115
116
117
density = M_tot / volume
entropy = (gas_gamma - 1.) * u_therm / density**(gas_gamma - 1.)

print "--- Problem properties [internal units] ---"
118
119
120
121
122
print "Box:        [%.1f, %.1f, %.1f]"%(boxSize_x, boxSize_y, boxSize_z)
print "Volume:     %.5e"%volume
print "Total mass: %.5e"%M_tot
print "Density:    %.5e"%density
print "Entropy:    %.5e"%entropy
123
124
125
126
127
128
129
130
131
132
print ""

####################################################################

# Read glass pre-ICs
infile  = h5py.File('glassCube_32.hdf5', "r")
one_glass_pos = infile["/PartType0/Coordinates"][:,:]
one_glass_h   = infile["/PartType0/SmoothingLength"][:]

# Rescale to the problem size
133
134
one_glass_pos *= side_length
one_glass_h   *= side_length
135

136
# Now create enough copies to fill the volume in x
137
138
pos = np.copy(one_glass_pos)
h = np.copy(one_glass_h)
139
140
for i in range(1, x_factor):
    one_glass_pos[:,0] += side_length
141
142
    pos = np.append(pos, one_glass_pos, axis=0)
    h   = np.append(h, one_glass_h, axis=0)
143

144
145
146
# Compute further properties of ICs
numPart = np.size(h)
mass = M_tot / numPart
147

148
149
print "--- Particle properties [internal units] ---"
print "Number part.: ", numPart
150
print "Part. mass:   %.5e"%mass
151
print ""
152

153
154
155
156
157
# Create additional arrays
u    = np.ones(numPart) * u_therm
mass = np.ones(numPart) * mass
vel  = np.zeros((numPart, 3))
ids  = 1 + np.linspace(0, numPart, numPart, endpoint=False)
158

159
####################################################################
160
161
162
163
164
165
166
# Create and write output file

#File
file = h5py.File(fileName, 'w')

#Units
grp = file.create_group("/Units")
167
grp.attrs["Unit length in cgs (U_L)"] = unit_length_in_cgs
168
grp.attrs["Unit mass in cgs (U_M)"] = unit_mass_in_cgs
169
grp.attrs["Unit time in cgs (U_t)"] = unit_time_in_cgs
170
171
172
173
174
grp.attrs["Unit current in cgs (U_I)"] = 1.
grp.attrs["Unit temperature in cgs (U_T)"] = 1.

# Header
grp = file.create_group("/Header")
175
176
grp.attrs["BoxSize"] = [boxSize_x, boxSize_y, boxSize_z]
grp.attrs["NumPart_Total"] =  [numPart, 0, 0, 0, 0, 0]
177
grp.attrs["NumPart_Total_HighWord"] = [0, 0, 0, 0, 0, 0]
178
grp.attrs["NumPart_ThisFile"] = [numPart, 0, 0, 0, 0, 0]
179
180
181
grp.attrs["Time"] = 0.0
grp.attrs["NumFilesPerSnapshot"] = 1
grp.attrs["MassTable"] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
182
grp.attrs["Flag_Entropy_ICs"] = [0, 0, 0, 0, 0, 0]
183
grp.attrs["Dimension"] = 3
184
185
186

#Runtime parameters
grp = file.create_group("/RuntimePars")
187
grp.attrs["PeriodicBoundariesOn"] = 1
188
189
190
191

# write gas particles
grp0   = file.create_group("/PartType0")

192
193
194
195
196
197
ds = grp0.create_dataset('Coordinates', (numPart, 3), 'f', data=pos)
ds = grp0.create_dataset('Velocities', (numPart, 3), 'f')
ds = grp0.create_dataset('Masses', (numPart,), 'f', data=mass)
ds = grp0.create_dataset('SmoothingLength', (numPart,), 'f', data=h)
ds = grp0.create_dataset('InternalEnergy', (numPart,), 'f', data=u)
ds = grp0.create_dataset('ParticleIDs', (numPart, ), 'L', data=ids)
198

199
####################################################################
200

201
202
203
print "--- Runtime parameters (YAML file): ---"
print "DiscPatchPotential:surface_density:    ", surface_density
print "DiscPatchPotential:scale_height:       ", scale_height
204
print "DiscPatchPotential:x_disc:             ", 0.5 * boxSize_x
205
print ""
206

207
208
print "--- Constant parameters: ---"
print "const_isothermal_internal_energy: %ef"%u_therm