Initial Work on Reading Crystal and Creation Gaussian Input

This commit is contained in:
2022-12-26 06:49:14 -03:00
parent 787d17eccd
commit 3716017cb0
30 changed files with 3262 additions and 852 deletions

0
tests/__init__.py Normal file
View File

0
tests/shared/__init__.py Normal file
View File

View File

View File

@@ -0,0 +1,21 @@
from crystalpol.shared.config import Config
import unittest
class TestConfig(unittest.TestCase):
def test_class_instantiation(self):
config = Config(
mem=1,
level="b3lyp/aug-cc-pVDZ",
n_atoms=10
)
self.assertIsInstance(config, Config)
def test_config_raises_exception(self):
with self.assertRaises(ValueError):
Config(
mem="1",
level="b3lyp/aug-cc-pVDZ",
n_atoms=10
)

View File

View File

@@ -0,0 +1,19 @@
from crystalpol.shared.system.atom import Atom
import unittest
class TestAtom(unittest.TestCase):
def test_atom_instantiation(self):
atom = Atom(
na=1,
rx=0,
ry=0,
rz=0,
)
self.assertIsInstance(atom, Atom)
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,102 @@
import unittest
from crystalpol.shared.system.atom import Atom
from crystalpol.shared.system.crystal import Crystal
from crystalpol.shared.system.molecule import Molecule
class TestCrystal(unittest.TestCase):
def test_class_instantiation(self):
# Note that this is not a valid crystal
crystal_structure = [
['H']
]
crystal = Crystal(crystal_structure)
self.assertIsInstance(crystal, Crystal)
def test_is_valid_cell(self):
crystal_structure = [
['H ']
]
crystal = Crystal(crystal_structure)
molecule = Molecule("TESTE")
molecule.add_atom(
Atom(
na=1,
rx=0,
ry=0,
rz=0,
)
)
self.assertTrue(crystal._is_valid_cell([molecule]))
molecule.add_atom(
Atom(
na=1,
rx=0,
ry=0,
rz=0,
)
)
self.assertFalse(crystal._is_valid_cell([molecule]))
def test_add_cell(self):
# Note that this is not a valid crystal
crystal_structure = [
['H ']
]
crystal = Crystal(crystal_structure)
molecule = Molecule("TESTE")
molecule.add_atom(
Atom(
na=1,
rx=0,
ry=0,
rz=0,
)
)
crystal.add_cell([molecule])
self.assertIsInstance(crystal, Crystal)
def test_add_cell_raises_exception(self):
# Note that this is not a valid crystal
crystal_structure = [
['H ']
]
crystal = Crystal(crystal_structure)
molecule = Molecule("TESTE")
molecule.add_atom(
Atom(
na=1,
rx=0,
ry=0,
rz=0,
)
)
molecule.add_atom(
Atom(
na=1,
rx=0,
ry=0,
rz=0,
)
)
with self.assertRaises(ValueError):
crystal.add_cell([molecule])
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,87 @@
from crystalpol.shared.system.molecule import Molecule
from crystalpol.shared.system.atom import Atom
import io
import unittest
class TestMolecule(unittest.TestCase):
def test_class_instantiation(self):
molecule = Molecule("TEST")
self.assertEqual(molecule.mol_name, "TEST")
self.assertIsInstance(molecule, Molecule)
def test_add_atom(self):
molecule = Molecule("TEST")
atom = Atom(
na=1,
rx=0,
ry=0,
rz=0,
)
molecule.add_atom(atom)
self.assertEqual(len(molecule.atoms), 1)
self.assertEqual(molecule.atoms[0], atom)
def test_update_charges(self):
molecule = Molecule("TEST")
atom = Atom(
na=1,
rx=0,
ry=0,
rz=0,
)
molecule.add_atom(atom)
molecule.update_charges([1])
self.assertEqual(molecule.atoms[-1].chg, 1)
def test_update_charges_raises_exception(self):
molecule = Molecule("TEST")
atom = Atom(
na=1,
rx=0,
ry=0,
rz=0,
)
molecule.add_atom(atom)
with self.assertRaises(ValueError):
molecule.update_charges([1, 1])
def test_print_mol_info(self):
molecule = Molecule("TEST")
atom = Atom(
na=1,
rx=0,
ry=0,
rz=0,
)
molecule.add_atom(atom)
with io.StringIO() as file:
molecule.print_mol_info(file)
file.seek(0)
info_string = file.read()
self.assertIsNotNone(info_string)
self.assertTrue(len(info_string) > 0)
self.assertTrue("Molecule Name: TEST" in info_string)
self.assertTrue("H r: [0, 0, 0] charge: None" in info_string)
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,199 @@
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 io import StringIO
from unittest import mock, TestCase
import unittest
class TestGaussian(TestCase):
def test_class_instantiation(self):
gaussian = Gaussian(
Config(
mem=1,
level="b3lyp/aug-cc-pVDZ",
n_atoms=10
)
)
self.assertIsInstance(gaussian, Gaussian)
def test_check_keyword(self):
gaussian = Gaussian(
Config(
mem=1,
level="b3lyp/aug-cc-pVDZ",
n_atoms=10,
pop="lorota"
)
)
self.assertEqual(gaussian.config.pop, "chelpg")
@mock.patch('crystalpol.gaussian.os')
def test_create_simulation_dir(self, os_mock):
os_mock.path.exists.return_value = False
gaussian = Gaussian(
Config(
mem=1,
level="b3lyp/aug-cc-pVDZ",
n_atoms=10
)
)
gaussian.create_simulation_dir()
self.assertTrue(os_mock.makedirs.called)
@mock.patch('crystalpol.gaussian.os')
def test_create_simulation_dir_raises_exception(self, os_mock):
os_mock.path.exists.return_value = True
gaussian = Gaussian(
Config(
mem=1,
level="b3lyp/aug-cc-pVDZ",
n_atoms=10
)
)
with self.assertRaises(RuntimeError):
gaussian.create_simulation_dir()
@mock.patch('crystalpol.gaussian.open')
def test_make_gaussian_input_cycle_1(self, open_mock):
open_mock.return_value = StringIO()
crystal = self.create_crystal()
gaussian = Gaussian(
Config(
mem=1,
level="b3lyp/aug-cc-pVDZ",
n_atoms=10
)
)
gaussian_input = gaussian.make_gaussian_input(1, crystal)
expected_output = """\
%Mem=1MB
%Nprocs=1
#P b3lyp/aug-cc-pVDZ Pop = chelpg Density = Current NoSymm
crystalpol - Cycle number 1
0, 1
H 0.00000 0.00000 0.00000
"""
self.assertEqual(gaussian_input, expected_output)
@mock.patch('crystalpol.gaussian.open')
def test_make_gaussian_input_cycle_2(self, open_mock):
open_mock.return_value = StringIO()
crystal = self.create_crystal()
gaussian = Gaussian(
Config(
mem=1,
level="b3lyp/aug-cc-pVDZ",
n_atoms=10
)
)
gaussian_input = gaussian.make_gaussian_input(2, "test", crystal)
expected_output = """\
%Mem=1MB
%Nprocs=1
#P b3lyp/aug-cc-pVDZ Pop = chelpg Density = Current NoSymm charge
crystalpol - Cycle number 2
0, 1
H 0.00000 0.00000 0.00000
H 0.00000 0.00000 0.00000
"""
self.assertEqual(gaussian_input, expected_output)
def test_make_gaussian_charges(self):
file = StringIO()
crystal = self.create_crystal()
gaussian = Gaussian(
Config(
mem=1,
level="b3lyp/aug-cc-pVDZ",
n_atoms=10
)
)
gaussian.make_gaussian_charges(file, crystal)
file.seek(0)
charges_string = file.read()
expected_charges = '\nH 0.00000 0.00000 0.00000\n'
self.assertEqual(charges_string, expected_charges)
@mock.patch('crystalpol.gaussian.subprocess.call', autospec=True, return_value=0)
@mock.patch('crystalpol.gaussian.Gaussian.make_gaussian_input')
def test_run(self, subprocess_call_mock, make_gaussian_input_mock):
gaussian = Gaussian(
Config(
mem=1,
level="b3lyp/aug-cc-pVDZ",
n_atoms=10
)
)
gaussian.run(1, self.create_crystal())
self.assertTrue(subprocess_call_mock.called)
@mock.patch('crystalpol.gaussian.subprocess.call', autospec=True, return_value=1)
@mock.patch('crystalpol.gaussian.Gaussian.make_gaussian_input')
def test_run_raises_exception(self, subprocess_call_mock, make_gaussian_input_mock):
gaussian = Gaussian(
Config(
mem=1,
level="b3lyp/aug-cc-pVDZ",
n_atoms=10
)
)
with self.assertRaises(RuntimeError):
gaussian.run(1, self.create_crystal())
@staticmethod
def create_crystal():
crystal_structure = [
['H ']
]
crystal = Crystal(crystal_structure)
molecule = Molecule("TESTE")
molecule.add_atom(
Atom(
na=1,
rx=0,
ry=0,
rz=0,
)
)
crystal.add_cell([molecule])
crystal.add_cell([molecule])
return crystal
if __name__ == '__main__':
unittest.main()

