def V(values=None): # pylint:disable=dangerous-default-value if hasattr(V, "counter"): V.counter += 1 else: V.counter = 0 substitutions = list(zip(symbolic_expressions, values)) new_zmat = zmolecule.subs(substitutions) if isfile(input_path(V.counter)): result = {} while len(result.keys()) < 3: try: result = molcas.parse_output(output_path(V.counter)) except FileNotFoundError: pass sleep(0.5) else: result = molcas.calculate( molecule=new_zmat, forces=True, el_calc_input=input_path(V.counter), start_orb=start_orb_path(V.counter - 1) if V.counter else start_orb, hamiltonian=hamiltonian, basis=basis, charge=charge, title=title, multiplicity=multiplicity, num_procs=num_procs, mem_per_proc=mem_per_proc, **kwargs) return result['energy']
def V(C_rad=None, calculated=[]): # pylint:disable=dangerous-default-value try: previous_zmat = calculated[-1].copy() except IndexError: new_zmat = zmolecule.copy() else: new_zmat = get_new_zmat(C_rad, previous_zmat) if isfile(input_path(len(calculated))): result = {} while len(result.keys()) < 3: try: result = molcas.parse_output(output_path(len(calculated))) except FileNotFoundError: pass sleep(0.5) else: result = molcas.calculate( molecule=new_zmat, forces=True, el_calc_input=input_path(len(calculated)), start_orb=start_orb_path(len(calculated) - 1) if calculated else start_orb, hamiltonian=hamiltonian, basis=basis, charge=charge, title=title, multiplicity=multiplicity, num_procs=num_procs, mem_per_proc=mem_per_proc, **kwargs) calculated.append(new_zmat) return result['energy']
def grad_V(values=None, get_calculated=False, calculated=[]): # pylint:disable=dangerous-default-value if get_calculated: return calculated elif values is not None: substitutions = list(zip(symbolic_expressions, values)) new_zmat = zmolecule.subs(substitutions) if isfile(input_path(len(calculated))): result = {} while len(result.keys()) < 3: try: result = molcas.parse_output(output_path(len(calculated))) except FileNotFoundError: pass sleep(0.5) else: result = molcas.calculate( molecule=new_zmat, forces=True, el_calc_input=input_path(len(calculated)), start_orb=start_orb_path(len(calculated) - 1) if calculated else start_orb, hamiltonian=hamiltonian, basis=basis, charge=charge, title=title, multiplicity=multiplicity, num_procs=num_procs, mem_per_proc=mem_per_proc, **kwargs) energy, grad_energy_X = result['energy'], result['gradient'] grad_energy_C = _get_grad_energy_C(new_zmat, grad_energy_X) zm_values_rad = zmolecule.loc[:, value_cols].values zm_values_rad[:, [1, 2]] = sympy.rad(zm_values_rad[:, [1, 2]]) energy_symb = np.sum(zm_values_rad * grad_energy_C) grad_energy_symb = sympy.Matrix([ energy_symb.diff(arg) for arg in symbolic_expressions]) grad_energy_symb = np.array(grad_energy_symb.subs(substitutions)) grad_energy_symb = grad_energy_symb.astype('f8').flatten() new_zmat.metadata['energy'] = energy new_zmat.metadata['symbols'] = substitutions calculated.append({'energy': energy, 'structure': new_zmat, 'symbols': substitutions}) with open(md_out, 'a') as f: f.write(_get_table_row(calculated, grad_energy_symb)) if is_converged(calculated, etol=etol): raise ConvergenceFinished(successful=True) elif len(calculated) >= max_iter: raise ConvergenceFinished(successful=False) return grad_energy_symb else: raise ValueError
def calculate(molecule, hamiltonian, basis, el_calc_input=None, backend=None, charge=fixed_defaults['charge'], forces=fixed_defaults['forces'], title=fixed_defaults['title'], multiplicity=fixed_defaults['multiplicity'], **kwargs): """Calculate the energy of a molecule. Args: molecule (chemcoord.Cartesian or chemcoord.Zmat or str): If it is a string, it has to be a valid xyz-file. hamiltonian (str): {hamiltonian} basis (str): {basis} el_calc_input (str): {el_calc_input} backend (str): {backend} charge (int): {charge} forces (bool): {forces} title (str): {title} multiplicity (int): {multiplicity} Returns: dict: A dictionary with at least the keys ``'structure'`` and ``'energy'`` which contains the energy in Hartree. If forces were calculated, the key ``'gradient'`` contains the gradient in Hartree / Angstrom. """ if backend is None: backend = conf_defaults['backend'] if backend == 'molpro': return molpro.calculate(el_calc_input=el_calc_input, molecule=molecule, hamiltonian=hamiltonian, basis=basis, charge=charge, forces=forces, title=title, multiplicity=multiplicity) elif backend == 'molcas': return molcas.calculate(el_calc_input=el_calc_input, molecule=molecule, hamiltonian=hamiltonian, basis=basis, charge=charge, forces=forces, title=title, multiplicity=multiplicity) else: raise ValueError('Backend {} is not implemented.'.format(backend))
def grad_V(C_rad=None, get_calculated=False, calculated=[]): # pylint:disable=dangerous-default-value if get_calculated: return calculated elif C_rad is not None: try: previous_zmat = calculated[-1]['structure'].copy() except IndexError: new_zmat = zmolecule.copy() else: new_zmat = get_new_zmat(C_rad, previous_zmat) if isfile(input_path(len(calculated))): result = {} while len(result.keys()) < 3: try: result = molcas.parse_output(output_path(len(calculated))) except FileNotFoundError: pass sleep(0.5) else: result = molcas.calculate( molecule=new_zmat, forces=True, el_calc_input=input_path(len(calculated)), start_orb=start_orb_path(len(calculated) - 1) if calculated else start_orb, hamiltonian=hamiltonian, basis=basis, charge=charge, title=title, multiplicity=multiplicity, num_procs=num_procs, mem_per_proc=mem_per_proc, **kwargs) energy, grad_energy_X = result['energy'], result['gradient'] grad_energy_C = _get_grad_energy_C(new_zmat, grad_energy_X) new_zmat.metadata['energy'] = energy new_zmat.metadata['grad_energy'] = grad_energy_C calculated.append({'energy': energy, 'grad_energy': grad_energy_C, 'structure': new_zmat}) with open(md_out, 'a') as f: f.write(_get_table_row(calculated, grad_energy_X)) if is_converged(calculated, grad_energy_X, etol=etol, gtol=gtol): raise ConvergenceFinished(successful=True) elif len(calculated) >= max_iter: raise ConvergenceFinished(successful=False) return grad_energy_C.flatten() else: raise ValueError