Ejemplo n.º 1
0
    def _compute_multipole_potential_integrals(self, sites, orders, moments):
        orders = numpy.asarray(orders)
        if numpy.any(orders > 2):
            raise NotImplementedError("""Multipole potential integrals not
                                      implemented for order > 2.""")

        # order 0
        fakemol = gto.fakemol_for_charges(sites)
        integral0 = df.incore.aux_e2(self.mol, fakemol, intor='int3c2e')
        moments_0 = numpy.array([m[0] for m in moments])
        op = numpy.einsum('ijg,ga->ij', integral0,
                          moments_0 * cppe.prefactors(0))

        # order 1
        if numpy.any(orders >= 1):
            idx = numpy.where(orders >= 1)[0]
            fakemol = gto.fakemol_for_charges(sites[idx])
            integral1 = df.incore.aux_e2(self.mol,
                                         fakemol,
                                         intor='int3c2e_ip1')
            moments_1 = numpy.array([moments[i][1] for i in idx])
            v = numpy.einsum('aijg,ga,a->ij', integral1, moments_1,
                             cppe.prefactors(1))
            op += v + v.T

        if numpy.any(orders >= 2):
            idx = numpy.where(orders >= 2)[0]
            fakemol = gto.fakemol_for_charges(sites[idx])
            n_sites = idx.size
            # moments_2 is the lower triangler of
            # [[XX, XY, XZ], [YX, YY, YZ], [ZX, ZY, ZZ]] i.e.
            # XX, XY, XZ, YY, YZ, ZZ = 0,1,2,4,5,8
            # symmetrize it to the upper triangler part
            # XX, YX, ZX, YY, ZY, ZZ = 0,3,6,4,7,8
            m2 = numpy.einsum('ga,a->ga', [moments[i][2] for i in idx],
                              cppe.prefactors(2))
            moments_2 = numpy.zeros((n_sites, 9))
            moments_2[:, [0, 1, 2, 4, 5, 8]] = m2
            moments_2[:, [0, 3, 6, 4, 7, 8]] += m2
            moments_2 *= .5

            integral2 = df.incore.aux_e2(self.mol,
                                         fakemol,
                                         intor='int3c2e_ipip1')
            v = numpy.einsum('aijg,ga->ij', integral2, moments_2)
            op += v + v.T
            integral2 = df.incore.aux_e2(self.mol,
                                         fakemol,
                                         intor='int3c2e_ipvip1')
            op += numpy.einsum('aijg,ga->ij', integral2, moments_2) * 2

        return op
Ejemplo n.º 2
0
 def test_int1e_grids_spvsp(self):
     ngrids = 201
     grids = numpy.random.random((ngrids, 3)) * 12 - 5
     fmol = gto.fakemol_for_charges(grids)
     ref = df.r_incore.aux_e2(mol, fmol, intor='int3c2e_spsp1_spinor').transpose(2,0,1)
     j3c = mol.intor('int1e_grids_spvsp_spinor', grids=grids)
     self.assertAlmostEqual(abs(j3c - ref).max(), 0, 12)
Ejemplo n.º 3
0
        def get_hcore(self, mol=None):
            if mol is None: mol = self.mol
            if hasattr(scf_method, 'get_hcore'):
                h1e = method_class.get_hcore(self, mol)
            else:  # DO NOT modify post-HF objects to avoid the MM charges applied twice
                raise RuntimeError('mm_charge function cannot be applied on post-HF methods')

            if pyscf.DEBUG:
                v = 0
                for i,q in enumerate(charges):
                    mol.set_rinv_origin(coords[i])
                    v += mol.intor('int1e_rinv') * -q
            else:
                if mol.cart:
                    intor = 'int3c2e_cart'
                else:
                    intor = 'int3c2e_sph'
                nao = mol.nao
                max_memory = self.max_memory - lib.current_memory()[0]
                blksize = int(max(max_memory*1e6/8/nao**2, 400))
                v = 0
                for i0, i1 in lib.prange(0, charges.size, blksize):
                    fakemol = gto.fakemol_for_charges(coords[i0:i1])
                    j3c = df.incore.aux_e2(mol, fakemol, intor=intor, aosym='s2ij')
                    v += numpy.einsum('xk,k->x', j3c, -charges[i0:i1])
                v = lib.unpack_tril(v)
            return h1e + v
Ejemplo n.º 4
0
    def test_range_separated_coulomb_int1e_grids(self):
        mol1 = gto.M(atom='''
O 0.5 0.5 0.
H  1.  1.2 0.
H  0.  0.  1.3''', basis='ccpvtz')
        ngrids = 201
        grids = numpy.random.random((ngrids, 3)) * 12 - 5
        fmol = gto.fakemol_for_charges(grids)

        with mol1.with_range_coulomb(.8):
            ref = df.incore.aux_e2(mol1, fmol, intor='int3c2e').transpose(2,0,1)
            j3c = mol1.intor('int1e_grids', grids=grids)
            self.assertAlmostEqual(abs(j3c - ref).max(), 0, 12)

            ref = df.incore.aux_e2(mol1, fmol, intor='int3c2e_cart').transpose(2,0,1)
            j3c = mol1.intor('int1e_grids_cart', grids=grids)
            self.assertAlmostEqual(abs(j3c - ref).max(), 0, 12)

            ref = df.incore.aux_e2(mol1, fmol, intor='int3c2e_spinor').transpose(2,0,1)
            j3c = mol1.intor('int1e_grids_spinor', grids=grids)
            self.assertAlmostEqual(abs(j3c - ref).max(), 0, 12)

        with mol1.with_range_coulomb(-.8):
            ref = df.incore.aux_e2(mol1, fmol, intor='int3c2e').transpose(2,0,1)
            j3c = mol1.intor('int1e_grids', grids=grids)
            self.assertAlmostEqual(abs(j3c - ref).max(), 0, 12)

            ref = df.incore.aux_e2(mol1, fmol, intor='int3c2e_cart').transpose(2,0,1)
            j3c = mol1.intor('int1e_grids_cart', grids=grids)
            self.assertAlmostEqual(abs(j3c - ref).max(), 0, 12)

            ref = df.incore.aux_e2(mol1, fmol, intor='int3c2e_spinor').transpose(2,0,1)
            j3c = mol1.intor('int1e_grids_spinor', grids=grids)
            self.assertAlmostEqual(abs(j3c - ref).max(), 0, 12)
Ejemplo n.º 5
0
    def jk_part(mol, grid_coords, dms, fg):

        # transfer bvv to SGXsetnr_direct_scf_blk. from _vhf.VHFOpt
        # need add mol._bvv in scf.mole.py
        c_bvv = numpy.asarray(mol._bvv, dtype=numpy.int32, order='C')
        nbvv = ctypes.c_int(c_bvv.shape[0])
        ao_loc = make_loc(c_bas, intor)
        fsetqcond = getattr(libcvhf, 'SGXsetnr_direct_scf_blk')
        fsetqcond(vhfopt._this, getattr(libcvhf, intor), lib.c_null_ptr(),
                  ao_loc.ctypes.data_as(ctypes.c_void_p),
                  c_atm.ctypes.data_as(ctypes.c_void_p), natm,
                  c_bas.ctypes.data_as(ctypes.c_void_p), nbas,
                  c_env.ctypes.data_as(ctypes.c_void_p),
                  c_bvv.ctypes.data_as(ctypes.c_void_p), nbvv)

        fakemol = gto.fakemol_for_charges(grid_coords)
        atm, bas, env = gto.mole.conc_env(mol._atm, mol._bas, mol._env,
                                          fakemol._atm, fakemol._bas,
                                          fakemol._env)

        ao_loc = moleintor.make_loc(bas, intor)
        shls_slice = (0, mol.nbas, 0, mol.nbas, mol.nbas, len(bas))
        ngrids = grid_coords.shape[0]

        vj = vk = None
        fjk = []
        dmsptr = []
        vjkptr = []
        if with_j:
            if dms[0].ndim == 1:  # the value of density at each grid
                vj = numpy.zeros((len(dms), ncomp, nao, nao))[:, 0]
                for i, dm in enumerate(dms):
                    dmsptr.append(dm.ctypes.data_as(ctypes.c_void_p))
                    vjkptr.append(vj[i].ctypes.data_as(ctypes.c_void_p))
                    fjk.append(_vhf._fpointer('SGXnr' + aosym + '_ijg_g_ij'))
            else:
                vj = numpy.zeros((len(dms), ncomp, ngrids))[:, 0]
                for i, dm in enumerate(dms):
                    dmsptr.append(dm.ctypes.data_as(ctypes.c_void_p))
                    vjkptr.append(vj[i].ctypes.data_as(ctypes.c_void_p))
                    fjk.append(_vhf._fpointer('SGXnr' + aosym + '_ijg_ji_g'))
        if with_k:
            vk = numpy.zeros((len(fg), ncomp, ngrids, nao))[:, 0]
            for i, dm in enumerate(fg):
                dmsptr.append(dm.ctypes.data_as(ctypes.c_void_p))
                vjkptr.append(vk[i].ctypes.data_as(ctypes.c_void_p))
                fjk.append(_vhf._fpointer('SGXnr' + aosym + '_ijg_gj_gi'))

        n_dm = len(fjk)
        fjk = (ctypes.c_void_p * (n_dm))(*fjk)
        dmsptr = (ctypes.c_void_p * (n_dm))(*dmsptr)
        vjkptr = (ctypes.c_void_p * (n_dm))(*vjkptr)

        drv(cintor, fdot, fjk, dmsptr, vjkptr, n_dm, ncomp,
            (ctypes.c_int * 6)(*shls_slice),
            ao_loc.ctypes.data_as(ctypes.c_void_p), cintopt, vhfopt._this,
            atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm),
            bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas),
            env.ctypes.data_as(ctypes.c_void_p))
        return vj, vk
Ejemplo n.º 6
0
 def _compute_field_integrals(self, sites, moments):
     mol = self.mol
     fakemol = gto.fakemol_for_charges(sites)
     j3c = df.incore.aux_e2(mol, fakemol, intor='int3c2e_ip1')
     op = numpy.einsum('aijg,nga->nij', j3c, -moments)
     op = op + op.transpose(0, 2, 1)
     return op
Ejemplo n.º 7
0
 def _compute_field(self, sites, Ds):
     mol = self.mol
     fakemol = gto.fakemol_for_charges(sites)
     j3c = df.incore.aux_e2(mol, fakemol, intor='int3c2e_ip1')
     field = (numpy.einsum('aijg,nij->nga', j3c, Ds) +
              numpy.einsum('aijg,nji->nga', j3c, Ds))
     return field
