def compute_nbody_components(func, method_string, metadata): """Computes requested N-body components. Performs requested computations for psi4::Molecule object `molecule` according to `compute_list` with function `func` at `method_string` level of theory. Parameters ---------- func : {'energy', 'gradient', 'hessian'} Function object to be called within N-Body procedure. method_string : str Indicates level of theory to be passed to function `func`. metadata : dict of str Dictionary of N-body metadata. Required ``'key': value`` pairs: ``'compute_list'``: dict of int: set List of computations to perform. Keys indicate body-levels, e.g,. `compute_list[2]` is the list of all 2-body computations required. ``'kwargs'``: dict Arbitrary keyword arguments to be passed to function `func`. Returns ------- dict of str: dict Dictionary containing computed N-body components. Contents: ``'energies'``: dict of set: float64 Dictionary containing all energy components required for given N-body procedure. ``'ptype'``: dict of set: float64 or dict of set: psi4.Matrix Dictionary of returned quantities from calls of function `func` during N-body computations ``'intermediates'``: dict of str: float64 Dictionary of psivars for intermediate N-body computations to be set at the end of the N-body procedure. """ # Get required metadata kwargs = metadata['kwargs'] molecule = metadata['molecule'] #molecule = core.get_active_molecule() compute_list = metadata['compute_dict']['all'] # Now compute the energies energies_dict = {} gradients_dict = {} ptype_dict = {} intermediates_dict = {} if kwargs.get('charge_method', False) and not metadata['embedding_charges']: metadata['embedding_charges'] = driver_nbody_helper.compute_charges(kwargs['charge_method'], kwargs.get('charge_type', 'MULLIKEN_CHARGES').upper(), molecule) for count, n in enumerate(compute_list.keys()): core.print_out("\n ==> N-Body: Now computing %d-body complexes <==\n\n" % n) total = len(compute_list[n]) for num, pair in enumerate(compute_list[n]): core.print_out( "\n N-Body: Computing complex (%d/%d) with fragments %s in the basis of fragments %s.\n\n" % (num + 1, total, str(pair[0]), str(pair[1]))) ghost = list(set(pair[1]) - set(pair[0])) current_mol = molecule.extract_subsets(list(pair[0]), ghost) current_mol.set_name("%s_%i_%i" % (current_mol.name(), count, num)) if metadata['embedding_charges']: driver_nbody_helper.electrostatic_embedding(metadata, pair=pair) # Save energies info ptype_dict[pair], wfn = func(method_string, molecule=current_mol, return_wfn=True, **kwargs) core.set_global_option_python('EXTERN', None) energies_dict[pair] = core.variable("CURRENT ENERGY") gradients_dict[pair] = wfn.gradient() var_key = "N-BODY (%s)@(%s) TOTAL ENERGY" % (', '.join([str(i) for i in pair[0]]), ', '.join( [str(i) for i in pair[1]])) intermediates_dict[var_key] = core.variable("CURRENT ENERGY") core.print_out("\n N-Body: Complex Energy (fragments = %s, basis = %s: %20.14f)\n" % (str( pair[0]), str(pair[1]), energies_dict[pair])) # Flip this off for now, needs more testing #if 'cp' in bsse_type_list and (len(bsse_type_list) == 1): # core.set_global_option('DF_INTS_IO', 'LOAD') core.clean() return { 'energies': energies_dict, 'gradients': gradients_dict, 'ptype': ptype_dict, 'intermediates': intermediates_dict }
def compute_nbody_components(func, method_string, metadata): """Computes requested N-body components. Performs requested computations for psi4::Molecule object `molecule` according to `compute_list` with function `func` at `method_string` level of theory. Parameters ---------- func : str {'energy', 'gradient', 'hessian'} Function object to be called within N-Body procedure. method_string : str Indicates level of theory to be passed to function `func`. metadata : dict of str Dictionary of N-body metadata. Required ``'key': value`` pairs: ``'compute_list'``: dict of int: set List of computations to perform. Keys indicate body-levels, e.g,. `compute_list[2]` is the list of all 2-body computations required. ``'kwargs'``: dict Arbitrary keyword arguments to be passed to function `func`. Returns ------- dict of str: dict Dictionary containing computed N-body components. Contents: ``'energies'``: dict of set: float64 Dictionary containing all energy components required for given N-body procedure. ``'ptype'``: dict of set: float64 or dict of set: psi4.Matrix Dictionary of returned quantities from calls of function `func` during N-body computations ``'intermediates'``: dict of str: float64 Dictionary of psivars for intermediate N-body computations to be set at the end of the N-body procedure. """ # Get required metadata kwargs = metadata['kwargs'] molecule = metadata['molecule'] #molecule = core.get_active_molecule() compute_list = metadata['compute_dict']['all'] # Now compute the energies energies_dict = {} gradients_dict = {} ptype_dict = {} intermediates_dict = {} if kwargs.get('charge_method', False) and not metadata['embedding_charges']: metadata['embedding_charges'] = driver_nbody_helper.compute_charges( kwargs['charge_method'], kwargs.get('charge_type', 'MULLIKEN_CHARGES').upper(), molecule) for count, n in enumerate(compute_list.keys()): core.print_out( "\n ==> N-Body: Now computing %d-body complexes <==\n\n" % n) total = len(compute_list[n]) for num, pair in enumerate(compute_list[n]): core.print_out( "\n N-Body: Computing complex (%d/%d) with fragments %s in the basis of fragments %s.\n\n" % (num + 1, total, str(pair[0]), str(pair[1]))) ghost = list(set(pair[1]) - set(pair[0])) current_mol = molecule.extract_subsets(list(pair[0]), ghost) current_mol.set_name("%s_%i_%i" % (current_mol.name(), count, num)) if metadata['embedding_charges']: driver_nbody_helper.electrostatic_embedding(metadata, pair=pair) # Save energies info ptype_dict[pair], wfn = func(method_string, molecule=current_mol, return_wfn=True, **kwargs) core.set_global_option_python('EXTERN', None) energies_dict[pair] = core.variable("CURRENT ENERGY") gradients_dict[pair] = wfn.gradient() var_key = "N-BODY (%s)@(%s) TOTAL ENERGY" % (', '.join( [str(i) for i in pair[0]]), ', '.join([str(i) for i in pair[1]])) intermediates_dict[var_key] = core.variable("CURRENT ENERGY") core.print_out( "\n N-Body: Complex Energy (fragments = %s, basis = %s: %20.14f)\n" % (str(pair[0]), str(pair[1]), energies_dict[pair])) # Flip this off for now, needs more testing #if 'cp' in bsse_type_list and (len(bsse_type_list) == 1): # core.set_global_option('DF_INTS_IO', 'LOAD') core.clean() return { 'energies': energies_dict, 'gradients': gradients_dict, 'ptype': ptype_dict, 'intermediates': intermediates_dict }