Esempio n. 1
0
    def Qsca( self, E, a=1.0, cm=cmi.CmDrude() ):

        if np.size(a) != 1:
            print 'Error: Must specify only 1 value of a'
            return

        a_cm = a * c.micron2cm()        # cm -- Can only be a single value
        lam  = c.kev2lam() / E          # cm -- Can be many values
        x    = 2.0 * np.pi * a_cm / lam
        mm1  = cm.rp(E) - 1 + 1j * cm.ip(E)
        return 2.0 * np.power( x, 2 ) * np.power( np.abs(mm1), 2 )
Esempio n. 2
0
    def __init__( self ):
        self.cmtype = 'Silicate'

        D03vals = c.restore( os.path.join(CMROOT,'CM_D03.pysav'))      # look up file
        
        lamvals = D03vals['Sil_lam']
        revals  = D03vals['Sil_re']
        imvals  = D03vals['Sil_im']
        
        lamEvals = c.kev2lam() / c.micron2cm() / lamvals # keV
        self.rp  = interp1d( lamEvals, revals )
        self.ip  = interp1d( lamEvals, imvals )
Esempio n. 3
0
    def __init__( self ):
        self.cmtype = 'Silicate'

        D03file = find_cmfile('CM_D03.pysav')
        D03vals = c.restore(D03file)      # look up file
        
        lamvals = D03vals['Sil_lam']
        revals  = D03vals['Sil_re']
        imvals  = D03vals['Sil_im']
        
        lamEvals = c.kev2lam() / c.micron2cm() / lamvals # keV
        self.rp  = interp1d( lamEvals, revals )
        self.ip  = interp1d( lamEvals, imvals )
Esempio n. 4
0
    def Diff( self, theta, E=1.0, a=1.0, cm=cmi.CmDrude() ):
        
        cgeo = np.pi * np.power( a*c.micron2cm(), 2 )
                           
        if np.size(a) != 1:
            print 'Error: Must specify only 1 value of a'
            return
        if np.logical_and( np.size(E) > 1, np.size(E) != np.size(theta) ):
            print 'Error: E and theta must have same size if np.size(E) > 1'
            return

        dQ  = self.getQs( a=a, E=E, cm=cm, getQ='diff', theta=theta )
                           
        return dQ * cgeo
Esempio n. 5
0
    def __init__( self, E=1.0, scatm=Scatmodel(), dist=dust.Dustspectrum() ):
        self.scatm  = scatm
        self.E      = E
        self.dist   = dist

        if scatm.stype == 'RG':
            print 'Rayleigh-Gans cross-section not currently supported for Kappaext'
            self.kappa = None
            return

        cm   = scatm.cmodel
        scat = scatm.smodel

        cgeo = np.pi * np.power( dist.a * c.micron2cm(), 2 )

        qext    = np.zeros( shape=( np.size(E),np.size(dist.a) )  )
        qext_pe = np.zeros( shape=( np.size(E),np.size(dist.a) )  )
        qext_pa = np.zeros( shape=( np.size(E),np.size(dist.a) )  )
                                
        # Test for graphite case
        if cm.cmtype == 'Graphite':
            cmGraphitePerp = cmi.CmGraphite(size=cm.size, orient='perp')
            cmGraphitePara = cmi.CmGraphite(size=cm.size, orient='para')

            if np.size(dist.a) > 1:
                for i in range( np.size(dist.a) ):
                    qext_pe[:,i] = scat.Qext( E, a=dist.a[i], cm=cmGraphitePerp )
                    qext_pa[:,i] = scat.Qext( E, a=dist.a[i], cm=cmGraphitePara )
            else:
                qext_pe = scat.Qext( E, a=dist.a, cm=cmGraphitePerp )
                qext_pa = scat.Qext( E, a=dist.a, cm=cmGraphitePara )
            
            qext    = ( qext_pa + 2.0 * qext_pe ) / 3.0

        else:
            if np.size(dist.a) > 1:
                for i in range( np.size(dist.a) ):
                    qext[:,i] = scat.Qext( E, a=dist.a[i], cm=cm )
            else:
                qext = scat.Qext( E, a=dist.a, cm=cm )

        if np.size(dist.a) == 1:
            kappa = dist.nd * qext * cgeo / dist.md
        else:
            kappa = np.array([])
            for j in range( np.size(E) ):
                kappa = np.append( kappa, \
                                   c.intz( dist.a, dist.nd * qext[j,:] * cgeo ) / dist.md )

        self.kappa = kappa