Ejemplo n.º 8
0
Archivo: itrf.py Proyecto: tmash/pyscf
        def get_hcore(self, mol=None):
            ''' (QM 1e grad) + <-d/dX i|q_mm/r_mm|j>'''
            if mol is None: mol = self.mol
            coords = self.base.mm_mol.atom_coords()
            charges = self.base.mm_mol.atom_charges()

            g_qm = grad_class.get_hcore(self, mol)
            nao = g_qm.shape[1]
            if pyscf.DEBUG:
                v = 0
                for i, q in enumerate(charges):
                    mol.set_rinv_origin(coords[i])
                    v += mol.intor('int1e_iprinv', comp=3) * q
            else:
                if mol.cart:
                    intor = 'int3c2e_ip1_cart'
                else:
                    intor = 'int3c2e_ip1_sph'
                nao = mol.nao
                max_memory = self.max_memory - lib.current_memory()[0]
                blksize = int(min(max_memory * 1e6 / 8 / nao**2, 200))
                cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas,
                                                     mol._env, intor)
                v = 0
                for i0, i1 in lib.prange(0, charges.size, blksize):
                    fakemol = gto.fakemol_for_charges(coords[i0:i1])
                    j3c = df.incore.aux_e2(mol,
                                           fakemol,
                                           intor,
                                           aosym='s1',
                                           comp=3,
                                           cintopt=cintopt)
                    v += numpy.einsum('ipqk,k->ipq', j3c, charges[i0:i1])
            return g_qm + v
Ejemplo n.º 9
0
def mep(surface, mol, dm):
    '''Calculate the MEP, by taking each point on the density isosurface.
       Returned as a NumPy array.
    '''
    coords = np.asarray([surface[i][1:] for i in range(len(surface))])
    
    #Nuclear potential at given points
    Vnuc = 0
    for i in range(mol.natm):
        r = mol.atom_coord(i)
        Z = mol.atom_charge(i)
        rp = r - coords
        Vnuc += Z / np.einsum('xi,xi->x', rp, rp)**.5
    
    #Potential of electron density
    Vele = np.empty_like(Vnuc)
    for p0, p1 in lib.prange(0, Vele.size, 600):
        fakemol = gto.fakemol_for_charges(coords[p0:p1])
        ints = df.incore.aux_e2(mol, fakemol)
        Vele[p0:p1] = np.einsum('ijp,ij->p', ints, dm)
    
    MEP = Vnuc - Vele
    
    mep_arr = surface
    for i in range(len(mep_arr)):
        mep_arr[i][0] = MEP[i]
    
    return mep_arr
Ejemplo n.º 10
0
        def get_hcore(self, mol=None):
            if mol is None: mol = self.mol
            if getattr(scf_method, 'get_hcore', None):
                h1e = method_class.get_hcore(self, mol)
            else:  # DO NOT modify post-HF objects to avoid the MM charges applied twice
                raise RuntimeError('mm_charge function cannot be applied on post-HF methods')

            if pyscf.DEBUG:
                v = 0
                for i,q in enumerate(charges):
                    mol.set_rinv_origin(coords[i])
                    v += mol.intor('int1e_rinv') * -q
            else:
                if mol.cart:
                    intor = 'int3c2e_cart'
                else:
                    intor = 'int3c2e_sph'
                nao = mol.nao
                max_memory = self.max_memory - lib.current_memory()[0]
                blksize = int(min(max_memory*1e6/8/nao**2, 200))
                v = 0
                for i0, i1 in lib.prange(0, charges.size, blksize):
                    fakemol = gto.fakemol_for_charges(coords[i0:i1])
                    j3c = df.incore.aux_e2(mol, fakemol, intor=intor, aosym='s2ij')
                    v += numpy.einsum('xk,k->x', j3c, -charges[i0:i1])
                v = lib.unpack_tril(v)
            return h1e + v
Ejemplo n.º 11
0
def mep(mol,
        outfile,
        dm,
        nx=80,
        ny=80,
        nz=80,
        resolution=RESOLUTION,
        margin=BOX_MARGIN):
    """Calculates the molecular electrostatic potential (MEP) and write out in
    cube format.

    Args:
        mol : Mole
            Molecule to calculate the electron density for.
        outfile : str
            Name of Cube file to be written.
        dm : ndarray
            Density matrix of molecule.

    Kwargs:
        nx : int
            Number of grid point divisions in x direction.
            Note this is function of the molecule's size; a larger molecule
            will have a coarser representation than a smaller one for the
            same value. Conflicts to keyword resolution.
        ny : int
            Number of grid point divisions in y direction.
        nz : int
            Number of grid point divisions in z direction.
        resolution: float
            Resolution of the mesh grid in the cube box. If resolution is
            given in the input, the input nx/ny/nz have no effects.  The value
            of nx/ny/nz will be determined by the resolution and the cube box
            size.
    """
    cc = Cube(mol, nx, ny, nz, resolution, margin)

    coords = cc.get_coords()

    # Nuclear potential at given points
    Vnuc = 0
    for i in range(mol.natm):
        r = mol.atom_coord(i)
        Z = mol.atom_charge(i)
        rp = r - coords
        Vnuc += Z / numpy.einsum('xi,xi->x', rp, rp)**.5

    # Potential of electron density
    Vele = numpy.empty_like(Vnuc)
    for p0, p1 in lib.prange(0, Vele.size, 600):
        fakemol = gto.fakemol_for_charges(coords[p0:p1])
        ints = df.incore.aux_e2(mol, fakemol)
        Vele[p0:p1] = numpy.einsum('ijp,ij->p', ints, dm)

    MEP = Vnuc - Vele  # MEP at each point
    MEP = MEP.reshape(cc.nx, cc.ny, cc.nz)

    # Write the potential
    cc.write(MEP, outfile, 'Molecular electrostatic potential in real space')
    return MEP
Ejemplo n.º 12
0
 def batch_nuc(mol, grid_coords, out=None):
     fakemol = gto.fakemol_for_charges(grid_coords)
     j3c = aux_e2(mol,
                  fakemol,
                  intor='int3c2e',
                  aosym='s2ij',
                  cintopt=cintopt)
     return lib.unpack_tril(j3c.T, out=out)
Ejemplo n.º 13
0
def make_B(pcmobj, r_vdw, ui, ylm_1sph, cached_pol, L):
    '''0th order'''
    mol = pcmobj.mol
    coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(
        pcmobj.lebedev_order)
    ngrid_1sph = coords_1sph.shape[0]
    mol = pcmobj.mol
    natm = mol.natm
    nao = mol.nao
    lmax = pcmobj.lmax
    nlm = (lmax + 1)**2

    atom_coords = mol.atom_coords()
    atom_charges = mol.atom_charges()
    grids = pcmobj.grids

    extern_point_idx = ui > 0
    cav_coords = (atom_coords.reshape(natm, 1, 3) +
                  numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))

    cav_coords = cav_coords[extern_point_idx]
    int3c2e = mol._add_suffix('int3c2e')
    cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas, mol._env, int3c2e)
    fakemol = gto.fakemol_for_charges(cav_coords)
    v_nj = df.incore.aux_e2(mol,
                            fakemol,
                            intor=int3c2e,
                            aosym='s1',
                            cintopt=cintopt)
    nao_pair = v_nj.shape[0]
    v_phi = numpy.zeros((natm, ngrid_1sph, nao, nao))
    v_phi[extern_point_idx] += v_nj.transpose(2, 0, 1)

    phi = numpy.einsum('n,xn,jn,jnpq->jxpq', weights_1sph, ylm_1sph, ui, v_phi)

    Xvec = numpy.linalg.solve(L.reshape(natm * nlm, -1),
                              phi.reshape(natm * nlm, -1))
    Xvec = Xvec.reshape(natm, nlm, nao, nao)

    ao = mol.eval_gto('GTOval', grids.coords)
    aow = numpy.einsum('gi,g->gi', ao, grids.weights)
    aopair = numpy.einsum('gi,gj->gij', ao, aow)

    psi = numpy.zeros((natm, nlm, nao, nao))
    i1 = 0
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        i0, i1 = i1, i1 + fak_pol[0].shape[1]
        p1 = 0
        for l in range(lmax + 1):
            fac = 4 * numpy.pi / (l * 2 + 1)
            p0, p1 = p1, p1 + (l * 2 + 1)
            psi[ia, p0:p1] = -fac * numpy.einsum('mn,nij->mij', fak_pol[l],
                                                 aopair[i0:i1])

    B = lib.einsum('nlpq,nlrs->pqrs', psi, Xvec)
    B = B + B.transpose(2, 3, 0, 1)
    return B
Ejemplo n.º 14
0
def make_phi(pcmobj, dm, r_vdw, ui, ylm_1sph, with_nuc=True):
    '''
    Induced potential of ddCOSMO model

    Kwargs:
        with_nuc (bool): Mute the contribution of nuclear charges when
            computing the second order derivatives of energy
    '''
    mol = pcmobj.mol
    natm = mol.natm
    coords_1sph, weights_1sph = make_grids_one_sphere(pcmobj.lebedev_order)
    ngrid_1sph = coords_1sph.shape[0]

    dms = numpy.asarray(dm)
    is_single_dm = dms.ndim == 2

    nao = dms.shape[-1]
    dms = dms.reshape(-1,nao,nao)
    n_dm = dms.shape[0]
    diagidx = numpy.arange(nao)
    diagidx = diagidx*(diagidx+1)//2 + diagidx
    tril_dm = lib.pack_tril(dms+dms.transpose(0,2,1))
    tril_dm[:,diagidx] *= .5

    atom_coords = mol.atom_coords()
    atom_charges = mol.atom_charges()

    extern_point_idx = ui > 0
    cav_coords = (atom_coords.reshape(natm,1,3)
                  + numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))

    v_phi = numpy.zeros((n_dm, natm, ngrid_1sph))

    if with_nuc:
        for ia in range(natm):
