def pyq2_dft(atomtuples=[(2,0,0,0)],basis = '6-31G**',maxit=10,xcname='svwn'): import pyquante2 as pyq2 print ("pyq2 DFT run") geo = pyq2.molecule(atomtuples) bfs = pyq2.basisset(geo,name=basis) i1 = pyq2.onee_integrals(bfs,geo) i2 = pyq2.twoe_integrals(bfs) grid = pyq2.grid(geo) h = i1.T + i1.V orbe,orbs = pyq2.geigh(h,i1.S) eold = 0 grid.setbfamps(bfs) E0 = geo.nuclear_repulsion() for i in range(maxit): D = pyq2.dmat(orbs,geo.nocc()) E1 = 2*pyq2.trace2(h,D) J = i2.get_j(D) Ej = 2*pyq2.trace2(J,D) Exc,Vxc = pyq2.get_xc(grid,0.5*D,xcname=xcname) energy = E0+E1+Ej+Exc F = h+2*J+Vxc orbe,orbs = pyq2.geigh(F,i1.S) print (i,energy,E1,Ej,Exc,E0) if np.isclose(energy,eold): break eold = energy return energy
def _parse_molecule(val, units, charge, multiplicity): val = _check_molecule_format(val) parts = [x.strip() for x in val.split(";")] if parts is None or len(parts) < 1: # pylint: disable=len-as-condition raise QiskitNatureError("Molecule format error: " + val) geom = [] for n, _ in enumerate(parts): part = parts[n] geom.append(_parse_atom(part)) if len(geom) < 1: # pylint: disable=len-as-condition raise QiskitNatureError("Molecule format error: " + val) try: # pylint: disable=import-error,import-outside-toplevel from pyquante2 import ( molecule, ) return molecule(geom, units=units, charge=charge, multiplicity=multiplicity) except Exception as exc: raise QiskitNatureError("Failed to create molecule") from exc
def test_h2_svwn(self): h2 = molecule([(1, 0, 0, -0.368), (1, 0, 0, 0.368)], units='angs', nrad=50, do_sg1=False) bfs = basisset(h2, 'sto3g') solver = dft(h2, bfs, 'svwn') ens = solver.converge() self.assertAlmostEqual(solver.energy, -1.1212155284066108)
def test_h4(self): h4 = molecule([ (1, 0.00000000, 0.00000000, 0.36628549), (1, 0.00000000, 0.00000000, -0.36628549), (1, 0.00000000, 4.00000000, 0.36628549), (1, 0.00000000, 4.00000000, -0.36628549), ], units='Angstrom') bfs = basisset(h4,'sto3g') solver = rhf(h4,bfs) ens = solver.converge() self.assertAlmostEqual(solver.energy,-2.234185653441159,6)
def test_h4(self): h4 = molecule([ (1, 0.00000000, 0.00000000, 0.36628549), (1, 0.00000000, 0.00000000, -0.36628549), (1, 0.00000000, 4.00000000, 0.36628549), (1, 0.00000000, 4.00000000, -0.36628549), ], units='Angstrom') bfs = basisset(h4, 'sto3g') solver = rhf(h4, bfs) ens = solver.converge() self.assertAlmostEqual(solver.energy, -2.234185653441159, match_digits)
def pyq2_rohf(atomtuples=[(2, 0, 0, 0)], basis='6-31G**', maxit=10, xcname='svwn', mult=3): import pyquante2 as pyq2 print("pyq2 ROHF run") geo = pyq2.molecule(atomtuples, multiplicity=mult) bfs = pyq2.basisset(geo, name=basis) i1 = pyq2.onee_integrals(bfs, geo) i2 = pyq2.twoe_integrals(bfs) h = i1.T + i1.V orbe, orbs = pyq2.geigh(h, i1.S) eold = 0 E0 = geo.nuclear_repulsion() nalpha, nbeta = geo.nup(), geo.ndown() norbs = len(bfs) for i in range(maxit): Da = pyq2.dmat(orbs, nalpha) Db = pyq2.dmat(orbs, nbeta) E1 = 0.5 * pyq2.trace2(Da + Db, h) Ja, Ka = i2.get_j(Da), i2.get_k(Da) Jb, Kb = i2.get_j(Db), i2.get_k(Db) Fa = h + Ja + Jb - Ka Fb = h + Ja + Jb - Kb E2 = 0.5 * (pyq2.trace2(Fa, Da) + pyq2.trace2(Fb, Db)) energy = E0 + E1 + E2 print(energy, E1, E2, E0) Fa = pyq2.utils.simx(Fa, orbs) Fb = pyq2.utils.simx(Fb, orbs) F = 0.5 * (Fa + Fb) K = Fb - Fa # Make explicit slice objects to simplify this do = slice(0, nbeta) so = slice(nbeta, nalpha) uo = slice(nalpha, norbs) F[do, do] -= K[do, do] F[uo, uo] += K[uo, uo] F[do, so] += 0.5 * K[do, so] F[so, do] += 0.5 * K[so, do] F[so, uo] -= 0.5 * K[so, uo] F[uo, so] -= 0.5 * K[uo, so] E, cmo = np.linalg.eigh(F) orbs = np.dot(orbs, cmo) return
def test_h4(self): h4 = molecule([ (1, 0.00000000, 0.00000000, 0.36628549), (1, 0.00000000, 0.00000000, -0.36628549), (1, 0.00000000, 4.00000000, 0.36628549), (1, 0.00000000, 4.00000000, -0.36628549), ], units='Angstrom') bfs = basisset(h4,'sto-3g') hamiltonian = rhf(bfs) iterator = SCFIterator(hamiltonian) iterator.converge() self.assertTrue(iterator.converged) self.assertAlmostEqual(iterator.energy, -2.234185358600, 7)
def __parseMolecule(val, units, charge, multiplicity): parts = [x.strip() for x in val.split(';')] if parts is None or len(parts) < 1: raise ACQUAChemistryError('Molecule format error: ' + val) geom = [] for n in range(len(parts)): part = parts[n] geom.append(__parseAtom(part)) if len(geom) < 1: raise ACQUAChemistryError('Molecule format error: ' + val) try: return molecule(geom, units=units, charge=charge, multiplicity=multiplicity) except Exception as exc: raise ACQUAChemistryError('Failed to create molecule') from exc
def pyq2_rohf(atomtuples=[(2,0,0,0)],basis = '6-31G**',maxit=10,xcname='svwn', mult=3): import pyquante2 as pyq2 print ("pyq2 ROHF run") geo = pyq2.molecule(atomtuples,multiplicity=mult) bfs = pyq2.basisset(geo,name=basis) i1 = pyq2.onee_integrals(bfs,geo) i2 = pyq2.twoe_integrals(bfs) h = i1.T + i1.V orbe,orbs = pyq2.geigh(h,i1.S) eold = 0 E0 = geo.nuclear_repulsion() nalpha,nbeta = geo.nup(),geo.ndown() norbs = len(bfs) for i in range(maxit): Da = pyq2.dmat(orbs,nalpha) Db = pyq2.dmat(orbs,nbeta) E1 = 0.5*pyq2.trace2(Da+Db,h) Ja,Ka = i2.get_j(Da),i2.get_k(Da) Jb,Kb = i2.get_j(Db),i2.get_k(Db) Fa = h + Ja + Jb - Ka Fb = h + Ja + Jb - Kb E2 = 0.5*(pyq2.trace2(Fa,Da)+pyq2.trace2(Fb,Db)) energy = E0+E1+E2 print (energy,E1,E2,E0) Fa = pyq2.utils.simx(Fa,orbs) Fb = pyq2.utils.simx(Fb,orbs) F = 0.5*(Fa+Fb) K = Fb-Fa # Make explicit slice objects to simplify this do = slice(0,nbeta) so = slice(nbeta,nalpha) uo = slice(nalpha,norbs) F[do,do] -= K[do,do] F[uo,uo] += K[uo,uo] F[do,so] += 0.5*K[do,so] F[so,do] += 0.5*K[so,do] F[so,uo] -= 0.5*K[so,uo] F[uo,so] -= 0.5*K[uo,so] E,cmo = np.linalg.eigh(F) orbs = np.dot(orbs,cmo) return
def test_makepyquante(self): # Test pyquante2 bridge from pyquante2 import molecule, rhf, h2o, basisset bfs = basisset(h2o) # Copied from water_ccsd.log refmol = molecule( [(8, 0.0, 0.0, 0.119159), (1, 0, 0.790649, -0.476637), (1, 0, -0.790649, -0.476637)], units="Angstroms", ) refsolver = rhf(refmol, bfs) refsolver.converge() pyqmol = cclib2pyquante.makepyquante(self.data) pyqsolver = rhf(pyqmol, bfs) pyqsolver.converge() assert_array_almost_equal(refsolver.energies[-1], pyqsolver.energies[-1], decimal=6)
def makepyquante(data): """Create a PyQuante Molecule from ccData object.""" _check_pyquante() # Check required attributes. required_attrs = {"atomcoords", "atomnos"} missing = [x for x in required_attrs if not hasattr(data, x)] if missing: missing = " ".join(missing) raise MissingAttributeError( "Could not create pyquante molecule due to missing attribute: {}". format(missing)) # For older PyQuante if _found_pyquante: # In PyQuante, molecular geometry is specified in a format of: # [(3,( .0000000000, .0000000000, .0000000000)), (1,( .0000000000, .0000000000,1.629912))] return Molecule( "notitle", [(data.atomnos[i], tuple(data.atomcoords[-1][i])) for i in range(len(data.atomnos))], units="Angstroms", charge=data.charge, multiplicity=data.mult, ) # For pyquante2 elif _found_pyquante2: # In pyquante2, molecular geometry is specified in a format of: # [(3,.0000000000, .0000000000, .0000000000), (1, .0000000000, .0000000000,1.629912)] moldesc = numpy.insert(data.atomcoords[-1], 0, data.atomnos, 1).tolist() return molecule( [tuple(x) for x in moldesc], units="Angstroms", charge=data.charge, multiplicity=data.mult, )
def _parse_molecule(val, units, charge, multiplicity): val = _check_molecule_format(val) parts = [x.strip() for x in val.split(';')] if parts is None or len(parts) < 1: # pylint: disable=len-as-condition raise QiskitChemistryError('Molecule format error: ' + val) geom = [] for n, _ in enumerate(parts): part = parts[n] geom.append(_parse_atom(part)) if len(geom) < 1: # pylint: disable=len-as-condition raise QiskitChemistryError('Molecule format error: ' + val) try: from pyquante2 import molecule # pylint: disable=import-error return molecule(geom, units=units, charge=charge, multiplicity=multiplicity) except Exception as exc: raise QiskitChemistryError('Failed to create molecule') from exc
def pyq2_dft(atomtuples=[(2, 0, 0, 0)], basis='6-31G**', maxit=10, xcname='svwn'): import pyquante2 as pyq2 print("pyq2 DFT run") geo = pyq2.molecule(atomtuples) bfs = pyq2.basisset(geo, name=basis) i1 = pyq2.onee_integrals(bfs, geo) i2 = pyq2.twoe_integrals(bfs) grid = pyq2.grid(geo) h = i1.T + i1.V orbe, orbs = pyq2.geigh(h, i1.S) eold = 0 grid.setbfamps(bfs) E0 = geo.nuclear_repulsion() for i in range(maxit): D = pyq2.dmat(orbs, geo.nocc()) E1 = 2 * pyq2.trace2(h, D) J = i2.get_j(D) Ej = 2 * pyq2.trace2(J, D) Exc, Vxc = pyq2.get_xc(grid, 0.5 * D, xcname=xcname) energy = E0 + E1 + Ej + Exc F = h + 2 * J + Vxc orbe, orbs = pyq2.geigh(F, i1.S) print(i, energy, E1, Ej, Exc, E0) if np.isclose(energy, eold): break eold = energy return energy
def test_he_triplet_lda(self): he_trip = molecule([(2, 0, 0, 0)], multiplicity=3) bfs = basisset(he_trip, '6-31G**') solver = dft(he_trip, bfs, 'lda') ens = solver.converge() self.assertAlmostEqual(solver.energy, -1.1784857927828982)
import unittest, logging import tables as tb from pyquante2 import molecule, rhf, basisset from pyquante2.geo.molecule import read_xyz from pyquante2.scf.iterators import AveragingIterator CH4 = molecule( [ (6, 0.000000000000, 0.000000000000, 0.000000000000), (1, 0.000000000000, -1.697250289185, -1.200137188939), (1, 1.697250289426, 0.000000000000, 1.200137188939), (1, -1.697250289426, -0.000000000000, 1.200137188939), (1, -0.000000000000, 1.697250289185, -1.200137188939), ], units="Bohr", name="CH4", ) class PyQuanteAssertions: def assertPrecisionEqual(self, a, b, prec=1e-8): x = abs(2 * (a - b) / (a + b)) if x > prec: raise AssertionError("%.9f is equal %.9f with precision %.9f)" % (a, b, x)) def hp5(filename, a): h5file = tb.open_file(filename, mode="w") atom = tb.Atom.from_dtype(a.dtype) ds = h5file.createCArray(h5file.root, "integrals", atom, a.shape) ds[:] = a
def test_h2_svwn(self): h2 = molecule([(1,0,0,-0.368),(1,0,0,0.368)],units='angs',nrad=50,do_sg1=False) bfs = basisset(h2,'sto3g') solver = dft(h2,bfs,'svwn') ens = solver.converge() self.assertAlmostEqual(solver.energy, -1.1212155284066108)
def test_he_triplet_lda(self): he_trip = molecule([(2,0,0,0)], multiplicity=3) bfs = basisset(he_trip,'6-31G**') solver = dft(he_trip,bfs,'lda') ens = solver.converge() self.assertAlmostEqual(solver.energy,-1.1784857927828982)
# a_ij = 0, b_ij = -c_i c_j If i and j are in the same pair for i in range(ncoresh+nopen,ncoresh+nopen+npair): a[i,i+npair] = a[i+npair,i] = 0 b[i,i+npair] = b[i+npair,i] = -coeffs[i]*coeffs[i+npair] return f,a,b if __name__ == '__main__': #import doctest; doctest.testmod() #gvb(h,maxiter=5,verbose=True) # -0.46658 #gvb(lih,maxiter=5,verbose=True) # -7.86073 #gvb(li,maxiter=5,verbose=True) # -7.3155 #gvb(h2,npair=1,verbose=True) # RHF = -1.1171, GVB ?= -1.1373 # # h- example for Rajib: Does not currently work with GVB. # RHF energy is -0.4224, GVB energy is -0.3964 h_m = molecule(atomlist = [(1,0,0,0)],charge=-1,name="H-") from pyquante2.orbman import orbman E,orbs = gvb(h_m,maxiter=10,basisname='6-31g',npair=0,verbose=True, return_orbs=True) o_hf = orbman(orbs,basisset(h_m,'6-31g'),h_m) E,orbs = gvb(h_m,maxiter=10,basisname='6-31g',npair=1,verbose=True, return_orbs=True,input_orbs=orbs) o_gvb = orbman(orbs,basisset(h_m,'6-31g'),h_m) for i in [0,1]: print("Orbital %d after HF" % i) o_hf[i] print(" GVB") o_gvb[i]
for i in range(ncoresh + nopen, ncoresh + nopen + npair): a[i, i + npair] = a[i + npair, i] = 0 b[i, i + npair] = b[i + npair, i] = -coeffs[i] * coeffs[i + npair] return f, a, b if __name__ == '__main__': #import doctest; doctest.testmod() #gvb(h,maxiter=5,verbose=True) # -0.46658 #gvb(lih,maxiter=5,verbose=True) # -7.86073 #gvb(li,maxiter=5,verbose=True) # -7.3155 #gvb(h2,npair=1,verbose=True) # RHF = -1.1171, GVB ?= -1.1373 # # h- example for Rajib: Does not currently work with GVB. # RHF energy is -0.4224, GVB energy is -0.3964 h_m = molecule(atomlist=[(1, 0, 0, 0)], charge=-1, name="H-") from pyquante2.orbman import orbman E, orbs = gvb(h_m, maxiter=10, basisname='6-31g', npair=0, verbose=True, return_orbs=True) o_hf = orbman(orbs, basisset(h_m, '6-31g'), h_m) E, orbs = gvb(h_m, maxiter=10, basisname='6-31g', npair=1, verbose=True, return_orbs=True, input_orbs=orbs)