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