Source code for pyscf.gto.pp_int
#!/usr/bin/env python
# Copyright 2014-2020 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>
#
'''Analytic GTH-PP integrals for open boundary conditions.
See also pyscf/pbc/gto/pseudo/pp_int.py
'''
import numpy as np
from pyscf import lib
from pyscf.gto.mole import ATOM_OF, intor_cross
[docs]
def get_gth_pp(mol):
from pyscf.pbc.gto.pseudo import pp_int
from pyscf.df import incore
# Analytical integration for get_pp_loc_part1(cell).
fakemol = pp_int.fake_cell_vloc(mol, 0)
vpploc = 0
if fakemol.nbas > 0:
charges = fakemol.atom_charges()
atmlst = fakemol._bas[:,ATOM_OF]
v = incore.aux_e2(mol, fakemol, 'int3c2e', aosym='s2', comp=1)
vpploc = np.einsum('...i,i->...', v, -charges[atmlst])
intors = ('int3c2e', 'int3c1e', 'int3c1e_r2_origk',
'int3c1e_r4_origk', 'int3c1e_r6_origk')
for cn in range(1, 5):
fakemol = pp_int.fake_cell_vloc(mol, cn)
if fakemol.nbas > 0:
v = incore.aux_e2(mol, fakemol, intors[cn], aosym='s2', comp=1)
vpploc += np.einsum('...i->...', v)
if isinstance(vpploc, np.ndarray):
vpploc = lib.unpack_tril(vpploc)
fakemol, hl_blocks = pp_int.fake_cell_vnl(mol)
hl_dims = np.array([len(hl) for hl in hl_blocks])
_bas = fakemol._bas
ppnl_half = []
intors = ('int1e_ovlp', 'int1e_r2_origi', 'int1e_r4_origi')
for i, intor in enumerate(intors):
fakemol._bas = _bas[hl_dims>i]
if fakemol.nbas > 0:
ppnl_half.append(intor_cross(intor, fakemol, mol))
else:
ppnl_half.append(None)
fakemol._bas = _bas
nao = mol.nao
offset = [0] * 3
for ib, hl in enumerate(hl_blocks):
l = fakemol.bas_angular(ib)
nd = 2 * l + 1
hl_dim = hl.shape[0]
ilp = np.empty((hl_dim, nd, nao))
for i in range(hl_dim):
p0 = offset[i]
if ppnl_half[i] is None:
ilp[i] = 0.
else:
ilp[i] = ppnl_half[i][p0:p0+nd]
offset[i] = p0 + nd
vpploc += np.einsum('ilp,ij,jlq->pq', ilp.conj(), hl, ilp)
return vpploc