예제 #1
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')