Пример #1
0
 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")
Пример #2
0
def get_wf_FFopt_and_critic(molecule,
                            suffix,
                            qchem_input_params=None,
                            db_file=">>db_file<<",
                            **kwargs):
    """
    """

    # FFopt
    fw1 = FrequencyFlatteningOptimizeFW(
        molecule=molecule,
        name="{}:{}".format(molecule.composition.alphabetical_formula,
                            "FFopt_" + suffix),
        qchem_cmd=">>qchem_cmd<<",
        max_cores=">>max_cores<<",
        qchem_input_params=qchem_input_params,
        linked=True,
        db_file=">>db_file<<")

    # Critic
    fw2 = CubeAndCritic2FW(name="{}:{}".format(
        molecule.composition.alphabetical_formula, "CC2_" + suffix),
                           qchem_cmd=">>qchem_cmd<<",
                           max_cores=">>max_cores<<",
                           qchem_input_params=qchem_input_params,
                           db_file=">>db_file<<",
                           parents=fw1)
    fws = [fw1, fw2]

    wfname = "{}:{}".format(molecule.composition.alphabetical_formula,
                            "FFopt_CC2_WF_" + suffix)

    return Workflow(fws, name=wfname, **kwargs)
Пример #3
0
 def _build_new_FWs(self):
     """
     Build the list of new fireworks: a FrequencyFlatteningOptimizeFW for each unique fragment
     molecule, unless the fragment is a single atom, in which case add a SinglePointFW instead.
     If the fragment is already in the database, don't add any new firework.
     """
     from atomate.qchem.fireworks.core import FrequencyFlatteningOptimizeFW
     from atomate.qchem.fireworks.core import SinglePointFW
     new_FWs = []
     for ii, unique_molecule in enumerate(self.unique_molecules):
         if not self._in_database(unique_molecule):
             if len(unique_molecule) == 1:
                 new_FWs.append(
                     SinglePointFW(
                         molecule=unique_molecule,
                         name="fragment_" + str(ii),
                         qchem_cmd=">>qchem_cmd<<",
                         max_cores=">>max_cores<<",
                         qchem_input_params=self.qchem_input_params,
                         db_file=">>db_file<<"))
             else:
                 new_FWs.append(
                     FrequencyFlatteningOptimizeFW(
                         molecule=unique_molecule,
                         name="fragment_" + str(ii),
                         qchem_cmd=">>qchem_cmd<<",
                         max_cores=">>max_cores<<",
                         qchem_input_params=self.qchem_input_params,
                         linked=self.linked,
                         db_file=">>db_file<<"))
     return new_FWs
Пример #4
0
 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")
Пример #5
0
def get_wf_double_FF_opt(molecule,
                         pcm_dielectric,
                         max_cores=32,
                         qchem_input_params=None,
                         name="douple_FF_opt",
                         qchem_cmd=">>qchem_cmd<<",
                         db_file=">>db_file<<",
                         **kwargs):
    """
    Returns a workflow to the torsion potential for a molecule.

    Firework 1 : write QChem input for an FF optimization,
                 run FF_opt QCJob,
                 parse directory and insert into db,
                 pass relaxed molecule to fw_spec and on to fw2,

    Firework 2 : write QChem input for an optimization in the
                    presence of a PCM, using the molecule passed
                    from fw1,
                 run FF_opt QCJob,
                 parse directory and insert into db

    Args:
        molecule (Molecule): input molecule to be optimized and run.
        pcm_dielectric (float): The PCM dielectric constant.
        max_cores (int): Maximum number of cores to parallelize over.
            Defaults to 32.
        qchem_input_params (dict): Specify kwargs for instantiating
            the input set parameters.
        qchem_cmd (str): Command to run QChem.
        db_file (str): path to file containing the database credentials.
        kwargs (keyword arguments): additional kwargs to be passed to Workflow

    Returns:
        Workflow
    """

    first_qchem_input_params = qchem_input_params or {}

    # Optimize the molecule in vacuum
    fw1 = FrequencyFlatteningOptimizeFW(
        molecule=molecule,
        name="first_FF_no_pcm",
        qchem_cmd=qchem_cmd,
        max_cores=max_cores,
        qchem_input_params=first_qchem_input_params,
        db_file=db_file)

    # Optimize the molecule in PCM
    second_qchem_input_params = {"pcm_dielectric": pcm_dielectric}
    for key in first_qchem_input_params:
        second_qchem_input_params[key] = first_qchem_input_params[key]
    fw2 = FrequencyFlatteningOptimizeFW(
        name="second_FF_with_pcm",
        qchem_cmd=qchem_cmd,
        max_cores=max_cores,
        qchem_input_params=second_qchem_input_params,
        db_file=db_file,
        parents=fw1)
    fws = [fw1, fw2]

    wfname = "{}:{}".format(molecule.composition.reduced_formula, name)

    return Workflow(fws, name=wfname, **kwargs)
