Ejemplo n.º 1
0
 def test_e_subclass_star(self):
     d = s.Direct((1,1,1),np.array([1,1,1])*np.pi/2)
     r = s.Reciprocal(np.array([1,1,1])*np.pi*2, np.array([1,1,1])*np.pi/2)
     self.assertTrue( d.isstar(r) )
     self.assertTrue( r.isstar(d) )
     self.assertEqual( d, r.star )
     self.assertEqual( r, d.star )
Ejemplo n.º 2
0
 def test_i_iron_self_consistency(self):
     """Test with data as iron spinwaves, but test only *at* grid points."""
     d = s.Direct((2.87, 2.87, 2.87), np.pi/2*np.array((1, 1, 1)), "Im-3m")
     r = d.star
     bz = s.BrillouinZone(r) # constructs an irreducible Bz by default
     bzg = s.BZTrellisQdc(bz, 0.125)
     Q = bzg.rlu
     bzg.fill(fe_dispersion(Q), (1,), bzg.rlu, (0,3))
     # The irreducible interpolation must be used here
     # since the Brillouin zone is an *irreducible* Brillouin zone!!
     intres, _ = bzg.ir_interpolate_at(Q, False, False)
     antres = fe_dispersion(Q)
     self.assertTrue(np.isclose(np.squeeze(intres), antres).all())
Ejemplo n.º 3
0
    def test_aflow_crystaldatabase(self):
        tested = 0
        failed = 0
        errored = 0
        failed_afl = []
        failed_ratio = []
        errored_afl = []
        errored_arg = []
        hall_groups_passed = np.zeros(530, dtype='int')
        hall_groups_failed = np.zeros(530, dtype='int')
        for afl in get_aflow_lattices():
            # afl == [hall_number, basis_vector_lengths, basis_vector_angles, Hall_symbol]
            dlat = s.Direct(afl[1], afl[2], afl[3])
            tested += 1
            try:
                bz = s.BrillouinZone(dlat.star)
                vol_bz = bz.polyhedron.volume
                vol_ir = bz.ir_polyhedron.volume
                if not np.isclose(vol_ir,
                                  vol_bz / s.PointSymmetry(afl[0]).size):
                    failed += 1
                    failed_afl.append(afl)
                    failed_ratio.append(vol_ir / vol_bz *
                                        s.PointSymmetry(afl[0]).size)
                    hall_groups_failed[afl[0] - 1] += 1
                else:
                    hall_groups_passed[afl[0] - 1] += 1
            except Exception as err:
                errored += 1
                errored_afl.append(afl)
                errored_arg.append(err.args)
        if failed > 0:
            print("\nFailed to find correct irreducible Brillouin zone for",
                  failed, "out of", tested, "lattices")
            for file, rat in zip(failed_afl, failed_ratio):
                print(file, rat)
        if errored > 0:
            print("\nException raised for", errored, "out of", tested,
                  "lattices")
            for file, arg in zip(errored_afl, errored_arg):
                print(file, arg)
        print("\nHall groups passed (total =", hall_groups_passed.sum(), "of",
              tested, "tested)")
        encoded_hgp = [n2chr(x) for x in hall_groups_passed]
        for x in [encoded_hgp[i * 53:(i + 1) * 53] for i in range(10)]:
            print(''.join(x))

        self.assertTrue(failed == 0)
        self.assertTrue(errored == 0)
Ejemplo n.º 4
0
def make_dr(a, b, c, al=np.pi / 2, be=np.pi / 2, ga=np.pi / 2, hall=1):
    """Make a Direct and Reciprocal lattice from Direct lattice parameters."""
    d = s.Direct(a, b, c, al, be, ga, hall)
    r = d.star
    return (d, r)
Ejemplo n.º 5
0
    def test_nacl(self):
        # load numpy arrays from the compressed binary pack
        nacl = getLoad(np.load,'test_5_gamma.npz')
        # construct the NaCl direct lattice
        basis_vec = nacl['basis_vectors']
        atom_pos = nacl['atom_positions']
        atom_idx = nacl['atom_index']
        dlat = s.Direct(basis_vec, atom_pos, atom_idx, 'P1')
        dlat.spacegroup = s.Symmetry(nacl['spacegroup_mat'],nacl['spacegroup_vec'])
        # use it to construct an irreducible Brillouin zone
        bz = s.BrillouinZone(dlat.star)
        # and use that to produce a hybrid interpolation grid
        # with parameters stored in the binary pack
        max_volume = float(nacl['grid_max_volume'])
        always_triangulate = bool(nacl['grid_always_triangulate'])
        grid = s.BZTrellisQdc(bz, max_volume, always_triangulate)

        # verify the stored grid points to ensure we have the same irreducible
        # wedge and grid
        self.assertTrue(np.allclose(grid.rlu, nacl['grid_rlu']))
        # insert the Euphonic-derived eigenvalues and eigenvectors for the grid
        # points, which are used in the interpolation
        grid.fill(
            nacl['grid_values'], nacl['grid_values_elements'], nacl['grid_values_weights'],
            nacl['grid_vectors'], nacl['grid_vectors_elements'], nacl['grid_vectors_weights'],
            bool(nacl['grid_sort']))

        # the fourth grid point is inside of the irreducible volume, which
        # ensures we avoid degeneracies
        q_ir = grid.rlu[4:5]
        # find all symmetry equivalent q within the first Brillouin zone by
        # applying each pointgroup operator to q_ir to find q_nu = R^T_nu q_ir
        q_nu = np.einsum('xji,aj->xi', dlat.pointgroup.W, q_ir)
        
        # The std::sort algorithm does not provide the same pointgroup sorting
        # on all systems, but there should be a permutation mapping:
        perm = np.array([np.squeeze(np.argwhere(np.all(np.isclose(q_nu,x),axis=1))) for x in nacl['q_nu']])
        # The permutation must be complete and unique
        self.assertTrue(np.unique(perm).size == q_nu.shape[0])
        # And the permuted q_nu must match the stored q_nu
        q_nu = q_nu[perm]
        self.assertTrue(np.allclose(q_nu, nacl['q_nu']))      
        
        # Use the grid to interpolate at each q_nu:
        br_val, br_vec = grid.ir_interpolate_at(q_nu)
        br_val = np.squeeze(br_val)
        
        # verify that q_ir does not have degeneracies:
        self.assertFalse(np.any(np.isclose(np.diff(br_val, axis=1), 0.)))
        # and that the 'interpolated' eigenvalues are identical for all q_nu
        self.assertTrue(np.allclose(np.diff(br_val, axis=0), 0.))
        # plus that the interpolated eigenvalues match the store Euphonic eigenvalues
        self.assertTrue(np.allclose(br_val, nacl['euphonic_values']))
        
        # convert the eigenvalues into the same cartesian coordinate system
        # used by Euphonic
        br_vec = np.einsum('ba,ijkb->ijka', basis_vec, br_vec)
        # load the Euphonic calculated eigenvectors
        eu_vec = nacl['euphonic_vectors']
        # The 'interpolated' eigenvectors and the Euphonic eigenvectors should
        # only be equivalent up to an overall phase factor, so find it:
        antiphase = np.exp(-1J*np.angle(np.einsum('qmij,qmij->qm', np.conj(eu_vec), br_vec)))
        # and remove the phase from the interpolated eigenvectors
        br_vec = np.einsum('ab,abij->abij', antiphase, br_vec)
        # now all eigenvectors must match
        self.assertTrue(np.allclose(br_vec, eu_vec))