Beispiel #1
0
 def rmass(self):
     """reduced mass for a path"""
     if self.__rmass is None:
         amass = 0
         for label, iz, ipot, x, y, z in self.geom:
             m = atomic_mass(iz, _larch=self._larch)
             amass += 1.0/max(1., m)
         self.__rmass = 1./amass
     return self.__rmass
Beispiel #2
0
def material_mu(name, energy, density=None, kind='total', _larch=None):
    """
    material_mu(name, energy, density=None, kind='total')

    return X-ray attenuation length (in 1/cm) for a material by name or formula

    arguments
    ---------
     name:     chemical formul or name of material from materials list.
     energy:   energy or array of energies in eV
     density:  material density (gr/cm^3).  If None, and material is a
               known material, that density will be used.
     kind:     'photo' or 'total' (default) for whether to
               return photo-absorption or total cross-section.
    returns
    -------
     mu, absorption length in 1/cm

    notes
    -----
      1.  material names are not case sensitive,
          chemical compounds are case sensitive.
      2.  mu_elam() is used for mu calculation.

    example
    -------
      >>> print material_mu('H2O', 10000.0)
      5.32986401658495
    """
    _materials = get_materials(_larch)
    formula = None
    mater = _materials.get(name.lower(), None)
    if mater is not None:
        formula, density = mater
    else:
        for key, val in _materials.items():
            if name.lower() == val[0].lower(): # match formula
                formula, density = val
                break
    # default to using passed in name as a formula
    if formula is None:
        formula = name
    if density is None:
        raise Warning('material_mu(): must give density for unknown materials')

    mass_tot, mu = 0.0, 0.0
    for elem, frac in chemparse(formula).items():
        mass  = frac * atomic_mass(elem, _larch=_larch)
        mu   += mass * mu_elam(elem, energy, kind=kind, _larch=_larch)
        mass_tot += mass
    return density*mu/mass_tot
Beispiel #3
0
def sigma2_debye(t, theta, path=None, _larch=None):
    """calculate sigma2 for a Feff Path wih the correlated Debye model

    sigma2 = sigma2_debye(t, theta, path=None)

    Parameters:
    -----------
      t        sample temperature (in K)
      theta    Debye temperature (in K)
      path     FeffPath to cacluate sigma2 for [None]

    if path is None, the 'current path'
    (_sys.paramGroup._feffdat) is used.
    """
    global FEFF6LIB
    if FEFF6LIB is None:
        FEFF6LIB = get_dll('feff6')
        FEFF6LIB.sigma2_debye.restype = ctypes.c_double

    if path is None:
        try:
            path = _larch.symtable._sys.paramGroup
        except:
            pass
    try:
        fdat = path._feffdat
    except:
        return 0.00
    if theta < 1.e-5: theta = 1.e-5
    if t < 1.e-5: t = 1.e-5

    npts = len(fdat.geom)
    nat  = ctypes.pointer(ctypes.c_int(npts))
    t    = ctypes.pointer(ctypes.c_double(t))
    th   = ctypes.pointer(ctypes.c_double(theta))
    rs   = ctypes.pointer(ctypes.c_double(fdat.rnorman))
    ax   = (npts*ctypes.c_double)()
    ay   = (npts*ctypes.c_double)()
    az   = (npts*ctypes.c_double)()
    am   = (npts*ctypes.c_double)()
    for i, dat in enumerate(fdat.geom):
        s, iz, ip, x, y, z =  dat
        ax[i], ay[i], az[i], am[i] = x, y, z, atomic_mass(iz, _larch=_larch)

    return FEFF6LIB.sigma2_debye(nat, t, th, rs, ax, ay, az, am)
Beispiel #4
0
def material_mu_components(name, energy, density=None, kind='total',
                           _larch=None):
    """material_mu_components: absorption coefficient (in 1/cm) for a compound

    arguments
    ---------
     name:     material name or compound formula
     energy:   energy or array of energies at which to calculate mu
     density:  compound density in gr/cm^3
     kind:     cross-section to use ('total', 'photo') for mu_elam())

    returns
    -------
     dictionary of data for constructing mu per element,
     with elements 'mass' (total mass), 'density', and
     'elements' (list of atomic symbols for elements in material).
     For each element, there will be an item (atomic symbol as key)
     with tuple of (stoichiometric fraction, atomic mass, mu)

     larch> material_mu_components('quartz', 10000)
     {'Si': (1, 28.0855, 33.879432430185062), 'elements': ['Si', 'O'],
     'mass': 60.0843, 'O': (2.0, 15.9994, 5.9528248152970837), 'density': 2.65}
     """
    _materials = get_materials(_larch)
    mater = _materials.get(name.lower(), None)
    if mater is None:
        formula = name
        if density is None:
            raise Warning('material_mu(): must give density for unknown materials')
    else:
        formula, density = mater


    out = {'mass': 0.0, 'density': density, 'elements':[]}
    for atom, frac in chemparse(formula).items():
        mass  = atomic_mass(atom, _larch=_larch)
        mu    = mu_elam(atom, energy, kind=kind, _larch=_larch)
        out['mass'] += frac*mass
        out[atom] = (frac, mass, mu)
        out['elements'].append(atom)
    return out
