Fixes Tests Implementations

This commit is contained in:
2023-02-10 09:07:50 -03:00
parent 3716017cb0
commit 0f7484756b
6 changed files with 72 additions and 37 deletions

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
*.pyc *.pyc
.idea/ .idea/
simfiles

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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(

View File

@@ -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()