Exemple #1
0
    def test_a(self):
        """Test whether SimPhony gives the same result *at* grid points.

        This test should always pass, since the BZGridQcomplex object is filled
        by calculating eigen-energies and eigen-vectors using SimPhony.
        Unfortunately, due to rounding errors, this test can fail to run if an
        out-of-bounds interpolation point is required by brille.

        The moveinto keyword is what makes it possible to verify the
        "interpolation" result against the SimPhony result. This same keyword
        also opens up the possibility of rounding-errors leading to a runtime
        error of brille.
        With the moveinto keyword omitted (or set to True), out-of-zone grid
        points *will* likely have different polarization vectors compared to
        the SimPhony result as one interpolates at q=Q-τ and the other
        calculates at Q. It's unclear if this difference is important for
        intensity calculations.
        """
        i_data = load_interpolation_data('nb')
        symsim = BrEu(i_data, halfN=(2, 2, 2))

        q_rlu = symsim.grid.rlu
        int_freq, int_vecs = symsim.frqs_vecs(q_rlu,
                                              interpolate=True,
                                              moveinto=False)
        sim_freq, sim_vecs = symsim.frqs_vecs(q_rlu, interpolate=False)

        ad_freq = np.abs(int_freq - sim_freq).magnitude
        as_freq = np.abs(int_freq + sim_freq).magnitude
        # Check if |interpolated-simulated|/|interpolated+simulated|>1e-14
        # AND if |interpolated-simulated|>1e-14
        unequal_freq = (ad_freq > 1e-14 * as_freq) * (ad_freq > 1e-14)
        self.assertFalse(unequal_freq.any())

        # The vectors only need to be equal up to an arbitrary phase
        # which is equivalent to saying that the inner product between
        # equal ion eigenvectors for each branch should have ||ϵ⋅ϵ||²≡1
        n_pt, n_br, n_io, n_d = int_vecs.shape
        int_vecs = int_vecs.reshape(n_pt * n_br * n_io, n_d)
        sim_vecs = sim_vecs.reshape(n_pt * n_br * n_io, n_d)
        product = [hermitian_product(x, y) for x, y in zip(int_vecs, sim_vecs)]

        self.assertTrue(np.isclose(np.abs(product), 1).all())
    def test_NaCl(self):
        # fetch and load the NaCl.castep_bin file from the brille repository
        idata = get_InterpolationData_object('NaCl')
        # Do not sort the modes on neighbouring trellis vertices to make comparison with Euphonic easier
        breu = BrEu(idata, sort=False, trellis=True, max_volume=0.1, parallel=False)
        # pick a trellis Q vertex inside the irreducible polyhedron, away from the boundaries:
        q_ir = breu.grid.rlu[6:7] # shape = (1,3)
        # pull together the pointgroup operations
        ptgr = b.PointSymmetry(breu.grid.BrillouinZone.lattice.hall)
        # and apply each to q_ir to find q_nu = R^T_nu q_ir
        q_nu = np.einsum('xji,aj->xi', ptgr.W, q_ir)

        # use brille to find eigenenergies and eigenvectors at each q_nu
        # this *should* be only an application of the rotation, so
        #   all omega_nu are expected to be identical
        #   and all epsilon_nu will be permuted as Gamma(q|nu) dictates
        br_omega_nu, br_epsilon_nu = breu.frqs_vecs(q_nu, interpolate=True)
        # use Euphonic to diagonalise the dynamical matrix at each q_nu
        eu_omega_nu, eu_epsilon_nu = breu.frqs_vecs(q_nu, interpolate=False)

        # verify that all brille eigenvalues are identical for each q_nu
        self.assertTrue(np.allclose(np.diff(br_omega_nu.magnitude, axis=0), 0.))
        # and that these results match the Euphonic results
        self.assertTrue(np.allclose(br_omega_nu.magnitude, eu_omega_nu.magnitude))
        # Now that we're sure the permutation is the same, we can verify the eigenvectors
        # brille stores and returns eigenvectors expressed in units of the conventional direct lattice
        # while euphonic calculates, returns, and stores them in a cartesian coordinate system defined
        # relative to the lattice by its lat_vec matrix.
        # A brille.spglib method handles conversion between these descriptions:
        br_epsilon_nu_xyz = breu.brspgl.conventional_to_orthogonal_eigenvectors(br_epsilon_nu)

        # The eigenvectors returned by brille and those from Euphonic should be the same up to an overall complex phase factor
        # the eigenvectors are normalised, so the phase is calculated directly
        antiphase_per_q_per_mode = np.exp(-1J*np.angle(np.einsum('qmij,qmij->qm', np.conj(eu_epsilon_nu), br_epsilon_nu_xyz)))
        # and removed from the cartesian coordinate eigenvectors
        br_epsilon_nu_xyz_phased = np.array([[x0*y0 for x0,y0 in zip(x,y)] for x,y in zip(antiphase_per_q_per_mode, br_epsilon_nu_xyz)])
        # now all eigenvectors returned from brille should be the same as
        # calculated by Euphonic directly
        self.assertTrue(np.allclose(br_epsilon_nu_xyz_phased, eu_epsilon_nu))