# Note (-) sign is not applied to atom_charges, because (-) is explicitly
# included in rhs and L matrix
            d_rs = atom_coords.reshape(-1,1,3) - cav_coords[ia]
            v_phi[:,ia] = numpy.einsum('z,zp->p', atom_charges, 1./lib.norm(d_rs,axis=2))

    max_memory = pcmobj.max_memory - lib.current_memory()[0]
    blksize = int(max(max_memory*.9e6/8/nao**2, 400))

    cav_coords = cav_coords[extern_point_idx]
    v_phi_e = numpy.empty((n_dm, cav_coords.shape[0]))
    int3c2e = mol._add_suffix('int3c2e')
    cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas, mol._env, int3c2e)
    for i0, i1 in lib.prange(0, cav_coords.shape[0], blksize):
        fakemol = gto.fakemol_for_charges(cav_coords[i0:i1])
        v_nj = df.incore.aux_e2(mol, fakemol, intor=int3c2e, aosym='s2ij', cintopt=cintopt)
        v_phi_e[:,i0:i1] = numpy.einsum('nx,xk->nk', tril_dm, v_nj)
    v_phi[:,extern_point_idx] -= v_phi_e

    phi = -numpy.einsum('n,xn,jn,ijn->ijx', weights_1sph, ylm_1sph, ui, v_phi)
    if is_single_dm:
        phi = phi[0]
    return phi
Ejemplo n.º 15
0
def make_phi(pcmobj, dm, r_vdw, ui):
    mol = pcmobj.mol
    natm = mol.natm
    coords_1sph, weights_1sph = make_grids_one_sphere(pcmobj.lebedev_order)
    ngrid_1sph = coords_1sph.shape[0]

    if not (isinstance(dm, numpy.ndarray) and dm.ndim == 2):
        dm = dm[0] + dm[1]
    tril_dm = lib.pack_tril(dm + dm.T)
    nao = dm.shape[0]
    diagidx = numpy.arange(nao)
    diagidx = diagidx * (diagidx + 1) // 2 + diagidx
    tril_dm[diagidx] *= .5

    atom_coords = mol.atom_coords()
    atom_charges = mol.atom_charges()

    extern_point_idx = ui > 0
    cav_coords = (atom_coords.reshape(natm, 1, 3) +
                  numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))

    v_phi = numpy.empty((natm, ngrid_1sph))
    for ia in range(natm):
        # Note (-) sign is not applied to atom_charges, because (-) is explicitly
        # included in rhs and L matrix
        d_rs = atom_coords.reshape(-1, 1, 3) - cav_coords[ia]
        v_phi[ia] = numpy.einsum('z,zp->p', atom_charges,
                                 1. / lib.norm(d_rs, axis=2))

    max_memory = pcmobj.max_memory - lib.current_memory()[0]
    blksize = int(max(max_memory * 1e6 / 8 / nao**2, 400))

    cav_coords = cav_coords[extern_point_idx]
    v_phi_e = numpy.empty(cav_coords.shape[0])
    int3c2e = mol._add_suffix('int3c2e')
    cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas, mol._env, int3c2e)
    for i0, i1 in lib.prange(0, cav_coords.shape[0], blksize):
        fakemol = gto.fakemol_for_charges(cav_coords[i0:i1])
        v_nj = df.incore.aux_e2(mol,
                                fakemol,
                                intor=int3c2e,
                                aosym='s2ij',
                                cintopt=cintopt)
        v_phi_e[i0:i1] = numpy.einsum('x,xk->k', tril_dm, v_nj)
    v_phi[extern_point_idx] -= v_phi_e

    ylm_1sph = numpy.vstack(sph.real_sph_vec(coords_1sph, pcmobj.lmax, True))
    phi = -numpy.einsum('n,xn,jn,jn->jx', weights_1sph, ylm_1sph, ui, v_phi)
    return phi
Ejemplo n.º 16
0
    def test_fakemol(self):
        numpy.random.seed(1)
        coords = numpy.random.random((6,3))*4
        vref = 0
        mol = mol0.copy()
        for c in coords:
            mol.set_rinv_origin(c)
            vref += mol.intor('int1e_rinv')

        fakemol = gto.fakemol_for_charges(coords)
        pmol = mol + fakemol
        shls_slice = (0, mol.nbas, 0, mol.nbas, mol.nbas, pmol.nbas)
        v = pmol.intor('int3c2e', comp=1, shls_slice=shls_slice)
        v = numpy.einsum('pqk->pq', v)
        self.assertAlmostEqual(abs(vref-v).max(), 0, 12)
Ejemplo n.º 17
0
    def test_fakemol(self):
        numpy.random.seed(1)
        coords = numpy.random.random((6, 3)) * 4
        vref = 0
        mol = mol0.copy()
        for c in coords:
            mol.set_rinv_origin(c)
            vref += mol.intor('int1e_rinv')

        fakemol = gto.fakemol_for_charges(coords)
        pmol = mol + fakemol
        shls_slice = (0, mol.nbas, 0, mol.nbas, mol.nbas, pmol.nbas)
        v = pmol.intor('int3c2e', comp=1, shls_slice=shls_slice)
        v = numpy.einsum('pqk->pq', v)
        self.assertAlmostEqual(abs(vref - v).max(), 0, 12)
Ejemplo n.º 18
0
    def test_int1e_grids_ip(self):
        ngrids = 201
        grids = numpy.random.random((ngrids, 3)) * 12 - 5
        fmol = gto.fakemol_for_charges(grids)
        ref = df.incore.aux_e2(mol1, fmol, intor='int3c2e_ip1').transpose(0,3,1,2)
        j3c = mol1.intor('int1e_grids_ip', grids=grids)
        self.assertAlmostEqual(abs(j3c - ref).max(), 0, 12)

        ref = df.incore.aux_e2(mol1, fmol, intor='int3c2e_ip1_cart').transpose(0,3,1,2)
        j3c = mol1.intor('int1e_grids_ip_cart', grids=grids)
        self.assertAlmostEqual(abs(j3c - ref).max(), 0, 12)

        ref = df.incore.aux_e2(mol1, fmol, intor='int3c2e_ip1_spinor').transpose(0,3,1,2)
        j3c = mol1.intor('int1e_grids_ip_spinor', grids=grids)
        self.assertAlmostEqual(abs(j3c - ref).max(), 0, 12)
Ejemplo n.º 19
0
def mep(mol, outfile, dm, nx=80, ny=80, nz=80, resolution=RESOLUTION):
    """Calculates the molecular electrostatic potential (MEP) and write out in
    cube format.

    Args:
        mol : Mole
            Molecule to calculate the electron density for.
        outfile : str
            Name of Cube file to be written.
        dm : ndarray
            Density matrix of molecule.

    Kwargs:
        nx : int
            Number of grid point divisions in x direction.
            Note this is function of the molecule's size; a larger molecule
            will have a coarser representation than a smaller one for the
            same value.
        ny : int
            Number of grid point divisions in y direction.
        nz : int
            Number of grid point divisions in z direction.
    """
    cc = Cube(mol, nx, ny, nz, resolution)

    coords = cc.get_coords()

    # Nuclear potential at given points
    Vnuc = 0
    for i in range(mol.natm):
        r = mol.atom_coord(i)
        Z = mol.atom_charge(i)
        rp = r - coords
        Vnuc += Z / numpy.einsum('xi,xi->x', rp, rp)**.5

    # Potential of electron density
    Vele = numpy.empty_like(Vnuc)
    for p0, p1 in lib.prange(0, Vele.size, 600):
        fakemol = gto.fakemol_for_charges(coords[p0:p1])
        ints = df.incore.aux_e2(mol, fakemol)
        Vele[p0:p1] = numpy.einsum('ijp,ij->p', ints, dm)

    MEP = Vnuc - Vele     # MEP at each point
    MEP = MEP.reshape(nx,ny,nz)

    # Write the potential
    cc.write(MEP, outfile, 'Molecular electrostatic potential in real space')
Ejemplo n.º 20
0
 def effective_dipole_operator(self):
     """
     Compute the derivatives of induced moments wrt each coordinate
     and form integrals for effective dipole operator (EEF)
     """
     dips = self.mol.intor_symmetric('int1e_r', comp=3)
     if self.eef:
         logger.info(self, "Computing effective dipole operator for EEF.")
         positions = self.cppe_state.positions_polarizable
         n_sites = positions.shape[0]
         induced_moments = self.cppe_state.induced_moments_eef()
         induced_moments = induced_moments.reshape(n_sites, 3, 3)
         fakemol = gto.fakemol_for_charges(positions)
         j3c = df.incore.aux_e2(self.mol, fakemol, intor='int3c2e_ip1')
         V_ind = numpy.einsum('aijg,gax->xij', j3c, -induced_moments)
         dips += V_ind + V_ind.transpose(0, 2, 1)
     return list(dips)
Ejemplo n.º 21
0
    def jk_part(mol, grid_coords, dms, fg):
        fakemol = gto.fakemol_for_charges(grid_coords)
        atm, bas, env = gto.mole.conc_env(mol._atm, mol._bas, mol._env,
                                          fakemol._atm, fakemol._bas, fakemol._env)

        ao_loc = moleintor.make_loc(bas, sgxopt._intor)
        shls_slice = (0, mol.nbas, 0, mol.nbas, mol.nbas, len(bas))
        ngrids = grid_coords.shape[0]

        vj = vk = None
        fjk = []
        dmsptr = []
        vjkptr = []
        if with_j:
            if dms[0].ndim == 1:  # the value of density at each grid
                vj = numpy.zeros((len(dms),ncomp,nao,nao))[:,0]
                for i, dm in enumerate(dms):
                    dmsptr.append(dm.ctypes.data_as(ctypes.c_void_p))
                    vjkptr.append(vj[i].ctypes.data_as(ctypes.c_void_p))
                    fjk.append(_vhf._fpointer('SGXnr'+aosym+'_ijg_g_ij'))
            else:
                vj = numpy.zeros((len(dms),ncomp,ngrids))[:,0]
                for i, dm in enumerate(dms):
                    dmsptr.append(dm.ctypes.data_as(ctypes.c_void_p))
                    vjkptr.append(vj[i].ctypes.data_as(ctypes.c_void_p))
                    fjk.append(_vhf._fpointer('SGXnr'+aosym+'_ijg_ji_g'))
        if with_k:
            vk = numpy.zeros((len(fg),ncomp,ngrids,nao))[:,0]
            for i, dm in enumerate(fg):
                dmsptr.append(dm.ctypes.data_as(ctypes.c_void_p))
                vjkptr.append(vk[i].ctypes.data_as(ctypes.c_void_p))
                fjk.append(_vhf._fpointer('SGXnr'+aosym+'_ijg_gj_gi'))

        n_dm = len(fjk)
        fjk = (ctypes.c_void_p*(n_dm))(*fjk)
        dmsptr = (ctypes.c_void_p*(n_dm))(*dmsptr)
        vjkptr = (ctypes.c_void_p*(n_dm))(*vjkptr)

        drv(cintor, fdot, fjk, dmsptr, vjkptr, n_dm, ncomp,
            (ctypes.c_int*6)(*shls_slice),
            ao_loc.ctypes.data_as(ctypes.c_void_p),
            sgxopt._cintopt, sgxopt._this,
            atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm),
            bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas),
            env.ctypes.data_as(ctypes.c_void_p))
        return vj, vk
