コード例 #1
0
ファイル: snapshot.py プロジェクト: shfengcj/concept
 def load(self, filename, compare_params=True, only_params=False):
     # Load all particles
     with h5py.File(filename,
                    mode='r',
                    driver='mpio',
                    comm=comm,
                    ) as hdf5_file:
         # Load used base units
         snapshot_unit_length = eval(hdf5_file.attrs['unit length'], units_dict)
         snapshot_unit_time   = eval(hdf5_file.attrs['unit time'],   units_dict)
         snapshot_unit_mass   = eval(hdf5_file.attrs['unit mass'],   units_dict)
         # Load global attributes
         self.params['a']       = hdf5_file.attrs['a']
         self.params['boxsize'] = hdf5_file.attrs['boxsize']*snapshot_unit_length
         self.params['H0']      = hdf5_file.attrs['H0']*(1/snapshot_unit_time)
         self.params['Ωm']      = hdf5_file.attrs[unicode('Ω') + 'm']
         self.params['ΩΛ']      = hdf5_file.attrs[unicode('Ω') + unicode('Λ')]
         # Check if the parameters of the snapshot
         # matches those of the current simulation run.
         # Display a warning if they do not.
         if compare_params:
             tol = 1e-4
             msg = ''
             if np.abs(self.params['a']/a_begin - 1) > tol:
                 msg += ('\n' + ' '*8 + 'a_begin: {} vs {}'
                         ).format(a_begin, self.params['a'])
             if np.abs(self.params['boxsize']/boxsize - 1) > tol:
                 msg += ('\n' + ' '*8 + 'boxsize: {} vs {} ({})').format(boxsize,
                                                                         self.params['boxsize'],
                                                                         units.length)
             if np.abs(self.params['H0']/H0 - 1) > tol:
                 unit = units.km/(units.s*units.Mpc)
                 msg += ('\n' + ' '*8 + 'H0: {} vs {} ({})').format(H0/unit,
                                                                    self.params['H0']/unit,
                                                                    'km s⁻¹ Mpc⁻¹')
             if np.abs(self.params['Ωm']/Ωm - 1) > tol:
                 msg += ('\n' + ' '*8 + unicode('Ω') + 'm: {} vs {}').format(Ωm,
                                                                             self.params['Ωm'])
             if np.abs(self.params['ΩΛ']/ΩΛ - 1) > tol:
                 msg += ('\n' + ' '*8 + unicode('Ω')
                                      + unicode('Λ') + ': {} vs {}').format(ΩΛ,
                                                                            self.params['ΩΛ'])
             if msg:
                 msg = ('Mismatch between current parameters and those in'
                        + 'the snapshot "{}":{}').format(filename, msg)
                 masterwarn(msg, indent=4)
         # Initialize the particle_attributes dict
         self.params['particle_attributes'] = {}
         # Load particle data
         all_particles = hdf5_file['particles']
         for particle_type in all_particles:
             # Load particle attributes
             particles_h5 = all_particles[particle_type]
             particle_N = particles_h5['posx'].size
             particle_mass = particles_h5.attrs['mass']*snapshot_unit_mass
             particle_species = particles_h5.attrs['species']
             # The keys in the particle_attributes dict are the
             # particle types, and the values are new dicts,
             # containing the information for each type.
             self.params['particle_attributes'][particle_type] = {}
             particle_attribute = self.params['particle_attributes'][particle_type]
             particle_attribute['N']       = particle_N
             particle_attribute['mass']    = particle_mass
             particle_attribute['species'] = particle_species
             # Done loading particle attributes
             if only_params:
                 continue
             # Write out progress message
             masterprint('Loading', particle_N, particle_type,
                         '({}) ...'.format(particle_species),
                         indent=4)
             # Extract HDF5 datasets
             posx_h5 = particles_h5['posx']
             posy_h5 = particles_h5['posy']
             posz_h5 = particles_h5['posz']
             momx_h5 = particles_h5['momx']
             momy_h5 = particles_h5['momy']
             momz_h5 = particles_h5['momz']
             # Compute a fair distribution of 
             # particle data to the processes.
             N_locals = ((particle_N//nprocs, )
                         *(nprocs - (particle_N % nprocs))
                         + (particle_N//nprocs + 1, )*(particle_N % nprocs))
             N_local = N_locals[rank]
             start_local = np.sum(N_locals[:rank], dtype=C2np['Py_ssize_t'])
             end_local = start_local + N_local
             # Construct a Particles instance
             self.particles = construct(particle_type,
                                        particle_species,
                                        mass=particle_mass,
                                        N=particle_N)
             # Populate the Particles instance with data from the file
             self.particles.populate(posx_h5[start_local:end_local], 'posx')
             self.particles.populate(posy_h5[start_local:end_local], 'posy')
             self.particles.populate(posz_h5[start_local:end_local], 'posz')
             self.particles.populate(momx_h5[start_local:end_local], 'momx')
             self.particles.populate(momy_h5[start_local:end_local], 'momy')
             self.particles.populate(momz_h5[start_local:end_local], 'momz')
             # If the snapshot and the current run uses different
             # systems of units, mulitply the particle positions
             # and momenta by the snapshot units.
             if snapshot_unit_length != 1:
                 for i in range(N_local):
                     self.particles.posx[i] *= snapshot_unit_length
                     self.particles.posy[i] *= snapshot_unit_length
                     self.particles.posz[i] *= snapshot_unit_length
             unit = snapshot_unit_length/snapshot_unit_time*snapshot_unit_mass
             if unit != 1:
                 for i in range(N_local):
                     self.particles.momx[i] *= unit
                     self.particles.momy[i] *= unit
                     self.particles.momz[i] *= unit
             # Finalize progress message
             masterprint('done')
     # Update the "contains" string
     if only_params:
         self.contains = 'params'
     else:
         self.contains = 'params and particles'
     # Scatter particles to the correct domain-specific process.
     # Setting reset_indices_send == True ensures that buffers
     # will be reset afterwards, as this initial exchange is not
     # representable for those to come.
     if 'particles' in self.contains:
         exchange(self.particles, reset_buffers=True)
コード例 #2
0
ファイル: generate_IC.py プロジェクト: shfengcj/concept
# Include the concept_dir in the searched paths
import sys, os
sys.path.append(os.environ['concept_dir'])

# Imports from the CO𝘕CEPT code
from commons import *
from species import construct
from snapshot import save

# Create close to homogeneous particles
N = 4**3
mass = Ωm*ϱ*boxsize**3/N
mean_sep = boxsize/N**(1/3)
max_mom = 0.5e+10*units.kpc/units.Gyr*units.m_sun
particles = construct('dark matter particles', 'dark matter', mass, N)
posx = zeros(N)
posy = zeros(N)
posz = zeros(N)
momx = zeros(N)
momy = zeros(N)
momz = zeros(N)
count = 0
for i in range(round(N**(1/3))):
    for j in range(round(N**(1/3))):
        for k in range(round(N**(1/3))):
            x = (i/N**(1/3)*boxsize + (random()*2 - 1)*mean_sep*0.1) % boxsize
            y = (j/N**(1/3)*boxsize + (random()*2 - 1)*mean_sep*0.1) % boxsize
            z = (k/N**(1/3)*boxsize + (random()*2 - 1)*mean_sep*0.1) % boxsize
            posx[count] = x
            posy[count] = y
コード例 #3
0
ファイル: snapshot.py プロジェクト: shfengcj/concept
 def load(self, filename, compare_params=True, only_params=False):
     """ It is assumed that the snapshot on the disk is a GADGET
     snapshot of type 2 and that it uses single precision. The
     GadgetSnapshot instance stores the data (positions and
     velocities) in double precision. Only GADGET type 1 (halo)
     particles, corresponding to dark matter particles,
     are supported.
     """
     # Only type 1 (halo) particles are supported
     particle_species = 'dark matter'
     particle_type = 'GADGET halos'
     # Read in the snapshot
     offset = 0
     with open(filename, 'rb') as f:
         # Read the HEAD block into a params['header'] dict.
         # No unit conversion will be done.
         offset = self.new_block(f, offset)
         name = self.read(f, '4s').decode('utf8')  # "HEAD"
         size = self.read(f, 'i')  # 264
         offset = self.new_block(f, offset)
         self.params['header'] = collections.OrderedDict()
         header = self.params['header']
         header['Npart']         = self.read(f, '6I')
         header['Massarr']       = self.read(f, '6d')
         header['Time']          = self.read(f, 'd')
         header['Redshift']      = self.read(f, 'd')
         header['FlagSfr']       = self.read(f, 'i')
         header['FlagFeedback']  = self.read(f, 'i')
         header['Nall']          = self.read(f, '6i')
         header['FlagCooling']   = self.read(f, 'i')
         header['NumFiles']      = self.read(f, 'i')
         header['BoxSize']       = self.read(f, 'd')
         header['Omega0']        = self.read(f, 'd')
         header['OmegaLambda']   = self.read(f, 'd')
         header['HubbleParam']   = self.read(f, 'd')
         header['FlagAge']       = self.read(f, 'i')
         header['FlagMetals']    = self.read(f, 'i')
         header['NallHW']        = self.read(f, '6i')
         header['flag_entr_ics'] = self.read(f, 'i')
         # Also include some of the header fields as parameters
         # directly in the params dict.
         self.params['a']       = header['Time']
         unit = units.kpc/header['HubbleParam']
         self.params['boxsize'] = header['BoxSize']*unit
         unit = 100*units.km/(units.s*units.Mpc)
         self.params['H0']      = header['HubbleParam']*unit
         self.params['Ωm']      = header['Omega0']
         self.params['ΩΛ']      = header['OmegaLambda']
         # Check if the parameters of the snapshot matches
         # those of the current simulation run. Display a warning
         # if they do not.
         if compare_params:
             tol = 1e-4
             msg = ''
             if np.abs(self.params['a']/a_begin - 1) > tol:
                 msg += '\n' + ' '*8 + 'a_begin: {} vs {}'.format(a_begin, self.params['a'])
             if np.abs(self.params['boxsize']/boxsize - 1) > tol:
                 msg += ('\n' + ' '*8 + 'boxsize: {} vs {} ({})').format(boxsize,
                                                                         self.params['boxsize'],
                                                                         units.length)
             if np.abs(self.params['H0']/H0 - 1) > tol:
                 unit = units.km/(units.s*units.Mpc)
                 msg += ('\n' + ' '*8 + 'H0: {} vs {} ({})').format(H0/unit,
                                                                    self.params['H0']/unit,
                                                                    'km s⁻¹ Mpc⁻¹')
             if np.abs(self.params['Ωm']/Ωm - 1) > tol:
                 msg += ('\n' + ' '*8 + unicode('Ω') + 'm: {} vs {}').format(Ωm,
                                                                             self.params['Ωm'])
             if np.abs(self.params['ΩΛ']/ΩΛ - 1) > tol:
                 msg += ('\n' + ' '*8 + unicode('Ω')
                                      + unicode('Λ') + '{} vs {}').format(ΩΛ,
                                                                          self.params['ΩΛ'])
             if msg:
                 msg = ('Mismatch between current parameters and those in '
                        + 'the GADGET snapshot '
                        + '"{}":{}').format(filename, msg)
                 masterwarn(msg, indent=4)
         # Initialize the particle_attributes dict
         self.params['particle_attributes'] = {}
         # The keys in the particle_attributes dict are the
         # particle types, and the values are new dicts,
         # containing the information for each type.
         self.params['particle_attributes'][particle_type] = {}
         particle_attribute = (self.params['particle_attributes']
                                          [particle_type])
         N = header['Npart'][1]
         particle_attribute['N'] = N
         unit = 1e+10*units.m_sun/header['HubbleParam']
         mass = header['Massarr'][1]*unit
         particle_attribute['mass'] = mass
         particle_attribute['species'] = particle_species
         # Done loading particle attributes
         if only_params:
             self.contains = 'params'
             return
         # Write out progress message
         masterprint('Loading', N, particle_type, '({}) ...'.format(particle_species), indent=4)
         # Compute a fair distribution
         # of particle data to the processes.
         N_locals = ((N//nprocs, )*(nprocs - (N % nprocs))
                     + (N//nprocs + 1, )*(N % nprocs))
         N_local = N_locals[rank]
         start_local = np.sum(N_locals[:rank], dtype=C2np['Py_ssize_t'])
         # Construct a Particles instance
         self.particles = construct(particle_type, particle_species, mass=mass, N=N)
         # Read in the POS block. The positions are given in kpc/h.
         offset = self.new_block(f, offset)
         unit = units.kpc/header['HubbleParam']
         name = self.read(f, '4s').decode('utf8')  # "POS "
         size = self.read(f, 'i')
         offset = self.new_block(f, offset)
         f.seek(12*start_local, 1)  # 12 = sizeof(float)*Ndims
         file_position = f.tell()
         self.particles.populate(asarray(np.fromfile(f, dtype=C2np['float'], count=3*N_local)
                                         [0::3], dtype=C2np['double'])*unit,
                                 'posx')
         f.seek(file_position)
         self.particles.populate(asarray(np.fromfile(f, dtype=C2np['float'], count=3*N_local)
                                         [1::3], dtype=C2np['double'])*unit,
                                 'posy')
         f.seek(file_position)
         self.particles.populate(asarray(np.fromfile(f, dtype=C2np['float'], count=3*N_local)
                                         [2::3], dtype=C2np['double'])*unit,
                                 'posz')
         # Read in the VEL block. The velocities are peculiar
         # velocities u=a*dx/dt divided by sqrt(a), given in km/s.
         offset = self.new_block(f, offset)
         unit = units.km/units.s*mass*header['Time']**1.5
         name = self.read(f, '4s').decode('utf8')  # "VEL "
         size = self.read(f, 'i')
         offset = self.new_block(f, offset)
         f.seek(12*start_local, 1)  # 12 = sizeof(float)*Ndims
         file_position = f.tell()
         self.particles.populate(asarray(np.fromfile(f, dtype=C2np['float'], count=3*N_local)
                                         [0::3], dtype=C2np['double'])*unit,
                                 'momx')
         f.seek(file_position)
         self.particles.populate(asarray(np.fromfile(f, dtype=C2np['float'], count=3*N_local)
                                         [1::3], dtype=C2np['double'])*unit,
                                 'momy')
         f.seek(file_position)
         self.particles.populate(asarray(np.fromfile(f, dtype=C2np['float'], count=3*N_local)
                                         [2::3], dtype=C2np['double'])*unit,
                                 'momz')
         # Read in the ID block.
         # The ID's will be distributed among all processes.
         offset = self.new_block(f, offset)
         name = self.read(f, '4s').decode('utf8')  # "ID  "
         size = self.read(f, 'i')
         offset = self.new_block(f, offset)
         f.seek(4*start_local, 1)  # 4 = sizeof(unsigned int)
         file_position = f.tell()
         self.ID = np.fromfile(f, dtype=C2np['unsigned int'], count=N_local)
         # Finalize progress message
         masterprint('done')
         # Possible additional meta data ignored
     # Update the "contains" string
     self.contains = 'params and particles'
     # Scatter particles to the correct domain-specific process.
     # Setting reset_indices_send == True ensures that buffers
     # will be reset afterwards, as this initial exchange is not
     # representable for those to come.
     exchange(self.particles, reset_buffers=True)
コード例 #4
0
ファイル: generate_IC.py プロジェクト: shfengcj/concept

# This file has to be run in pure Python mode!

# Include the concept_dir in the searched paths
import sys, os

sys.path.append(os.environ["concept_dir"])

# Imports from the CO𝘕CEPT code
from commons import *
from species import construct
from snapshot import save

# Create the particles.
# It is important that no interparticle separation exceeds boxsize/2 in
# any direction, as the nearest particle image in all cases must be the
# actual particle itself.
N = 8
mass = Ωm * ϱ * boxsize ** 3 / N
particles = construct("dark matter particles", "dark matter", mass, N)
particles.populate(array([0.26] * 4 + [0.74] * 4) * boxsize, "posx")
particles.populate(array([0.25, 0.25, 0.75, 0.75] * 2) * boxsize, "posy")
particles.populate(array([0.25, 0.75, 0.75, 0.25] * 2) * boxsize, "posz")
particles.populate(zeros(N), "momx")
particles.populate(zeros(N), "momy")
particles.populate(zeros(N), "momz")

# Save snapshot
save(particles, a_begin, IC_file)