Exemple #3
0
# SQWS = (SQW_0, SQW_N, SQW_S)
# times =(intt, part, simt)
# uncer =(intu, paru, simu)
# FIG_0, AX_0 = pp.subplots(1, len(SQWS))
# for i, (dat, t,u) in enumerate(zip(SQWS,times,uncer)):
#     pp.sca(AX_0[i])
#     pp.pcolormesh(px, py, np.real(dat.reshape(inshape)), shading='flat')
#     pp.title('{:5.3f}±{:5.3f} s'.format(t,u))
#     pp.axis('square')
#
# pp.show()
#

q = np.random.rand(10000, 3) * 10

senb = BrEu(nb, mesh=True, parallel=True, max_size=0.0001, lattice_ratio=2.)

tictoc.tic()
while not (tictoc.elapsed() > 60 or tictoc.relative_uncertainty() < 0.05):
    senb(q, interpolate=False)
    tictoc.toc()
eu_time_point = tictoc.average() / q.shape[0] * 10**6
eu_delt_point = tictoc.uncertainty() / q.shape[0] * 10**6

nthreads = np.arange(1, os.cpu_count() // 2 + 1, dtype='int')
it = np.nditer([nthreads, None, None], op_dtypes=('int', 'double', 'double'))
for n, t, u in it:
    tictoc.tic()
    while not (tictoc.elapsed() > 60 or tictoc.relative_uncertainty() < 0.05):
        senb(q, threads=n)
        tictoc.toc()
Exemple #4
0
 def test_b(self):
     """Do something."""
     i_data = load_interpolation_data('nb')
     symsim = BrEu(i_data, halfN=(10, 10, 10))
     print(symsim.grid.centre_sort_perm())
Exemple #5
0
        axis=1)
    return Z


def pcolormesh(X, Y, Z, *args, **kwargs):
    return pp.pcolormesh(cen2corner(X), cen2corner(Y), Z, *args, **kwargs)


tictoc.tic()
nb = load_interpolation_data('La2Zr2O7')
details['euphonic_load_seconds'] = tictoc.toc()

q = np.random.rand(100000, 3) * 10 - 5

tictoc.tic()
senb = BrEu(nb, trellis=True, parallel=True, max_volume=0.0001)
details['breu_setup_seconds'] = tictoc.toc()

tictoc.tic()
while not (tictoc.elapsed() > 30 or tictoc.relative_uncertainty() < 0.05):
    senb.w_q(q, interpolate=False)
    tictoc.toc()
eu_time_point = tictoc.average() / q.shape[0] * 10**6
eu_delt_point = tictoc.uncertainty() / q.shape[0] * 10**6

details['euphonic_us_per_point'] = eu_time_point
details['euphonic_us_per_point_uncertainty'] = eu_delt_point

it = np.nditer([details['n_threads'], None, None],
               op_dtypes=('int', 'double', 'double'))
