Example #1
0
    def getStatic(self):
        ''' calculate the static matrix for the specified temperature'''
        temperature = self.Temperature
        z = self.Z
        ionList = []
        chIons = []
        evolver = np.zeros((z + 1, z + 1), 'float64')
        for ion in range(1, z + 2):
            ions = util.zion2name(z, ion)
            ionList.append(ions)
            #            print z, ion, ions
            atom = ch.ion(ions, temperature=temperature)
            atom.ionizRate()
            atom.recombRate()
            chIons.append(atom)
        for stage in range(0, z):
            atom = chIons[stage]
            #            if type(atom.IonizRate) != types.NoneType:
            evolver[stage, stage] -= atom.IonizRate['rate']
            atom = chIons[stage + 1]
            evolver[stage, stage + 1] += atom.RecombRate['rate']
#                evolver[stage-2,stage] += atom.IonizRate['rate']
        for stage in range(1, z + 1):
            atom = chIons[stage]
            #            if type(atom.RecombRate) != types.NoneType:
            evolver[stage, stage] -= atom.RecombRate['rate']
            atom = chIons[stage - 1]
            evolver[stage, stage - 1] += atom.IonizRate['rate']
#                evolver[stage-1,stage-2] += atom.RecombRate['rate']
# include normalization of ionization stages
        for stage in range(0, z + 1):
            evolver[0, stage] = 1.
        self.Static = evolver
Example #2
0
    def getStatic(self):
        ''' calculate the static matrix for the specified temperature'''
        temperature = self.Temperature
        z = self.Z
        ionList=[]
        chIons=[]
        evolver = np.zeros((z+1,z+1),'float64')
        for ion in range(1, z+2):
            ions=util.zion2name(z, ion)
            ionList.append(ions)
#            print z, ion, ions
            atom=ch.ion(ions, temperature=temperature)
            atom.ionizRate()
            atom.recombRate()
            chIons.append(atom)
        for stage in range(0,z):
            atom = chIons[stage]
#            if type(atom.IonizRate) != types.NoneType:
            evolver[stage,stage] -= atom.IonizRate['rate']
            atom = chIons[stage+1]
            evolver[stage,stage+1] += atom.RecombRate['rate']
#                evolver[stage-2,stage] += atom.IonizRate['rate']
        for stage in range(1,z+1):
            atom = chIons[stage]
#            if type(atom.RecombRate) != types.NoneType:
            evolver[stage,stage] -= atom.RecombRate['rate']
            atom = chIons[stage-1]
            evolver[stage,stage-1] += atom.IonizRate['rate']
#                evolver[stage-1,stage-2] += atom.RecombRate['rate']
        # include normalization of ionization stages
        for stage in range(0,z+1):
            evolver[0,stage] = 1.
        self.Static = evolver
Example #3
0
def match_line(ion_name, wvls, s_flux, tmax, density):

    #	t = 10**((tmax - 0.3) + 0.001*np.arange(600))

    lowtemp = 4.0
    hightemp = 8.0
    npoints = 1000
    t = 10**(np.linspace(lowtemp, hightemp, npoints))

    ion_n = ch.ion(ion_name, temperature=t, eDensity=density)
    ion_n.gofnt(wvlRange=[min(wvls) - 1, max(wvls) + 1])

    return ion_n.Gofnt
Example #4
0
def sum_match_lines(ion_name,wvls,t,density,search_width = 1.0):

  ion_n = ch.ion(ion_name, temperature=t, eDensity=density)

  intensity = t.copy()*0.0
  print(wvls)
  for wvl in wvls:
    ion_n.intensity(wvlRange=[min(wvls)-search_width,max(wvls)+search_width])

    if wvl in(ion_n.Intensity['wvl']): 
      intensity_s = ion_n.Intensity['intensity'][:,(ion_n.Intensity['wvl'] == wvl)]
      intensity += np.array(intensity_s.T[0])
      print('match')
    else:
      print('Something is wrong - cannot find matching line! for {} {}'.format(ion_name,wvl))
      intensity += 0
  return intensity
Example #5
0
    def getIoneq(self):
        ''' get the ionization equilibrium for this ion at the specified temperature
        getIoneqFromEvolver does the same but is a bit less accurate'''
        z = self.Z
        temperature = self.Temperature
        ionList = []
        chIons = []
        for ion in range(1, z + 2):
            ions = util.zion2name(z, ion)
            ionList.append(ions)
            #            print z, ion, ions
            atom = ch.ion(ions, temperature=temperature, setup=0)
            atom.ionizRate()
            atom.recombRate()
            chIons.append(atom)
        ioneq = np.zeros((z + 1), 'float64')
        factor = []
        for anIon in chIons:
            if type(anIon.IonizRate) != type(None) and type(
                    anIon.RecombRate) != type(None):
                rat = anIon.IonizRate['rate'] / anIon.RecombRate['rate']
                factor.append(rat**2 + rat**(-2))
            else:
                factor.append(0.)
        factor[0] = max(factor)
        factor[-1] = max(factor)
        ionmax = factor.index(min(factor))
        ioneq[ionmax] = 1.
        #
        for iz in range(ionmax + 1, z + 1):
            ionrate = chIons[iz - 1].IonizRate['rate']
            recrate = chIons[iz].RecombRate['rate']
            ioneq[iz] = ionrate * ioneq[iz - 1] / recrate