Esempio n. 6
0
    def Diff( self, theta, E=1.0, a=1.0, cm=cmi.CmDrude() ): # cm^2 ster^-1
        
        if np.size(a) != 1:
            print 'Error: Must specify only 1 value of a'
            return
        if np.logical_and( np.size(E) > 1,                  # If more than 1 energy is specified
                           np.size(E) != np.size(theta) ):  # theta must be of the same size
            print 'Error: If specifying > 1 energy, must have same number of values for theta'
            return

        a_cm  = a * c.micron2cm()      # cm -- Can only be a single value
        lam   = c.kev2lam() / E   # cm
        x     = 2.0 * np.pi * a_cm / lam
        mm1   = cm.rp(E) + 1j * cm.ip(E) - 1
        thdep = 2./9. * np.exp( -np.power( theta/self.Char(a=a, E=E) , 2 ) / 2.0 )
        dsig  = 2.0 * np.power(a_cm,2) * np.power(x,4) * np.power( np.abs(mm1),2 )
        return dsig * thdep
Esempio n. 7
0
    def __init__( self, E=1.0, scatm=Scatmodel(), dist=dust.Dustspectrum() ):
        self.scatm  = scatm
        self.E      = E
        self.dist   = dist

        cm   = scatm.cmodel
        scat = scatm.smodel

        cgeo = np.pi * np.power( dist.a * c.micron2cm(), 2 )

        qsca    = np.zeros( shape=( np.size(E),np.size(dist.a) )  )
        qsca_pe = np.zeros( shape=( np.size(E),np.size(dist.a) )  )
        qsca_pa = np.zeros( shape=( np.size(E),np.size(dist.a) )  )
                                
        # Test for graphite case
        if cm.cmtype == 'Graphite':
            cmGraphitePerp = cmi.CmGraphite(size=cm.size, orient='perp')
            cmGraphitePara = cmi.CmGraphite(size=cm.size, orient='para')

            if np.size(dist.a) > 1:
                for i in range( np.size(dist.a) ):
                    qsca_pe[:,i] = scat.Qsca( E, a=dist.a[i], cm=cmGraphitePerp )
                    qsca_pa[:,i] = scat.Qsca( E, a=dist.a[i], cm=cmGraphitePara )
            else:
                qsca_pe = scat.Qsca( E, a=dist.a, cm=cmGraphitePerp )
                qsca_pa = scat.Qsca( E, a=dist.a, cm=cmGraphitePara )
            
            qsca    = ( qsca_pa + 2.0 * qsca_pe ) / 3.0

        else:
            if np.size(dist.a) > 1:
                for i in range( np.size(dist.a) ):
                    qsca[:,i] = scat.Qsca( E, a=dist.a[i], cm=cm )
            else:
                qsca = scat.Qsca( E, a=dist.a, cm=cm )

        if np.size(dist.a) == 1:
            kappa = dist.nd * qsca * cgeo / dist.md
        else:
            kappa = np.array([])
            for j in range( np.size(E) ):
                kappa = np.append( kappa, \
                                   c.intz( dist.a, dist.nd * qsca[j,:] * cgeo ) / dist.md )

        self.kappa = kappa
