def _read_amr_level(self, oct_handler): """Open the oct file, read in octs level-by-level. For each oct, only the position, index, level and domain are needed - its position in the octree is found automatically. The most important is finding all the information to feed oct_handler.add """ self.level_offsets f = open(self.ds._file_amr, "rb") for level in range(1, self.ds.max_level + 1): unitary_center, fl, iocts, nocts, root_level = _read_art_level_info( f, self._level_oct_offsets, level, coarse_grid=self.ds.domain_dimensions[0], root_level=self.ds.root_level, ) nocts_check = oct_handler.add(self.domain_id, level, unitary_center) assert nocts_check == nocts mylog.debug( "Added %07i octs on level %02i, cumulative is %07i", nocts, level, oct_handler.nocts, )
def _parse_parameter_file(self): """ Get the various simulation parameters & constants. """ self.domain_left_edge = np.zeros(3, dtype='float') self.domain_right_edge = np.zeros(3, dtype='float') + 1.0 self.dimensionality = 3 self.refine_by = 2 self.periodicity = (True, True, True) self.cosmological_simulation = True self.parameters = {} self.unique_identifier = \ int(os.stat(self.parameter_filename)[stat.ST_CTIME]) self.parameters.update(constants) self.parameters['Time'] = 1.0 # read the amr header with open(self._file_amr, 'rb') as f: amr_header_vals = fpu.read_attrs(f, amr_header_struct, '>') for to_skip in ['tl', 'dtl', 'tlold', 'dtlold', 'iSO']: fpu.skip(f, endian='>') (self.ncell) = fpu.read_vector(f, 'i', '>')[0] # Try to figure out the root grid dimensions est = int(np.rint(self.ncell**(1.0 / 3.0))) # Note here: this is the number of *cells* on the root grid. # This is not the same as the number of Octs. # domain dimensions is the number of root *cells* self.domain_dimensions = np.ones(3, dtype='int64') * est self.root_grid_mask_offset = f.tell() self.root_nocts = self.domain_dimensions.prod() // 8 self.root_ncells = self.root_nocts * 8 mylog.debug( "Estimating %i cells on a root grid side," + "%i root octs", est, self.root_nocts) self.root_iOctCh = fpu.read_vector(f, 'i', '>')[:self.root_ncells] self.root_iOctCh = self.root_iOctCh.reshape(self.domain_dimensions, order='F') self.root_grid_offset = f.tell() self.root_nhvar = fpu.skip(f, endian='>') self.root_nvar = fpu.skip(f, endian='>') # make sure that the number of root variables is a multiple of # rootcells assert self.root_nhvar % self.root_ncells == 0 assert self.root_nvar % self.root_ncells == 0 self.nhydro_variables = ((self.root_nhvar + self.root_nvar) / self.root_ncells) self.iOctFree, self.nOct = fpu.read_vector(f, 'i', '>') self.child_grid_offset = f.tell() # lextra needs to be loaded as a string, but it's actually # array values. So pop it off here, and then re-insert. lextra = amr_header_vals.pop("lextra") amr_header_vals['lextra'] = np.fromstring(lextra, '>f4') self.parameters.update(amr_header_vals) amr_header_vals = None # estimate the root level float_center, fl, iocts, nocts, root_level = _read_art_level_info( f, [0, self.child_grid_offset], 1, coarse_grid=self.domain_dimensions[0]) del float_center, fl, iocts, nocts self.root_level = root_level mylog.info("Using root level of %02i", self.root_level) # read the particle header self.particle_types = [] self.particle_types_raw = () if not self.skip_particles and self._file_particle_header: with open(self._file_particle_header, "rb") as fh: particle_header_vals = fpu.read_attrs(fh, particle_header_struct, '>') fh.seek(seek_extras) n = particle_header_vals['Nspecies'] wspecies = np.fromfile(fh, dtype='>f', count=10) lspecies = np.fromfile(fh, dtype='>i', count=10) # extras needs to be loaded as a string, but it's actually # array values. So pop it off here, and then re-insert. extras = particle_header_vals.pop("extras") particle_header_vals['extras'] = np.fromstring(extras, '>f4') self.parameters['wspecies'] = wspecies[:n] self.parameters['lspecies'] = lspecies[:n] for specie in range(n): self.particle_types.append("specie%i" % specie) self.particle_types_raw = tuple(self.particle_types) ls_nonzero = np.diff(lspecies)[:n - 1] ls_nonzero = np.append(lspecies[0], ls_nonzero) self.star_type = len(ls_nonzero) mylog.info("Discovered %i species of particles", len(ls_nonzero)) mylog.info("Particle populations: " + '%9i ' * len(ls_nonzero), *ls_nonzero) self._particle_type_counts = dict( zip(self.particle_types_raw, ls_nonzero)) for k, v in particle_header_vals.items(): if k in self.parameters.keys(): if not self.parameters[k] == v: mylog.info("Inconsistent parameter %s %1.1e %1.1e", k, v, self.parameters[k]) else: self.parameters[k] = v self.parameters_particles = particle_header_vals self.parameters.update(particle_header_vals) self.parameters['ng'] = self.parameters['Ngridc'] self.parameters['ncell0'] = self.parameters['ng']**3 # setup standard simulation params yt expects to see self.current_redshift = self.parameters["aexpn"]**-1.0 - 1.0 self.omega_lambda = self.parameters['Oml0'] self.omega_matter = self.parameters['Om0'] self.hubble_constant = self.parameters['hubble'] self.min_level = self.parameters['min_level'] self.max_level = self.parameters['max_level'] if self.limit_level is not None: self.max_level = min(self.limit_level, self.parameters['max_level']) if self.force_max_level is not None: self.max_level = self.force_max_level self.hubble_time = 1.0 / (self.hubble_constant * 100 / 3.08568025e19) self.current_time = self.quan(b2t(self.parameters['t']), 'Gyr') self.gamma = self.parameters["gamma"] mylog.info("Max level is %02i", self.max_level)