def test_RunQChemCustodian_using_fw_spec_defaults(self): with patch("atomate.qchem.firetasks.run_calc.Custodian" ) as custodian_patch: firetask = RunQChemCustodian(qchem_cmd=">>qchem_cmd<<", scratch_dir=">>scratch_dir<<", input_file=os.path.join( module_dir, "..", "..", "test_files", "co_qc.in")) firetask.run_task( fw_spec={ "_fw_env": { "qchem_cmd": "qchem -slurm", "scratch_dir": "/this/is/a/test" } }) custodian_patch.assert_called_once() self.assertEqual( custodian_patch.call_args[0][0][0].as_dict(), QChemErrorHandler(input_file=os.path.join( module_dir, "..", "..", "test_files", "co_qc.in"), output_file="mol.qout").as_dict()) self.assertEqual( custodian_patch.call_args[0][1][0].as_dict(), QCJob(qchem_command="qchem -slurm", multimode="openmp", input_file=os.path.join(module_dir, "..", "..", "test_files", "co_qc.in"), output_file="mol.qout", scratch_dir="/this/is/a/test").as_dict()) self.assertEqual(custodian_patch.call_args[1], { "max_errors": 5, "gzipped_output": True })
def test_RunQChemCustodian_basic_defaults(self): with patch("atomate.qchem.firetasks.run_calc.Custodian" ) as custodian_patch: firetask = RunQChemCustodian( qchem_cmd="qchem", input_file=os.path.join(module_dir, "..", "..", "test_files", "co_qc.in"), max_cores=32) firetask.run_task(fw_spec={}) custodian_patch.assert_called_once() self.assertEqual(custodian_patch.call_args[0][0][0].as_dict(), QChemErrorHandler( input_file=os.path.join( module_dir, "..", "..", "test_files", "co_qc.in"), output_file="mol.qout").as_dict()) self.assertEqual(custodian_patch.call_args[0][1][0].as_dict(), QCJob( qchem_command="qchem", max_cores=32, multimode="openmp", input_file=os.path.join( module_dir, "..", "..", "test_files", "co_qc.in"), output_file="mol.qout").as_dict()) self.assertEqual(custodian_patch.call_args[1], { "max_errors": 5, "gzipped_output": True })
def test_RunQChemCustodian_FF_basic_defaults(self): with patch("atomate.qchem.firetasks.run_calc.Custodian" ) as custodian_patch: with patch( "atomate.qchem.firetasks.run_calc.QCJob.opt_with_frequency_flattener" ) as FF_patch: firetask = RunQChemCustodian( qchem_cmd="qchem", max_cores=32, input_file=os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qin"), output_file=os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qout"), job_type="opt_with_frequency_flattener", ) firetask.run_task(fw_spec={}) custodian_patch.assert_called_once() self.assertEqual( custodian_patch.call_args[0][0][0].as_dict(), QChemErrorHandler( input_file=os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qin"), output_file=os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qout")).as_dict()) self.assertEqual(custodian_patch.call_args[1], { "max_errors": 5, "gzipped_output": True }) self.assertEqual( FF_patch.call_args[1], { "qchem_command": "qchem", "multimode": "openmp", "input_file": os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qin"), "output_file": os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qout"), "qclog_file": "mol.qclog", "max_iterations": 10, "max_molecule_perturb_scale": 0.3, "scratch_dir": "/dev/shm/qcscratch/", "save_scratch": False, "save_name": "default_save_name", "max_cores": 32 })
def test_RunQChemCustodian_using_fw_spec_not_defaults(self): with patch("atomate.qchem.firetasks.run_calc.Custodian" ) as custodian_patch: firetask = RunQChemCustodian( qchem_cmd=">>qchem_cmd<<", calc_loc=">>calc_loc<<", multimode=">>multimode<<", input_file=os.path.join(module_dir, "..", "..", "test_files", "co_qc.in"), output_file="this_is_a_test.qout", max_cores=4, qclog_file="this_is_a_test.qclog", suffix="bad_idea", save_scratch=True, max_errors=137, gzipped_output=False, handler_group="no_handler", ) firetask.run_task( fw_spec={ "_fw_env": { "qchem_cmd": "qchem -slurm", "calc_loc": "/this/is/a/test", "max_cores": 32, "multimode": "mpi", } }) custodian_patch.assert_called_once() self.assertEqual(custodian_patch.call_args[0][0], []) self.assertEqual( custodian_patch.call_args[0][1][0].as_dict(), QCJob( qchem_command="qchem -slurm", calc_loc="/this/is/a/test", multimode="mpi", input_file=os.path.join(module_dir, "..", "..", "test_files", "co_qc.in"), output_file="this_is_a_test.qout", max_cores=4, qclog_file="this_is_a_test.qclog", suffix="bad_idea", save_scratch=True, ).as_dict(), ) self.assertEqual( custodian_patch.call_args[1], { "max_errors": 137, "gzipped_output": False }, )
def test_SinglePointFW_not_defaults(self): firework = SinglePointFW(molecule=self.act_mol, name="special single point", qchem_cmd="qchem -slurm", multimode="mpi", max_cores=12, qchem_input_params={"pcm_dielectric": 10.0}, db_file=os.path.join(db_dir, "db.json"), 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 }).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, job_type="normal").as_dict()) self.assertEqual( firework.tasks[2].as_dict(), QChemToDb(db_file=os.path.join(db_dir, "db.json"), input_file="mol.qin", output_file="mol.qout", additional_fields={ "task_label": "special single point" }).as_dict()) self.assertEqual(firework.parents, []) self.assertEqual(firework.name, "special single point")
def test_SinglePointFW_defaults(self): firework = SinglePointFW(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={}).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<<", job_type="normal").as_dict()) self.assertEqual( firework.tasks[2].as_dict(), QChemToDb(db_file=None, input_file="mol.qin", output_file="mol.qout", additional_fields={ "task_label": "single point" }).as_dict()) self.assertEqual(firework.parents, []) self.assertEqual(firework.name, "single point")
def test_FrequencyFlatteningOptimizeFW_defaults(self): firework = FrequencyFlatteningOptimizeFW(molecule=self.act_mol) self.assertEqual( firework.tasks[0].as_dict(), WriteInputFromIOSet(molecule=self.act_mol, qchem_input_set="OptSet", input_file="mol.qin", qchem_input_params={}).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<<", job_type="opt_with_frequency_flattener", max_iterations=10, max_molecule_perturb_scale=0.3, reversed_direction=False).as_dict()) self.assertEqual( firework.tasks[2].as_dict(), QChemToDb(db_file=None, input_file="mol.qin", output_file="mol.qout", additional_fields={ "task_label": "frequency flattening structure optimization", "special_run_type": "frequency_flattener" }).as_dict()) self.assertEqual(firework.parents, []) self.assertEqual(firework.name, "frequency flattening structure optimization")
def test_CubeAndCritic2FW_defaults(self): firework = CubeAndCritic2FW(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={ "plot_cubes": 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<<", job_type="normal").as_dict()) self.assertEqual( firework.tasks[2].as_dict(), RunCritic2(molecule=self.act_mol, cube_file="dens.0.cube.gz").as_dict()) self.assertEqual(firework.tasks[3].as_dict(), ProcessCritic2(molecule=self.act_mol).as_dict()) self.assertEqual( firework.tasks[4].as_dict(), QChemToDb(db_file=None, input_file="mol.qin", output_file="mol.qout", additional_fields={ "task_label": "cube and critic2" }).as_dict()) self.assertEqual(firework.parents, []) self.assertEqual(firework.name, "cube and critic2")
def test_OptimizeFW_defaults(self): firework = OptimizeFW(molecule=self.act_mol) self.assertEqual( firework.tasks[0].as_dict(), WriteInputFromIOSet(molecule=self.act_mol, qchem_input_set="OptSet", input_file="mol.qin", qchem_input_params={}).as_dict()) self.assertEqual( firework.tasks[1].as_dict(), RunQChemCustodian(qchem_cmd="qchem", multimode="openmp", input_file="mol.qin", output_file="mol.qout", max_cores=32, job_type="normal").as_dict()) self.assertEqual( firework.tasks[2].as_dict(), QChemToDb(db_file=None, input_file="mol.qin", output_file="mol.qout", additional_fields={ "task_label": "structure optimization" }).as_dict()) self.assertEqual(firework.parents, []) self.assertEqual(firework.name, "structure optimization")
def test_FrequencyFlatteningOptimizeFW_not_defaults(self): firework = FrequencyFlatteningOptimizeFW( molecule=self.act_mol, name="special frequency flattening structure optimization", qchem_cmd="qchem -slurm", multimode="mpi", max_cores=12, qchem_input_params={"pcm_dielectric": 10.0}, max_iterations=5, max_molecule_perturb_scale=0.2, linked=True, db_file=os.path.join(db_dir, "db.json"), parents=None, ) self.assertEqual( firework.tasks[0].as_dict(), WriteInputFromIOSet( molecule=self.act_mol, qchem_input_set="OptSet", input_file="mol.qin", qchem_input_params={ "pcm_dielectric": 10.0 }, ).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, job_type="opt_with_frequency_flattener", max_iterations=5, max_molecule_perturb_scale=0.2, linked=True, ).as_dict(), ) self.assertEqual( firework.tasks[2].as_dict(), QChemToDb( db_file=os.path.join(db_dir, "db.json"), input_file="mol.qin", output_file="mol.qout", additional_fields={ "task_label": "special frequency flattening structure optimization", "special_run_type": "frequency_flattener", "linked": True, }, ).as_dict(), ) self.assertEqual(firework.parents, []) self.assertEqual( firework.name, "special frequency flattening structure optimization")
def test_CubeAndCritic2FW_not_defaults(self): firework = CubeAndCritic2FW( molecule=self.act_mol, name="special cube and critic2", qchem_cmd="qchem -slurm", multimode="mpi", max_cores=12, qchem_input_params={"pcm_dielectric": 10.0}, db_file=os.path.join(db_dir, "db.json"), 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, "plot_cubes": 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, job_type="normal", ).as_dict(), ) self.assertEqual( firework.tasks[2].as_dict(), RunCritic2(molecule=self.act_mol, cube_file="dens.0.cube.gz").as_dict(), ) self.assertEqual(firework.tasks[3].as_dict(), ProcessCritic2(molecule=self.act_mol).as_dict()) self.assertEqual( firework.tasks[4].as_dict(), QChemToDb( db_file=os.path.join(db_dir, "db.json"), input_file="mol.qin", output_file="mol.qout", additional_fields={ "task_label": "special cube and critic2" }, ).as_dict(), ) self.assertEqual(firework.parents, []) self.assertEqual(firework.name, "special cube and critic2")
def test_RunQChemCustodian_FF_using_fw_spec_not_defaults(self): with patch("atomate.qchem.firetasks.run_calc.Custodian" ) as custodian_patch: with patch( "atomate.qchem.firetasks.run_calc.QCJob.opt_with_frequency_flattener" ) as FF_patch: firetask = RunQChemCustodian( qchem_cmd=">>qchem_cmd<<", calc_loc=">>calc_loc<<", input_file=os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qin"), output_file=os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qout"), job_type="opt_with_frequency_flattener", max_cores=4, qclog_file="this_is_a_test.qclog", suffix="bad_idea", save_scratch=True, max_errors=137, gzipped_output=False, handler_group="no_handler", linked=False, max_iterations=1029, max_molecule_perturb_scale=0.5, multimode=">>multimode<<") firetask.run_task( fw_spec={ "_fw_env": { "qchem_cmd": "qchem -slurm", "calc_loc": "/this/is/a/test", "max_cores": 32, "multimode": "mpi" } }) custodian_patch.assert_called_once() self.assertEqual(custodian_patch.call_args[0][0], []) self.assertEqual(custodian_patch.call_args[1], { "max_errors": 137, "gzipped_output": False }) self.assertEqual( FF_patch.call_args[1], { "qchem_command": "qchem -slurm", "multimode": "mpi", "input_file": os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qin"), "output_file": os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qout"), "qclog_file": "this_is_a_test.qclog", "max_iterations": 1029, "max_molecule_perturb_scale": 0.5, "linked": False, "calc_loc": "/this/is/a/test", "save_final_scratch": True, "max_cores": 4 })
def test_RunQChemCustodian_FF_using_fw_spec_defaults(self): with patch("atomate.qchem.firetasks.run_calc.Custodian" ) as custodian_patch: with patch( "atomate.qchem.firetasks.run_calc.QCJob.opt_with_frequency_flattener" ) as FF_patch: firetask = RunQChemCustodian( qchem_cmd=">>qchem_cmd<<", calc_loc=">>calc_loc<<", max_cores=">>max_cores<<", multimode=">>multimode<<", input_file=os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qin"), output_file=os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qout"), job_type="opt_with_frequency_flattener") firetask.run_task( fw_spec={ "_fw_env": { "qchem_cmd": "qchem -slurm", "calc_loc": "/this/is/a/test", "max_cores": 32, "multimode": "openmp" } }) custodian_patch.assert_called_once() self.assertEqual(custodian_patch.call_args[0][0][0].as_dict(), QChemErrorHandler( input_file=os.path.join( module_dir, "..", "..", "test_files", "FF_before_run", "test.qin"), output_file=os.path.join( module_dir, "..", "..", "test_files", "FF_before_run", "test.qout")).as_dict()) self.assertEqual(custodian_patch.call_args[1], { "max_errors": 5, "gzipped_output": True }) self.assertEqual( FF_patch.call_args[1], { "qchem_command": "qchem -slurm", "multimode": "openmp", "input_file": os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qin"), "output_file": os.path.join(module_dir, "..", "..", "test_files", "FF_before_run", "test.qout"), "qclog_file": "mol.qclog", "max_iterations": 10, "linked": True, "calc_loc": "/this/is/a/test", "save_final_scratch": False, "max_cores": 32 })
def __init__(self, molecule=None, name="structure optimization", qchem_cmd=">>qchem_cmd<<", multimode=">>multimode<<", max_cores=">>max_cores<<", qchem_input_params=None, db_file=None, parents=None, **kwargs): """ Optimize the given structure. 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. Defaults to openmp. max_cores (int): Maximum number of cores to parallelize over. 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 conjuction 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 = qchem_input_params or {} input_file = "mol.qin" output_file = "mol.qout" t = [] t.append( WriteInputFromIOSet(molecule=molecule, qchem_input_set="OptSet", 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="normal")) t.append( QChemToDb(db_file=db_file, input_file=input_file, output_file=output_file, additional_fields={"task_label": name})) super(OptimizeFW, self).__init__(t, parents=parents, name=name, **kwargs)
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)