Exemplo n.º 1
0
    def atoms(self, constrained=True, parameters=DEFAULT):
        if parameters is DEFAULT:
            parameters = self.parameters()
        parameters = self.defaultParameters(parameters)
        vectors = np.array(parameters['vectors'])

        lengths = vectorLength(vectors, 1)
        assert lengths.all()

        atoms = self.__atoms.copy()
        pos = atoms.get_positions()
        size = np.array([pos[:, i].max() - pos[:,i].min() for i in range(3)])
        size = size + parameters['length_scales']['correlation_length']

        repeats = (1, 1, vectors[0][0])
        vectors = atoms.cell[2] * vectors[0][0]

        atoms = atoms.repeat(repeats)
        atoms.set_cell(size)
        atoms.cell[2] = vectors
        atoms = removeCopies(atoms)
        atoms = orderAtoms(atoms)

        atoms = self.makeAtomsRelaxed(atoms, self.relaxation())

        return atoms
Exemplo n.º 2
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
Exemplo n.º 3
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
Exemplo n.º 4
0
    def crystalAtoms(self,
                     start_layer=0,
                     end_layer=1,
                     coordinates='orth_surface',
                     vectors=((1,0),(0,1)),
                     sub_layers=False,
                     minimal=True,
                     ):
        sl = slice(start_layer, end_layer)
        if minimal:
            unit_cell = self.minimalCell('crystal')
        else:
            unit_cell = self.cell('crystal')
        catoms = self.crystal().atoms()
        catoms.purgeTags()
        atoms = makeSlabWithVectors(catoms, unit_cell, sl.stop)
        atoms = self.change(atoms, to=coordinates, fro='orth_crystal')
        unit_cell = self.crystal().change(unit_cell, to='orth_crystal', fro='crystal',
                                    difference=True,)[:2]
        unit_cell = self.change(unit_cell, to='orth_surface', fro='orth_crystal')

        if len(atoms)==0:
            return atoms

        if minimal:
            vectors = unit_cell
        else:
            vectors = np.array(vectors)
            vectors = np.dot(unit_cell.transpose(), vectors.transpose()).transpose()
            repeats = fitBoxIntoBox(unit_cell, vectors)
            atoms = atoms.repeat(list(repeats) + [1])

        out_vector = atoms.cell[2]
        out_vector[:2] = 0
        vectors = np.array([vectors[0], vectors[1], out_vector])

        atoms.set_cell(vectors)
        atoms.set_pbc([True, True, False])
        atoms = removeCopies(atoms)
        atoms.wrap()
        atoms = orderAtoms(atoms, (2, 1, 0))


        if sub_layers:
            groups = groupAtoms(atoms)[sl]
            if len(groups) == 0:
                return Atoms([], cell=atoms.get_cell(), pbc=atoms.get_pbc())

            atoms, indices = groups[0]
            for atoms_group, indices in groups[1:]:
                atoms += atoms_group

        return atoms
Exemplo n.º 5
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
Exemplo n.º 6
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
Exemplo n.º 7
0
    def atoms(self, constrained=True, parameters=DEFAULT):
        parameters = self.defaultParameters(parameters)
        vectors = np.array(parameters['vectors'])

        lengths = vectorLength(vectors, 1)
        assert lengths.all()

        atoms = self.__atoms.copy()

        vectors = convertFromBasis(vectors, atoms.cell)
        repeats = findNeededRepetitions(atoms.cell, 1.5*lengths.max())

        atoms = atoms.repeat(repeats)
        atoms.cell[atoms.pbc] = vectors
        atoms.wrap()
        atoms = removeCopies(atoms)
        atoms.setTag('Reference', picker=None)

        padding = np.logical_not(atoms.pbc)
        assert padding.sum() == 0

        atoms = self.makeAtomsRelaxed(atoms, self.relaxation())

        return atoms