Пример #6
0
def get_fragmentation_wf(molecule,
                         depth=1,
                         open_rings=True,
                         additional_charges=None,
                         do_triplets=True,
                         pcm_dielectric=None,
                         do_optimization=True,
                         linked=False,
                         qchem_input_params=None,
                         name="FF then fragment",
                         db_file=">>db_file<<",
                         check_db=True,
                         **kwargs):
    """

    Args:
        molecule (Molecule): input molecule to be fragmented.
        depth (int): The number of levels of iterative fragmentation to perform,
                     where each evel will include fragments obtained by breaking
                     one bond of a fragment one level up. If set to 0, instead
                     all possible fragments are generated using an alternative,
                     non-iterative scheme. Defaults to 1.
        open_rings (bool): Whether or not to open any rings encountered during fragmentation.
                           Defaults to True. If true, any bond that fails to yield disconnected
                           graphs when broken is instead removed and the entire structure is
                           optimized with OpenBabel in order to obtain a good initial guess for
                           an opened geometry that can then be put back into QChem to be
                           optimized without the ring just reforming.
        additional_charges (list): List of additional charges besides the defaults described in the
                                   firetask. For example, if a principle molecule with a +2 charge
                                   is provided, by default all fragments will be calculated with
                                   +1 and +2 charges. If the user includes additional_charges=[0]
                                   then all fragments will be calculated with 0, +1, and +2 charges.
                                   Additional charge values of 1 or 2 would not cause any new charges
                                   to be calculated as they are already done. Defaults to [].
        do_triplets (bool): Whether to simulate triplets as well as singlets for molecules with
                            an even number of electrons. Defaults to True.
        pcm_dielectric (float): The PCM dielectric constant.
        do_optimization (bool): Whether or not to optimize the given molecule
                                before fragmentation. Defaults to True.
        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 containing the database credentials.
        check_db (bool): Whether or not to check the database for equivalent
                         structures before adding new fragment fireworks.
                         Defaults to True.
        kwargs (keyword arguments): additional kwargs to be passed to Workflow

    Returns:
        Workflow with the following fireworks:

        Firework 1 : write QChem input for an FF optimization,
                     run FF_opt QCJob,
                     parse directory and insert into db,
                     pass relaxed molecule to fw_spec and on to fw2,

        Firework 2 : find all unique fragments of the optimized molecule
                     and add a frequency flattening optimize FW to the
                     workflow for each one

        Note that Firework 1 is only present if do_optimization=True.

    """

    qchem_input_params = qchem_input_params or {}
    additional_charges = additional_charges or []
    if pcm_dielectric != None:
        qchem_input_params["pcm_dielectric"] = pcm_dielectric

    if do_optimization:
        # Optimize the original molecule
        fw1 = FrequencyFlatteningOptimizeFW(
            molecule=molecule,
            name="first FF",
            qchem_cmd=">>qchem_cmd<<",
            max_cores=">>max_cores<<",
            qchem_input_params=qchem_input_params,
            linked=linked,
            db_file=db_file)

        # Fragment the optimized molecule
        fw2 = FragmentFW(depth=depth,
                         open_rings=open_rings,
                         additional_charges=additional_charges,
                         do_triplets=do_triplets,
                         linked=linked,
                         name="fragment and FF_opt",
                         qchem_input_params=qchem_input_params,
                         db_file=db_file,
                         check_db=check_db,
                         parents=fw1)
        fws = [fw1, fw2]

    else:
        # Fragment the given molecule
        fw1 = FragmentFW(molecule=molecule,
                         depth=depth,
                         open_rings=open_rings,
                         additional_charges=additional_charges,
                         do_triplets=do_triplets,
                         linked=linked,
                         name="fragment and FF_opt",
                         qchem_input_params=qchem_input_params,
                         db_file=db_file,
                         check_db=check_db)
        fws = [fw1]

    wfname = "{}:{}".format(molecule.composition.reduced_formula, name)

    return Workflow(fws, name=wfname, **kwargs)
