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')