Fixes Tests Implementations
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
*.pyc
|
*.pyc
|
||||||
|
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
simfiles
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
crystal_pol:
|
crystal_pol:
|
||||||
mem: 42
|
mem: 28
|
||||||
n_procs: 20
|
n_procs: 20
|
||||||
level: "b3lyp/aug-cc-pVDZ"
|
level: "b3lyp/aug-cc-pVDZ"
|
||||||
pop: "chelpg"
|
pop: "chelpg"
|
||||||
mult: [0, 1]
|
mult: [0, 1]
|
||||||
n_atoms: 18
|
n_atoms: 18
|
||||||
comment: "DC-MBI UAEnvolvida"
|
comment: "Crystal"
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
%mem=42GB
|
%mem=30GB
|
||||||
%Nprocs=20
|
%Nprocs=24
|
||||||
#p ${LEVEL} POP=${POP} density=current NoSymm (CHARGE - A partir do segundo)
|
#p ${LEVEL} POP=${POP} density=current NoSymm (CHARGE - A partir do segundo)
|
||||||
|
|
||||||
${COMMENTARY} passo 1
|
${COMMENTARY} passo 1
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from crystalpol.shared.system.crystal import Crystal
|
|||||||
from crystalpol.shared.config import Config
|
from crystalpol.shared.config import Config
|
||||||
|
|
||||||
from pathlib import Path, PosixPath
|
from pathlib import Path, PosixPath
|
||||||
from typing import TextIO
|
from typing import TextIO, Union
|
||||||
import subprocess
|
import subprocess
|
||||||
import textwrap
|
import textwrap
|
||||||
import shutil
|
import shutil
|
||||||
@@ -25,8 +25,14 @@ class Gaussian:
|
|||||||
|
|
||||||
def run(self, cycle: int, crystal: Crystal) -> None:
|
def run(self, cycle: int, crystal: Crystal) -> None:
|
||||||
|
|
||||||
file = Path("simfiles", f"crystal-{str(cycle).zfill(2)}.gjf")
|
self.create_simulation_dir()
|
||||||
|
|
||||||
|
file = Path(
|
||||||
|
"simfiles",
|
||||||
|
f"crystal-{str(cycle).zfill(2)}",
|
||||||
|
f"crystal-{str(cycle).zfill(2)}.gjf"
|
||||||
|
)
|
||||||
|
self.create_step_dir(cycle)
|
||||||
self.make_gaussian_input(cycle, file, crystal)
|
self.make_gaussian_input(cycle, file, crystal)
|
||||||
|
|
||||||
if shutil.which("bash") is not None:
|
if shutil.which("bash") is not None:
|
||||||
@@ -35,7 +41,7 @@ class Gaussian:
|
|||||||
"bash",
|
"bash",
|
||||||
"-c",
|
"-c",
|
||||||
"exec -a {}-step{} {} {}".format(
|
"exec -a {}-step{} {} {}".format(
|
||||||
self.qmprog, cycle, self.qmprog, file.name
|
self.qmprog, cycle, self.qmprog, str(file)
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -47,6 +53,19 @@ class Gaussian:
|
|||||||
|
|
||||||
return self.read_charges_from_gaussian_output()
|
return self.read_charges_from_gaussian_output()
|
||||||
|
|
||||||
|
def create_step_dir(self, cycle):
|
||||||
|
step_dir = Path(
|
||||||
|
"simfiles",
|
||||||
|
f"crystal-{str(cycle).zfill(2)}"
|
||||||
|
)
|
||||||
|
if not os.path.exists(step_dir):
|
||||||
|
os.makedirs(step_dir)
|
||||||
|
else:
|
||||||
|
raise RuntimeError(
|
||||||
|
f"Step directory '{str(step_dir)}' already exists. "
|
||||||
|
f"Please remove it before proceeding."
|
||||||
|
)
|
||||||
|
|
||||||
def create_simulation_dir(self):
|
def create_simulation_dir(self):
|
||||||
if not os.path.exists(self.config.simulation_dir):
|
if not os.path.exists(self.config.simulation_dir):
|
||||||
os.makedirs(self.config.simulation_dir)
|
os.makedirs(self.config.simulation_dir)
|
||||||
@@ -56,17 +75,17 @@ class Gaussian:
|
|||||||
f"Please remove it before proceeding."
|
f"Please remove it before proceeding."
|
||||||
)
|
)
|
||||||
|
|
||||||
def make_gaussian_input(self, cycle: int, file: PosixPath, crystal: Crystal) -> str:
|
def make_gaussian_input(self, cycle: int, file: Union[PosixPath, Path], crystal: Crystal) -> str:
|
||||||
|
|
||||||
with open(file, 'w+') as fh:
|
with open(file, 'w+') as fh:
|
||||||
|
|
||||||
fh.write(f"%Mem={self.config.mem}MB\n")
|
fh.write(f"%Mem={self.config.mem}Gb\n")
|
||||||
|
|
||||||
fh.write(f"%Nprocs={self.config.n_procs}\n")
|
fh.write(f"%Nprocs={self.config.n_procs}\n")
|
||||||
|
|
||||||
kwords_line = f"#P {self.config.level} " \
|
kwords_line = f"#P {self.config.level} " \
|
||||||
f"Pop = {self.config.pop} " \
|
f"Pop={self.config.pop} " \
|
||||||
f"Density = Current " \
|
f"Density=Current " \
|
||||||
f"NoSymm "
|
f"NoSymm "
|
||||||
|
|
||||||
if cycle > 1:
|
if cycle > 1:
|
||||||
@@ -77,17 +96,19 @@ class Gaussian:
|
|||||||
|
|
||||||
fh.write(f"\n{self.config.comment} - Cycle number {cycle}\n")
|
fh.write(f"\n{self.config.comment} - Cycle number {cycle}\n")
|
||||||
fh.write("\n")
|
fh.write("\n")
|
||||||
fh.write(f"{self.config.mult[0]}, {self.config.mult[1]}\n")
|
fh.write(f"{self.config.mult[0]} {self.config.mult[1]}\n")
|
||||||
|
|
||||||
for atom in crystal[0][0]:
|
for atom in crystal[0][0]:
|
||||||
symbol = atom_symbol[atom.na]
|
symbol = atom_symbol[atom.na]
|
||||||
fh.write(
|
fh.write(
|
||||||
f"{symbol:<2s} "
|
f"{symbol:<2s} "
|
||||||
f"{atom.rx:>10.5f} "
|
f"{float(atom.rx):>10.5f} "
|
||||||
f"{atom.ry:>10.5f} "
|
f"{float(atom.ry):>10.5f} "
|
||||||
f"{atom.rz:>10.5f}\n"
|
f"{float(atom.rz):>10.5f}\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fh.write("\n")
|
||||||
|
|
||||||
if cycle > 1:
|
if cycle > 1:
|
||||||
self.make_gaussian_charges(fh, crystal)
|
self.make_gaussian_charges(fh, crystal)
|
||||||
|
|
||||||
@@ -96,8 +117,6 @@ class Gaussian:
|
|||||||
|
|
||||||
def make_gaussian_charges(self, fh: TextIO, crystal: Crystal) -> None:
|
def make_gaussian_charges(self, fh: TextIO, crystal: Crystal) -> None:
|
||||||
|
|
||||||
fh.write("\n")
|
|
||||||
|
|
||||||
for index_cell, cell in enumerate(crystal):
|
for index_cell, cell in enumerate(crystal):
|
||||||
for index_mol, molecule in enumerate(cell):
|
for index_mol, molecule in enumerate(cell):
|
||||||
if (index_cell == 0 and index_mol != 0) or (index_cell != 0):
|
if (index_cell == 0 and index_mol != 0) or (index_cell != 0):
|
||||||
@@ -105,10 +124,12 @@ class Gaussian:
|
|||||||
symbol = atom_symbol[atom.na]
|
symbol = atom_symbol[atom.na]
|
||||||
fh.write(
|
fh.write(
|
||||||
f"{symbol:<2s} "
|
f"{symbol:<2s} "
|
||||||
f"{atom.rx:>10.5f} "
|
f"{float(atom.rx):>10.5f} "
|
||||||
f"{atom.ry:>10.5f} "
|
f"{float(atom.ry):>10.5f} "
|
||||||
f"{atom.rz:>10.5f}\n"
|
f"{float(atom.rz):>10.5f}\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fh.write("\n")
|
||||||
|
|
||||||
def read_charges_from_gaussian_output(self) -> None:
|
def read_charges_from_gaussian_output(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from crystalpol.shared.system.atom import Atom
|
|||||||
from crystalpol.shared.config import Config
|
from crystalpol.shared.config import Config
|
||||||
from crystalpol.gaussian import Gaussian
|
from crystalpol.gaussian import Gaussian
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
from unittest import mock, TestCase
|
from unittest import mock, TestCase
|
||||||
@@ -38,6 +39,7 @@ class TestGaussian(TestCase):
|
|||||||
@mock.patch('crystalpol.gaussian.os')
|
@mock.patch('crystalpol.gaussian.os')
|
||||||
def test_create_simulation_dir(self, os_mock):
|
def test_create_simulation_dir(self, os_mock):
|
||||||
os_mock.path.exists.return_value = False
|
os_mock.path.exists.return_value = False
|
||||||
|
os_mock.makedirs = mock.MagicMock()
|
||||||
|
|
||||||
gaussian = Gaussian(
|
gaussian = Gaussian(
|
||||||
Config(
|
Config(
|
||||||
@@ -53,6 +55,7 @@ class TestGaussian(TestCase):
|
|||||||
@mock.patch('crystalpol.gaussian.os')
|
@mock.patch('crystalpol.gaussian.os')
|
||||||
def test_create_simulation_dir_raises_exception(self, os_mock):
|
def test_create_simulation_dir_raises_exception(self, os_mock):
|
||||||
os_mock.path.exists.return_value = True
|
os_mock.path.exists.return_value = True
|
||||||
|
os_mock.makedirs = mock.MagicMock()
|
||||||
gaussian = Gaussian(
|
gaussian = Gaussian(
|
||||||
Config(
|
Config(
|
||||||
mem=1,
|
mem=1,
|
||||||
@@ -64,6 +67,7 @@ class TestGaussian(TestCase):
|
|||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
gaussian.create_simulation_dir()
|
gaussian.create_simulation_dir()
|
||||||
|
|
||||||
|
# @mock.patch('crystalpol.gaussian.os')
|
||||||
@mock.patch('crystalpol.gaussian.open')
|
@mock.patch('crystalpol.gaussian.open')
|
||||||
def test_make_gaussian_input_cycle_1(self, open_mock):
|
def test_make_gaussian_input_cycle_1(self, open_mock):
|
||||||
|
|
||||||
@@ -78,16 +82,17 @@ class TestGaussian(TestCase):
|
|||||||
n_atoms=10
|
n_atoms=10
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
gaussian_input = gaussian.make_gaussian_input(1, crystal)
|
gaussian_input = gaussian.make_gaussian_input(1, Path(), crystal)
|
||||||
expected_output = """\
|
expected_output = """\
|
||||||
%Mem=1MB
|
%Mem=1Gb
|
||||||
%Nprocs=1
|
%Nprocs=1
|
||||||
#P b3lyp/aug-cc-pVDZ Pop = chelpg Density = Current NoSymm
|
#P b3lyp/aug-cc-pVDZ Pop=chelpg Density=Current NoSymm
|
||||||
|
|
||||||
crystalpol - Cycle number 1
|
crystalpol - Cycle number 1
|
||||||
|
|
||||||
0, 1
|
0 1
|
||||||
H 0.00000 0.00000 0.00000
|
H 0.00000 0.00000 0.00000
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.assertEqual(gaussian_input, expected_output)
|
self.assertEqual(gaussian_input, expected_output)
|
||||||
|
|
||||||
@@ -107,16 +112,17 @@ H 0.00000 0.00000 0.00000
|
|||||||
)
|
)
|
||||||
gaussian_input = gaussian.make_gaussian_input(2, "test", crystal)
|
gaussian_input = gaussian.make_gaussian_input(2, "test", crystal)
|
||||||
expected_output = """\
|
expected_output = """\
|
||||||
%Mem=1MB
|
%Mem=1Gb
|
||||||
%Nprocs=1
|
%Nprocs=1
|
||||||
#P b3lyp/aug-cc-pVDZ Pop = chelpg Density = Current NoSymm charge
|
#P b3lyp/aug-cc-pVDZ Pop=chelpg Density=Current NoSymm charge
|
||||||
|
|
||||||
crystalpol - Cycle number 2
|
crystalpol - Cycle number 2
|
||||||
|
|
||||||
0, 1
|
0 1
|
||||||
H 0.00000 0.00000 0.00000
|
H 0.00000 0.00000 0.00000
|
||||||
|
|
||||||
|
H 0.00000 0.00000 0.00000
|
||||||
|
|
||||||
H 0.00000 0.00000 0.00000
|
|
||||||
"""
|
"""
|
||||||
self.assertEqual(gaussian_input, expected_output)
|
self.assertEqual(gaussian_input, expected_output)
|
||||||
|
|
||||||
@@ -136,13 +142,15 @@ H 0.00000 0.00000 0.00000
|
|||||||
file.seek(0)
|
file.seek(0)
|
||||||
|
|
||||||
charges_string = file.read()
|
charges_string = file.read()
|
||||||
expected_charges = '\nH 0.00000 0.00000 0.00000\n'
|
expected_charges = 'H 0.00000 0.00000 0.00000\n\n'
|
||||||
|
|
||||||
self.assertEqual(charges_string, expected_charges)
|
self.assertEqual(charges_string, expected_charges)
|
||||||
|
|
||||||
|
@mock.patch('crystalpol.gaussian.os')
|
||||||
@mock.patch('crystalpol.gaussian.subprocess.call', autospec=True, return_value=0)
|
@mock.patch('crystalpol.gaussian.subprocess.call', autospec=True, return_value=0)
|
||||||
@mock.patch('crystalpol.gaussian.Gaussian.make_gaussian_input')
|
@mock.patch('crystalpol.gaussian.Gaussian.make_gaussian_input')
|
||||||
def test_run(self, subprocess_call_mock, make_gaussian_input_mock):
|
def test_run(self, make_gaussian_input_mock, subprocess_call_mock, os_mock):
|
||||||
|
os_mock.path.exists.return_value = False
|
||||||
|
|
||||||
gaussian = Gaussian(
|
gaussian = Gaussian(
|
||||||
Config(
|
Config(
|
||||||
@@ -155,9 +163,11 @@ H 0.00000 0.00000 0.00000
|
|||||||
|
|
||||||
self.assertTrue(subprocess_call_mock.called)
|
self.assertTrue(subprocess_call_mock.called)
|
||||||
|
|
||||||
|
@mock.patch('crystalpol.gaussian.os')
|
||||||
@mock.patch('crystalpol.gaussian.subprocess.call', autospec=True, return_value=1)
|
@mock.patch('crystalpol.gaussian.subprocess.call', autospec=True, return_value=1)
|
||||||
@mock.patch('crystalpol.gaussian.Gaussian.make_gaussian_input')
|
@mock.patch('crystalpol.gaussian.Gaussian.make_gaussian_input')
|
||||||
def test_run_raises_exception(self, subprocess_call_mock, make_gaussian_input_mock):
|
def test_run_raises_exception(self, subprocess_call_mock, make_gaussian_input_mock, os_mock):
|
||||||
|
os_mock.path.exists.return_value = False
|
||||||
|
|
||||||
gaussian = Gaussian(
|
gaussian = Gaussian(
|
||||||
Config(
|
Config(
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ from crystalpol.shared.system.molecule import Molecule
|
|||||||
from unittest import TestCase, mock
|
from unittest import TestCase, mock
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
GEOM_DATA = """\
|
GEOM_DATA = """\
|
||||||
Cl 0.529511 -1.626652 1.247344
|
Cl 0.529511 -1.626652 1.247344
|
||||||
N 3.703161 2.470259 1.679277
|
N 3.703161 2.470259 1.679277
|
||||||
@@ -85,9 +84,12 @@ class TestPolarization(TestCase):
|
|||||||
self.assertEqual(len(pol.crystal), 2)
|
self.assertEqual(len(pol.crystal), 2)
|
||||||
self.assertEqual(len(pol.crystal[0]), 1)
|
self.assertEqual(len(pol.crystal[0]), 1)
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('builtins.open', mock.mock_open(read_data=GEOM_DATA))
|
@mock.patch('builtins.open', mock.mock_open(read_data=GEOM_DATA))
|
||||||
def test_run(self):
|
@mock.patch('crystalpol.gaussian.subprocess.call', autospec=True, return_value=0)
|
||||||
|
@mock.patch('crystalpol.gaussian.os')
|
||||||
|
def test_run(self, os_mock, subprocess_call_mock):
|
||||||
|
os_mock.path.exists.return_value = False
|
||||||
|
|
||||||
pol = Polarization("geom_file", "outfile", self.config)
|
pol = Polarization("geom_file", "outfile", self.config)
|
||||||
|
|
||||||
pol.run()
|
pol.run()
|
||||||
|
|||||||
Reference in New Issue
Block a user