Ejemplo n.º 1
0
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')
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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')
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
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()
Ejemplo n.º 9
0
    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')
Ejemplo n.º 10
0
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)