Пример #1
0
    def test_products(self):

        p = 5

        np.random.seed(13)

        n = 3
        Vx = np.random.random(n)
        Vy = np.random.random(n)
        Vz = np.random.random(n)

        V_r = displacive.products(Vx, Vy, Vz, p)

        V_r = V_r.reshape(displacive.number(np.arange(p + 1)).sum(), n)

        np.testing.assert_array_almost_equal(V_r[0, :], Vx**0 * Vy**0 * Vz**0)

        np.testing.assert_array_almost_equal(V_r[1, :], Vx**1 * Vy**0 * Vz**0)
        np.testing.assert_array_almost_equal(V_r[2, :], Vx**0 * Vy**1 * Vz**0)
        np.testing.assert_array_almost_equal(V_r[3, :], Vx**0 * Vy**0 * Vz**1)

        np.testing.assert_array_almost_equal(V_r[4, :], Vx**2 * Vy**0 * Vz**0)
        np.testing.assert_array_almost_equal(V_r[5, :], Vx**1 * Vy**1 * Vz**0)
        np.testing.assert_array_almost_equal(V_r[6, :], Vx**0 * Vy**2 * Vz**0)
        np.testing.assert_array_almost_equal(V_r[7, :], Vx**1 * Vy**0 * Vz**1)
        np.testing.assert_array_almost_equal(V_r[8, :], Vx**0 * Vy**1 * Vz**1)
        np.testing.assert_array_almost_equal(V_r[9, :], Vx**0 * Vy**0 * Vz**2)
Пример #2
0
    def displacive_parameters(self, p, centering):

        coeffs = displacive.coefficients(p)

        start = (np.cumsum(displacive.number(np.arange(p + 1))) -
                 displacive.number(np.arange(p + 1)))[::2]
        end = np.cumsum(displacive.number(np.arange(p + 1)))[::2]

        even = []
        for k in range(len(end)):
            even += range(start[k], end[k])
        even = np.array(even)

        nuclear = ['P', 'I', 'F', 'R', 'C', 'A', 'B']

        cntr = np.argwhere([x in centering for x in nuclear])[0][0]

        cntr += 1

        return coeffs, even, cntr
Пример #3
0
    def test_coefficients(self):

        p = 5

        coeffs = displacive.coefficients(p)

        numbers = displacive.number(np.arange(p + 1))

        self.assertEqual(coeffs.size, numbers.sum())
        self.assertEqual(coeffs[0], 1)

        even = np.isreal(coeffs)
        odd = ~np.isreal(coeffs)

        end = np.cumsum(numbers)
        start = end - numbers

        self.assertTrue(even[start[0]:end[0]].all())
        self.assertTrue(odd[start[1]:end[1]].all())
        self.assertTrue(even[start[2]:end[2]].all())
        self.assertTrue(odd[start[3]:end[3]].all())
        self.assertTrue(even[start[4]:end[4]].all())
        self.assertTrue(odd[start[5]:end[5]].all())

        self.assertAlmostEqual(coeffs[0], 1)

        self.assertAlmostEqual(coeffs[1], 1j)
        self.assertAlmostEqual(coeffs[2], 1j)
        self.assertAlmostEqual(coeffs[3], 1j)

        self.assertAlmostEqual(coeffs[4], -0.5)
        self.assertAlmostEqual(coeffs[5], -1)
        self.assertAlmostEqual(coeffs[6], -0.5)
        self.assertAlmostEqual(coeffs[7], -1)
        self.assertAlmostEqual(coeffs[8], -1)
        self.assertAlmostEqual(coeffs[9], -0.5)
Пример #4
0
def intensity(U_k, A_k, Q_k, coeffs, cond, p, i_dft, factors, subtract=True):
    """
    Chemical scattering intensity.

    Parameters
    ----------
    U_k : 1d array
        Fourier transform of Taylor expansion displacement products
    A_k : 1d array
        Fourier transform of relative site occupancies
    Q_k : 1d array
        Fourier transform of Taylor expansion wavevector products
    coeffs : 1d array
        Taylor expansion coefficients
    cond : 1d array
        Array indices corresponding to nuclear Bragg peaks
    p : int
        Order of Taylor expansion
    i_dft: 1d array, int
        Array indices of Fourier transform corresponding to reciprocal space
    factors: 1d array
        Prefactors of form factors, phase factors, and composition factors

    Returns
    -------
    I : 1d array
        Array has a flattened shape of size ``i_dft.shape[0]``

    """

    n_prod = coeffs.shape[0]

    n_peaks = i_dft.shape[0]

    n_atm = factors.shape[0] // n_peaks

    factors = factors.reshape(n_peaks, n_atm)

    n_uvw = U_k.shape[0] // n_prod // n_atm

    U_k = U_k.reshape(n_prod, n_uvw, n_atm)
    A_k = A_k.reshape(n_prod, n_uvw, n_atm)
    Q_k = Q_k.reshape(n_prod, n_peaks)

    start = (np.cumsum(number(np.arange(p + 1))) -
             number(np.arange(p + 1)))[::2]
    end = np.cumsum(number(np.arange(p + 1)))[::2]

    even = []

    for k in range(len(end)):
        even += range(start[k], end[k])

    even = np.array(even)

    V_k = np.einsum('ijk,kj->ji', coeffs*(U_k[:,i_dft,:]+\
                                          A_k[:,i_dft,:]).T, Q_k)
    V_k_nuc = np.einsum('ijk,kj->ji',
                        (coeffs[even]*(U_k[:,i_dft,:][even,:]+\
                                       A_k[:,i_dft,:][even,:]).T),
                        Q_k[even,:])[cond]

    prod = factors * V_k
    prod_nuc = factors[cond, :] * V_k_nuc

    F = np.sum(prod, axis=1)
    F_nuc = np.sum(prod_nuc, axis=1)

    if subtract:
        F[cond] -= F_nuc

        I = np.real(F)**2 + np.imag(F)**2
        return I / (n_uvw * n_atm)
    else:
        F_bragg = np.zeros(F.shape, dtype=complex)
        F_bragg[cond] = F_nuc

        I = np.real(F)**2 + np.imag(F)**2
        return I / (n_uvw * n_atm), F_bragg
