def __init__(self, lattice=None, basis=None, coords=None, cartesian=False, wrap_coords=False): super().__init__() if basis is None: basis = BasisAtoms() else: basis = BasisAtoms(basis) basis.lattice = lattice if lattice is not None and coords is not None: for atom, pos in zip(basis, coords): atom.lattice = lattice if not cartesian: atom.rs = pos else: atom.rs = lattice.cartesian_to_fractional(pos) self.lattice = lattice self.basis = basis self.wrap_coords = wrap_coords self.fmtstr = "{lattice!r}, {basis!r}, {coords!r}, " + \ "cartesian=False, wrap_coords={wrap_coords!r}"
def __init__(self, a=lattparams['alpha_quartz']['a'], c=lattparams['alpha_quartz']['c'], **kwargs): lattice = Crystal3DLattice.hexagonal(a, c) basis = BasisAtoms(3 * ["Si"] + 6 * ["O"]) coords = [[0.4697, 0.0000, 0.0000], [0.0000, 0.4697, 0.6667], [0.5305, 0.5303, 0.3333], [0.4133, 0.2672, 0.1188], [0.2672, 0.4133, 0.5479], [0.7328, 0.1461, 0.7855], [0.5867, 0.8539, 0.2145], [0.8539, 0.5867, 0.4521], [0.1461, 0.7328, 0.8812]] alpha_quartz = pymatgen_structure(lattice.cell_matrix, basis.symbols, coords) alpha_quartz = \ Crystal3DStructure.from_pymatgen_structure(alpha_quartz) # alpha_quartz = \ # HexagonalStructure.from_spacegroup(154, a, c, ["Si", "O"], # [[0.4697, 0.0000, 0.0000], # [0.4135, 0.2669, 0.1191]], # scaling_matrix=scaling_matrix) super().__init__(structure=alpha_quartz, **kwargs)
def from_pymatgen_structure(cls, structure): atoms = BasisAtoms() for site in structure.sites: atoms.append(BasisAtom(element=site.specie.symbol, x=site.x, y=site.y, z=site.z)) return cls(lattice=Crystal2DLattice( cell_matrix=structure.lattice.matrix), basis=atoms)
def test4(): lattice = Crystal3DLattice.cubic(a=5.0) basis = BasisAtoms(atoms=['C', 'C']) print(basis) print(basis.lattice) assert_true(basis.lattice is None) basis.lattice = lattice assert_true(isinstance(basis.lattice, Crystal3DLattice))
def scaling_matrix(self, value): if value is None: self._scaling_matrix = np.asmatrix(np.ones(3, dtype=int)) return if not isinstance(value, (int, float, tuple, list, np.ndarray)): return if isinstance(value, np.ndarray) and \ ((value.shape == np.ones(3).shape and np.allclose(value, np.ones(3))) or (value.shape == np.eye(3).shape and np.allclose(value, np.eye(3)))): self._scaling_matrix = np.asmatrix(value) return if isinstance(value, numbers.Number): value = self.lattice.nd * [int(value)] scaling_matrix = np.asmatrix(value, dtype=int) # scaling_matrix = np.asmatrix(value) if scaling_matrix.shape != self.lattice.matrix.shape: scaling_matrix = np.diagflat(scaling_matrix) self._scaling_matrix = scaling_matrix self.lattice = self.lattice.__class__(cell_matrix=self.scaling_matrix * self.lattice.matrix) tvecs = \ np.asarray( np.asmatrix(supercell_lattice_points(self.scaling_matrix)) * self.lattice.matrix) basis = self.basis[:] self.basis = BasisAtoms() for atom in basis: for tvec in tvecs: xs, ys, zs = \ self.lattice.cartesian_to_fractional(atom.r + tvec) if self.wrap_coords: xs, ys, zs = \ self.lattice.wrap_fractional_coordinate( [xs, ys, zs]) self.basis.append( BasisAtom(atom.element, lattice=self.lattice, xs=xs, ys=ys, zs=zs))
def test5(): atoms = \ BasisAtoms(atoms=generate_atoms(elements='periodic_table').symbols) print(atoms[:5]) atoms_slice = atoms[5:10] atoms[:5] = atoms_slice assert_equal(atoms[:5], atoms[5:10]) print(atoms[:5]) atoms[:5] = ['C', 'H', 'N', 'Ar', 'He'] print(atoms[:8]) atoms[0] = 'Au' print(atoms[:2])
def from_pymatgen_structure(cls, structure): """Return a `Crystal3DStructure` from a \ :class:`pymatgen:pymatgen.core.Structure`. Parameters ---------- structure : :class:`pymatgen:pymatgen.core.Structure` Returns ------- :class:`Crystal3DStructure` """ atoms = BasisAtoms() for site in structure.sites: atoms.append(BasisAtom(site.specie.symbol, x=site.x, y=site.y, z=site.z)) return cls(lattice=Crystal3DLattice( cell_matrix=structure.lattice.matrix), basis=atoms)
def __init__(self, lattice=None, basis=None, coords=None, cartesian=False, wrap_coords=False, unit_cell=None, scaling_matrix=None): super().__init__() if unit_cell is None and basis is not None: basis = BasisAtoms(basis) basis.lattice = lattice if lattice is not None and coords is not None: for atom, pos in zip(basis, coords): atom.lattice = lattice if not cartesian: atom.rs = pos else: atom.rs = lattice.cartesian_to_fractional(pos) # if basis is None: # basis = BasisAtoms() # These attributes may be reset in the `@scaling_matrix.setter` # method and so they need to be initialized *before* setting # `self.scaling_matrix`. self.basis = basis self.lattice = lattice self.unit_cell = unit_cell self.wrap_coords = wrap_coords self.scaling_matrix = scaling_matrix self.fmtstr = \ "lattice={lattice!r}, basis={basis!r}, coords={coords!r}, " + \ "cartesian=False, wrap_coords={wrap_coords!r}, " + \ "unit_cell={unit_cell!r}, scaling_matrix={scaling_matrix!r}"
def generate_unit_cell(self): """Generate the nanotube unit cell.""" eps = 0.01 e1 = self.element1 e2 = self.element2 N = self.N T = self.T rt = self.rt psi, tau, dpsi, dtau = self.unit_cell_symmetry_params a = compute_dt(self.n, self.m, bond=self.bond) + 2 * self.gutter c = compute_T(self.n, self.m, bond=self.bond, length=True) lattice = Crystal3DLattice.hexagonal(a, c) basis = BasisAtoms() if self.verbose: print('dpsi: {}'.format(dpsi)) print('dtau: {}\n'.format(dtau)) for i in range(N): for j, element in enumerate((e1, e2), start=1): theta = i * psi h = i * tau if j == 2: theta += dpsi h -= dtau x = rt * np.cos(theta) y = rt * np.sin(theta) z = h while z > T - eps: z -= T if z < 0: z += T xs, ys, zs = \ lattice.cartesian_to_fractional([x, y, z]) if self.wrap_coords: xs, ys, zs = \ lattice.wrap_fractional_coordinate([xs, ys, zs]) if self.debug: print('i={}: x, y, z = ({:.6f}, {:.6f}, {:.6f})'.format( i, x, y, z)) print('xs, ys, zs = ({:.6f}, {:.6f}, {:.6f})'.format( xs, ys, zs)) # atom = BasisAtom(element, lattice=lattice, x=x, y=y, z=z) # print('i={}: x, y, z = ({:.6f}, {:.6f}, {:.6f})'.format( # i, x, y, z)) atom = BasisAtom(element, lattice=lattice, xs=xs, ys=ys, zs=zs) atom.rezero() if self.verbose: print('Basis Atom:\n{}'.format(atom)) basis.append(atom) self.unit_cell = UnitCell(lattice=lattice, basis=basis)