Ejemplo n.º 22
0
def make_phi(pcmobj, dm, r_vdw, ui):
    mol = pcmobj.mol
    natm = mol.natm
    coords_1sph, weights_1sph = make_grids_one_sphere(pcmobj.lebedev_order)
    ngrid_1sph = coords_1sph.shape[0]

    if not (isinstance(dm, numpy.ndarray) and dm.ndim == 2):
        dm = dm[0] + dm[1]
    tril_dm = lib.pack_tril(dm+dm.T)
    nao = dm.shape[0]
    diagidx = numpy.arange(nao)
    diagidx = diagidx*(diagidx+1)//2 + diagidx
    tril_dm[diagidx] *= .5

    atom_coords = mol.atom_coords()
    atom_charges = mol.atom_charges()

    extern_point_idx = ui > 0
    cav_coords = (atom_coords.reshape(natm,1,3)
                  + numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))

    v_phi = numpy.empty((natm,ngrid_1sph))
    for ia in range(natm):
# Note (-) sign is not applied to atom_charges, because (-) is explicitly
# included in rhs and L matrix
        d_rs = atom_coords.reshape(-1,1,3) - cav_coords[ia]
        v_phi[ia] = numpy.einsum('z,zp->p', atom_charges, 1./lib.norm(d_rs,axis=2))

    max_memory = pcmobj.max_memory - lib.current_memory()[0]
    blksize = int(max(max_memory*1e6/8/nao**2, 400))

    cav_coords = cav_coords[extern_point_idx]
    v_phi_e = numpy.empty(cav_coords.shape[0])
    int3c2e = mol._add_suffix('int3c2e')
    for i0, i1 in lib.prange(0, cav_coords.shape[0], blksize):
        fakemol = gto.fakemol_for_charges(cav_coords[i0:i1])
        v_nj = df.incore.aux_e2(mol, fakemol, intor=int3c2e, aosym='s2ij')
        v_phi_e[i0:i1] = numpy.einsum('x,xk->k', tril_dm, v_nj)
    v_phi[extern_point_idx] -= v_phi_e

    ylm_1sph = numpy.vstack(sph.real_sph_vec(coords_1sph, pcmobj.lmax, True))
    phi = -numpy.einsum('n,xn,jn,jn->jx', weights_1sph, ylm_1sph, ui, v_phi)
    return phi
Ejemplo n.º 23
0
 def get_hcore(self, mol=None):
     ''' (QM 1e grad) + <-d/dX i|q_mm/r_mm|j>'''
     if mol is None: mol = self.mol
     g_qm = scf_grad.get_hcore(mol)
     nao = g_qm.shape[1]
     if pyscf.DEBUG:
         v = 0
         for i, q in enumerate(charges):
             mol.set_rinv_origin(coords[i])
             v += mol.intor('int1e_iprinv', comp=3) * q
     else:
         fakemol = gto.fakemol_for_charges(coords)
         j3c = df.incore.aux_e2(mol,
                                fakemol,
                                intor='int3c2e_ip1',
                                aosym='s1',
                                comp=3)
         v = numpy.einsum('ipqk,k->ipq', j3c, charges)
     return scf_grad.get_hcore(mol) + v
Ejemplo n.º 24
0
Archivo: itrf.py Proyecto: tmash/pyscf
        def get_hcore(self, mol=None):
            if mol is None: mol = self.mol
            if getattr(method_class, 'get_hcore', None):
                h1e = method_class.get_hcore(self, mol)
            else:  # DO NOT modify post-HF objects to avoid the MM charges applied twice
                raise RuntimeError(
                    'mm_charge function cannot be applied on post-HF methods')

            coords = self.mm_mol.atom_coords()
            charges = self.mm_mol.atom_charges()
            if pyscf.DEBUG:
                v = 0
                for i, q in enumerate(charges):
                    mol.set_rinv_origin(coords[i])
                    v += mol.intor('int1e_rinv') * -q
            else:
                if mol.cart:
                    intor = 'int3c2e_cart'
                else:
                    intor = 'int3c2e_sph'
                nao = mol.nao
                max_memory = self.max_memory - lib.current_memory()[0]
                blksize = int(min(max_memory * 1e6 / 8 / nao**2, 200))
                if max_memory <= 0:
                    blksize = 1
                    logger.warn(
                        self,
                        'Memory estimate for reading point charges is negative. '
                        'Trying to read point charges one by one.')
                cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas,
                                                     mol._env, intor)
                v = 0
                for i0, i1 in lib.prange(0, charges.size, blksize):
                    fakemol = gto.fakemol_for_charges(coords[i0:i1])
                    j3c = df.incore.aux_e2(mol,
                                           fakemol,
                                           intor=intor,
                                           aosym='s2ij',
                                           cintopt=cintopt)
                    v += numpy.einsum('xk,k->x', j3c, -charges[i0:i1])
                v = lib.unpack_tril(v)
            return h1e + v
Ejemplo n.º 25
0
def _mm_pot(mol: gto.Mole, mm_mol: gto.Mole) -> np.ndarray:
        """
        this function returns the full mm potential
        (adapted from: qmmm/itrf.py:get_hcore() in PySCF)
        """
        # settings
        coords = mm_mol.atom_coords()
        charges = mm_mol.atom_charges()
        blksize = BLKSIZE
        # integrals
        intor = 'int3c2e_cart' if mol.cart else 'int3c2e_sph'
        cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas,
                                             mol._env, intor)
        # compute interaction potential
        mm_pot = 0
        for i0, i1 in lib.prange(0, charges.size, blksize):
            fakemol = gto.fakemol_for_charges(coords[i0:i1])
            j3c = df.incore.aux_e2(mol, fakemol, intor=intor,
                                   aosym='s2ij', cintopt=cintopt)
            mm_pot += np.einsum('xk,k->x', j3c, -charges[i0:i1])
        mm_pot = lib.unpack_tril(mm_pot)
        return mm_pot
Ejemplo n.º 26
0
        def get_hcore(self, mol=None):
            if mol is None: mol = self.mol
            if hasattr(scf_method, 'get_hcore'):
                h1e = method_class.get_hcore(self, mol)
            else:  # DO NOT modify post-HF objects to avoid the MM charges applied twice
                raise RuntimeError(
                    'mm_charge function cannot be applied on post-HF methods')

            if pyscf.DEBUG:
                v = 0
                for i, q in enumerate(charges):
                    mol.set_rinv_origin(coords[i])
                    v += mol.intor('int1e_rinv') * -q
            else:
                fakemol = gto.fakemol_for_charges(coords)
                if mol.cart:
                    intor = 'int3c2e_cart'
                else:
                    intor = 'int3c2e_sph'
                j3c = df.incore.aux_e2(mol, fakemol, intor=intor, aosym='s2ij')
                v = lib.unpack_tril(numpy.einsum('xk,k->x', j3c, -charges))
            return h1e + v
Ejemplo n.º 27
0
def inter_elecbg(mol, dm, coords, charges):
    r"""
    inter energy between electrons in real frags and background charges
    """
    if mol.cart:
        intor = 'int3c2e_cart'
    else:
        intor = 'int3c2e_sph'
    nao = mol.nao
    #max_memory = mol.max_memory - lib.current_memory()[0]
    #blksize = int(min(max_memory * 1e6 / 8 / nao**2, 200))
    #print(coords,'\n',len(coords))
    vc = np.zeros((nao, nao))
    for i in range(0, charges.size):
        fakemol = gto.fakemol_for_charges(coords[i:i + 1])
        j3c = df.incore.aux_e2(mol, fakemol, intor=intor, aosym='s2ij')
        v = np.einsum('xk,k->x', j3c, -charges[i:i + 1])
        v = lib.unpack_tril(v)
        #print(vc.shape, v.shape)
        vc += v
    #E = np.einsum('ij,ji', v, dm)
    #print("inter_elecbg: %f" % E)
    return vc
Ejemplo n.º 28
0
 def get_hcore(self, mol=None):
     ''' (QM 1e grad) + <-d/dX i|q_mm/r_mm|j>'''
     if mol is None: mol = self.mol
     g_qm = grad_class.get_hcore(self, mol)
     nao = g_qm.shape[1]
     if pyscf.DEBUG:
         v = 0
         for i,q in enumerate(charges):
             mol.set_rinv_origin(coords[i])
             v += mol.intor('int1e_iprinv', comp=3) * q
     else:
         if mol.cart:
             intor = 'int3c2e_ip1_cart'
         else:
             intor = 'int3c2e_ip1_sph'
         nao = mol.nao
         max_memory = self.max_memory - lib.current_memory()[0]
         blksize = int(min(max_memory*1e6/8/nao**2, 200))
         v = 0
         for i0, i1 in lib.prange(0, charges.size, blksize):
             fakemol = gto.fakemol_for_charges(coords[i0:i1])
             j3c = df.incore.aux_e2(mol, fakemol, intor, aosym='s1', comp=3)
             v += numpy.einsum('ipqk,k->ipq', j3c, charges[i0:i1])
     return g_qm + v
Ejemplo n.º 29
0
 def get_hcore(self, mol=None):
     ''' (QM 1e grad) + <-d/dX i|q_mm/r_mm|j>'''
     if mol is None: mol = self.mol
     g_qm = scf_grad.get_hcore(mol)
     nao = g_qm.shape[1]
     if pyscf.DEBUG:
         v = 0
         for i,q in enumerate(charges):
             mol.set_rinv_origin(coords[i])
             v += mol.intor('int1e_iprinv', comp=3) * q
     else:
         if mol.cart:
             intor = 'int3c2e_ip1_cart'
         else:
             intor = 'int3c2e_ip1_sph'
         nao = mol.nao
         max_memory = self.max_memory - lib.current_memory()[0]
         blksize = int(max(max_memory*1e6/8/nao**2, 400))
         v = 0
         for i0, i1 in lib.prange(0, charges.size, blksize):
             fakemol = gto.fakemol_for_charges(coords[i0:i1])
             j3c = df.incore.aux_e2(mol, fakemol, intor, aosym='s1', comp=3)
             v += numpy.einsum('ipqk,k->ipq', j3c, charges[i0:i1])
     return scf_grad.get_hcore(mol) + v
