Source code for pyscf.grad.uccsd_t

#!/usr/bin/env python
# Copyright 2014-2019 The PySCF Developers. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# 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.
#
# Author: Qiming Sun <osirpt.sun@gmail.com>
#

from pyscf import lib
from pyscf.cc import uccsd_t_rdm
from pyscf.grad import uccsd as uccsd_grad

# Only works with canonical orbitals
[docs] def grad_elec(cc_grad, t1=None, t2=None, l1=None, l2=None, eris=None, atmlst=None, verbose=lib.logger.INFO): mycc = cc_grad.base if t1 is None: t1 = mycc.t1 if t2 is None: t2 = mycc.t2 if l1 is None: l1 = mycc.l1 if l2 is None: l2 = mycc.l2 if eris is None: eris = mycc.ao2mo() d1 = uccsd_t_rdm._gamma1_intermediates(mycc, t1, t2, l1, l2, eris, for_grad=True) fd2intermediate = lib.H5TmpFile() d2 = uccsd_t_rdm._gamma2_outcore(mycc, t1, t2, l1, l2, eris, fd2intermediate, True) cc_grad = uccsd_grad.Gradients(mycc) de = uccsd_grad.grad_elec(cc_grad, t1, t2, l1, l2, eris, atmlst, d1, d2, verbose) return de
[docs] class Gradients(uccsd_grad.Gradients): grad_elec = grad_elec
if __name__ == '__main__': from pyscf import gto from pyscf import scf from pyscf import cc from pyscf.cc import uccsd_t from pyscf.cc import uccsd_t_lambda mol = gto.M( verbose = 0, atom = [ ["O" , (0. , 0. , 0. )], [1 , (0. ,-0.757 ,-0.587)], [1 , (0. , 0.757 ,-0.587)]], basis = '631g', spin=2, ) mf = scf.UHF(mol) mf.conv_tol = 1e-14 ehf = mf.scf() mycc = cc.UCCSD(mf) mycc.conv_tol = 1e-10 mycc.conv_tol_normt = 1e-10 ecc, t1, t2 = mycc.kernel() eris = mycc.ao2mo() e3ref = uccsd_t.kernel(mycc, eris, t1, t2) print(ehf+ecc+e3ref) conv, l1, l2 = uccsd_t_lambda.kernel(mycc, eris, t1, t2) g1 = Gradients(mycc).kernel(t1, t2, l1, l2, eris=eris) print(g1) myccs = mycc.as_scanner() mol.atom[0] = ["O" , (0., 0., 0.001)] mol.build(0, 0) e1 = myccs(mol) e1 += myccs.ccsd_t() mol.atom[0] = ["O" , (0., 0.,-0.001)] mol.build(0, 0) e2 = myccs(mol) e2 += myccs.ccsd_t() print(g1[0,2], (e1-e2)/0.002*lib.param.BOHR) #O 0. 0.0000000 -0.1480942 #H 0. 0.1122898 0.0740461 #H 0. -0.1122898 0.0740461 mol = gto.M( verbose = 0, atom = ''' H -1.90779510 0.92319522 0.08700656 H -1.08388168 -1.61405643 -0.07315086 H 2.02822318 -0.61402169 0.09396693 H 0.96345360 1.30488291 -0.10782263 ''', unit='bohr', basis = '631g') mf = scf.UHF(mol) mf.conv_tol = 1e-14 ehf0 = mf.scf() mycc = cc.UCCSD(mf) mycc.conv_tol = 1e-10 mycc.conv_tol_normt = 1e-10 ecc, t1, t2 = mycc.kernel() eris = mycc.ao2mo() e3ref = uccsd_t.kernel(mycc, eris, t1, t2) print(ehf0+ecc+e3ref) eris = mycc.ao2mo(mf.mo_coeff) conv, l1, l2 = uccsd_t_lambda.kernel(mycc, eris, t1, t2) g1 = Gradients(mycc).kernel(t1, t2, l1, l2, eris=eris) print(g1) myccs = mycc.as_scanner() mol.atom = ''' H -1.90679510 0.92319522 0.08700656 H -1.08388168 -1.61405643 -0.07315086 H 2.02822318 -0.61402169 0.09396693 H 0.96345360 1.30488291 -0.10782263 ''' mol.build(0, 0) e1 = myccs(mol) e1 += myccs.ccsd_t() mol.atom = ''' H -1.90879510 0.92319522 0.08700656 H -1.08388168 -1.61405643 -0.07315086 H 2.02822318 -0.61402169 0.09396693 H 0.96345360 1.30488291 -0.10782263 ''' mol.build(0, 0) e2 = myccs(mol) e2 += myccs.ccsd_t() # FIXME: disagreements between analytical value and finite difference value print(g1[0,0], (e1-e2)/0.002) #CCSD #H 0.0113620114 0.0664344363 0.0029855587 #H 0.0528858926 -0.0483942979 -0.0033960631 #H 0.0109676543 -0.0827248466 0.0074005299 #H -0.0752155583 0.0646847082 -0.0069900255 # #CCSD(T) gradient: # #H 0.0112264011 0.0658917731 0.0029936671 #H 0.0525667206 -0.0481602008 -0.0033751503 #H 0.0107197424 -0.0823677005 0.0073804163 #H -0.0745128642 0.0646361282 -0.0069989330