Skip to content

Commit

Permalink
ENH: Add a new MultiMolecule method for constructing supercells
Browse files Browse the repository at this point in the history
  • Loading branch information
BvB93 committed Jun 30, 2021
1 parent 402f141 commit 303d8de
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions FOX/classes/multi_mol.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,42 @@ def delete_atoms(self: MT, atom_subset: AtomSubset) -> MT:
ret.atoms_alias = alias_dct
return ret

def get_supercell(self: MT, supercell_size: tuple[int, int, int]) -> MT:
"""Construct a new supercell by duplicating the molecule.
Parameters
----------
supercell_size : :class:`tuple[int, int, int]`
The size of the supercell along each cartesian axes.
Returns
-------
:class:`FOX.MultiMolecule`
The new supercell constructed from **self**.
"""
if self.lattice is None:
raise ValueError(f"Cannot construct a supercell from a {self.__class__.__name__} "
"without a lattice")

# Parse and validate th
ar = np.array(supercell_size).astype(np.int64, copy=False, casting="same_kind")
if ar.shape != (3,):
raise ValueError('`duplicates` expected a sequence of length 3')
elif not (ar >= 1).all():
raise ValueError('`duplicates` values must be larger than or equal to 1')

mult = np.array([(i, j, k) for i in range(ar[0]) for j in range(ar[1]) for k in range(ar[2])])
lat = self.lattice if self.lattice.ndim == 2 else self.lattice[None, ...]
lat_trans = (lat[:, None, ...] * mult[None, ..., None]).sum(axis=-1)

mol_trans = lat_trans[..., None, :] + self[:, None, ...]
if mol_trans.shape[1] == 1:
return mol_trans[..., 0]
else:
mol, other = mol_trans[..., 0], mol_trans[..., 1:]
return mol.concatenate(mol_trans[..., 1:], lattice=lat * ar)

def concatenate(
self: MT,
other: Iterable[MT],
Expand Down

0 comments on commit 303d8de

Please sign in to comment.