Ejemplo n.º 30
0
def make_psi_vmat(pcmobj, dm, r_vdw, ui, grids, ylm_1sph, cached_pol, L_X, L):
    mol = pcmobj.mol
    natm = mol.natm
    lmax = pcmobj.lmax
    nlm = (lmax+1)**2

    i1 = 0
    scaled_weights = numpy.empty(grids.weights.size)
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        i0, i1 = i1, i1 + fak_pol[0].shape[1]
        eta_nj = 0
        p1 = 0
        for l in range(lmax+1):
            fac = 4*numpy.pi/(l*2+1)
            p0, p1 = p1, p1 + (l*2+1)
            eta_nj += fac * numpy.einsum('mn,m->n', fak_pol[l], L_X[ia,p0:p1])
        scaled_weights[i0:i1] = eta_nj * grids.weights[i0:i1]

    if not (isinstance(dm, numpy.ndarray) and dm.ndim == 2):
        dm = dm[0] + dm[1]
    ni = numint.NumInt()
    max_memory = pcmobj.max_memory - lib.current_memory()[0]
    make_rho, nset, nao = ni._gen_rho_evaluator(mol, dm)
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()
    den = numpy.empty(grids.weights.size)
    vmat = numpy.zeros((nao,nao))
    p1 = 0
    aow = None
    for ao, mask, weight, coords \
            in ni.block_loop(mol, grids, nao, 0, max_memory):
        p0, p1 = p1, p1 + weight.size
        den[p0:p1] = weight * make_rho(0, ao, mask, 'LDA')
        aow = numpy.ndarray(ao.shape, order='F', buffer=aow)
        aow = numpy.einsum('pi,p->pi', ao, scaled_weights[p0:p1], out=aow)
        vmat -= numint._dot_ao_ao(mol, ao, aow, mask, shls_slice, ao_loc)
    ao = aow = scaled_weights = None

    nelec_leak = 0
    psi = numpy.empty((natm,nlm))
    i1 = 0
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        i0, i1 = i1, i1 + fak_pol[0].shape[1]
        nelec_leak += den[i0:i1][leak_idx].sum()
        p1 = 0
        for l in range(lmax+1):
            fac = 4*numpy.pi/(l*2+1)
            p0, p1 = p1, p1 + (l*2+1)
            psi[ia,p0:p1] = -fac * numpy.einsum('n,mn->m', den[i0:i1], fak_pol[l])
# Contribution of nuclear charge to the total density
# The factor numpy.sqrt(4*numpy.pi) is due to the product of 4*pi * Y_0^0
        psi[ia,0] += numpy.sqrt(4*numpy.pi)/r_vdw[ia] * mol.atom_charge(ia)
    logger.debug(pcmobj, 'electron leak %f', nelec_leak)

    # <Psi, L^{-1}g> -> Psi = SL the adjoint equation to LX = g
    L_S = numpy.linalg.solve(L.T.reshape(natm*nlm,-1), psi.ravel()).reshape(natm,-1)
    coords_1sph, weights_1sph = make_grids_one_sphere(pcmobj.lebedev_order)
    # JCP, 141, 184108, Eq (39)
    xi_jn = numpy.einsum('n,jn,xn,jx->jn', weights_1sph, ui, ylm_1sph, L_S)
    extern_point_idx = ui > 0
    cav_coords = (mol.atom_coords().reshape(natm,1,3)
                  + numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))
    cav_coords = cav_coords[extern_point_idx]
    xi_jn = xi_jn[extern_point_idx]

    max_memory = pcmobj.max_memory - lib.current_memory()[0]
    blksize = int(max(max_memory*1e6/8/nao**2, 400))

    vmat_tril = 0
    for i0, i1 in lib.prange(0, xi_jn.size, blksize):
        fakemol = gto.fakemol_for_charges(cav_coords[i0:i1])
        v_nj = df.incore.aux_e2(mol, fakemol, intor='int3c2e', aosym='s2ij')
        vmat_tril += numpy.einsum('xn,n->x', v_nj, xi_jn[i0:i1])
    vmat += lib.unpack_tril(vmat_tril)
    return psi, vmat, L_S
Ejemplo n.º 31
0
def get_jk(mol_or_mf, dm, hermi, dmcur, *args, **kwargs):
    '''MPI version of scf.hf.get_jk function'''
    #vj = get_j(mol_or_mf, dm, hermi)
    #vk = get_k(mol_or_mf, dm, hermi)
    if isinstance(mol_or_mf, gto.mole.Mole):
        mf = hf.SCF(mol_or_mf).view(SCF)
    else:
        mf = mol_or_mf

    # dm may be too big for mpi4py library to serialize. Broadcast dm here.
    if any(comm.allgather(isinstance(dm, str) and dm == 'SKIPPED_ARG')):
        dm = mpi.bcast_tagged_array_occdf(dm)

    mf.unpack_(comm.bcast(mf.pack()))

# initial and final grids level
    grdlvl_i = 0
    grdlvl_f = 1
# norm_ddm threshold for grids change
    thrd_nddm = 0.2
# set block size to adapt memory 
    sblk = 200
# interspace betweeen v shell
    intsp = 1
# threshold for u and v
    gthrdu = 1e-10
    gthrdvs = 1e-10
    gthrdvd = 1e-10

    global cond, wao_vx, ngridsx, coordsx, gridatm

    dms = numpy.asarray(dm)
    dm_shape = dms.shape
    nao = dm_shape[-1]
    dms = dms.reshape(-1,nao,nao)
    nset = dms.shape[0]
    vj = [0] * nset
    vk = [0] * nset

# DF-J and sgX set
    mf.with_df = mf
    mol = mf.mol
    global int2c, ovlp, ao_loc, rao_loc
# use mf.opt to calc int2c once, cond, dm0, and rao, ao_loc, ovlp for sgX
    if mf.opt is None:
        mf.opt = mf.init_direct_scf()
        cond = 0
# set auxbasis in input file, need self.auxbasis = None in __init__ of hf.py
#        mf.auxbasis = 'weigend' 
        auxbasis = mf.auxbasis
        auxbasis = comm.bcast(auxbasis)
        mf.auxbasis = comm.bcast(mf.auxbasis)
        auxmol = df.addons.make_auxmol(mol, auxbasis)
# (P|Q)
        int2c = auxmol.intor('int2c2e', aosym='s1', comp=1)
        if rank == 0: print('auxmol.basis',auxmol.basis,'number of aux basis',int2c.shape[0])
# for sgX
        # ao_loc and rao_loc
        intbn = mol._add_suffix('int3c2e')
        intbn = gto.moleintor.ascint3(intbn)
        ao_loc = gto.moleintor.make_loc(mol._bas, intbn)
        #print('dsssa',mol.nbas, ao_loc.shape,ao_loc[0],ao_loc[-1],ao_loc[1],ao_loc[2],ao_loc[3],ao_loc[115])
        rao_loc = numpy.zeros((nao),dtype=int)
        for i in range(mol.nbas):
            for j in range(ao_loc[i],ao_loc[i+1]):
                rao_loc[j] = i 
        ovlp = mol.intor_symmetric('int1e_ovlp')

        if rank == 0: print('thrd_nddm',thrd_nddm, 'sblk',sblk, 'intsp',intsp, 'gthrdu',gthrdu)

# coase and fine grids change
    grdchg = 0
    norm_ddm = 0
    for k in range(nset):
        norm_ddm += numpy.linalg.norm(dms[k])
    if norm_ddm < thrd_nddm and cond == 2 :
        cond = 1
    if cond == 0:
        wao_vx, ngridsx, coordsx, gridatm  = get_gridss(mol,grdlvl_i, sblk)
        if rank == 0: print('grids level at first is', grdlvl_i) 
        cond = 2
    elif cond == 1:
        wao_vx, ngridsx, coordsx, gridatm = get_gridss(mol,grdlvl_f, sblk)
        if rank == 0: print('grids level change to', grdlvl_f)
        dms = numpy.asarray(dmcur)
        dms = dms.reshape(-1,nao,nao)
        grdchg = 1
        cond = 3

