def run_refgradient(mol, bqfield, options): """The function calculates SCF gradient in addition to MP2 or CCSD gradients and saves it the file en_grad0.dat """ basis = 'aug-cc-pvdz' if 'basis' not in options else options['basis'] theory = 'mp2' if 'theory' not in options else options['theory'] psi4.core.set_global_option('freeze_core', 'True') method_str = theory + '/' + basis ref_str = 'scf/' + basis psi4.core.set_global_option_python('EXTERN', bqfield.extern) psi4.core.set_global_option('BASIS', basis) grad0, wfn0 = pri4.gradient(ref_str, return_wfn=True) E0 = psi4.core.get_variable('CURRENT ENERGY') grad, wfn = psi4.gradient(method_str, return_wfn=True, ref_wfn=wfn0) E = psi4.core.get_variable('CURRENT ENERGY') gradarr0 = psi4.p4util.mat2arr(grad0) gradarr = psi4.p4util.mat2arr(grad) with open('en_grad_ref.dat', 'w') as fp: fp.write("%24.16f\n" % E0) for g in gradarr0: fp.write(("%24.16f" * 3 + "\n") % (g0[0], g0[1], g0[2])) with open('en_grad_correl.dat', 'w') as fp: fp.write("%24.16f\n" % E) for g, g0 in zip(gradarr, gradarr0): fp.write(("%24.16f" * 3 + "\n") % (g[0], g[1], g[2])) bq_list = options['bq_list'] # feed BQ positions into Psi4 as angstrom with open('grid.dat', 'w') as fp: for bq in bq_list: fp.write('%16.10f%16.10f%16.10f\n' % (bq[1], bq[2], bq[3])) psi4.oeprop(wfn, 'GRID_FIELD')
def compute_scf_charges(self, charge_method='MULLIKEN_CHARGES'): """ Calls Psi4 to obtain the self.charges on each atom given and saves it as a numpy array. This method works well for SCF wavefunctions. For correlated levels of theory (e.g., MP2), it is advised that compute_energy_and_charges() be used instead. """ if self.wavefunction is not None: psi4.oeprop(self.wavefunction, charge_method) self.charges = np.asarray(self.wavefunction.atomic_point_charges()) self.charges = self.charges
def FMO1init(fragList): createChargefield(fragList, []) for i in fragList: E, wfn = psi4.energy(theory ,return_wfn=True, molecule=fragList[i][0]) fragList[i] += [wfn] psi4.oeprop(fragList[i][1], chargeTheory) # calculate the FMO cluster energy fragEnergies =[] for i in fragList: fragEnergies += [fragList[i][1].energy()] FMOEnergy = np.sum(fragEnergies) return(FMOEnergy, fragEnergies)
def calculate(inp, calc, save): '''Run nwchem on input, return data in results dict Args inp: Psi4 input object (geometry, bq_pos, bq_charges) calc: calculation type save: save calculation results Returns results: dictionary ''' options = params.options mol, bqfield, bqs = inp psi4.core.set_global_option_python('EXTERN', bqfield.extern) psi4.core.set_global_option('BASIS', options['basis']) psi4.set_memory(int(options['mem_mb'] * 1e6)) if options['correlation'] and calc not in ['esp', 'energy_hf']: theory = options['correlation'] psi4.core.set_global_option('freeze_core', 'True') else: theory = 'scf' method_str = theory + '/' + options['basis'] results = {} if calc == 'energy' or calc == 'energy_hf': results['E_tot'] = psi4.energy(method_str) elif calc == 'esp': raise RuntimeError("Not implemented") elif calc == 'gradient': grad, wfn = psi4.gradient(method_str, return_wfn=True) E = psi4.core.get_variable('CURRENT ENERGY') results['E'] = E results['gradient'] = psi4.p4util.mat2arr(grad) with open('grid.dat', 'w') as fp: for bq in bqs: fp.write('%16.10f%16.10f%16.10f\n' % (bq[0], bq[1], bq[2])) psi4.oeprop(wfn, 'GRID_FIELD') bq_field = np.loadtxt('grid_field.dat') assert bq_field.shape == (len(bqs), 3) bqgrad = [] for chg, field_vec in zip(bqs, bq_field): bqgrad.append(-1.0 * chg[3] * field_vec) results['bq_gradient'] = np.array(bqgrad) elif calc == 'hessian': hess = psi4.hessian(theory) hessarr = np.array(psi4.p4util.mat2arr(hess)) results['hess'] = hessarr return results
def run_gradient(mol, bqfield, options): basis = 'aug-cc-pvdz' if 'basis' not in options else options['basis'] theory = 'mp2' if 'theory' not in options else options['theory'] psi4.core.set_global_option('freeze_core', 'True') method_str = theory + '/' + basis psi4.core.set_global_option_python('EXTERN', bqfield.extern) psi4.core.set_global_option('BASIS', basis) grad, wfn = psi4.gradient(method_str, return_wfn=True) E = psi4.core.get_variable('CURRENT ENERGY') gradarr = psi4.p4util.mat2arr(grad) with open('en_grad.dat', 'w') as fp: fp.write("%24.16f\n" % E) for g in gradarr: fp.write(("%24.16f" * 3 + "\n") % (g[0], g[1], g[2])) bq_list = options['bq_list'] # feed BQ positions into Psi4 as angstrom with open('grid.dat', 'w') as fp: for bq in bq_list: fp.write('%16.10f%16.10f%16.10f\n' % (bq[1], bq[2], bq[3])) psi4.oeprop(wfn, 'GRID_FIELD')
def FMO1iter(fragList): # create the new wfn objects in the 3rd array posiiton for count, i in enumerate(fragList): fragnums = list(range(len(fragList))) fragnums.remove(count) createChargefield(fragList, fragnums) E, wfn = psi4.energy(theory ,return_wfn=True, molecule=fragList[i][0]) fragList[i] += [wfn] psi4.oeprop(fragList[i][-1], chargeTheory) # delete the old wfn objects for i in fragList: del fragList[i][1] # calculate the FMO cluster energy fragEnergies = [] for i in fragList: fragEnergies += [fragList[i][1].energy()] FMOEnergy = np.sum(fragEnergies) return(FMOEnergy, fragEnergies)
def compute_esp_rmsd(self, r_max=7., min_points=50000): print('generating grid') grid = esp.generate_coords(self.R, self.Z, r_max=r_max, min_points=min_points) folder = '../data/potential_data/' + self.basisset + '/' filename = (self.generate_molname(scheme_name=False) + '_' + self.basisset + '_' + self.lot + '_mp_' + str(min_points) + '_rm_' + str(r_max)[:5].replace('.', '-') + '.dat') try: qm_esp = np.loadtxt(folder + filename) print('Potential data loaded') except OSError: print('Calculating QM ESP at the gridpoints') psi4.oeprop(self.model.wavefunction, 'GRID_ESP') print('Saving QM ESP') qm_esp = np.loadtxt('grid_esp.dat') np.savetxt(folder + filename, qm_esp) print('Computing classical ESP') self.L_centers = np.einsum( 'ji,jka,ki->ia', self.W, self.center_matrix, self.W, optimize=True) / angstrom nuc_esp = esp.calculate_ESP(grid, self.R, self.Z) elec_esp = esp.calculate_ESP(grid, self.L_centers, np.full((self.N_occ), -2.)) clas_esp = (nuc_esp + elec_esp) / angstrom # print(np.min(np.abs(clas_esp))) print('Valid points: ' + str(len(clas_esp))) # self.Errmsd = np.sqrt(np.sum(((qm_esp - clas_esp)/clas_esp)**2)/len(clas_esp)) self.Ersd = np.sqrt(np.sum((qm_esp - clas_esp)**2)) self.esp_points = len(clas_esp) return self.Ersd
S 2 1.00 12.2874690000 0.4448700000 4.7568050000 0.2431720000 S 1 1.00 1.0042710000 1.0000000000 S 1 1.00 0.3006860000 1.0000000000 S 1 1.00 0.0900300000 1.0000000000 P 4 1.00 34.8564630000 0.0156480000 7.8431310000 0.0981970000 2.3062490000 0.3077680000 0.7231640000 0.4924700000 P 1 1.00 0.2148820000 1.0000000000 P 1 1.00 0.0638500000 1.0000000000 D 2 1.00 2.3062000000 0.2027000000 0.7232000000 0.5791000000 D 2 1.00 0.2149000000 0.7854500000 0.0639000000 0.5338700000 **** """) ccsd_e, wfn = psi4.properties('ccsd',properties=['dipole'],return_wfn=True) psi4.oeprop(wfn,"DIPOLE", "QUADRUPOLE", title="(OEPROP)CC") psi4.core.print_variables()
AllChem.EmbedMolecule(mol, AllChem.ETKDGv2()) AllChem.UFFOptimizeMolecule(mol) conf = mol.GetConformer(-1) xyz = '0 1' for atom, (x, y, z) in zip(mol.GetAtoms(), conf.GetPositions()): xyz += '\n' xyz += '{}\t{}\t{}\t{}'.format(atom.GetSymbol(), x, y, z) return xyz # 入力する分子(thiacloprid) smiles = 'C1CSC(=NC#N)N1CC2=CN=C(C=C2)Cl' psi4.set_output_file('04_thiacloprid.txt') dinotefuran = psi4.geometry(smi2xyz(smiles)) _, wfn_dtf = psi4.optimize('B3LYP/6-31G*', molecule=dinotefuran, return_wfn=True) rdkit_dinotefuran = Chem.AddHs(Chem.MolFromSmiles(smiles)) ## 双極子モーメントの計算 psi4.oeprop(wfn_dtf, 'DIPOLE', titile='dipole') dipole_x, dipole_y, dipole_z = psi4.variable('SCF DIPOLE X'), psi4.variable( 'SCF DIPOLE Y'), psi4.variable('SCF DIPOLE Z') dipole_moment = np.sqrt(dipole_x**2 + dipole_y**2 + dipole_z**2) #print(round(dipole_moment,3),'D')
def free_atom_volumes(wfn, **kwargs): """ Computes free-atom volumes using MBIS density partitioning. The free-atom volumes are computed for all unique (inc. basis set) atoms in a molecule and stored as wavefunction variables. Free-atom densities are computed at the same level of theory as the molecule, and we use unrestricted references as needed in computing the ground-state. The free-atom volumes are used to compute volume ratios in routine MBIS computations Parameters ---------- wfn : psi4.core.Wavefunction The wave function associated with the molecule, method, and basis for atomic computations """ # the level of theory current_en = wfn.scalar_variable('CURRENT ENERGY') total_energies = [ k for k, v in wfn.scalar_variables().items() if abs(v - current_en) <= 1e-12 ] theory = "" for var in total_energies: if 'TOTAL ENERGY' in var: var = var.split() if var[0] == 'SCF': continue elif var[0] == 'DFT': theory = wfn.functional().name() else: theory = var[0] # list of reference number of unpaired electrons. # Note that this is not the same as the # total spin of the ground state atom reference_S = [ 0, 1, 0, 1, 0, 1, 2, 3, 2, 1, 0, 1, 0, 1, 2, 3, 2, 1, 0, 1, 0, 1, 2, 3, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 0, 1, 2, 5, 6, 5, 4, 3, 0, 1, 0, 1, 2, 3, 2, 1, 0, 1, 0, 1, 0, 3, 4, 5, 6, 7, 8, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0 ] # the parent molecule and reference type mol = wfn.molecule() # Get unique atoms by input symbol, # Be to handle different basis sets unq_atoms = set() for atom in range(mol.natom()): symbol = mol.symbol(atom) Z = int(mol.Z(atom)) basis = mol.basis_on_atom(atom) unq_atoms.add((symbol, Z, basis)) psi4.core.print_out( f" Running {len(unq_atoms)} free-atom UHF computations") optstash = optproc.OptionsState(["SCF", 'REFERENCE']) for a_sym, a_z, basis in unq_atoms: # make sure we do UHF/UKS if we're not a singlet if reference_S[a_z] != 0: psi4.core.set_local_option("SCF", "REFERENCE", "UHF") else: psi4.core.set_local_option("SCF", "REFERENCE", "RHF") # Set the molecule, here just an atom a_mol = psi4.core.Molecule.from_arrays( geom=[0, 0, 0], elem=[a_sym], molecular_charge=0, molecular_multiplicity=int(1 + reference_S[a_z])) a_mol.update_geometry() psi4.molutil.activate(a_mol) method = theory + "/" + basis # Get the atomic wfn at_e, at_wfn = psi4.energy(method, return_wfn=True) # Now, re-run mbis for the atomic density, grabbing only the volume psi4.oeprop(at_wfn, 'MBIS_CHARGES', title=a_sym + " " + method, free_atom=True) vw = at_wfn.array_variable('MBIS RADIAL MOMENTS <R^3>') # P::e OEPROP vw = vw.get(0, 0) # set the atomic widths as wfn variables wfn.set_variable("MBIS FREE ATOM " + a_sym.upper() + " VOLUME", vw) # set_variable("MBIS FREE ATOM n VOLUME") # P::e OEPROP psi4.core.clean() psi4.core.clean_variables() # reset mol and reference to original optstash.restore() mol.update_geometry() psi4.molutil.activate(mol)