Statistiques
| Révision :

root / ase / xrdebye.py @ 20

Historique | Voir | Annoter | Télécharger (3,57 ko)

1 1 tkerber
from math import exp, pi, sin, sqrt, cos, acos
2 1 tkerber
import numpy as np
3 1 tkerber
4 1 tkerber
from ase.data import atomic_numbers
5 1 tkerber
6 1 tkerber
# Table (1) of
7 1 tkerber
# D. WAASMAIER AND A. KIRFEL, Acta Cryst. (1995). A51, 416-431
8 1 tkerber
waasmaier = {
9 1 tkerber
    #      a1        b1         a2        b2        a3        b3          a4         b4         a5         b5        c
10 1 tkerber
    'C' : [2.657506, 14.780758, 1.078079, 0.776775, 1.490909, 42.086843,  -4.241070, -0.000294, 0.713791, 0.239535, 4.297983],
11 1 tkerber
    'S' : [6.372157, 1.514347, 5.154568, 22.092528, 1.473732, 0.061373,   1.635073,  55.445176, 1.209372, 0.646925, 0.154722],
12 1 tkerber
    'Pd': [6.121511, 0.062549,  4.784063, 0.784031, 16.631683, 8.751391,  4.318258, 34.489983, 13.246773, 0.784031, 0.883099],
13 1 tkerber
    'Ag': [6.073874, 0.055333, 17.155437, 7.896512, 4.173344, 28.443739,  0.852238, 110.376108, 17.988685, 0.716809, 0.756603],
14 1 tkerber
    'Au': [16.777389, 0.122737, 19.317156, 8.621570, 32.979682, 1.256902, 5.595453, 38.008821, 10.576854, 0.000601, -6.279078],
15 1 tkerber
    'P' : [1.950541, 0.908139, 4.146930, 27.044953, 1.494560, 0.071280, 1.522042, 67.520190, 5.729711, 1.981173, 0.155233],
16 1 tkerber
    'Cl': [1.446071, 0.052357, 6.870609, 1.193165, 6.151801, 18.343416, 1.750347, 46.398394, 0.634168, 0.401005, 0.146773],
17 1 tkerber
}
18 1 tkerber
19 1 tkerber
class XrDebye:
20 1 tkerber
    def __init__(self, wavelength, alpha=1.01, damping=0.04, warn=True,
21 1 tkerber
                 method='Iwasa'):
22 1 tkerber
        """
23 1 tkerber
        Obtain powder x-ray spectra.
24 1 tkerber

25 1 tkerber
        wavelength in Angstrom
26 1 tkerber
        damping in Angstrom**2
27 1 tkerber
        """
28 1 tkerber
        self.wavelength = wavelength
29 1 tkerber
        self.damping = damping
30 1 tkerber
        self.alpha = alpha
31 1 tkerber
        self.warn = warn
32 1 tkerber
        self.method = method
33 1 tkerber
34 1 tkerber
    def set_damping(self, damping):
35 1 tkerber
        self.damping = damping
36 1 tkerber
37 1 tkerber
    def get(self, atoms, s):
38 1 tkerber
        """Get the powder x-ray (XRD) pattern using the Debye-Formula.
39 1 tkerber

40 1 tkerber
        After: T. Iwasa and K. Nobusada, J. Phys. Chem. C 111 (2007) 45
41 1 tkerber
               s is assumed to be in 1/Angstrom
42 1 tkerber
        """
43 1 tkerber
44 1 tkerber
        sinth = self.wavelength * s / 2.
45 1 tkerber
        costh = sqrt(1. - sinth**2)
46 1 tkerber
        cos2th = cos(2. * acos(costh))
47 1 tkerber
        pre = exp(- self.damping * s**2 / 2)
48 1 tkerber
49 1 tkerber
        if self.method == 'Iwasa':
50 1 tkerber
            pre *= costh / (1. + self.alpha * cos2th**2)
51 1 tkerber
52 1 tkerber
        f = {}
53 1 tkerber
        def atomic(symbol):
54 1 tkerber
            if not f.has_key(symbol):
55 1 tkerber
                if self.method == 'Iwasa':
56 1 tkerber
                    f[symbol] = self.get_waasmaier(symbol, s)
57 1 tkerber
                else:
58 1 tkerber
                    f[symbol] = atomic_numbers[symbol]
59 1 tkerber
            return f[symbol]
60 1 tkerber
61 1 tkerber
        def sinc(x):
62 1 tkerber
            if x < 1.e-6:
63 1 tkerber
                x2 = x * x
64 1 tkerber
                return 1 - x2 / 6. + x2 * x2 / 120.
65 1 tkerber
            else:
66 1 tkerber
                return sin(x) / x
67 1 tkerber
68 1 tkerber
        I = 0.
69 1 tkerber
        for a in atoms:
70 1 tkerber
            fa = atomic(a.symbol)
71 1 tkerber
#            print a.symbol, fa
72 1 tkerber
            for b in atoms:
73 1 tkerber
                fb = atomic(b.symbol)
74 1 tkerber
75 1 tkerber
                if a == b:
76 1 tkerber
                    twopis = 0.
77 1 tkerber
                else:
78 1 tkerber
                    vrij = a.position - b.position
79 1 tkerber
                    rij = np.sqrt(np.dot(vrij, vrij))
80 1 tkerber
                    twopisr = 2 * pi * s * rij
81 1 tkerber
82 1 tkerber
                I += fa * fb * sinc(twopisr)
83 1 tkerber
84 1 tkerber
        return pre * I
85 1 tkerber
86 1 tkerber
    def get_waasmaier(self, symbol, s):
87 1 tkerber
        """Scattering factor for free atoms."""
88 1 tkerber
        if symbol == 'H':
89 1 tkerber
            # XXXX implement analytical H
90 1 tkerber
            return 0
91 1 tkerber
        elif waasmaier.has_key(symbol):
92 1 tkerber
            abc = waasmaier[symbol]
93 1 tkerber
            f = abc[10]
94 1 tkerber
            s2 = s*s
95 1 tkerber
            for i in range(5):
96 1 tkerber
                f += abc[2 * i] * exp(-abc[2 * i + 1] * s2)
97 1 tkerber
            return f
98 1 tkerber
        if self.warn:
99 1 tkerber
            print '<xrdebye::get_atomic> Element', symbol, 'not available'
100 1 tkerber
        return 0