# DF-J
    dmtril = []
    for k in range(nset):
        dmtril.append(lib.pack_tril(dms[k]+dms[k].T))
        i = numpy.arange(nao)
        dmtril[k][i*(i+1)//2+i] *= .5
    rho = []
    b0 = 0
    for eri1 in loop(mf.with_df):
        naux, nao_pair = eri1.shape
        #if rank==0: print('slice-naux',naux,'rank',rank)
        b1 = b0 + naux
        assert(nao_pair == nao*(nao+1)//2)
        for k in range(nset):
            if b0 == 0: rho.append(numpy.empty(paux[rank]))
            rho[k][b0:b1] = numpy.dot(eri1, dmtril[k])
        b0 = b1
    orho = []
    rec = []
    for k in range(nset):
        orho.append(mpi.gather(rho[k]))
        if rank == 0:
            ivj0 = scipy.linalg.solve(int2c, orho[k])
        else:
            ivj0 = None
        rec.append(numpy.empty(paux[rank]))
        comm.Scatterv([ivj0,paux],rec[k],root=0)
    b0 = 0
    for eri1 in loop(mf.with_df):
        naux, nao_pair = eri1.shape
        b1 = b0 + naux
        assert(nao_pair == nao*(nao+1)//2)
        for k in range(nset):
            vj[k] += numpy.dot(rec[k][b0:b1].T, eri1)
        b0 = b1
    for k in range(nset):
        vj[k] = comm.reduce(vj[k])

# sgX
    wao_v = wao_vx
    coords = coordsx
    for k in range(nset):
# Kuv = Sum(Xug Avt Dkt Xkg)
        ngrids = coords.shape[0]
        for ii in range(gridatm.shape[0]-1):
            i0 = gridatm[ii]
            i1 = gridatm[ii+1]
            # screening u by value of grids 
            umaxg = numpy.amax(numpy.absolute(wao_v[i0:i1]), axis=0)
            usi = numpy.argwhere(umaxg > gthrdu).reshape(-1)
            # screening v by dm and ovlp then triangle matrix bn
            uovl = ovlp[usi, :]
            vmaxu = numpy.amax(numpy.absolute(uovl), axis=0)
            osi = numpy.argwhere(vmaxu > gthrdvs).reshape(-1) 
            udms = dms[k][usi, :]            
            dmaxg = numpy.amax(numpy.absolute(udms), axis=0)
            dsi = numpy.argwhere(dmaxg > gthrdvd).reshape(-1) 
            vsi = numpy.intersect1d(dsi, osi) 
            if len(vsi) != 0:
                vsh = numpy.unique(rao_loc[vsi])          
                #vshbeg = vsh[0]
                vshfin = vsh[-1]+1
                # use gap between continurous v to save time
                vsh1 = vsh
                vsh1= numpy.delete(vsh1, 0)
                vsh1 = numpy.append(vsh1, [vshfin])
                vshd = numpy.argwhere(vsh1-vsh > intsp)
                vshd = numpy.append(vshd, vsh.shape[0]-1)
                nvshd = vshd.shape[0]                 
                #vbeg = ao_loc[vshbeg]
                vfin = ao_loc[vshfin]
                fakemol = gto.fakemol_for_charges(coords[i0:i1])
                pmol = gto.mole.conc_mol(mol, fakemol)
                bn = []
                dmsk = [] 
                bntp = [[0 for col in range(nvshd)] for row in range(nvshd)]        
                for i in range(nvshd):
                    if i==0:
                        ii0 = vsh[0]
                        ii1 = vsh[vshd[0]]+1
                    else:
                        ii0 = vsh[vshd[i-1]+1]
                        ii1 = vsh[vshd[i]]+1
                    dmsk.append(dms[k][:,ao_loc[ii0]:ao_loc[ii1]])
                    bnh = []
                    for j in range(0, i):                       
                        bnh.append(bntp[j][i].swapaxes(0,1))
                    for j in range(i, nvshd):
                        if j==0:
                            jj0 = vsh[0]
                            jj1 = vsh[vshd[0]]+1
                        else:
                            jj0 = vsh[vshd[j-1]+1]
                            jj1 = vsh[vshd[j]]+1
                        shls_slice = (ii0, ii1, jj0, jj1, mol.nbas, mol.nbas+fakemol.nbas)
                        bntp[i][j] = pmol.intor(intor='int3c2e', comp=1, aosym='s1', shls_slice=shls_slice)
                        bnh.append(bntp[i][j])
                    bnrow = numpy.concatenate(bnh, axis=1)
                    bn.append(bnrow)                 
                bn = numpy.concatenate(bn, axis=0)
                abn = numpy.absolute(bn)
                #if cond==3: print(rank,'wet',numpy.amax(abn), numpy.median(abn))
                dmsk = numpy.asarray(numpy.hstack(dmsk))
                fg = numpy.dot(wao_v[i0:i1,usi],dmsk[usi])      
                gv = lib.einsum('vtg,gt->gv', bn, fg) 
                vk0 = numpy.zeros((nao,nao))
                vksp = lib.einsum('gu,gv->uv', wao_v[i0:i1,usi], gv)
                blen = 0
                for i in range(nvshd):
                    if i==0:
                        ii0 = vsh[0]
                        ii1 = vsh[vshd[0]]+1
                    else:
                        ii0 = vsh[vshd[i-1]+1]
                        ii1 = vsh[vshd[i]]+1
                    baa = ao_loc[ii1]-ao_loc[ii0]
                    vk0[usi,ao_loc[ii0]:ao_loc[ii1]] = vksp[:,blen:(blen+baa)]
                    blen += baa
                vk[k] += vk0
            else:
                vk0 = numpy.zeros((nao,nao))
                vk[k] += vk0 
        sn = lib.einsum('gu,gv->uv', wao_v, wao_v)
        vk[k] = comm.reduce(vk[k])
        sn = comm.reduce(sn)
        # SSn^-1 for grids to analitic
        if rank == 0:
            snsgk = scipy.linalg.solve(sn, vk[k])
            vk[k] = numpy.matmul(ovlp, snsgk)

    if rank == 0:
        vj = lib.unpack_tril(numpy.asarray(vj), 1).reshape(dm_shape)
        vk = numpy.asarray(vk).reshape(dm_shape)

    #if cond==3: cond=4

    return vj, vk, grdchg
Ejemplo n.º 32
0
def B1_dot_x(pcmobj, dm, r_vdw, ui, ylm_1sph, cached_pol, L):
    mol = pcmobj.mol
    mol = pcmobj.mol
    natm = mol.natm
    nao = mol.nao
    lmax = pcmobj.lmax
    nlm = (lmax + 1)**2

    dms = numpy.asarray(dm)
    is_single_dm = dms.ndim == 2
    dms = dms.reshape(-1, nao, nao)
    n_dm = dms.shape[0]

    atom_coords = mol.atom_coords()
    atom_charges = mol.atom_charges()
    aoslices = mol.aoslice_by_atom()
    grids = pcmobj.grids
    coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(
        pcmobj.lebedev_order)
    ngrid_1sph = coords_1sph.shape[0]

    extern_point_idx = ui > 0
    fi0 = ddcosmo.make_fi(pcmobj, r_vdw)
    fi1 = ddcosmo_grad.make_fi1(pcmobj, pcmobj.get_atomic_radii())
    fi1[:, :, ui == 0] = 0
    ui1 = -fi1

    Bx = numpy.zeros((natm, 3, nao, nao))

    ao = mol.eval_gto('GTOval', grids.coords)
    aow = numpy.einsum('gi,g->gi', ao, grids.weights)
    aopair = numpy.einsum('gi,gj->gij', ao, aow)
    den = numpy.einsum('gij,ij->g', aopair, dm)
    psi0 = numpy.zeros((natm, nlm))
    i1 = 0
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        fac_pol = ddcosmo._vstack_factor_fak_pol(fak_pol, lmax)
        i0, i1 = i1, i1 + fac_pol.shape[1]
        psi0[ia] = -numpy.einsum('mn,n->m', fac_pol, den[i0:i1])
    LS0 = numpy.linalg.solve(L.reshape(natm * nlm, -1).T, psi0.ravel())
    LS0 = LS0.reshape(natm, nlm)

    phi0 = numpy.zeros((natm, nlm))
    phi1 = numpy.zeros((natm, 3, natm, nlm))
    int3c2e = mol._add_suffix('int3c2e')
    int3c2e_ip1 = mol._add_suffix('int3c2e_ip1')
    cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas, mol._env, int3c2e)
    cintopt_ip1 = gto.moleintor.make_cintopt(mol._atm, mol._bas, mol._env,
                                             int3c2e_ip1)
    for ia in range(natm):
        cav_coords = atom_coords[ia] + r_vdw[ia] * coords_1sph
        #fakemol = gto.fakemol_for_charges(cav_coords[ui[ia]>0])
        fakemol = gto.fakemol_for_charges(cav_coords)
        v_nj = df.incore.aux_e2(mol,
                                fakemol,
                                intor=int3c2e,
                                aosym='s1',
                                cintopt=cintopt)

        v_phi = numpy.einsum('pqg,pq->g', v_nj, dm)
        phi0[ia] = numpy.einsum('n,ln,n,n->l', weights_1sph, ylm_1sph, ui[ia],
                                v_phi)
        phi1[:, :, ia] += lib.einsum('n,ln,azn,n->azl', weights_1sph, ylm_1sph,
                                     ui1[:, :, ia], v_phi)
        Bx += lib.einsum('l,n,ln,azn,ijn->azij', LS0[ia], weights_1sph,
                         ylm_1sph, ui1[:, :, ia], v_nj)

        wtmp = lib.einsum('n,ln,n->ln', weights_1sph, ylm_1sph, ui[ia])

        v_e1_nj = df.incore.aux_e2(mol,
                                   fakemol,
                                   intor=int3c2e_ip1,
                                   comp=3,
                                   aosym='s1',
                                   cintopt=cintopt_ip1)
        vtmp = lib.einsum('l,ln,xijn->xij', LS0[ia], wtmp, v_e1_nj)
        Bx[ia] += vtmp
        Bx[ia] += vtmp.transpose(0, 2, 1)

        for ja in range(natm):
            shl0, shl1, p0, p1 = aoslices[ja]
            Bx[ja, :, p0:p1, :] -= vtmp[:, p0:p1]
            Bx[ja, :, :, p0:p1] -= vtmp[:, p0:p1].transpose(0, 2, 1)
            tmp = numpy.einsum('xijn,ij->xn', v_e1_nj[:, p0:p1], dm[p0:p1])
            tmp += numpy.einsum('xijn,ji->xn', v_e1_nj[:, p0:p1], dm[:, p0:p1])
            phitmp = numpy.einsum('ln,xn->xl', wtmp, tmp)
            phi1[ja, :, ia] -= phitmp
            phi1[ia, :, ia] += phitmp

    Xvec0 = numpy.linalg.solve(L.reshape(natm * nlm, -1), phi0.ravel())
    Xvec0 = Xvec0.reshape(natm, nlm)

    L1 = ddcosmo_grad.make_L1(pcmobj, r_vdw, ylm_1sph, fi0)

    phi1 -= lib.einsum('aziljm,jm->azil', L1, Xvec0)
    Xvec1 = numpy.linalg.solve(L.reshape(natm * nlm, -1),
                               phi1.reshape(-1, natm * nlm).T)
    Xvec1 = Xvec1.T.reshape(natm, 3, natm, nlm)

    psi1 = numpy.zeros((natm, 3, natm, nlm))
    i1 = 0
    for ia, (coords, weight,
             weight1) in enumerate(rks_grad.grids_response_cc(grids)):
        i0, i1 = i1, i1 + weight.size
        ao = mol.eval_gto('GTOval_sph_deriv1', coords)
        aow = numpy.einsum('gi,g->gi', ao[0], weight)
        aopair1 = lib.einsum('xgi,gj->xgij', ao[1:], aow)
        aow = numpy.einsum('gi,zxg->zxgi', ao[0], weight1)
        aopair0 = lib.einsum('zxgi,gj->zxgij', aow, ao[0])
        den0 = numpy.einsum('zxgij,ij->zxg', aopair0, dm)
        den1 = numpy.empty((natm, 3, weight.size))
        for ja in range(natm):
            shl0, shl1, p0, p1 = aoslices[ja]
            den1[ja] = numpy.einsum('xgij,ij->xg', aopair1[:, :, p0:p1],
                                    dm[p0:p1, :])
            den1[ja] += numpy.einsum('xgij,ji->xg', aopair1[:, :, p0:p1],
                                     dm[:, p0:p1])

        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        fac_pol = ddcosmo._vstack_factor_fak_pol(fak_pol, lmax)
        scaled_weights = lib.einsum('azm,mn->azn', Xvec1[:, :, ia], fac_pol)
        scaled_weights *= weight
        aow = numpy.einsum('gi,azg->azgi', ao[0], scaled_weights)
        Bx -= numpy.einsum('gi,azgj->azij', ao[0], aow)

        tmp = numpy.einsum('mn,zxn->zxm', fac_pol, den1)
        psi1[:, :, ia] -= numpy.einsum('mn,zxn->zxm', fac_pol, den0)
        psi1[ia, :, ia] -= tmp.sum(axis=0)
        for ja in range(natm):
            psi1[ja, :, ia] += tmp[ja]

        eta_nj = lib.einsum('mn,m->n', fac_pol, Xvec0[ia])
        Bx -= lib.einsum('n,zxnpq->zxpq', eta_nj, aopair0)
        vtmp = lib.einsum('n,xnpq->xpq', eta_nj, aopair1)
        Bx[ia] -= vtmp
        Bx[ia] -= vtmp.transpose(0, 2, 1)
        for ja in range(natm):
            shl0, shl1, q0, q1 = aoslices[ja]
            Bx[ja, :, q0:q1, :] += vtmp[:, q0:q1]
            Bx[ja, :, :, q0:q1] += vtmp[:, q0:q1].transpose(0, 2, 1)

    psi1 -= numpy.einsum('il,aziljm->azjm', LS0, L1)
    LS1 = numpy.linalg.solve(
        L.reshape(natm * nlm, -1).T,
        psi1.reshape(-1, natm * nlm).T)
    LS1 = LS1.T.reshape(natm, 3, natm, nlm)

    cav_coords = (atom_coords.reshape(natm, 1, 3) +
                  numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))
    cav_coords = cav_coords[extern_point_idx]
    fakemol = gto.fakemol_for_charges(cav_coords)
    v_nj = df.incore.aux_e2(mol,
                            fakemol,
                            intor=int3c2e,
                            aosym='s1',
                            cintopt=cintopt)
    v_phi = numpy.zeros((natm, ngrid_1sph, nao, nao))
    v_phi[extern_point_idx] += v_nj.transpose(2, 0, 1)
    Bx += lib.einsum('azjx,n,xn,jn,jnpq->azpq', LS1, weights_1sph, ylm_1sph,
                     ui, v_phi)

    return Bx
Ejemplo n.º 33
0
def make_phi1(pcmobj, dm, r_vdw, ui):
    mol = pcmobj.mol
    natm = mol.natm
    nlm = (pcmobj.lmax+1)**2

    if not (isinstance(dm, numpy.ndarray) and dm.ndim == 2):
        dm = dm[0] + dm[1]
    tril_dm = lib.pack_tril(dm+dm.T)
    nao = dm.shape[0]
    diagidx = numpy.arange(nao)
    diagidx = diagidx*(diagidx+1)//2 + diagidx
    tril_dm[diagidx] *= .5

    atom_coords = mol.atom_coords()
    atom_charges = mol.atom_charges()

    coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(pcmobj.lebedev_order)
    ylm_1sph = numpy.vstack(sph.real_sph_vec(coords_1sph, pcmobj.lmax, True))
    extern_point_idx = ui > 0

    fi1 = make_fi1(pcmobj, pcmobj.get_atomic_radii())
    fi1[:,:,ui==0] = 0
    ui1 = -fi1

    ngrid_1sph = weights_1sph.size
    v_phi0 = numpy.empty((natm,ngrid_1sph))
    for ia in range(natm):
        cav_coords = atom_coords[ia] + r_vdw[ia] * coords_1sph
        d_rs = atom_coords.reshape(-1,1,3) - cav_coords
        v_phi0[ia] = numpy.einsum('z,zp->p', atom_charges, 1./lib.norm(d_rs,axis=2))
    phi1 = -numpy.einsum('n,ln,azjn,jn->azjl', weights_1sph, ylm_1sph, ui1, v_phi0)

    for ia in range(natm):
        cav_coords = atom_coords[ia] + r_vdw[ia] * coords_1sph
        for ja in range(natm):
            rs = atom_coords[ja] - cav_coords
            d_rs = lib.norm(rs, axis=1)
            v_phi = atom_charges[ja] * numpy.einsum('px,p->px', rs, 1./d_rs**3)
            tmp = numpy.einsum('n,ln,n,nx->xl', weights_1sph, ylm_1sph, ui[ia], v_phi)
            phi1[ja,:,ia] += tmp  # response of the other atoms
            phi1[ia,:,ia] -= tmp  # response of cavity grids

    int3c2e = mol._add_suffix('int3c2e')
    int3c2e_ip1 = mol._add_suffix('int3c2e_ip1')
    aoslices = mol.aoslice_by_atom()
    for ia in range(natm):
        cav_coords = atom_coords[ia] + r_vdw[ia] * coords_1sph
        #fakemol = gto.fakemol_for_charges(cav_coords[ui[ia]>0])
        fakemol = gto.fakemol_for_charges(cav_coords)
        v_nj = df.incore.aux_e2(mol, fakemol, intor=int3c2e, aosym='s1')
        v_phi = numpy.einsum('ij,ijk->k', dm, v_nj)
        phi1[:,:,ia] += numpy.einsum('n,ln,azn,n->azl', weights_1sph, ylm_1sph, ui1[:,:,ia], v_phi)

        v_e1_nj = df.incore.aux_e2(mol, fakemol, intor=int3c2e_ip1, comp=3, aosym='s1')
        v_e2_nj = v_e1_nj + v_e1_nj.transpose(0,2,1,3)
        phi1_e2_nj = numpy.einsum('ji,xijr->xr', dm, v_e2_nj)
        phi1[ia,:,ia] += numpy.einsum('n,ln,n,xn->xl', weights_1sph, ylm_1sph, ui[ia], phi1_e2_nj)

        for ja in range(natm):
            shl0, shl1, p0, p1 = aoslices[ja]
            phi1_nj  = numpy.einsum('ij,xijr->xr', dm[p0:p1  ], v_e1_nj[:,p0:p1])
            phi1_nj += numpy.einsum('ji,xijr->xr', dm[:,p0:p1], v_e1_nj[:,p0:p1])
            phi1[ja,:,ia] -= numpy.einsum('n,ln,n,xn->xl', weights_1sph, ylm_1sph, ui[ia], phi1_nj)
    return phi1
Ejemplo n.º 34
0
def make_B(pcmobj, r_vdw, ui, ylm_1sph, cached_pol, L):
    mol = pcmobj.mol
    coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(
        pcmobj.lebedev_order)
    ngrid_1sph = coords_1sph.shape[0]
    mol = pcmobj.mol
    natm = mol.natm
    nao = mol.nao
    lmax = pcmobj.lmax
    nlm = (lmax + 1)**2

    atom_coords = mol.atom_coords()
    atom_charges = mol.atom_charges()
    grids = pcmobj.grids

    extern_point_idx = ui > 0
    cav_coords = (atom_coords.reshape(natm, 1, 3) +
                  numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))

    max_memory = pcmobj.max_memory - lib.current_memory()[0]
    blksize = int(max(max_memory * .9e6 / 8 / nao**2, 400))

    cav_coords = cav_coords[extern_point_idx]
    int3c2e = mol._add_suffix('int3c2e')
    cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas, mol._env, int3c2e)
    fakemol = gto.fakemol_for_charges(cav_coords)
    v_nj = df.incore.aux_e2(mol,
                            fakemol,
                            intor=int3c2e,
                            aosym='s2ij',
                            cintopt=cintopt)
    nao_pair = v_nj.shape[0]
    v_phi = numpy.zeros((nao_pair, natm, ngrid_1sph))
    v_phi[:, extern_point_idx] += v_nj

    phi = numpy.einsum('n,xn,jn,ijn->ijx', weights_1sph, ylm_1sph, ui, v_phi)

    Xvec = numpy.linalg.solve(L.reshape(natm * nlm, -1),
                              phi.reshape(-1, natm * nlm).T)
    Xvec = Xvec.reshape(natm, nlm, nao_pair)

    ao = mol.eval_gto('GTOval', grids.coords)
    aow = numpy.einsum('gi,g->gi', ao, grids.weights)
    aopair = lib.pack_tril(numpy.einsum('gi,gj->gij', ao, aow))

    psi = numpy.zeros((nao_pair, natm, nlm))
    i1 = 0
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        i0, i1 = i1, i1 + fak_pol[0].shape[1]
        p1 = 0
        for l in range(lmax + 1):
            fac = 4 * numpy.pi / (l * 2 + 1)
            p0, p1 = p1, p1 + (l * 2 + 1)
            psi[:, ia, p0:p1] = -fac * numpy.einsum('mn,ni->im', fak_pol[l],
                                                    aopair[i0:i1])

    B = lib.einsum('pnl,nlq->pq', psi, Xvec)
    B = B + B.T
    B = ao2mo.restore(1, B, nao)
    return B
