예제 #1
0
    def __init__(
            self,
            surface,
            name=DEFAULT,
            identifiers=tuple(),
            added_atoms=DEFAULT,
            periodicity=tuple(tuple()),
            charge=0,
            initial_state=DEFAULT,
            parameters=DEFAULT,
            ):
        if added_atoms is DEFAULT:
            added_atoms = Atoms([])
        self.__identifiers = convertShorthand(identifiers)
        surface = surface.copy()
        self.__periodicity = np.array(periodicity)
        self.__added_atoms = added_atoms.copy()
        self.__initial_state = initial_state
        self.__charge=charge

        API.System.__init__(
                self,
                name=name,
                sub_systems=[surface],
                initial_state=initial_state,
                parameters=parameters,
                )
예제 #2
0
class Crystal1D(Crystal):
    def __init__(
            self,
            atoms,
            parameters=DEFAULT,
            ):
        assert all(atoms.pbc == np.array([False, False, True]))
        self.__atoms = Atoms(atoms)
        API.System.__init__(
                self,
                sub_systems=tuple(),
                parameters=parameters,
                )

    def setUpBasisChanger(self):
        atoms = self.atoms()
        cell = atoms.cell

        basis_changer = BasisChanger(
                transformations=[Transformation(to='orth_crystal', fro='crystal', trans_matrix=cell.transpose())]
                )
        return basis_changer

    def pbc(self):
        return [False, False, True]

    def defaultParameters(self, parameters=DEFAULT):
        if parameters is DEFAULT:
            parameters = CrystalParameters1D()

        vectors = parameters['vectors']
        if parameters['vectors'] is DEFAULT:
            vectors = ((1,),)

        kpts = parameters['kpts']
        if kpts is DEFAULT:
            kpts = parameters.neededKpts(self.__atoms.cell[self.__atoms.pbc])

        parameters = parameters.copy(kpts=kpts, vectors=vectors)

        return parameters

    def inputAtoms(self):
        return self.__atoms.copy()

    def relaxationFactor(self):
        if self.relaxation() is None:
            return 1.0
        lr = vectorLength(self.relaxation().get_cell()[2])
        lu = vectorLength(self.__atoms.get_cell()[2])

        return lr/lu

    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

    def makeAtomsRelaxed(self, atoms, relaxation, tolerance=1):
        factor = self.relaxationFactor()
        atoms.positions *= factor
        atoms.cell[2] *= factor
        atoms = makeAtomsRelaxed(atoms, self.relaxation(), tolerance=tolerance)

        return atoms

    def unitCell(self, coordinates='orth_crystal'):
        if self.isRelaxed():
            unit_cell = self.relaxation().get_cell()
        else:
            unit_cell = self.__atoms.get_cell()

        unit_cell = unit_cell[np.array(self.pbc())]

        return self.change(unit_cell, to=coordinates, fro='orth_crystal')
예제 #3
0
class Crystal3D(Crystal):
    def __init__(
            self,
            atoms,
            parameters=DEFAULT,
            ):
        assert all(atoms.pbc == np.array([True, True, True]))
        self.__atoms = Atoms(atoms)

        Crystal.__init__(self, sub_systems=tuple(), parameters=parameters)

    def setUpBasisChanger(self):
        atoms = self.atoms()
        cell = atoms.cell

        basis_changer = BasisChanger(
                transformations=[Transformation(to='orth_crystal', fro='crystal', trans_matrix=cell.transpose())]
                )
        return basis_changer

    def unitCell(self, coordinates='orth_crystal'):
        unit_cell = np.array(self.__atoms.cell[self.__atoms.pbc])
        unit_cell *= relaxationFactor(self.__atoms, self.relaxation())

        if coordinates == 'orth_crystal':
            return unit_cell

        return self.change(unit_cell, to=coordinates, fro='orth_crystal')

    def normalVector(self, miller_indices):
        raise Exception

    def defaultParameters(self, parameters=DEFAULT):
        if parameters is DEFAULT:
            parameters = CrystalParameters3D()

        kpts = parameters['kpts']
        if kpts is DEFAULT:
            kpts = parameters.neededKpts(self.unitCell())

        vectors = parameters['vectors']
        if vectors is DEFAULT:
            vectors = ((1,0,0), (0,1,0), (0,0,1))

        parameters = parameters.copy(kpts=kpts, vectors=vectors)

        return parameters

    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

    def makeSubsystemsRelaxed(self, atoms):
        return atoms

    def makeAtomsRelaxed(self, atoms, relaxation, tolerance=1.0):
        if relaxation is None:
            return atoms

        factor = relaxationFactor(self.__atoms, relaxation)
        atoms.positions *= factor
        atoms.cell *= factor

        atoms = makeAtomsRelaxed(atoms, relaxation, tolerance=tolerance)

        for electrode in atoms.electrodes():
            electrode.setCell(electrode.cell()*factor)

        return atoms

    def pbc(self):
        return [True, True, True]