Пример #5
0
def structure(U_k, A_k, Q_k, coeffs, cond, p, i_dft, factors):
    """
    Partial displacive structure factor.

    Parameters
    ----------
    U_k : 1d array
        Fourier transform of Taylor expansion displacement products
    A_k : 1d array
        Fourier transform of relative site occupancies times Taylor expansion
        displacement products
    Q_k : 1d array
        Fourier transform of Taylor expansion wavevector products
    coeffs : 1d array
        Taylor expansion coefficients
    cond : 1d array
        Array indices corresponding to nuclear Bragg peaks
    p : int
        Order of Taylor expansion
    i_dft: 1d array, int
        Array indices of Fourier transform corresponding to reciprocal space
    factors: 1d array
        Prefactors of scattering lengths, phase factors, and occupancies

    Returns
    -------
    F : 1d array
        Array has a flattened shape of size ``coeffs.shape[0]*i_dft.shape[0]``
    F_nuc : 1d array
        Array has a flattened shape of size ``cond.sum()*i_dft.shape[0]``
    prod : 1d array
        Array has a flattened shape of size
        ``coeffs.shape[0]*i_dft.shape[0]*n_atm``
    prod_nuc : 1d array
        Array has a flattened shape of size
        ``coeffs.sum()*i_dft.shape[0]*n_atm``
    V_k : 1d array
        Array has a flattened shape of size
        ``coeffs.shape[0]*i_dft.shape[0]*n_atm``
    V_k_nuc : 1d array
        Array has a flattened shape of size
        ``coeffs.sum()*i_dft.shape[0]*n_atm``
    even : 1d array, int
        Array indices of the even Taylor expandion coefficients
    bragg : 1d array, int
        Array has a flattened shape of size ``coeffs.sum()``

    """

    n_prod = coeffs.shape[0]

    n_peaks = i_dft.shape[0]

    n_atm = factors.shape[0] // n_peaks

    factors = factors.reshape(n_peaks, n_atm)

    n_uvw = U_k.shape[0] // n_prod // n_atm

    U_k = U_k.reshape(n_prod, n_uvw, n_atm)
    A_k = A_k.reshape(n_prod, n_uvw, n_atm)
    Q_k = Q_k.reshape(n_prod, n_peaks)

    start = (np.cumsum(number(np.arange(p + 1))) -
             number(np.arange(p + 1)))[::2]
    end = np.cumsum(number(np.arange(p + 1)))[::2]

    even = []

    for k in range(len(end)):
        even += range(start[k], end[k])

    even = np.array(even)

    V_k = np.einsum('ijk,kj->ji', coeffs*(U_k[:,i_dft,:]+\
                                          A_k[:,i_dft,:]).T, Q_k)
    V_k_nuc = np.einsum('ijk,kj->ji',
                        (coeffs[even]*(U_k[:,i_dft,:][even,:]+\
                                       A_k[:,i_dft,:][even,:]).T),
                        Q_k[even,:])[cond]

    prod = factors * V_k
    prod_nuc = factors[cond, :] * V_k_nuc

    F = np.sum(prod, axis=1)
    F_nuc = np.sum(prod_nuc, axis=1)

    bragg = np.arange(n_peaks)[cond]

    return F, \
           F_nuc, \
           prod.flatten(), \
           prod_nuc.flatten(), \
           V_k.flatten(), \
           V_k_nuc.flatten(), \
           even, \
           bragg
Пример #6
0
    def test_numbers(self):

        m = np.arange(10)
        n = displacive.numbers(m)

        np.testing.assert_array_equal(np.diff(n), displacive.number(m[1:]))
Пример #7
0
    def test_number(self):

        m = np.arange(10)
        n = displacive.number(m)

        np.testing.assert_array_equal(np.diff(n), 2 + m[:-1])