Beispiel #1
0
def optimize_qcengine(opt_input, computer_type="qc"):
    """Try to optimize, find TS, or find IRC of the system as specifed by a QCSchema
    OptimizationInput.

        Parameters
        ----------
        opt_input: Union[OptimizationInput, dict]
            Pydantic Schema of the OptimizationInput model.
            see https://github.com/MolSSI/QCElemental/blob/master/qcelemental/models/procedures.py
        computer_type: str

        Returns
        -------
        dict
    """
    logger = logging.getLogger(__name__)

    if isinstance(opt_input, OptimizationInput):
        opt_input = json.loads(json_dumps(
            opt_input))  # Remove numpy elements turn into dictionary
    opt_output = copy.deepcopy(opt_input)

    # Make basic optking molecular system
    oMolsys = molsys.Molsys.from_schema(opt_input["initial_molecule"])
    try:
        initialize_options(opt_input["keywords"])
        computer = make_computer(opt_input, computer_type)
        opt_output = optimize(oMolsys, computer)
    except (OptError, KeyError, ValueError, AttributeError) as error:
        opt_output = {
            "success": False,
            "error": {
                "error_type": error.err_type,
                "error_message": error.mesg
            },
        }
        logger.critical(f"Error placed in qcschema: {opt_output}")
    except Exception as error:
        logger.critical(
            "An unknown error has occured and evaded all error checking")
        opt_output = {
            "success": False,
            "error": {
                "error_type": error,
                "error_message": str(error)
            },
        }
        logger.critical(f"Error placed in qcschema: {opt_output}")
    finally:
        opt_input.update(opt_output)
        opt_input.update({"provenance": optking._optking_provenance_stamp})
        opt_input["provenance"]["routine"] = "optimize_qcengine"
        return opt_input
def test_optimization_input():

    opt_input_dict = {
        "schema_name": "qcschema_optimization_input",
        "schema_version": 1,
        "keywords": {
            "program": "psi4"
        },
        "initial_molecule": {
            "geometry": [
                0.90, 0.80, 0.5, 0.00, 0.70, 0.0, 0.00, -0.70, 0.0, -0.90,
                -0.80, 0.5
            ],
            "symbols": ["H", "O", "O", "H"],
        },
        "input_specification": {
            "schema_name": "qcschema_input",
            "schema_version": 1,
            "driver": "gradient",
            "model": {
                "method": "HF",
                "basis": "sto-3g"
            },
            "keywords": {
                "soscf": True
            },
        },
    }

    # Create Pydantic Model Fills all fields (including non-required)
    opt_in = OptimizationInput(**opt_input_dict)

    # Convert back to plain python dictionary
    full_model = json.loads(json_dumps(opt_in))

    oMolsys = Molsys.from_schema(
        full_model["initial_molecule"])  # Create Optking's molecular system
    initialize_options(full_model["keywords"])
    computer = make_computer(full_model, "qc")
    # Takes the o_json object and creates QCSchema formatted python dict. Has numpy elements
    opt_output = prepare_opt_output(oMolsys, computer)

    assert "success" in opt_output

    psi_computer = make_computer(full_model, "psi4")
    opt_output = prepare_opt_output(oMolsys, computer)
Beispiel #3
0
  def molsys_to_qc_molecule(self) -> qcel.models.Molecule:
      """
          Creates a qcschema molecule. version 1
 
      """
      #print("molsys_to_qc_molecule: input molsys:") 
      #print(self)
      geom = [i for i in self.geom.flat]
      qc_mol = {"symbols": self.atom_symbols,
                "geometry": geom,
                "masses": self.masses.tolist(),
                "molecular_multiplicity": self.multiplicity,
                "fragments":self.fragments_atom_list,
               #"molecular_charge": self.charge, Should be unnecessary
                "fix_com": True,
                "fix_orientation": True}
      qc_mol = Molecule(**qc_mol)
      qc_mol = json.loads(json_dumps(qc_mol))
      return qc_mol
Beispiel #4
0
    def compute(self, geom, driver, return_full=True, print_result=False):
        """Perform calculation of type driver

        Parameters
        ----------
        geom: np.ndarray
        driver: str
        return_full: boolean
        print_result: boolean

        Returns
        -------
        dict
        """

        logger = logging.getLogger(__name__)

        self.update_geometry(geom)
        ret = self._compute(driver)
        # Decodes the Result Schema to remove numpy elements (Makes ret JSON serializable)
        ret = json.loads(json_dumps(ret))
        self.trajectory.append(ret)

        if print_result:
            logger.debug(json.dumps(ret, indent=2))

        if ret["success"]:
            self.energies.append(ret["properties"]["return_energy"])
        else:
            raise OptError(
                f"Error encountered for {driver} calc. {ret['error']['error_message']}",
                ret["error"]["error_type"],
            )

        if return_full:
            return ret
        else:
            return ret["return_result"]
