Ejemplo n.º 1
0
def makeSlab(surface, pertubation_length, correlation_length):
    vectors = surface.cell(coordinates='orth_crystal')
    atoms = makeSample(surface.crystal(), vectors)
    surface.change(atoms, to='orth_surface', fro='orth_crystal')
    vectors = surface.cell(coordinates='orth_surface')

    vectors, repeats = makeLargeEnoughQuiteOrthogonalBox(vectors, pertubation_length)
    atoms = atoms.repeat(repeats)

    # Make repetitions to satisfy correlation length.
    n2 = int(numpy.ceil(correlation_length/vectors[2,2]))
    atoms = atoms.repeat((1,1,n2))

    # Wrap into box with atoms below zero in third direction.
    wrap_vectors = numpy.array([vectors[0], vectors[1], -n2*vectors[2]])
    atoms.set_cell(wrap_vectors)
    atoms = wrap(atoms)
    atoms.set_cell(vectors)
    atoms.set_pbc([True, True, False])

    # Crop number of layers.
    take = atoms.get_positions()[:, 2] > - correlation_length + 1e-5
    atoms = atoms[take]

    extra_atoms = surface.extraAtoms('orth_surface')
    repeats = fitBoxIntoBox(extra_atoms.get_cell()[:2], vectors[:2])
    repeats = list(repeats)
    repeats.append(1)
    extra_atoms = extra_atoms.repeat(tuple(repeats))
    extra_atoms.set_cell(vectors)
    extra_atoms = wrap(extra_atoms)
    extra_atoms = removeCopies(extra_atoms)
    atoms += extra_atoms

    # Passivate lower surface.
    positions = atoms.get_positions()
    z_min = min(positions[:,2])
    lower_positions = positions[(positions[:,2] < z_min + 1e-5)]
    h_positions = [position + [0,0,-0.8] for position in lower_positions]
    passivation = Atoms('H%d'%len(h_positions), h_positions)
    atoms += passivation

    # Make vaccum in the out-of-surface direction.
    z_pos = atoms.get_positions()[:, 2]
    z_min, z_max = min(z_pos), max(z_pos)
    z_diff = z_max - z_min
    tot_diff = correlation_length + z_diff
    atoms.cell[2] = numpy.array([0,0,tot_diff])
    atoms = wrap(atoms)

    # Put atoms in order.
    atoms = orderAtoms(atoms)

    # Fix lowest coordinates.
    constraint = FixAtoms(mask=(atoms.get_positions()[:, 2] < -pertubation_length + 1e-5))
    atoms.set_constraint(constraint)

    return atoms
Ejemplo n.º 2
0
def makeSample(crystal, vectors):
    radius = numpy.max(vectorLength(vectors))
    repeats = findNeededRepetitions(crystal.unitCell(), radius)
    atoms = crystal.toAseAtoms()
    atoms = atoms.repeat(repeats)
    atoms.set_cell(vectors)
    atoms = wrap(atoms)
    atoms = removeCopies(atoms)

    return atoms
Ejemplo n.º 3
0
def makeSlabWithVector(surface, vector, radius):
    v1 = numpy.zeros(3, dtype=numpy.int)
    v1[:2] = vector
    v1 = surface.change(v1, to='orth_surface', fro='surface')

    unit_cell = surface.unitCell('orth_surface')

    pro = [abs(numpy.dot(v, v1))/vectorLength(v) for v in unit_cell]
    v2 =  unit_cell[numpy.argmin(pro)]
    l1 = vectorLength(v1)
    pro = vectorLength(numpy.cross(v1/l1, v2))
    n2 = int(numpy.ceil(radius/pro))
    v2 *= n2

    v3 = surface.outOfPlaneVector('orth_surface')
    vectors = numpy.array([v1, v2, v3])
    vectors = surface.change(vectors, to='crystal', fro='orth_surface')

    layer_distance = surface.outOfPlaneVector('orth_surface')[2]
    n_layers = int(numpy.ceil(radius/layer_distance))

    atoms = makeSlabWithVectors(surface.crystal(), vectors, n_layers)
    surface.change(atoms, to='orth_surface', fro='orth_crystal')
    atoms.cell[2, :2] = 0
    atoms.set_pbc([True, True, False])
    atoms = wrap(atoms)

    # Make vaccum in the out-of-surface direction.
    z_pos = atoms.get_positions()[:, 2]
    z_min, z_max = min(z_pos), max(z_pos)
    z_diff = z_max - z_min
    tot_diff = radius + z_diff
    atoms.cell[2] = numpy.array([0,0,tot_diff])
    atoms = wrap(atoms)

    # Put atoms in order.
    atoms = orderAtoms(atoms)

    return atoms
Ejemplo n.º 4
0
def makeSlabWithVectors(atoms, vectors, n_layers):
    unit_cell = atoms.get_cell()
    vectors[2] *= -1
    vectors = numpy.dot(unit_cell.transpose(), vectors.transpose()).transpose()
    repeats = fitBoxIntoBox(unit_cell, vectors)
    atoms = atoms.repeat(repeats)
    atoms.set_cell(vectors)
    atoms = wrap(atoms)
    atoms = removeCopies(atoms)

    atoms = atoms.repeat((1,1,n_layers))

    return atoms
Ejemplo n.º 5
0
def makePeriodicSample(crystal, radius=5):
    unit_cell=crystal.unitCell()
    l_b=len(unit_cell)
    atoms = crystal.toAseAtoms()

    repeats = findNeededRepetitions(unit_cell, numpy.array([radius]*3))
    sample = atoms.repeat(repeats)

    vectors = makeQuiteOrthogonalVectors(unit_cell, repeats)

    sample.set_cell(vectors)
    sample = removeCopies(sample)
    sample = wrap(sample)

    return sample