def _grid_point_group(extent: Sequence[int], pbc: Sequence[bool]) -> PointGroup: # axis permutations # can exchange two axes iff they have the same kind of BC and length # represent open BC by setting kind[i] = -extent[i], so just have to # match these axis_perm = [] axes = np.arange(len(extent), dtype=int) extent = np.asarray(extent, dtype=int) kind = np.where(pbc, extent, -extent) ndim = len(extent) for perm in permutations(axes): if np.all(kind == kind[list(perm)]): axis_perm.append(_perm_symm(perm)) result = PointGroup(axis_perm, ndim=ndim) # reflections across axes and setting the origin # OBC axes are only symmetric w.r.t. their midpoint, (extent[i]-1)/2 origin = [] for i in axes: result = result @ PointGroup( [Identity(), _axis_reflection(i, ndim)], ndim=ndim) origin.append(0 if pbc[i] else (extent[i] - 1) / 2) result = result.elems result[0] = Identity() # it would otherwise be an equivalent PGSymmetry return PointGroup(result, ndim=ndim).change_origin(origin)
def _grid_point_group(extent: Sequence[int], pbc: Sequence[bool], color_edges: bool) -> PointGroup: """Point group of `Grid`, made up of axis permutations and flipping each axis.""" ndim = len(extent) # Cannot exchange two axes if they are colored differently; otherwise, # can only exchange them if they have the same kind of BC and length. # Represent open BC by setting kind[i] = -extent[i], so just have to match these if color_edges: result = PointGroup([Identity()], ndim=ndim) else: axis_perm = [] axes = np.arange(ndim, dtype=int) extent = np.asarray(extent, dtype=int) kind = np.where(pbc, extent, -extent) for perm in permutations(axes): if np.all(kind == kind[list(perm)]): if np.all(perm == axes): axis_perm.append(Identity()) else: axis_perm.append(_perm_symm(perm)) result = PointGroup(axis_perm, ndim=ndim) # reflections across axes and setting the origin # OBC axes are only symmetric w.r.t. their midpoint, (extent[i]-1)/2 origin = [] for i in range(ndim): result = result @ PointGroup( [Identity(), _axis_reflection(i, ndim)], ndim=ndim) origin.append(0 if pbc[i] else (extent[i] - 1) / 2) return result.change_origin(origin)
def _translations_along_axis(self, axis: int) -> PermutationGroup: """ The group of valid translations along an axis as a `PermutationGroup` acting on the sites of `self.lattice.` """ if self.lattice._pbc[axis]: trans_list = [Identity()] # note that we need the preimages in the permutation trans_perm = self.lattice.id_from_position( self.lattice.positions - self.lattice.basis_vectors[axis]) vector = np.zeros(self.lattice.ndim, dtype=int) vector[axis] = 1 trans_by_one = Translation(trans_perm, vector) for _ in range(1, self.lattice.extent[axis]): trans_list.append(trans_list[-1] @ trans_by_one) return PermutationGroup(trans_list, degree=self.lattice.n_nodes) else: return PermutationGroup([Identity()], degree=self.lattice.n_nodes)
def rotation_group(self) -> PermutationGroup: """The group of rotations (i.e. point group symmetries with determinant +1) as a `PermutationGroup` acting on the sites of `self.lattice`.""" perms = [] for p in self.point_group_.rotation_group(): if isinstance(p, Identity): perms.append(Identity()) else: # note that we need the preimages in the permutation perm = self.lattice.id_from_position( p.preimage(self.lattice.positions)) perms.append(Permutation(perm, name=str(p))) return PermutationGroup(perms, degree=self.lattice.n_nodes)