def __init__(self): """ Initialization for all slab classes """ # attach units #----------------------------------------------- self.U = units.Units() # check input #----------------------------------------------- assert (self.Edges.size == self.T.size + 1) assert (self.T.shape == self.nH.shape == self.nHe.shape) assert (self.T.shape == (self.T.size, )) assert (self.rec_meth == 'fixed' or self.rec_meth == 'ray') if self.find_Teq and self.z == None: msg = 'need to supply redshift if finding equilibrium temperature' raise utils.InputError(msg) # set units #----------------------------------------------- self.Edges.units = 'cm' self.T.units = 'K' self.nH.units = '1.0/cm^3' self.nHe.units = '1.0/cm^3' # format input #----------------------------------------------- self.format_for_fortran()
def validate_spectrum_type(self): """ Performs check to make sure the input is compatible with the source type. """ if not self.spectrum_type in ValidSpectrumTypes: msg = '\nspectrum_type = ' + self.spectrum_type + ' \n' msg += 'spectrum_type must be one of: ' msg += str(ValidSpectrumTypes) raise utils.InputError(msg) if self.spectrum_type == 'hm12': if self.z == None: msg = '\nif source type = hm12, must provide z' raise utils.InputError(msg) if self.spectrum_type == 'thermal': if self.T_eff == None: msg = '\nif source type = thermal, must provide T_eff' raise utils.InputError(msg) if self.spectrum_type == 'powerlaw': if self.alpha == None: msg = '\nif source type = powerlaw, must provide alpha' raise utils.InputError(msg) if self.spectrum_type == 'monochromatic': if self.q_min != self.q_max: msg = '\nsource type = monochromatic, but q_min != q_max' raise utils.InputError(msg) if self.spectrum_type == 'user': if self.user_E is None: msg = '\nif source type = user, must provide user_E' raise utils.InputError(msg) if self.user_shape is None: msg = '\nif source type = user, must provide user_shape' raise utils.InputError(msg) if self.user_E.size != self.user_shape.size: msg = '\n E and shape muse be same size for source_type = user' raise utils.InputError(msg)
def __init__(self, fit_type='verner' ): self.fit_type = fit_type self.VALID_FITS = ['verner'] if self.fit_type == 'verner': self.v96 = verner_photox.PhotoXsections_Verner96() self.Eth_H1 = self.v96.return_Eth( 1,1 ) self.Eth_He1 = self.v96.return_Eth( 2,2 ) self.Eth_He2 = self.v96.return_Eth( 2,1 ) else: msg = 'PhotoX fit_type not recognized\n' + \ 'fit_type: ' + fit_type + '\n' + \ 'valid fit types: ' + str(self.VALID_FITS) + '\n' raise utils.InputError( msg ) self.sigma_H1th = self.sigma_th( 1, 1 ) self.sigma_He1th = self.sigma_th( 2, 2 ) self.sigma_He2th = self.sigma_th( 2, 1 )
def __init__( self, Edges, T, nH, nHe, rad_src, # rec_meth="fixed", fixed_fcA=1.0, atomic_fit_name="hg97", find_Teq=False, z=None, verbose=False, tol=1.0e-10, thin=False, ): # attach units #----------------------------------------------- self.U = units.Units() # check input #----------------------------------------------- assert (Edges.size == T.size + 1) assert (T.shape == nH.shape == nHe.shape) assert (T.shape == (T.size, )) assert (rec_meth == 'fixed') if find_Teq and z == None: msg = 'need to supply redshift if finding equilibrium temperature' raise utils.InputError(msg) if rad_src.source_type != 'point': msg = 'source type needs to be point' raise utils.InputError(msg) # set units #----------------------------------------------- Edges.units = 'cm' T.units = 'K' nH.units = '1.0/cm^3' nHe.units = '1.0/cm^3' # attach input #----------------------------------------------- self.Edges = Edges.copy() self.T = T.copy() self.nH = nH.copy() self.nHe = nHe.copy() self.rad_src = rad_src self.rec_meth = rec_meth if self.rec_meth == 'fixed': self.fixed_fcA = fixed_fcA self.atomic_fit_name = atomic_fit_name self.find_Teq = find_Teq self.verbose = verbose self.tol = tol self.thin = thin if find_Teq: self.z = z # initialize sphere #----------------------------------------------- self.init_sphere() self.set_optically_thin() if self.thin: return # solve sphere (sweep until convergence) #----------------------------------------------------------- conv_old = np.sum(self.ne) not_converged = True self.itr = 0 while not_converged: self.sweep_sphere() conv_new = np.sum(self.ne) if np.abs(conv_new / conv_old - 1.0) < self.tol: not_converged = False conv_old = conv_new self.itr += 1 # finalize slab #----------------------------------------------------------- self.finalize_sphere()
def __init__( self, Edges, T, nH, nHe, rad_src, # rec_meth="fixed", fixed_fcA=1.0, thresh_P_A=0.01, thresh_P_B=0.99, thresh_xmfp=3.0e1, atomic_fit_name="hg97", find_Teq=False, z=None, verbose=False, tol=1.0e-10, thin=False): # attach units #----------------------------------------------- self.U = units.Units() # check input #----------------------------------------------- assert (Edges.size == T.size + 1) assert (T.shape == nH.shape == nHe.shape) assert (T.shape == (T.size, )) assert (rec_meth == 'fixed' or rec_meth == 'thresh') if find_Teq and z == None: msg = 'need to supply redshift if finding equilibrium temperature' raise utils.InputError(msg) if rad_src.source_type != 'plane': msg = 'source type needs to be plane' raise utils.InputError(msg) if nH.size % 2 != 0: msg = 'the number of layers must be even' raise utils.InputError(msg) # set units #----------------------------------------------- Edges.units = 'cm' T.units = 'K' nH.units = '1.0/cm^3' nHe.units = '1.0/cm^3' # attach input #----------------------------------------------- self.Edges = Edges.copy() self.T = T.copy() self.nH = nH.copy() self.nHe = nHe.copy() self.rad_src = rad_src self.rec_meth = rec_meth if self.rec_meth == 'fixed': self.fixed_fcA = fixed_fcA elif self.rec_meth == 'thresh': assert thresh_xmfp > 0.0 assert thresh_P_B > thresh_P_A self.thresh_xmfp = thresh_xmfp self.thresh_P_A = thresh_P_A self.thresh_P_B = thresh_P_B self.thresh_dPAB = thresh_P_B - thresh_P_A self.thresh_tau_A = -np.log(1.0 - thresh_P_A) self.thresh_tau_B = -np.log(1.0 - thresh_P_B) self.atomic_fit_name = atomic_fit_name self.find_Teq = find_Teq self.verbose = verbose self.tol = tol self.thin = thin if find_Teq: self.z = z # initialize slab #----------------------------------------------- self.init_slab() self.set_optically_thin() if self.thin: return # solve slab, sweep through layers until convergence #----------------------------------------------------------- conv_old = np.sum(self.ne) not_converged = True self.itr = 0 while not_converged: self.sweep_slab() conv_new = np.sum(self.ne) if np.abs(conv_new / conv_old - 1.0) < self.tol: not_converged = False conv_old = conv_new self.itr += 1 # finalize slab #----------------------------------------------------------- self.finalize_slab()
def __init__( self, Edges, T, nH, nHe, rad_src, # rec_meth="fixed", fixed_fcA=1.0, atomic_fit_name="hg97", find_Teq=False, z=None, Hz=None, verbose=False, tol=1.0e-4, thin=False, i_rec_ems_prf=0): # initialize #----------------------------------------------- self.Edges = Edges.copy() self.T = T.copy() self.nH = nH.copy() self.nHe = nHe.copy() self.rad_src = rad_src self.rec_meth = rec_meth self.fixed_fcA = fixed_fcA self.atomic_fit_name = atomic_fit_name self.find_Teq = find_Teq self.verbose = verbose self.tol = tol self.thin = thin self.i_rec_ems_prf = i_rec_ems_prf if find_Teq: self.z = z else: self.z = 0 # call base class init #----------------------------------------------- super(Slab2Pln, self).__init__() if Hz == None: self.Hz = 0.0 / self.U.s else: self.Hz = Hz self.Hz.units = '1/s' # check for even number of layers #----------------------------------------------- if self.nH.size % 2 != 0: msg = 'the number of layers must be even' raise utils.InputError(msg) # call the fortran solver routine #----------------------------------------------- self.i_2side = 1 (xH1, xH2, xHe1, xHe2, xHe3, H1i_src, He1i_src, He2i_src, H1i_rec, He1i_rec, He2i_rec, H1h_src, He1h_src, He2h_src, H1h_rec, He1h_rec, He2h_rec) = \ rabacus_fc.slab_plane.slab_plane_solve( self.Edges, self.nH, self.nHe, self.T, self.E_eV, self.shape, self.i_2side, self.i_rec_meth, self.fixed_fcA, self.i_photo_fit, self.i_rate_fit, self.i_find_Teq, self.i_thin, self.z, self.Hz, self.tol, self.Nl, self.Nnu ) # attach output with units. #----------------------------------------------- self.xH1 = xH1 self.xH2 = xH2 self.xHe1 = xHe1 self.xHe2 = xHe2 self.xHe3 = xHe3 self.H1i_src = H1i_src / self.U.s self.He1i_src = He1i_src / self.U.s self.He2i_src = He2i_src / self.U.s self.H1i_rec = H1i_rec / self.U.s self.He1i_rec = He1i_rec / self.U.s self.He2i_rec = He2i_rec / self.U.s self.H1i = self.H1i_src + self.H1i_rec self.He1i = self.He1i_src + self.He1i_rec self.He2i = self.He2i_src + self.He2i_rec self.H1h_src = H1h_src * self.U.erg / self.U.s self.He1h_src = He1h_src * self.U.erg / self.U.s self.He2h_src = He2h_src * self.U.erg / self.U.s self.H1h_rec = H1h_rec * self.U.erg / self.U.s self.He1h_rec = He1h_rec * self.U.erg / self.U.s self.He2h_rec = He2h_rec * self.U.erg / self.U.s self.H1h = self.H1h_src + self.H1h_rec self.He1h = self.He1h_src + self.He1h_rec self.He2h = self.He2h_src + self.He2h_rec # do post-calculation #----------------------------------------------- super(Slab2Pln, self).__post__()
def __init__( self, Edges, T, nH, nHe, rad_src, # rec_meth="fixed", fixed_fcA=1.0, atomic_fit_name="hg97", find_Teq=False, z=None, Hz=None, verbose=False, tol=1.0e-4, thin=False, ): # initialize #----------------------------------------------- self.Edges = Edges.copy() self.T = T.copy() self.nH = nH.copy() self.nHe = nHe.copy() self.rad_src = rad_src self.rec_meth = rec_meth self.fixed_fcA = fixed_fcA self.atomic_fit_name = atomic_fit_name self.find_Teq = find_Teq self.verbose = verbose self.tol = tol self.thin = thin if z != None: self.z = z else: self.z = 0.0 # call base class init #----------------------------------------------- super(Slab2Bgnd, self).__init__() if Hz == None: self.Hz = 0.0 / self.U.s else: self.Hz = Hz self.Hz.units = '1/s' # check for even number of layers #----------------------------------------------- if self.nH.size % 2 != 0: msg = 'the number of layers must be even' raise utils.InputError(msg) # call solver #----------------------------------------------- self.call_fortran_solver() # do post-calculation #----------------------------------------------- super(Slab2Bgnd, self).__post__()