From 3b09d18112f089231b4d0fc3691555de41da3471 Mon Sep 17 00:00:00 2001 From: Evan Walter Clark Spotte-Smith Date: Wed, 4 Sep 2019 15:45:56 -0400 Subject: [PATCH 01/11] Added FrequencyFlatteningTransitionStatteFW --- atomate/qchem/fireworks/core.py | 120 ++++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 5 deletions(-) diff --git a/atomate/qchem/fireworks/core.py b/atomate/qchem/fireworks/core.py index c68c7b4f9..d3bf8d23d 100644 --- a/atomate/qchem/fireworks/core.py +++ b/atomate/qchem/fireworks/core.py @@ -226,9 +226,10 @@ def __init__(self, """ qchem_input_params = qchem_input_params or {} - input_file="mol.qin" - output_file="mol.qout" - t = [] + input_file = "mol.qin" + output_file = "mol.qout" + + t = list() t.append( WriteInputFromIOSet( molecule=molecule, @@ -262,6 +263,117 @@ def __init__(self, **kwargs) +#TODO: test (actually with Q-Chem and by writing tests) +class FrequencyFlatteningTransitionStateFW(Firework): + def __init__(self, + molecule=None, + name="frequency flattening transition state optimization", + qchem_cmd=">>qchem_cmd<<", + multimode=">>multimode<<", + max_cores=">>max_cores<<", + directory=None, + qchem_input_params=None, + max_iterations=10, + max_molecule_perturb_scale=0.3, + reversed_direction=False, + db_file=None, + parents=None, + **kwargs): + """ + First, perform a search over the potential energy surface between reactants and products in order to determine + a guess for the transition state. Then, iteratively optimize the transition state structure and flatten + imaginary frequencies to ensure that the resulting structure is a true transition state. + + Args: + molecule (dict of Molecules): Input molecules. The dict should have two entries, "reactants" and "products". + Note that the order of the molecules, and the atoms of the molecules, is important. The FSM and GSM + methods will only work properly if the atoms in the reactants and products correspond exactly. + name (str): Name for the Firework. + qchem_cmd (str): Command to run QChem. Supports env_chk. + multimode (str): Parallelization scheme, either openmp or mpi. Supports env_chk. + max_cores (int): Maximum number of cores to parallelize over. Supports env_chk. + directory (str): Location where calculation should take place. Default is current working directory. + qchem_input_params (dict): Specify kwargs for instantiating the input set parameters. + Basic uses would be to modify the default inputs of the set, + such as dft_rung, basis_set, pcm_dielectric, scf_algorithm, + or max_scf_cycles. See pymatgen/io/qchem/sets.py for default + values of all input parameters. For instance, if a user wanted + to use a more advanced DFT functional, include a pcm with a + dielectric of 30, and use a larger basis, the user would set + qchem_input_params = {"dft_rung": 5, "pcm_dielectric": 30, + "basis_set": "6-311++g**"}. However, more advanced customization + of the input is also possible through the overwrite_inputs key + which allows the user to directly modify the rem, pcm, smd, and + solvent dictionaries that QChemDictSet passes to inputs.py to + print an actual input file. For instance, if a user wanted to + set the sym_ignore flag in the rem section of the input file + to true, then they would set qchem_input_params = {"overwrite_inputs": + "rem": {"sym_ignore": "true"}}. Of course, overwrite_inputs + could be used in conjuction with more typical modifications, + as seen in the test_double_FF_opt workflow test. + max_iterations (int): Number of perturbation -> optimization -> frequency + iterations to perform. Defaults to 10. + max_molecule_perturb_scale (float): The maximum scaled perturbation that can be + applied to the molecule. Defaults to 0.3. + reversed_direction (bool): Whether to reverse the direction of the vibrational + frequency vectors. Defaults to False. + db_file (str): Path to file specifying db credentials to place output parsing. + parents ([Firework]): Parents of this particular Firework. + **kwargs: Other kwargs that are passed to Firework.__init__. + """ + + qchem_input_params = qchem_input_params or {} + input_file = "mol.qin" + output_file = "mol.qout" + + t = list() + t.append( + WriteInputFromIOSet( + molecule=molecule, + qchem_input_set="FreezingStringSet", + input_file=input_file, + qchem_input_params=qchem_input_params)) + t.append( + RunQChemCustodian( + qchem_cmd=qchem_cmd, + multimode=multimode, + input_file=input_file, + output_file=output_file, + max_cores=max_cores, + job_type="ts_with_frequency_flattener", + max_iterations=max_iterations, + max_molecule_perturb_scale=max_molecule_perturb_scale, + reversed_direction=reversed_direction, + gzipped_output=False)) + if directory is None: + t.append( + QChemToDb( + db_file=db_file, + input_file=input_file, + output_file=output_file, + additional_fields={ + "task_label": name, + "special_run_type": "ts_frequency_flattener" + })) + else: + t.append( + QChemToDb( + db_file=db_file, + calc_dir=directory, + input_file="mol.qin", + output_file="mol.qout", + additional_fields={ + "task_label": name, + "special_run_type": "ts_frequency_flattener" + })) + + super(FrequencyFlatteningTransitionStateFW, self).__init__( + t, + parents=parents, + name=name, + **kwargs) + + class FragmentFW(Firework): def __init__(self, molecule=None, @@ -270,8 +382,6 @@ def __init__(self, additional_charges=None, do_triplets=True, name="fragment and optimize", - qchem_cmd=">>qchem_cmd<<", - multimode=">>multimode<<", max_cores=">>max_cores<<", qchem_input_params=None, db_file=None, From 99d59e2449d9787817274e9f4ddfdcbce557e25a Mon Sep 17 00:00:00 2001 From: Evan Walter Clark Spotte-Smith Date: Thu, 30 Jan 2020 10:39:07 -0800 Subject: [PATCH 02/11] Get up-to-date with recent changes in pymatgen --- atomate/qchem/firetasks/fragmenter.py | 6 ++---- atomate/qchem/firetasks/write_inputs.py | 20 ++++++-------------- atomate/qchem/tests/test_drones.py | 16 ++++------------ 3 files changed, 12 insertions(+), 30 deletions(-) diff --git a/atomate/qchem/firetasks/fragmenter.py b/atomate/qchem/firetasks/fragmenter.py index 8edc8ae63..084cedfb0 100644 --- a/atomate/qchem/firetasks/fragmenter.py +++ b/atomate/qchem/firetasks/fragmenter.py @@ -208,13 +208,11 @@ def _in_database(self, molecule): # otherwise, look through the docs for an entry with an isomorphic molecule with # equivalent charge and multiplicity else: - new_mol_graph = MoleculeGraph.with_local_env_strategy(molecule, OpenBabelNN(), - reorder=False, extend_structure=False) + new_mol_graph = MoleculeGraph.with_local_env_strategy(molecule, OpenBabelNN()) for doc in self.all_relevant_docs: if molecule.composition.reduced_formula == doc["formula_pretty"]: old_mol = Molecule.from_dict(doc["input"]["initial_molecule"]) - old_mol_graph = MoleculeGraph.with_local_env_strategy(old_mol, OpenBabelNN(), - reorder=False, extend_structure=False) + old_mol_graph = MoleculeGraph.with_local_env_strategy(old_mol, OpenBabelNN()) # If such an equivalent molecule is found, return true if new_mol_graph.isomorphic_to(old_mol_graph) and molecule.charge == old_mol_graph.molecule.charge and molecule.spin_multiplicity == old_mol_graph.molecule.spin_multiplicity: return True diff --git a/atomate/qchem/firetasks/write_inputs.py b/atomate/qchem/firetasks/write_inputs.py index e196722f1..3cf598525 100644 --- a/atomate/qchem/firetasks/write_inputs.py +++ b/atomate/qchem/firetasks/write_inputs.py @@ -77,13 +77,9 @@ def run_task(self, fw_spec): mol = self.get("molecule") # check if mol and prev_calc_mol are isomorphic mol_graph = MoleculeGraph.with_local_env_strategy(mol, - OpenBabelNN(), - reorder=False, - extend_structure=False) - prev_mol_graph = MoleculeGraph.with_local_env_strategy(prev_calc_molecule, - OpenBabelNN(), - reorder=False, - extend_structure=False) + OpenBabelNN()) + prev_mol_graph = MoleculeGraph.with_local_env_strategy(prev_calc_mol, + OpenBabelNN()) # If they are isomorphic, aka a previous FW has not changed bonding, # then we will use prev_calc_mol. If bonding has changed, we will use mol. if mol_graph.isomorphic_to(prev_mol_graph): @@ -148,13 +144,9 @@ def run_task(self, fw_spec): mol = self.get("molecule") # check if mol and prev_calc_mol are isomorphic mol_graph = MoleculeGraph.with_local_env_strategy(mol, - OpenBabelNN(), - reorder=False, - extend_structure=False) - prev_mol_graph = MoleculeGraph.with_local_env_strategy(prev_calc_molecule, - OpenBabelNN(), - reorder=False, - extend_structure=False) + OpenBabelNN()) + prev_mol_graph = MoleculeGraph.with_local_env_strategy(prev_calc_mol, + OpenBabelNN()) if mol_graph.isomorphic_to(prev_mol_graph): mol = prev_calc_mol else: diff --git a/atomate/qchem/tests/test_drones.py b/atomate/qchem/tests/test_drones.py index 970f53b53..252f05b1f 100644 --- a/atomate/qchem/tests/test_drones.py +++ b/atomate/qchem/tests/test_drones.py @@ -208,13 +208,9 @@ def test_assimilate_unstable_opt(self): self.assertEqual(doc["orig"]["rem"], doc["calcs_reversed"][-1]["input"]["rem"]) self.assertEqual(doc["orig"]["molecule"], doc["calcs_reversed"][-1]["input"]["molecule"]) orig_molgraph = MoleculeGraph.with_local_env_strategy(Molecule.from_dict(doc["orig"]["molecule"]), - OpenBabelNN(), - reorder=False, - extend_structure=False) + OpenBabelNN()) initial_molgraph = MoleculeGraph.with_local_env_strategy(Molecule.from_dict(doc["input"]["initial_molecule"]), - OpenBabelNN(), - reorder=False, - extend_structure=False) + OpenBabelNN()) self.assertEqual(orig_molgraph.isomorphic_to(initial_molgraph), True) def test_assimilate_opt_with_hidden_changes_from_handler(self): @@ -238,13 +234,9 @@ def test_assimilate_opt_with_hidden_changes_from_handler(self): self.assertEqual(doc["pointgroup"], "C1") self.assertEqual(doc["orig"]["rem"], doc["calcs_reversed"][-1]["input"]["rem"]) orig_molgraph = MoleculeGraph.with_local_env_strategy(Molecule.from_dict(doc["orig"]["molecule"]), - OpenBabelNN(), - reorder=False, - extend_structure=False) + OpenBabelNN()) initial_molgraph = MoleculeGraph.with_local_env_strategy(Molecule.from_dict(doc["input"]["initial_molecule"]), - OpenBabelNN(), - reorder=False, - extend_structure=False) + OpenBabelNN()) self.assertEqual(orig_molgraph.isomorphic_to(initial_molgraph), False) def test_assimilate_disconnected_opt(self): From b0c1b57d3a8b2be07ed3bb4cc536dd11ee1c5d98 Mon Sep 17 00:00:00 2001 From: "Evan Walter Clark Spotte-Smith, PhD" Date: Thu, 18 Jul 2024 09:58:38 -0400 Subject: [PATCH 03/11] Working on Multiwfn/QTAIM calculations for new MPcules expansion --- atomate/qchem/drones.py | 3 +- atomate/qchem/firetasks/multiwfn.py | 88 +++++++++++++++++ .../qchem/firetasks/tests/test_multiwfn.py | 71 +++++++++++++ atomate/qchem/fireworks/core.py | 88 +++++++++++++++++ atomate/qchem/fireworks/tests/test_core.py | 99 +++++++++++++++++++ 5 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 atomate/qchem/firetasks/multiwfn.py create mode 100644 atomate/qchem/firetasks/tests/test_multiwfn.py diff --git a/atomate/qchem/drones.py b/atomate/qchem/drones.py index 08c416b4b..bed8cdb2e 100644 --- a/atomate/qchem/drones.py +++ b/atomate/qchem/drones.py @@ -14,12 +14,13 @@ from pymatgen.io.babel import BabelMolAdaptor from pymatgen.io.qchem.inputs import QCInput from pymatgen.io.qchem.outputs import QCOutput +from pymatgen.io.multiwfn import process_multiwfn_qtaim from pymatgen.symmetry.analyzer import PointGroupAnalyzer from atomate import __version__ as atomate_version from atomate.utils.utils import get_logger -__author__ = "Samuel Blau" +__author__ = "Samuel Blau, Evan Spotte-Smith" __copyright__ = "Copyright 2018, The Materials Project" __version__ = "0.1" __maintainer__ = "Samuel Blau" diff --git a/atomate/qchem/firetasks/multiwfn.py b/atomate/qchem/firetasks/multiwfn.py new file mode 100644 index 000000000..53f385ed5 --- /dev/null +++ b/atomate/qchem/firetasks/multiwfn.py @@ -0,0 +1,88 @@ +# This module defines Firetask that run Multiwfn to analyze a wavefunction (*.wfn) file produced by e.g. Q-Chem. + + +from pathlib import Path +import subprocess + +from fireworks import FiretaskBase, explicit_serialize +from monty.serialization import dumpfn, loadfn +from monty.shutil import compress_file, decompress_file + +from atomate.utils.utils import get_logger + +__author__ = "Evan Spotte-Smith" +__copyright__ = "Copyright 2024, The Materials Project" +__version__ = "0.1" +__maintainer__ = "Evan Spotte-Smith" +__email__ = "espottesmith@gmail.com" +__status__ = "Alpha" +__date__ = "07/17/2024" + + +logger = get_logger(__name__) + + +@explicit_serialize +class RunMultiwfn_QTAIM(FiretaskBase): + """ + Run the Multiwfn package on an electron density wavefunction (*.wfn) file produced by a Q-Chem calculation + to generate a CPprop file for quantum theory of atoms in molecules (QTAIM) analysis. + + Required params: + molecule (Molecule): Molecule object of the molecule whose electron density is being analyzed + Note that if prev_calc_molecule is set in the firework spec it will override + the molecule required param. + multiwfn_command (str): Shell command to run Multiwfn + wfn_file (str): Name of the wavefunction file being analyzed + + """ + + required_params = ["molecule", "multiwfn_command", "wfn_file", "output_file"] + + def run_task(self, fw_spec): + if fw_spec.get("prev_calc_molecule"): + molecule = fw_spec.get("prev_calc_molecule") + else: + molecule = self.get("molecule") + if molecule is None: + raise ValueError( + "No molecule passed and no prev_calc_molecule found in spec! Exiting..." + ) + + compress_at_end = False + + wfn = self.get("wfn_file") + + if wfn[-3:] == ".gz": + compress_at_end = True + decompress_file(wfn) + wfn = wfn[:-3] + + # This will run through an interactive Multiwfn dialogue and select the necessary options for QTAIM + input_script = """ +2 +2 +3 +4 +5 +6 +-1 +-9 +8 +7 +0 +-10 +q + """ + + with open("multiwfn_options.txt", "w") as file: + file.write(input_script) + + cmd = f"{self.get('multiwfn_command')} {wfn} < multiwfn_options.txt | tee {self.get('output_file')}" + + logger.info(f"Running command: {cmd}") + return_code = subprocess.call(cmd, shell=True) + logger.info(f"Command {cmd} finished running with return code: {return_code}") + + if compress_at_end: + compress_file(wfn) diff --git a/atomate/qchem/firetasks/tests/test_multiwfn.py b/atomate/qchem/firetasks/tests/test_multiwfn.py new file mode 100644 index 000000000..28b8dc3d7 --- /dev/null +++ b/atomate/qchem/firetasks/tests/test_multiwfn.py @@ -0,0 +1,71 @@ +import json +import os +import shutil +import unittest +from shutil import which + +from pymatgen.io.qchem.outputs import QCOutput + +from atomate.qchem.firetasks.critic2 import ProcessCritic2, RunCritic2 +from atomate.utils.testing import AtomateTest + +__author__ = "Evan Spotte-Smith" +__email__ = "espottesmith@gmail.com" + +module_dir = os.path.dirname(os.path.abspath(__file__)) + + +@unittest.skipIf(not which("Multiwfn_noGUI"), "Multiwfn executable not present") +class TestRunMultiwfn_QTAIM(AtomateTest): + + def setUp(self, lpad=False): + os.chdir( + os.path.join( + module_dir, + "..", + "..", + "test_files", + "critic_test_files", + "small_critic_example", + ) + ) + out_file = "mol.qout" + qc_out = QCOutput(filename=out_file) + self.mol = qc_out.data["initial_molecule"] + self.cube_file = "dens.0.cube" + super().setUp(lpad=False) + + def tearDown(self): + os.remove("cpreport.json") + os.remove("yt.json") + + def test_RunCritic2(self): + os.chdir( + os.path.join( + module_dir, + "..", + "..", + "test_files", + "critic_test_files", + "small_critic_example", + ) + ) + firetask = RunCritic2(molecule=self.mol, cube_file="dens.0.cube.gz") + firetask.run_task(fw_spec={}) + with open("cpreport_correct.json") as f: + cpreport_reference = json.load(f) + with open("yt_correct.json") as f: + yt_reference = json.load(f) + with open("cpreport.json") as f: + cpreport = json.load(f) + with open("yt.json") as f: + yt = json.load(f) + # Context for below - reference files were built before units were added + # to Critic2, and we avoid testing the actual critical points because they + # can change order between runs. But comparing everything else is sufficient. + for key in cpreport: + if key in ["structure", "field"]: + self.assertEqual(cpreport_reference[key], cpreport[key]) + for key in yt: + if key != "units": + self.assertEqual(yt_reference[key], yt[key]) diff --git a/atomate/qchem/fireworks/core.py b/atomate/qchem/fireworks/core.py index 91f438ff0..7b4086c10 100644 --- a/atomate/qchem/fireworks/core.py +++ b/atomate/qchem/fireworks/core.py @@ -11,6 +11,7 @@ from atomate.qchem.firetasks.critic2 import ProcessCritic2, RunCritic2 from atomate.qchem.firetasks.fragmenter import FragmentMolecule from atomate.qchem.firetasks.geo_transformations import PerturbGeometry +from atomate.qchem.firetasks.multiwfn import RunMultiwfn_QTAIM from atomate.qchem.firetasks.parse_outputs import ProtCalcToDb, QChemToDb from atomate.qchem.firetasks.run_calc import RunQChemCustodian from atomate.qchem.firetasks.write_inputs import WriteInputFromIOSet @@ -1036,3 +1037,90 @@ def __init__( ) ) super().__init__(t, parents=parents, name=name, **kwargs) + + +class WfnAndQTAIMFW(Firework): + def __init__( + self, + molecule=None, + name="Wavefunction and QTAIM", + qchem_cmd=">>qchem_cmd<<", + multimode=">>multimode<<", + max_cores=">>max_cores<<", + multiwfn_command=">>multiwfn_command<<", + qchem_input_params=None, + db_file=None, + parents=None, + max_errors=5, + **kwargs + ): + """ + Perform a Q-Chem single point calculation in order to generate a wavefunction file of the electron density + and then analyze the electron density critical points with the Multiwfn package. + + Args: + molecule (Molecule): Input molecule. + name (str): Name for the Firework. + qchem_cmd (str): Command to run QChem. Supports env_chk. + multimode (str): Parallelization scheme, either openmp or mpi. Supports env_chk. + max_cores (int): Maximum number of cores to parallelize over. Supports env_chk. + multiwfn_command (str): Terminal command for Multiwfn. Supports env_chk. + qchem_input_params (dict): Specify kwargs for instantiating the input set parameters. + Basic uses would be to modify the default inputs of the set, such as dft_rung, + basis_set, pcm_dielectric, scf_algorithm, or max_scf_cycles. See + pymatgen/io/qchem/sets.py for default values of all input parameters. For + instance, if a user wanted to use a more advanced DFT functional, include a pcm + with a dielectric of 30, and use a larger basis, the user would set + qchem_input_params = {"dft_rung": 5, "pcm_dielectric": 30, "basis_set": + "6-311++g**"}. However, more advanced customization of the input is also + possible through the overwrite_inputs key which allows the user to directly + modify the rem, pcm, smd, and solvent dictionaries that QChemDictSet passes to + inputs.py to print an actual input file. For instance, if a user wanted to set + the sym_ignore flag in the rem section of the input file to true, then they + would set qchem_input_params = {"overwrite_inputs": "rem": {"sym_ignore": + "true"}}. Of course, overwrite_inputs could be used in conjunction with more + typical modifications, as seen in the test_double_FF_opt workflow test. + db_file (str): Path to file specifying db credentials to place output parsing. + parents ([Firework]): Parents of this particular Firework. + **kwargs: Other kwargs that are passed to Firework.__init__. + """ + + qchem_input_params = copy.deepcopy(qchem_input_params) or {} + qchem_input_params["output_wavefunction"] = True + + input_file = "mol.qin" + output_file = "mol.qout" + t = [] + t.append( + WriteInputFromIOSet( + molecule=molecule, + qchem_input_set="SinglePointSet", + input_file=input_file, + qchem_input_params=qchem_input_params, + ) + ) + t.append( + RunQChemCustodian( + qchem_cmd=qchem_cmd, + multimode=multimode, + input_file=input_file, + output_file=output_file, + max_cores=max_cores, + max_errors=max_errors, + job_type="normal", + ) + ) + t.append(RunMultiwfn_QTAIM( + molecule=molecule, + multiwfn_command=multiwfn_command, + wfn_file="WAVEFUNCTION.wfn", + output_file="qtaim.out")) + t.append( + QChemToDb( + db_file=db_file, + input_file=input_file, + output_file=output_file, + additional_fields={"task_label": name}, + ) + ) + super().__init__(t, parents=parents, name=name, **kwargs) diff --git a/atomate/qchem/fireworks/tests/test_core.py b/atomate/qchem/fireworks/tests/test_core.py index 7f743668c..a6e7970fa 100644 --- a/atomate/qchem/fireworks/tests/test_core.py +++ b/atomate/qchem/fireworks/tests/test_core.py @@ -9,6 +9,7 @@ from atomate.qchem.firetasks.critic2 import ProcessCritic2, RunCritic2 from atomate.qchem.firetasks.fragmenter import FragmentMolecule from atomate.qchem.firetasks.geo_transformations import PerturbGeometry +from atomate.qchem.firetasks.multiwfn import RunMultiwfn_QTAIM from atomate.qchem.firetasks.parse_outputs import ProtCalcToDb, QChemToDb from atomate.qchem.firetasks.run_calc import RunQChemCustodian from atomate.qchem.firetasks.write_inputs import WriteInputFromIOSet @@ -23,6 +24,7 @@ ProtonEnergyFW, SinglePointFW, TransitionStateFW, + WfnAndQTAIMFW ) from atomate.utils.testing import AtomateTest @@ -924,3 +926,100 @@ def test_CubeAndCritic2FW_not_defaults(self): ) self.assertEqual(firework.parents, []) self.assertEqual(firework.name, "special cube and critic2") + + def test_WfnAndQTAIMFW_defaults(self): + firework = WfnAndQTAIMFW(molecule=self.act_mol) + self.assertEqual( + firework.tasks[0].as_dict(), + WriteInputFromIOSet( + molecule=self.act_mol, + qchem_input_set="SinglePointSet", + input_file="mol.qin", + qchem_input_params={"output_wavefunction": True}, + ).as_dict(), + ) + self.assertEqual( + firework.tasks[1].as_dict(), + RunQChemCustodian( + qchem_cmd=">>qchem_cmd<<", + multimode=">>multimode<<", + input_file="mol.qin", + output_file="mol.qout", + max_cores=">>max_cores<<", + max_errors=5, + job_type="normal", + ).as_dict(), + ) + self.assertEqual( + firework.tasks[2].as_dict(), + RunMultiwfn_QTAIM( + molecule=self.act_mol, + multiwfn_command=">>multiwfn_command<<", + wfn_file="WAVEFUNCTION.wfn", + output_file="qtaim.out" + ).as_dict(), + ) + self.assertEqual( + firework.tasks[3].as_dict(), + QChemToDb( + db_file=None, + input_file="mol.qin", + output_file="mol.qout", + additional_fields={"task_label": "Wavefunction and QTAIM"}, + ).as_dict(), + ) + self.assertEqual(firework.parents, []) + self.assertEqual(firework.name, "Wavefunction and QTAIM") + + def test_WfnAndQTAIMFW_not_defaults(self): + firework = WfnAndQTAIMFW( + molecule=self.act_mol, + name="special multiwfn QTAIM", + qchem_cmd="qchem -slurm", + multimode="mpi", + max_cores=12, + qchem_input_params={"pcm_dielectric": 10.0}, + db_file=db_file, + parents=None, + ) + self.assertEqual( + firework.tasks[0].as_dict(), + WriteInputFromIOSet( + molecule=self.act_mol, + qchem_input_set="SinglePointSet", + input_file="mol.qin", + qchem_input_params={"pcm_dielectric": 10.0, "output_wavefunction": True}, + ).as_dict(), + ) + self.assertEqual( + firework.tasks[1].as_dict(), + RunQChemCustodian( + qchem_cmd="qchem -slurm", + multimode="mpi", + input_file="mol.qin", + output_file="mol.qout", + max_cores=12, + max_errors=5, + job_type="normal", + ).as_dict(), + ) + self.assertEqual( + firework.tasks[2].as_dict(), + RunMultiwfn_QTAIM( + molecule=self.act_mol, + multiwfn_command=">>multiwfn_command<<", + wfn_file="WAVEFUNCTION.wfn", + output_file="qtaim.out" + ).as_dict(), + ) + self.assertEqual( + firework.tasks[3].as_dict(), + QChemToDb( + db_file=db_file, + input_file="mol.qin", + output_file="mol.qout", + additional_fields={"task_label": "special multiwfn QTAIM"}, + ).as_dict(), + ) + self.assertEqual(firework.parents, []) + self.assertEqual(firework.name, "special multiwfn QTAIM") From 2dc370251d31faf2fdef9f9a35a1e7ecea3e50d1 Mon Sep 17 00:00:00 2001 From: "Evan Walter Clark Spotte-Smith, PhD" Date: Thu, 18 Jul 2024 10:59:48 -0400 Subject: [PATCH 04/11] Initial work on drones; trying to bugfix Multiwfn to handle compression --- atomate/qchem/drones.py | 13 ++++++++++++- atomate/qchem/firetasks/multiwfn.py | 7 +++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/atomate/qchem/drones.py b/atomate/qchem/drones.py index bed8cdb2e..e4a4cd04b 100644 --- a/atomate/qchem/drones.py +++ b/atomate/qchem/drones.py @@ -9,6 +9,8 @@ from monty.io import zopen from monty.json import jsanitize +from monty.shutil import compress_file, decompress_file + from pymatgen.apps.borg.hive import AbstractDrone from pymatgen.core import Molecule from pymatgen.io.babel import BabelMolAdaptor @@ -20,7 +22,7 @@ from atomate import __version__ as atomate_version from atomate.utils.utils import get_logger -__author__ = "Samuel Blau, Evan Spotte-Smith" +__author__ = "Samuel Blau" __copyright__ = "Copyright 2018, The Materials Project" __version__ = "0.1" __maintainer__ = "Samuel Blau" @@ -503,6 +505,15 @@ def post_process(dir_name, d): if len(filenames) >= 1: with zopen(filenames[0], "rt") as f: d["critic2"]["bonding"] = json.load(f) + # filenames = glob.glob(os.path.join(fullpath, "CPprop.txt*")) + # if len(filenames) >= 1: + # filename = filenames[0] + # recompress = False + # if filename[-3:] == ".gz": + # recompress = True + # decompress_file(os.path.join(fullpath, filename)) + # filename = filename[:-3] + def validate_doc(self, d): """ diff --git a/atomate/qchem/firetasks/multiwfn.py b/atomate/qchem/firetasks/multiwfn.py index 53f385ed5..2650abb1a 100644 --- a/atomate/qchem/firetasks/multiwfn.py +++ b/atomate/qchem/firetasks/multiwfn.py @@ -1,6 +1,5 @@ # This module defines Firetask that run Multiwfn to analyze a wavefunction (*.wfn) file produced by e.g. Q-Chem. - from pathlib import Path import subprocess @@ -34,7 +33,7 @@ class RunMultiwfn_QTAIM(FiretaskBase): the molecule required param. multiwfn_command (str): Shell command to run Multiwfn wfn_file (str): Name of the wavefunction file being analyzed - + output_file (str): Name of the output file containing the Multiwfn outputs """ required_params = ["molecule", "multiwfn_command", "wfn_file", "output_file"] @@ -53,6 +52,10 @@ def run_task(self, fw_spec): wfn = self.get("wfn_file") + # File might be compressed + if not os.path.exists(wfn) and not wfn.endswith(".gz"): + wfn += ".gz" + if wfn[-3:] == ".gz": compress_at_end = True decompress_file(wfn) From 7cfb5aa2b06618f9f2a8dc5d1f7e67318b4350ec Mon Sep 17 00:00:00 2001 From: "Evan Walter Clark Spotte-Smith, PhD" Date: Thu, 18 Jul 2024 13:49:41 -0400 Subject: [PATCH 05/11] more bugfixes --- atomate/qchem/drones.py | 13 +++++++++++++ atomate/qchem/firetasks/multiwfn.py | 1 + atomate/qchem/fireworks/core.py | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/atomate/qchem/drones.py b/atomate/qchem/drones.py index e4a4cd04b..497172e36 100644 --- a/atomate/qchem/drones.py +++ b/atomate/qchem/drones.py @@ -514,6 +514,19 @@ def post_process(dir_name, d): # decompress_file(os.path.join(fullpath, filename)) # filename = filename[:-3] + # if "optimized_molecule" in d["output"]: + # mol = d["output"]["optimized_molecule"] + # else: + # mol = d["output"]["initial_molecule"] + + # if not isinstance(mol, Molecule): + # mol = Molecule.from_dict(mol) + + # d["output"]["qtaim"] = process_multiwfn_qtaim(mol, os.path.join(fullpath, filename)) + + # if recompress: + # compress_file(os.path.join(fullpath, filename)) + def validate_doc(self, d): """ diff --git a/atomate/qchem/firetasks/multiwfn.py b/atomate/qchem/firetasks/multiwfn.py index 2650abb1a..feeaa4517 100644 --- a/atomate/qchem/firetasks/multiwfn.py +++ b/atomate/qchem/firetasks/multiwfn.py @@ -1,5 +1,6 @@ # This module defines Firetask that run Multiwfn to analyze a wavefunction (*.wfn) file produced by e.g. Q-Chem. +import os from pathlib import Path import subprocess diff --git a/atomate/qchem/fireworks/core.py b/atomate/qchem/fireworks/core.py index 7b4086c10..9a2dda1e1 100644 --- a/atomate/qchem/fireworks/core.py +++ b/atomate/qchem/fireworks/core.py @@ -1039,7 +1039,7 @@ def __init__( super().__init__(t, parents=parents, name=name, **kwargs) -class WfnAndQTAIMFW(Firework): +class basic.css(Firework): def __init__( self, molecule=None, From 7d3f4427c1ba493481e46608ad9d8a35f1cf4c2f Mon Sep 17 00:00:00 2001 From: "Evan Walter Clark Spotte-Smith, PhD" Date: Thu, 18 Jul 2024 13:51:15 -0400 Subject: [PATCH 06/11] Name --- atomate/qchem/fireworks/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atomate/qchem/fireworks/core.py b/atomate/qchem/fireworks/core.py index 9a2dda1e1..7b4086c10 100644 --- a/atomate/qchem/fireworks/core.py +++ b/atomate/qchem/fireworks/core.py @@ -1039,7 +1039,7 @@ def __init__( super().__init__(t, parents=parents, name=name, **kwargs) -class basic.css(Firework): +class WfnAndQTAIMFW(Firework): def __init__( self, molecule=None, From f55466fb98b0019506ef3a687579fbd1bce3f157 Mon Sep 17 00:00:00 2001 From: "Evan Walter Clark Spotte-Smith, PhD" Date: Thu, 18 Jul 2024 14:59:59 -0400 Subject: [PATCH 07/11] removing unnecessary output --- atomate/qchem/firetasks/multiwfn.py | 4 ++-- atomate/qchem/fireworks/core.py | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/atomate/qchem/firetasks/multiwfn.py b/atomate/qchem/firetasks/multiwfn.py index feeaa4517..d3d18e5a9 100644 --- a/atomate/qchem/firetasks/multiwfn.py +++ b/atomate/qchem/firetasks/multiwfn.py @@ -37,7 +37,7 @@ class RunMultiwfn_QTAIM(FiretaskBase): output_file (str): Name of the output file containing the Multiwfn outputs """ - required_params = ["molecule", "multiwfn_command", "wfn_file", "output_file"] + required_params = ["molecule", "multiwfn_command", "wfn_file"] def run_task(self, fw_spec): if fw_spec.get("prev_calc_molecule"): @@ -82,7 +82,7 @@ def run_task(self, fw_spec): with open("multiwfn_options.txt", "w") as file: file.write(input_script) - cmd = f"{self.get('multiwfn_command')} {wfn} < multiwfn_options.txt | tee {self.get('output_file')}" + cmd = f"{self.get('multiwfn_command')} {wfn} < multiwfn_options.txt" logger.info(f"Running command: {cmd}") return_code = subprocess.call(cmd, shell=True) diff --git a/atomate/qchem/fireworks/core.py b/atomate/qchem/fireworks/core.py index 7b4086c10..9e1076380 100644 --- a/atomate/qchem/fireworks/core.py +++ b/atomate/qchem/fireworks/core.py @@ -1110,11 +1110,12 @@ def __init__( job_type="normal", ) ) - t.append(RunMultiwfn_QTAIM( - molecule=molecule, - multiwfn_command=multiwfn_command, - wfn_file="WAVEFUNCTION.wfn", - output_file="qtaim.out")) + t.append( + RunMultiwfn_QTAIM( + molecule=molecule, + multiwfn_command=multiwfn_command, + wfn_file="WAVEFUNCTION.wfn") + ) t.append( QChemToDb( db_file=db_file, From a9edc261815b635f532bfbb837cbb11a72da02d7 Mon Sep 17 00:00:00 2001 From: "Evan Walter Clark Spotte-Smith, PhD" Date: Thu, 18 Jul 2024 15:07:19 -0400 Subject: [PATCH 08/11] Trying to parse, and also trying to handle env_chk --- atomate/qchem/drones.py | 34 ++++++++++++++--------------- atomate/qchem/firetasks/multiwfn.py | 7 +++--- atomate/qchem/fireworks/core.py | 3 ++- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/atomate/qchem/drones.py b/atomate/qchem/drones.py index 497172e36..a2df7ed0e 100644 --- a/atomate/qchem/drones.py +++ b/atomate/qchem/drones.py @@ -505,27 +505,27 @@ def post_process(dir_name, d): if len(filenames) >= 1: with zopen(filenames[0], "rt") as f: d["critic2"]["bonding"] = json.load(f) - # filenames = glob.glob(os.path.join(fullpath, "CPprop.txt*")) - # if len(filenames) >= 1: - # filename = filenames[0] - # recompress = False - # if filename[-3:] == ".gz": - # recompress = True - # decompress_file(os.path.join(fullpath, filename)) - # filename = filename[:-3] + filenames = glob.glob(os.path.join(fullpath, "CPprop.txt*")) + if len(filenames) >= 1: + filename = filenames[0] + recompress = False + if filename[-3:] == ".gz": + recompress = True + decompress_file(os.path.join(fullpath, filename)) + filename = filename[:-3] - # if "optimized_molecule" in d["output"]: - # mol = d["output"]["optimized_molecule"] - # else: - # mol = d["output"]["initial_molecule"] + if "optimized_molecule" in d["output"]: + mol = d["output"]["optimized_molecule"] + else: + mol = d["output"]["initial_molecule"] - # if not isinstance(mol, Molecule): - # mol = Molecule.from_dict(mol) + if not isinstance(mol, Molecule): + mol = Molecule.from_dict(mol) - # d["output"]["qtaim"] = process_multiwfn_qtaim(mol, os.path.join(fullpath, filename)) + d["output"]["qtaim"] = process_multiwfn_qtaim(mol, os.path.join(fullpath, filename)) - # if recompress: - # compress_file(os.path.join(fullpath, filename)) + if recompress: + compress_file(os.path.join(fullpath, filename)) def validate_doc(self, d): diff --git a/atomate/qchem/firetasks/multiwfn.py b/atomate/qchem/firetasks/multiwfn.py index d3d18e5a9..739509a24 100644 --- a/atomate/qchem/firetasks/multiwfn.py +++ b/atomate/qchem/firetasks/multiwfn.py @@ -8,7 +8,7 @@ from monty.serialization import dumpfn, loadfn from monty.shutil import compress_file, decompress_file -from atomate.utils.utils import get_logger +from atomate.utils.utils import env_chk, get_logger __author__ = "Evan Spotte-Smith" __copyright__ = "Copyright 2024, The Materials Project" @@ -34,7 +34,6 @@ class RunMultiwfn_QTAIM(FiretaskBase): the molecule required param. multiwfn_command (str): Shell command to run Multiwfn wfn_file (str): Name of the wavefunction file being analyzed - output_file (str): Name of the output file containing the Multiwfn outputs """ required_params = ["molecule", "multiwfn_command", "wfn_file"] @@ -82,7 +81,9 @@ def run_task(self, fw_spec): with open("multiwfn_options.txt", "w") as file: file.write(input_script) - cmd = f"{self.get('multiwfn_command')} {wfn} < multiwfn_options.txt" + base_command = env_chk(self.get("multiwfn_command"), fw_spec) + + cmd = f"{base_command} {wfn} < multiwfn_options.txt" logger.info(f"Running command: {cmd}") return_code = subprocess.call(cmd, shell=True) diff --git a/atomate/qchem/fireworks/core.py b/atomate/qchem/fireworks/core.py index 9e1076380..09f322551 100644 --- a/atomate/qchem/fireworks/core.py +++ b/atomate/qchem/fireworks/core.py @@ -1114,8 +1114,9 @@ def __init__( RunMultiwfn_QTAIM( molecule=molecule, multiwfn_command=multiwfn_command, - wfn_file="WAVEFUNCTION.wfn") + wfn_file="WAVEFUNCTION.wfn" ) + ) t.append( QChemToDb( db_file=db_file, From 5b67e8f13c312f742930ee4e765c2213a1cf9c04 Mon Sep 17 00:00:00 2001 From: "Evan Walter Clark Spotte-Smith, PhD" Date: Thu, 18 Jul 2024 15:39:22 -0400 Subject: [PATCH 09/11] Testing --- .../qchem/firetasks/tests/test_multiwfn.py | 68 +++-- .../multiwfn_example/CPprop_correct.txt | 285 ++++++++++++++++++ .../multiwfn_example/WAVEFUNCTION.wfn.gz | Bin 0 -> 2406 bytes .../test_files/multiwfn_example/mol.qin.gz | Bin 0 -> 265 bytes .../multiwfn_example/mol.qin.orig.gz | Bin 0 -> 270 bytes .../test_files/multiwfn_example/mol.qout.gz | Bin 0 -> 5272 bytes 6 files changed, 325 insertions(+), 28 deletions(-) create mode 100644 atomate/qchem/test_files/multiwfn_example/CPprop_correct.txt create mode 100644 atomate/qchem/test_files/multiwfn_example/WAVEFUNCTION.wfn.gz create mode 100644 atomate/qchem/test_files/multiwfn_example/mol.qin.gz create mode 100644 atomate/qchem/test_files/multiwfn_example/mol.qin.orig.gz create mode 100644 atomate/qchem/test_files/multiwfn_example/mol.qout.gz diff --git a/atomate/qchem/firetasks/tests/test_multiwfn.py b/atomate/qchem/firetasks/tests/test_multiwfn.py index 28b8dc3d7..54c46985d 100644 --- a/atomate/qchem/firetasks/tests/test_multiwfn.py +++ b/atomate/qchem/firetasks/tests/test_multiwfn.py @@ -5,8 +5,9 @@ from shutil import which from pymatgen.io.qchem.outputs import QCOutput +from pymatgen.io.multiwfn import process_multiwfn_qtaim -from atomate.qchem.firetasks.critic2 import ProcessCritic2, RunCritic2 +from atomate.qchem.firetasks.multiwfn import RunMultiwfn_QTAIM from atomate.utils.testing import AtomateTest __author__ = "Evan Spotte-Smith" @@ -25,47 +26,58 @@ def setUp(self, lpad=False): "..", "..", "test_files", - "critic_test_files", - "small_critic_example", + "multiwfn_example", ) ) - out_file = "mol.qout" + out_file = "mol.qout.gz" qc_out = QCOutput(filename=out_file) self.mol = qc_out.data["initial_molecule"] - self.cube_file = "dens.0.cube" + self.wavefunction = "WAVEFUNCTION.wfn.gz" super().setUp(lpad=False) def tearDown(self): - os.remove("cpreport.json") - os.remove("yt.json") + os.remove("multiwfn_options.txt") + os.remove("CPprop.txt") - def test_RunCritic2(self): + def test_run(self): os.chdir( os.path.join( module_dir, "..", "..", "test_files", - "critic_test_files", - "small_critic_example", + "multiwfn_example" ) ) - firetask = RunCritic2(molecule=self.mol, cube_file="dens.0.cube.gz") + firetask = RunMultiwfn_QTAIM( + molecule=self.mol, + multiwfn_command="Multiwfn_noGUI", + wfn_file="WAVEFUNCTION.wfn.gz" + ) firetask.run_task(fw_spec={}) - with open("cpreport_correct.json") as f: - cpreport_reference = json.load(f) - with open("yt_correct.json") as f: - yt_reference = json.load(f) - with open("cpreport.json") as f: - cpreport = json.load(f) - with open("yt.json") as f: - yt = json.load(f) - # Context for below - reference files were built before units were added - # to Critic2, and we avoid testing the actual critical points because they - # can change order between runs. But comparing everything else is sufficient. - for key in cpreport: - if key in ["structure", "field"]: - self.assertEqual(cpreport_reference[key], cpreport[key]) - for key in yt: - if key != "units": - self.assertEqual(yt_reference[key], yt[key]) + + reference = process_multiwfn_qtaim( + self.mol, + "CPprop_correct.txt" + ) + + this_output = process_multiwfn_qtaim( + self.mol, + "Cpprop.txt" + ) + + for root in ["atom", "bond", "ring", "cage"]: + assert len(reference[root]) == len(this_output[root]) + + for k, v in reference[root].items(): + assert k in this_output[root] + + for kk, vv in reference[root][k].items(): + output_val = this_output[root][k].get(kk) + if isinstance(vv, list): + assert isinstance(output_val, list) + assert len(vv) == len(output_val) + for index, vvelem in enumerate(vv): + self.assertAlmostEqual(vvelem, output_val[index]) + + self.assertAlmostEqual(vv, output_val) diff --git a/atomate/qchem/test_files/multiwfn_example/CPprop_correct.txt b/atomate/qchem/test_files/multiwfn_example/CPprop_correct.txt new file mode 100644 index 000000000..29d079c6c --- /dev/null +++ b/atomate/qchem/test_files/multiwfn_example/CPprop_correct.txt @@ -0,0 +1,285 @@ + ---------------- CP 1, Type (3,-3) ---------------- + Corresponding nucleus: 3(H ) + Position (Bohr): -1.337339520632 -0.000000000000 0.775959946246 + Position (Angstrom): -0.707689597558 -0.000000000000 0.410620320127 + Density of all electrons: 0.3782607341E+00 + Density of Alpha electrons: 0.1891303670E+00 + Density of Beta electrons: 0.1891303670E+00 + Spin density of electrons: 0.0000000000E+00 + Lagrangian kinetic energy G(r): 0.3512887562E-01 + G(r) in X,Y,Z: 0.7302608021E-02 0.1630970689E-01 0.1151656070E-01 + Hamiltonian kinetic energy K(r): 0.2755647555E+01 + Potential energy density V(r): -0.2790776431E+01 + Energy density E(r) or H(r): -0.2755647555E+01 + Laplacian of electron density: -0.1088207472E+02 + Electron localization function (ELF): 0.9961880925E+00 + Localized orbital locator (LOL): 0.9417605346E+00 + Local information entropy: 0.1238711851E+00 + Interaction region indicator (IRI): 0.1227765191E-14 + Reduced density gradient (RDG): 0.1000000000E+03 + Reduced density gradient with promolecular approximation: 0.1000000000E+03 + Sign(lambda2)*rho: -0.3782607341E+00 + Sign(lambda2)*rho with promolecular approximation: -0.2725147331E+00 + Corr. hole for alpha, ref.: 0.00000 0.00000 0.00000 : -0.1644007684E-01 + Source function, ref.: 0.00000 0.00000 0.00000 : 0.5600789039E+00 + Wavefunction value for orbital 1 : 0.5188581219E-03 + Average local ionization energy (ALIE): 0.6005322342E+00 + van der Waals potential (probe atom: C ): 0.2967244083E+21 kcal/mol + Delta-g (under promolecular approximation): 0.2685216677E+00 + Delta-g (under Hirshfeld partition): 0.4848667837E+00 + User-defined real space function: 0.1000000000E+01 + ESP from nuclear charges: 0.1509528627E+02 + ESP from electrons: -0.5975126213E+01 + Total ESP: 0.9120160059E+01 a.u. ( 0.2481722E+03 eV, 0.5722992E+04 kcal/mol) + + Note: Below information are for electron density + + Components of gradient in x/y/z are: + -0.4024558464E-15 -0.2341930812E-30 -0.1249000903E-15 + Norm of gradient is: 0.4213914343E-15 + + Components of Laplacian in x/y/z are: + -0.3197448104E+01 -0.4129218918E+01 -0.3555407697E+01 + Total: -0.1088207472E+02 + + Hessian matrix: + -0.3197448104E+01 -0.4545748972E-15 -0.7528122252E+00 + -0.4545748972E-15 -0.4129218918E+01 0.3306752341E-15 + -0.7528122252E+00 0.3306752341E-15 -0.3555407697E+01 + Eigenvalues of Hessian: -0.4150223748E+01 -0.4129218918E+01 -0.2602632053E+01 + Eigenvectors (columns) of Hessian: + 0.6199592504E+00 -0.2119371817E-13 -0.7846340089E+00 + -0.3468205455E-13 -0.1000000000E+01 -0.2507157086E-15 + 0.7846340089E+00 -0.2736815302E-13 0.6199592504E+00 + Determinant of Hessian: -0.4460178024E+02 + Ellipticity of electron density: 0.005087 + eta index: -1.594626 + + ---------------- CP 2, Type (3,-3) ---------------- + Corresponding nucleus: 1(H ) + Position (Bohr): 1.337339520632 0.000000000000 0.775959946246 + Position (Angstrom): 0.707689597558 0.000000000000 0.410620320127 + Density of all electrons: 0.3782607341E+00 + Density of Alpha electrons: 0.1891303670E+00 + Density of Beta electrons: 0.1891303670E+00 + Spin density of electrons: 0.0000000000E+00 + Lagrangian kinetic energy G(r): 0.3512887562E-01 + G(r) in X,Y,Z: 0.7302608021E-02 0.1630970689E-01 0.1151656070E-01 + Hamiltonian kinetic energy K(r): 0.2755647555E+01 + Potential energy density V(r): -0.2790776431E+01 + Energy density E(r) or H(r): -0.2755647555E+01 + Laplacian of electron density: -0.1088207472E+02 + Electron localization function (ELF): 0.9961880925E+00 + Localized orbital locator (LOL): 0.9417605346E+00 + Local information entropy: 0.1238711851E+00 + Interaction region indicator (IRI): 0.5725639045E-15 + Reduced density gradient (RDG): 0.1000000000E+03 + Reduced density gradient with promolecular approximation: 0.1000000000E+03 + Sign(lambda2)*rho: -0.3782607341E+00 + Sign(lambda2)*rho with promolecular approximation: -0.2725147331E+00 + Corr. hole for alpha, ref.: 0.00000 0.00000 0.00000 : -0.1644007684E-01 + Source function, ref.: 0.00000 0.00000 0.00000 : 0.5600789039E+00 + Wavefunction value for orbital 1 : 0.5188581219E-03 + Average local ionization energy (ALIE): 0.6005322342E+00 + van der Waals potential (probe atom: C ): 0.2967244083E+21 kcal/mol + Delta-g (under promolecular approximation): 0.2685216677E+00 + Delta-g (under Hirshfeld partition): 0.4848667837E+00 + User-defined real space function: 0.1000000000E+01 + ESP from nuclear charges: 0.1509528627E+02 + ESP from electrons: -0.5975126213E+01 + Total ESP: 0.9120160059E+01 a.u. ( 0.2481722E+03 eV, 0.5722992E+04 kcal/mol) + + Note: Below information are for electron density + + Components of gradient in x/y/z are: + 0.1960237528E-15 0.5423418723E-30 -0.1387778781E-16 + Norm of gradient is: 0.1965143879E-15 + + Components of Laplacian in x/y/z are: + -0.3197448104E+01 -0.4129218918E+01 -0.3555407697E+01 + Total: -0.1088207472E+02 + + Hessian matrix: + -0.3197448104E+01 -0.4175808500E-16 0.7528122252E+00 + -0.4175808500E-16 -0.4129218918E+01 -0.7124909311E-16 + 0.7528122252E+00 -0.7124909311E-16 -0.3555407697E+01 + Eigenvalues of Hessian: -0.4150223748E+01 -0.4129218918E+01 -0.2602632053E+01 + Eigenvectors (columns) of Hessian: + -0.6199592504E+00 -0.2494513094E-13 -0.7846340089E+00 + 0.4109806020E-13 -0.1000000000E+01 -0.5390657820E-15 + 0.7846340089E+00 0.3258113455E-13 -0.6199592504E+00 + Determinant of Hessian: -0.4460178024E+02 + Ellipticity of electron density: 0.005087 + eta index: -1.594626 + + ---------------- CP 3, Type (3,-3) ---------------- + Corresponding nucleus: 2(O ) + Position (Bohr): 0.000000000000 -0.000000000000 -0.312446803730 + Position (Angstrom): 0.000000000000 -0.000000000000 -0.165339728153 + Density of all electrons: 0.2786227526E+03 + Density of Alpha electrons: 0.1393113763E+03 + Density of Beta electrons: 0.1393113763E+03 + Spin density of electrons: 0.0000000000E+00 + Lagrangian kinetic energy G(r): 0.5052394325E+02 + G(r) in X,Y,Z: 0.1377724761E+02 0.2056159587E+02 0.1618509977E+02 + Hamiltonian kinetic energy K(r): 0.2904432903E+06 + Potential energy density V(r): -0.2904938142E+06 + Energy density E(r) or H(r): -0.2904432903E+06 + Laplacian of electron density: -0.1161571065E+07 + Electron localization function (ELF): 0.9999978082E+00 + Localized orbital locator (LOL): 0.9985217138E+00 + Local information entropy: -0.9270541381E+02 + Interaction region indicator (IRI): 0.1806726223E-13 + Reduced density gradient (RDG): 0.1000000000E+03 + Reduced density gradient with promolecular approximation: 0.1000000000E+03 + Sign(lambda2)*rho: -0.2786227526E+03 + Sign(lambda2)*rho with promolecular approximation: -0.2923070389E+03 + Corr. hole for alpha, ref.: 0.00000 0.00000 0.00000 : -0.9764694622E+02 + Source function, ref.: 0.00000 0.00000 0.00000 : 0.2958420035E+06 + Wavefunction value for orbital 1 : -0.1142124610E+02 + Average local ionization energy (ALIE): 0.1782273936E+02 + van der Waals potential (probe atom: C ): 0.1561486723E+66 kcal/mol + Delta-g (under promolecular approximation): 0.5233952285E-01 + Delta-g (under Hirshfeld partition): 0.7788415015E-01 + User-defined real space function: 0.1000000000E+01 + ESP from nuclear charges: 0.3857985358E+06 + ESP from electrons: -0.2338450309E+02 + Total ESP: 0.3857751513E+06 a.u. ( 0.1049748E+08 eV, 0.2420778E+09 kcal/mol) + + Note: Below information are for electron density + + Components of gradient in x/y/z are: + -0.6605776261E-16 0.1893266173E-28 0.8839151633E-11 + Norm of gradient is: 0.8839151633E-11 + + Components of Laplacian in x/y/z are: + -0.3872033274E+06 -0.3871752762E+06 -0.3871924617E+06 + Total: -0.1161571065E+07 + + Hessian matrix: + -0.3872033274E+06 0.2232200022E-13 -0.1004592445E-12 + 0.2232200022E-13 -0.3871752762E+06 -0.6480635931E-14 + -0.1004592445E-12 -0.6480635931E-14 -0.3871924617E+06 + Eigenvalues of Hessian: -0.3872033274E+06 -0.3871924617E+06 -0.3871752762E+06 + Eigenvectors (columns) of Hessian: + -0.1000000000E+01 0.0000000000E+00 0.1716317631E-11 + 0.1716393475E-11 0.0000000000E+00 0.1000000000E+01 + 0.0000000000E+00 0.1000000000E+01 0.0000000000E+00 + Determinant of Hessian: -0.5804617289E+17 + Ellipticity of electron density: 0.000028 + eta index: -1.000072 + + ---------------- CP 4, Type (3,-1) ---------------- + Connected atoms: 3(H ) -- 2(O ) + Position (Bohr): -1.139728273109 -0.000000000000 0.619195673290 + Position (Angstrom): -0.603118228751 -0.000000000000 0.327664239395 + Density of all electrons: 0.3555268313E+00 + Density of Alpha electrons: 0.1777634156E+00 + Density of Beta electrons: 0.1777634156E+00 + Spin density of electrons: 0.0000000000E+00 + Lagrangian kinetic energy G(r): 0.7225412024E-01 + G(r) in X,Y,Z: 0.1525767948E-01 0.3373165197E-01 0.2326478879E-01 + Hamiltonian kinetic energy K(r): 0.6194515984E+00 + Potential energy density V(r): -0.6917057186E+00 + Energy density E(r) or H(r): -0.6194515984E+00 + Laplacian of electron density: -0.2188789912E+01 + Electron localization function (ELF): 0.9804906069E+00 + Localized orbital locator (LOL): 0.8763940244E+00 + Local information entropy: 0.1186300475E+00 + Interaction region indicator (IRI): 0.9246173984E-16 + Reduced density gradient (RDG): 0.1000000000E+03 + Reduced density gradient with promolecular approximation: 0.1000000000E+03 + Sign(lambda2)*rho: -0.3555268313E+00 + Sign(lambda2)*rho with promolecular approximation: -0.2179416158E+00 + Corr. hole for alpha, ref.: 0.00000 0.00000 0.00000 : -0.1521712915E-01 + Source function, ref.: 0.00000 0.00000 0.00000 : 0.1342862893E+00 + Wavefunction value for orbital 1 : -0.8709544497E-03 + Average local ionization energy (ALIE): 0.6306096902E+00 + van der Waals potential (probe atom: C ): 0.7516746618E+14 kcal/mol + Delta-g (under promolecular approximation): 0.5517191603E+00 + Delta-g (under Hirshfeld partition): 0.8206477678E+00 + User-defined real space function: 0.1000000000E+01 + ESP from nuclear charges: 0.8670885241E+01 + ESP from electrons: -0.6660434572E+01 + Total ESP: 0.2010450669E+01 a.u. ( 0.5470714E+02 eV, 0.1261578E+04 kcal/mol) + + Note: Below information are for electron density + + Components of gradient in x/y/z are: + -0.1040834086E-16 0.3081487911E-30 0.2775557562E-16 + Norm of gradient is: 0.2964296775E-16 + + Components of Laplacian in x/y/z are: + 0.1713195623E+00 -0.1802345267E+01 -0.5577642076E+00 + Total: -0.2188789912E+01 + + Hessian matrix: + 0.1713195623E+00 -0.7296900222E-15 -0.1608135921E+01 + -0.7296900222E-15 -0.1802345267E+01 0.5305490406E-15 + -0.1608135921E+01 0.5305490406E-15 -0.5577642076E+00 + Eigenvalues of Hessian: -0.1842158927E+01 -0.1802345267E+01 0.1455714282E+01 + Eigenvectors (columns) of Hessian: + 0.6240685235E+00 0.1686365420E-14 -0.7813696167E+00 + 0.3341919019E-14 -0.1000000000E+01 0.2267511291E-15 + 0.7813696167E+00 0.2752782226E-14 0.6240685235E+00 + Determinant of Hessian: 0.4833271910E+01 + Ellipticity of electron density: 0.022090 + eta index: 1.265467 + + ---------------- CP 5, Type (3,-1) ---------------- + Connected atoms: 1(H ) -- 2(O ) + Position (Bohr): 1.139728273109 0.000000000000 0.619195673290 + Position (Angstrom): 0.603118228751 0.000000000000 0.327664239395 + Density of all electrons: 0.3555268313E+00 + Density of Alpha electrons: 0.1777634156E+00 + Density of Beta electrons: 0.1777634156E+00 + Spin density of electrons: 0.0000000000E+00 + Lagrangian kinetic energy G(r): 0.7225412024E-01 + G(r) in X,Y,Z: 0.1525767948E-01 0.3373165197E-01 0.2326478879E-01 + Hamiltonian kinetic energy K(r): 0.6194515984E+00 + Potential energy density V(r): -0.6917057186E+00 + Energy density E(r) or H(r): -0.6194515984E+00 + Laplacian of electron density: -0.2188789912E+01 + Electron localization function (ELF): 0.9804906069E+00 + Localized orbital locator (LOL): 0.8763940244E+00 + Local information entropy: 0.1186300475E+00 + Interaction region indicator (IRI): 0.1092522371E-14 + Reduced density gradient (RDG): 0.1000000000E+03 + Reduced density gradient with promolecular approximation: 0.1000000000E+03 + Sign(lambda2)*rho: -0.3555268313E+00 + Sign(lambda2)*rho with promolecular approximation: -0.2179416158E+00 + Corr. hole for alpha, ref.: 0.00000 0.00000 0.00000 : -0.1521712915E-01 + Source function, ref.: 0.00000 0.00000 0.00000 : 0.1342862893E+00 + Wavefunction value for orbital 1 : -0.8709544497E-03 + Average local ionization energy (ALIE): 0.6306096902E+00 + van der Waals potential (probe atom: C ): 0.7516746618E+14 kcal/mol + Delta-g (under promolecular approximation): 0.5517191603E+00 + Delta-g (under Hirshfeld partition): 0.8206477678E+00 + User-defined real space function: 0.1000000000E+01 + ESP from nuclear charges: 0.8670885241E+01 + ESP from electrons: -0.6660434572E+01 + Total ESP: 0.2010450669E+01 a.u. ( 0.5470714E+02 eV, 0.1261578E+04 kcal/mol) + + Note: Below information are for electron density + + Components of gradient in x/y/z are: + -0.2914335440E-15 0.1956744823E-30 -0.1942890293E-15 + Norm of gradient is: 0.3502595287E-15 + + Components of Laplacian in x/y/z are: + 0.1713195623E+00 -0.1802345267E+01 -0.5577642076E+00 + Total: -0.2188789912E+01 + + Hessian matrix: + 0.1713195623E+00 0.9434550634E-16 0.1608135921E+01 + 0.9434550634E-16 -0.1802345267E+01 0.1065551374E-16 + 0.1608135921E+01 0.1065551374E-16 -0.5577642076E+00 + Eigenvalues of Hessian: -0.1842158927E+01 -0.1802345267E+01 0.1455714282E+01 + Eigenvectors (columns) of Hessian: + -0.6240685235E+00 0.0000000000E+00 0.7813696167E+00 + 0.0000000000E+00 -0.1000000000E+01 0.0000000000E+00 + 0.7813696167E+00 0.0000000000E+00 0.6240685235E+00 + Determinant of Hessian: 0.4833271910E+01 + Ellipticity of electron density: 0.022090 + eta index: 1.265467 + diff --git a/atomate/qchem/test_files/multiwfn_example/WAVEFUNCTION.wfn.gz b/atomate/qchem/test_files/multiwfn_example/WAVEFUNCTION.wfn.gz new file mode 100644 index 0000000000000000000000000000000000000000..5dd00499674064b048680ce693eca566a199577c GIT binary patch literal 2406 zcmV-s37PgEiwFoIXqjdL|5rg)MMhOlLsUsmPA+$5ZUEI;+fpRS4SnygsK?!KbXoVz zeDDKi@j%1?6TnV*KVbj=7krdiS=}@XV-HVei3!wIrBX`g97(;0FIT@mKi^$FEU$ii zxqtk+JU;#N?&a$1^Z3Y@Z%=pkcQ1F}Z=UCUx;*@T{q^SVuq?M}bN=(o_07Y}(+#X& z^P|-`m?&adXr=8Z|E?NT3gMaS+pDK9H_JcrZi27JbR(~PN&0&I{QmcmR%Nj$Zs)#g z_jNnsJolyWb^PDs+8)0`zP>!%!+73~{K2n$@cWKK`RU*P&Y^zrdwBWd+neX#oCtT? z*&iRB{T+wrVc7hA>)DqD)hQ_Dvb2R!9e>B+#cdx2e7O1dx5tO^D6dLPsP&(JL%n%z zA>u_~(PFEaYiaT4v0oEzhU?v`6EJC=JA8HF!s3++8MXE!>)fHN62T=ZV$wxdql$0| zmMmp08p`TDdRf^Jtqm*I@Y+l@&vFrAE8faDmaOgyw2xyIJX8dyh9!szpR<#7hq~5K zck)YzpoUdy!aZvrJoM3>=MF!5NY)a@Znj1Lu66D()g z^dI63mX+Aa=rkR6Ckb{Uciwrw8q-hl0bGy2WU%8oULa*-)Pm?cvRx3C{rW% zy4wN=L^|-25tEbFQMp4p2uDmPSjTHJR+Xz8j|hE@+C-GM2m=v<6}8%ouzF=CZ)x`& zG7jKn-cZ-{SA*KHp(ErGEy}QEttDD9l5QUhpalrR=g8qP(2F5ak`70b3rf_OV%WYy zm3%NR9muLlkruwc0MSzOI&!$QHKGtA$RyXy3BjX~j);&mGi2E~Q{ug7)q&?)MoPdD zX^IrLEkbmD)rOSS2@B-dS!*82^8xmN`x@QGbtDXQf|e#KQjy$|ftV5I8=$BICj9}C zs_-Y{1qD?Vq2S>FM}|sih_#slA`3;1_M&_W*vlJW`%1`R(^~%$*vCs?*R>j+R`zk^ z3t-=$2DG1{aSm*)5MnO%&G6WoAc!dDR}g z9Fi0zL!}zCV1TR@o(^@5(!e1}gdqPF*}&D-wgLl!4#WZWdHpc*PYl`)$pk6Xin_{X zH`sZC;Aw-#2BK}(@j^sgs6&#+ks-(IrGL;#6M~xS=)6f96ui2}q;-W+ytC9Z1%asm zHOu<=K#YP@RNBC7tjQ=R-XI3vtD@wSwtyfY&&_udHSNNBijai?(d`HcF>el**|eir z6J%j04GAZ%2aO>_0oqufEUY_p4ur&I3JYfs!i+K?i7I+6Y&`{oG*qFSy~?`n5!Ns= zj4I=Zh^L_W`7X}DNo!@pEF1`=6kMGtNC%{yb#>4fjPR2MgJ>@&ee)C9oTG0<9i1;{~w$^^L~* z85(17fRJ)KoUKH4r`=MR)GQx>8XQ-n6B{xa^=}c04B#kQ1N^Ka%1 zB7tVdvr$0kpaiXM4n12FS|@L3%W2!7vUS0cS#O?6V_S=$%d32aCudPUW+zXbN6v44ifm>keL>X6l95PsoJ z^;+6F!|tmsWAiLgY?ocAA||ew5G|I&N*~W+420M(po=kQ4MHo$mPJ!$p-AXtR;NQN z4IbxClB~n&IZisA)xuD{JHX_H391YSsROy^?h|G1c}Upob@_Z?i)v-tntPP=ZUuOqLMV&kf0sg_Fi(R zu7RO&3KLWWDxq^q&j&npW~V8hEf~r6=7xo15-T~$Jse@wapo~?j&K&ug$v<#h4c;2YcR@ZFJj64sgt*=XZ*brjb*O zu-L0H0dt!pZO!j1xr=ul-+-ieGSQ3x4!~^QmuZaD0M4u`ScvB%H0D}RQAIGb?o&FH zR0gZY4UiGqV6i=bgu3i&0JIr7=o3v(QGUIG5kvMV{S~lr1C|U_t!`r{Xj?IIb!D0( z(HXF_J6Od~=N(3en}^?)->zP+4llPi%X0g#Glt^lSW*bFO;*Tjur7Jm_q(UNtFONt YzyJN^*M8gS|3@7D15JPy3!xbR08;>#_5c6? literal 0 HcmV?d00001 diff --git a/atomate/qchem/test_files/multiwfn_example/mol.qin.gz b/atomate/qchem/test_files/multiwfn_example/mol.qin.gz new file mode 100644 index 0000000000000000000000000000000000000000..233dce5fcaba87b8883f64d0fd7c339cb3861561 GIT binary patch literal 265 zcmV+k0rvhMiwFoHXqjdJ|7~w+F`!=*~S)y3nQ3$1jYp~8Nc!^#PM8Ts^(1!A$Ad8u}fXcx{{YH zjDP&y_Dc@pST?8XB+lF5b;o~hEWo#n6%icErO$9vX`O(-bDRin8ZG9mg-#yuKDC5S zKNOlynbnLy)simYya!M2w9l5}41^D(`e@rM6{Ts2fCJ6cl%o8GW`q2$9{Uh&8XPUQ z7Rhtdq|BgWzir%K$JIGVan01}5qDFz_aVZM#@saox&n>%1WVokYU$|KMc<*Dy-7Cs P*N;2_8FEp0(E$JeIGKVs literal 0 HcmV?d00001 diff --git a/atomate/qchem/test_files/multiwfn_example/mol.qin.orig.gz b/atomate/qchem/test_files/multiwfn_example/mol.qin.orig.gz new file mode 100644 index 0000000000000000000000000000000000000000..30d8b1422fa181fdf25bac58620138a030fe4f8e GIT binary patch literal 270 zcmV+p0rCDHiwFoHXqjdJ|7~wLkwF;C07;ZY;pJj1>_a%cak7Q)!)mzjK@jZW=A-tc6Y< z@IJMKPCpcyPMOt=K-H2i;JgP04wW+761SM literal 0 HcmV?d00001 diff --git a/atomate/qchem/test_files/multiwfn_example/mol.qout.gz b/atomate/qchem/test_files/multiwfn_example/mol.qout.gz new file mode 100644 index 0000000000000000000000000000000000000000..5aee097b78dc1f13dc5c545152d881fb82e3953d GIT binary patch literal 5272 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 literal 0 HcmV?d00001 From 5347f887180545aed290cb835df086483e8934a7 Mon Sep 17 00:00:00 2001 From: "Evan Walter Clark Spotte-Smith, PhD" Date: Thu, 18 Jul 2024 15:42:18 -0400 Subject: [PATCH 10/11] Bugfix --- atomate/qchem/firetasks/tests/test_multiwfn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atomate/qchem/firetasks/tests/test_multiwfn.py b/atomate/qchem/firetasks/tests/test_multiwfn.py index 54c46985d..908faa453 100644 --- a/atomate/qchem/firetasks/tests/test_multiwfn.py +++ b/atomate/qchem/firetasks/tests/test_multiwfn.py @@ -63,7 +63,7 @@ def test_run(self): this_output = process_multiwfn_qtaim( self.mol, - "Cpprop.txt" + "CPprop.txt" ) for root in ["atom", "bond", "ring", "cage"]: From 95112d30a0b74dffc0a5019af0ad3e98660629cd Mon Sep 17 00:00:00 2001 From: "Evan Walter Clark Spotte-Smith, PhD" Date: Thu, 18 Jul 2024 15:44:00 -0400 Subject: [PATCH 11/11] Tests now pass --- atomate/qchem/fireworks/tests/test_core.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/atomate/qchem/fireworks/tests/test_core.py b/atomate/qchem/fireworks/tests/test_core.py index a6e7970fa..a78ed035d 100644 --- a/atomate/qchem/fireworks/tests/test_core.py +++ b/atomate/qchem/fireworks/tests/test_core.py @@ -956,7 +956,6 @@ def test_WfnAndQTAIMFW_defaults(self): molecule=self.act_mol, multiwfn_command=">>multiwfn_command<<", wfn_file="WAVEFUNCTION.wfn", - output_file="qtaim.out" ).as_dict(), ) self.assertEqual( @@ -1009,7 +1008,6 @@ def test_WfnAndQTAIMFW_not_defaults(self): molecule=self.act_mol, multiwfn_command=">>multiwfn_command<<", wfn_file="WAVEFUNCTION.wfn", - output_file="qtaim.out" ).as_dict(), ) self.assertEqual(