Ejemplo n.º 35
0
    def _exec_cppe(self, dm, elec_only=False):
        dms = numpy.asarray(dm)
        is_single_dm = dms.ndim == 2

        nao = dms.shape[-1]
        dms = dms.reshape(-1,nao,nao)
        n_dm = dms.shape[0]

        if self.V_es is None:
            positions = numpy.array([p.position for p in self.potentials])
            moments = []
            orders = []
            for p in self.potentials:
                p_moments = []
                for m in p.multipoles:
                    m.remove_trace()
                    p_moments.append(m.values)
                orders.append(m.k)
                moments.append(p_moments)
            self.V_es = self._compute_multipole_potential_integrals(positions, orders, moments)

        e_static = numpy.einsum('ij,xij->x', self.V_es, dms)
        self.cppe_state.energies["Electrostatic"]["Electronic"] = (
            e_static[0]
        )

        positions = numpy.array([p.position for p in self.potentials
                                 if p.is_polarizable])
        n_sites = positions.shape[0]
        V_ind = numpy.zeros((n_dm, nao, nao))

        e_tot = []
        e_pol = []
        if n_sites > 0:
            #:elec_fields = self._compute_field(positions, dms)
            fakemol = gto.fakemol_for_charges(positions)
            j3c = df.incore.aux_e2(self.mol, fakemol, intor='int3c2e_ip1')
            elec_fields = (numpy.einsum('aijg,nij->nga', j3c, dms) +
                           numpy.einsum('aijg,nji->nga', j3c, dms))

            induced_moments = numpy.empty((n_dm, n_sites * 3))
            for i_dm in range(n_dm):
                self.cppe_state.update_induced_moments(elec_fields[i_dm].ravel(), elec_only)
                induced_moments[i_dm] = numpy.array(self.cppe_state.get_induced_moments())

                e_tot.append(self.cppe_state.total_energy)
                e_pol.append(self.cppe_state.energies["Polarization"]["Electronic"])

            induced_moments = induced_moments.reshape(n_dm, n_sites, 3)
            #:V_ind = self._compute_field_integrals(positions, induced_moments)
            V_ind = numpy.einsum('aijg,nga->nij', j3c, -induced_moments)
            V_ind = V_ind + V_ind.transpose(0, 2, 1)

        if not elec_only:
            vmat = self.V_es + V_ind
            e = numpy.array(e_tot)
        else:
            vmat = V_ind
            e = numpy.array(e_pol)

        if is_single_dm:
            e = e[0]
            vmat = vmat[0]
        return e, vmat
