def energygrad(self): """ # N = <0|0> # dN = 2<d0|0> # E = <0|H|0>/<0|0> # dE = 2<d0|H-E|0>/<0|0> """ h_struct_grad = full.matrix(len(self.structs)) h_orb_grad = full.matrix(Nod.C.shape) for s1, (str1, cstr1) in enumerate(zip(self.structs, self.coef)): for str2, cstr2 in zip(self.structs, self.coef): for det1, cdet1 in zip(str1.nods, str1.coef): for det2, cdet2 in zip(str2.nods, str2.coef): det12 = BraKet(det1, det2) h_struct_grad[s1] += \ 2*(cdet1*cstr2*cdet2)*\ det12.overlap()*\ det12.energy((self.h, self.h)) h_orb_grad += \ cstr1*cdet1*cstr2*cdet2*\ det12.energy_gradient((self.h, self.h)) N = self.norm() E = self.energy() n_struct_grad, n_orb_grad = self.normgrad() structgrad = (1/N)*(h_struct_grad - E*n_struct_grad) orbgrad = (1/N)*(h_orb_grad - E*n_orb_grad) return (structgrad, orbgrad[:, :])
def normhess(self): """ Numerical norm Hessian # N = <0|0> # d2<0|0> = <d20|0> + <0|d20> + 2<d0|d0> = 2<0|d20> + 2<d0|d0> """ n_struct_hess = full.matrix(self.coef.shape*2) n_orb_structhess = full.matrix(Nod.C.shape + self.coef.shape) n_orb_hess = full.matrix(Nod.C.shape*2) # for s1, (str1, cstr1) in enumerate(zip(self.structs, self.coef)): for s2, (str2, cstr2) in enumerate(zip(self.structs, self.coef)): for det1, cdet1 in zip(str1.nods, str1.coef): for det2, cdet2 in zip(str2.nods, str2.coef): # bk12 = BraKet(det1, det2) # n_struct_hess[s1, s2] += (cdet1*cdet2)*bk12.overlap() n_orb_structhess[:, :, s1] += \ cdet1*cstr2*cdet2*bk12.overlap_gradient() n_orb_hess += \ cstr1*cdet1*cstr2*cdet2*bk12.overlap_hessian() n_struct_hess *= 2 n_orb_structhess *= 2 #n_orb_hess return n_struct_hess, n_orb_structhess, n_orb_hess
def constraint(x, self): self.x = x mo = self.C[:, i] sg = full.matrix(self.coef.shape) og = full.matrix(self.C.shape) og[:, i] = 2*vb.Nod.S*mo return self.so2x(sg, og)
def numgrad(self, func, delta=1e-3): """ # Numerical gradient """ deltah = delta/2 # # structure coefficients # structgrad = full.matrix(len(self.structs)) # # for s in range(structgrad.shape[0]): self.coef[s] += deltah ep = func() self.coef[s] -= delta em = func() self.coef[s] += deltah structgrad[s] = (ep - em)/delta # # orbital gradient # r, c = Nod.C.shape orbgrad = full.matrix((r, c)) for m in range(c): for t in range(r): Nod.C[t, m] += deltah ep = func() Nod.C[t, m] -= delta em = func() orbgrad[t, m] = (ep - em)/delta Nod.C[t, m] += deltah return (structgrad, orbgrad[:, :])
def test_quadrupole_total(self, molfrag): rRab = full.matrix((6, molfrag.noa, molfrag.noa)) RRab = full.matrix((6, molfrag.noa, molfrag.noa)) Rabc = 1.0 * molfrag.Rab for a in range(molfrag.noa): for b in range(molfrag.noa): Rabc[a, b, :] -= molfrag.Rc for a in range(molfrag.noa): for b in range(molfrag.noa): ij = 0 for i in range(3): for j in range(i, 3): rRab[ij, a, b] = ( molfrag.Dab[i, a, b] * Rabc[a, b, j] + molfrag.Dab[j, a, b] * Rabc[a, b, i] ) RRab[ij, a, b] = ( molfrag.Qab[a, b] * (molfrag.R[a, i] - molfrag.Rc[i]) * (molfrag.R[b, j] - molfrag.Rc[j]) ) ij += 1 QUcab = molfrag.QUab + rRab + RRab QUc = QUcab.sum(axis=2).sum(axis=1).view(full.matrix) self.assert_allclose(QUc, ref.QUc)
def contravariant_transition_density_ao_mo(self): """Return contravariant density matrix in mix ao,mo basis""" d_am = (full.matrix(Nod.C.shape), full.matrix(Nod.C.shape)) CK = self.K.orbitals() for s in (0, 1): if self.K(s) and self.L(s): d_am[s][:, self.L(s)] = CK[s]*self.transition_density[s] return d_am
def contravariant_transition_density_mo_ao(self): """Return contravariant density matrix in mix mo,ao basis""" d_ma = (full.matrix(Nod.C.shape[::-1]), full.matrix(Nod.C.shape[::-1])) CL = self.L.orbitals() for s in (0, 1): if self.K(s) and self.L(s): d_ma[s][self.K(s), :] = self.transition_density[s]*CL[s].T return d_ma
def fun(coef, wf): grad = full.matrix(coef.size) VBTestH2C.update_wf(coef, wf) mo = wf.C[:, i] dc2 = 2*vb.Nod.S*mo tmp = full.matrix(wf.C.shape) tmp[:, i] = dc2 grad[wf.coef.size:] = tmp.block(*wf.blockdims).ravel(order='F') return grad
def QUab(self): """Quadrupole moment""" if self._QUab is not None: return self._QUab D = self.D R = self.R Rc = self.Rc dRab = self.dRab Qab = self.Qab Dab = self.Dab lab = ("XXSECMOM", "XYSECMOM", "XZSECMOM", "YYSECMOM", "YZSECMOM", "ZZSECMOM") xy = self.getprop(*lab) noa = self.noa QUab = full.matrix((6, noa, noa)) rrab = full.matrix((6, noa, noa)) rRab = full.matrix((6, noa, noa)) RRab = full.matrix((6, noa, noa)) Rab = self.Rab for a in range(noa): for b in range(noa): ij = 0 for i in range(3): for j in range(i, 3): rrab[ij, a, b] = -( xy[ij].subblock[a][b]&D.subblock[a][b] ) rRab[ij, a, b] = Dab[i, a, b]*Rab[a,b,j]+Dab[j, a, b]*Rab[a,b,i] RRab[ij, a, b] = Rab[a,b,i]*Rab[a,b,j]*Qab[a, b] ij += 1 QUab = rrab-rRab-RRab self._QUab = QUab # # Addition term - gauge correction summing up bonds # dQUab = full.matrix(self.QUab.shape) for a in range(noa): for b in range(noa): ij = 0 for i in range(3): for j in range(i, 3): dQUab[ij, a, b] = dRab[a, b, i]*Dab[j, a, b] \ +dRab[a, b, j]*Dab[i, a, b] ij += 1 self.dQUab = - dQUab return self._QUab
def project_virtual_occupied(self, h1): """Rhs derivative <K|h|dL/dC(mu, m)>""" D_mo = self.transition_density delta = self.co_contravariant_transition_delta() K_h_dL = (full.matrix(Nod.C.shape), full.matrix(Nod.C.shape)) CK = self.K.orbitals() for s in (0, 1): if self.K(s) and self.L(s): K_h_dL[s][:, self.L(s)] += \ delta[s]*h1[s].T*CK[s]*D_mo[s]*self.overlap() return K_h_dL
def full_mo_transition_density(self): """ Return mo transition density matrix in full mo basis """ if self._ftd is None: _, mo = Nod.C.shape D_KL = self.transition_density self._ftd = (full.matrix((mo, mo)), full.matrix((mo, mo))) for s in (0, 1): if self.K(s) and self.L(s): D_KL[s].scatter( self._ftd[s], rows=self.K(s), columns=self.L(s) ) return self._ftd
def fock(D, component, **kwargs): """ Generate two-electron spin-orbit Fock matrix from integral file AO2SOINT """ hfc = kwargs.get('hfc', 1.0) hfx = kwargs.get('hfx', 1.0) # left = 1 right = 2 nbast, _ = D.shape J = matrix((nbast, nbast)) JL = matrix((nbast, nbast)) JR = matrix((nbast, nbast)) K = matrix((nbast, nbast)) for buf, ibuf in two.list_buffers(label='AO2SOINT', **kwargs): for g, ig in zip(buf, ibuf): if ig[0] == 0: comp = "*xyz"[ig[1]] else: #print comp, ig, g, component if comp != component: continue p, q, r, s = ig s, r, q, p = (p - 1, q - 1, r - 1, s - 1) if (p == q): g *= 0.5 x = 1.5 * g JL[r, s] += g * (D[p, q] + D[q, p]) JL[s, r] -= g * (D[p, q] + D[q, p]) JR[p, q] += 2 * g * (D[r, s] - D[s, r]) JR[q, p] += 2 * g * (D[r, s] - D[s, r]) K[p, s] -= x * D[r, q] K[s, p] += x * D[q, r] K[p, r] += x * D[s, q] K[r, p] -= x * D[q, s] K[q, s] -= x * D[r, p] K[s, q] += x * D[p, r] K[q, r] += x * D[s, p] K[r, q] -= x * D[p, s] J = JR + JL F = hfc * J + hfx * K return F
def Dao(K, L): """ # Return intermediate normalized ao transition density matrix given # determinants K and L # as [Dalpha, Dbeta] """ if abs(K*L) < SINGULAR_OVERLAP_THRESHOLD: raise SingularOverlapError CK = K.orbitals() CL = L.orbitals() # D = [] for s in range(2): if CK[s] is None or CL[s] is None: # # if None orbitals set atomic density to zero matrix # D.append(full.matrix(Nod.S.shape)) else: SLK = CL[s].T*Nod.S*CK[s] try: D.append(CK[s]*(CL[s].T/SLK)) except LinAlgError: raise SingularOverlapError return D
def vb_transform2(Dma, Dam, Delta1, Delta2, **kwargs): filename = kwargs.get('filename', '/tmp/AOTWOINT') H_umvn = matrix(Dam[0].shape + Dam[0].shape) for ig, g in list_integrals(filename): p, q, r, s = ig s, r, q, p = p-1, q-1, r-1, s-1 if p == q: g *= 0.5 if r == s: g *= 0.5 if (p, q) == (r, s): g *= 0.5 for d1a, d2a, D1a, D2a in zip(Dma, Dam, Delta1, Delta2): for d1b, d2b, D1b, D2b in zip(Dma, Dam, Delta1, Delta2): H_umvn += D1a[p,:].x(d1a[:, q].x(D2b[:, s].x(d2b[r, :]*g))) H_umvn += D1a[q,:].x(d1a[:, p].x(D2b[:, s].x(d2b[r, :]*g))) H_umvn += D1a[p,:].x(d1a[:, q].x(D2b[:, r].x(d2b[s, :]*g))) H_umvn += D1a[q,:].x(d1a[:, p].x(D2b[:, r].x(d2b[s, :]*g))) H_umvn += D1a[r,:].x(d1a[:, s].x(D2b[:, q].x(d2b[p, :]*g))) H_umvn += D1a[r,:].x(d1a[:, s].x(D2b[:, p].x(d2b[q, :]*g))) H_umvn += D1a[s,:].x(d1a[:, r].x(D2b[:, q].x(d2b[p, :]*g))) H_umvn += D1a[s,:].x(d1a[:, r].x(D2b[:, p].x(d2b[q, :]*g))) H_umvn -= D1a[p, :].x(d1a[:, s].x(D2a[:, q].x(d2a[r, :]*g))) H_umvn -= D1a[q, :].x(d1a[:, s].x(D2a[:, p].x(d2a[r, :]*g))) H_umvn -= D1a[p, :].x(d1a[:, r].x(D2a[:, q].x(d2a[s, :]*g))) H_umvn -= D1a[q, :].x(d1a[:, r].x(D2a[:, p].x(d2a[s, :]*g))) H_umvn -= D1a[r, :].x(d1a[:, q].x(D2a[:, s].x(d2a[p, :]*g))) H_umvn -= D1a[r, :].x(d1a[:, p].x(D2a[:, s].x(d2a[q, :]*g))) H_umvn -= D1a[s, :].x(d1a[:, q].x(D2a[:, r].x(d2a[p, :]*g))) H_umvn -= D1a[s, :].x(d1a[:, p].x(D2a[:, r].x(d2a[q, :]*g))) return H_umvn
def vb_transform(dens, delta, **kwargs): filename = kwargs.get('filename', '/tmp/AOTWOINT') a, m = dens[0].shape H_uvmn = matrix((a, a, m, m)) for ig, g in list_integrals(filename): p, q, r, s = ig s, r, q, p = p-1, q-1, r-1, s-1 if p == q: g *= 0.5 if r == s: g *= 0.5 if (p, q) == (r, s): g *= 0.5 for d1, D1 in zip(dens, delta): for d2, D2 in zip(dens, delta): H_uvmn += D1[:, q].x(D2[:, s].x(d1[p, :].x(d2[r, :]*g))) H_uvmn += D1[:, p].x(D2[:, s].x(d1[q, :].x(d2[r, :]*g))) H_uvmn += D1[:, q].x(D2[:, r].x(d1[p, :].x(d2[s, :]*g))) H_uvmn += D1[:, p].x(D2[:, r].x(d1[q, :].x(d2[s, :]*g))) H_uvmn += D1[:, s].x(D2[:, q].x(d1[r, :].x(d2[p, :]*g))) H_uvmn += D1[:, r].x(D2[:, q].x(d1[s, :].x(d2[p, :]*g))) H_uvmn += D1[:, s].x(D2[:, p].x(d1[r, :].x(d2[q, :]*g))) H_uvmn += D1[:, r].x(D2[:, p].x(d1[s, :].x(d2[q, :]*g))) H_uvmn -= D1[:, s].x(D1[:, q].x(d1[p, :].x(d1[r, :]*g))) H_uvmn -= D1[:, s].x(D1[:, p].x(d1[q, :].x(d1[r, :]*g))) H_uvmn -= D1[:, r].x(D1[:, q].x(d1[p, :].x(d1[s, :]*g))) H_uvmn -= D1[:, r].x(D1[:, p].x(d1[q, :].x(d1[s, :]*g))) H_uvmn -= D1[:, q].x(D1[:, s].x(d1[r, :].x(d1[p, :]*g))) H_uvmn -= D1[:, q].x(D1[:, r].x(d1[s, :].x(d1[p, :]*g))) H_uvmn -= D1[:, p].x(D1[:, s].x(d1[r, :].x(d1[q, :]*g))) H_uvmn -= D1[:, p].x(D1[:, r].x(d1[s, :].x(d1[q, :]*g))) return H_uvmn.transpose(0, 2, 1, 3)
def test_quadrupole_allbonds(self): QU = full.matrix(ref.QU.shape) QUab = self.m.QUab for ab, a, b in pairs(self.m.noa): QU[:, ab] += QUab[:, a, b ] if a != b: QU[:, ab] += QUab[:, b, a] self.assert_allclose(QU, ref.QU)
def Bab(self): """Localized hyperpolariziabilities""" if self._Bab is not None: return self._Bab D2k = self.D2k Rab = self.Rab d2Qa = self.d2Qa x = self.x labs = ('XDIPLEN ', 'YDIPLEN ', 'ZDIPLEN ') qlabs = [labs[i] + labs[j] for i in range(3) for j in range(i,3)] Bab = full.matrix( (self.nfreqs, 3, 6, self.noa, self.noa) ) #correction term for shifting origin from O to Rab for i, li in enumerate(labs): for jk,ljk in enumerate(qlabs): for a in range(self.noa): for b in range(self.noa): for iw, w in enumerate(self.freqs): Bab[iw, i, jk, a, b] = ( -x[i].subblock[a][b] & D2k [(ljk, w, w)].subblock[a][b] ) for iw in self.rfreqs: Bab[iw, i, jk, a, a] -= d2Qa[iw, a, jk]*Rab[a, a, i] self._Bab = Bab return self._Bab
def ifc(filename="SIRIFC", ifc_=None): """ Return inactive/active densities from orbitals on interface file SIRIFC """ if ifc_ is None: ifc_ = sirifc.sirifc(filename) Di = blocked.BlockDiagonalMatrix(ifc_.nbas, ifc_.nbas) for isym in range(ifc_.nsym): if ifc_.nish[isym]: Ci = ifc_.cmo.subblock[isym] Cocci = Ci[:, : ifc_.nish[isym]] Di.subblock[isym] = 2 * Cocci @ Cocci.T Di = Di.unblock() if ifc_.nasht: cmoa = blocked.BlockDiagonalMatrix(ifc_.nbas, ifc_.nash) for isym in range(ifc_.nsym): if ifc_.nash[isym]: nishi = ifc_.nish[isym] nocci = ifc_.nish[isym] + ifc_.nash[isym] cmoa.subblock[isym] = ifc_.cmo.subblock[isym][:, nishi:nocci] cmoa = cmoa.unblock() Dv = cmoa @ ifc_.dv.unpack() @ cmoa.T else: Dv = full.matrix((ifc_.nbast, ifc_.nbast)) return Di, Dv
def constraint_norm_grad(coef, wf): grad = full.matrix(coef.size) VBTestH2C.update_wf(coef, wf) sg, og = wf.normgrad() grad[:wf.coef.size] = sg grad[wf.coef.size:] = og.block(*wf.blockdims).ravel(order='F') return grad
def test_dipole_allbonds(self): D = full.matrix(ref.D.shape) Dab = self.m.Dab for ab, a, b in pairs(self.m.noa): D[:, ab] += Dab[:, a, b ] if a != b: D[:, ab] += Dab[:, b, a] self.assert_allclose(D, ref.D)
def wf_gradient(coef, wf): grad = full.matrix(coef.size) VBTestH2C.update_wf(coef, wf) sg, og = wf.energygrad() grad[:wf.coef.size] = sg grad[wf.coef.size:] = og.block(*wf.blockdims).ravel(order='F') return grad
def test_quadrupole_allbonds(self, molfrag): QU = full.matrix(ref.QU.shape) QUab = molfrag.QUab for ab, a, b in pairs(molfrag.noa): QU[:, ab] += QUab[:, a, b] if a != b: QU[:, ab] += QUab[:, b, a] self.assert_allclose(QU, ref.QU)
def test_dipole_allbonds(self, molfrag): D = full.matrix(ref.D.shape) Dab = molfrag.Dab for ab, a, b in pairs(molfrag.noa): D[:, ab] += Dab[:, a, b] if a != b: D[:, ab] += Dab[:, b, a] self.assert_allclose(D, ref.D)
def mkB2(vecs): B = full.matrix(len(vecs) + 1, len(vecs) + 1) for i in range(len(vecs)): for j in range(len(vecs)): B[i, j] = -(vecs[i] * vecs[j]).tr() B[i, len(vecs)] = -1 B[len(vecs), i] = -1 return B
def grad(x, self): _x = self.x self.x = x p = self.p dL = full.matrix(len(x)) dL[:len(p)] = self.gp(p) - sum(l*c['jac'](p) for l, c in zip(self.l, self.cp)) dL[len(p):] = [-c['fun'](p) for c in self.cp] self.x = _x return dL
def project_occupied_virtual(self, h1): """Lhs derivative <dK/dC(mu,m)|h|L>""" D_mo = self.transition_density delta = self.contra_covariant_transition_delta() dK_h_La = full.matrix(Nod.C.shape[::-1]) dK_h_Lb = full.matrix(Nod.C.shape[::-1]) CL = self.L.orbitals() if self.L(0): dK_h_La[self.K(0), :] += \ D_mo[0]*CL[0].T*h1[0].T*delta[0]*self.overlap() if self.L(1): dK_h_Lb[self.K(1), :] += \ D_mo[1]*CL[1].T*h1[1].T*delta[1]*self.overlap() return dK_h_La.T, dK_h_Lb.T
def tovec(mat, ifc, tmpdir="/tmp"): """Vector to matrix""" lwop = ifc.nisht * ifc.nasht + ifc.nocct * (ifc.norbt - ifc.nocct) N = full.matrix((2 * lwop, )) for ij, (i, j) in enumerate(jwop(ifc)): N[ij] = mat[i, j] N[ij + lwop] = mat[j, i] return N
def test_quadrupole_total(self): rrab=full.matrix((6, self.m.noa, self.m.noa)) rRab=full.matrix((6, self.m.noa, self.m.noa)) RRab=full.matrix((6, self.m.noa, self.m.noa)) Rabc = 1.0*self.m.Rab for a in range(self.m.noa): for b in range(self.m.noa): Rabc[a,b,:] -= self.m.Rc for a in range(self.m.noa): for b in range(self.m.noa): ij = 0 for i in range(3): for j in range(i,3): rRab[ij, a, b] = self.m.Dab[i, a, b]*Rabc[a, b, j]\ + self.m.Dab[j, a, b]*Rabc[a, b, i] RRab[ij, a, b] = self.m.Qab[a, b]*(self.m.R[a, i] - self.m.Rc[i])*(self.m.R[b, j] - self.m.Rc[j]) ij += 1 QUcab = self.m.QUab + rRab + RRab QUc = QUcab.sum(axis=2).sum(axis=1).view(full.matrix) self.assert_allclose(QUc, ref.QUc)
def ao_density(self): """Electron number check""" D_ao = full.matrix(Nod.S.shape) for S, CS in zip(self.structs, self.coef): for T, CT in zip(self.structs, self.coef): for K, CK in zip(S.nods, S.coef): for L, CL in zip(T.nods, T.coef): KL = BraKet(K, L) DKL = KL.transition_ao_density D_ao += sum(DKL)*CS*CT*CK*CL*KL.overlap() return D_ao/self.norm()
def hess(x, self): _x = self.x self.x = x p = self.p d2L = full.matrix((len(x), len(x))) d2L[:len(p), :len(p)] = self.hp(p) - sum(l*c['hes'](p) for l, c in zip(self.l, self.cp)) for i, c in enumerate(self.cp): d2L[:len(p), len(p) + i] = -c['jac'](p) d2L[len(p):, :len(p)] = d2L[:len(p), len(p):].T d2L[len(p):, len(p):] = 0.0 self.x = _x return d2L
def tovec(mat, ifc, tmpdir='/tmp'): """Vector to matrix""" import os from util import full lwop = ifc.nisht*ifc.nasht + ifc.nocct*(ifc.norbt-ifc.nocct) N = full.matrix((2*lwop,)) ij = 0 for i, j in jwop(ifc): N[ij] = mat[i, j] N[ij+lwop] = mat[j, i] ij += 1 return N
def tomat(N, ifc, tmpdir="/tmp"): """Vector to matrix""" norbt = ifc.norbt new = full.matrix((norbt, norbt)) lwop = len(N) // 2 for ij, (i, j) in enumerate(jwop(ifc)): new[i, j] = N[ij] new[j, i] = N[ij + lwop] return new
def get_dens(self, ndim, idim, nocc=None): if nocc is None: nocc_ = [1]*len(ndim) else: nocc_ = nocc dens = matrix((self.nbast, self.nbast)) for ni, no, offset in zip(ndim, nocc_, idim): if ni > 0: cmoi = self.cmo[:, offset: offset + ni] dens += no*cmoi*cmoi.T return dens
def test_polarizability_nobonds(self, molfrag): Aab = molfrag.Aab[0] + molfrag.dAab[0] / 2 noa = molfrag.noa Acmp = full.matrix((6, noa)) Aa = Aab.sum(axis=3).view(full.matrix) for a in range(noa): Acmp[:, a] = Aa[:, :, a].pack() # atoms self.assert_allclose(Acmp, ref.Aa, atol=0.07)
def get_dens(self, ndim, idim, nocc=None): if nocc is None: nocc_ = [1] * len(ndim) else: nocc_ = nocc dens = matrix((self.nbast, self.nbast)) for ni, no, offset in zip(ndim, nocc_, idim): if ni > 0: cmoi = self.cmo[:, offset:offset + ni] dens += no * cmoi * cmoi.T return dens
def test_bond_charge_shift(self, molfrag): dQab = molfrag.dQab[0] noa = molfrag.noa dQabref = (ref.dQab[:, 1:7:2] - ref.dQab[:, 2:7:2]) / (2 * ref.ff) dQabcmp = full.matrix((3, 3)) ab = 0 for a in range(noa): for b in range(a): dQabcmp[ab, :] = dQab[a, b, :] ab += 1 # The sign difference is because mocas sets up rhs with opposite sign self.assert_allclose(-dQabref, dQabcmp, atol=0.006)
def test_bond_charge_shift(self): dQab = self.m.dQab[0] noa = self.m.noa dQabref = (ref.dQab[:, 1:7:2] - ref.dQab[:, 2:7:2])/(2*ref.ff) dQabcmp = full.matrix((3, 3)) ab = 0 for a in range(noa): for b in range(a): dQabcmp[ab, :] = dQab[a, b, :] ab += 1 # The sign difference is because mocas sets up rhs with opposite sign self.assert_allclose(-dQabref, dQabcmp, atol=0.006)
def QUc(self): if self._QUc is not None: return self._QUc rrab=full.matrix((6, self.noa, self.noa)) rRab=full.matrix((6, self.noa, self.noa)) RRab=full.matrix((6, self.noa, self.noa)) Rabc = 1.0*self.Rab for a in range(self.noa): for b in range(self.noa): Rabc[a,b,:] -= self.Rc for a in range(self.noa): for b in range(self.noa): ij = 0 for i in range(3): for j in range(i,3): rRab[ij, a, b] = self.Dab[i, a, b]*Rabc[a, b, j]\ + self.Dab[j, a, b]*Rabc[a, b, i] RRab[ij, a, b] = self.Qab[a, b]*(self.R[a, i] - self.Rc[i])*(self.R[b, j] - self.Rc[j]) ij += 1 QUcab = self.QUab + rRab + RRab self._QUc = QUcab.sum(axis=2).sum(axis=1).view(full.matrix) return self._QUc
def tomat(N, ifc, tmpdir='/tmp'): """Vector to matrix""" import os from util import full norbt = ifc.norbt new = full.matrix((norbt, norbt)) lwop = len(N)/2 ij = 0 for i, j in jwop(ifc): new[i, j] = N[ij] new[j, i] = N[ij+lwop] ij += 1 return new
def setUp(self): self.tmp = os.path.join(os.path.dirname(__file__), 'test_h2_c') def tmp(fil): return os.path.join(self.tmp, fil) self.qcifc = QuantumChemistry.get_factory('Dalton', tmpdir=self.tmp) vb.Nod.tmpdir = self.tmp vb.Nod.C = full.matrix((10, 2)) vb.Nod.C[0, 0] = 1.0 vb.Nod.C[5, 1] = 1.0 vb.Nod.S = self.qcifc.get_overlap() self.blockdims = ((5, 5), (1, 1)) self.wf = vb.WaveFunction( [vb.Structure( [vb.Nod([0], [1]), vb.Nod([1], [0])], [1.0, 1.0] ), vb.Structure([vb.Nod([0], [0])], [1.0]), vb.Structure([vb.Nod([1], [1])], [1.0]), ], [1.0, 0.0, 0.0], tmpdir = self.tmp, blockdims=self.blockdims ) # In this setup we have local expansions of mos, leading to a block diagonal C self.final = full.matrix(13) self.final_coef =[0.83675, 0.09850, 0.09850] self.final[:3] = self.final_coef self.final_C = full.init([ [0.7633862173, 0.3075441467, 0.0, 0.0, 0.0328947818,0,0,0,0,0], [0,0,0,0,0, 0.7633862173, 0.3075441467, 0.0, 0.0, -0.0328947818] ]) self.final[3:8] = self.final_C[:5, 0] self.final[8:13] = self.final_C[5:, 1] self.wf.normalize_structures() self.xfg = VBMinimizer(self.wf)
def test_polarizability_nobonds(self): Aab = self.m.Aab[0] + self.m.dAab[0]/2 noa = self.m.noa Acmp = full.matrix((6, noa )) Aa = Aab.sum(axis=3).view(full.matrix) ab = 0 for a in range(noa): Acmp[:, a,] = Aa[:, :, a].pack() # atoms self.assert_allclose(Acmp, ref.Aa, atol=0.07)
def get_molecule_info(self): """ ` Get overlap, nuclear charges and coordinates from AOONEINT """ # # Data from the ISORDK section in AOONEINT # isordk = one.readisordk(filename=self.aooneint) # # Number of nuclei # N = isordk["nucdep"] # # MXCENT , Fix dimension defined in nuclei.h # mxcent = len(isordk["chrn"]) # # Nuclear charges # self.Z = full.matrix((N, )) self.Z[:] = isordk["chrn"][:N] # # Nuclear coordinates # R = full.matrix((mxcent * 3, )) R[:] = isordk["cooo"][:] self.R = R.reshape((mxcent, 3), order="F")[:N, :] # # Bond center matrix and half bond vector # noa = self.noa self.Rab = full.matrix((noa, noa, 3)) self.dRab = full.matrix((noa, noa, 3)) for a in range(noa): for b in range(noa): self.Rab[a, b, :] = (self.R[a, :] + self.R[b, :]) / 2 self.dRab[a, b, :] = (self.R[a, :] - self.R[b, :]) / 2
def mkB3(avecs, bvecs, unrest): dim = len(avecs) B = full.matrix((dim + 1, dim + 1)) for i in range(dim): for j in range(dim): if unrest: B[i, j] = -(avecs[i] @ avecs[j]).tr() - ( bvecs[i] @ bvecs[j]).tr() else: vecsi = avecs[i] + bvecs[i] vecsj = avecs[j] + bvecs[j] B[i, j] = (vecsi @ vecsj.T).tr() B[i, dim] = -1 B[dim, i] = -1 return B
def pv(self): """Get two-electron density""" if self._pv is None: with FortranBinary(self.name) as fb: fb.find(self.ifclabel) for i in range(7): fb.next() m2ashy = max(self.nnashx**2, 4) dbl = fb.readbuf(m2ashy, self.FLOAT) self._pv = full.matrix((self.nnashx, self.nnashx)) n = 0 for i in range(self.nnashx): for j in range(self.nnashx): self._pv[j, i] = dbl[n] n += 1 assert n == self.nnashx**2 return self._pv
def test_polarizability_allbonds_atoms(self, molfrag): Aab = molfrag.Aab[0] # + molfrag.dAab[0] noa = molfrag.noa Acmp = full.matrix(ref.Aab.shape) ab = 0 for a in range(noa): for b in range(a): Acmp[:, ab] = (Aab[:, :, a, b] + Aab[:, :, b, a]).pack() ab += 1 Acmp[:, ab] = Aab[:, :, a, a].pack() ab += 1 # atoms self.assert_allclose(ref.Aab[:, 0], Acmp[:, 0], atol=0.005) self.assert_allclose(ref.Aab[:, 2], Acmp[:, 2], atol=0.005) self.assert_allclose(ref.Aab[:, 5], Acmp[:, 5], atol=0.005)
def test_polarizability_allbonds_bonds(self, molfrag): Aab = molfrag.Aab[0] + molfrag.dAab[0] / 2 noa = molfrag.noa Acmp = full.matrix(ref.Aab.shape) ab = 0 for a in range(noa): for b in range(a): Acmp[:, ab] = (Aab[:, :, a, b] + Aab[:, :, b, a]).pack() ab += 1 Acmp[:, ab] = Aab[:, :, a, a].pack() ab += 1 # atoms self.assert_allclose(ref.Aab[:, 1], Acmp[:, 1], atol=0.150, err_msg="H1O") self.assert_allclose(ref.Aab[:, 3], Acmp[:, 3], atol=0.150, err_msg="H2O") self.assert_allclose(ref.Aab[:, 4], Acmp[:, 4], atol=0.005, err_msg="H2H1")
def read(label="OVERLAP", filename="AOONEINT"): """Read integral for label""" lbuf = 600 # # Initialize # unlabeled = readhead(filename) nsym = unlabeled["nsym"] nbas = unlabeled["naos"] INT = unlabeled["int_fmt"] FLOAT = unlabeled["float_fmt"] nnbast = 0 for nbasi in nbas: nnbast += nbasi * (nbasi + 1) // 2 s = full.matrix((nnbast, )) # # Open file, locate label # aooneint = FortranBinary(filename) aooneint.find(label) # # Loop over records # for rec in aooneint: buf = rec.read(lbuf, FLOAT) ibuf = rec.read(lbuf, INT) length, = rec.read(1, INT) if length < 0: break for i, b in zip(ibuf[:length], buf[:length]): s[i - 1] = b _S = blocked.triangular(nbas) off = 0 for isym in range(nsym): nbasi = nbas[isym] * (nbas[isym] + 1) // 2 _S.subblock[isym] = np.array(s[off:off + nbasi]).view(full.triangular) off += nbasi # aooneint.close() return _S
def cmo(F, S, filename="AOONEINT"): """ Return MO coefficients from diagonalization of a provided Fock matrix F, an optional overlap matrix S. The returned MOs are normalized and ordered with respect to eigenvalue """ nbast = F.shape[0] e, V = F.eigvec(S) C = full.matrix((nbast, nbast)) N2 = (V.T @ S @ V).diagonal() for i in range(nbast): Ni = 1.0 / sqrt(N2[i]) C[:, i] = V[:, i] * Ni rephase_columns(C, inplace=True) # # Finish off with Gram Schmidt because degenerate orbitals are not # properly orthonormalized # C = C.GS(S) # # return C
import numpy from util.full import matrix d = matrix((24, 24)) f = matrix((24, 24)) d[:11, :5] = numpy.array([ [ 2.00160706, -0.01036708, -0.00181429, 0.00677187, -0.00241386], [-0.01036708, 1.69869523, -0.09633899, -0.27114604, -0.10920586], [-0.00181429, -0.09633899, 0.08874347, -0.30570693, 0.01352778], [ 0.00677187, -0.27114604, -0.30570693, 1.28122865, -0.01084007], [-0.00241386, -0.10920586, 0.01352778, -0.01084007, 0.00767067], [ 0.00006681, -0.00823265, -0.00653547, 0.02831209, -0.00008716], [-0.00018734, -0.00235146, 0.00228316, -0.00791291, 0.00034070], [-0.00389444, 0.35145795, -0.19737922, 0.62805954, -0.03821221], [ 0.00283175, -0.18331099, 0.08114304, -0.24351160, 0.01800991], [ 0.00146798, -0.04495921, 0.01951429, -0.05823360, 0.00438197], [ 0.00123945, -0.03923112, 0.00210759, 0.00671245, 0.00251033] ]) d[:11, 5:10] = numpy.array([ [ 0.00006681, -0.00018734, -0.00389444, 0.00283175, 0.00146798], [-0.00823265, -0.00235146, 0.35145795, -0.18331099, -0.04495921], [-0.00653547, 0.00228316, -0.19737922, 0.08114304, 0.01951429], [ 0.02831209, -0.00791291, 0.62805954, -0.24351160, -0.05823360], [-0.00008716, 0.00034070, -0.03821221, 0.01800991, 0.00438197], [ 0.00062869, -0.00016935, 0.01321749, -0.00506051, -0.00120868], [-0.00016935, 0.00005876, -0.00506668, 0.00207976, 0.00050004], [ 0.01321749, -0.00506668, 0.45083132, -0.18868220, -0.04545457], [-0.00506051, 0.00207976, -0.18868220, 0.07988865, 0.01926631], [-0.00120868, 0.00050004, -0.04545457, 0.01926631, 0.00464710],
def udiis( Ca, Cb, na, nb, iters=10, fock=jensen, hfx=1, threshold=1e-6, maxerr=2, unrest=False, wrkdir="/tmp", ): print(Ca, Cb) saveD = 1 saveC = 0 E = 0 aooneint = os.path.join(wrkdir, "AOONEINT") aotwoint = os.path.join(wrkdir, "AOTWOINT") potnuc = one.readhead(aooneint)["potnuc"] vecs = [] vecsa = [] vecsb = [] evecsa = [] evecsb = [] Eit = [] S = one.read("OVERLAP", aooneint).unpack().unblock() h = S.I @ one.read("ONEHAMIL", aooneint).unpack().unblock() Da = dens.C1D(Ca, na) @ S Db = dens.C1D(Cb, nb) @ S try: for i in range(iters): Da = dens.C1D(Ca, na) @ S Db = dens.C1D(Cb, nb) @ S print("D", (Da + Db) @ S.I) (Fa, Fb), = two.fockab((Da, Db), hfx=hfx, filename=aotwoint) Fa = h + S.I @ Fa Fb = h + S.I @ Fb E0 = E E = ((Da @ (h + Fa)) + (Db @ (h + Fb))).tr() / 2 + potnuc D = Da + Db print("hd", (h @ D).tr(), h & D, h & D.T) print("FD", Fa & Da) Eit.append(E) ga = Da @ Fa - Fa @ Da gb = Db @ Fb - Fb @ Db if unrest: g2 = -(ga @ ga + gb @ gb) else: g2 = -(ga + gb) @ (ga + gb) gn = math.sqrt(g2.tr()) print("%2d:E = %16.12f %16.5e %16.2e" % (i + 1, E, gn, E - E0)) if gn < threshold: raise Converged(gn) # if E > E0: # raise Exception("Energy increase") if unrest: Ca = dens.cmo(Fa) Cb = dens.cmo(Fb) # Ca = Ca*Ua # Cb = Cb*Ub else: Ca = dens.cmo(Feff(Da, Db, Fa, Fb), S) Cb = Ca[:, :] Da = dens.C1D(Ca, na) @ S Db = dens.C1D(Cb, nb) @ S if saveD: vecsa.append(Da) vecsb.append(Db) evecsa.append(ga @ Da - Da @ ga) evecsb.append(gb @ Db - Db @ gb) elif saveC: vecsa.append(Ca) vecsb.append(Cb) evecsa.append(ga) evecsb.append(gb) else: vecsa.append(Fa) vecsb.append(Fb) evecsa.append(ga) evecsb.append(gb) edim = min(len(evecsa), maxerr) eva = evecsa[-edim:] evb = evecsb[-edim:] fva = vecsa[-edim:] fvb = vecsb[-edim:] B = mkB3(eva, evb, unrest) rhs = full.matrix((edim + 1, 1)) rhs[-1, 0] = -1 c = rhs / B subvecsa = full.matrix(Fa.shape) subvecsb = full.matrix(Fb.shape) for j in range(edim): subvecsa += c[j, 0] * fva[j] subvecsb += c[j, 0] * fvb[j] if saveD: Da = subvecsa Db = subvecsb (Fa, Fb), = two.fockab((Da, Db), hfx=hfx, filename=aotwoint) Fa = h + S.I @ Fa Fb = h + S.I @ Fb vecsa[i] = Da vecsb[i] = Db elif saveC: Ca = subvecsa Cb = subvecsb Da = dens.C1D(Ca, na) @ S Db = dens.C1D(Cb, nb) @ S else: Fa = subvecsa Fb = subvecsb Da = dens.C1D(Ca, na) @ S Db = dens.C1D(Cb, nb) @ S except Converged: print("Converged after %d iterations\n" % (i + 1, )) except Increase: print("Ca Cb", Ca, Cb) print("Da Db", Da, Db) print("Na Nb", Da.tr(), Db.tr()) print("Fa Fb", Fa, Fb) print("E1", (h * (Da + Db)).tr()) print("E2", (Fa * Da + Fb * Db).tr() / 2 - (h * (Da + Db)).tr() / 2) print("E", E - potnuc)
def diis( C, nisht, nasht, iters=10, fock=jensen, hfx=1, threshold=1e-6, maxerr=2, wrkdir="/tmp", ): C1 = C E = 0 aooneint = pathlib.Path(wrkdir) / "AOONEINT" aotwoint = pathlib.Path(wrkdir) / "AOTWOINT" potnuc = one.readhead(aooneint)["potnuc"] vecs = [] evecs = [] h = one.read("ONEHAMIL", aooneint).unpack().unblock() S = one.read("OVERLAP", aooneint).unpack().unblock() try: for i in range(iters): Di, Da = dens.C2D(C, nisht, nasht) D = Di + Da Fc = h + two.fock(D, filename=aotwoint, hfx=hfx) Fo = two.fock(Da, hfc=0, filename=aotwoint) + Fc F = fock(S, Di, Da, Fc, Fo, C, h) E0 = E E = ((h + Fc) & D) / 2 + ((Fo - Fc) & Da) / 2 + potnuc g = grad(S, C1, Di, Da, Fc, Fo) # gao = gradao(S, C, Di, Da, Fc, Fo) gn = gradvec(S, C, Di, Da, Fc, Fo, nisht, nasht).norm2() gn /= math.sqrt(2) print("%2d:E = %16.12f %16.5e %16.2e" % (i + 1, E, gn, E - E0)) if gn < threshold: raise Converged(gn) vecs.append(F) evecs.append(g) edim = min(len(evecs), maxerr) ev = evecs[-edim:] fv = vecs[-edim:] B = mkB(ev) rhs = full.matrix((edim + 1, 1)) rhs[-1, 0] = 1 c = rhs / B subevecs = full.matrix(g.shape) subvecs = full.matrix(F.shape) for i in range(edim): subevecs += c[i, 0] * ev[i] subvecs += c[i, 0] * fv[i] update = -subevecs upd = update.lower() upd.anti = 0 update = upd.unpack() F = subvecs # +update C = dens.cmo(F, S) except Converged: print("-Converged-") except Stop: print("-STOP-")
import numpy from util.full import matrix cmo = matrix((24, 24)) cmo[:11, :11] = numpy.array( [[ 1.00037005644774, 0.00213928142197, -0.00139645162733, 0.00250320614892, -0.00168365551156, 0.00000417179213, -0.00010568751627, -0.00027311036476, 0.00056204660778, 0.00052477299313, 0.00045051613113 ], [ -0.00764995676695, 0.87372007927195, -0.11446369166089, 0.11081294767437, -0.06188049075196, 0.00122390477237, -0.00288482651200, 0.31909593297047, -0.14943668512171, -0.03635107656087, -0.02008905901125 ], [ 0.00218188411380, -0.29318297900759, -0.17682717408706, 0.79267177820451, 0.00181832874368, 0.01768753372185, -0.00458766924852, 0.35155848740093, -0.13271279540296, -0.03165237343243, 0.00704103155682 ], [ 0.05189274589511, -0.14332375175701, -0.90584515407463, -0.28547304713507, -0.21170912054705, -0.00753222886420, 0.00920238615519, 0.10575589422514, 0.76987725358803, -0.01621298099706, -0.01563551317394 ], [ 0.06833791423126, 0.50854763250820, -0.61069110991343,
def setup_class(cls): numpy.random.seed(0) cls.beta = full.matrix((3, 6)).random() cls.dipole = full.matrix(3).random()
def fockab(Da, Db, component, **kwargs): """ Generate two-electron spin-orbit Fock(alpha,beta) matrix from integral file AO2SOINT Input: component 'x', 'y', or 'z' Density matrices, tuple (Da, Db) AO integral file, FortranBinary object, positioned Output Fock matrics, tuple(Fa, Fb) """ hfc = kwargs.get('hfc', 1.0) hfx = kwargs.get('hfx', 1.0) Fa = matrix(Da.shape) Fb = matrix(Db.shape) for buf, ibuf in two.list_buffers(label='AO2SOINT', **kwargs): for g, ig in zip(buf, ibuf): if ig[0] == 0: comp = "*xyz"[ig[1]] else: #print comp, ig, g, component if comp != component: continue p, q, r, s = ig s, r, q, p = (p - 1, q - 1, r - 1, s - 1) if (p == q): g *= 0.5 j = hfc * g x = 3 * hfx * g #Fa[p,q]=(pq|rs)(2D+(r,s) + D-(r,s)) Fapq = j * (3 * (Da[r, s] - Da[s, r]) + Db[r, s] - Db[s, r]) Fa[p, q] += Fapq Fa[q, p] += Fapq #Fb[p,q]=(pq|rs)(-2D+(r,s) + D-(r,s)) Fbpq = j * (-(Da[r, s] - Da[s, r]) - 3 * (Db[r, s] - Db[s, r])) Fb[p, q] += Fbpq Fb[q, p] += Fbpq #Fa[r,s]=(pq|rs)(2D-(p,p) + D+(p,q)) Fars = j * (3 * (Da[p, q] + Da[q, p]) - Db[p, q] - Db[q, p]) Fa[r, s] += Fars Fa[s, r] -= Fars #Fb[r,s]=(pq|rs)(2D+(p,q) - D-(p,q)) Fbrs = j * (Da[p, q] + Da[q, p] - 3 * (Db[p, q] + Db[q, p])) Fb[r, s] += Fbrs Fb[s, r] -= Fbrs Fa[p, s] -= x * Da[r, q] Fa[q, s] -= x * Da[r, p] Fa[p, r] += x * Da[s, q] Fa[q, r] += x * Da[s, p] Fb[p, s] += x * Db[r, q] Fb[q, s] += x * Db[r, p] Fb[p, r] -= x * Db[s, q] Fb[q, r] -= x * Db[s, p] Fa[r, q] -= x * Da[p, s] Fa[r, p] -= x * Da[q, s] Fa[s, q] += x * Da[p, r] Fa[s, p] += x * Da[q, r] Fb[r, q] += x * Db[p, s] Fb[r, p] += x * Db[q, s] Fb[s, q] -= x * Db[p, r] Fb[s, p] -= x * Db[q, r] return (Fa, Fb)
1 1.481 0.000 -0.349 0.352 -0.153 0.000 0.127 -0.132 -0.000 -0.250 -0.445 0.000 -0.261 """ PA21 = """AU 3 2 1 1 1 0.000 0.000 0.698 -0.703 -0.000 0.000 -0.284 -3.293 0.000 -0.000 -4.543 -0.000 -4.005 3.466 1 -1.481 0.000 -0.349 0.352 0.153 0.000 0.127 -0.132 0.000 0.250 -0.445 0.000 -0.261 1.576 1 1.481 0.000 -0.349 0.352 -0.153 0.000 0.127 -0.132 -0.000 -0.250 -0.445 0.000 -0.261 1.576 """ PA22 = """AU 3 2 2 1 1 0.000 0.000 0.698 -0.703 -0.000 0.000 -0.284 -3.293 0.000 -0.000 -4.543 -0.000 -4.005 3.875 -0.000 -0.000 3.000 -0.000 3.524 1 -1.481 0.000 -0.349 0.352 0.153 0.000 0.127 -0.132 0.000 0.250 -0.445 0.000 -0.261 2.156 -0.000 1.106 1.051 -0.000 1.520 1 1.481 0.000 -0.349 0.352 -0.153 0.000 0.127 -0.132 -0.000 -0.250 -0.445 0.000 -0.261 2.156 -0.000 -1.106 1.051 -0.000 1.520 """ Bm = matrix((3, 6)) # matrix components (x, y, z)(T) * (xx xy xz yy yz zz) # xxz, zxx Bm[0, 2] = Bm[2, 0] = 14.74097586 # yyz, zyy Bm[1, 4] = Bm[2, 3] = 3.28345383 # zzz Bm[2, 5] = 9.20782221 OUTPUT_BY_ATOM_n0 = """\ --------------- Atomic domain 1 --------------- Domain center: 0.00000 0.00000 0.69801 Nuclear charge: 8.00000