Пример #1
0
def test_bravais_2d_cell_pbc():
    """Verify 2D Bravais lattice and band path versus pbc information."""

    from ase.cell import Cell

    cell = Cell([[1.,0.,0.],
                 [.1,1.,0.],
                 [0.,0.,0.]])
    lat = cell.get_bravais_lattice()
    print(cell.cellpar())
    print(lat)
    assert lat.name == 'OBL'

    cell[2, 2] = 7
    lat3d = cell.get_bravais_lattice()
    print(lat3d)
    assert lat3d.name == 'MCL'
    lat2d_pbc = cell.get_bravais_lattice(pbc=[1, 1, 0])
    print(lat2d_pbc)
    assert lat2d_pbc.name == 'OBL'

    path = cell.bandpath()
    print(path)

    path2d = cell.bandpath(pbc=[1, 1, 0])
    print(path2d)
    assert path2d.cell.rank == 2
    assert path2d.cell.get_bravais_lattice().name == 'OBL'
Пример #2
0
def find_niggli_ops(latcls, length_grid, angle_grid):
    niggli_ops = {}


    for lat in lattice_loop(latcls, length_grid, angle_grid):
        cell = lat.tocell()

        try:
            rcell, op = cell.niggli_reduce()
        except RuntimeError:
            print('Niggli reduce did not converge')
            continue
        assert op.dtype == int
        op_key = tuple(op.ravel())

        if op_key in niggli_ops:
            niggli_ops[op_key] += 1
        else:
            niggli_ops[op_key] = 1

        rcell_test = Cell(op.T @ cell)
        rcellpar_test = rcell_test.cellpar()
        rcellpar = rcell.cellpar()
        err = np.abs(rcellpar_test - rcellpar).max()
        assert err < 1e-7, err

    return niggli_ops
Пример #3
0
def test_monoclinic():
    """Test band structure from different variations of hexagonal cells."""
    mc1 = Cell([[1, 0, 0], [0, 1, 0], [0, 0.2, 1]])
    par = mc1.cellpar()
    mc2 = Cell.new(par)
    mc3 = Cell([[1, 0, 0], [0, 1, 0], [-0.2, 0, 1]])
    mc4 = Cell([[1, 0, 0], [-0.2, 1, 0], [0, 0, 1]])
    path = 'GYHCEM1AXH1'

    firsttime = True
    for cell in [mc1, mc2, mc3, mc4]:
        a = Atoms(cell=cell, pbc=True)
        a.cell *= 3
        a.calc = FreeElectrons(nvalence=1, kpts={'path': path})

        lat = a.cell.get_bravais_lattice()
        assert lat.name == 'MCL'
        a.get_potential_energy()
        bs = a.calc.band_structure()
        coords, labelcoords, labels = bs.get_labels()
        assert ''.join(labels) == path
        e_skn = bs.energies

        if firsttime:
            coords1 = coords
            labelcoords1 = labelcoords
            e_skn1 = e_skn
            firsttime = False
        else:
            for d in [coords - coords1,
                      labelcoords - labelcoords1,
                      e_skn - e_skn1]:
                print(abs(d).max())
                assert abs(d).max() < 1e-13, d
Пример #4
0
def format_cell(cell: Cell) -> str:
    assert cell.rank == 3
    lines = []
    for name, value in zip(CIFBlock.cell_tags, cell.cellpar()):
        line = '{:20} {:g}\n'.format(name, value)
        lines.append(line)
    assert len(lines) == 6
    return ''.join(lines)
Пример #5
0
def test_niggli_op():
    import numpy as np
    from ase.cell import Cell

    rng = np.random.RandomState(3)

    for i in range(5):
        cell = Cell(rng.rand(3, 3))
        print(cell.cellpar())
        rcell, op = cell.niggli_reduce()
        print(op)
        rcell1 = Cell(op.T @ cell)

        rcellpar = rcell.cellpar()
        rcellpar1 = rcell1.cellpar()
        err = np.abs(rcellpar - rcellpar1).max()
        print(err)
        assert err < 1e-10, err
Пример #6
0
def check_single(name, cell, pbc=None):
    c = Cell(cell, pbc=pbc)
    try:
        lattice = c.get_bravais_lattice()
    except RuntimeError:
        print('error checking {}'.format(name))
        raise
    name1 = lattice.name.lower()
    latname = name.split('@')[0]
    ok = latname == name1
    print(name, '-->', name1, 'OK' if ok else 'ERR', c.cellpar())
    assert ok, 'Expected {latname} but found {name1}'.format(latname, name1)