for n, t, u in it:
    dX = np.diff(X, axis=0) / 2
    X = np.concatenate((X[:-1] - dX, X[np.newaxis, -1] - dX[np.newaxis, -1],
                        X[np.newaxis, -1] + dX[np.newaxis, -1]),
                       axis=0)
    dY = np.diff(X, axis=1) / 2
    X = np.concatenate(
        (X[:, :-1] - dY, X[:, np.newaxis, -1] - dY[:, np.newaxis, -1],
         X[:, np.newaxis, -1] + dY[:, np.newaxis, -1]),
        axis=1)
    return X


# Construct a brille BZTrellisQdc object from a Euphonic object.
# parallel=False ensures the Euphonic C module is *not* used.
nacl = BrEu(get_InterpolationData_object('NaCl'),
            trellis=True,
            max_volume=1e-5,
            parallel=False)
# but we want to use the brille C++ module
nacl.parallel = True

# Define a path through reciprocal space from (000) to (123)
xi = np.linspace(0, 1, 100)
qhkl = np.vstack((xi, 2 * xi, 3 * xi)).T
# Interpolate the mode energies at qhkl
w_q = nacl.w_q(qhkl).magnitude

bz = nacl.grid.BrillouinZone
# plot the first Brillouin zones for (000), (111), (022), and (113) and path
fig = pp.figure(figsize=pp.figaspect(2))
ax = fig.add_axes([0, 0, 1, 1], projection='3d')
ax.view_init(5, 300)
Exemple #7
0
    return pp.pcolormesh(cen2corner(X), cen2corner(Y), Z, *args, **kwargs)


# Next investigate now choice of tetrahedra levels size
# effect point-interpolation time
q = np.random.rand(10000,3)*10
nb = load_interpolation_data('nb')

max_sizes = 1/(10**np.linspace(6,12,5))**(1/3)
num_levels = np.arange(1,7).reshape(6,1)

print('Interpolation of {} points:'.format(q.shape[0]))
it = np.nditer([max_sizes,num_levels, None, None, None],op_dtypes=('double','int','double','double','double'))
for m, n, s, i, ie in it:
    tictoc.tic()
    se = BrEu(nb, mesh=True, max_size=m, num_levels=n)
    s[...] = tictoc.toc()
    tictoc.tic()
    while not (tictoc.elapsed() > 5 or tictoc.relative_uncertainty() < 0.01):
    # while not (tictoc.elapsed() > 1 or tictoc.relative_uncertainty() < 0.5):
        se.w_q(q)
        tictoc.toc()
    i[...] = tictoc.average()
    ie[...] = tictoc.uncertainty()
    print('levels {:d}: <time>={:5.3f}({:5.3f}) sum(time)={:5.2f} sec'.format(n,i,ie,tictoc.elapsed()))
setup_time = it.operands[2]
interpolation_time = it.operands[3]
interpolation_uncertainty = it.operands[4]

# pp.figure()
# pp.errorbar(num_levels, interpolation_time, yerr=interpolation_uncertainty, marker='o', linestyle='-')
Exemple #8
0
    Z = np.concatenate(
        (Z[:, :-1] - dY, Z[:, np.newaxis, -1] - dY[:, np.newaxis, -1],
         Z[:, np.newaxis, -1] + dY[:, np.newaxis, -1]),
        axis=1)
    return Z


def pcolormesh(X, Y, Z, *args, **kwargs):
    return pp.pcolormesh(cen2corner(X), cen2corner(Y), Z, *args, **kwargs)


nb = load_interpolation_data('nb')

q = np.random.rand(10000, 3) * 10 - 5

senb = BrEu(nb, nest=True, parallel=True, max_volume=0.0001, max_branchings=5)

tictoc.tic()
while not (tictoc.elapsed() > 60 or tictoc.relative_uncertainty() < 0.05):
    senb.w_q(q, interpolate=False)
    tictoc.toc()
eu_time_point = tictoc.average() / q.shape[0] * 10**6
eu_delt_point = tictoc.uncertainty() / q.shape[0] * 10**6