Ejemplo n.º 36
0
def make_phi1(pcmobj, dm, r_vdw, ui):
    mol = pcmobj.mol
    natm = mol.natm
    nlm = (pcmobj.lmax+1)**2

    if not (isinstance(dm, numpy.ndarray) and dm.ndim == 2):
        dm = dm[0] + dm[1]
    tril_dm = lib.pack_tril(dm+dm.T)
    nao = dm.shape[0]
    diagidx = numpy.arange(nao)
    diagidx = diagidx*(diagidx+1)//2 + diagidx
    tril_dm[diagidx] *= .5

    atom_coords = mol.atom_coords()
    atom_charges = mol.atom_charges()

    coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(pcmobj.lebedev_order)
    ylm_1sph = numpy.vstack(sph.real_sph_vec(coords_1sph, pcmobj.lmax, True))
    extern_point_idx = ui > 0

    fi1 = make_fi1(pcmobj, pcmobj.get_atomic_radii())
    fi1[:,:,ui==0] = 0
    ui1 = -fi1

    ngrid_1sph = weights_1sph.size
    v_phi0 = numpy.empty((natm,ngrid_1sph))
    for ia in range(natm):
        cav_coords = atom_coords[ia] + r_vdw[ia] * coords_1sph
        d_rs = atom_coords.reshape(-1,1,3) - cav_coords
        v_phi0[ia] = numpy.einsum('z,zp->p', atom_charges, 1./lib.norm(d_rs,axis=2))
    phi1 = -numpy.einsum('n,ln,azjn,jn->azjl', weights_1sph, ylm_1sph, ui1, v_phi0)

    for ia in range(natm):
        cav_coords = atom_coords[ia] + r_vdw[ia] * coords_1sph
        for ja in range(natm):
            rs = atom_coords[ja] - cav_coords
            d_rs = lib.norm(rs, axis=1)
            v_phi = atom_charges[ja] * numpy.einsum('px,p->px', rs, 1./d_rs**3)
            tmp = numpy.einsum('n,ln,n,nx->xl', weights_1sph, ylm_1sph, ui[ia], v_phi)
            phi1[ja,:,ia] += tmp  # response of the other atoms
            phi1[ia,:,ia] -= tmp  # response of cavity grids

    int3c2e = mol._add_suffix('int3c2e')
    int3c2e_ip1 = mol._add_suffix('int3c2e_ip1')
    aoslices = mol.aoslice_by_atom()
    for ia in range(natm):
        cav_coords = atom_coords[ia] + r_vdw[ia] * coords_1sph
        #fakemol = gto.fakemol_for_charges(cav_coords[ui[ia]>0])
        fakemol = gto.fakemol_for_charges(cav_coords)
        v_nj = df.incore.aux_e2(mol, fakemol, intor=int3c2e, aosym='s1')
        v_phi = numpy.einsum('ij,ijk->k', dm, v_nj)
        phi1[:,:,ia] += numpy.einsum('n,ln,azn,n->azl', weights_1sph, ylm_1sph, ui1[:,:,ia], v_phi)

        v_e1_nj = df.incore.aux_e2(mol, fakemol, intor=int3c2e_ip1, comp=3, aosym='s1')
        v_e2_nj = v_e1_nj + v_e1_nj.transpose(0,2,1,3)
        phi1_e2_nj = numpy.einsum('ji,xijr->xr', dm, v_e2_nj)
        phi1[ia,:,ia] += numpy.einsum('n,ln,n,xn->xl', weights_1sph, ylm_1sph, ui[ia], phi1_e2_nj)

        for ja in range(natm):
            shl0, shl1, p0, p1 = aoslices[ja]
            phi1_nj  = numpy.einsum('ij,xijr->xr', dm[p0:p1  ], v_e1_nj[:,p0:p1])
            phi1_nj += numpy.einsum('ji,xijr->xr', dm[:,p0:p1], v_e1_nj[:,p0:p1])
            phi1[ja,:,ia] -= numpy.einsum('n,ln,n,xn->xl', weights_1sph, ylm_1sph, ui[ia], phi1_nj)
    return phi1
Ejemplo n.º 37
0
def make_psi_vmat(pcmobj, dm, r_vdw, ui, grids, ylm_1sph, cached_pol, L_X, L):
    mol = pcmobj.mol
    natm = mol.natm
    lmax = pcmobj.lmax
    nlm = (lmax+1)**2

    i1 = 0
    scaled_weights = numpy.empty(grids.weights.size)
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        i0, i1 = i1, i1 + fak_pol[0].shape[1]
        eta_nj = 0
        p1 = 0
        for l in range(lmax+1):
            fac = 4*numpy.pi/(l*2+1)
            p0, p1 = p1, p1 + (l*2+1)
            eta_nj += fac * numpy.einsum('mn,m->n', fak_pol[l], L_X[ia,p0:p1])
        scaled_weights[i0:i1] = eta_nj * grids.weights[i0:i1]

    if not (isinstance(dm, numpy.ndarray) and dm.ndim == 2):
        dm = dm[0] + dm[1]
    ni = numint.NumInt()
    max_memory = pcmobj.max_memory - lib.current_memory()[0]
    make_rho, nset, nao = ni._gen_rho_evaluator(mol, dm)
    shls_slice = (0, mol.nbas)
    ao_loc = mol.ao_loc_nr()
    den = numpy.empty(grids.weights.size)
    vmat = numpy.zeros((nao,nao))
    p1 = 0
    aow = None
    for ao, mask, weight, coords \
            in ni.block_loop(mol, grids, nao, 0, max_memory):
        p0, p1 = p1, p1 + weight.size
        den[p0:p1] = weight * make_rho(0, ao, mask, 'LDA')
        aow = numpy.ndarray(ao.shape, order='F', buffer=aow)
        aow = numpy.einsum('pi,p->pi', ao, scaled_weights[p0:p1], out=aow)
        vmat -= numint._dot_ao_ao(mol, ao, aow, mask, shls_slice, ao_loc)
    ao = aow = scaled_weights = None

    nelec_leak = 0
    psi = numpy.empty((natm,nlm))
    i1 = 0
    for ia in range(natm):
        fak_pol, leak_idx = cached_pol[mol.atom_symbol(ia)]
        i0, i1 = i1, i1 + fak_pol[0].shape[1]
        nelec_leak += den[i0:i1][leak_idx].sum()
        p1 = 0
        for l in range(lmax+1):
            fac = 4*numpy.pi/(l*2+1)
            p0, p1 = p1, p1 + (l*2+1)
            psi[ia,p0:p1] = -fac * numpy.einsum('n,mn->m', den[i0:i1], fak_pol[l])
# Contribution of nuclear charge to the total density
# The factor numpy.sqrt(4*numpy.pi) is due to the product of 4*pi * Y_0^0
        psi[ia,0] += numpy.sqrt(4*numpy.pi)/r_vdw[ia] * mol.atom_charge(ia)
    logger.debug(pcmobj, 'electron leak %f', nelec_leak)

    # <Psi, L^{-1}g> -> Psi = SL the adjoint equation to LX = g
    L_S = numpy.linalg.solve(L.T.reshape(natm*nlm,-1), psi.ravel()).reshape(natm,-1)
    coords_1sph, weights_1sph = make_grids_one_sphere(pcmobj.lebedev_order)
    # JCP, 141, 184108, Eq (39)
    xi_jn = numpy.einsum('n,jn,xn,jx->jn', weights_1sph, ui, ylm_1sph, L_S)
    extern_point_idx = ui > 0
    cav_coords = (mol.atom_coords().reshape(natm,1,3)
                  + numpy.einsum('r,gx->rgx', r_vdw, coords_1sph))
    cav_coords = cav_coords[extern_point_idx]
    xi_jn = xi_jn[extern_point_idx]

    max_memory = pcmobj.max_memory - lib.current_memory()[0]
    blksize = int(max(max_memory*1e6/8/nao**2, 400))

    cintopt = gto.moleintor.make_cintopt(mol._atm, mol._bas,
                                         mol._env, 'int3c2e')
    vmat_tril = 0
    for i0, i1 in lib.prange(0, xi_jn.size, blksize):
        fakemol = gto.fakemol_for_charges(cav_coords[i0:i1])
        v_nj = df.incore.aux_e2(mol, fakemol, intor='int3c2e', aosym='s2ij',
                                cintopt=cintopt)
        vmat_tril += numpy.einsum('xn,n->x', v_nj, xi_jn[i0:i1])
    vmat += lib.unpack_tril(vmat_tril)
    return psi, vmat, L_S
Ejemplo n.º 38
0
# There are two ways to compute this potential.
# Method 1 (slow): looping over r_orig and evaluating 1/|r-r_orig| for each
# point.
dm = mf.make_rdm1()
Vele = []
for p in points:
    mol.set_rinv_orig_(p)
    Vele.append(numpy.einsum('ij,ij', mol.intor('int1e_rinv'), dm))
Vele = numpy.array(Vele)

# Method 2 (fast): Mimicing the points with delta function (steep S-type
# Gaussians) then calling the 3-center integral code to calculate the
# interaction between points and other AOs. Below, fakemol holds the delta
# functions.
from pyscf import df
fakemol = gto.fakemol_for_charges(points)
Vele = np.einsum('ijp,ij->p', df.incore.aux_e2(mol, fakemol), dm)

#
# 4. MEP at each point
#
MEP = Vnuc - Vele
print(MEP.shape)

#
# 5. MEP force = -d/dr MEP = -d/dr Vnuc + d/dr Vele
#
Fnuc = 0
for i in range(mol.natm):
    r = mol.atom_coord(i)
    Z = mol.atom_charge(i)