Beispiel #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)
Beispiel #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)
     bzg = s.BZGridQcomplex(bz, halfN=(1, 1, 1))
     Q = bzg.rlu
     bzg.fill(fe_dispersion(Q),[1,])
     intres = bzg.interpolate_at(Q, False, False)
     antres = fe_dispersion(Q)
     self.assertTrue(np.isclose(intres, antres).all())
Beispiel #3
0
def test_aflow_crystaldatabase():
    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():
        dlat = s.Direct(afl[1], afl[2],
                        afl[0])  # use the pre-determined Hall number
        i = dlat.hall
        try:
            bz = s.BrillouinZone(dlat.star)
            vol_bz = bz.polyhedron.volume
            vol_ir = bz.ir_polyhedron.volume
            tested += 1
            if not np.isclose(vol_ir, vol_bz / s.PointSymmetry(i).size):
                failed += 1
                failed_afl.append(afl)
                failed_ratio.append(vol_ir / vol_bz * s.PointSymmetry(i).size)
                hall_groups_failed[i - 1] += 1
            else:
                hall_groups_passed[i - 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))
Beispiel #4
0
def make_drbz(a, b, c, al=np.pi / 2, be=np.pi / 2, ga=np.pi / 2):
    """Make a Direct Reicprocal and BrillouinZone object."""
    d = s.Direct(a, b, c, al, be, ga)
    r = d.star
    bz = s.BrillouinZone(r)
    return (d, r, bz)
Beispiel #5
0
 def isapprox(self, other):
     return b.Direct(self.lat).isapprox(b.Direct(other.lat))
Beispiel #6
0
 def get_conventional_Direct(self):
     return b.Direct(self.get_conventional_basis(),
                     self.get_conventional_atom_positions(),
                     self.get_conventional_atom_index(), self.hall)
Beispiel #7
0
 def get_input_Direct(self):
     return b.Direct(self.get_input_basis(),
                     self.get_input_atom_positions(),
                     self.get_input_atom_index(), self.hall)
Beispiel #8
0
    Z = np.concatenate((Z[:-1] - dX, Z[np.newaxis, -1] - dX[np.newaxis, -1],
                        Z[np.newaxis, -1] + dX[np.newaxis, -1]),
                       axis=0)
    dY = np.diff(Z, axis=1) / 2
    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)


dlat = brille.Direct((5., 5., 5.), (90., 90., 90.), 525)
bz = brille.BrillouinZone(dlat.star)
nb = load_interpolation_data('nb')

# Next investigate now choice of maximum tetrahedra size and trellis size
# effect point-interpolation time
qx, qy = np.mgrid[1 - 0.3:1 + 0.3:0.005, 1 - 0.3:1 + 0.3:0.005]

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)
energy = 4.1 + np.zeros_like(qx)
Beispiel #9
0
    Z = np.concatenate((Z[:-1] - dX, Z[np.newaxis, -1] - dX[np.newaxis, -1],
                        Z[np.newaxis, -1] + dX[np.newaxis, -1]),
                       axis=0)
    dY = np.diff(Z, axis=1) / 2
    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)


dlat = brille.Direct((10, 10, 10.), (90., 90., 90.), 525)
bz = brille.BrillouinZone(dlat.star)

# max_sizes = 1/np.arange(100,5000,500)
max_sizes = 1 / (10**np.linspace(6, 12, 5))**(1 / 3)
num_levels = np.arange(1, 5).reshape(4, 1)

print('pybind object creation times:')
it = np.nditer([max_sizes, num_levels, None, None, None])
for s, l, c, e, n in it:
    tictoc.tic()
    while not (tictoc.elapsed() > 30 or tictoc.relative_uncertainty() < 0.2):
        mesh = brille.BZNestQ(bz, max_volume=s, max_branchings=l)
        tictoc.toc()
    c[...] = tictoc.average()
    e[...] = tictoc.uncertainty()
Beispiel #10
0
if hall_sym != explicit_sym:
    print('Something has gone horribly wrong')
else:
    print('The generated space groups are equivalent! (All is well.)')
    if np.all(hall_sym.W == explicit_sym.W):
        print(
            "\tWe're extra lucky that the groups have the same-ordered motions"
        )
    else:
        print(
            "\tSymmetry group equivalency does not imply same-ordered motions")

# Now construct a real space Direct lattice a few ways:
# -F 4 3 2 is a cubic system, so all lattice basis vector lengths are the same
lat_parameters_hall_symbol = brille.Direct((1, 1, 1), (90, 90, 90), '-F 4 3 2')
# we can also provide explicit basis vectors as a matrix
# a possible pitfall: brille does not store the orientation of the basis vectors
bv = lambda t: np.array([[np.cos(t), 0, np.sin(t)], [0, 1, 0],
                         [-np.sin(t), 0, np.cos(t)]])
lat_basis_hall_symbol = brille.Direct(bv(np.random.rand() * np.pi), '-F 4 3 2')

if lat_basis_hall_symbol != lat_parameters_hall_symbol:
    print('Something has gone wrong creating the Direct lattices')

p1_cube = brille.Direct((1, 1, 1), (90, 90, 90))
# another potential pitfall, lattice equivalency does not consider spacegroups
if lat_basis_hall_symbol == p1_cube:
    print('brille Lattice equivalency ignores the Spacegroup information')
if lat_basis_hall_symbol.spacegroup != p1_cube.spacegroup:
    print('\tSo explicit checks of the spacegroup may be necessary')
