def cambfile(self) -> str: """ Generate the IC power spectrum using classylss. Basically is using pre_params feed into class and compute the powerspec files based on the range of redshift and redend. All files are stored in the directory camb_out. Return: ---- camb_output (str) : power specs directory. default: "camb_linear/" """ #Load high precision defaults pre_params = { 'tol_background_integration': 1e-9, 'tol_perturb_integration' : 1.e-7, 'tol_thermo_integration':1.e-5, 'k_per_decade_for_pk': 50,'k_bao_width': 8, 'k_per_decade_for_bao': 200, 'neglect_CMB_sources_below_visibility' : 1.e-30, 'transfer_neglect_late_source': 3000., 'l_max_g' : 50, 'l_max_ur':150, 'extra metric transfer functions': 'y'} #Set the neutrino density and subtract it from omega0 omeganu = self.m_nu/93.14/self.hubble**2 omcdm = (self.omega0 - self.omegab) - omeganu gparams = {'h': self.hubble, 'Omega_cdm': omcdm,'Omega_b': self.omegab, 'Omega_k': 0, 'n_s': self.ns, 'A_s': self.scalar_amp} #Lambda is computed self-consistently gparams['Omega_fld'] = 0 numass = get_neutrino_masses(self.m_nu, self.nu_hierarchy) #Set up massive neutrinos if self.m_nu > 0: gparams['m_ncdm'] = '%.8f,%.8f,%.8f' % (numass[2], numass[1], numass[0]) gparams['N_ncdm'] = 3 gparams['N_ur'] = 0.00641 #Neutrino accuracy: Default pk_ref.pre has tol_ncdm_* = 1e-10, #which takes 45 minutes (!) on my laptop. #tol_ncdm_* = 1e-8 takes 20 minutes and is machine-accurate. #Default parameters are fast but off by 2%. #I chose 1e-5, which takes 6 minutes and is accurate to 1e-5 gparams['tol_ncdm_newtonian'] = min(self.nu_acc,1e-5) gparams['tol_ncdm_synchronous'] = self.nu_acc gparams['tol_ncdm_bg'] = 1e-10 gparams['l_max_ncdm'] = 50 #This disables the fluid approximations, which make P_nu not match # camb on small scales. #We need accurate P_nu to initialise our neutrino code. gparams['ncdm_fluid_approximation'] = 2 #Does nothing unless ncdm_fluid_approximation = 2 #Spend less time on neutrino power for smaller neutrino mass gparams['ncdm_fluid_trigger_tau_over_tau_k'] = 30000.* (self.m_nu / 0.4) else: gparams['N_ur'] = 3.046 #Initial cosmology pre_params.update(gparams) maxk = 2 * math.pi / self.box * self.npart * 8 powerparams = {'output': 'dTk vTk mPk', 'P_k_max_h/Mpc' : maxk, "z_max_pk" : self.redshift + 1} pre_params.update(powerparams) #At which redshifts should we produce CAMB output: we want the start and # end redshifts of the simulation, but we also want some other values # for checking purposes camb_zz = np.concatenate( [ [self.redshift,], 1 / self.generate_times() - 1, [self.redend,] ] ) cambpars = os.path.join(self.outdir, "_class_params.ini") classconf = configobj.ConfigObj() classconf.filename = cambpars classconf.update(pre_params) classconf['z_pk'] = camb_zz classconf.write() # feed in the parameters and generate the powerspec object engine = CLASS.ClassEngine(pre_params) powspec = CLASS.Spectra(engine) # powerspec is an object #Save directory camb_output = "camb_linear/" camb_outdir = os.path.join(self.outdir, camb_output) try: os.mkdir(camb_outdir) except FileExistsError: pass #Save directory #Get and save the transfer functions for zz in camb_zz: trans = powspec.get_transfer(z=zz) #fp-roundoff trans['k'][-1] *= 0.9999 transferfile = os.path.join( camb_outdir, "ics_transfer_" + self._camb_zstr(zz) + ".dat") save_transfer(trans, transferfile) pk_lin = powspec.get_pklin(k=trans['k'], z=zz) pkfile = os.path.join( camb_outdir, "ics_matterpow_" + self._camb_zstr(zz) + ".dat") np.savetxt(pkfile, np.vstack([trans['k'], pk_lin]).T) return camb_output
'h': 0.6711, 'N_ur': 3.046, 'omega_b': 0.022068, 'omega_cdm': 0.12029, # 'Omega_cdm': 0.32, # 'Omega_k': 0., 'P_k_max_1/Mpc': 3.0, # 'N_ncdm': 3, # 'm_ncdm': str(nuMasses[0])+','+str(nuMasses[1])+','+str(nuMasses[2]), # 'deg_ncdm': '1, 1, 1', 'non linear': 'none,halofit', 'z_max_pk': 100., # 'z_pk': '0.,5.' } engine = CLASS.ClassEngine(params) #pre_params = classylss.load_precision('pk_ref.pre') #print(pre_params) #high_pre_engine = CLASS.ClassEngine(pre_params) # initialize the background module bg = CLASS.Background(engine) # print out some cosmological parameters print("h = ", bg.h) print("Omega0_m = ", bg.Omega0_m) print("Omega0_lambda = ", bg.Omega0_lambda) print("Omega0_r = ", bg.Omega0_r) print("Omega0_k = ", bg.Omega0_k)
def make_class_power(paramfile, external_pk=None, extraz=None, verbose=False): """Main routine: parses a parameter file and makes a matter power spectrum. Will not over-write power spectra if already present. Options are loaded from the MP-GenIC parameter file. Supported: - Omega_fld and DE parameters. - Massive neutrinos. - Using Sigma8 to set the power spectrum scale. - Different transfer functions. We use class velocity transfer functions to have accurate initial conditions even on superhorizon scales, and to properly support multiple species. The alternative is to use rescaling. Not supported: - Warm dark matter power spectra. - Rescaling with different transfer functions.""" config = configobj.ConfigObj(infile=paramfile, configspec=GenICconfigspec, file_error=True) #Input sanitisation _check_genic_config(config) #Precision pre_params = { 'tol_background_integration': 1e-9, 'tol_perturb_integration': 1.e-7, 'tol_thermo_integration': 1.e-5, 'k_per_decade_for_pk': 50, 'k_bao_width': 8, 'k_per_decade_for_bao': 200, 'neglect_CMB_sources_below_visibility': 1.e-30, 'transfer_neglect_late_source': 3000., 'l_max_g': 50, 'l_max_ur': 150 } #Important! Densities are in synchronous gauge! pre_params['gauge'] = 'synchronous' gparams = _build_cosmology_params(config) pre_params.update(gparams) redshift = config['Redshift'] if config['InputPowerRedshift'] >= 0: redshift = config['InputPowerRedshift'] outputs = redshift if extraz is not None: outputs = [ outputs, ] + extraz #Pass options for the power spectrum MPC_in_cm = 3.085678e24 boxmpc = config['BoxSize'] / MPC_in_cm * config['UnitLength_in_cm'] maxk = max(10, 2 * math.pi / boxmpc * config['Ngrid'] * 4) #CLASS needs the first redshift to be relatively high for some internal interpolation reasons maxz = max(1 + np.max(outputs), 99) powerparams = { 'output': 'dTk vTk mPk', 'P_k_max_h/Mpc': maxk, "z_max_pk": maxz, 'z_pk': outputs, 'extra metric transfer functions': 'y' } pre_params.update(powerparams) if verbose: verb_params = { 'input_verbose': 1, 'background_verbose': 1, 'thermodynamics_verbose': 1, 'perturbations_verbose': 1, 'transfer_verbose': 1, 'primordial_verbose': 1, 'spectra_verbose': 1, 'nonlinear_verbose': 1, 'lensing_verbose': 1, 'output_verbose': 1 } pre_params.update(verb_params) #Specify an external primordial power spectrum if external_pk is not None: pre_params['P_k_ini'] = "external_pk" pre_params["command"] = "cat ", external_pk #Print the class parameters to terminal in a format #readable by the command line class. if verbose: for k in pre_params: print(k, '=', pre_params[k]) if 'ncdm_fluid_approximation' in pre_params: print( 'Starting CLASS power spectrum with accurate P(k) for massive neutrinos.' ) print('Computation may take several minutes') #Make the power spectra module engine = CLASS.ClassEngine(pre_params) powspec = CLASS.Spectra(engine) print("sigma_8(z=0) = ", powspec.sigma8, "A_s = ", powspec.A_s) #Save directory sdir = os.path.split(paramfile)[0] #Get and save the transfer functions if needed trans = powspec.get_transfer(z=redshift) if config['DifferentTransferFunctions'] == 1.: tfile = os.path.join(sdir, config['FileWithTransferFunction']) if os.path.exists(tfile): raise IOError("Refusing to write to existing file: ", tfile) save_transfer(trans, tfile) #fp-roundoff trans['k'][-1] *= 0.9999 #Get and save the matter power spectrum pk_lin = powspec.get_pklin(k=trans['k'], z=redshift) pkfile = os.path.join(sdir, config['FileWithInputSpectrum']) if os.path.exists(pkfile): raise IOError("Refusing to write to existing file: ", pkfile) np.savetxt(pkfile, np.vstack([trans['k'], pk_lin]).T) if extraz is not None: for red in extraz: trans = powspec.get_transfer(z=red) tfile = os.path.join( sdir, config['FileWithTransferFunction'] + "-" + str(red)) if os.path.exists(tfile): raise IOError("Refusing to write to existing file: ", tfile) save_transfer(trans, tfile) trans['k'][-1] *= 0.9999 #Get and save the matter power spectrum pk_lin = powspec.get_pklin(k=trans['k'], z=red) pkfile = os.path.join( sdir, config['FileWithInputSpectrum'] + "-" + str(red)) if os.path.exists(pkfile): raise IOError("Refusing to write to existing file: ", pkfile) np.savetxt(pkfile, np.vstack([trans['k'], pk_lin]).T)