#            print ' iz, ioneq = ',iz,ioneq[iz]
#
        for iz in range(ionmax - 1, -1, -1):
            ionrate = chIons[iz].IonizRate['rate']
            recrate = chIons[iz + 1].RecombRate['rate']
            ioneq[iz] = recrate * ioneq[iz + 1] / ionrate
#            print ' iz, ioneq = ',iz,ioneq[iz]
        ionsum = ioneq.sum()
        #        print ' ionsum = ', ionsum
        ioneq = ioneq / ionsum
        self.Ioneq = ioneq
Example #6
0
    def getIoneq(self):
        ''' get the ionization equilibrium for this ion at the specified temperature
        getIoneqFromEvolver does the same but is a bit less accurate'''
        z = self.Z
        temperature = self.Temperature
        ionList=[]
        chIons=[]
        for ion in range(1, z+2):
            ions=util.zion2name(z, ion)
            ionList.append(ions)
#            print z, ion, ions
            atom=ch.ion(ions, temperature=temperature, setup=0)
            atom.ionizRate()
            atom.recombRate()
            chIons.append(atom)
        ioneq=np.zeros((z+1), 'float64')
        factor=[]
        for anIon in chIons:
            if type(anIon.IonizRate) != type(None) and type(anIon.RecombRate) != type(None):
                rat=anIon.IonizRate['rate']/anIon.RecombRate['rate']
                factor.append(rat**2 + rat**(-2))
            else:
                factor.append(0.)
        factor[0]=max(factor)
        factor[-1]=max(factor)
        ionmax=factor.index(min(factor))
        ioneq[ionmax]=1.
        #
        for iz in range(ionmax+1, z+1):
            ionrate=chIons[iz-1].IonizRate['rate']
            recrate=chIons[iz].RecombRate['rate']
            ioneq[iz]=ionrate*ioneq[iz-1]/recrate
#            print ' iz, ioneq = ',iz,ioneq[iz]
        #
        for iz in range(ionmax-1, -1, -1):
            ionrate=chIons[iz].IonizRate['rate']
            recrate=chIons[iz+1].RecombRate['rate']
            ioneq[iz]=recrate*ioneq[iz+1]/ionrate
#            print ' iz, ioneq = ',iz,ioneq[iz]
        ionsum=ioneq.sum()
#        print ' ionsum = ', ionsum
        ioneq=ioneq/ionsum
        self.Ioneq=ioneq
Example #7
0
def old_find_tm(ion_name):

    h = 6.626068e-34
    c = 299792458
    k = 1.3806503e-23

    ion_state = int(ion_name.rsplit('_')[1])

    t = 10**(3.8 + 0.01 * np.arange(400))

    ion = ch.ion(ion_name, temperature=t)

    ioneq = ion.IoneqOne
    W = h * c * ion.Elvlc['ecm'][ion_state - 1] * 100
    gt = ioneq * (t**-0.5) * np.exp(-W / (k * t))

    tm = t[np.argmax(gt)]

    return np.log10(tm)
Example #8
0
def old_e_measure(ion_name, wvls, s_flux, tmax, star_dist, star_radius,
                  density):

    rs = 6.96e10
    pc = 3.08567758e18
    t = 10**((tmax - 0.3) + 0.001 * np.arange(600))
    ion_n = ch.ion(ion_name, temperature=t, eDensity=density)

    ion_n.gofnt(wvlRange=[min(wvls) - 1, max(wvls) + 1])
    star_dist = star_dist * pc
    star_radius = star_radius * rs

    flux = s_flux * (star_dist / star_radius)**2.0

    print('ANYONE THERE?!')
    quit()

    ion_n.Gofnt['emeasure'] = (flux / density) / (2 * np.pi *
                                                  ion_n.Gofnt['gofnt'])
    return ion_n.Gofnt