Esempio n. 8
0
    def __init__( self, scatm=Scatmodel(), E=1.0, a=1.0 ):
        self.scatm  = scatm
        self.E      = E
        self.a      = a

        cm   = scatm.cmodel
        scat = scatm.smodel

        cgeo  = np.pi * np.power( a*c.micron2cm(), 2 )

        if cm.cmtype == 'Graphite':
            qsca_pe = scat.Qsca( a=a, E=E, cm=cmi.CmGraphite(size=cm.size, orient='perp') )
            qsca_pa = scat.Qsca( a=a, E=E, cm=cmi.CmGraphite(size=cm.size, orient='para') )
            self.qsca = ( qsca_pa + 2.0*qsca_pe ) / 3.0
        else:
            self.qsca = scat.Qsca( a=a, E=E, cm=cm )

        self.sigma = self.qsca * cgeo
Esempio n. 9
0
    def __init__( self, size='big', orient='perp' ):
        # size : string ('big' or 'small')
        #      : 'big' gives results for 0.1 um sized graphite grains at 20 K [Draine (2003)]
        #      : 'small' gives results for 0.01 um sized grains at 20 K
        # orient : string ('perp' or 'para')
        #        : 'perp' gives results for E-field perpendicular to c-axis
        #        : 'para' gives results for E-field parallel to c-axis
        #
        self.cmtype = 'Graphite'
        self.size   = size
        self.orient = orient
        
        D03file = find_cmfile('CM_D03.pysav') # look up file
        D03vals = c.restore(D03file) # read in index values
        
        if size == 'big':            
            if orient == 'perp':
                lamvals = D03vals['Cpe_010_lam']
                revals  = D03vals['Cpe_010_re']
                imvals  = D03vals['Cpe_010_im']
                
            if orient == 'para':
                lamvals = D03vals['Cpa_010_lam']
                revals  = D03vals['Cpa_010_re']
                imvals  = D03vals['Cpa_010_im']
                    
        if size == 'small':
                        
            if orient == 'perp':
                lamvals = D03vals['Cpe_001_lam']
                revals  = D03vals['Cpe_001_re']
                imvals  = D03vals['Cpe_001_im']

            if orient == 'para':
                lamvals = D03vals['Cpa_001_lam']
                revals  = D03vals['Cpa_001_re']
                imvals  = D03vals['Cpa_001_im']

        lamEvals = c.kev2lam() / c.micron2cm() / lamvals # keV
        self.rp  = interp1d( lamEvals, revals )
        self.ip  = interp1d( lamEvals, imvals )
Esempio n. 10
0
    def __call__(self, with_mp=False):
        cm   = self.scatm.cmodel
        scat = self.scatm.smodel

        cgeo = np.pi * np.power( self.dist.a * c.micron2cm(), 2 )

        # Test for graphite case
        if cm.cmtype == 'Graphite':
            if np.size(self.dist.a) > 1:
                for i in range( np.size(self.dist.a) ):
                    self.qsca_pe[:,i] = scat.Qsca( self.E, a=self.dist.a[i], cm=cmi.CmGraphite(size=cm.size, orient='perp') )
                    self.qsca_pa[:,i] = scat.Qsca( self.E, a=self.dist.a[i], cm=cmi.CmGraphite(size=cm.size, orient='para') )
            else:
                self.qsca_pe = scat.Qsca( self.E, a=self.dist.a, cm=cmi.CmGraphite(size=cm.size, orient='perp') )
                self.qsca_pa = scat.Qsca( self.E, a=self.dist.a, cm=cmi.CmGraphite(size=cm.size, orient='para') )
            
            self.qsca = ( self.qsca_pa + 2.0 * self.qsca_pe ) / 3.0

        else:
            if np.size(self.dist.a) > 1:
                if with_mp:
                    pool = Pool(processes=2)
                    self.qsca = np.array(pool.map(self._one_scatter,self.dist.a)).T
                else:
                    for i in range( np.size(self.dist.a) ):
                        self.qsca[:,i] = self._one_scatter(self.dist.a[i])
            else:
                self.qsca = scat.Qsca( self.E, a=self.dist.a, cm=cm )

        if np.size(self.dist.a) == 1:
            kappa = self.dist.nd * self.qsca * cgeo / self.dist.md
        else:
            kappa = np.array([])
            for j in range( np.size(self.E) ):
                kappa = np.append( kappa, \
                                   c.intz( self.dist.a, self.dist.nd * self.qsca[j,:] * cgeo ) / self.dist.md )

        self.kappa = kappa
