diff --git a/geometric/tests/conftest.py b/geometric/tests/conftest.py index 2f8d275d..93ff3ef0 100644 --- a/geometric/tests/conftest.py +++ b/geometric/tests/conftest.py @@ -1,5 +1,9 @@ import logging import _pytest.logging +import pytest +import geometric +import os, tempfile +from . import addons # 2022-09-22: This modification allows live and captured logs to be # formatted in the expected way when running tests using pytest. @@ -9,3 +13,33 @@ # It took a long time to figure out and I'm glad it only took one line to fix it! logging.StreamHandler.terminator = "" + +datad = addons.datad + +@pytest.fixture +def molecule_engine_neb(): + """Return the Molecule and Engine for an NEB Calculation.""" + input_ext = {'psi4': 'psi4in', 'qchem': 'qcin', 'tera': 'tcin'} + def get_molecule_engine(engine: str, images: int): + + return geometric.prepare.get_molecule_engine( + input=os.path.join(datad, "hcn_neb_input.%s" %input_ext.get(engine)), + chain_coords=os.path.join(datad, "hcn_neb_input.xyz"), + images=images, + neb=True, + engine=engine, + ) + + return get_molecule_engine + +@pytest.fixture +def bigchem_frequency(): + """Return frequency calculation results carried by BigChem""" + def get_freqs(engine: str, input: str): + molecule, engine = geometric.prepare.get_molecule_engine(engine=engine, input=os.path.join(datad, input)) + coords = molecule.xyzs[0].flatten()*geometric.nifty.ang2bohr + hessian = geometric.normal_modes.calc_cartesian_hessian(coords, molecule, engine, tempfile.mkdtemp(), bigchem=True) + freqs, modes, G = geometric.normal_modes.frequency_analysis(coords, hessian, elem=molecule.elem, verbose=True) + return freqs + + return get_freqs diff --git a/geometric/tests/test_hessian.py b/geometric/tests/test_hessian.py index 9df20297..f2a444e5 100644 --- a/geometric/tests/test_hessian.py +++ b/geometric/tests/test_hessian.py @@ -46,11 +46,8 @@ def test_hessian_assort(): @addons.using_psi4 @addons.using_bigchem -def test_psi4_bigchem_hessian(): - molecule, engine = geometric.prepare.get_molecule_engine(engine="psi4", input=os.path.join(datad, 'hcn_minimized.psi4in')) - coords = molecule.xyzs[0].flatten()*geometric.nifty.ang2bohr - hessian = geometric.normal_modes.calc_cartesian_hessian(coords, molecule, engine, tempfile.mkdtemp()) - freqs, modes, G = geometric.normal_modes.frequency_analysis(coords, hessian, elem=molecule.elem, verbose=True) +def test_psi4_bigchem_hessian(bigchem_frequency): + freqs = bigchem_frequency("psi4", "hcn_minimized.psi4in") np.testing.assert_almost_equal(freqs, [989.5974, 989.5992, 2394.0352, 3690.5745], decimal=0) assert len(freqs) == 4 @@ -58,13 +55,9 @@ def test_psi4_bigchem_hessian(): @addons.using_qchem @addons.using_bigchem -def test_qchem_bigchem_hessian(): - +def test_qchem_bigchem_hessian(bigchem_frequency): # Optimized TS structure of HCN -> CNH reaction. - molecule, engine = geometric.prepare.get_molecule_engine(engine="qchem", input=os.path.join(datad, 'hcn_minimized_ts.qcin')) - coords = molecule.xyzs[0].flatten()*geometric.nifty.ang2bohr - hessian = geometric.normal_modes.calc_cartesian_hessian(coords, molecule, engine, tempfile.mkdtemp()) - freqs, modes, G = geometric.normal_modes.frequency_analysis(coords, hessian, elem=molecule.elem, verbose=True) + freqs = bigchem_frequency("qchem", "hcn_minimized_ts.qcin") np.testing.assert_almost_equal(freqs, [-1215.8587, 2126.6551, 2451.8599], decimal=0) assert freqs[0] < 0 @@ -73,16 +66,12 @@ def test_qchem_bigchem_hessian(): @addons.using_terachem @addons.using_bigchem -def test_terachem_bigchem_hessian(): - shutil.copy2(os.path.join(datad, 'hcn_minimized.xyz'), os.path.join(os.getcwd(), 'hcn_minimized.xyz')) - molecule, engine = geometric.prepare.get_molecule_engine(engine="tera", input=os.path.join(datad, 'hcn_minimized.tcin')) - os.remove('hcn_minimized.xyz') - coords = molecule.xyzs[0].flatten()*geometric.nifty.ang2bohr - hessian = geometric.normal_modes.calc_cartesian_hessian(coords, molecule, engine, tempfile.mkdtemp()) - freqs, modes, G = geometric.normal_modes.frequency_analysis(coords, hessian, elem=molecule.elem, verbose=True) - +def test_terachem_bigchem_hessian(bigchem_frequency): + shutil.copy2(os.path.join(datad,"hcn_minimized.xyz"), os.path.join(os.getcwd(), "hcn_minimized.xyz")) + freqs = bigchem_frequency("tera", "hcn_minimized.tcin") + os.remove("hcn_minimized.xyz") - np.testing.assert_almost_equal(freqs, [991.5956, 991.6469, 2393.3915, 3691.8975], decimal=0) + np.testing.assert_almost_equal(freqs, [989.5482, 989.7072, 2394.4201, 3687.4741], decimal=0) assert len(freqs) == 4 diff --git a/geometric/tests/test_irc.py b/geometric/tests/test_irc.py index e1405bd2..f48037ad 100644 --- a/geometric/tests/test_irc.py +++ b/geometric/tests/test_irc.py @@ -45,7 +45,7 @@ def test_hcn_irc_psi4_bigchem(localizer): """ shutil.copy2(os.path.join(datad, 'hcn_irc.psi4in'), os.path.join(os.getcwd(), 'hcn_irc.psi4in')) progress = geometric.optimize.run_optimizer(engine='psi4', input='hcn_irc.psi4in', converge=['set', 'GAU_LOOSE'], - nt=4, reset=False, trust=0.05, irc=True, maxiter=50) + nt=4, reset=False, trust=0.05, irc=True, maxiter=50, bigchem=True) e_ref1 = -92.35408411 e_ref2 = -92.33971205 max_e = np.max(progress.qm_energies) diff --git a/geometric/tests/test_neb.py b/geometric/tests/test_neb.py index 627de8d9..2553ebe9 100644 --- a/geometric/tests/test_neb.py +++ b/geometric/tests/test_neb.py @@ -14,48 +14,28 @@ datad = addons.datad exampled = addons.exampled - -def test_hcn_neb_input(localizer): +def test_hcn_neb_input(localizer, molecule_engine_neb): """ Test lengths of input chains """ chain_M = geometric.molecule.Molecule(os.path.join(datad, "hcn_neb_input.xyz")) - nimg = 7 - M1, engine = geometric.prepare.get_molecule_engine( - input=os.path.join(datad, "hcn_neb_input.psi4in"), - chain_coords=os.path.join(datad, "hcn_neb_input.xyz"), - images=nimg, - neb=True, - engine="psi4", - ) + + M1, engine = molecule_engine_neb('psi4', nimg) # The number of images can't exceed the maximum number of images in the input chain - M2, engine = geometric.prepare.get_molecule_engine( - input=os.path.join(datad, "hcn_neb_input.psi4in"), - chain_coords=os.path.join(datad, "hcn_neb_input.xyz"), - images=9999, - neb=True, - engine="psi4", - ) + M2, engine = molecule_engine_neb('psi4', 9999) assert nimg == len(M1) assert len(M2) == len(chain_M) @addons.using_psi4 -def test_hcn_neb_optimize_1(localizer): +def test_hcn_neb_optimize_1(localizer, molecule_engine_neb): """ Optimize a HCN chain without alignment """ - - M, engine = geometric.prepare.get_molecule_engine( - input=os.path.join(datad, "hcn_neb_input.psi4in"), - chain_coords=os.path.join(datad, "hcn_neb_input.xyz"), - images=11, - neb=True, - engine="psi4", - ) + M, engine = molecule_engine_neb('psi4', 11) params = geometric.params.NEBParams(**{"optep": True, "align": False, "verbose": 1}) chain = geometric.neb.ElasticBand( @@ -72,17 +52,11 @@ def test_hcn_neb_optimize_1(localizer): @addons.using_psi4 -def test_hcn_neb_optimize_2(localizer): +def test_hcn_neb_optimize_2(localizer, molecule_engine_neb): """ Optimize a HCN chain with alignment """ - M, engine = geometric.prepare.get_molecule_engine( - input=os.path.join(datad, "hcn_neb_input.psi4in"), - chain_coords=os.path.join(datad, "hcn_neb_input.xyz"), - images=11, - neb=True, - engine="psi4", - ) + M, engine = molecule_engine_neb('psi4', 11) # maxg and avgg are increased here to make them converge faster after the alignment params = geometric.params.NEBParams(**{"verbose": 1, "maxg": 3.0, "avgg": 2.0}) @@ -101,20 +75,13 @@ def test_hcn_neb_optimize_2(localizer): @addons.using_psi4 @addons.using_bigchem -def test_psi4_bigchem(localizer): +def test_psi4_bigchem(localizer, molecule_engine_neb): """ Optimize a HCN chain without alignment with BigChem and Psi4 """ + M, engine = molecule_engine_neb('psi4', 11) - M, engine = geometric.prepare.get_molecule_engine( - input=os.path.join(datad, "hcn_neb_input.psi4in"), - chain_coords=os.path.join(datad, "hcn_neb_input.xyz"), - images=11, - neb=True, - engine="psi4", - ) - - params = geometric.params.NEBParams(**{"align": False, "verbose": 1}) + params = geometric.params.NEBParams(**{"align": False, "verbose": 1, "bigchem": True}) chain = geometric.neb.ElasticBand( M, engine=engine, tmpdir=tempfile.mkdtemp(), params=params, plain=0 ) @@ -131,19 +98,13 @@ def test_psi4_bigchem(localizer): @addons.using_qchem @addons.using_bigchem -def test_qchem_bigchem(localizer): +def test_qchem_bigchem(localizer, molecule_engine_neb): """ Optimize a HCN chain without alignment with BigChem and QChem """ - M, engine = geometric.prepare.get_molecule_engine( - input=os.path.join(datad, "hcn_neb_input.qcin"), - chain_coords=os.path.join(datad, "hcn_neb_input.xyz"), - images=11, - neb=True, - engine="qchem", - ) + M, engine = molecule_engine_neb('qchem', 11) - params = geometric.params.NEBParams(**{"align": False, "verbose": 1}) + params = geometric.params.NEBParams(**{"align": False, "verbose": 1, "bigchem": True}) chain = geometric.neb.ElasticBand( M, engine=engine, tmpdir=tempfile.mkdtemp(), params=params, plain=0 ) @@ -159,23 +120,15 @@ def test_qchem_bigchem(localizer): @addons.using_terachem @addons.using_bigchem -def test_terachem_bigchem(localizer): +def test_terachem_bigchem(localizer, molecule_engine_neb): """ Optimize a HCN chain without alignment with BigChem and TeraChem """ - - shutil.copy2(os.path.join(datad, 'hcn_neb_input.xyz'), os.path.join(os.getcwd(), 'hcn_neb_input.xyz')) - M, engine = geometric.prepare.get_molecule_engine( - input=os.path.join(datad, "hcn_neb_input.tcin"), - chain_coords=os.path.join(datad, "hcn_neb_input.xyz"), - images=11, - neb=True, - engine="tera", - ) + M, engine = molecule_engine_neb('tera', 11) - params = geometric.params.NEBParams(**{"align": False, "verbose": 1}) + params = geometric.params.NEBParams(**{"align": False, "verbose": 1, "bigchem": True}) chain = geometric.neb.ElasticBand( M, engine=engine, tmpdir=tempfile.mkdtemp(), params=params, plain=0 ) @@ -206,14 +159,8 @@ def work_queue_cleanup(self): @addons.using_psi4 @addons.using_workqueue - def test_psi4_work_queue_neb(self, localizer): - M, engine = geometric.prepare.get_molecule_engine( - input=os.path.join(datad, "hcn_neb_input.psi4in"), - chain_coords=os.path.join(datad, "hcn_neb_input.xyz"), - images=11, - neb=True, - engine="psi4", - ) + def test_psi4_work_queue_neb(self, localizer, molecule_engine_neb): + M, engine = molecule_engine_neb('psi4', 11) params = geometric.params.NEBParams(**{"optep": True, "align": False, "verbose": 1}) chain = geometric.neb.ElasticBand( M, engine=engine, tmpdir=tempfile.mkdtemp(), params=params, plain=0 diff --git a/setup.py b/setup.py index 426bc310..efb321db 100644 --- a/setup.py +++ b/setup.py @@ -31,6 +31,9 @@ 'pytest', 'pytest-cov', ], + extra_require={ + 'bigchem': ['bigchem'] + } version=versioneer.get_version(), cmdclass=versioneer.get_cmdclass(), classifiers=[