Initial Work on Reading Crystal and Creation Gaussian Input
This commit is contained in:
74
crystalpol/polarization.py
Normal file
74
crystalpol/polarization.py
Normal file
@@ -0,0 +1,74 @@
|
||||
import os
|
||||
|
||||
from crystalpol.shared.system.molecule import Molecule
|
||||
from crystalpol.shared.system.crystal import Crystal
|
||||
from crystalpol.shared.system.atom import Atom
|
||||
from crystalpol.shared.config import Config
|
||||
from crystalpol.gaussian import Gaussian
|
||||
|
||||
from typing import List
|
||||
|
||||
|
||||
class Polarization:
|
||||
__slots__ = ('geom_file', 'outfile', 'config', 'gaussian', 'crystal')
|
||||
|
||||
def __init__(self, geom_file: str, outfile: str, config: Config) -> None:
|
||||
self.crystal = None
|
||||
|
||||
self.geom_file = geom_file
|
||||
self.outfile = outfile
|
||||
self.config = config
|
||||
|
||||
self.gaussian = Gaussian(config)
|
||||
|
||||
def run(self):
|
||||
|
||||
self.read_crystal()
|
||||
|
||||
self.gaussian.run(1, self.crystal)
|
||||
|
||||
def read_crystal(self) -> None:
|
||||
with open(self.geom_file, 'r') as geom_file:
|
||||
lines = geom_file.readlines()
|
||||
|
||||
molecules = self._get_molecules_from_lines(lines)
|
||||
structure = self._get_crystal_structure(molecules[0])
|
||||
|
||||
self.crystal = Crystal([structure])
|
||||
for molecule in molecules:
|
||||
self.crystal.add_cell([molecule])
|
||||
|
||||
def _get_molecules_from_lines(self, lines: List[str]) -> List[Molecule]:
|
||||
if (len(lines) % self.config.n_atoms) == 0:
|
||||
molecules: List[Molecule] = []
|
||||
|
||||
for index, molecule in enumerate(split(lines, self.config.n_atoms)):
|
||||
mol = Molecule(f"Molecule-{index}")
|
||||
for atom_line in molecule:
|
||||
symbol, rx, ry, rz = tuple(atom_line.split())
|
||||
mol.add_atom(
|
||||
Atom(
|
||||
rx, ry, rz,
|
||||
symbol=symbol.ljust(2),
|
||||
)
|
||||
)
|
||||
molecules.append(mol)
|
||||
|
||||
return molecules
|
||||
|
||||
else:
|
||||
raise RuntimeError(
|
||||
"Invalid Geom File, the number of atoms doesn't match the number of lines."
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _get_crystal_structure(molecule: Molecule) -> List[str]:
|
||||
structure: List[str] = []
|
||||
for atom in molecule:
|
||||
structure.append(atom.symbol)
|
||||
return structure
|
||||
|
||||
|
||||
def split(array: List, partitions: int):
|
||||
for i in range(0, len(array), partitions):
|
||||
yield array[i: i + partitions]
|
||||
Reference in New Issue
Block a user