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)
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
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"]
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
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