Esempio n. 11
0
    def __init__( self, scatm=Scatmodel(), E=1.0, a=1.0 ):
        self.scatm  = scatm
        self.E      = E
        self.a      = a

        if scatm.stype == 'RG':
            print 'Rayleigh-Gans cross-section not currently supported for Kappaext'
            self.sigma = None
            return

        cm   = scatm.cmodel
        scat = scatm.smodel

        cgeo  = np.pi * np.power( a*c.micron2cm(), 2 )

        if cm.cmtype == 'Graphite':
            qext_pe = scat.Qext( a=a, E=E, cm=cmi.CmGraphite(size=cm.size, orient='perp') )
            qext_pa = scat.Qext( a=a, E=E, cm=cmi.CmGraphite(size=cm.size, orient='para') )
            self.qext = ( qext_pa + 2.0*qext_pe ) / 3.0
        else:
            self.qext = scat.Qext( a=a, E=E, cm=cm )

        self.sigma = self.qext * cgeo
Esempio n. 12
0
    def getQs( self, a=1.0, E=1.0, cm=cmi.CmDrude(), getQ='sca', theta=None ):  # Takes single a and E argument

        if np.size(a) > 1:
            print 'Error: Can only specify one value for a'
            return

        indl90 = np.array([])  # Empty arrays indicate that there are no theta values set
        indg90 = np.array([])
          # Do not have to check if theta != None throughout calculation
        s1     = np.array([])
        s2     = np.array([])
        pi     = np.array([])
        pi0    = np.array([])
        pi1    = np.array([])
        tau    = np.array([])
        amu    = np.array([])

        if theta != None:
            if np.size(E) > 1 and np.size(E) != np.size(theta):
                print 'Error: If more than one E value specified, theta must have same size as E'
                return

            if np.size( theta ) == 1:
                theta = np.array( [theta] )
            
            theta_rad = theta * c.arcs2rad()
            amu       = np.abs( np.cos(theta_rad) )

            indl90    = np.where( theta_rad < np.pi/2.0 )
            indg90    = np.where( theta_rad >= np.pi/2.0 )
                        
            nang  = np.size( theta )
            s1    = np.zeros( nang, dtype='complex' )
            s2    = np.zeros( nang, dtype='complex' )
            pi    = np.zeros( nang, dtype='complex' )
            pi0   = np.zeros( nang, dtype='complex' )
            pi1   = np.zeros( nang, dtype='complex' ) + 1.0
            tau   = np.zeros( nang, dtype='complex' )

        refrel = cm.rp(E) + 1j*cm.ip(E)

        x      = ( 2.0 * np.pi * a*c.micron2cm() ) / ( c.kev2lam()/E  )
        y      = x * refrel
        ymod   = np.abs(y)
        nx     = np.size( x )


        # *** Series expansion terminated after NSTOP terms
        # Logarithmic derivatives calculated from NMX on down
        
        xstop  = x + 4.0 * np.power( x, 0.3333 ) + 2.0
        test   = np.append( xstop, ymod )
        nmx    = np.max( test ) + 15
        nmx    = np.int32(nmx)
      
        nstop  = xstop
#        nmxx   = 150000
        