Beispiel #5
0
def initialize_from_psi4(calc_name,
                         program,
                         computer_type,
                         dertype=None,
                         **xtra_opt_params):
    """Gathers information from an active psi4 instance. to cleanly run optking from a
    psithon or psi4api input file

    Parameters
    ----------
    calc_name: str
    computer_type: str
    dertype: Union[int, None]
    program: str
    **xtra_opt_params
        extra keywords which are not recognized by psi4

    Returns
    -------
    params: op.OptParams
    o_molsys: molsys.Molsys
    computer: ComputeWrapper
    opt_input: qcelemental.models.OptimizationInput

    """
    import psi4

    logger = logging.getLogger(__name__)
    mol = psi4.core.get_active_molecule()
    o_molsys, qc_mol = molsys.Molsys.from_psi4(mol)

    # Get optking options and globals from psi4
    # Look through optking module specific options first. If a global has already appeared
    # in optking's options, don't include as a qc package option
    logger.debug("Getting module and psi4 options for qcschema construction")
    module_options = psi4.driver.p4util.prepare_options_for_modules()
    all_options = psi4.core.get_global_option_list()
    opt_keys = {"program": program}

    qc_keys = {}
    if dertype is not None:
        qc_keys["dertype"] = 0

    optking_options = module_options["OPTKING"]
    for opt, optval in optking_options.items():
        if optval["has_changed"]:
            opt_keys[opt.lower()] = optval["value"]

    if xtra_opt_params:
        for xtra_key, xtra_value in xtra_opt_params.items():
            opt_keys[xtra_key.lower()] = xtra_value

    for option in all_options:
        if psi4.core.has_global_option_changed(option):
            if option not in opt_keys:
                qc_keys[option.lower()] = psi4.core.get_global_option(option)

    # Make a qcSchema OptimizationInput
    opt_input = {
        "keywords": opt_keys,
        "initial_molecule": qc_mol,
        "input_specification": {
            "model": {
                "basis": qc_keys.pop("basis"),
                "method": calc_name
            },
            "driver": "gradient",
            "keywords": qc_keys,
        },
    }
    logger.debug("Creating OptimizationInput")

    opt_input = OptimizationInput(**opt_input)
    # Remove numpy elements to allow at will json serialization
    opt_input = json.loads(json_dumps(opt_input))

    initialize_options(opt_keys)
    params = op.Params
    computer = make_computer(opt_input, computer_type)
    return params, o_molsys, computer, opt_input
Beispiel #6
0
def optimize_psi4(calc_name, program='psi4', dertype=None):
    """
    Wrapper for optimize.optimize() Looks for an active psi4 molecule and optimizes.
    This is the written warning that Optking will try to use psi4 if no program is provided
    Parameters
    ----------
    calc_name: str
        level of theory for optimization. eg MP2
    program: str
        program used for gradients, hessians...

    Returns
    -------
    opt_output: dict
        dictionary serialized MOLSSI OptimizationResult.
        see https://github.com/MolSSI/QCElemental/blob/master/qcelemental/models/procedures.py
    """

    import psi4

    logger = logging.getLogger(__name__)
    mol = psi4.core.get_active_molecule()
    oMolsys = molsys.Molsys.from_psi4_molecule(mol)

    # Get optking options and globals from psi4
    # Look through optking module specific options first. If a global has already appeared
    # in optking's options, don't include as a qc package option

    logger.debug("Getting module and psi4 options for qcschema construction")
    module_options = psi4.driver.p4util.prepare_options_for_modules()
    all_options = psi4.core.get_global_option_list()
    opt_keys = {'program': program}
    qc_keys = {}
    if dertype is not None:
        qc_keys['dertype'] = 0

    optking_options = module_options['OPTKING']
    for opt, optval in optking_options.items():
        if optval['has_changed']:
            opt_keys[opt.lower()] = optval['value']

    for option in all_options:
        if psi4.core.has_global_option_changed(option):
            if option in opt_keys:
                pass
            else:
                qc_keys[option.lower()] = psi4.core.get_global_option(option)

    # Make a qcSchema OptimizationInput
    opt_input = {
        "keywords": opt_keys,
        "initial_molecule": oMolsys.molsys_to_qc_molecule(),
        "input_specification": {
            "model": {
                'basis': qc_keys.pop('basis'),
                'method': calc_name
            },
            "driver": "gradient",
            "keywords": qc_keys
        }
    }

    logger.debug("Creating OptimizationInput")
    opt_input = OptimizationInput(**opt_input)

    # Remove numpy elements to allow at will json serialization
    opt_input = json.loads(json_dumps(opt_input))
    opt_output = copy.deepcopy(opt_input)

    try:
        initialize_options(opt_keys)
        computer = make_computer(opt_input)
        opt_output = optimize(oMolsys, computer)
    except (OptError, KeyError, ValueError, AttributeError) as error:
        opt_output = {
            "success": False,
            "error": {
                "error_type": error.err_type,
                "error_message": error.mesg
            }
        }
        logger.critical(f"Error placed in qcschema: {opt_output}")
    except Exception as error:
        logger.critical(
            "An unknown error has occured and evaded all error checking")

        opt_output = {
            "success": False,
            "error": {
                "error_type": error,
                "error_message": str(error)
            }
        }
        logger.critical(f"Error placed in qcschema: {opt_output}")
    finally:
        opt_input.update({"provenance": optking._optking_provenance_stamp})
        opt_input["provenance"]["routine"] = "optimize_psi4"
        opt_input.update(opt_output)
        return opt_input