Пример #7
0
    def check_single(name, cell, pbc=None):
        c = Cell(cell)

        try:
            print('TEST', c, pbc)
            if pbc[:2].all() or sum(pbc) == 1:
                lattice = c.get_bravais_lattice(pbc=pbc)
            else:
                with must_raise(UnsupportedLattice):
                    lattice = c.get_bravais_lattice(pbc=pbc)
                return
        except RuntimeError:
            print('error checking {}'.format(name))
            raise
        name1 = lattice.name.lower()
        latname = name.split('@')[0]
        ok = latname == name1
        print(name, '-->', name1, 'OK' if ok else 'ERR', c.cellpar())
        assert ok, 'Expected {} but found {}'.format(latname, name1)
Пример #8
0
"""Verify 2D Bravais lattice and band path versus pbc information."""

from ase.cell import Cell

cell = Cell([[1., 0., 0.], [.1, 1., 0.], [0., 0., 0.]])
lat = cell.get_bravais_lattice()
print(cell.cellpar())
print(lat)
assert lat.name == 'OBL'

cell[2, 2] = 7
lat3d = cell.get_bravais_lattice()
print(lat3d)
assert lat3d.name == 'MCL'
lat2d_pbc = cell.get_bravais_lattice(pbc=[1, 1, 0])
print(lat2d_pbc)
assert lat2d_pbc.name == 'OBL'

path = cell.bandpath()
print(path)

path2d = cell.bandpath(pbc=[1, 1, 0])
print(path2d)
assert path2d.cell.rank == 2
assert path2d.cell.get_bravais_lattice().name == 'OBL'
Пример #9
0
def get_2d_bravais_lattice(origcell, eps=2e-4, *, pbc=True):

    pbc = origcell.any(1) & pbc2pbc(pbc)
    if list(pbc) != [1, 1, 0]:
        raise UnsupportedLattice(
            'Can only get 2D Bravais lattice of cell with '
            'pbc==[1, 1, 0]; but we have {}'.format(pbc))

    nonperiodic = pbc.argmin()
    # Start with op = I
    ops = [np.eye(3)]
    for i in range(-1, 1):
        for j in range(-1, 1):
            op = [[1, j], [i, 1]]
            if np.abs(np.linalg.det(op)) > 1e-5:
                # Only touch periodic dirs:
                op = np.insert(op, nonperiodic, [0, 0], 0)
                op = np.insert(op, nonperiodic, ~pbc, 1)
                ops.append(np.array(op))

    def allclose(a, b):
        return np.allclose(a, b, atol=eps)

    symrank = 0
    for op in ops:
        cell = Cell(op.dot(origcell))
        cellpar = cell.cellpar()
        angles = cellpar[3:]
        # Find a, b and gamma
        gamma = angles[~pbc][0]
        a, b = cellpar[:3][pbc]

        anglesm90 = np.abs(angles - 90)
        # Maximum one angle different from 90 deg in 2d please
        if np.sum(anglesm90 > eps) > 1:
            continue

        all_lengths_equal = abs(a - b) < eps

        if all_lengths_equal:
            if allclose(gamma, 90):
                lat = SQR(a)
                rank = 5
            elif allclose(gamma, 120):
                lat = HEX2D(a)
                rank = 4
            else:
                lat = CRECT(a, gamma)
                rank = 3
        else:
            if allclose(gamma, 90):
                lat = RECT(a, b)
                rank = 2
            else:
                lat = OBL(a, b, gamma)
                rank = 1

        op = lat.get_transformation(origcell, eps=eps)
        if not allclose(
                np.dot(op, lat.tocell())[pbc][:, pbc],
                origcell.array[pbc][:, pbc]):
            msg = ('Cannot recognize cell at all somehow! {}, {}, {}'.format(
                a, b, gamma))
            raise RuntimeError(msg)
        if rank > symrank:
            finalop = op
            symrank = rank
            finallat = lat

    return finallat, finalop.T
Пример #10
0
import numpy as np
from ase.cell import Cell

rng = np.random.RandomState(3)

for i in range(5):
    cell = Cell(rng.rand(3, 3))
    print(cell.cellpar())
    rcell, op = cell.niggli_reduce()
    print(op)
    rcell1 = Cell(op.T @ cell)

    rcellpar = rcell.cellpar()
    rcellpar1 = rcell1.cellpar()
    err = np.abs(rcellpar - rcellpar1).max()
    print(err)
    assert err < 1e-10, err