#        if (nmx > nmxx):
#            print 'error: nmx > nmxx=', nmxx, ' for |m|x=', ymod

        # *** Logarithmic derivative D(J) calculated by downward recurrence
        # beginning with initial value (0.,0.) at J=NMX

        d = self.create_d(nx,nmx,y)
        
        # *** Riccati-Bessel functions with real argument X
        # calculated by upward recurrence

        psi0 = np.cos(x)
        psi1 = np.sin(x)
        chi0 = -np.sin(x)
        chi1 = np.cos(x)
        xi1  = psi1 - 1j * chi1

        qsca = 0.0    # scattering efficiency
        gsca = 0.0    # <cos(theta)>

        s1_ext = 0
        s2_ext = 0
        s1_back = 0
        s2_back = 0
        
        pi_ext  = 0
        pi0_ext = 0
        pi1_ext = 1
        tau_ext = 0

        p    = -1.0

        for n in np.arange( np.max(nstop) )+1:  # for n=1, nstop do begin
            en = n
            fn = (2.0*en+1.0)/ (en* (en+1.0))

            # for given N, PSI  = psi_n        CHI  = chi_n
            #              PSI1 = psi_{n-1}    CHI1 = chi_{n-1}
            #              PSI0 = psi_{n-2}    CHI0 = chi_{n-2}
            # Calculate psi_n and chi_n
            # *** Compute AN and BN:

            #*** Store previous values of AN and BN for use
            #    in computation of g=<cos(theta)>
            if n > 1:
                an1 = an
                bn1 = bn

            if nx > 1:
                ig  = nstop >= n
                
                psi    = np.zeros( nx )
                chi    = np.zeros( nx )

                psi[ig] = (2.0*en-1.0) * psi1[ig]/x[ig] - psi0[ig]
                chi[ig] = (2.0*en-1.0) * chi1[ig]/x[ig] - chi0[ig]
                xi      = psi - 1j * chi

                an = np.zeros( nx, dtype='complex' )
                bn = np.zeros( nx, dtype='complex' )
                an[ig], bn[ig] = scattering_utils.an_bn(d[ig,n],refrel[ig],en,x[ig],psi[ig],psi1[ig],xi[ig],xi1[ig])
                # an[ig], bn[ig] = self.an_bn(d[ig,n],refrel[ig],en,x[ig],psi[ig],psi1[ig],xi[ig],xi1[ig])
            else:
                psi = (2.0*en-1.0) * psi1/x - psi0
                chi = (2.0*en-1.0) * chi1/x - chi0
                xi  = psi - 1j * chi

                an = ( d[0,n]/refrel + en/x ) * psi - psi1
                an = an / ( ( d[0,n]/refrel + en/x ) * xi - xi1 )
                bn = ( refrel*d[0,n] + en / x ) * psi - psi1
                bn = bn / ( ( refrel*d[0,n] + en/x ) * xi - xi1 )


            # *** Augment sums for Qsca and g=<cos(theta)>
 
            # NOTE from LIA: In IDL version, bhmie casts double(an)
            # and double(bn).  This disgards the imaginary part.  To
            # avoid type casting errors, I use an.real and bn.real

            # Because animag and bnimag were intended to isolate the
            # real from imaginary parts, I replaced all instances of
            # double( foo * complex(0.d0,-1.d0) ) with foo.imag

            qsca += self.compute_qsca(en,an,bn)
            gsca += self.compute_gsca(en,an,bn)

            if n > 1:
                gsca += self.update_gsca(en,an,an1,bn,bn1)

            # *** Now calculate scattering intensity pattern
            #     First do angles from 0 to 90

                
            # LIA : Altered the two loops below so that only the indices where ang
            # < 90 are used.  Replaced (j) with [indl90]

            # Note also: If theta is specified, and np.size(E) > 1,
            # the number of E values must match the number of theta
            # values.  Cosmological halo functions will utilize this
            # Diff this way.

            pi  = pi1
            tau = en * amu * pi - (en + 1.0) * pi0
            
            if np.size(indl90) != 0:
                antmp = an
                bntmp = bn
                if nx > 1:
                    antmp = an[indl90]
                    bntmp = bn[indl90]  # For case where multiple E and theta are specified
                    
                s1[indl90]  = s1[indl90] + fn* (antmp*pi[indl90]+bntmp*tau[indl90])
                s2[indl90]  = s2[indl90] + fn* (antmp*tau[indl90]+bntmp*pi[indl90])
            #ENDIF

            pi_ext = pi1_ext
            tau_ext = en*1.0*pi_ext - (en+1.0)*pi0_ext
            
            s1_ext = s1_ext + fn* (an*pi_ext+bn*tau_ext)
            s2_ext = s2_ext + fn* (bn*pi_ext+an*tau_ext)

            # *** Now do angles greater than 90 using PI and TAU from
            #     angles less than 90.
            #     P=1 for N=1,3,...; P=-1 for N=2,4,...
            
            p = -p
            
            # LIA : Previous code used tau(j) from the previous loop.  How do I
            # get around this?

            if np.size(indg90) != 0:
                antmp = an
                bntmp = bn
                if nx > 1:
                    antmp = an[indg90]
                    bntmp = bn[indg90]  # For case where multiple E and theta are specified

                s1[indg90]  = s1[indg90] + fn*p* (antmp*pi[indg90]-bntmp*tau[indg90])
                s2[indg90]  = s2[indg90] + fn*p* (bntmp*pi[indg90]-antmp*tau[indg90])
            #ENDIF

            s1_back = s1_back + fn*p* (an*pi_ext-bn*tau_ext)
            s2_back = s2_back + fn*p* (bn*pi_ext-an*tau_ext)
            
            psi0 = psi1
            psi1 = psi
            chi0 = chi1
            chi1 = chi
            xi1  = psi1 - 1j*chi1

            # *** Compute pi_n for next value of n
            #     For each angle J, compute pi_n+1
            #     from PI = pi_n , PI0 = pi_n-1

            pi1  = ( (2.0*en+1.0)*amu*pi- (en+1.0)*pi0 ) / en
            pi0  = pi

            pi1_ext = ( (2.0*en+1.0)*1.0*pi_ext - (en+1.0)*pi0_ext ) / en
            pi0_ext = pi_ext

            # ENDFOR

        # *** Have summed sufficient terms.
        #     Now compute QSCA,QEXT,QBACK,and GSCA
        gsca = 2.0 * gsca / qsca
        qsca = ( 2.0 / np.power(x,2) ) * qsca

        # LIA : Changed qext to use s1(theta=0) instead of s1(1).  Why did the
        # original code use s1(1)?

        qext = ( 4.0 / np.power(x,2) ) * s1_ext.real
        qback = np.power( np.abs(s1_back)/x, 2) / np.pi

        if getQ == 'sca':
            return qsca
        if getQ == 'ext':
            return qext
        if getQ == 'back':
            return qback
        if getQ == 'gsca':
            return gsca
        if getQ == 'diff':
            bad_theta = np.where( theta_rad > np.pi )  #Set to 0 values where theta > !pi
            s1[bad_theta] = 0
            s2[bad_theta] = 0
            return 0.5 * ( np.power( np.abs(s1), 2 ) + np.power( np.abs(s2), 2) ) / (np.pi * x*x)
        else:
            return 0.0