Beispiel #11
0
def create_bz(*args,
              is_reciprocal=False,
              use_primitive=True,
              search_length=1,
              time_reversal_symmetry=False,
              wedge_search=True,
              **kwargs):
    """
    Construct a BrillouinZone object. 

    Parameters
    ----------
    a, b, c : float
        Lattice parameters as separate floating point values
    lens : (3,) :py:class:`numpy.ndarray` or list
        Lattice parameters as a 3-element array or list
    alpha, beta, gamma : float
        Lattice angles in degrees or radians as separate floating point values
        Brille tries to determine if the input is in degrees or radians
        by looking at its magnitude. If the values are all less than PI it
        assumes the angles are in radians otherwise it assumes degrees
    angs : (3,) :py:class:`numpy.ndarray` or list
        Lattice angles in degrees or radians as a 3-element array or list
    lattice_vectors : (3, 3) :py:class:`numpy.ndarray` or list of list
        The lattice vectors as a 3x3 matrix, array or list of list
    spacegroup: str or int
        The spacegroup in either International Tables (Hermann-Mauguin)
        notation or a Hall symbol or an integer Hall number.
    is_reciprocal : bool, keyword-only optional (default: False)
        Whether the lattice parameters or lattice vectors refers to a 
        reciprocal rather than direct lattice. If True, a/b/c/lens should
        be in reciprocal Angstrom, otherwise they should be in Angstrom
    use_primitive : bool, keyword-only optional (default: True)
        Whether the primitive (or conventional) lattice should be used
    search_length : int, keyword-only optional (default: 1)
        An integer to control how-far the vertex-finding algorithm should
        search in τ-index. The default indicates that (1̄1̄1̄), (1̄1̄0), (1̄1̄1),
        (1̄0̄1), ..., (111) are included.
    time_reversal_symmetry : bool, keyword-only optional (default: False)
        Whether to include time-reversal symmetry as an operation to
        determine the irreducible Brillouin zone
    wedge_search : bool, keyword-only optional (default: True)
        If true, return an irreducible first Brillouin zone,
        otherwise just return the first Brillouin zone

    Note
    ----
    Note that the required lattice parameters must be specified as:
        - EITHER ``create_bz(a, b, c, alpha, beta, gamma, spacegroup, ...)``
        - OR     ``create_bz(lens, angs, spacegroup, ...)``
        - OR     ``create_bz(lattice_vectors, spacegroup, ...)``

    E.g. you cannot mix specifing `a`, `b`, `c`, and `angs` etc.
    """
    # Take keyword arguments in preference to positional ones
    a, b, c, alpha, beta, gamma, lens, angs = (
        kwargs.pop(pname, None)
        for pname in ['a', 'b', 'c', 'alpha', 'beta', 'gamma', 'lens', 'angs'])
    no_lat_kw_s = any([v is None for v in [a, b, c, alpha, beta, gamma]])
    no_lat_kw_v = any([v is None for v in [lens, angs]])
    if no_lat_kw_v and not no_lat_kw_s:
        lens, angs = ([a, b, c], [alpha, beta, gamma])
    lattice_vectors = kwargs.pop('lattice_vectors', None)
    spacegroup = kwargs.pop('spacegroup', None)
    # Parse positional arguments
    spg_id = 0
    if no_lat_kw_s and no_lat_kw_v and lattice_vectors is None:
        if np.shape(args[0]) == ():
            lens, angs = (args[:3], args[3:6])
            spg_id = 6
        elif np.shape(args[0]) == (3, ):
            lens, angs = tuple(args[:2])
            spg_id = 2
        elif np.shape(args[0]) == (3, 1) or np.shape(args[0]) == (1, 3):
            lens, angs = tuple(args[:2])
            lens = np.squeeze(np.array(lens))
            angs = np.squeeze(np.array(angs))
            spg_id = 2
        elif np.shape(args[0]) == (3, 3):
            lattice_vectors = args[0]
            spg_id = 1
        else:
            raise ValueError('No lattice parameters or vectors given')
    if spacegroup is None:
        if len(args) > spg_id:
            spacegroup = args[spg_id]
        else:
            raise ValueError('Spacegroup not given')
    if not isinstance(spacegroup, str):
        try:
            spacegroup = int(spacegroup)
        except TypeError as e0:
            e1 = ValueError(
                'Invalid spacegroup input. It must be a string or number')
            e1.__suppress_context__ = True
            e1.__traceback__ = e0.__traceback__
            raise e1

    if is_reciprocal:
        if lattice_vectors is not None:
            lattice = brille.Reciprocal(lattice_vectors, spacegroup)
        else:
            lattice = brille.Reciprocal(lens, angs, spacegroup)
    else:
        if lattice_vectors is not None:
            lattice = brille.Direct(lattice_vectors, spacegroup)
        else:
            lattice = brille.Direct(lens, angs, spacegroup)
        lattice = lattice.star

    try:
        return brille.BrillouinZone(
            lattice,
            use_primitive=use_primitive,
            search_length=search_length,
            time_reversal_symmetry=time_reversal_symmetry,
            wedge_search=wedge_search)
    except RuntimeError as e0:
        # We set wedge_search=True by default so add a hint here.
        if 'Failed to find an irreducible Brillouin zone' in str(e0):
            e1 = RuntimeError(str(e0) + ' You can try again with wedge_search=False ' \
                            'to calculate with just the first Brillouin zone')
            e1.__suppress_context__ = True
            e1.__traceback__ = e0.__traceback__
            raise e1
        else:
            raise e0
Beispiel #12
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)