Example #9
0
    def getEvolver(self, temperature, density, time):
        ''' calculate the evolver matrix for the new temperature'''
        self.NewTemperature = temperature
        z = self.Z
        ionList = []
        chIons = []
        evolver = np.zeros((z + 1, z + 1), 'float64')
        for ion in range(1, z + 2):
            ions = util.zion2name(z, ion)
            ionList.append(ions)
            #            print z, ion, ions
            atom = ch.ion(ions, temperature=temperature, setup=0)
            atom.ionizRate()
            atom.recombRate()
            chIons.append(atom)
        for stage in range(0, z):
            #            atom = chIons[stage]
            #            if type(atom.IonizRate) != types.NoneType:
            evolver[stage, stage] -= chIons[stage].IonizRate['rate']
            #            atom = chIons[stage+1]
            evolver[stage, stage + 1] += chIons[stage + 1].RecombRate['rate']
#                evolver[stage-2,stage] += atom.IonizRate['rate']
        for stage in range(1, z + 1):
            #            atom = chIons[stage]
            #            if type(atom.RecombRate) != types.NoneType:
            evolver[stage, stage] -= chIons[stage].RecombRate['rate']
            #            atom = chIons[stage-1]
            evolver[stage, stage - 1] += chIons[stage - 1].IonizRate['rate']
#                evolver[stage-1,stage-2] += atom.RecombRate['rate']
# include normalization of ionization stages
#        for stage in range(0,z+1):
#            evolver[0,stage] = 1.
# this is the first order Euler solution
#        implicitEvolver = np.invert(np.identity(z+1,'float64') - evolver)
        implicitEvolver = np.dual.inv(
            np.identity(z + 1, 'float64') - density * time * evolver)
        self.Evolver = implicitEvolver
Example #10
0
    def getEvolver(self,temperature,density,time):
        ''' calculate the evolver matrix for the new temperature'''
        self.NewTemperature = temperature
        z = self.Z
        ionList=[]
        chIons=[]
        evolver = np.zeros((z+1,z+1),'float64')
        for ion in range(1, z+2):
            ions=util.zion2name(z, ion)
            ionList.append(ions)
#            print z, ion, ions
            atom=ch.ion(ions, temperature=temperature, setup=0)
            atom.ionizRate()
            atom.recombRate()
            chIons.append(atom)
        for stage in range(0,z):
#            atom = chIons[stage]
#            if type(atom.IonizRate) != types.NoneType:
            evolver[stage,stage] -= chIons[stage].IonizRate['rate']
#            atom = chIons[stage+1]
            evolver[stage,stage+1] += chIons[stage+1].RecombRate['rate']
#                evolver[stage-2,stage] += atom.IonizRate['rate']
        for stage in range(1,z+1):
#            atom = chIons[stage]
#            if type(atom.RecombRate) != types.NoneType:
            evolver[stage,stage] -= chIons[stage].RecombRate['rate']
#            atom = chIons[stage-1]
            evolver[stage,stage-1] += chIons[stage-1].IonizRate['rate']
#                evolver[stage-1,stage-2] += atom.RecombRate['rate']
        # include normalization of ionization stages
#        for stage in range(0,z+1):
#            evolver[0,stage] = 1.
        # this is the first order Euler solution
#        implicitEvolver = np.invert(np.identity(z+1,'float64') - evolver)
        implicitEvolver = np.dual.inv(np.identity(z+1,'float64') - density*time*evolver)
        self.Evolver = implicitEvolver
