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