nthreads = np.arange(1, os.cpu_count() // 2 + 1, dtype='int')
it = np.nditer([nthreads, None, None], op_dtypes=('int', 'double', 'double'))
for n, t, u in it:
    tictoc.tic()
    while not (tictoc.elapsed() > 20 or tictoc.relative_uncertainty() < 0.05):
        senb.w_q(q, threads=n)
        tictoc.toc()
Exemple #9
0
    return pp.pcolormesh(cen2corner(X), cen2corner(Y), Z, *args, **kwargs)


# Next investigate now choice of tetrahedra levels size
# effect point-interpolation time
q = np.random.rand(10000, 3) * 10
nb = load_interpolation_data('nb')

max_sizes = 1 / (10**np.linspace(6, 12, 5))**(1 / 3)

print('Interpolation of {} points:'.format(q.shape[0]))
it = np.nditer([max_sizes, None, None, None],
               op_dtypes=('double', 'double', 'double', 'double'))
for m, s, i, ie in it:
    tictoc.tic()
    se = BrEu(nb, trellis=True, max_volume=m)
    s[...] = tictoc.toc()
    tictoc.tic()
    while not (tictoc.elapsed() > 5 or tictoc.relative_uncertainty() < 0.01):
        # while not (tictoc.elapsed() > 1 or tictoc.relative_uncertainty() < 0.5):
        se.w_q(q)
        tictoc.toc()
    i[...] = tictoc.average()
    ie[...] = tictoc.uncertainty()
    print('max volume {:f}: <time>={:5.3f}({:5.3f}) sum(time)={:5.2f} sec'.
          format(m, i, ie, tictoc.elapsed()))
setup_time = it.operands[1]
interpolation_time = it.operands[2]
interpolation_uncertainty = it.operands[3]

# pp.figure()
Exemple #10
0
# inshape = qx.shape
# px = cen2corner(qx)
# py = cen2corner(qy)

qx = qx.reshape(qx.size, 1)
qy = qy.reshape(qy.size, 1)
qxyz = np.concatenate((qx, qy, 0 * qx), axis=1)

nb = load_interpolation_data('nb')

interpolation_trellis_ratios = 2**np.arange(-3, 1.51, 0.1)

print('Interpolation of {} points:'.format(qx.size))
it = np.nditer([interpolation_trellis_ratios, None, None])
for tr, i, ie in it:
    se = BrEu(nb, mesh=True, max_size=0.01, lattice_ratio=tr)
    tictoc.tic()
    while not (tictoc.elapsed() > 5 or tictoc.relative_uncertainty() < 0.01):
        # while not (tictoc.elapsed() > 1 or tictoc.relative_uncertainty() < 0.5):
        se(qxyz)
        tictoc.toc()
    i[...] = tictoc.average()
    ie[...] = tictoc.uncertainty()
    print(
        'ratio {:6.4f}: <time>={:5.3f}({:5.3f}) sum(time)={:5.2f} sec'.format(
            tr, i, ie, tictoc.elapsed()))
interpolation_time = it.operands[1]
interpolation_uncertainty = it.operands[2]

pp.figure()
pp.errorbar(interpolation_trellis_ratios,
Exemple #11
0
    Z = np.concatenate(
        (Z[:, :-1] - dY, Z[:, np.newaxis, -1] - dY[:, np.newaxis, -1],
         Z[:, np.newaxis, -1] + dY[:, np.newaxis, -1]),
        axis=1)
    return Z


def pcolormesh(X, Y, Z, *args, **kwargs):
    return pp.pcolormesh(cen2corner(X), cen2corner(Y), Z, *args, **kwargs)


nb = load_interpolation_data('nb')

q = np.random.rand(10000, 3) * 10

senb = BrEu(nb, mesh=True, parallel=True, max_size=0.0001, num_levels=5)

tictoc.tic()
while not (tictoc.elapsed() > 60 or tictoc.relative_uncertainty() < 0.05):
    senb.w_q(q, interpolate=False)
    tictoc.toc()
eu_time_point = tictoc.average() / q.shape[0] * 10**6
eu_delt_point = tictoc.uncertainty() / q.shape[0] * 10**6

nthreads = np.arange(1, os.cpu_count() // 2 + 1, dtype='int')
it = np.nditer([nthreads, None, None], op_dtypes=('int', 'double', 'double'))
for n, t, u in it:
    tictoc.tic()
    while not (tictoc.elapsed() > 20 or tictoc.relative_uncertainty() < 0.05):
        senb.w_q(q, threads=n)
        tictoc.toc()