def test_B2(): from numpy import all from pylada.ce import cluster_factory from pylada.crystal import binary # test multi-lattice with different occupations. lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] a = cluster_factory(lattice, B2=1) assert len(a) == 2 assert all(a[0].spins['sublattice'] == [0, 1]) assert all(abs(a[0].spins['position'][0]) < 1e-8) vector = a[0].spins[1] assert abs(sum((lattice[vector[1]].pos + vector[0])**2) - 3*0.25*0.25) < 1e-8 assert all(a[1].spins['sublattice'] == [1, 0]) assert all(abs(a[1].spins['position'][0]) < 1e-8) assert all(abs(a[1].spins['position'][1]) < 1e-8) a = cluster_factory(lattice, B2=2) assert len(a) == 4 a = cluster_factory(lattice, B2=3) assert len(a) == 6 # test multi-lattice with same occupations. lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge'] a = cluster_factory(lattice, B2=1) assert len(a) == 1 a = cluster_factory(lattice, B2=2) assert len(a) == 2 a = cluster_factory(lattice, B2=3) assert len(a) == 3
def test_occmap(): from numpy import cos, sin, pi, abs, all from pylada.crystal import binary from pylada.ce import Cluster lattice = binary.zinc_blende() for atom in lattice: atom.type = ['Si', 'Ge'] a = Cluster(lattice) mapping = a.occupation_mapping() assert len(mapping) == len(lattice) assert len(mapping[0]) == 2 assert len(mapping[1]) == 2 assert abs(mapping[0]['Si'] - cos(2e0*pi*0e0/2.0)) < 1e-8 assert abs(mapping[0]['Ge'] - cos(2e0*pi*1e0/2.0)) < 1e-8 assert abs(mapping[1]['Si'] - cos(2e0*pi*0e0/2.0)) < 1e-8 assert abs(mapping[1]['Ge'] - cos(2e0*pi*1e0/2.0)) < 1e-8 lattice = binary.zinc_blende() lattice[1].type = ['Si', 'Ge', 'C'] a = Cluster(lattice) mapping = a.occupation_mapping() assert len(mapping) == len(lattice) assert mapping[0] is None assert len(mapping[1]) == len(lattice[1].type) assert all(abs(mapping[1]['C'] - [cos(2e0*pi*0e0/3.0), sin(2e0*pi*2e0/3.0)])) assert all(abs(mapping[1]['Si'] - [cos(2e0*pi*1e0/3.0), sin(2e0*pi*1e0/3.0)])) assert all(abs(mapping[1]['Ge'] - [cos(2e0*pi*2e0/3.0), sin(2e0*pi*2e0/3.0)]))
def test_J1(): from numpy import all from pylada.ce import cluster_factory from pylada.crystal import binary # test multi-lattice with different occupations. lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] a = cluster_factory(lattice, J1=True) assert len(a) == 2 assert all(all(abs(u.spins['position']) < 1e-8) for u in a) assert a[0].spins['sublattice'] == 0 assert a[1].spins['sublattice'] == 1 # test multi-lattice with same occupations. lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge'] a = cluster_factory(lattice, J1=True) assert len(a) == 1 assert all(all(abs(u.spins['position']) < 1e-8) for u in a) assert a[0].spins['sublattice'] == 0
def test_B3(): from numpy import all from pylada.ce import cluster_factory from pylada.crystal import binary def topos(s): return lattice[s[1]].pos + s[0] # test multi-lattice with different occupations. lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] a = cluster_factory(lattice, B3=1) assert len(a) == 2 for cluster in a: assert all(abs(abs(topos(cluster.spins[1]) - topos(cluster.spins[0])) - 0.25) < 1e-8) assert all(abs(abs(topos(cluster.spins[2]) - topos(cluster.spins[0])) - 0.25) < 1e-8) # test multi-lattice with same occupations. lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge'] a = cluster_factory(lattice, B3=1) assert len(a) == 1 for cluster in a: assert all(abs(abs(topos(cluster.spins[1]) - topos(cluster.spins[0])) - 0.25) < 1e-8) assert all(abs(abs(topos(cluster.spins[2]) - topos(cluster.spins[0])) - 0.25) < 1e-8)
def test_single_counting(): from pylada.crystal import binary, supercell from pylada.vff import build_tree a = binary.zinc_blende() a = supercell(binary.zinc_blende(), [[4, 0, 0], [0, 2, 0], [0, 0, 1]]) b = build_tree(a, overlap=0.5) n = 0 for center in b: for endpoint, vector in center.sc_bond_iter(): n += 1 for other, v in endpoint.sc_bond_iter(): assert other is not center assert id(center) in [id(c) for c, v in endpoint] assert n == 2 * len(a)
def test_onsite(): """ Tests J0 PI calculation. This uses the same algorithmic pathway as more complex figures, but can be easily computed as the sum of particular specie-dependent terms on each site. """ from numpy import dot, abs, all from random import choice from pylada.crystal import binary, supercell from pylada.ce import Cluster lattice = binary.zinc_blende() for atom in lattice: atom.type = ['Si', 'Ge', 'C'] structure = binary.zinc_blende() for atom in structure: atom.type = 'Si' a = Cluster(lattice) # Empty cluster first assert abs(a(structure) - len(structure)) < 1e-8 for i in xrange(10): superstructure = supercell(lattice, dot(lattice.cell, get_cell())) for atom in superstructure: atom.type = choice(atom.type) assert abs(a(superstructure) - len(superstructure)) < 1e-8 # Try on-site cluster. # loop over random supercells. # PI should be number of proportional to number of each atomic type on each # site, or thereabouts mapping = a.occupation_mapping() for i in xrange(10): # create random superstructure superstructure = supercell(lattice, dot(lattice.cell, get_cell())) for atom in superstructure: atom.type = choice(atom.type) # now first and second site clusters for i, site in enumerate(lattice): # loop over flavors. types = [u.type for u in superstructure] a.spins = None a.add_spin(site.pos) s = mapping[i].itervalues().next().copy() s[:] = 0e0 for t in site.type: s += float(types.count(t)) * mapping[i][t] assert all(abs(a(superstructure) - s) < 1e-8)
def test_disorder(lim=8): from numpy import all, array, dot from numpy.random import random, randint from numpy.linalg import det from pylada.crystal import binary, supercell from pylada.vff import build_tree lattice = binary.zinc_blende() for i in xrange(10): cell = randint(-lim, lim, (3,3)) while det(cell) == 0: cell = randint(-lim, lim, (3,3)) a = supercell(lattice, dot(lattice.cell, cell)) b = build_tree(a, overlap=0.8) ids = [id(node.center) for node in b] connections = array([ sorted([ids.index(id(n.center)) for n, v in node]) for node in b ]) epsilon = random((3,3)) * 0.1 epsilon = epsilon + epsilon.T a.cell += dot(epsilon, a.cell) for atom in a: atom.pos += dot(epsilon, atom.pos) b = build_tree(a, overlap=0.8) c = array([ sorted([ids.index(id(n.center)) for n, v in node]) for node in b ]) assert all(connections == c) b = build_tree(a, overlap=0.8) for atom in a: atom.pos += random(3) * 0.05 - 0.025 c = array([ sorted([ids.index(id(n.center)) for n, v in node]) for node in b ]) assert all(connections == c) return a
def test_tree(): from numpy import all, array, dot, sum, any from pylada.crystal import binary, supercell from pylada.vff import build_tree a = binary.zinc_blende() a = supercell(binary.zinc_blende(), [[2, 0, 0], [0, 2, 0], [0, 0, 1]]) b = build_tree(a, overlap=0.5) for center in b: positions = [] for i, (bond, vector) in enumerate(center): position = bond.pos + dot(a.cell, vector) assert abs(sum((position - center.pos)**2) - 0.25*0.25*3) < 1e-8 assert all( [any(abs(array(p) - position[None, :]) > 1e-8) for p in positions] ) positions.append(position) assert i == 3
def test_translations(cell): from numpy import abs, all from pylada.crystal import binary, supercell, HFTransform from pylada.decorations import Transforms lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] # create random structure structure = supercell(lattice, cell) hft = HFTransform(lattice, structure) # these are all the translations translations = Transforms(lattice).translations(hft) assert translations.shape == (len(structure) // len(lattice) - 1, len(structure)) # compute each translation and gets decorations for atom in structure: if atom.site != 0: continue # create translation trans = atom.pos - lattice[0].pos if all(abs(trans) < 1e-8): continue # figure out its index index = hft.index(trans) - 1 for site in structure: pos = site.pos - lattice[site.site].pos i = hft.index(pos, site.site) j = hft.index(pos + trans, site.site) assert translations[index, i] == j
def test_inas(): from numpy import identity, abs, all, dot, array from pylada.crystal.binary import zinc_blende from quantities import eV, angstrom vff = functional() structure = zinc_blende() structure[0].type = 'In' structure[1].type = 'As' structure.scale = 6.5 #2.62332 * 2 / sqrt(3) / 0.529177 out = vff._pyeval(structure) assert abs(out.energy - 0.34958768908 * eV) < 1e-8 assert abs(out.energy - vff.energy(structure)) < 1e-8 assert all(abs(out.stress - vff.jacobian(structure)[0]) < 1e-8) assert all(abs(out.stress - identity(3) * -0.04096678 * eV/angstrom**3) < 1e-8) assert all(abs(out[0].gradient) < 1e-8) assert all(abs(out[1].gradient) < 1e-8) epsilon = array([[1e0, 0.1, 0], [0.1, 1e0, 0], [0, 0, 1e0]]) structure.cell = dot(epsilon, structure.cell) for atom in structure: atom.pos = dot(epsilon, atom.pos) out = vff._pyeval(structure) assert abs(out.energy - 0.527010806043 * eV) < 1e-8 assert abs(out.energy - vff.energy(structure)) < 1e-8 assert all(abs(out.stress - [[ -2.50890474e-02, -2.95278697e-02, 0], [ -2.95278697e-02, -2.50890474e-02, 0], [ 0, 0, -1.85427515e-02]] * eV / angstrom**3) < 1e-6) assert all(abs(out.stress - vff.jacobian(structure)[0]) < 1e-8) assert all(abs(out[0].gradient - [0, 0, 1.09205526] * eV / angstrom) < 1e-6) assert all(abs(out[1].gradient - [0, 0, -1.09205526] * eV / angstrom) < 1e-6) assert all(abs([u.gradient for u in out] - vff.jacobian(structure)[1].magnitude) < 1e-8)
def test_toarray(): """ Tests label exchange """ from random import choice from numpy import all, zeros from pylada.crystal import binary, supercell, HFTransform from pylada.decorations import Transforms lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] transforms = Transforms(lattice) lattice = transforms.lattice for u in range(11): structure = supercell(lattice, get_cell()) for atom in structure: atom.type = choice(atom.type) hft = HFTransform(lattice, structure) a = transforms.toarray(hft, structure) b = zeros(len(structure), dtype='int') for atom in structure: site = lattice[atom.site] b[hft.index(atom.pos - site.pos, atom.site)] = site.type.index(atom.type) + 1 assert all(a == b)
def test_zb(): from numpy import all, abs, dot from pylada.crystal import space_group, transform, binary from pylada.crystal.cppwrappers import equivalent structure = binary.zinc_blende() ops = space_group(structure) assert len(ops) == 24 for op in ops: assert op.shape == (4, 3) other = transform(structure, op) assert all(abs(dot(op[:3], structure.cell)-other.cell) < 1e-8) for a, atom in zip(structure, other): assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8) assert a.type == atom.type assert equivalent(structure, other, cartesian=False) assert equivalent(other, structure, cartesian=False) for atom in structure: atom.type = ['A', 'B'] ops = space_group(structure) assert len(ops) == 48 for op in ops: assert op.shape == (4, 3) other = transform(structure, op) assert all(abs(dot(op[:3], structure.cell)-other.cell) < 1e-8) for a, atom in zip(structure, other): assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8) assert a.type == atom.type assert equivalent(structure, other, cartesian=False) assert equivalent(other, structure, cartesian=False)
def test_cmp(): """ Test Cluster._contains function """ from numpy import all, any from pylada.crystal import binary from pylada.ce import Cluster from pylada.ce.cluster import spin lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] def cmp(a,b): if len(a) != len(b): return False return all([any([all(v == s) for s in a]) for v in b]) a = Cluster(lattice) a.add_spin(lattice[0].pos) assert cmp(a.spins, [spin([0, 0, 0], 0)]) assert not cmp(a.spins, [spin([0.5, 0.5, 0.5], 0)]) assert not cmp(a.spins, [spin([0, 0, 0], 1)]) a = Cluster(lattice) a.add_spin(lattice[1].pos) assert cmp(a.spins, [spin([0, 0, 0], 1)]) assert not cmp(a.spins, [spin([0.5, 0.5, 0.5], 1)]) assert not cmp(a.spins, [spin([0, 0, 0], 0)]) a.add_spin(lattice[0].pos) assert cmp(a.spins, [spin([0, 0, 0], 1), spin([0, 0, 0])]) assert cmp(a.spins, [spin([0, 0, 0]), spin([0, 0, 0], 1)]) assert not cmp(a.spins, [spin([0, 0, 0], 1), spin([0, 0, 0]), spin([1, 0, 0])]) assert not cmp(a.spins, [spin([1, 0, 0]), spin([0, 0, 0], 1)])
def test_zb(): from numpy import all, abs, dot from pylada.crystal import space_group, transform, binary structure = binary.zinc_blende() ops = space_group(structure) assert len(ops) == 24 for op in ops: assert op.shape == (4, 3) other = transform(structure, op) assert all(abs(dot(op[:3], structure.cell) - other.cell) < 1e-8) for a, atom in zip(structure, other): assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8) assert a.type == atom.type for atom in structure: atom.type = ['A', 'B'] ops = space_group(structure) assert len(ops) == 48 for op in ops: assert op.shape == (4, 3) other = transform(structure, op) assert all(abs(dot(op[:3], structure.cell) - other.cell) < 1e-8) for a, atom in zip(structure, other): assert all(abs(dot(op[:3], a.pos) + op[3] - atom.pos) < 1e-8) assert a.type == atom.type
def test_angle(): from pylada.crystal import binary, supercell from pylada.vff import build_tree a = binary.zinc_blende() a = supercell(binary.zinc_blende(), [[4, 0, 0], [0, 2, 0], [0, 0, 1]]) b = build_tree(a, overlap=0.5) for center in b: ids = [id(u.center) for u, d in center] angles = set([(id(u.center), id(v.center)) for (u, d), (v, d) in center.angle_iter()]) for i, ida in enumerate(ids[:-1]): for idb in ids[i+1:]: if (ida, idb) in angles: assert (idb, ida) not in angles else: assert (idb, ida) in angles assert len(angles) == 6
def test_random(): from numpy import dot, all, abs from numpy.random import randint from random import choice from pylada.ce import Cluster from pylada.crystal import binary, supercell lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] # now try random clusters with cell and their supercells for i in xrange(10): # random cluster a = Cluster(lattice) site = choice([0, 1]) a.add_spin(lattice[site].pos) for j in xrange(4): site = choice([0, 1]) pos = lattice[site].pos + dot(lattice.cell, randint(4, size=(3,))-2) try: a.add_spin(pos) except ValueError: pass # random structure structure = supercell(lattice, dot(lattice.cell, get_cell(3))) for atom in structure: atom.type = choice(lattice[atom.site].type) # random supercell for j in xrange(5): sp = supercell(structure, dot(structure.cell, get_cell(3))) for atom in sp: atom.site = structure[atom.site].site assert all(abs(a(sp) - len(sp) / len(structure) * a(structure)) < 1e-8)
def test_labelexchange(): """ Tests label exchange """ from pylada.crystal import binary, supercell, HFTransform from pylada.decorations import Transforms lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] transforms = Transforms(lattice) lattice = transforms.lattice structure = supercell(lattice, [[8, 0, 0], [0, 0.5, 0.5], [0, -0.5, 0.5]]) species = ['Ge', 'C', 'Si', 'C', 'Si', 'C', 'Si', 'Si', 'Ge', 'Si', 'Ge', 'Si', 'Ge', 'Si', 'Ge', 'Ge', 'Ge', 'C', 'Ge', 'Si', 'Si', 'Si', 'Si', 'Ge', 'Si', 'Ge', 'Si', 'Si', 'Si', 'C', 'Ge', 'Si'] for atom, s in zip(structure, species): atom.type = s hft = HFTransform(lattice, structure) x = transforms.toarray(hft, structure) results = [21112222221111123331111231122131, # <- this is x 21112222221111122221111321133121, 21112222221111123332222132211232, 21112222221111121112222312233212, 21112222221111122223333123311323, 21112222221111121113333213322313, 12221111112222213331111231122131, 12221111112222212221111321133121, 12221111112222213332222132211232, 12221111112222211112222312233212, 12221111112222212223333123311323, 12221111112222211113333213322313] permutations = transforms.label_exchange(hft) for a, b in zip(permutations(x), results[1:]): assert int(str(a)[1:-1].replace(' ', '')) == b
def test_symmetrized(): """ Tests that symmetrized clusters are determined correctly. """ from numpy import all, any from pylada.ce import Cluster from pylada.crystal import binary, neighbors lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge'] a = Cluster(lattice) a.add_spin(lattice[0].pos) a.add_spin(lattice[0].pos + [0.0, -0.5, -0.5]) a._create_symmetrized() assert len(a._symmetrized) == 2 * 12 for i, (atom, vec, d) in enumerate(neighbors(lattice, 16, lattice[0].pos)): if i < 4: continue b = Cluster(lattice) b.add_spin(lattice[0].pos) b.add_spin(vec) assert any(all(b.spins == u) for u in a._symmetrized) for i, (atom, vec, d) in enumerate(neighbors(lattice, 16, lattice[1].pos)): if i < 4: continue b = Cluster(lattice) b.add_spin(lattice[1].pos) b.add_spin(vec) assert any(all(b.spins == u) for u in a._symmetrized) lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] a = Cluster(lattice) a.add_spin(lattice[1].pos) a.add_spin(lattice[1].pos + [1.0, 0, 0]) a._create_symmetrized() assert len(a._symmetrized) == 6 for i, (atom, vec, d) in enumerate(neighbors(lattice, 24, lattice[0].pos)): if i < 16: continue b = Cluster(lattice) b.add_spin(lattice[1].pos) b.add_spin(vec) assert any(all(b.spins == u) for u in a._symmetrized)
def test_write_gulp_zinc_blende(): """ Tries and writes a gulp file. """ from numpy import array, abs, all from pylada.crystal.binary import zinc_blende from pylada.crystal.write import gulp a = zinc_blende() string = [u.rstrip().lstrip() for u in gulp(a).splitlines()] string = [u for u in string if len(u) > 0] assert string[0] == 'name' assert string[1] == 'Zinc-Blende' assert string[2] == 'vectors' assert all(abs(array(string[3].split(), dtype='float64') - [0, 0.5, 0.5]) < 1e-8) assert all(abs(array(string[4].split(), dtype='float64') - [0.5, 0, 0.5]) < 1e-8) assert all(abs(array(string[5].split(), dtype='float64') - [0.5, 0.5, 0]) < 1e-8) assert string[6] == 'cartesian' assert string[7].split()[:2] == ['A', 'core'] assert all(abs(array(string[7].split()[2:], dtype='float64')) < 1e-8) assert string[8].split()[:2] == ['B', 'core'] assert all(abs(array(string[8].split()[2:], dtype='float64') - [0.25, 0.25, 0.25]) < 1e-8) string2 = gulp(a, symmgroup=216).splitlines() string2 = [u.rstrip().lstrip() for u in string2] string2 = [u for u in string2 if len(u) > 0] assert string2[:6] == string[:6] assert string2[6] == 'spacegroup' assert string2[7] == '216' assert string2[8:] == string[6:] a.symmgroup = 216 string = gulp(a).splitlines() string = [u.rstrip().lstrip() for u in string] string = [u for u in string if len(u) > 0] assert string2 == string a[0].asymmetric = True a[1].asymmetric = False string = gulp(a).splitlines() string = [u.rstrip().lstrip() for u in string] string = [u for u in string if len(u) > 0] assert string2[:-1] == string del a[0].asymmetric string = gulp(a).splitlines() string = [u.rstrip().lstrip() for u in string] string = [u for u in string if len(u) > 0] assert string2 == string del a[1].asymmetric a[1].type = 'A' a.symmgroup = 227 string = gulp(a).splitlines() string = [u.rstrip().lstrip() for u in string] string = [u for u in string if len(u) > 0] assert string2[:7] == string[:7] assert string[7] == '227' assert string2[8:-1] == string[8:]
def testzb(): """ Tries and writes a gulp file. """ from numpy import array, abs, all from pylada.crystal.binary import zinc_blende from pylada.crystal.write import gulp a = zinc_blende() string = [u.rstrip().lstrip() for u in gulp(a).splitlines()] string = [u for u in string if len(u) > 0] assert string[0] == "name" assert string[1] == "Zinc-Blende" assert string[2] == "vectors" assert all(abs(array(string[3].split(), dtype="float64") - [0, 0.5, 0.5]) < 1e-8) assert all(abs(array(string[4].split(), dtype="float64") - [0.5, 0, 0.5]) < 1e-8) assert all(abs(array(string[5].split(), dtype="float64") - [0.5, 0.5, 0]) < 1e-8) assert string[6] == "cartesian" assert string[7].split()[:2] == ["A", "core"] assert all(abs(array(string[7].split()[2:], dtype="float64")) < 1e-8) assert string[8].split()[:2] == ["B", "core"] assert all(abs(array(string[8].split()[2:], dtype="float64") - [0.25, 0.25, 0.25]) < 1e-8) string2 = gulp(a, symmgroup=216).splitlines() string2 = [u.rstrip().lstrip() for u in string2] string2 = [u for u in string2 if len(u) > 0] assert string2[:6] == string[:6] assert string2[6] == "spacegroup" assert string2[7] == "216" assert string2[8:] == string[6:] a.symmgroup = 216 string = gulp(a).splitlines() string = [u.rstrip().lstrip() for u in string] string = [u for u in string if len(u) > 0] assert string2 == string a[0].asymmetric = True a[1].asymmetric = False string = gulp(a).splitlines() string = [u.rstrip().lstrip() for u in string] string = [u for u in string if len(u) > 0] assert string2[:-1] == string del a[0].asymmetric string = gulp(a).splitlines() string = [u.rstrip().lstrip() for u in string] string = [u for u in string if len(u) > 0] assert string2 == string del a[1].asymmetric a[1].type = "A" a.symmgroup = 227 string = gulp(a).splitlines() string = [u.rstrip().lstrip() for u in string] string = [u for u in string if len(u) > 0] assert string2[:7] == string[:7] assert string[7] == "227" assert string2[8:-1] == string[8:]
def test(): import gc from numpy import all, abs, ones from sys import getrefcount from pylada.crystal.binary import zinc_blende from pylada.error import ValueError, AttributeError from pylada.vff import Node structure = zinc_blende() assert getrefcount(structure[0]) == 2 # structure, getrefcount arg. nodeA = Node(structure[0], 0)
def test_J0(): from pylada.ce import cluster_factory from pylada.crystal import binary lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] a = cluster_factory(lattice, J0=True) assert len(a) == 1 assert a[0].order == 0
def test_zincblende(): from pylada.crystal import binary from pylada.enum import generate_bitstrings from zincblendesets import zincblendesets lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Ga'] for n in xrange(2, 8): result = [] for x, hft, hermite in generate_bitstrings(lattice, [n]): result.append( ''.join(str(i) for i in hermite.flatten()[[0, 3, 4, 6, 7, 8]]) + ' ' + ''.join(str(i-1) for i in x) ) assert len(result) == len(zincblendesets[n]) assert set(result) == zincblendesets[n]
def test_firstisid(cell): """ Assumption is made in Transforms.transformations """ from numpy import abs, all, identity from pylada.crystal import binary, supercell, space_group lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] # create random structure structure = supercell(lattice, cell) while len(structure) > 1: structure.pop(-1) assert len(structure) == 1 sg = space_group(structure)[0] assert all(abs(sg[:3] - identity(3, dtype='float64')) < 1e-8) assert all(abs(sg[3]) < 1e-8)
def create_jobs(): """ Simple job-folders. """ from pylada.jobfolder import JobFolder from pylada.crystal.binary import zinc_blende root = JobFolder() for name, value, species in zip( ['diamond', 'diamond/alloy', 'GaAs'], [0, 1, 2], [('Si', 'Si'), ('Si', 'Ge'), ('Ga', 'As')] ): job = root / name job.functional = functional job.params['value'] = value job.params['structure'] = zinc_blende() for atom, specie in zip(job.structure, species): atom.type = specie return root
def test_spins_are_sorted(): """ Check spin sorting when using add_spins. """ from numpy import all, dot from numpy.random import randint from random import choice from itertools import permutations from pylada.ce.cluster import spin from pylada.ce import Cluster from pylada.crystal import binary lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] # Trial with known result. a = Cluster(lattice) a.add_spin(lattice[1].pos) a.add_spin(lattice[0].pos + [0.5, 0, 0.5]) a.add_spin(lattice[1].pos + [-0.5, 0, 0.5]) a.add_spin(lattice[0].pos + [-2.5, -1.0, 0.5]) assert all(a.spins[0] == spin([0, 0, 0], 1)) assert all(a.spins[1] == spin([0.5, 0, 0.5])) assert all(a.spins[2] == spin([-0.5, 0, 0.5], 1)) assert all(a.spins[3] == spin([-2.5, -1.0, 0.5], 0)) spins = a.spins.copy() for p in permutations(range(len(spins))): a = Cluster(lattice) for i in p: a.add_spin(spins[i]['position'] + lattice[spins[i]['sublattice']].pos) assert all(a.spins == spins) # Trial with unknown result. for i in xrange(20): a = Cluster(lattice) for j in xrange(5): site = choice([0, 1]) pos = lattice[site].pos + dot(lattice.cell, randint(4, size=(3,))-2) try: a.add_spin(pos) except ValueError: pass if a.order < 1: continue spins = a.spins.copy() for p in permutations(range(len(spins))): a = Cluster(lattice) for i in p: a.add_spin(spins[i]['position'] + lattice[spins[i]['sublattice']].pos) assert all(a.spins == spins)
def test_rotations(): from numpy import all, dot, zeros from numpy.linalg import inv from pylada.crystal import binary, supercell, HFTransform, space_group, \ which_site from pylada.enum import Transforms lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] sg = space_group(lattice) invcell = inv(lattice.cell) def get_cells(n): for i in xrange(1, n): yield [[i, 0, 0], [0, 0.5, 0.5], [0, -0.5, 0.5]] for i in xrange(1, n): yield [[i, 0, 0], [0, i, 0], [0, 0, 1]] for i in xrange(1, n): yield [[i, 0, 0], [0, i, 0], [0, 0, i]] yield dot(lattice.cell, [[1, 0, 0], [0, 1, 0], [0, 0, 2]]) for cell in get_cells(8): # create random structure structure = supercell(lattice, cell) hft = HFTransform(lattice, structure) # these are all the translations transforms = Transforms(lattice) permutations = transforms.transformations(hft) assert permutations.shape == (len(sg) - 1, len(structure)) operations = transforms.invariant_ops(structure) assert any(operations) # compute each translation and gets decorations for index, (op, isgood) in enumerate(zip(sg[1:], operations)): if not isgood: continue # Create rotation and figure out its index permutation = zeros(len(structure), dtype='int') - 1 for atom in structure: pos = dot(op[:3], atom.pos) + op[3] newsite = which_site(pos, lattice, invcell) i = hft.index(atom.pos - lattice[atom.site].pos, atom.site) j = hft.index(pos - lattice[newsite].pos, newsite) permutation[i] = j assert all(permutation == permutations[index])
def create_jobs(): """ Simple job-folders. """ from pylada.jobfolder import JobFolder from pylada.crystal.binary import zinc_blende root = JobFolder() for name, value, species in zip(['diamond', 'diamond/alloy', 'GaAs'], [0, 1, 2], [('Si', 'Si'), ('Si', 'Ge'), ('Ga', 'As')]): job = root / name job.functional = functional job.params['value'] = value job.params['structure'] = zinc_blende() for atom, specie in zip(job.structure, species): atom.type = specie return root
def test_zinc_blende_lattice_diff_occupations(): from numpy import all from pylada.crystal import binary from pylada.decorations import Transforms lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] transforms = Transforms(lattice) assert len([u for u in transforms.lattice if u.asymmetric]) == 2 assert transforms.lattice[0].asymmetric assert transforms.lattice[0].equivto == 0 assert transforms.lattice[0].nbflavors == 2 assert transforms.lattice[0].index == 0 assert transforms.lattice[0].asymmetric assert transforms.lattice[1].equivto == 1 assert transforms.lattice[1].nbflavors == 3 assert transforms.lattice[1].index == 1 assert all(all(a == b) for a, b in zip(transforms.flavors, (list(range(1)), list(range(2)))))
def test_addspins(): """ Test adding spins to cluster. Check failure modes. """ from numpy import all from pylada.crystal import binary from pylada.ce import Cluster from pylada.ce.cluster import spin from pylada.error import ValueError lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] a = Cluster(lattice) # Wrong position try: a.add_spin(lattice[0].pos+0.1) except ValueError: pass else: raise Exception() # now add first spin a.add_spin(lattice[0].pos) assert len(a.spins) == 1 assert all(a.spins[0] == spin([0, 0, 0], 0)) # try adding it again try: a.add_spin(lattice[0].pos) except ValueError: pass else: raise Exception() # Wrong position try: a.add_spin(lattice[1].pos+[1.1, -0.5, -2.5]) except ValueError: pass else: raise Exception() # Then add a different spin a.add_spin(lattice[1].pos + [1.0, -0.5, -2.5]) assert len(a.spins) == 2 assert all(a.spins[0] == spin([0, 0, 0], 0)) assert all(a.spins[1] == spin([1.0, -0.5, -2.5], 1))
def test_zinc_blende_lattice_diff_occupations(): from numpy import all from pylada.crystal import binary from pylada.decorations import Transforms lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] transforms = Transforms(lattice) assert len([u for u in transforms.lattice if u.asymmetric]) == 2 assert transforms.lattice[0].asymmetric assert transforms.lattice[0].equivto == 0 assert transforms.lattice[0].nbflavors == 2 assert transforms.lattice[0].index == 0 assert transforms.lattice[0].asymmetric assert transforms.lattice[1].equivto == 1 assert transforms.lattice[1].nbflavors == 3 assert transforms.lattice[1].index == 1 assert all( all(a == b) for a, b in zip(transforms.flavors, (list(range(1)), list(range(2)))))
def test_manysupercell(): from numpy import dot from numpy.linalg import inv, det from pylada.crystal import supercell, binary, are_periodic_images as api lattice = binary.zinc_blende() invlat = inv(lattice.cell) for i in range(10): cell = get_cell() struc = supercell(lattice, dot(lattice.cell, cell)) assert len(struc) == len(lattice) * int(abs(det(cell)) + 0.01) invcell = inv(struc.cell) for i, atom in enumerate(struc): # compare to lattice tolat = [api(atom.pos, site.pos, invlat) for site in lattice] assert tolat.count(True) == 1 assert tolat.index(True) == atom.site assert lattice[tolat.index(True)].type == atom.type # compare to self tolat = [api(atom.pos, site.pos, invcell) for site in struc] assert tolat.count(True) == 1 assert i == tolat.index(True)
def test_gradients(epsilon = 1e-4): from numpy import abs, dot, array, sqrt from pylada.crystal.binary import zinc_blende vff = functional() structure = zinc_blende() structure[0].type = 'In' structure[1].type = 'As' structure.scale = 6.5 #2.62332 * 2 / sqrt(3) / 0.529177 out = vff(structure) for atom, check in zip(structure, out): oldpos = atom.pos.copy() for dir in [[1, 0, 0], [0, 1, 0], [0, 0, 1]]: dir = array(dir) / sqrt(dot(dir, dir)) atom.pos = epsilon * dir + oldpos xplus = vff(structure).energy atom.pos = -epsilon * dir + oldpos xminus = vff(structure).energy assert abs(xplus - xminus) < 1e-8 strain = array([[1e0, 0.1, 0], [0.1, 1e0, 0], [0, 0, 1e0]]) structure.cell = dot(strain, structure.cell) for atom in structure: atom.pos = dot(strain, atom.pos) out = vff(structure) for atom, check in zip(structure, out): oldpos = atom.pos.copy() for dir in [[1, 0, 0], [0, 1, 0], [0, 0, 1]]: dir = array(dir) / sqrt(dot(dir, dir)) atom.pos = epsilon * dir + oldpos xplus = vff(structure).energy atom.pos = -epsilon * dir + oldpos xminus = vff(structure).energy deriv = (xplus - xminus).magnitude / (2e0*structure.scale * epsilon) assert abs(deriv.magnitude - dot(check.gradient, dir)) < 1e2*epsilon
def test_labelexchange(): """ Tests label exchange """ from pylada.crystal import binary, supercell, HFTransform from pylada.decorations import Transforms lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] transforms = Transforms(lattice) lattice = transforms.lattice structure = supercell(lattice, [[8, 0, 0], [0, 0.5, 0.5], [0, -0.5, 0.5]]) species = [ 'Ge', 'C', 'Si', 'C', 'Si', 'C', 'Si', 'Si', 'Ge', 'Si', 'Ge', 'Si', 'Ge', 'Si', 'Ge', 'Ge', 'Ge', 'C', 'Ge', 'Si', 'Si', 'Si', 'Si', 'Ge', 'Si', 'Ge', 'Si', 'Si', 'Si', 'C', 'Ge', 'Si' ] for atom, s in zip(structure, species): atom.type = s hft = HFTransform(lattice, structure) x = transforms.toarray(hft, structure) results = [ 21112222221111123331111231122131, # <- this is x 21112222221111122221111321133121, 21112222221111123332222132211232, 21112222221111121112222312233212, 21112222221111122223333123311323, 21112222221111121113333213322313, 12221111112222213331111231122131, 12221111112222212221111321133121, 12221111112222213332222132211232, 12221111112222211112222312233212, 12221111112222212223333123311323, 12221111112222211113333213322313 ] permutations = transforms.label_exchange(hft) for a, b in zip(permutations(x), results[1:]): assert int(str(a)[1:-1].replace(' ', '')) == b
def test_rotations(cell): from numpy import all, dot, zeros from numpy.linalg import inv from pylada.crystal import binary, supercell, HFTransform, space_group, \ which_site from pylada.decorations import Transforms lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Si', 'Ge', 'C'] sg = space_group(lattice) invcell = inv(lattice.cell) # create random structure structure = supercell(lattice, cell) hft = HFTransform(lattice, structure) # these are all the translations transforms = Transforms(lattice) permutations = transforms.transformations(hft) assert permutations.shape == (len(sg) - 1, len(structure)) operations = transforms.invariant_ops(structure) assert any(operations) # compute each translation and gets decorations for index, (op, isgood) in enumerate(zip(sg[1:], operations)): if not isgood: continue # Create rotation and figure out its index permutation = zeros(len(structure), dtype='int') - 1 for atom in structure: pos = dot(op[:3], atom.pos) + op[3] newsite = which_site(pos, lattice, invcell) i = hft.index(atom.pos - lattice[atom.site].pos, atom.site) j = hft.index(pos - lattice[newsite].pos, newsite) permutation[i] = j assert all(permutation == permutations[index])
# crystal structures, as well as to a number of DFT (VASP, CRYSTAL) and atomic potential programs. It # is able to organise and launch computational jobs on PBS and SLURM. # # PyLaDa is free software: you can redistribute it and/or modify it under the terms of the GNU General # Public License as published by the Free Software Foundation, either version 3 of the License, or (at # your option) any later version. # # PyLaDa is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even # the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along with PyLaDa. If not, see # <http://www.gnu.org/licenses/>. ############################### from pylada.crystal import binary lattice = binary.zinc_blende() lattice[0].type = ['Si', 'Ge'] lattice[1].type = ['Ga'] dummy = r""" 1 0 1 0 0 1 02 1 0 1 0 0 1 12 1 0 1 0 0 2 0122 1 0 1 0 1 2 0122 1 0 1 0 0 3 001222 1 0 1 0 0 3 011222 1 0 1 0 1 3 001222 1 0 1 0 1 3 011222 1 0 1 0 2 3 001222 1 0 1 0 2 3 011222 1 0 1 0 0 4 00012222 1 0 1 0 2 4 00012222
def test_write_gulp_zinc_blende(): """ Tries and writes a gulp file. """ from numpy import array, abs, all from pylada.crystal.binary import zinc_blende from pylada.crystal.write import gulp a = zinc_blende() string = [u.rstrip().lstrip() for u in gulp(a).splitlines()] string = [u for u in string if len(u) > 0] assert string[0] == 'name' assert string[1] == 'Zinc-Blende' assert string[2] == 'vectors' assert all( abs(array(string[3].split(), dtype='float64') - [0, 0.5, 0.5]) < 1e-8) assert all( abs(array(string[4].split(), dtype='float64') - [0.5, 0, 0.5]) < 1e-8) assert all( abs(array(string[5].split(), dtype='float64') - [0.5, 0.5, 0]) < 1e-8) assert string[6] == 'cartesian' assert string[7].split()[:2] == ['A', 'core'] assert all(abs(array(string[7].split()[2:], dtype='float64')) < 1e-8) assert string[8].split()[:2] == ['B', 'core'] assert all( abs( array(string[8].split()[2:], dtype='float64') - [0.25, 0.25, 0.25]) < 1e-8) string2 = gulp(a, symmgroup=216).splitlines() string2 = [u.rstrip().lstrip() for u in string2] string2 = [u for u in string2 if len(u) > 0] assert string2[:6] == string[:6] assert string2[6] == 'spacegroup' assert string2[7] == '216' assert string2[8:] == string[6:] a.symmgroup = 216 string = gulp(a).splitlines() string = [u.rstrip().lstrip() for u in string] string = [u for u in string if len(u) > 0] assert string2 == string a[0].asymmetric = True a[1].asymmetric = False string = gulp(a).splitlines() string = [u.rstrip().lstrip() for u in string] string = [u for u in string if len(u) > 0] assert string2[:-1] == string del a[0].asymmetric string = gulp(a).splitlines() string = [u.rstrip().lstrip() for u in string] string = [u for u in string if len(u) > 0] assert string2 == string del a[1].asymmetric a[1].type = 'A' a.symmgroup = 227 string = gulp(a).splitlines() string = [u.rstrip().lstrip() for u in string] string = [u for u in string if len(u) > 0] assert string2[:7] == string[:7] assert string[7] == '227' assert string2[8:-1] == string[8:]