101
tests/test_polarization.py Normal file
View File

@@ -0,0 +1,101 @@
from crystalpol.polarization import Polarization
from crystalpol.shared.config import Config
from crystalpol.shared.system.atom import Atom
from crystalpol.shared.system.molecule import Molecule
from unittest import TestCase, mock
import unittest
GEOM_DATA = """\
Cl 0.529511 -1.626652 1.247344
N 3.703161 2.470259 1.679277
Cl 0.362927 -1.511555 4.375374
N 3.582138 2.531106 3.906529
"""
class TestPolarization(TestCase):
def setUp(self):
self.config = Config(
mem=42,
n_atoms=2,
level="b3lyp/aug-cc-pVDZ"
)
def test_class_instantiation(self):
pol = Polarization("geom_file", "outfile", self.config)
self.assertIsInstance(pol, Polarization)
def test_get_molecules_from_lines(self):
pol = Polarization("geom_file", "outfile", self.config)
lines = [
"Cl 0.529511 -1.626652 1.247344",
"N 3.703161 2.470259 1.679277",
"Cl 0.362927 -1.511555 4.375374",
"N 3.582138 2.531106 3.906529",
]
molecules = pol._get_molecules_from_lines(lines)
self.assertIsNotNone(molecules)
self.assertTrue(any(atom.symbol == "Cl" for atom in molecules[0]))
self.assertTrue(any(atom.symbol == "N " for atom in molecules[1]))
def test_get_molecules_from_lines_raises_exception(self):
pol = Polarization("geom_file", "outfile", self.config)
lines = [
"Cl 0.529511 -1.626652 1.247344",
"N 3.703161 2.470259 1.679277",
"Cl 0.362927 -1.511555 4.375374",
"N 3.582138 2.531106 3.906529",
"N 3.582138 2.531106 3.906529",
]
with self.assertRaises(RuntimeError):
pol._get_molecules_from_lines(lines)
def test_get_crystal_structure(self):
pol = Polarization("geom_file", "outfile", self.config)
molecule = Molecule("TEST")
molecule.add_atom(
Atom(
na=1,
rx=0,
ry=0,
rz=0,
)
)
structure = pol._get_crystal_structure(molecule)
self.assertEqual(structure, ['H '])
@mock.patch('builtins.open', mock.mock_open(read_data=GEOM_DATA))
def test_read_crystal(self):
pol = Polarization("geom_file", "outfile", self.config)
pol.read_crystal()
self.assertIsNotNone(pol.crystal)
self.assertEqual(len(pol.crystal), 2)
self.assertEqual(len(pol.crystal[0]), 1)
@mock.patch('builtins.open', mock.mock_open(read_data=GEOM_DATA))
def test_run(self):
pol = Polarization("geom_file", "outfile", self.config)
pol.run()
self.assertIsNotNone(pol.crystal)
self.assertEqual(len(pol.crystal), 2)
self.assertEqual(len(pol.crystal[0]), 1)
if __name__ == '__main__':
unittest.main()