def setUpBasisChanger(self): crystal = self.crystal() minimal_unit_cell = self.__minimal_unit_cell extra_atoms = self.__extra_atoms shift_origin = self.__shift_origin surface_cell = self.__surface_cell cell = np.zeros((3, 3), dtype=float) cell[:2, :2] = surface_cell cell[2, 2] = 1 surface_in_minimal = cell cell = convertFromBasis(cell, self.__minimal_unit_cell) cell = convertToIntegers(cell) cell = convertFromBasis(cell, crystal.unitCell()) orth_surface_basis = findOrthogonalBasisSet(cell) if len(extra_atoms) == 0: top = 0 else: top = np.max(extra_atoms.get_positions()[:, 2]) shift = list(shift_origin) + [top] transformations = [ Transformation(to='minimal_unit_cell', fro='surface', trans_matrix=surface_in_minimal.transpose()), Transformation(to='orth_crystal', fro='crystal', trans_matrix=crystal.unitCell().transpose()), Transformation(to='crystal', fro='minimal_unit_cell', trans_matrix=minimal_unit_cell.transpose()), Transformation(to='from_top', fro='orth_surface', rotation_point=[[0,0,0], shift]), Transformation(to='orth_crystal', fro='orth_surface', trans_matrix=orth_surface_basis.transpose()), ] basis_changer = BasisChanger(transformations=transformations) return basis_changer
def groupAtoms(atoms, order=(2,), tolerance=1e-2): atoms = atoms.copy() del atoms.constraints pbc = atoms.get_pbc() atoms.set_pbc([True]*3) cell = atoms.get_cell() positions, remainder = convertToBasis(atoms.get_positions(), cell) atoms.set_positions(positions) tolerance1 = convertToBasis(np.array([1,1,1])*tolerance, cell)[0][0] tolerance2 = convertToBasis(np.array([-1,1,-1])*tolerance, cell)[0][0] tolerance1 = map(abs, tolerance1) tolerance2 = map(abs, tolerance2) tolerance = np.max((tolerance1, tolerance2), 0) indices = np.arange(len(atoms)) groups = [(atoms, indices)] for i in order: new_groups = [] for atoms, indices in groups: while len(atoms) > 0: positions = atoms.get_positions() min_value = np.min(positions[:, i]) group_mask = abs(positions[:, i] - min_value) < tolerance[i] atom_group = atoms[group_mask] indices_group = indices[group_mask] atoms = atoms[np.logical_not(group_mask)] indices = indices[np.logical_not(group_mask)] new_groups.append((atom_group, indices_group)) groups = new_groups for atoms, indices in groups: positions = convertFromBasis(atoms.get_positions(), cell) atoms.set_positions(positions) atoms.set_cell(cell) return groups
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