def solve(mol, nel, cf_core, cf_gs, ImpOrbs, chempot=0., n_orth=0, FrozenPot=None): # cf_core : core orbitals (in AO basis, assumed orthonormal) # cf_gs : guess orbitals (in AO basis) # ImpOrbs : cf_gs -> impurity orbitals transformation # n_orth : number of orthonormal orbitals in cf_gs [1..n_orth] mol_ = gto.Mole() mol_.build(verbose=0) mol_.nelectron = nel mol_.incore_anyway = True cfx = cf_gs Sf = mol.intor_symmetric('cint1e_ovlp_sph') Hc = mol.intor_symmetric('cint1e_kin_sph') \ + mol.intor_symmetric('cint1e_nuc_sph') \ + FrozenPot occ = np.zeros((cfx.shape[1], )) occ[:nel / 2] = 2. # core contributions dm_core = np.dot(cf_core, cf_core.T) * 2 jk_core = scf.hf.get_veff(mol, dm_core) e_core = np.trace(np.dot(Hc, dm_core)) \ + 0.5*np.trace(np.dot(jk_core, dm_core)) # transform integrals Sp = np.dot(cfx.T, np.dot(Sf, cfx)) Hp = np.dot(cfx.T, np.dot(Hc, cfx)) jkp = np.dot(cfx.T, np.dot(jk_core, cfx)) intsp = ao2mo.outcore.full_iofree(mol, cfx) # orthogonalize cf [virtuals] cf = np.zeros((cfx.shape[1], ) * 2, ) if n_orth > 0: assert (n_orth <= cfx.shape[1]) assert (np.allclose(np.eye(n_orth), Sp[:n_orth, :n_orth])) else: n_orth = 0 cf[:n_orth, :n_orth] = np.eye(n_orth) if n_orth < cfx.shape[1]: val, vec = sla.eigh(-Sp[n_orth:, n_orth:]) idx = -val > 1.e-12 U = np.dot(vec[:,idx]*1./(np.sqrt(-val[idx])), \ vec[:,idx].T) cf[n_orth:, n_orth:] = U # define ImpOrbs projection Xp = np.dot(ImpOrbs, ImpOrbs.T) # Si = np.dot(ImpOrbs.T, np.dot(Sp, ImpOrbs)) # Mp = np.dot(ImpOrbs, np.dot(sla.inv(Si), ImpOrbs.T)) Np = np.dot(Sp, Xp) # print np.allclose(Np, np.dot(Np, np.dot(Mp, Np))) # HF calculation mol_.energy_nuc = lambda *args: mol.energy_nuc() + e_core mf = scf.RHF(mol_) #mf.verbose = 4 mf.mo_coeff = cf mf.mo_occ = occ mf.get_ovlp = lambda *args: Sp mf.get_hcore = lambda *args: Hp + jkp - 0.5 * chempot * (Np + Np.T) mf._eri = ao2mo.restore(8, intsp, cfx.shape[1]) nt = scf.newton(mf) #nt.verbose = 4 nt.max_cycle_inner = 1 nt.max_stepsize = 0.25 nt.ah_max_cycle = 32 nt.ah_start_tol = 1.0e-12 nt.ah_grad_trust_region = 1.0e8 nt.conv_tol_grad = 1.0e-6 nt.kernel() cf = nt.mo_coeff if not nt.converged: raise RuntimeError('hf failed to converge') mf.mo_coeff = nt.mo_coeff mf.mo_energy = nt.mo_energy mf.mo_occ = nt.mo_occ # MP2 solution mp2solver = mp.DFMP2(mf) mp2solver.verbose = 5 mp2solver.kernel() rdm1 = mp2solver.make_rdm1() rdm2 = mp2solver.make_rdm2() # transform rdm's to original basis tei = ao2mo.restore(1, intsp, cfx.shape[1]) rdm1 = np.dot(cf, np.dot(rdm1, cf.T)) rdm2 = np.einsum('ai,ijkl->ajkl', cf, rdm2) rdm2 = np.einsum('bj,ajkl->abkl', cf, rdm2) rdm2 = np.einsum('ck,abkl->abcl', cf, rdm2) rdm2 = np.einsum('dl,abcl->abcd', cf, rdm2) ImpEnergy = +0.25 *np.einsum('ij,jk,ki->', 2*Hp+jkp, rdm1, Xp) \ +0.25 *np.einsum('ij,jk,ki->', 2*Hp+jkp, Xp, rdm1) \ +0.125*np.einsum('ijkl,ijkm,ml->', tei, rdm2, Xp) \ +0.125*np.einsum('ijkl,ijml,mk->', tei, rdm2, Xp) \ +0.125*np.einsum('ijkl,imkl,mj->', tei, rdm2, Xp) \ +0.125*np.einsum('ijkl,mjkl,mi->', tei, rdm2, Xp) Nel = np.trace(np.dot(np.dot(rdm1, Sp), Xp)) return Nel, ImpEnergy
# Period 1 2 3 4 5 6 7 # level ANG_ORDER = numpy.array(( (11, 15, 17, 17, 17, 17, 17), # 0 (17, 23, 23, 23, 23, 23, 23), # 1 (23, 29, 29, 29, 29, 29, 29), # 2 (29, 29, 35, 35, 35, 35, 35), # 3 (35, 41, 41, 41, 41, 41, 41), # 4 (41, 47, 47, 47, 47, 47, 47), # 5 (47, 53, 53, 53, 53, 53, 53), # 6 (53, 59, 59, 59, 59, 59, 59), # 7 (59, 59, 59, 59, 59, 59, 59), # 8 (65, 65, 65, 65, 65, 65, 65), )) # 9 def prange(start, end, step): for i in range(start, end, step): yield i, min(i + step, end) if __name__ == '__main__': h2o = gto.Mole() h2o.verbose = 0 h2o.output = None #"out_h2o" h2o.atom = [['O', (0., 0., 0.)], ['H', (0., -0.757, 0.587)], ['H', (0., 0.757, 0.587)]] h2o.build() g = Grids(h2o) g.build() print(g.coords.shape)
def get_pp(mydf, kpts=None): mydf = _sync_mydf(mydf) cell = mydf.cell if kpts is None: kpts_lst = numpy.zeros((1,3)) else: kpts_lst = numpy.reshape(kpts, (-1,3)) if abs(kpts_lst).sum < 1e-9: dtype = numpy.float64 else: dtype = numpy.complex128 gs = mydf.gs SI = cell.get_SI() Gv = cell.get_Gv(gs) vpplocG = pseudo.get_vlocG(cell, Gv) vpplocG = -numpy.einsum('ij,ij->j', SI, vpplocG) vpplocG[0] = numpy.sum(pseudo.get_alphas(cell)) # from get_jvloc_G0 function ngs = len(vpplocG) nao = cell.nao_nr() # vpploc evaluated in real-space vpplocR = tools.ifft(vpplocG, cell.gs).real vpp = [lib.dot(aoR.T.conj()*vpplocR, aoR) for k, aoR in mydf.mpi_aoR_loop(gs, kpts_lst)] vpp = mpi.gather(lib.asarray(vpp, dtype=dtype)) # vppnonloc evaluated in reciprocal space fakemol = gto.Mole() fakemol._atm = numpy.zeros((1,gto.ATM_SLOTS), dtype=numpy.int32) fakemol._bas = numpy.zeros((1,gto.BAS_SLOTS), dtype=numpy.int32) ptr = gto.PTR_ENV_START fakemol._env = numpy.zeros(ptr+10) fakemol._bas[0,gto.NPRIM_OF ] = 1 fakemol._bas[0,gto.NCTR_OF ] = 1 fakemol._bas[0,gto.PTR_EXP ] = ptr+3 fakemol._bas[0,gto.PTR_COEFF] = ptr+4 # buf for SPG_lmi upto l=0..3 and nl=3 buf = numpy.empty((48,ngs), dtype=numpy.complex128) def vppnl_by_k(kpt): Gk = Gv + kpt G_rad = lib.norm(Gk, axis=1) aokG = ft_ao.ft_ao(cell, Gv, kpt=kpt) * (ngs/cell.vol) vppnl = 0 for ia in range(cell.natm): symb = cell.atom_symbol(ia) if symb not in cell._pseudo: continue pp = cell._pseudo[symb] p1 = 0 for l, proj in enumerate(pp[5:]): rl, nl, hl = proj if nl > 0: fakemol._bas[0,gto.ANG_OF] = l fakemol._env[ptr+3] = .5*rl**2 fakemol._env[ptr+4] = rl**(l+1.5)*numpy.pi**1.25 pYlm_part = dft.numint.eval_ao(fakemol, Gk, deriv=0) p0, p1 = p1, p1+nl*(l*2+1) # pYlm is real, SI[ia] is complex pYlm = numpy.ndarray((nl,l*2+1,ngs), dtype=numpy.complex128, buffer=buf[p0:p1]) for k in range(nl): qkl = pseudo.pp._qli(G_rad*rl, l, k) pYlm[k] = pYlm_part.T * qkl #:SPG_lmi = numpy.einsum('g,nmg->nmg', SI[ia].conj(), pYlm) #:SPG_lm_aoG = numpy.einsum('nmg,gp->nmp', SPG_lmi, aokG) #:tmp = numpy.einsum('ij,jmp->imp', hl, SPG_lm_aoG) #:vppnl += numpy.einsum('imp,imq->pq', SPG_lm_aoG.conj(), tmp) SPG_lmi = buf[:p1] SPG_lmi *= SI[ia].conj() SPG_lm_aoGs = lib.zdot(SPG_lmi, aokG) p1 = 0 for l, proj in enumerate(pp[5:]): rl, nl, hl = proj if nl > 0: p0, p1 = p1, p1+nl*(l*2+1) hl = numpy.asarray(hl) SPG_lm_aoG = SPG_lm_aoGs[p0:p1].reshape(nl,l*2+1,-1) tmp = numpy.einsum('ij,jmp->imp', hl, SPG_lm_aoG) vppnl += numpy.einsum('imp,imq->pq', SPG_lm_aoG.conj(), tmp) return vppnl * (1./ngs**2) vppnl = [] for kpt in mpi.static_partition(kpts_lst): vppnl.append(vppnl_by_k(kpt)) vppnl = mpi.gather(lib.asarray(vppnl, dtype=dtype)) if rank == 0: vpp += vppnl if kpts is None or numpy.shape(kpts) == (3,): vpp = vpp[0] return vpp
import copy import numpy from functools import reduce from pyscf import gto, lib from pyscf import scf, dft from pyscf import mp from pyscf import cc from pyscf import ao2mo from pyscf.cc import uccsd from pyscf.cc import gccsd from pyscf.cc import addons from pyscf.cc import uccsd_rdm from pyscf.fci import direct_uhf mol = gto.Mole() mol.verbose = 7 mol.output = '/dev/null' mol.atom = [[8, (0., 0., 0.)], [1, (0., -0.757, 0.587)], [1, (0., 0.757, 0.587)]] mol.basis = '631g' mol.build() rhf = scf.RHF(mol) rhf.conv_tol_grad = 1e-8 rhf.kernel() mf = scf.addons.convert_to_uhf(rhf) myucc = cc.UCCSD(mf).run(conv_tol=1e-10) mol_s2 = gto.Mole()
def build(eda, gjf, method): starttime = time.time() #xyznam = sys.argv[1] mol = gto.Mole() ##with open(xyznam) as f: # geom = f.read() mol.atom, coords, charges, mol.charge, mol.spin = gjf_kit.gjf_parser(gjf) if 'charge' in method: eda.bgchgs = (coords, charges) if eda.molchgs is None: logger.slog(eda.stdout, "Warning: center frag has no atomic charges") if 'qmmm' in method: eda.bgchgs = (coords, charges) mol.cart = ('cart' in method) mol.basis = method[1] #mol.symmetry = 1 mol.output = eda.output + '-pyscf.log' mol.verbose = eda.verbose mol.build() eda.mol = mol if method[0] == 'hf': mf = scf.RHF(mol) elif dft_kit.is_dft(method[0]): mf = dft.RKS(mol) mf.xc = method[0] if 'ultrafine' in method: mf.grids.atom_grid = (99, 590) if ('charge' in method) or ('qmmm' in method): mf = qmmm.mm_charge(mf, coords, charges, unit='au') mf.kernel() eda.mf = mf if 'force' in method: g = mf.Gradients() eda.force = g.grad() pyscf_time = time.time() #print("pyscf_time=",pyscf_time-starttime) eda.dm = mf.make_rdm1() eda.nao = len(eda.dm) eda.cart = mol.cart os.system("echo '' > " + eda.output + '-eda.log') eda.stdout = open(eda.output + '-eda.log', 'a') if eda.showinter: os.system("echo '' > " + eda.output + '-inter.log') eda.stdout_inter = open(eda.output + '-inter.log', 'a') #with open(self.output+'-eda.log','a') as f: logger.mlog(eda.stdout, "method,basis: ", eda.method) eda.atm2bas_f, eda.atm2bas_p = get_atm2bas(eda.mol) # _p: bas starts from 0 # _f: bas starts from 1 eda.bas2atm, eda.bas2atm_f = get_bas2atm(eda.atm2bas_f, eda.nao, eda.mol.natm) # atm starts from 0 # _f: atm starts from 1 if eda.showinter: if eda.frag_list is None: eda.get_frags() eda.bas2frg = get_bas2frg(eda.bas2atm, eda.frag_list) # frg starts from 1 eda.atm2frg = get_atm2frg(mol.natm, eda.frag_list) eda.nfrag = len(eda.frag_list) eda.ncap = 0 eda.capatoms = [] eda.frag2layer = {} for f in eda.frag_list: eda.frag2layer[f.label] = f.layer if f.layer == 'cap': eda.ncap += 1 eda.capatoms.append(f.atm_insub[0]) eda.capbas_p = [] eda.capbas_f = [] for i in eda.capatoms: eda.capbas_p.append(eda.atm2bas_p[i - 1]) eda.capbas_f.append(eda.atm2bas_f[i - 1]) if eda.verbose >= 6: logger.mlog(eda.stdout, "atm2bas_f", eda.atm2bas_f) logger.mlog(eda.stdout, "atm2bas_p", eda.atm2bas_p) #print(eda.bas2atm) logger.mlog(eda.stdout, "bas2atm", eda.bas2atm) if eda.showinter: logger.mlog(eda.stdout, "bas2frg", eda.bas2frg) logger.mlog(eda.stdout, "atm2frg", eda.atm2frg) logger.mlog(eda.stdout, "cap atoms", eda.capatoms) logger.mlog(eda.stdout, "cap basis_p", eda.capbas_p) eda.built = True return eda
# Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Author: Qiming Sun <*****@*****.**> # import unittest import numpy import copy from pyscf import lib, gto, scf, dft from pyscf import tdscf mol = gto.Mole() mol.verbose = 5 mol.output = '/dev/null' mol.atom = ''' O 0. 0. 0. H 0. -0.757 0.587 H 0. 0.757 0.587''' mol.spin = 2 mol.basis = '631g' mol.build() mol1 = gto.Mole() mol1.verbose = 0 mol1.atom = ''' O 0. 0. 0. H 0. -0.757 0.587
def init(self, molecule, charge, spin, basis_set, orb_basis='scf', cas=False, cas_nstart=None, cas_nstop=None, cas_nel=None, loc_nstart=None, loc_nstop=None): # {{{ import pyscf from pyscf import gto, scf, ao2mo, molden, lo pyscf.lib.num_threads( 1 ) #with degenerate states and multiple processors there can be issues #PYSCF inputs print(" ---------------------------------------------------------") print(" Using Pyscf:") print(" ---------------------------------------------------------") print(" ") mol = gto.Mole() mol.atom = molecule mol.max_memory = 1000 # MB mol.symmetry = True mol.charge = charge mol.spin = spin mol.basis = basis_set mol.build() print("symmertry") print(mol.topgroup) #SCF #mf = scf.RHF(mol).run(init_guess='atom') mf = scf.RHF(mol).run() #C = mf.mo_coeff #MO coeffs enu = mf.energy_nuc() print(mf.get_fock()) print(np.linalg.eig(mf.get_fock())[0]) if mol.symmetry == True: from pyscf import symm mo = symm.symmetrize_orb(mol, mf.mo_coeff) osym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo) #symm.addons.symmetrize_space(mol, mo, s=None, check=True, tol=1e-07) for i in range(len(osym)): print("%4d %8s %16.8f" % (i + 1, osym[i], mf.mo_energy[i])) #orbitals and lectrons n_orb = mol.nao_nr() n_b, n_a = mol.nelec nel = n_a + n_b self.n_orb = mol.nao_nr() json_mol = pyscf.gto.mole.dumps(mol) import json with open('data/mol.json', 'w') as fp: json.dump(json_mol, fp) if cas == True: cas_norb = cas_nstop - cas_nstart from pyscf import mcscf assert (cas_nstart != None) assert (cas_nstop != None) assert (cas_nel != None) else: cas_nstart = 0 cas_nstop = n_orb cas_nel = nel ##AO 2 MO Transformation: orb_basis or scf if orb_basis == 'scf': print("\nUsing Canonical Hartree Fock orbitals...\n") C = cp.deepcopy(mf.mo_coeff) print("C shape") print(C.shape) elif orb_basis == 'lowdin': assert (cas == False) S = mol.intor('int1e_ovlp_sph') print("Using lowdin orthogonalized orbitals") C = lowdin(S) #end elif orb_basis == 'boys': pyscf.lib.num_threads( 1 ) #with degenerate states and multiple processors there can be issues cl_c = mf.mo_coeff[:, :cas_nstart] cl_a = lo.Boys(mol, mf.mo_coeff[:, cas_nstart:cas_nstop]).kernel(verbose=4) cl_v = mf.mo_coeff[:, cas_nstop:] C = np.column_stack((cl_c, cl_a, cl_v)) elif orb_basis == 'boys2': pyscf.lib.num_threads( 1 ) #with degenerate states and multiple processors there can be issues cl_c = mf.mo_coeff[:, :loc_nstart] cl_a = lo.Boys(mol, mf.mo_coeff[:, loc_nstart:loc_nstop]).kernel(verbose=4) cl_v = mf.mo_coeff[:, loc_nstop:] C = np.column_stack((cl_c, cl_a, cl_v)) elif orb_basis == 'PM': pyscf.lib.num_threads( 1 ) #with degenerate states and multiple processors there can be issues cl_c = mf.mo_coeff[:, :cas_nstart] cl_a = lo.PM(mol, mf.mo_coeff[:, cas_nstart:cas_nstop]).kernel(verbose=4) cl_v = mf.mo_coeff[:, cas_nstop:] C = np.column_stack((cl_c, cl_a, cl_v)) elif orb_basis == 'PM2': pyscf.lib.num_threads( 1 ) #with degenerate states and multiple processors there can be issues cl_c = mf.mo_coeff[:, :loc_nstart] cl_a = lo.PM(mol, mf.mo_coeff[:, loc_nstart:loc_nstop]).kernel(verbose=4) cl_v = mf.mo_coeff[:, loc_nstop:] C = np.column_stack((cl_c, cl_a, cl_v)) elif orb_basis == 'ER': pyscf.lib.num_threads( 1 ) #with degenerate states and multiple processors there can be issues cl_c = mf.mo_coeff[:, :cas_nstart] cl_a = lo.PM(mol, mf.mo_coeff[:, cas_nstart:cas_nstop]).kernel(verbose=4) cl_v = mf.mo_coeff[:, cas_nstop:] C = np.column_stack((cl_c, cl_a, cl_v)) elif orb_basis == 'ER2': pyscf.lib.num_threads( 1 ) #with degenerate states and multiple processors there can be issues cl_c = mf.mo_coeff[:, :loc_nstart] cl_a = lo.ER(mol, mf.mo_coeff[:, loc_nstart:loc_nstop]).kernel(verbose=4) cl_v = mf.mo_coeff[:, loc_nstop:] C = np.column_stack((cl_c, cl_a, cl_v)) elif orb_basis == 'ibmo': loc_vstop = loc_nstop - n_a print(loc_vstop) mo_occ = mf.mo_coeff[:, mf.mo_occ > 0] mo_vir = mf.mo_coeff[:, mf.mo_occ == 0] c_core = mo_occ[:, :loc_nstart] iao_occ = lo.iao.iao(mol, mo_occ[:, loc_nstart:]) iao_vir = lo.iao.iao(mol, mo_vir[:, :loc_vstop]) c_out = mo_vir[:, loc_vstop:] # Orthogonalize IAO iao_occ = lo.vec_lowdin(iao_occ, mf.get_ovlp()) iao_vir = lo.vec_lowdin(iao_vir, mf.get_ovlp()) # # Method 1, using Knizia's alogrithm to localize IAO orbitals # ''' Generate IBOS from orthogonal IAOs ''' ibo_occ = lo.ibo.ibo(mol, mo_occ[:, loc_nstart:], iao_occ) ibo_vir = lo.ibo.ibo(mol, mo_vir[:, :loc_vstop], iao_vir) C = np.column_stack((c_core, ibo_occ, ibo_vir, c_out)) else: print("Error:NO orbital basis defined") molden.from_mo(mol, 'orbitals.molden', C) if cas == True: print(C.shape) print(cas_norb) print(cas_nel) mycas = mcscf.CASSCF(mf, cas_norb, cas_nel) h1e_cas, ecore = mycas.get_h1eff( mo_coeff=C) #core core orbs to form ecore and eff h2e_cas = ao2mo.kernel(mol, C[:, cas_nstart:cas_nstop], aosym='s4', compact=False).reshape(4 * ((cas_norb), )) print(h1e_cas) print(h1e_cas.shape) #return h1e_cas,h2e_cas,ecore,C,mol,mf self.h = h1e_cas self.g = h2e_cas self.ecore = ecore self.mf = mf self.mol = mol self.C = cp.deepcopy(C[:, cas_nstart:cas_nstop]) J, K = mf.get_jk() self.J = self.C.T @ J @ self.C self.K = self.C.T @ J @ self.C if 0: h = C.T.dot(mf.get_hcore()).dot(C) g = ao2mo.kernel(mol, C, aosym='s4', compact=False).reshape(4 * ((n_orb), )) const, heff = get_eff_for_casci(cas_nstart, cas_nstop, h, g) print(heff) print("const", const) print("ecore", ecore) self.h = heff self.g = g elif cas == False: h = C.T.dot(mf.get_hcore()).dot(C) g = ao2mo.kernel(mol, C, aosym='s4', compact=False).reshape(4 * ((n_orb), )) print(h) #return h, g, enu, C,mol,mf self.h = h self.g = g self.ecore = enu self.mf = mf self.mol = mol self.C = C J, K = mf.get_jk() self.J = self.C.T @ J @ self.C self.K = self.C.T @ J @ self.C
#! /usr/bin/env python from pyscf import scf # Nexus expands this with Mole info ### generated system text ### from pyscf import gto as gto_loc mol = gto_loc.Mole() mol.atom = ''' O 0.00000000 0.00000000 0.00000000 H 0.00000000 0.75716000 0.58626000 H 0.00000000 0.75716000 -0.58626000 ''' mol.basis = 'bfd-vtz' mol.unit = 'A' mol.ecp = 'bfd' mol.charge = 0 mol.spin = 0 mol.symmetry = True mol.build() ### end generated system text ### mf = scf.RHF(mol) mf.kernel()
def init_guess_by_minao(mol): '''Generate initial guess density matrix based on ANO basis, then project the density matrix to the basis set defined by ``mol`` Returns: Density matrix, 2D ndarray Examples: >>> from pyscf import gto, scf >>> mol = gto.M(atom='H 0 0 0; H 0 0 1.1') >>> scf.hf.init_guess_by_minao(mol) array([[ 0.94758917, 0.09227308], [ 0.09227308, 0.94758917]]) ''' from pyscf.scf import atom_hf from pyscf.scf import addons def minao_basis(symb, nelec_ecp): basis_add = gto.basis.load('ano', symb) occ = [] basis_new = [] # coreshl defines the core shells to be removed in the initial guess coreshl = gto.ecp.core_configuration(nelec_ecp) #coreshl = (0,0,0,0) # it keeps all core electrons in the initial guess for l in range(4): ndocc, nfrac = atom_hf.frac_occ(symb, l) if coreshl[l] > 0: occ.extend([0] * coreshl[l] * (2 * l + 1)) if ndocc > coreshl[l]: occ.extend([2] * (ndocc - coreshl[l]) * (2 * l + 1)) if nfrac > 1e-15: occ.extend([nfrac] * (2 * l + 1)) ndocc += 1 if ndocc > 0: basis_new.append([l] + [b[:ndocc + 1] for b in basis_add[l][1:]]) return occ, basis_new atmlst = set([mol.atom_symbol(ia) for ia in range(mol.natm)]) nelec_ecp_dic = {} for ia in range(mol.natm): symb = mol.atom_symbol(ia) if symb not in nelec_ecp_dic: nelec_ecp_dic[symb] = mol.atom_nelec_core(ia) basis = {} occdic = {} for symb in atmlst: if symb != 'GHOST': nelec_ecp = nelec_ecp_dic[symb] stdsymb = gto.mole._std_symbol(symb) occ_add, basis_add = minao_basis(stdsymb, nelec_ecp) occdic[symb] = occ_add basis[symb] = basis_add occ = [] new_atom = [] for ia in range(mol.natm): symb = mol.atom_symbol(ia) if symb != 'GHOST': occ.append(occdic[symb]) new_atom.append(mol._atom[ia]) occ = numpy.hstack(occ) pmol = gto.Mole() pmol._atm, pmol._bas, pmol._env = pmol.make_env(new_atom, basis, []) c = addons.project_mo_nr2nr(pmol, 1, mol) dm = numpy.dot(c * occ, c.T) # normalize eletron number # s = mol.intor_symmetric('cint1e_ovlp_sph') # dm *= mol.nelectron / (dm*s).sum() return dm
def load(moldenfile): '''Extract mol and orbitals from molden file ''' mol = gto.Mole() with open(moldenfile, 'r') as f: line = first_token(f, '[Atoms]') if 'ANG' in line.upper(): unit = 1 else: unit = lib.param.BOHR atoms = [] line = f.readline() while line: if '[GTO]' in line: break dat = line.split() symb, atmid, chg = dat[:3] coord = numpy.array([float(x) for x in dat[3:]]) * unit atoms.append((gto.mole._std_symbol(symb) + atmid, coord)) line = f.readline() mol.atom = atoms def read_one_bas(lsym, nb, fac): fac = float(fac) bas = [ lib.param.ANGULARMAP[lsym], ] for i in range(int(nb)): dat = _d2e(f.readline()).split() bas.append((float(dat[0]), float(dat[1]) * fac)) return bas basis = {} line = f.readline() # Be careful with the atom sequence in [GTO] session, it does not correspond # to the atom sequence in [Atoms] session. atom_seq = [] while line: if '[' in line: break dat = line.split() if len(dat) == 0: pass elif dat[0].isdigit(): atom_seq.append(int(dat[0]) - 1) symb = mol.atom[int(dat[0]) - 1][0] basis[symb] = [] elif dat[0] in 'spdfghij': lsym, nb, fac = dat basis[symb].append(read_one_bas(lsym, nb, fac)) line = f.readline() mol.basis = basis mol.atom = [mol.atom[i] for i in atom_seq] mol.cart = True while line: if '[5d]' in line or '[9g]' in line: mol.cart = False elif '[core]' in line: line = f.readline() while line: dat = line.split(':') if dat[0].strip().isdigit(): atm_id = int(dat[0].strip()) - 1 nelec_core = int(dat[1].strip()) mol.ecp[atoms[atm_id][0]] = [nelec_core, []] elif '[MO]' in line: break line = f.readline() if '[MO]' in line: break line = f.readline() if mol.ecp: sys.stderr.write( '\nECP were dectected in the molden file.\n' 'Note Molden format does not support ECP data. ' 'ECP information was lost when saving to molden format.\n\n') try: mol.build(0, 0) except RuntimeError: mol.build(0, 0, spin=1) data = f.read() data = data.split('Sym')[1:] irrep_labels = [] mo_energy = [] spins = [] mo_occ = [] mo_coeff = [] norb_alpha = -1 for rawd in data: lines = rawd.split('\n') irrep_labels.append(lines[0].split('=')[1].strip()) orb = [] for line in lines[1:]: if line.strip() == '': continue elif 'Ene' in line: mo_energy.append(float(_d2e(line).split('=')[1].strip())) elif 'Spin' in line: spins.append(line.split('=')[1].strip()) elif 'Occ' in line: mo_occ.append(float(_d2e(line.split('=')[1].strip()))) elif '[MO]' in line: norb_alpha = len(mo_energy) else: orb.append(float(_d2e(line.split()[1]))) mo_coeff.append(orb) mo_energy = numpy.array(mo_energy) mo_occ = numpy.array(mo_occ) if mol.cart: aoidx = numpy.argsort(order_ao_index(mol, cart=True)) mo_coeff = (numpy.array(mo_coeff).T)[aoidx] # AO are assumed to be normalized in molpro molden file s = mol.intor('int1e_ovlp') mo_coeff = numpy.einsum('i,ij->ij', numpy.sqrt(1 / s.diagonal()), mo_coeff) else: aoidx = numpy.argsort(order_ao_index(mol)) mo_coeff = (numpy.array(mo_coeff).T)[aoidx] if norb_alpha > 0: irrep_labels = (irrep_labels[:norb_alpha], irrep_labels[norb_alpha:]) spins = (spins[:norb_alpha], spins[norb_alpha:]) mo_energy = (mo_energy[:norb_alpha], mo_energy[norb_alpha:]) mo_occ = (mo_occ[:norb_alpha], mo_occ[norb_alpha:]) mo_coeff = (mo_coeff[:, :norb_alpha], mo_coeff[:, norb_alpha:]) return mol, mo_energy, mo_coeff, mo_occ, irrep_labels, spins
def main(): functionals = ['LDA,PW_MOD', 'PBE,PBE'] systems = { "H": { 'name': 'Hydrogen', 'symbol': 'H', 'spin': 1, 'positions': [[0., 0., 0.]] }, "Li": { 'name': 'Lithium', 'symbol': 'Li', 'spin': 1, 'positions': [[0., 0., 0.]] }, "O": { 'name': 'Oxygen', 'symbol': 'O', 'spin': 2, 'positions': [[0., 0., 0.]] }, "Ar": { 'name': 'Argon', 'symbol': 'Ar', 'spin': 0, 'positions': [[0., 0., 0.]] } } kskernel = kernel.KSKernel() for key in systems: system = systems[key] print( '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' ) print(system['name'] + ' 0.0 0.0 0.0') coords = system['symbol'] + ' 0.0 0.0 0.0' mol = gto.Mole() mol.atom = coords mol.basis = '../basis/6-311+g2dp.nw' mol.cart = True mol.spin = system['spin'] mol.charge = 0 mol.build() kskernel.CalculateKSKernel(mol) print('E = {:.12e}\tX = {:.12e}\tC = {:.12e}\tXC = {:.12e}'.format( kskernel.mf.e_tot, 0.0, 0.0, kskernel.mf.get_veff().exc)) exks = ExKS(mol, kskernel, 'exks,') x = exks.CalculateTotalX() c = exks.CalculateTotalC() xc = exks.CalculateTotalXC() e = exks.CalculateTotalEnergy() print('E = {:.12e}\tX = {:.12e}\tC = {:.12e}\tXC = {:.12e}'.format( e, x, c, xc)) lsd = DFA(mol, kskernel, 'LDA,PW_MOD') x = lsd.CalculateTotalX() c = lsd.CalculateTotalC() xc = lsd.CalculateTotalXC() e = lsd.CalculateTotalEnergy() print('E = {:.12e}\tX = {:.12e}\tC = {:.12e}\tXC = {:.12e}'.format( e, x, c, xc)) pbe = DFA(mol, kskernel, 'PBE,PBE') x = pbe.CalculateTotalX() c = pbe.CalculateTotalC() xc = pbe.CalculateTotalXC() e = pbe.CalculateTotalEnergy() print('E = {:.12e}\tX = {:.12e}\tC = {:.12e}\tXC = {:.12e}'.format( e, x, c, xc))
def sdf_to_dict(sdf_path, mode="orbital"): with open(sdf_path, "r") as f: sdf_string = f.read() mol_sdf = Chem.MolFromMolBlock(sdf_string, removeHs=False) # -- Atomic Feature atm_dict = {} atm_coord = mol_sdf.GetConformers()[0].GetPositions() / lib.param.BOHR atm_dist = np.linalg.norm(atm_coord[None, :, :] - atm_coord[:, None, :], axis=-1) atm_charge = np.array([atm.GetAtomicNum() for atm in mol_sdf.GetAtoms()]) atm_addcharge = np.array( [atm.GetFormalCharge() for atm in mol_sdf.GetAtoms()]) atm_nuceng_adaj = atm_dist + np.diag(np.ones(atm_dist.shape[0]) * np.inf) atm_nuceng_adaj = (atm_charge[None, :] * atm_charge[:, None]) / atm_nuceng_adaj atm_symbol = np.array([atm.GetSymbol() for atm in mol_sdf.GetAtoms()]) atm_symbol_onehot = [] for symbol in atm_symbol: atm_symbol_onehot.append([ 1 if symbol == x else 0 for x in ['H', 'C', 'N', 'O', 'F', 'S', 'Cl'] ]) atm_symbol_onehot = np.array(atm_symbol_onehot) # Emperical descriptors atm_aromatic = np.array( [int(atm.GetIsAromatic()) for atm in mol_sdf.GetAtoms()]) atm_hybrid = np.array([[ int(atm.GetHybridization() == x) for x in (Chem.rdchem.HybridizationType.SP, Chem.rdchem.HybridizationType.SP2, Chem.rdchem.HybridizationType.SP3) ] for atm in mol_sdf.GetAtoms()]) natm = mol_sdf.GetNumAtoms() atm_edge_type = np.zeros((5, natm, natm)) for i in range(natm): for j in range(natm): e_ij = mol_sdf.GetBondBetweenAtoms(i, j) if e_ij is None: continue edge_type_vect = (e_ij.GetBondType() == np.array([ Chem.rdchem.BondType.SINGLE, Chem.rdchem.BondType.DOUBLE, Chem.rdchem.BondType.TRIPLE, Chem.rdchem.BondType.AROMATIC, 0 ])) if edge_type_vect.sum() == 0: edge_type_vect[4] = 1 atm_edge_type[:, i, j] = edge_type_vect atm_dict[ "atm_coord"] = atm_coord # Atomic position, unit Bohr, for backup (natm, 3) atm_dict[ "atm_dist"] = atm_dist # Atomic distance matrix, unit in Bohr (natm, natm) atm_dict["atm_charge"] = atm_charge # Atom charges, unit a.u. (natm, ) atm_dict[ "atm_nuceng_adaj"] = atm_nuceng_adaj # Nuculeu repulsion energy matrix, unit Eh (natm, natm) atm_dict[ "atm_symbol_onehot"] = atm_symbol_onehot # Atom name in one-hot encoding (natm, 7) atm_dict[ "atm_addcharge"] = atm_addcharge # WARNING: emperical value # Additional charge on atom (natm, ) atm_dict[ "atm_aromatic"] = atm_aromatic # WARNING: emperical value # Whether atom is aromatic (natm, ) atm_dict[ "atm_hybrid"] = atm_hybrid # WARNING: emperical value # Atom hybrid type (natm, 3) atm_dict[ "atm_edge_type"] = atm_edge_type # WARNING: emperical value # Edge type (5, natm, natm) if mode == "atom": return atm_dict, None # -- Electronic Feature ao_dict = {} # construct molecule mol_list = [] for atm, coord in zip(atm_symbol, atm_coord): atm_row = [atm] + [str(f) for f in coord.tolist()] mol_list.append(" ".join(atm_row)) mol = gto.Mole() mol.atom = "\n".join(mol_list) mol.charge = atm_addcharge.sum() mol.basis = "STO-3G" mol.build() assert (mol.nelec[0] == mol.nelec[1]) nocc = mol.nelec[0] # integrals S = mol.intor("int1e_ovlp") T = mol.intor("int1e_kin") V = mol.intor("int1e_nuc") P = mol.intor("int1e_r") # guess density e, C = scipy.linalg.eigh(T + V, S) D = C[:, :nocc] @ C[:, :nocc].T * 2 # ao feature / definition ao_idx = np.zeros(mol.nao) ao_atomchg = np.zeros(mol.nao) ao_atomhot = np.zeros((mol.nao, 7)) ao_zeta = np.zeros(mol.nao) ao_valence = np.zeros(mol.nao) ao_momentum = np.zeros(mol.nao) ao_spacial_x = np.zeros(mol.nao) ao_spacial_y = np.zeros(mol.nao) ao_spacial_z = np.zeros(mol.nao) ao_coord = np.zeros((mol.nao, 3)) ao_dist = np.zeros((mol.nao, mol.nao)) for atm, aoslice in zip(range(mol.natm), mol.aoslice_by_atom()): atm_symbol = mol.atom_symbol(atm) _, _, p0, p1 = aoslice ao_idx[p0:p1] = atm ao_atomchg[p0:p1] = mol.atom_charge(atm) ao_atomhot[p0:p1] = [ 1 if atm_symbol == x else 0 for x in ['H', 'C', 'N', 'O', 'F', 'S', 'Cl'] ] ao_coord[p0:p1] = mol.atom_coord(atm) ao_zeta[p0:p1], ao_valence[p0:p1] = slater_zeta_valance[atm_symbol] for atm2, aoslice2 in zip(range(mol.natm), mol.aoslice_by_atom()): _, _, p20, p21 = aoslice2 ao_dist[p0:p1, p20:p21] = np.linalg.norm( mol.atom_coord(atm) - mol.atom_coord(atm2)) ao_momentum[mol.search_ao_label("p")] = 1 ao_spacial_x[mol.search_ao_label("x")] = 1 ao_spacial_y[mol.search_ao_label("y")] = 1 ao_spacial_z[mol.search_ao_label("z")] = 1 # merge in ao_dict ao_dict["nelec"] = mol.nelec[0] * 2 ao_dict["int1e_ovlp"] = S ao_dict["int1e_kin"] = T ao_dict["int1e_nuc"] = V ao_dict["int1e_r"] = P ao_dict["rdm1e"] = D ao_dict["ao_idx"] = ao_idx ao_dict["ao_atomchg"] = ao_atomchg ao_dict["ao_atomhot"] = ao_atomhot ao_dict["ao_zeta"] = ao_zeta ao_dict["ao_valence"] = ao_valence # WARNING: emperical value ao_dict["ao_momentum"] = ao_momentum ao_dict["ao_spacial_x"] = ao_spacial_x ao_dict["ao_spacial_y"] = ao_spacial_y ao_dict["ao_spacial_z"] = ao_spacial_z ao_dict["ao_coord"] = ao_coord ao_dict["ao_dist"] = ao_dist return atm_dict, ao_dict
def solve(frag, guess_1RDM, chempot_imp): # Augment OEI with the chemical potential OEI = frag.impham_OEI_C - chempot_imp # Do I need to get the full RHF solution? guess_orbs_av = len(frag.imp_cache) == 2 or frag.norbs_as > 0 # Get the RHF solution mol = gto.Mole() abs_2MS = int(round(2 * abs(frag.target_MS))) abs_2S = int(round(2 * abs(frag.target_S))) sign_MS = np.sign(frag.target_MS) or 1 mol.spin = abs_2MS mol.verbose = 0 if frag.mol_output is None else lib.logger.DEBUG mol.output = frag.mol_output mol.atom.append(('H', (0, 0, 0))) mol.nelectron = frag.nelec_imp if frag.enforce_symmetry: mol.groupname = frag.symmetry mol.symm_orb = get_subspace_symmetry_blocks(frag.loc2imp, frag.loc2symm) mol.irrep_name = frag.ir_names mol.irrep_id = frag.ir_ids mol.build() if frag.enforce_symmetry: mol.symmetry = True #mol.incore_anyway = True mf = scf.RHF(mol) mf.get_hcore = lambda *args: OEI mf.get_ovlp = lambda *args: np.eye(frag.norbs_imp) mf.energy_nuc = lambda *args: frag.impham_CONST if frag.impham_CDERI is not None: mf = mf.density_fit() mf.with_df._cderi = frag.impham_CDERI else: mf._eri = ao2mo.restore(8, frag.impham_TEI, frag.norbs_imp) mf = fix_my_RHF_for_nonsinglet_env(mf, sign_MS * frag.impham_OEI_S) mf.__dict__.update(frag.mf_attr) if guess_orbs_av: mf.max_cycle = 2 mf.scf(guess_1RDM) if (not mf.converged) and (not guess_orbs_av): if np.any(np.abs(frag.impham_OEI_S) > 1e-8) and mol.spin != 0: raise NotImplementedError( 'Gradient and Hessian fixes for nonsinglet environment of Newton-descent ROHF algorithm' ) print( "CASSCF RHF-step not converged on fixed-point iteration; initiating newton solver" ) mf = mf.newton() mf.kernel() # Instability check and repeat if not guess_orbs_av: for i in range(frag.num_mf_stab_checks): if np.any(np.abs(frag.impham_OEI_S) > 1e-8) and mol.spin != 0: raise NotImplementedError( 'ROHF stability-check fixes for nonsinglet environment') mf.mo_coeff = mf.stability()[0] guess_1RDM = mf.make_rdm1() mf = scf.RHF(mol) mf.get_hcore = lambda *args: OEI mf.get_ovlp = lambda *args: np.eye(frag.norbs_imp) mf._eri = ao2mo.restore(8, frag.impham_TEI, frag.norbs_imp) mf = fix_my_RHF_for_nonsinglet_env(mf, sign_MS * frag.impham_OEI_S) mf.scf(guess_1RDM) if not mf.converged: mf = mf.newton() mf.kernel() E_RHF = mf.e_tot print("CASSCF RHF-step energy: {}".format(E_RHF)) # Get the CASSCF solution CASe = frag.active_space[0] CASorb = frag.active_space[1] checkCAS = (CASe <= frag.nelec_imp) and (CASorb <= frag.norbs_imp) if (checkCAS == False): CASe = frag.nelec_imp CASorb = frag.norbs_imp if (abs_2MS > abs_2S): CASe = ((CASe + abs_2S) // 2, (CASe - abs_2S) // 2) else: CASe = ((CASe + abs_2MS) // 2, (CASe - abs_2MS) // 2) if frag.impham_CDERI is not None: mc = mcscf.DFCASSCF(mf, CASorb, CASe) else: mc = mcscf.CASSCF(mf, CASorb, CASe) smult = abs_2S + 1 if frag.target_S is not None else (frag.nelec_imp % 2) + 1 mc.fcisolver = csf_solver(mf.mol, smult, symm=frag.enforce_symmetry) if frag.enforce_symmetry: mc.fcisolver.wfnsym = frag.wfnsym mc.max_cycle_macro = 50 if frag.imp_maxiter is None else frag.imp_maxiter mc.ah_start_tol = 1e-10 mc.ah_conv_tol = 1e-10 mc.conv_tol = 1e-9 mc.__dict__.update(frag.corr_attr) mc = fix_my_CASSCF_for_nonsinglet_env(mc, sign_MS * frag.impham_OEI_S) norbs_amo = mc.ncas norbs_cmo = mc.ncore norbs_imo = frag.norbs_imp - norbs_amo nelec_amo = sum(mc.nelecas) norbs_occ = norbs_amo + norbs_cmo #mc.natorb = True # Guess orbitals ci0 = None dm_imp = frag.get_oneRDM_imp() fock_imp = mf.get_fock(dm=dm_imp) if len(frag.imp_cache) == 2: imp2mo, ci0 = frag.imp_cache print("Taking molecular orbitals and ci vector from cache") elif frag.norbs_as > 0: nelec_imp_guess = int(round(np.trace(frag.oneRDMas_loc))) norbs_cmo_guess = (frag.nelec_imp - nelec_imp_guess) // 2 print( "Projecting stored amos (frag.loc2amo; spanning {} electrons) onto the impurity basis and filling the remainder with default guess" .format(nelec_imp_guess)) imp2mo, my_occ = project_amo_manually(frag.loc2imp, frag.loc2amo, fock_imp, norbs_cmo_guess, dm=frag.oneRDMas_loc) elif frag.loc2amo_guess is not None: print( "Projecting stored amos (frag.loc2amo_guess) onto the impurity basis (no amo dm available)" ) imp2mo, my_occ = project_amo_manually(frag.loc2imp, frag.loc2amo_guess, fock_imp, norbs_cmo, dm=None) frag.loc2amo_guess = None else: dm_imp = np.asarray(mf.make_rdm1()) while dm_imp.ndim > 2: dm_imp = dm_imp.sum(0) imp2mo = mf.mo_coeff fock_imp = mf.get_fock(dm=dm_imp) fock_mo = represent_operator_in_basis(fock_imp, imp2mo) _, evecs = matrix_eigen_control_options(fock_mo, sort_vecs=1) imp2mo = imp2mo @ evecs my_occ = ((dm_imp @ imp2mo) * imp2mo).sum(0) print( "No stored amos; using mean-field canonical MOs as initial guess") # Guess orbital processing if callable(frag.cas_guess_callback): mo = reduce(np.dot, (frag.ints.ao2loc, frag.loc2imp, imp2mo)) mo = frag.cas_guess_callback(frag.ints.mol, mc, mo) imp2mo = reduce(np.dot, (frag.imp2loc, frag.ints.ao2loc.conjugate().T, frag.ints.ao_ovlp, mo)) frag.cas_guess_callback = None # Guess CI vector if len(frag.imp_cache) != 2 and frag.ci_as is not None: loc2amo_guess = np.dot(frag.loc2imp, imp2mo[:, norbs_cmo:norbs_occ]) gOc = np.dot(loc2amo_guess.conjugate().T, frag.ci_as_orb) umat_g, svals, umat_c = matrix_svd_control_options( gOc, sort_vecs=-1, only_nonzero_vals=True) if (svals.size == norbs_amo): print( "Loading ci guess despite shifted impurity orbitals; singular value sum: {}" .format(np.sum(svals))) imp2mo[:, norbs_cmo:norbs_occ] = np.dot( imp2mo[:, norbs_cmo:norbs_occ], umat_g) ci0 = transform_ci_for_orbital_rotation(frag.ci_as, CASorb, CASe, umat_c) else: print( "Discarding stored ci guess because orbitals are too different (missing {} nonzero svals)" .format(norbs_amo - svals.size)) # Symmetry align if possible imp2mo[:, :norbs_cmo] = frag.align_imporbs_symm( imp2mo[:, :norbs_cmo], sorting_metric=fock_imp, sort_vecs=1, orbital_type='guess inactive', mol=mol)[0] imp2mo[:, norbs_cmo:norbs_occ], umat = frag.align_imporbs_symm( imp2mo[:, norbs_cmo:norbs_occ], sorting_metric=fock_imp, sort_vecs=1, orbital_type='guess active', mol=mol) imp2mo[:, norbs_occ:] = frag.align_imporbs_symm(imp2mo[:, norbs_occ:], sorting_metric=fock_imp, sort_vecs=1, orbital_type='guess external', mol=mol)[0] if frag.enforce_symmetry: imp2mo = cleanup_subspace_symmetry(imp2mo, mol.symm_orb) err_symm = measure_subspace_blockbreaking(imp2mo, mol.symm_orb) err_orth = measure_basis_nonorthonormality(imp2mo) print("Initial symmetry error after cleanup = {}".format(err_symm)) print( "Initial orthonormality error after cleanup = {}".format(err_orth)) if ci0 is not None: ci0 = transform_ci_for_orbital_rotation(ci0, CASorb, CASe, umat) # Guess orbital printing if frag.mfmo_printed == False: ao2mfmo = reduce(np.dot, [frag.ints.ao2loc, frag.loc2imp, imp2mo]) print("Writing {} {} orbital molden".format(frag.frag_name, 'CAS guess')) molden.from_mo(frag.ints.mol, frag.filehead + frag.frag_name + '_mfmorb.molden', ao2mfmo, occ=my_occ) frag.mfmo_printed = True elif len( frag.active_orb_list ) > 0: # This is done AFTER everything else so that the _mfmorb.molden always has consistent ordering print('Applying caslst: {}'.format(frag.active_orb_list)) imp2mo = mc.sort_mo(frag.active_orb_list, mo_coeff=imp2mo) frag.active_orb_list = [] if len(frag.frozen_orb_list) > 0: mc.frozen = copy.copy(frag.frozen_orb_list) print("Applying frozen-orbital list (this macroiteration only): {}". format(frag.frozen_orb_list)) frag.frozen_orb_list = [] if frag.enforce_symmetry: imp2mo = lib.tag_array(imp2mo, orbsym=label_orb_symm(mol, mol.irrep_id, mol.symm_orb, imp2mo, s=mf.get_ovlp(), check=False)) t_start = time.time() E_CASSCF = mc.kernel(imp2mo, ci0)[0] if not mc.converged: print('Restarting another firstorder mc solver...') imp2mo = mc.mo_coeff.copy() mc = mcscf.CASSCF(mf, CASorb, CASe) mc.max_cycle_macro = 50 if frag.imp_maxiter is None else frag.imp_maxiter smult = abs_2S + 1 if frag.target_S is not None else (frag.nelec_imp % 2) + 1 mc.fcisolver = csf_solver(mf.mol, smult) E_CASSCF = mc.kernel(imp2mo)[0] if not mc.converged: if np.any(np.abs(frag.impham_OEI_S) > 1e-8): raise NotImplementedError( 'Gradient and Hessian fixes for nonsinglet environment of Newton-descent CASSCF algorithm' ) mc = mc.newton() E_CASSCF = mc.kernel(mc.mo_coeff, mc.ci)[0] if not mc.converged: print('Assuming ci vector is poisoned; discarding...') imp2mo = mc.mo_coeff.copy() mc = mcscf.CASSCF(mf, CASorb, CASe) smult = abs_2S + 1 if frag.target_S is not None else ( frag.nelec_imp % 2) + 1 mc.fcisolver = csf_solver(mf.mol, smult) E_CASSCF = mc.kernel(imp2mo)[0] assert (mc.converged) ''' mc.conv_tol = 1e-12 mc.ah_start_tol = 1e-10 mc.ah_conv_tol = 1e-12 E_CASSCF = mc.kernel(mc.mo_coeff, mc.ci)[0] if not mc.converged: mc = mc.newton () E_CASSCF = mc.kernel(mc.mo_coeff, mc.ci)[0] #assert (mc.converged) ''' # Get twoRDM + oneRDM. cs: MC-SCF core, as: MC-SCF active space # I'm going to need to keep some representation of the active-space orbitals # Symmetry align if possible oneRDM_amo, twoRDM_amo = mc.fcisolver.make_rdm12(mc.ci, mc.ncas, mc.nelecas) fock_imp = mc.get_fock() mc.mo_coeff[:, :norbs_cmo] = frag.align_imporbs_symm( mc.mo_coeff[:, :norbs_cmo], sorting_metric=fock_imp, sort_vecs=1, orbital_type='optimized inactive', mol=mol)[0] mc.mo_coeff[:, norbs_cmo:norbs_occ], umat = frag.align_imporbs_symm( mc.mo_coeff[:, norbs_cmo:norbs_occ], sorting_metric=oneRDM_amo, sort_vecs=-1, orbital_type='optimized active', mol=mol) mc.mo_coeff[:, norbs_occ:] = frag.align_imporbs_symm( mc.mo_coeff[:, norbs_occ:], sorting_metric=fock_imp, sort_vecs=1, orbital_type='optimized external', mol=mol)[0] if frag.enforce_symmetry: amo2imp = mc.mo_coeff[:, norbs_cmo:norbs_occ].conjugate().T mc.mo_coeff = cleanup_subspace_symmetry(mc.mo_coeff, mol.symm_orb) umat = umat @ (amo2imp @ mc.mo_coeff[:, norbs_cmo:norbs_occ]) err_symm = measure_subspace_blockbreaking(mc.mo_coeff, mol.symm_orb) err_orth = measure_basis_nonorthonormality(mc.mo_coeff) print("Final symmetry error after cleanup = {}".format(err_symm)) print("Final orthonormality error after cleanup = {}".format(err_orth)) mc.ci = transform_ci_for_orbital_rotation(mc.ci, CASorb, CASe, umat) # Cache stuff imp2mo = mc.mo_coeff #mc.cas_natorb()[0] loc2mo = np.dot(frag.loc2imp, imp2mo) imp2amo = imp2mo[:, norbs_cmo:norbs_occ] loc2amo = loc2mo[:, norbs_cmo:norbs_occ] frag.imp_cache = [mc.mo_coeff, mc.ci] frag.ci_as = mc.ci frag.ci_as_orb = loc2amo.copy() t_end = time.time() # oneRDM oneRDM_imp = mc.make_rdm1() # twoCDM oneRDM_amo, twoRDM_amo = mc.fcisolver.make_rdm12(mc.ci, mc.ncas, mc.nelecas) oneRDMs_amo = np.stack(mc.fcisolver.make_rdm1s(mc.ci, mc.ncas, mc.nelecas), axis=0) oneSDM_amo = oneRDMs_amo[0] - oneRDMs_amo[ 1] if frag.target_MS >= 0 else oneRDMs_amo[1] - oneRDMs_amo[0] oneSDM_imp = represent_operator_in_basis(oneSDM_amo, imp2amo.conjugate().T) print("Norm of spin density: {}".format(linalg.norm(oneSDM_amo))) # Note that I do _not_ do the *real* cumulant decomposition; I do one assuming oneSDM_amo = 0. # This is fine as long as I keep it consistent, since it is only in the orbital gradients for this impurity that # the spin density matters. But it has to stay consistent! twoCDM_amo = get_2CDM_from_2RDM(twoRDM_amo, oneRDM_amo) twoCDM_imp = represent_operator_in_basis(twoCDM_amo, imp2amo.conjugate().T) print( 'Impurity CASSCF energy (incl chempot): {}; spin multiplicity: {}; time to solve: {}' .format(E_CASSCF, spin_square(mc)[1], t_end - t_start)) # Active-space RDM data frag.oneRDMas_loc = symmetrize_tensor( represent_operator_in_basis(oneRDM_amo, loc2amo.conjugate().T)) frag.oneSDMas_loc = symmetrize_tensor( represent_operator_in_basis(oneSDM_amo, loc2amo.conjugate().T)) frag.twoCDMimp_amo = twoCDM_amo frag.loc2mo = loc2mo frag.loc2amo = loc2amo frag.E2_cum = np.tensordot( ao2mo.restore(1, mc.get_h2eff(), mc.ncas), twoCDM_amo, axes=4) / 2 frag.E2_cum += (mf.get_k(dm=oneSDM_imp) * oneSDM_imp).sum() / 4 # The second line compensates for my incorrect cumulant decomposition. Anything to avoid changing the checkpoint files... # General impurity data frag.oneRDM_loc = frag.oneRDMfroz_loc + symmetrize_tensor( represent_operator_in_basis(oneRDM_imp, frag.imp2loc)) frag.oneSDM_loc = frag.oneSDMfroz_loc + frag.oneSDMas_loc frag.twoCDM_imp = None # Experiment: this tensor is huge. Do I actually need to keep it? In principle, of course not. frag.E_imp = E_CASSCF + np.einsum('ab,ab->', chempot_imp, oneRDM_imp) return None
#!/usr/bin/env python # # Author: Sebastian Wouters <*****@*****.**> # # Date: March 5, 2015 # # Test file to illustrate the usage of Edmiston-Ruedenberg localization # from pyscf import gto, scf from pyscf.tools import molden from pyscf.tools import localizer from pyscf.lib import parameters as param import numpy as np mol = gto.Mole() # Benzene mol.atom = ''' H 0.000000000000 2.491406946734 0.000000000000 C 0.000000000000 1.398696930758 0.000000000000 H 0.000000000000 -2.491406946734 0.000000000000 C 0.000000000000 -1.398696930758 0.000000000000 H 2.157597486829 1.245660462400 0.000000000000 C 1.211265339156 0.699329968382 0.000000000000 H 2.157597486829 -1.245660462400 0.000000000000 C 1.211265339156 -0.699329968382 0.000000000000 H -2.157597486829 1.245660462400 0.000000000000 C -1.211265339156 0.699329968382 0.000000000000 H -2.157597486829 -1.245660462400 0.000000000000 C -1.211265339156 -0.699329968382 0.000000000000 ''' mol.basis = '6-31g'
def test_rdm_vs_rcisd(self): mol = gto.Mole() mol.atom = [ [8 , (0. , 0. , 0.)], [1 , (0. , -0.757 , 0.587)], [1 , (0. , 0.757 , 0.587)]] mol.verbose = 5 mol.output = '/dev/null' mol.basis = '631g' mol.build() mf = scf.RHF(mol).run() myrci = ci.cisd.CISD(mf).run() rdm1 = myrci.make_rdm1() rdm2 = myrci.make_rdm2() mf = scf.addons.convert_to_ghf(mf) mygci = gcisd.GCISD(mf).run() dm1 = mygci.make_rdm1() dm2 = mygci.make_rdm2() nao = mol.nao_nr() mo_a = mf.mo_coeff[:nao] mo_b = mf.mo_coeff[nao:] nmo = mo_a.shape[1] eri = ao2mo.kernel(mf._eri, mo_a+mo_b, compact=False).reshape([nmo]*4) orbspin = mf.mo_coeff.orbspin sym_forbid = (orbspin[:,None] != orbspin) eri[sym_forbid,:,:] = 0 eri[:,:,sym_forbid] = 0 hcore = scf.RHF(mol).get_hcore() h1 = reduce(numpy.dot, (mo_a.T.conj(), hcore, mo_a)) h1+= reduce(numpy.dot, (mo_b.T.conj(), hcore, mo_b)) e1 = numpy.einsum('ij,ji', h1, dm1) e1+= numpy.einsum('ijkl,ijkl', eri, dm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, mygci.e_tot, 7) idxa = numpy.where(orbspin == 0)[0] idxb = numpy.where(orbspin == 1)[0] trdm1 = dm1[idxa[:,None],idxa] trdm1+= dm1[idxb[:,None],idxb] trdm2 = dm2[idxa[:,None,None,None],idxa[:,None,None],idxa[:,None],idxa] trdm2+= dm2[idxb[:,None,None,None],idxb[:,None,None],idxb[:,None],idxb] dm2ab = dm2[idxa[:,None,None,None],idxa[:,None,None],idxb[:,None],idxb] trdm2+= dm2ab trdm2+= dm2ab.transpose(2,3,0,1) self.assertAlmostEqual(abs(trdm1 - rdm1).max(), 0, 5) self.assertAlmostEqual(abs(trdm2 - rdm2).max(), 0, 5) c0, c1, c2 = myrci.cisdvec_to_amplitudes(myrci.ci) rt0 = c0 + .2j rt1 = c1 + numpy.cos(c1) * .2j rt2 = c2 + numpy.sin(c2) * .8j civec = myrci.amplitudes_to_cisdvec(rt0, rt1, rt2) rdm1 = myrci.make_rdm1(civec) rdm2 = myrci.make_rdm2(civec) gt1 = mygci.spatial2spin(rt1) gt2 = mygci.spatial2spin(rt2) civec = mygci.amplitudes_to_cisdvec(rt0, gt1, gt2) gdm1 = mygci.make_rdm1(civec) gdm2 = mygci.make_rdm2(civec) orbspin = mf.mo_coeff.orbspin idxa = numpy.where(orbspin == 0)[0] idxb = numpy.where(orbspin == 1)[0] trdm1 = gdm1[idxa[:,None],idxa] trdm1+= gdm1[idxb[:,None],idxb] trdm2 = gdm2[idxa[:,None,None,None],idxa[:,None,None],idxa[:,None],idxa] trdm2+= gdm2[idxb[:,None,None,None],idxb[:,None,None],idxb[:,None],idxb] dm2ab = gdm2[idxa[:,None,None,None],idxa[:,None,None],idxb[:,None],idxb] trdm2+= dm2ab trdm2+= dm2ab.transpose(2,3,0,1) self.assertAlmostEqual(abs(trdm1 - rdm1).max(), 0, 9) self.assertAlmostEqual(abs(trdm2 - rdm2).max(), 0, 9)
def initial_test(): import numpy as np from tcc._rccsd_thc_ls import (gen_energy, gen_R1, gen_RY1, gen_RY2, gen_RY3, gen_RY4, gen_RZ, gen_A1, gen_A2, gen_A3, gen_A4, gen_AZl, gen_AZr) from pyscf import gto from pyscf import scf mol = gto.Mole() mol.atom = [[8, (0., 0., 0.)], [1, (0., -0.757, 0.587)], [1, (0., 0.757, 0.587)]] mol.basis = { 'H': 'sto-3g', 'O': 'sto-3g', } mol.build() rhf = scf.RHF(mol) rhf.scf() # -76.0267656731 from tcc.rccsd_thc import RCCSD_THC_LS_T cc = RCCSD_THC_LS_T(rhf, load_ham_from='reference_random_ham.mat') h = cc.create_ham() from scipy.io import loadmat ref = loadmat('reference_random_ham.mat', matlab_compatible=True) t2l = ref['t2s'][0][0] t1 = ref['t1'] a = cc.types.AMPLITUDES_TYPE(t1, *t2l) from tcc.denom import cc_denom d = cc_denom(h.f, 4, ordering='mul', kind='cpd') from tcc._rccsd_thc_ls import gen_energy, gen_R1 energy = gen_energy(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1, a.x2, a.x3, a.x4, a.x5) e_ref = ref['energy'][0][0] print(energy - e_ref) rt1 = gen_R1(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1, a.x2, a.x3, a.x4, a.x5) gt1 = rt1 - a.t1 / cc_denom(h.f, 2, 'mul', 'full') t1n = gt1 * (-cc_denom(h.f, 2, 'mul', 'full')) t1n_ref = ref['t1n'] print(t1n - t1n_ref) rz = gen_RZ(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1, a.x2, a.x3, a.x4, a.x5, d[0], d[1], d[2], d[3]) ry1 = gen_RY1(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1, a.x2, a.x3, a.x4, a.x5, d[0], d[1], d[2], d[3]) ry2 = gen_RY2(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1, a.x2, a.x3, a.x4, a.x5, d[0], d[1], d[2], d[3]) ry3 = gen_RY3(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1, a.x2, a.x3, a.x4, a.x5, d[0], d[1], d[2], d[3]) ry4 = gen_RY4(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1, a.x2, a.x3, a.x4, a.x5, d[0], d[1], d[2], d[3]) print([ np.max(r_new + r_ref) for (r_new, r_ref) in zip([ry1, ry2, ry3, ry4, rz], ref['r2n'][0][0]) ]) a1 = gen_A1(a.x1, a.x2, a.x3, a.x4, a.x5) a2 = gen_A2(a.x1, a.x2, a.x3, a.x4, a.x5) a3 = gen_A3(a.x1, a.x2, a.x3, a.x4, a.x5) a4 = gen_A4(a.x1, a.x2, a.x3, a.x4, a.x5) azl = gen_AZl(a.x1, a.x2, a.x3, a.x4, a.x5) azr = gen_AZr(a.x1, a.x2, a.x3, a.x4, a.x5) print([ np.max(a_new - a_ref) for (a_new, a_ref) in zip([a1, a2, a3, a4, azl, azr], ref['as'][0][0]) ]) x1n = a.x1 - np.dot(ry1, np.linalg.pinv(a1))
norm_vector = np.empty(total_num_basis(mol)) c = 0 for i in range(mol.natm): for j, num_ao_l in enumerate( df_basis_dict[mol.basis][mol.atom_symbol(i)]): for k in range(num_ao_l): #print i,j,k,' ', norm_by_l_list[j] norm_vector[c] = norm_by_l_list[j] c += 1 return norm_vector # Examples if __name__ == '__main__': print ''' =====Example 1:===== ''' # Creating auxiliar Molecule x = gto.Mole() x.atom = '''H -0.37 0. 0. ; H 0.37 0. 0. ''' x.basis = 'weigend' x.build() print x.basis, 'basis set:' print normalize_df(x)
# You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import unittest import numpy from pyscf import gto, scf from pyscf.lo import boys, edmiston, pipek mol = gto.Mole() mol.atom = ''' H 0.000000000000 2.491406946734 0.000000000000 C 0.000000000000 1.398696930758 0.000000000000 H 0.000000000000 -2.491406946734 0.000000000000 C 0.000000000000 -1.398696930758 0.000000000000 H 2.157597486829 1.245660462400 0.000000000000 C 1.211265339156 0.699329968382 0.000000000000 H 2.157597486829 -1.245660462400 0.000000000000 C 1.211265339156 -0.699329968382 0.000000000000 H -2.157597486829 1.245660462400 0.000000000000 C -1.211265339156 0.699329968382 0.000000000000 H -2.157597486829 -1.245660462400 0.000000000000 C -1.211265339156 -0.699329968382 0.000000000000 ''' mol.basis = '6-31g'
H 2.57757 0.70882 1.05856 H 2.19751 -0.98641 1.27430 ''' sub2_trans = ''' C 3.45731 -0.58142 -0.42016 H 4.40140 -0.73248 0.10838 H 3.22542 -1.50333 -0.96012 H 3.61494 0.19921 -1.16898 ''' basis_to_use = 'cc-pVDZ' dft_method = 'm06' active_method = 'hf' sub1_react_mol = gto.Mole() sub1_react_mol.atom = sub1_react sub1_react_mol.basis = basis_to_use sub1_react_mol.charge = -1 sub1_react_mol.build() sub2_react_mol = gto.Mole() sub2_react_mol.atom = sub2_react sub2_react_mol.basis = basis_to_use sub2_react_mol.charge = 1 sub2_react_mol.build() sub1_trans_mol = gto.Mole() sub1_trans_mol.atom = sub1_trans sub1_trans_mol.basis = basis_to_use sub1_trans_mol.charge = -2
class TestPolarR: mol = gto.Mole(atom="N 0. 0. 0.; H .9 0. 0.; H 0. 1. 0.; H 0. 0. 1.1", basis="6-31G", verbose=0).build() grids = dft.Grids(mol) grids.atom_grid = (99, 590) grids.build() grids_cphf = dft.Grids(mol) grids_cphf.atom_grid = (50, 194) grids_cphf.build() def test_r_rhf_polar(self): scf_eng = scf.RHF(self.mol).run() diph = DipoleSCF({"scf_eng": scf_eng}) polh = PolarSCF({"deriv_A": diph}) formchk = FormchkInterface( resource_filename("pyxdh", "Validation/gaussian/NH3-HF-freq.fchk")) # ASSERT: polar - Gaussian assert np.allclose(-polh.E_2, formchk.polarizability(), atol=1e-6, rtol=1e-4) def test_r_b3lyp_polar(self): scf_eng = dft.RKS(self.mol, xc="B3LYPg") scf_eng.grids = self.grids scf_eng.run() diph = DipoleSCF({"scf_eng": scf_eng, "cphf_grids": self.grids_cphf}) polh = PolarSCF({"deriv_A": diph}) formchk = FormchkInterface( resource_filename("pyxdh", "Validation/gaussian/NH3-B3LYP-freq.fchk")) # ASSERT: polar - Gaussian assert np.allclose(-polh.E_2, formchk.polarizability(), atol=1e-6, rtol=1e-4) def test_r_hfb3lyp_polar(self): scf_eng = scf.RHF(self.mol) scf_eng.conv_tol_grad = 1e-8 scf_eng.run() nc_eng = dft.RKS(self.mol, xc="B3LYPg") nc_eng.grids = self.grids diph = DipoleNCDFT({"scf_eng": scf_eng, "nc_eng": nc_eng}) polh = PolarNCDFT({"deriv_A": diph}) with open( resource_filename( "pyxdh", "Validation/numerical_deriv/NH3-HFB3LYP-pol.dat"), "rb") as f: ref_polar = pickle.load(f) # ASSERT: polar - numerical assert np.allclose(-polh.E_2, ref_polar, atol=1e-6, rtol=1e-4) def test_r_mp2_polar(self): scf_eng = scf.RHF(self.mol).run() diph = DipoleMP2({"scf_eng": scf_eng}) polh = PolarMP2({"deriv_A": diph}) formchk = FormchkInterface( resource_filename("pyxdh", "Validation/gaussian/NH3-MP2-freq.fchk")) # ASSERT: polar - Gaussian assert np.allclose(-polh.E_2, formchk.polarizability(), atol=1e-6, rtol=1e-4) def test_r_xyg3_polar(self): scf_eng = dft.RKS(self.mol, xc="B3LYPg") scf_eng.grids = self.grids scf_eng.run() nc_eng = dft.RKS(self.mol, xc="0.8033*HF - 0.0140*LDA + 0.2107*B88, 0.6789*LYP") nc_eng.grids = self.grids config = { "scf_eng": scf_eng, "nc_eng": nc_eng, "cc": 0.3211, "cphf_grids": self.grids_cphf } diph = DipoleXDH(config) polh = PolarXDH({"deriv_A": diph}) formchk = FormchkInterface( resource_filename("pyxdh", "Validation/gaussian/NH3-XYG3-freq.fchk")) # ASSERT: polar - Gaussian np.allclose(-polh.E_2, formchk.polarizability(), atol=1e-6, rtol=1e-4) def test_r_xygjos_polar(self): scf_eng = dft.RKS(self.mol, xc="B3LYPg") scf_eng.grids = self.grids scf_eng.run() nc_eng = dft.RKS(self.mol, xc="0.7731*HF + 0.2269*LDA, 0.2309*VWN3 + 0.2754*LYP") nc_eng.grids = self.grids config = { "scf_eng": scf_eng, "nc_eng": nc_eng, "cc": 0.4364, "ss": 0., "cphf_grids": self.grids_cphf } diph = DipoleXDH(config) polh = PolarXDH({"deriv_A": diph}) formchk = FormchkInterface( resource_filename("pyxdh", "Validation/gaussian/NH3-XYGJOS-freq.fchk")) # ASSERT: polar - Gaussian np.allclose(-polh.E_2, formchk.polarizability(), atol=1e-6, rtol=1e-4)
''' An example of constructing CASSCF initial guess with the localized orbitals ''' import numpy from pyscf import gto, scf, mcscf, lo from pyscf import mo_mapping mol = gto.Mole(verbose=4, atom=''' C 0.000000000000 1.398696930758 0.000000000000 C 0.000000000000 -1.398696930758 0.000000000000 C 1.211265339156 0.699329968382 0.000000000000 C 1.211265339156 -0.699329968382 0.000000000000 C -1.211265339156 0.699329968382 0.000000000000 C -1.211265339156 -0.699329968382 0.000000000000 H 0.000000000000 2.491406946734 0.000000000000 H 0.000000000000 -2.491406946734 0.000000000000 H 2.157597486829 1.245660462400 0.000000000000 H 2.157597486829 -1.245660462400 0.000000000000 H -2.157597486829 1.245660462400 0.000000000000 H -2.157597486829 -1.245660462400 0.000000000000''', basis='ccpvdz', symmetry='D2h') mol.build() mf = scf.RHF(mol) mf.kernel() # # Search the active space orbitals based on certain AO components. In this # example, the pi-orbitals from carbon 2pz are considered.
env[off+i] = env[off0+i] for i in range(nh): bas[i+nh,ATOM_OF ] = bas[i,ATOM_OF ] bas[i+nh,ANG_OF ] = bas[i,ANG_OF ] - 1 bas[i+nh,KAPPA_OF] =-bas[i,KAPPA_OF] bas[i+nh,NPRIM_OF] = bas[i,NPRIM_OF] bas[i+nh,NCTR_OF ] = bas[i,NCTR_OF ] bas[i+nh,PTR_EXP ] = bas[i,PTR_EXP ] + n bas[i+nh,PTR_COEFF]= bas[i,PTR_COEFF] + n env[bas[i+nh,PTR_COEFF]] /= 2 * env[bas[i,PTR_EXP]] env[bas[5,PTR_COEFF]+0] = env[bas[1,PTR_COEFF]+0] / (2 * env[bas[1,PTR_EXP]+0]) env[bas[5,PTR_COEFF]+1] = env[bas[1,PTR_COEFF]+1] / (2 * env[bas[1,PTR_EXP]+1]) env[bas[5,PTR_COEFF]+2] = env[bas[1,PTR_COEFF]+2] / (2 * env[bas[1,PTR_EXP]+0]) env[bas[5,PTR_COEFF]+3] = env[bas[1,PTR_COEFF]+3] / (2 * env[bas[1,PTR_EXP]+1]) mol1 = gto.Mole() mol1._atm = atm mol1._bas = bas[:nh*2] mol1._env = env mol1._built = True numpy.random.seed(1) ngrids = 2000 coords = numpy.random.random((ngrids,3)) coords = (coords-.5)**2 * 80 def tearDownModule(): global mol, mol1, coords del mol, mol1, coords
def solve( CONST, OEI, FOCK, TEI, Norb, Nel, Nimp, DMguessRHF, energytype='LAMBDA', chempot_imp=0.0, printoutput=True ): assert (( energytype == 'LAMBDA' ) or ( energytype == 'LAMBDA_AMP' ) or ( energytype == 'LAMBDA_ZERO' ) or ( energytype == 'CASCI' )) # Killing output if necessary if ( printoutput==False ): sys.stdout.flush() old_stdout = sys.stdout.fileno() new_stdout = os.dup(old_stdout) devnull = os.open('/dev/null', os.O_WRONLY) os.dup2(devnull, old_stdout) os.close(devnull) # Augment the FOCK operator with the chemical potential FOCKcopy = FOCK.copy() if (chempot_imp != 0.0): for orb in range(Nimp): FOCKcopy[ orb, orb ] -= chempot_imp # Get the RHF solution mol = gto.Mole() mol.build( verbose=0 ) mol.atom.append(('C', (0, 0, 0))) mol.nelectron = Nel mol.incore_anyway = True mf = scf.RHF( mol ) mf.get_hcore = lambda *args: FOCKcopy mf.get_ovlp = lambda *args: np.eye( Norb ) mf._eri = ao2mo.restore(8, TEI, Norb) mf.scf( DMguessRHF ) DMloc = np.dot(np.dot( mf.mo_coeff, np.diag( mf.mo_occ )), mf.mo_coeff.T ) if ( mf.converged == False ): mf = mf.newton () mf.kernel () DMloc = np.dot(np.dot( mf.mo_coeff, np.diag( mf.mo_occ )), mf.mo_coeff.T ) # Check the RHF solution assert( Nel % 2 == 0 ) numPairs = Nel / 2 FOCKloc = FOCKcopy + np.einsum('ijkl,ij->kl', TEI, DMloc) - 0.5 * np.einsum('ijkl,ik->jl', TEI, DMloc) eigvals, eigvecs = np.linalg.eigh( FOCKloc ) idx = eigvals.argsort() eigvals = eigvals[ idx ] eigvecs = eigvecs[ :, idx ] print("psi4cc::solve : RHF h**o-lumo gap =", eigvals[numPairs] - eigvals[numPairs-1]) DMloc2 = 2 * np.dot( eigvecs[ :, :numPairs ], eigvecs[ :, :numPairs ].T ) print("Two-norm difference of 1-RDM(RHF) and 1-RDM(FOCK(RHF)) =", np.linalg.norm(DMloc - DMloc2)) # Get the CC solution from pyscf ccsolver = ccsd.CCSD( mf ) ccsolver.verbose = 5 ECORR, t1, t2 = ccsolver.ccsd() ERHF = mf.e_tot ECCSD = ERHF + ECORR # Compute the impurity energy if ( energytype == 'CASCI' ): # The 2-RDM is not required # Active space energy is computed with the Fock operator of the core (not rescaled) print("ECCSD =", ECCSD) ccsolver.solve_lambda() pyscfRDM1 = ccsolver.make_rdm1() # MO space pyscfRDM1 = 0.5 * (pyscfRDM1 + pyscfRDM1.T) # Symmetrize pyscfRDM1 = np.dot(mf.mo_coeff, np.dot(pyscfRDM1, mf.mo_coeff.T)) # From MO to localized space ImpurityEnergy = ECCSD if ( chempot_imp != 0.0 ): # [FOCK - FOCKcopy]_{ij} = chempot_imp * delta(i,j) * delta(i \in imp) ImpurityEnergy += np.einsum('ij,ij->', FOCK - FOCKcopy, pyscfRDM1) else: # Compute the DMET impurity energy based on the lambda equations if ( energytype == 'LAMBDA' ): ccsolver.solve_lambda() pyscfRDM1 = ccsolver.make_rdm1() # MO space pyscfRDM2 = ccsolver.make_rdm2() # MO space if ( energytype == 'LAMBDA_AMP' ): # Overwrite lambda tensors with t-amplitudes pyscfRDM1 = ccsolver.make_rdm1(t1, t2, t1, t2) # MO space pyscfRDM2 = ccsolver.make_rdm2(t1, t2, t1, t2) # MO space if ( energytype == 'LAMBDA_ZERO' ): # Overwrite lambda tensors with 0.0 fake_l1 = np.zeros( t1.shape, dtype=float ) fake_l2 = np.zeros( t2.shape, dtype=float ) pyscfRDM1 = ccsolver.make_rdm1(t1, t2, fake_l1, fake_l2) # MO space pyscfRDM2 = ccsolver.make_rdm2(t1, t2, fake_l1, fake_l2) # MO space pyscfRDM1 = 0.5 * ( pyscfRDM1 + pyscfRDM1.T ) # Symmetrize # Print a few to things to double check ''' print "Do we understand how the 1-RDM is stored?", np.linalg.norm( np.einsum('ii->', pyscfRDM1) - Nel ) print "Do we understand how the 2-RDM is stored?", np.linalg.norm( np.einsum('ijkk->ij', pyscfRDM2) / (Nel - 1.0) - pyscfRDM1 ) ''' # Change the pyscfRDM1/2 from MO space to localized space pyscfRDM1 = np.dot(mf.mo_coeff, np.dot(pyscfRDM1, mf.mo_coeff.T )) pyscfRDM2 = np.einsum('ai,ijkl->ajkl', mf.mo_coeff, pyscfRDM2) pyscfRDM2 = np.einsum('bj,ajkl->abkl', mf.mo_coeff, pyscfRDM2) pyscfRDM2 = np.einsum('ck,abkl->abcl', mf.mo_coeff, pyscfRDM2) pyscfRDM2 = np.einsum('dl,abcl->abcd', mf.mo_coeff, pyscfRDM2) ECCSDbis = CONST + np.einsum('ij,ij->', FOCKcopy, pyscfRDM1) + 0.5 * np.einsum('ijkl,ijkl->', TEI, pyscfRDM2) print("ECCSD1 =", ECCSD) print("ECCSD2 =", ECCSDbis) # To calculate the impurity energy, rescale the JK matrix with a factor 0.5 to avoid double counting: 0.5 * ( OEI + FOCK ) = OEI + 0.5 * JK ImpurityEnergy = CONST \ + 0.25 * np.einsum('ij,ij->', pyscfRDM1[:Nimp,:], FOCK[:Nimp,:] + OEI[:Nimp,:]) \ + 0.25 * np.einsum('ij,ij->', pyscfRDM1[:,:Nimp], FOCK[:,:Nimp] + OEI[:,:Nimp]) \ + 0.125 * np.einsum('ijkl,ijkl->', pyscfRDM2[:Nimp,:,:,:], TEI[:Nimp,:,:,:]) \ + 0.125 * np.einsum('ijkl,ijkl->', pyscfRDM2[:,:Nimp,:,:], TEI[:,:Nimp,:,:]) \ + 0.125 * np.einsum('ijkl,ijkl->', pyscfRDM2[:,:,:Nimp,:], TEI[:,:,:Nimp,:]) \ + 0.125 * np.einsum('ijkl,ijkl->', pyscfRDM2[:,:,:,:Nimp], TEI[:,:,:,:Nimp]) # Reviving output if necessary if ( printoutput==False ): sys.stdout.flush() os.dup2(new_stdout, old_stdout) os.close(new_stdout) return ( ImpurityEnergy, pyscfRDM1 )
def test_h4(self): mol = gto.Mole() mol.verbose = 0 mol.atom = [ ['H', ( 1.,-1. , 0. )], ['H', ( 0.,-1. ,-1. )], ['H', ( 1.,-0.5 , 0. )], ['H', ( 0.,-1. , 1. )], ] mol.charge = 2 mol.spin = 2 mol.basis = '3-21g' mol.build() mf = scf.GHF(mol).run(conv_tol=1e-14) myci = ci.GCISD(mf) myci.kernel() self.assertAlmostEqual(myci.e_tot, -0.86423570617209888, 8) mf = scf.RHF(mol).run(conv_tol=1e-14) myci = ci.GCISD(mf) myci.kernel() self.assertAlmostEqual(myci.e_tot, -0.86423570617209888, 8) mol = gto.Mole() mol.verbose = 0 mol.atom = [ ['H', ( 1.,-1. , 0. )], ['H', ( 0.,-1. ,-1. )], ['H', ( 1.,-0.5 , 0. )], ['H', ( 0.,-1. , 1. )], ] mol.charge = 2 mol.spin = 0 mol.basis = '3-21g' mol.build() mf = scf.UHF(mol).run(conv_tol=1e-14) myci = ci.GCISD(mf) myci.kernel() self.assertAlmostEqual(myci.e_tot, -0.86423570617209888, 8) mf = scf.UHF(mol).run(conv_tol=1e-14) gmf = scf.addons.convert_to_ghf(mf) ehf0 = mf.e_tot - mol.energy_nuc() myci = gcisd.GCISD(gmf) eris = myci.ao2mo() ecisd = myci.kernel(eris=eris)[0] eri_aa = ao2mo.kernel(mf._eri, mf.mo_coeff[0]) eri_bb = ao2mo.kernel(mf._eri, mf.mo_coeff[1]) eri_ab = ao2mo.kernel(mf._eri, [mf.mo_coeff[0], mf.mo_coeff[0], mf.mo_coeff[1], mf.mo_coeff[1]]) h1a = reduce(numpy.dot, (mf.mo_coeff[0].T, mf.get_hcore(), mf.mo_coeff[0])) h1b = reduce(numpy.dot, (mf.mo_coeff[1].T, mf.get_hcore(), mf.mo_coeff[1])) efci, fcivec = fci.direct_uhf.kernel((h1a,h1b), (eri_aa,eri_ab,eri_bb), h1a.shape[0], mol.nelec) self.assertAlmostEqual(myci.e_tot-mol.energy_nuc(), efci, 9) dm1ref, dm2ref = fci.direct_uhf.make_rdm12s(fcivec, h1a.shape[0], mol.nelec) nmo = myci.nmo rdm1 = myci.make_rdm1(myci.ci, nmo, mol.nelectron) rdm2 = myci.make_rdm2(myci.ci, nmo, mol.nelectron) idxa = eris.orbspin == 0 idxb = eris.orbspin == 1 self.assertAlmostEqual(abs(dm1ref[0] - rdm1[idxa][:,idxa]).max(), 0, 6) self.assertAlmostEqual(abs(dm1ref[1] - rdm1[idxb][:,idxb]).max(), 0, 6) self.assertAlmostEqual(abs(dm2ref[0] - rdm2[idxa][:,idxa][:,:,idxa][:,:,:,idxa]).max(), 0, 6) self.assertAlmostEqual(abs(dm2ref[1] - rdm2[idxa][:,idxa][:,:,idxb][:,:,:,idxb]).max(), 0, 6) self.assertAlmostEqual(abs(dm2ref[2] - rdm2[idxb][:,idxb][:,:,idxb][:,:,:,idxb]).max(), 0, 6)
# You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import unittest from pyscf import gto from pyscf import lib from pyscf import dft h2o = gto.Mole() h2o.verbose = 5 h2o.output = '/dev/null' h2o.atom = [["O", (0., 0., 0.)], [1, (0., -0.757, 0.587)], [1, (0., 0.757, 0.587)]] h2o.basis = { "H": '6-31g', "O": '6-31g', } h2o.build() h2osym = gto.Mole() h2osym.verbose = 5 h2osym.output = '/dev/null' h2osym.atom = [["O", (0., 0., 0.)], [1, (0., -0.757, 0.587)],
def test_h4_a(self): '''Compare to FCI''' mol = gto.Mole() mol.verbose = 0 mol.atom = [ ['H', ( 1.,-1. , 0. )], ['H', ( 0.,-1. ,-1. )], ['H', ( 1.,-0.5 , 0. )], ['H', ( 0.,-1. , 1. )], ] mol.charge = -2 mol.spin = 2 mol.basis = '3-21g' mol.build() mf = scf.UHF(mol).run(conv_tol=1e-14) ehf0 = mf.e_tot - mol.energy_nuc() gmf = scf.addons.convert_to_ghf(mf) myci = ci.GCISD(gmf) eris = myci.ao2mo() numpy.random.seed(12) nocca, noccb = mol.nelec nmo = mol.nao_nr() nvira = nmo - nocca nvirb = nmo - noccb #cisdvec = myci.get_init_guess(eris)[1] c1a = .1 * numpy.random.random((nocca,nvira)) c1b = .1 * numpy.random.random((noccb,nvirb)) c2aa = .1 * numpy.random.random((nocca,nocca,nvira,nvira)) c2bb = .1 * numpy.random.random((noccb,noccb,nvirb,nvirb)) c2ab = .1 * numpy.random.random((nocca,noccb,nvira,nvirb)) c1 = myci.spatial2spin((c1a, c1b)) c2 = myci.spatial2spin((c2aa, c2ab, c2bb)) cisdvec = myci.amplitudes_to_cisdvec(1., c1, c2) self.assertEqual(cisdvec.size, myci.vector_size()) hcisd0 = myci.contract(cisdvec, eris) eri_aa = ao2mo.kernel(mf._eri, mf.mo_coeff[0]) eri_bb = ao2mo.kernel(mf._eri, mf.mo_coeff[1]) eri_ab = ao2mo.kernel(mf._eri, [mf.mo_coeff[0], mf.mo_coeff[0], mf.mo_coeff[1], mf.mo_coeff[1]]) h1a = reduce(numpy.dot, (mf.mo_coeff[0].T, mf.get_hcore(), mf.mo_coeff[0])) h1b = reduce(numpy.dot, (mf.mo_coeff[1].T, mf.get_hcore(), mf.mo_coeff[1])) h2e = fci.direct_uhf.absorb_h1e((h1a,h1b), (eri_aa,eri_ab,eri_bb), h1a.shape[0], mol.nelec, .5) fcivec = myci.to_fcivec(cisdvec, mol.nelectron, eris.orbspin) hci1 = fci.direct_uhf.contract_2e(h2e, fcivec, h1a.shape[0], mol.nelec) hci1 -= ehf0 * fcivec hcisd1 = myci.from_fcivec(hci1, mol.nelectron, eris.orbspin) self.assertAlmostEqual(abs(hcisd1-hcisd0).max(), 0, 9) hdiag0 = myci.make_diagonal(eris) hdiag0 = myci.to_fcivec(hdiag0, mol.nelectron, eris.orbspin).ravel() hdiag0 = myci.from_fcivec(hdiag0, mol.nelectron, eris.orbspin).ravel() hdiag1 = fci.direct_uhf.make_hdiag((h1a,h1b), (eri_aa,eri_ab,eri_bb), h1a.shape[0], mol.nelec) hdiag1 = myci.from_fcivec(hdiag1, mol.nelectron, eris.orbspin).ravel() self.assertAlmostEqual(abs(abs(hdiag0)-abs(hdiag1)).max(), 0, 9) ecisd = myci.kernel()[0] efci = fci.direct_uhf.kernel((h1a,h1b), (eri_aa,eri_ab,eri_bb), h1a.shape[0], mol.nelec)[0] self.assertAlmostEqual(ecisd, -0.037067274690894436, 9) self.assertTrue(myci.e_tot-mol.energy_nuc() - efci < 0.002)
def get_pp(mydf, kpts=None): '''Get the periodic pseudotential nuc-el AO matrix, with G=0 removed. ''' cell = mydf.cell if kpts is None: kpts_lst = numpy.zeros((1, 3)) else: kpts_lst = numpy.reshape(kpts, (-1, 3)) low_dim_ft_type = mydf.low_dim_ft_type mesh = mydf.mesh SI = cell.get_SI() Gv = cell.get_Gv(mesh) vpplocG = pseudo.get_vlocG(cell, Gv, low_dim_ft_type) vpplocG = -numpy.einsum('ij,ij->j', SI, vpplocG) # from get_jvloc_G0 function vpplocG[0] = numpy.sum(pseudo.get_alphas(cell, low_dim_ft_type)) ngrids = len(vpplocG) # vpploc evaluated in real-space vpplocR = tools.ifft(vpplocG, mesh).real vpp = [0] * len(kpts_lst) for ao_ks_etc, p0, p1 in mydf.aoR_loop(mydf.grids, kpts_lst): ao_ks = ao_ks_etc[0] for k, ao in enumerate(ao_ks): vpp[k] += lib.dot(ao.T.conj() * vpplocR[p0:p1], ao) ao = ao_ks = None # vppnonloc evaluated in reciprocal space fakemol = gto.Mole() fakemol._atm = numpy.zeros((1, gto.ATM_SLOTS), dtype=numpy.int32) fakemol._bas = numpy.zeros((1, gto.BAS_SLOTS), dtype=numpy.int32) ptr = gto.PTR_ENV_START fakemol._env = numpy.zeros(ptr + 10) fakemol._bas[0, gto.NPRIM_OF] = 1 fakemol._bas[0, gto.NCTR_OF] = 1 fakemol._bas[0, gto.PTR_EXP] = ptr + 3 fakemol._bas[0, gto.PTR_COEFF] = ptr + 4 # buf for SPG_lmi upto l=0..3 and nl=3 buf = numpy.empty((48, ngrids), dtype=numpy.complex128) def vppnl_by_k(kpt): Gk = Gv + kpt G_rad = lib.norm(Gk, axis=1) aokG = ft_ao.ft_ao(cell, Gv, kpt=kpt) * (ngrids / cell.vol) vppnl = 0 for ia in range(cell.natm): symb = cell.atom_symbol(ia) if symb not in cell._pseudo: continue pp = cell._pseudo[symb] p1 = 0 for l, proj in enumerate(pp[5:]): rl, nl, hl = proj if nl > 0: fakemol._bas[0, gto.ANG_OF] = l fakemol._env[ptr + 3] = .5 * rl**2 fakemol._env[ptr + 4] = rl**(l + 1.5) * numpy.pi**1.25 pYlm_part = fakemol.eval_gto('GTOval', Gk) p0, p1 = p1, p1 + nl * (l * 2 + 1) # pYlm is real, SI[ia] is complex pYlm = numpy.ndarray((nl, l * 2 + 1, ngrids), dtype=numpy.complex128, buffer=buf[p0:p1]) for k in range(nl): qkl = pseudo.pp._qli(G_rad * rl, l, k) pYlm[k] = pYlm_part.T * qkl #:SPG_lmi = numpy.einsum('g,nmg->nmg', SI[ia].conj(), pYlm) #:SPG_lm_aoG = numpy.einsum('nmg,gp->nmp', SPG_lmi, aokG) #:tmp = numpy.einsum('ij,jmp->imp', hl, SPG_lm_aoG) #:vppnl += numpy.einsum('imp,imq->pq', SPG_lm_aoG.conj(), tmp) if p1 > 0: SPG_lmi = buf[:p1] SPG_lmi *= SI[ia].conj() SPG_lm_aoGs = lib.zdot(SPG_lmi, aokG) p1 = 0 for l, proj in enumerate(pp[5:]): rl, nl, hl = proj if nl > 0: p0, p1 = p1, p1 + nl * (l * 2 + 1) hl = numpy.asarray(hl) SPG_lm_aoG = SPG_lm_aoGs[p0:p1].reshape( nl, l * 2 + 1, -1) tmp = numpy.einsum('ij,jmp->imp', hl, SPG_lm_aoG) vppnl += numpy.einsum('imp,imq->pq', SPG_lm_aoG.conj(), tmp) return vppnl * (1. / ngrids**2) for k, kpt in enumerate(kpts_lst): vppnl = vppnl_by_k(kpt) if gamma_point(kpt): vpp[k] = vpp[k].real + vppnl.real else: vpp[k] += vppnl if kpts is None or numpy.shape(kpts) == (3, ): vpp = vpp[0] return numpy.asarray(vpp)
def test_rdm_vs_ucisd(self): mol = gto.Mole() mol.atom = [ [8 , (0. , 0. , 0.)], [1 , (0. , -0.757 , 0.587)], [1 , (0. , 0.757 , 0.587)]] mol.verbose = 5 mol.output = '/dev/null' mol.basis = '631g' mol.spin = 2 mol.build() mf = scf.UHF(mol).run() myuci = ucisd.UCISD(mf) myuci.frozen = 1 myuci.kernel() udm1 = myuci.make_rdm1() udm2 = myuci.make_rdm2() mf = scf.addons.convert_to_ghf(mf) mygci = gcisd.GCISD(mf) mygci.frozen = 2 mygci.kernel() dm1 = mygci.make_rdm1() dm2 = mygci.make_rdm2() nao = mol.nao_nr() mo_a = mf.mo_coeff[:nao] mo_b = mf.mo_coeff[nao:] nmo = mo_a.shape[1] eri = ao2mo.kernel(mf._eri, mo_a+mo_b, compact=False).reshape([nmo]*4) orbspin = mf.mo_coeff.orbspin sym_forbid = (orbspin[:,None] != orbspin) eri[sym_forbid,:,:] = 0 eri[:,:,sym_forbid] = 0 hcore = scf.RHF(mol).get_hcore() h1 = reduce(numpy.dot, (mo_a.T.conj(), hcore, mo_a)) h1+= reduce(numpy.dot, (mo_b.T.conj(), hcore, mo_b)) e1 = numpy.einsum('ij,ji', h1, dm1) e1+= numpy.einsum('ijkl,ijkl', eri, dm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, mygci.e_tot, 7) idxa = numpy.where(orbspin == 0)[0] idxb = numpy.where(orbspin == 1)[0] self.assertAlmostEqual(abs(dm1[idxa[:,None],idxa] - udm1[0]).max(), 0, 5) self.assertAlmostEqual(abs(dm1[idxb[:,None],idxb] - udm1[1]).max(), 0, 5) self.assertAlmostEqual(abs(dm2[idxa[:,None,None,None],idxa[:,None,None],idxa[:,None],idxa] - udm2[0]).max(), 0, 5) self.assertAlmostEqual(abs(dm2[idxa[:,None,None,None],idxa[:,None,None],idxb[:,None],idxb] - udm2[1]).max(), 0, 5) self.assertAlmostEqual(abs(dm2[idxb[:,None,None,None],idxb[:,None,None],idxb[:,None],idxb] - udm2[2]).max(), 0, 5) c0, c1, c2 = myuci.cisdvec_to_amplitudes(myuci.ci) ut1 = [0] * 2 ut2 = [0] * 3 ut0 = c0 + .2j ut1[0] = c1[0] + numpy.cos(c1[0]) * .2j ut1[1] = c1[1] + numpy.cos(c1[1]) * .2j ut2[0] = c2[0] + numpy.sin(c2[0]) * .8j ut2[1] = c2[1] + numpy.sin(c2[1]) * .8j ut2[2] = c2[2] + numpy.sin(c2[2]) * .8j civec = myuci.amplitudes_to_cisdvec(ut0, ut1, ut2) udm1 = myuci.make_rdm1(civec) udm2 = myuci.make_rdm2(civec) gt1 = mygci.spatial2spin(ut1) gt2 = mygci.spatial2spin(ut2) civec = mygci.amplitudes_to_cisdvec(ut0, gt1, gt2) gdm1 = mygci.make_rdm1(civec) gdm2 = mygci.make_rdm2(civec) self.assertAlmostEqual(abs(gdm1[idxa[:,None],idxa] - udm1[0]).max(), 0, 9) self.assertAlmostEqual(abs(gdm1[idxb[:,None],idxb] - udm1[1]).max(), 0, 9) self.assertAlmostEqual(abs(gdm2[idxa[:,None,None,None],idxa[:,None,None],idxa[:,None],idxa] - udm2[0]).max(), 0, 9) self.assertAlmostEqual(abs(gdm2[idxa[:,None,None,None],idxa[:,None,None],idxb[:,None],idxb] - udm2[1]).max(), 0, 9) self.assertAlmostEqual(abs(gdm2[idxb[:,None,None,None],idxb[:,None,None],idxb[:,None],idxb] - udm2[2]).max(), 0, 9)
#!/usr/bin/env python import sys, os, numpy from pyscf import gto, scf, dft, lo, df, lib einsum = lib.einsum mol = gto.Mole() mol.basis = {'O': 'crenbl', 'H': 'def2-svp'} mol.ecp = {'O': 'crenbl'} mol.atom = ''' O 0.000000 0.000000 0.118351 H 0.000000 0.761187 -0.469725 H 0.000000 -0.761187 -0.469725 ''' mol.verbose = 4 mol.spin = 0 mol.symmetry = 1 mol.charge = 0 mol.build() mf = dft.RKS(mol) mf.conv_tol = 1e-8 mf.grids.radi_method = dft.mura_knowles mf.grids.becke_scheme = dft.stratmann mf.grids.level = 3 mf.xc = 'pbe0' mf.kernel() c = lo.orth_ao(mol, 'nao', scf_method=mf) mo = numpy.linalg.solve(c, mf.mo_coeff) dm = mf.make_rdm1(mo, mf.mo_occ)
def test_input_symmetry1(self): mol1 = gto.Mole() mol1.atom = 'H 1 1 1; H -1 -1 1; H 1 -1 -1; H -1 1 -1' mol1.unit = 'B' mol1.symmetry = True mol1.verbose = 5 mol1.output = '/dev/null' mol1.build() self.assertAlmostEqual(lib.fp(mol1.atom_coords()), 3.4708548731841296, 9) mol1 = gto.Mole() mol1.atom = 'H 0 0 -1; H 0 0 1' mol1.cart = True mol1.unit = 'B' mol1.symmetry = 'Dooh' mol1.verbose = 5 mol1.output = '/dev/null' mol1.build() self.assertAlmostEqual(lib.fp(mol1.atom_coords()), 0.69980902201036865, 9) mol1 = gto.Mole() mol1.atom = 'H 0 -1 0; H 0 1 0' mol1.unit = 'B' mol1.symmetry = True mol1.symmetry_subgroup = 'D2h' mol1.build() self.assertAlmostEqual(lib.fp(mol1.atom_coords()), -1.1939459267317516, 9) mol1.atom = 'H 0 0 -1; H 0 0 1' mol1.unit = 'B' mol1.symmetry = 'Coov' mol1.symmetry_subgroup = 'C2' mol1.build() self.assertAlmostEqual(lib.fp(mol1.atom_coords()), 0.69980902201036865, 9) mol1.atom = 'H 1 0 -1; H 0 0 1; He 0 0 2' mol1.symmetry = 'Coov' self.assertRaises(PointGroupSymmetryError, mol1.build) mol1.atom = ''' C 0. 0. 0.7264 C 0. 0. -.7264 H 0.92419 0. 1.29252 H -.92419 0. 1.29252 H 0. 0.92419 -1.29252 H 0. -.92419 -1.29252''' mol1.symmetry = True mol1.symmetry_subgroup = 'C2v' mol1.build() self.assertAlmostEqual(lib.fp(mol1.atom_coords()), 2.9413856643164618, 9) mol1 = gto.Mole() mol1.atom = [["O", (0., 0., 0.)], ["H", (0., -0.757, 0.587)], ["H", (0., 0.757, 0.587)]] mol1.symmetry = "C3" self.assertRaises(PointGroupSymmetryError, mol1.build)