def _core_set_variable(key: str, val: Union[core.Matrix, np.ndarray, float]) -> None: """Sets scalar or array QCVariable *key* to *val* in global memory.""" if isinstance(val, core.Matrix): if core.has_scalar_variable(key): raise ValidationError( f"psi4.core.set_variable: Target variable '{key}' already a scalar variable!" ) else: core.set_array_variable(key, val) elif isinstance(val, np.ndarray): if core.has_scalar_variable(key): raise ValidationError( f"psi4.core.set_variable: Target variable '{key}' already a scalar variable!" ) else: core.set_array_variable( key, core.Matrix.from_array(_qcvar_reshape_set(key, val))) else: if core.has_array_variable(key): raise ValidationError( f"psi4.core.set_variable: Target variable '{key}' already an array variable!" ) else: core.set_scalar_variable(key, val)
def _core_set_variable(key, val): if isinstance(val, core.Matrix): if core.has_scalar_variable(key): raise ValidationError("psi4.core.set_variable: Target variable " + key + " already a scalar variable!") else: core.set_array_variable(key, val) elif isinstance(val, np.ndarray): if core.has_scalar_variable(key): raise ValidationError("psi4.core.set_variable: Target variable " + key + " already a scalar variable!") else: core.set_array_variable(key, core.Matrix.from_array(val)) else: if core.has_array_variable(key): raise ValidationError("psi4.core.set_variable: Target variable " + key + " already an array variable!") else: core.set_scalar_variable(key, val)
def _core_set_variable(key, val): if isinstance(val, core.Matrix): if core.has_scalar_variable(key): raise ValidationError("psi4.core.set_variable: Target variable " + key + " already a scalar variable!") else: core.set_array_variable(key, val) elif isinstance(val, np.ndarray): if core.has_scalar_variable(key): raise ValidationError("psi4.core.set_variable: Target variable " + key + " already a scalar variable!") else: core.set_array_variable(key, core.Matrix.from_array(_qcvar_reshape_set(key, val))) else: if core.has_array_variable(key): raise ValidationError("psi4.core.set_variable: Target variable " + key + " already an array variable!") else: core.set_scalar_variable(key, val)
def nbody_gufunc(func, method_string, **kwargs): """ Computes the nbody interaction energy, gradient, or Hessian depending on input. This is a generalized univeral function for computing interaction and total quantities. :returns: *return type of func* |w--w| The data. :returns: (*float*, :py:class:`~psi4.core.Wavefunction`) |w--w| data and wavefunction with energy/gradient/hessian set appropriately when **return_wfn** specified. :type func: function :param func: ``energy`` || etc. Python function that accepts method_string and a molecule. Returns a energy, gradient, or Hessian as requested. :type method_string: string :param method_string: ``'scf'`` || ``'mp2'`` || ``'ci5'`` || etc. First argument, lowercase and usually unlabeled. Indicates the computational method to be passed to func. :type molecule: :ref:`molecule <op_py_molecule>` :param molecule: ``h2o`` || etc. The target molecule, if not the last molecule defined. :type return_wfn: :ref:`boolean <op_py_boolean>` :param return_wfn: ``'on'`` || |dl| ``'off'`` |dr| Indicate to additionally return the :py:class:`~psi4.core.Wavefunction` calculation result as the second element of a tuple. :type bsse_type: string or list :param bsse_type: ``'cp'`` || ``['nocp', 'vmfc']`` || |dl| ``None`` |dr| || etc. Type of BSSE correction to compute: CP, NoCP, or VMFC. The first in this list is returned by this function. By default, this function is not called. :type max_nbody: int :param max_nbody: ``3`` || etc. Maximum n-body to compute, cannot exceed the number of fragments in the moleucle. :type ptype: string :param ptype: ``'energy'`` || ``'gradient'`` || ``'hessian'`` Type of the procedure passed in. :type return_total_data: :ref:`boolean <op_py_boolean>` :param return_total_data: ``'on'`` || |dl| ``'off'`` |dr| If True returns the total data (energy/gradient/etc) of the system, otherwise returns interaction data. :type levels: dict :param levels: ``{1: 'ccsd(t)', 2: 'mp2', 'supersystem': 'scf'}`` || ``{1: 2, 2: 'ccsd(t)', 3: 'mp2'}`` || etc Dictionary of different levels of theory for different levels of expansion Note that method_string is not used in this case. supersystem computes all higher order n-body effects up to nfragments. :type embedding_charges: dict :param embedding_charges: ``{1: [-0.834, 0.417, 0.417], ..}`` Dictionary of atom-centered point charges. keys: 1-based index of fragment, values: list of charges for each fragment. :type charge_method: string :param charge_method: ``scf/6-31g`` || ``b3lyp/6-31g*`` || etc Method to compute point charges for monomers. Overridden by embedding_charges if both are provided. :type charge_type: string :param charge_type: ``MULLIKEN_CHARGES`` || ``LOWDIN_CHARGES`` Default is ``MULLIKEN_CHARGES`` """ # Initialize dictionaries for easy data passing metadata, component_results, nbody_results = {}, {}, {} # Parse some kwargs kwargs = p4util.kwargs_lower(kwargs) if kwargs.get('levels', False): return driver_nbody_helper.multi_level(func, **kwargs) metadata['ptype'] = kwargs.pop('ptype', None) metadata['return_wfn'] = kwargs.pop('return_wfn', False) metadata['return_total_data'] = kwargs.pop('return_total_data', False) metadata['molecule'] = kwargs.pop('molecule', core.get_active_molecule()) metadata['molecule'].update_geometry() metadata['molecule'].fix_com(True) metadata['molecule'].fix_orientation(True) metadata['embedding_charges'] = kwargs.get('embedding_charges', False) metadata['kwargs'] = kwargs core.clean_variables() if metadata['ptype'] not in ['energy', 'gradient', 'hessian']: raise ValidationError("""N-Body driver: The ptype '%s' is not regonized.""" % metadata['ptype']) # Parse bsse_type, raise exception if not provided or unrecognized metadata['bsse_type_list'] = kwargs.pop('bsse_type') if metadata['bsse_type_list'] is None: raise ValidationError("N-Body GUFunc: Must pass a bsse_type") if not isinstance(metadata['bsse_type_list'], list): metadata['bsse_type_list'] = [metadata['bsse_type_list']] for num, btype in enumerate(metadata['bsse_type_list']): metadata['bsse_type_list'][num] = btype.lower() if btype.lower() not in ['cp', 'nocp', 'vmfc']: raise ValidationError("N-Body GUFunc: bsse_type '%s' is not recognized" % btype.lower()) metadata['max_nbody'] = kwargs.get('max_nbody', -1) metadata['max_frag'] = metadata['molecule'].nfragments() if metadata['max_nbody'] == -1: metadata['max_nbody'] = metadata['molecule'].nfragments() else: metadata['max_nbody'] = min(metadata['max_nbody'], metadata['max_frag']) # Flip this off for now, needs more testing # If we are doing CP lets save them integrals #if 'cp' in bsse_type_list and (len(bsse_type_list) == 1): # # Set to save RI integrals for repeated full-basis computations # ri_ints_io = core.get_global_option('DF_INTS_IO') # # inquire if above at all applies to dfmp2 or just scf # core.set_global_option('DF_INTS_IO', 'SAVE') # psioh = core.IOManager.shared_object() # psioh.set_specific_retention(97, True) bsse_str = metadata['bsse_type_list'][0] if len(metadata['bsse_type_list']) > 1: bsse_str = str(metadata['bsse_type_list']) core.print_out("\n\n") core.print_out(" ===> N-Body Interaction Abacus <===\n") core.print_out(" BSSE Treatment: %s\n" % bsse_str) # Get compute list metadata = build_nbody_compute_list(metadata) # Compute N-Body components component_results = compute_nbody_components(func, method_string, metadata) # Assemble N-Body quantities nbody_results = assemble_nbody_components(metadata, component_results) # Build wfn and bind variables wfn = core.Wavefunction.build(metadata['molecule'], 'def2-svp') dicts = [ 'energies', 'ptype', 'intermediates', 'energy_body_dict', 'gradient_body_dict', 'hessian_body_dict', 'nbody', 'cp_energy_body_dict', 'nocp_energy_body_dict', 'vmfc_energy_body_dict' ] if metadata['ptype'] == 'gradient': wfn.set_gradient(nbody_results['ret_ptype']) nbody_results['gradient_body_dict'] = nbody_results['ptype_body_dict'] elif metadata['ptype'] == 'hessian': nbody_results['hessian_body_dict'] = nbody_results['ptype_body_dict'] wfn.set_hessian(nbody_results['ret_ptype']) component_results_gradient = component_results.copy() component_results_gradient['ptype'] = component_results_gradient['gradients'] metadata['ptype'] = 'gradient' nbody_results_gradient = assemble_nbody_components(metadata, component_results_gradient) wfn.set_gradient(nbody_results_gradient['ret_ptype']) nbody_results['gradient_body_dict'] = nbody_results_gradient['ptype_body_dict'] for r in [component_results, nbody_results]: for d in r: if d in dicts: for var, value in r[d].items(): try: wfn.set_scalar_variable(str(var), value) core.set_scalar_variable(str(var), value) except: wfn.set_array_variable(d.split('_')[0].upper() + ' ' + str(var), core.Matrix.from_array(value)) core.set_variable("CURRENT ENERGY", nbody_results['ret_energy']) wfn.set_variable("CURRENT ENERGY", nbody_results['ret_energy']) if metadata['return_wfn']: return (nbody_results['ret_ptype'], wfn) else: return nbody_results['ret_ptype']
def nbody_gufunc(func: Union[str, Callable], method_string: str, **kwargs): """ Computes the nbody interaction energy, gradient, or Hessian depending on input. This is a generalized univeral function for computing interaction and total quantities. :returns: *return type of func* |w--w| The data. :returns: (*float*, :py:class:`~psi4.core.Wavefunction`) |w--w| data and wavefunction with energy/gradient/hessian set appropriately when **return_wfn** specified. :type func: Callable :param func: ``energy`` || etc. Python function that accepts method_string and a molecule. Returns a energy, gradient, or Hessian as requested. :type method_string: str :param method_string: ``'scf'`` || ``'mp2'`` || ``'ci5'`` || etc. First argument, lowercase and usually unlabeled. Indicates the computational method to be passed to func. :type molecule: :ref:`molecule <op_py_molecule>` :param molecule: ``h2o`` || etc. The target molecule, if not the last molecule defined. :type return_wfn: :ref:`boolean <op_py_boolean>` :param return_wfn: ``'on'`` || |dl| ``'off'`` |dr| Indicate to additionally return the :py:class:`~psi4.core.Wavefunction` calculation result as the second element of a tuple. :type bsse_type: str or list :param bsse_type: ``'cp'`` || ``['nocp', 'vmfc']`` || |dl| ``None`` |dr| || etc. Type of BSSE correction to compute: CP, NoCP, or VMFC. The first in this list is returned by this function. By default, this function is not called. :type max_nbody: int :param max_nbody: ``3`` || etc. Maximum n-body to compute, cannot exceed the number of fragments in the moleucle. :type ptype: str :param ptype: ``'energy'`` || ``'gradient'`` || ``'hessian'`` Type of the procedure passed in. :type return_total_data: :ref:`boolean <op_py_boolean>` :param return_total_data: ``'on'`` || |dl| ``'off'`` |dr| If True returns the total data (energy/gradient/etc) of the system, otherwise returns interaction data. :type levels: dict :param levels: ``{1: 'ccsd(t)', 2: 'mp2', 'supersystem': 'scf'}`` || ``{1: 2, 2: 'ccsd(t)', 3: 'mp2'}`` || etc Dictionary of different levels of theory for different levels of expansion Note that method_string is not used in this case. supersystem computes all higher order n-body effects up to nfragments. :type embedding_charges: dict :param embedding_charges: ``{1: [-0.834, 0.417, 0.417], ..}`` Dictionary of atom-centered point charges. keys: 1-based index of fragment, values: list of charges for each fragment. :type charge_method: str :param charge_method: ``scf/6-31g`` || ``b3lyp/6-31g*`` || etc Method to compute point charges for monomers. Overridden by embedding_charges if both are provided. :type charge_type: str :param charge_type: ``MULLIKEN_CHARGES`` || ``LOWDIN_CHARGES`` Default is ``MULLIKEN_CHARGES`` """ # Initialize dictionaries for easy data passing metadata, component_results, nbody_results = {}, {}, {} # Parse some kwargs kwargs = p4util.kwargs_lower(kwargs) if kwargs.get('levels', False): return driver_nbody_helper.multi_level(func, **kwargs) metadata['ptype'] = kwargs.pop('ptype', None) metadata['return_wfn'] = kwargs.pop('return_wfn', False) metadata['return_total_data'] = kwargs.pop('return_total_data', False) metadata['molecule'] = kwargs.pop('molecule', core.get_active_molecule()) metadata['molecule'].update_geometry() metadata['molecule'].fix_com(True) metadata['molecule'].fix_orientation(True) metadata['embedding_charges'] = kwargs.get('embedding_charges', False) metadata['kwargs'] = kwargs core.clean_variables() if metadata['ptype'] not in ['energy', 'gradient', 'hessian']: raise ValidationError( """N-Body driver: The ptype '%s' is not regonized.""" % metadata['ptype']) # Parse bsse_type, raise exception if not provided or unrecognized metadata['bsse_type_list'] = kwargs.pop('bsse_type') if metadata['bsse_type_list'] is None: raise ValidationError("N-Body GUFunc: Must pass a bsse_type") if not isinstance(metadata['bsse_type_list'], list): metadata['bsse_type_list'] = [metadata['bsse_type_list']] for num, btype in enumerate(metadata['bsse_type_list']): metadata['bsse_type_list'][num] = btype.lower() if btype.lower() not in ['cp', 'nocp', 'vmfc']: raise ValidationError( "N-Body GUFunc: bsse_type '%s' is not recognized" % btype.lower()) metadata['max_nbody'] = kwargs.get('max_nbody', -1) if metadata['molecule'].nfragments() == 1: raise ValidationError( "N-Body requires active molecule to have more than 1 fragment.") metadata['max_frag'] = metadata['molecule'].nfragments() if metadata['max_nbody'] == -1: metadata['max_nbody'] = metadata['molecule'].nfragments() else: metadata['max_nbody'] = min(metadata['max_nbody'], metadata['max_frag']) # Flip this off for now, needs more testing # If we are doing CP lets save them integrals #if 'cp' in bsse_type_list and (len(bsse_type_list) == 1): # # Set to save RI integrals for repeated full-basis computations # ri_ints_io = core.get_global_option('DF_INTS_IO') # # inquire if above at all applies to dfmp2 or just scf # core.set_global_option('DF_INTS_IO', 'SAVE') # psioh = core.IOManager.shared_object() # psioh.set_specific_retention(97, True) bsse_str = metadata['bsse_type_list'][0] if len(metadata['bsse_type_list']) > 1: bsse_str = str(metadata['bsse_type_list']) core.print_out("\n\n") core.print_out(" ===> N-Body Interaction Abacus <===\n") core.print_out(" BSSE Treatment: %s\n" % bsse_str) # Get compute list metadata = build_nbody_compute_list(metadata) # Compute N-Body components component_results = compute_nbody_components(func, method_string, metadata) # Assemble N-Body quantities nbody_results = assemble_nbody_components(metadata, component_results) # Build wfn and bind variables wfn = core.Wavefunction.build(metadata['molecule'], 'def2-svp') dicts = [ 'energies', 'ptype', 'intermediates', 'energy_body_dict', 'gradient_body_dict', 'hessian_body_dict', 'nbody', 'cp_energy_body_dict', 'nocp_energy_body_dict', 'vmfc_energy_body_dict' ] if metadata['ptype'] == 'gradient': wfn.set_gradient(nbody_results['ret_ptype']) nbody_results['gradient_body_dict'] = nbody_results['ptype_body_dict'] elif metadata['ptype'] == 'hessian': nbody_results['hessian_body_dict'] = nbody_results['ptype_body_dict'] wfn.set_hessian(nbody_results['ret_ptype']) component_results_gradient = component_results.copy() component_results_gradient['ptype'] = component_results_gradient[ 'gradients'] metadata['ptype'] = 'gradient' nbody_results_gradient = assemble_nbody_components( metadata, component_results_gradient) wfn.set_gradient(nbody_results_gradient['ret_ptype']) nbody_results['gradient_body_dict'] = nbody_results_gradient[ 'ptype_body_dict'] for r in [component_results, nbody_results]: for d in r: if d in dicts: for var, value in r[d].items(): try: wfn.set_scalar_variable(str(var), value) core.set_scalar_variable(str(var), value) except: wfn.set_array_variable( d.split('_')[0].upper() + ' ' + str(var), core.Matrix.from_array(value)) core.set_variable("CURRENT ENERGY", nbody_results['ret_energy']) wfn.set_variable("CURRENT ENERGY", nbody_results['ret_energy']) if metadata['ptype'] == 'gradient': core.set_variable("CURRENT GRADIENT", nbody_results['ret_ptype']) elif metadata['ptype'] == 'hessian': core.set_variable("CURRENT HESSIAN", nbody_results['ret_ptype']) if metadata['return_wfn']: return (nbody_results['ret_ptype'], wfn) else: return nbody_results['ret_ptype']