Esempio n. 13
0
File: WD01.py Progetto: EZmay15/dust
def make_WD01_Dustspectrum( R_V=3.1, bc=0.0, rad=dust.adist(), type='Graphite', gal='MW' ):
    """
    make_WD01_Dustspectrum(
    R_V [float],
    bc [float],
    rad [np.array : grain sizes (um)],
    type [string : 'Graphite' or 'Silicate'] )
    gal [string : 'MW', 'LMC', or 'SMC'], 
    -------------------------------------------
    Returns a dust.Dustspectrum object containing a (grain sizes), nd (dn/da), and md (total mass density of dust)
    """

    if type == 'Graphite':
        rho_d = 2.2  #g cm^-3
    elif type == 'Silicate':
        rho_d = 3.8
    else:
        print 'Error: Dust type not recognized'
        return

    dist   = dust.Dustdist( rad=rad, rho=rho_d, p=4 )
    result = dust.Dustspectrum( rad=dist )

    ANGS2MICRON = 1.e-10 * 1.e6
    a    = dist.a
    a_cm = dist.a * c.micron2cm()
    NA   = np.size( a )


    (alpha, beta, a_t, a_c, C) = get_dist_params( R_V=R_V, bc=bc, type=type, gal=gal )

    if type == 'Graphite':

        mc      = 12. * 1.67e-24   # Mass of carbon atom in grams (12 m_p)                                                  
        rho     = 2.24             # g cm^-3                                                                                
        sig     = 0.4
        a_01    = 3.5*ANGS2MICRON      # 3.5 angstroms in units of microns                                                  
        a_01_cm = a_01 * c.micron2cm()
        bc1     = 0.75 * bc * 1.e-5
        B_1     = (3.0/(2*np.pi)**1.5) * np.exp(-4.5 * 0.4**2) / (rho*a_01_cm**3 * 0.4) \
            * bc1 * mc / (1 + special.erf( 3*0.4/np.sqrt(2) + np.log(a_01/3.5e-4)/(0.4*np.sqrt(2)) ) )
        
        a_02    = 30.0*ANGS2MICRON       # 30 angtroms in units of microns                                                  
        a_02_cm = a_02 * c.micron2cm()
        bc2     = 0.25 * bc * 1.e-5
        B_2     = (3.0/(2*np.pi)**1.5) * np.exp(-4.5 * 0.4**2) / (rho*a_02_cm**3 * 0.4) \
            * bc2 * mc / (1 + special.erf( 3*0.4/np.sqrt(2) + np.log(a_02/3.5e-4)/(0.4*np.sqrt(2)) ) )
        
        D       = (B_1/a_cm) * np.exp( -0.5*( np.log(a/a_01)/sig )**2 ) + \
            (B_2/a_cm) * np.exp( -0.5*( np.log(a/a_02)/sig )**2 )

        Case_vsg = np.where( a < 3.5*ANGS2MICRON )
        if np.size(Case_vsg) != 0:
            D[Case_vsg] = 0.0

        Case_g = np.zeros( NA )
        case1g = np.where( np.logical_and(a > 3.5*ANGS2MICRON, a < a_t ) )
        case2g = np.where( a >= a_t )

        if np.size(case1g) != 0:
            Case_g[case1g] = 1.0
        if np.size(case2g) != 0:
            Case_g[case2g] = np.exp( -( (a[case2g]-a_t) / a_c )**3 )

        if beta >= 0:
            F_g  = 1 + beta * a / a_t
        if beta < 0:
            F_g  = 1.0 / (1 - beta * a / a_t)

        Dist_WD01 = D + C/a_cm * (a/a_t)**alpha * F_g * Case_g  #cm^-4 per n_H

    if type == 'Silicate':

        Case_s = np.zeros( NA )
        case1s = np.where( np.logical_and( a > 3.5*ANGS2MICRON, a < a_t ) )
        case2s = np.where( a >= a_t )

        if np.size(case1s) != 0:
            Case_s[case1s] = 1.0
        if np.size(case2s) != 0:
            Case_s[case2s] = np.exp( -( (a[case2s]-a_t)/a_c )**3 )

        F_s    = np.zeros( NA )
        if beta >= 0:
            F_s = 1 + beta * a / a_t
        if beta < 0:
            F_s = 1. / (1 - beta * a / a_t)

        Dist_WD01 = C/a_cm * (a/a_t)**alpha * F_s * Case_s #cm^-4 per n_H

    ## Modify result Dustspectrum so we get a proper WD01 dist!

    mg = 4.0/3.0*np.pi*a_cm**3 * rho_d  # mass of each dust grain
    Md = c.intz( a_cm, Dist_WD01 * mg )

    result.nd = Dist_WD01 * c.micron2cm()  # cm^-3 per um per n_H
    result.md = Md

    return result
Esempio n. 14
0
 def dnda(self, md=1.5e-5):
     adep  = np.power( self.a, -self.p )   # um^-p
     dmda  = adep * 4./3. * np.pi * self.rho * np.power( self.a*c.micron2cm(), 3 ) # g um^-p
     const = md / c.intz( self.a, dmda ) # cm^-? um^p-1
     return const * adep # cm^-? um^-1
Esempio n. 15
0
 def ndens(self, md=1.5e-5 ):
     gvol = 4./3. * np.pi * np.power( self.a*c.micron2cm(), 3 )
     return md / ( gvol*self.rho )