Пример #7
0
def get_wf_FFopt_and_critic(molecule,
                            suffix,
                            qchem_input_params=None,
                            db_file=">>db_file<<",
                            **kwargs):
    """

    Firework 1 : write QChem input for an FF optimization,
                 run FF_opt QCJob,
                 parse directory and insert into db,
                 pass relaxed molecule to fw_spec and on to fw2,

    Firework 2 : write QChem input for a single point calc to print a cube file
                 run SP QCJob, thereby printing a cube file
                 run Critic2 on the printed cube file
                 parse directory and insert into db

    Args:
        molecule (Molecule): input molecule to be optimized and run.
        suffix (str): Workflow naming suffix
        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 containing the database credentials.
        kwargs (keyword arguments): additional kwargs to be passed to Workflow

    Returns:
        Workflow
    """

    qchem_input_params = qchem_input_params or {}

    # FFopt
    fw1 = FrequencyFlatteningOptimizeFW(
        molecule=molecule,
        name="{}:{}".format(molecule.composition.alphabetical_formula,
                            "FFopt_" + suffix),
        qchem_cmd=">>qchem_cmd<<",
        max_cores=">>max_cores<<",
        qchem_input_params=qchem_input_params,
        linked=True,
        db_file=">>db_file<<",
    )

    # Critic
    fw2 = CubeAndCritic2FW(
        name="{}:{}".format(molecule.composition.alphabetical_formula,
                            "CC2_" + suffix),
        qchem_cmd=">>qchem_cmd<<",
        max_cores=">>max_cores<<",
        qchem_input_params=qchem_input_params,
        db_file=">>db_file<<",
        parents=fw1,
    )
    fws = [fw1, fw2]

    wfname = "{}:{}".format(molecule.composition.alphabetical_formula,
                            "FFopt_CC2_WF_" + suffix)

    return Workflow(fws, name=wfname, **kwargs)
Пример #8
0
def get_wf_double_FF_opt(molecule,
                         pcm_dielectric,
                         max_cores=">>max_cores<<",
                         qchem_input_params=None,
                         name="douple_FF_opt",
                         qchem_cmd=">>qchem_cmd<<",
                         db_file=">>db_file<<",
                         **kwargs):
    """

    Firework 1 : write QChem input for an FF optimization,
                 run FF_opt QCJob,
                 parse directory and insert into db,
                 pass relaxed molecule to fw_spec and on to fw2,

    Firework 2 : write QChem input for an optimization in the
                    presence of a PCM, using the molecule passed
                    from fw1,
                 run FF_opt QCJob,
                 parse directory and insert into db

    Args:
        molecule (Molecule): input molecule to be optimized and run.
        pcm_dielectric (float): The PCM dielectric constant.
        max_cores (int): Maximum number of cores to parallelize over.
            Defaults to 32.
        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.
        qchem_cmd (str): Command to run QChem.
        db_file (str): path to file containing the database credentials.
        kwargs (keyword arguments): additional kwargs to be passed to Workflow

    Returns:
        Workflow
    """

    first_qchem_input_params = qchem_input_params or {}

    # Optimize the molecule in vacuum
    fw1 = FrequencyFlatteningOptimizeFW(
        molecule=molecule,
        name="first_FF_no_pcm",
        qchem_cmd=qchem_cmd,
        max_cores=max_cores,
        qchem_input_params=first_qchem_input_params,
        db_file=db_file)

    # Optimize the molecule in PCM
    second_qchem_input_params = {"pcm_dielectric": pcm_dielectric}
    for key in first_qchem_input_params:
        second_qchem_input_params[key] = first_qchem_input_params[key]
    fw2 = FrequencyFlatteningOptimizeFW(
        name="second_FF_with_pcm",
        qchem_cmd=qchem_cmd,
        max_cores=max_cores,
        qchem_input_params=second_qchem_input_params,
        db_file=db_file,
        parents=fw1)
    fws = [fw1, fw2]

    wfname = "{}:{}".format(molecule.composition.reduced_formula, name)

    return Workflow(fws, name=wfname, **kwargs)