Example #11
0
def read_chianti(symbol, ion_number, level_observed=True, temperatures = np.linspace(2000, 50000, 20)):
    ion_data = ch.ion('{0}_{1:d}'.format(symbol.lower(), ion_number+1))
    levels_data = {}
    levels_data['level_number'] = ion_data.Elvlc['lvl']

    temperatures = np.array(temperatures)
    if level_observed:
        levels_data['energy'] = units.Unit('cm').to('eV', 1 / np.array(ion_data.Elvlc['ecm']), units.spectral())
    else:
        levels_data['energy'] = units.Unit('cm').to('eV', 1 / np.array(ion_data.Elvlc['ecmth']), units.spectral())
    levels_data['g'] = 2*np.array(ion_data.Elvlc['j']) + 1

    if levels_data['energy'][0] != 0.0:
        raise ValueError('Level 0 energy is not 0.0')

    levels_data = pd.DataFrame(levels_data)
    levels_data.set_index('level_number', inplace=True)

    last_bound_level = levels_data[levels_data['energy'] < ion_data.Ip].index[-1]

    levels_data = levels_data.ix[:last_bound_level]

    lines_data = {}

    lines_data['wavelength'] = ion_data.Wgfa['wvl']
    lines_data['level_number_lower'] = ion_data.Wgfa['lvl1']
    lines_data['level_number_upper'] = ion_data.Wgfa['lvl2']
    lines_data['A_ul'] = ion_data.Wgfa['avalue']
    nu = units.Unit('angstrom').to('Hz', lines_data['wavelength'], units.spectral())
    lines_data = pd.DataFrame(lines_data)

    g_lower = levels_data['g'].ix[lines_data['level_number_lower'].values].values
    g_upper = levels_data['g'].ix[lines_data['level_number_upper'].values].values

    A_coeff = (8 * np.pi**2 * constants.e.gauss.value**2 * nu**2)/ (constants.m_e.cgs.value * constants.c.cgs.value**3)
    lines_data['f_ul'] = lines_data['A_ul'] / A_coeff
    lines_data['f_lu'] = (lines_data['A_ul'] * g_upper) / (A_coeff * g_lower)
    lines_data['loggf'] = np.log10(lines_data['f_lu'] * g_lower)
    lines_data['wavelength'] = lines_data['wavelength']# / (1.0 + 2.735182E-4 + 131.4182 / lines_data['wavelength']**2
                                                       #   + 2.76249E8 / lines_data['wavelength']**4)

    lines_data = lines_data[lines_data['level_number_upper'] <= last_bound_level]
    collision_data_index = pd.MultiIndex.from_arrays((ion_data.Splups['lvl1'], ion_data.Splups['lvl2']))

    c_lvl1 = []
    c_lvl2 = []
    c_upper_lowers = []

    g_ratios = []
    delta_es = []


    for i, (lvl1, lvl2) in enumerate(zip(ion_data.Splups['lvl1'], ion_data.Splups['lvl2'])):
        if lvl2 > last_bound_level:
            continue

        c_lvl1.append(lvl1)
        c_lvl2.append(lvl2)
        c_upper_lower, g_ratio, delta_e = calculate_collisional_strength(ion_data.Splups, i, temperatures, levels_data)
        c_upper_lowers.append(c_upper_lower)
        g_ratios.append(g_ratio)
        delta_es.append(delta_e)

    c_upper_lowers = np.array(c_upper_lowers)
    g_ratios = np.array(g_ratios)
    delta_es = np.array(delta_es)


    collision_data = pd.DataFrame(c_upper_lowers, index=collision_data_index)
    collision_data['g_ratio'] = g_ratios

    #CAREFUL!!! delta_e has already been divided by k!!
    collision_data['delta_e'] = delta_es


    collision_data['level_number_lower'] = c_lvl1
    collision_data['level_number_upper'] = c_lvl2

    lines_data = lines_data[lines_data.wavelength>0]

    return levels_data, lines_data, collision_data
    init_values['de'][:] = 1e-30
    init_values = ion_by_ion.convert_to_mass_density(init_values)
else:
    # start CIE
    import chianti.core as ch
    import chianti.util as chu

    for s in sorted(ion_by_ion.required_species):
        if s.name != 'ge':
            if s.name == 'de':
                continue
            else:
                print s.name, s.free_electrons + 1
                ion_name = chu.zion2name(np.int(s.number),
                                         np.int(s.free_electrons + 1))
                ion = ch.ion(ion_name, temperature=init_values['T'])
                ion.ioneqOne()
                ion_frac = ion.IoneqOne
                init_values[s.name] = ion_frac * init_array * ion.Abundance

            # in case something is negative or super small:
            init_values[s.name][init_values[s.name] < tiny] = tiny

    init_values['de'] = init_array * 0.0
    #    total_density = combined.calculate_total_density(init_values, ("OI",))
    #    init_values["OI"] = init_array.copy() - total_density
    init_values = ion_by_ion.convert_to_mass_density(init_values)

init_values['de'] = ion_by_ion.calculate_free_electrons(init_values)
init_values['density'] = ion_by_ion.calculate_total_density(init_values)
number_density = ion_by_ion.calculate_number_density(init_values)
 def rec_rate(network):
     ion = ch.ion(ion_name, temperature = network.T)
     ion.recombRate()
     vals = ion.RecombRate['rate']
     return vals
 def ion_rate(network):
     ion = ch.ion(ion_name, temperature = network.T)
     ion.ionizRate()
     vals = ion.IonizRate['rate']
     return vals
Example #15
0
    def __init__(self, ion_name):

        self.ion = ch.ion(ion_name)
        self._levels = None
        self._lines = None
        self._collisions = None
Example #16
0
"""

import ares
import numpy as np
import matplotlib.pyplot as pl
import chianti.core as cc

pl.rcParams['legend.fontsize'] = 14

#
dims = 32
T = np.logspace(2, 7, dims)
#

# Chianti rates
h1 = cc.ion('h_1', T)
h2 = cc.ion('h_2', T)
he1 = cc.ion('he_1', T)
he2 = cc.ion('he_2', T)
he3 = cc.ion('he_3', T)

# Analytic fits
coeff = ares.physics.RateCoefficients()
"""
Plot collisional ionization rate coefficients.
"""

h1.diRate()
he1.diRate()
he2.diRate()