예제 #1
0
    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()
예제 #2
0
    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)
예제 #3
0
    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 )
예제 #4
0
    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()
예제 #5
0
    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()
예제 #6
0
    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__()
예제 #7
0
    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__()