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
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
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)
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
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
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