Beispiel #5
0
 def __read(self, filename):
     try:
         lines = open(filename, 'r').readlines()
     except:
         print( 'Error reading file %s ' % filename)
         return
     self.filename = filename
     mode = 'header'
     self.potentials, self.geom = [], []
     data = []
     pcounter = 0
     iline = 0
     for line in lines:
         iline += 1
         line = line[:-1]
         if line.startswith('#'): line = line[1:]
         line = line.strip()
         if iline == 1:
             self.title = line[:64].strip()
             self.version = line[64:].strip()
             continue
         if line.startswith('k') and line.endswith('real[p]@#'):
             mode = 'arrays'
             continue
         elif '----' in line[2:10]:
             mode = 'path'
             continue
         #
         if (mode == 'header' and
             line.startswith('Abs') or line.startswith('Pot')):
             words = line.replace('=', ' ').split()
             ipot, z, rmt, rnm = (0, 0, 0, 0)
             words.pop(0)
             if line.startswith('Pot'):
                 ipot = int(words.pop(0))
             iz = int(words[1])
             rmt = float(words[3])
             rnm = float(words[5])
             self.potentials.append((ipot, iz, rmt, rnm))
         elif mode == 'header' and line.startswith('Gam_ch'):
             words  = line.replace('=', ' ').split(' ', 2)
             self.gam_ch = float(words[1])
             self.exch   = words[2]
         elif mode == 'header' and line.startswith('Mu'):
             words  = line.replace('=', ' ').split()
             self.mu = float(words[1])
             self.kf = float(words[3])
             self.vint = float(words[5])
             self.rs_int= float(words[7])
         elif mode == 'path':
             pcounter += 1
             if pcounter == 1:
                 w = [float(x) for x in line.split()[:5]]
                 self.__nleg__ = int(w.pop(0))
                 self.degen, self.__reff__, self.rnorman, self.edge = w
             elif pcounter > 2:
                 words = line.split()
                 xyz = [float(x) for x in words[:3]]
                 ipot = int(words[3])
                 iz   = int(words[4])
                 if len(words) > 5:
                     lab = words[5]
                 else:
                     lab = atomic_symbol(iz)
                 amass = atomic_mass(iz)
                 geom = [lab, iz, ipot, amass] + xyz
                 self.geom.append(tuple(geom))
         elif mode == 'arrays':
             d = np.array([float(x) for x in line.split()])
             if len(d) == 7:
                 data.append(d)
     data = np.array(data).transpose()
     self.k        = data[0]
     self.real_phc = data[1]
     self.mag_feff = data[2]
     self.pha_feff = data[3]
     self.red_fact = data[4]
     self.lam = data[5]
     self.rep = data[6]
     self.pha = data[1] + data[3]
     self.amp = data[2] * data[4]
     self.__rmass = None  # reduced mass of path
Beispiel #6
0
 def __read(self, filename):
     try:
         lines = open(filename, 'r').readlines()
     except:
         print('Error reading file %s ' % filename)
         return
     self.filename = filename
     mode = 'header'
     self.potentials, self.geom = [], []
     data = []
     pcounter = 0
     iline = 0
     for line in lines:
         iline += 1
         line = line[:-1]
         if line.startswith('#'): line = line[1:]
         line = line.strip()
         if iline == 1:
             self.title = line[:64].strip()
             self.version = line[64:].strip()
             continue
         if line.startswith('k') and line.endswith('real[p]@#'):
             mode = 'arrays'
             continue
         elif '----' in line[2:10]:
             mode = 'path'
             continue
         #
         if (mode == 'header' and line.startswith('Abs')
                 or line.startswith('Pot')):
             words = line.replace('=', ' ').split()
             ipot, z, rmt, rnm = (0, 0, 0, 0)
             words.pop(0)
             if line.startswith('Pot'):
                 ipot = int(words.pop(0))
             iz = int(words[1])
             rmt = float(words[3])
             rnm = float(words[5])
             self.potentials.append((ipot, iz, rmt, rnm))
         elif mode == 'header' and line.startswith('Gam_ch'):
             words = line.replace('=', ' ').split(' ', 2)
             self.gam_ch = float(words[1])
             self.exch = words[2]
         elif mode == 'header' and line.startswith('Mu'):
             words = line.replace('=', ' ').split()
             self.mu = float(words[1])
             self.kf = float(words[3])
             self.vint = float(words[5])
             self.rs_int = float(words[7])
         elif mode == 'path':
             pcounter += 1
             if pcounter == 1:
                 w = [float(x) for x in line.split()[:5]]
                 self.__nleg__ = int(w.pop(0))
                 self.degen, self.__reff__, self.rnorman, self.edge = w
             elif pcounter > 2:
                 words = line.split()
                 xyz = [float(x) for x in words[:3]]
                 ipot = int(words[3])
                 iz = int(words[4])
                 if len(words) > 5:
                     lab = words[5]
                 else:
                     lab = atomic_symbol(iz, _larch=self._larch)
                 amass = atomic_mass(iz, _larch=self._larch)
                 geom = [lab, iz, ipot, amass] + xyz
                 self.geom.append(tuple(geom))
         elif mode == 'arrays':
             d = np.array([float(x) for x in line.split()])
             if len(d) == 7:
                 data.append(d)
     data = np.array(data).transpose()
     self.k = data[0]
     self.real_phc = data[1]
     self.mag_feff = data[2]
     self.pha_feff = data[3]
     self.red_fact = data[4]
     self.lam = data[5]
     self.rep = data[6]
     self.pha = data[1] + data[3]
     self.amp = data[2] * data[4]
     self.__rmass = None  # reduced mass of path