Ejemplo n.º 1
0
def minimize(obj,
             bounds=(None, None),
             method='brent',
             maxiter=OPT_MAXITER,
             tol=OPT_XTOL,
             x0=None,
             root_with_omp=False):
    # Runs the chemical potential minimization with a bunch of different
    # available methods, uses OpenMP on the root process only.
    # Best methods are golden and lstsq, golden uses more function calls with less
    # additional overhead, whereas lstsq uses fewer function calls and more overhead,
    # lstsq is best unless we efficiently parallelise the objective function.

    if method == 'brent':
        kwargs = dict(method='bounded',
                      bounds=bounds,
                      options=dict(maxiter=maxiter, xatol=tol))
        f = optimize.minimize_scalar
    elif method == 'golden':
        kwargs = dict(method='golden',
                      bounds=bounds,
                      options=dict(maxiter=maxiter, xtol=tol))
        f = optimize.minimize_scalar
    elif method == 'newton':
        kwargs = dict(method='TNC',
                      bounds=[bounds],
                      x0=x0,
                      options=dict(maxiter=maxiter, xtol=tol))
        f = optimize.minimize
    elif method == 'bfgs':
        kwargs = dict(method='L-BFGS-B',
                      bounds=[bounds],
                      x0=x0,
                      options=dict(maxiter=maxiter, ftol=tol))
        f = optimize.minimize
    elif method == 'lstsq':
        kwargs = dict(method='SLSQP',
                      x0=x0,
                      options=dict(maxiter=maxiter, ftol=tol))
        f = optimize.minimize
    elif method == 'stochastic':
        kwargs = dict(bounds=[(-5, 5)], maxiter=maxiter, tol=tol)
        f = optimize.differential_evolution
    else:
        raise ValueError

    if root_with_omp:
        opt = None

        if rank == 0:
            with lib.with_omp_threads(size):
                opt = f(obj, **kwargs)

        if size > 1:
            opt = comm.bcast(opt, root=0)

    else:
        opt = f(obj, **kwargs)

    return opt
Ejemplo n.º 2
0
    def run(self, **kwargs):
        if self.disable_omp:
            with lib.with_omp_threads(1):
                self._run(**kwargs)
        else:
            self._run(**kwargs)

        if not self._pyscf.converged:
            if mpi.rank:
                log.warn('%s did not converge.' % self.__class__.__name__)

        return self
Ejemplo n.º 3
0
    def build(self):

        t0 = (time.clock(), time.time())
        lib.logger.TIMER_LEVEL = 3

        self.nelectron = self.mol.nelectron
        self.charge = self.mol.charge
        self.spin = self.mol.spin
        self.natm = self.mol.natm
        self.coords = numpy.asarray([(numpy.asarray(atom[1])).tolist()
                                     for atom in self.mol._atom])
        self.charges = self.mol.atom_charges()
        self.mo_coeff = lib.chkfile.load(self.chkfile, 'scf/mo_coeff')
        self.mo_occ = lib.chkfile.load(self.chkfile, 'scf/mo_occ')
        nprims, nmo = self.mo_coeff.shape
        self.nprims = nprims
        self.nmo = nmo

        if (self.corr):
            self.rdm1 = lib.chkfile.load(self.chkfile, 'rdm/rdm1')
            natocc, natorb = numpy.linalg.eigh(self.rdm1)
            natorb = numpy.dot(self.mo_coeff, natorb)
            self.mo_coeff = natorb
            self.mo_occ = natocc
        nocc = self.mo_occ[abs(self.mo_occ) > self.occdrop]
        nocc = len(nocc)
        self.nocc = nocc

        self.grids.verbose = 0
        self.grids.stdout = self.stdout
        self.grids.build()

        vfree(self)

        if self.verbose >= logger.WARN:
            self.check_sanity()
        if self.verbose > logger.NOTE:
            self.dump_input()

        with lib.with_omp_threads(self.nthreads):
            integrate(self)

        logger.info(self, 'Hirshfeld properties done')
        logger.timer(self, 'Hirshfeld build', *t0)

        return self
Ejemplo n.º 4
0
    def build(self):

        t0 = time.clock()
        lib.logger.TIMER_LEVEL = 3

        self.mol = lib.chkfile.load_mol(self.chkfile)
        self.mo_coeff = lib.chkfile.load(self.chkfile, 'scf/mo_coeff')
        self.mo_occ = lib.chkfile.load(self.chkfile, 'scf/mo_occ')
        self.nelectron = self.mol.nelectron
        self.charge = self.mol.charge
        self.spin = self.mol.spin
        self.natm = self.mol.natm
        self.coords = numpy.asarray([(numpy.asarray(atom[1])).tolist()
                                     for atom in self.mol._atom])
        self.charges = self.mol.atom_charges()

        idx = 'grid' + str(self.inucs[0])
        jdx = 'grid' + str(self.inucs[1])
        with h5py.File(self.surfile) as f:
            self.p1 = f[idx + '/p'].value
            self.w1 = f[idx + '/w'].value
            self.p2 = f[jdx + '/p'].value
            self.w2 = f[jdx + '/w'].value
        self.npoints = numpy.zeros(2, dtype=numpy.int32)
        self.npoints[0] = len(self.w1)
        self.npoints[1] = len(self.w2)

        if self.verbose >= logger.WARN:
            self.check_sanity()
        if self.verbose > logger.NOTE:
            self.dump_input()

        with lib.with_omp_threads(self.nthreads):
            ev = vv10_e(self)
        lib.logger.info(self, 'VV10 energy %f' % ev)
        logger.info(self, 'Write info to HDF5 file')

        logger.info(self, 'VV10 of atoms %d %d done', *self.inucs)
        logger.timer(self, 'VV10 build', t0)

        return self
Ejemplo n.º 5
0
    def build(self):

        t0 = (time.clock(), time.time())
        lib.logger.TIMER_LEVEL = 3

        self.mol = lib.chkfile.load_mol(self.chkfile)
        self.nelectron = self.mol.nelectron
        self.charge = self.mol.charge
        self.spin = self.mol.spin
        self.natm = self.mol.natm
        self.coords = numpy.asarray([(numpy.asarray(atom[1])).tolist()
                                     for atom in self.mol._atom])
        self.charges = self.mol.atom_charges()
        if (self.cas):
            self.mo_coeff = lib.chkfile.load(self.chkfile, 'mcscf/mo_coeff')
        else:
            self.mo_coeff = lib.chkfile.load(self.chkfile, 'scf/mo_coeff')
        self.mo_occ = lib.chkfile.load(self.chkfile, 'scf/mo_occ')
        nprims, nmo = self.mo_coeff.shape
        self.nprims = nprims
        self.nmo = nmo
        if self.charges[self.inuc] == 1:
            self.rad = grid.BRAGG[self.charges[self.inuc]]
        else:
            self.rad = grid.BRAGG[self.charges[self.inuc]] * 0.5

        if (self.corr):
            self.rdm1 = lib.chkfile.load(self.chkfile, 'rdm/rdm1')
            natocc, natorb = numpy.linalg.eigh(self.rdm1)
            natorb = numpy.dot(self.mo_coeff, natorb)
            self.mo_coeff = natorb
            self.mo_occ = natocc
        nocc = self.mo_occ[abs(self.mo_occ) > self.occdrop]
        nocc = len(nocc)
        self.nocc = nocc

        idx = 'atom' + str(self.inuc)
        with h5py.File(self.surfile) as f:
            self.xnuc = f[idx + '/xnuc'].value
            self.xyzrho = f[idx + '/xyzrho'].value
            self.npang = f[idx + '/npang'].value
            self.ntrial = f[idx + '/ntrial'].value
            self.rmin = f[idx + '/rmin'].value
            self.rmax = f[idx + '/rmax'].value
            self.rsurf = f[idx + '/rsurf'].value
            self.nlimsurf = f[idx + '/nlimsurf'].value
            self.agrids = f[idx + '/coords'].value

        self.brad = self.rmin * self.betafac

        if self.verbose >= logger.WARN:
            self.check_sanity()
        if self.verbose > logger.NOTE:
            self.dump_input()

        if (self.iqudr == 'legendre'):
            self.iqudr = 1
        if (self.biqudr == 'legendre'):
            self.biqudr = 1

        if (self.mapr == 'becke'):
            self.mapr = 1
        elif (self.mapr == 'exp'):
            self.mapr = 2
        elif (self.mapr == 'none'):
            self.mapr = 0
        if (self.bmapr == 'becke'):
            self.bmapr = 1
        elif (self.bmapr == 'exp'):
            self.bmapr = 2
        elif (self.bmapr == 'none'):
            self.bmapr = 0

        if (self.full):
            self.nocc = self.nmo
            nocc = self.nmo
        else:
            nocc = self.mo_occ[self.mo_occ > self.occdrop]
            nocc = len(nocc)
            self.nocc = nocc

        self.aom = numpy.zeros((nocc, nocc))

        with lib.with_omp_threads(self.nthreads):
            aomb = int_beta(self)
            aoma = out_beta(self)

        idx = 0
        for i in range(nocc):
            for j in range(i + 1):
                self.aom[i, j] = aoma[idx] + aomb[idx]
                self.aom[j, i] = self.aom[i, j]
                idx += 1
        if (self.nmo <= 30):
            dump_tri(self.stdout, self.aom, ncol=NCOL, digits=DIGITS, start=0)

        logger.info(self, 'Write info to HDF5 file')
        atom_dic = {'aom': self.aom}
        lib.chkfile.save(self.surfile, 'ovlp' + str(self.inuc), atom_dic)
        logger.info(self, '')

        logger.info(self, 'AOM of atom %d done', self.inuc)
        logger.timer(self, 'AOM build', *t0)

        return self
Ejemplo n.º 6
0
    def build(self):

        t0 = (time.clock(), time.time())
        lib.logger.TIMER_LEVEL = 3

        mol = lib.chkfile.load_mol(self.chkfile)
        self.nelectron = mol.nelectron
        self.charge = mol.charge
        self.spin = mol.spin
        self.natm = mol.natm
        self.atm = numpy.asarray(mol._atm, dtype=numpy.int32, order='C')
        self.bas = numpy.asarray(mol._bas, dtype=numpy.int32, order='C')
        self.nbas = self.bas.shape[0]
        self.env = numpy.asarray(mol._env, dtype=numpy.double, order='C')
        self.ao_loc = mol.ao_loc_nr()
        self.shls_slice = (0, self.nbas)
        sh0, sh1 = self.shls_slice
        self.nao = self.ao_loc[sh1] - self.ao_loc[sh0]
        self.non0tab = numpy.ones((1, self.nbas), dtype=numpy.int8)
        self.coords = numpy.asarray([(numpy.asarray(atom[1])).tolist()
                                     for atom in mol._atom])
        self.charges = mol.atom_charges()
        #if (self.cas):
        #    self.mo_coeff = lib.chkfile.load(self.chkfile, 'mcscf/mo_coeff')
        #else:
        #    self.mo_coeff = lib.chkfile.load(self.chkfile, 'scf/mo_coeff')
        self.mo_coeff = lib.chkfile.load(self.chkfile, 'scf/mo_coeff')
        self.mo_occ = lib.chkfile.load(self.chkfile, 'scf/mo_occ')
        nprims, nmo = self.mo_coeff.shape
        self.nprims = nprims
        self.nmo = nmo
        self.cart = mol.cart
        if (not self.leb):
            self.npang = self.npphi * self.nptheta

        if (self.corr):
            self.rdm1 = lib.chkfile.load(self.chkfile, 'rdm/rdm1')
            nmo = self.rdm1.shape[0]
            natocc, natorb = numpy.linalg.eigh(self.rdm1)
            if (self.cas):
                self.mo_coeff = lib.chkfile.load(self.chkfile,
                                                 'mcscf/mo_coeff')
            natorb = numpy.dot(self.mo_coeff, natorb)
            self.mo_coeff = natorb
            self.mo_occ = natocc

        nocc = self.mo_occ[abs(self.mo_occ) > self.occdrop]
        nocc = len(nocc)
        self.nocc = nocc

        if (self.ntrial % 2 == 0): self.ntrial += 1
        geofac = numpy.power(((self.rmaxsurf - 0.1) / self.rprimer),
                             (1.0 / (self.ntrial - 1.0)))
        self.rpru = numpy.zeros((self.ntrial))
        for i in range(self.ntrial):
            self.rpru[i] = self.rprimer * numpy.power(geofac, (i + 1) - 1)
        self.rsurf = numpy.zeros((self.npang, self.ntrial), order='C')
        self.nlimsurf = numpy.zeros((self.npang), dtype=numpy.int32)

        if self.verbose >= logger.WARN:
            self.check_sanity()
        if self.verbose > logger.NOTE:
            self.dump_input()

        if (self.iqudt == 'legendre'):
            self.iqudt = 1

        if (self.leb):
            self.grids = grid.lebgrid(self.npang)
        else:
            self.grids = grid.anggrid(self.iqudt, self.nptheta, self.npphi)

        self.xyzrho = numpy.zeros((self.natm, 3))
        t = time.time()
        for i in range(self.natm):
            self.xyzrho[i], gradmod = gradrho(self, self.coords[i], self.step)
            if (gradmod > 1e-4):
                if (self.charges[i] > 2.0):
                    logger.info(self, 'Good rho position %.6f %.6f %.6f',
                                *self.xyzrho[i])
                else:
                    raise RuntimeError('Failed finding nucleus:',
                                       *self.xyzrho[i])
            else:
                logger.info(self, 'Check rho position %.6f %.6f %.6f',
                            *self.xyzrho[i])
                logger.info(self, 'Setting xyzrho for atom to imput coords')
                self.xyzrho[i] = self.coords[i]
        self.xnuc = numpy.asarray(self.xyzrho[self.inuc])
        logger.info(self,
                    'Time finding nucleus %.3f (sec)' % (time.time() - t))

        if (self.backend == 'rkck'):
            backend = 1
        elif (self.backend == 'rkdp'):
            backend = 2
        else:
            raise NotImplementedError(
                'Only rkck or rkdp ODE solver yet available')

        ct_ = numpy.asarray(self.grids[:, 0], order='C')
        st_ = numpy.asarray(self.grids[:, 1], order='C')
        cp_ = numpy.asarray(self.grids[:, 2], order='C')
        sp_ = numpy.asarray(self.grids[:, 3], order='C')

        t = time.time()
        feval = 'surf_driver'
        drv = getattr(libaim, feval)
        with lib.with_omp_threads(self.nthreads):
            drv(ctypes.c_int(self.inuc),
                self.xyzrho.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_int(self.npang), ct_.ctypes.data_as(ctypes.c_void_p),
                st_.ctypes.data_as(ctypes.c_void_p),
                cp_.ctypes.data_as(ctypes.c_void_p),
                sp_.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(self.ntrial),
                self.rpru.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_double(self.epsiscp), ctypes.c_double(self.epsroot),
                ctypes.c_double(self.rmaxsurf), ctypes.c_int(backend),
                ctypes.c_double(self.epsilon), ctypes.c_double(self.step),
                ctypes.c_int(self.mstep), ctypes.c_int(self.natm),
                self.coords.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_int(self.cart), ctypes.c_int(self.nmo),
                ctypes.c_int(self.nprims),
                self.atm.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_int(self.nbas),
                self.bas.ctypes.data_as(ctypes.c_void_p),
                self.env.ctypes.data_as(ctypes.c_void_p),
                self.ao_loc.ctypes.data_as(ctypes.c_void_p),
                self.mo_coeff.ctypes.data_as(ctypes.c_void_p),
                self.mo_occ.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_double(self.occdrop),
                self.nlimsurf.ctypes.data_as(ctypes.c_void_p),
                self.rsurf.ctypes.data_as(ctypes.c_void_p))
        logger.info(self,
                    'Time finding surface %.3f (sec)' % (time.time() - t))

        self.rmin = 1000.0
        self.rmax = 0.0
        for i in range(self.npang):
            nsurf = int(self.nlimsurf[i])
            self.rmin = numpy.minimum(self.rmin, self.rsurf[i, 0])
            self.rmax = numpy.maximum(self.rmax, self.rsurf[i, nsurf - 1])
        logger.info(self, 'Rmin for surface %.6f', self.rmin)
        logger.info(self, 'Rmax for surface %.6f', self.rmax)

        logger.info(self, 'Write HDF5 surface file')
        atom_dic = {
            'inuc': self.inuc,
            'xnuc': self.xnuc,
            'xyzrho': self.xyzrho,
            'coords': self.grids,
            'npang': self.npang,
            'ntrial': self.ntrial,
            'rmin': self.rmin,
            'rmax': self.rmax,
            'nlimsurf': self.nlimsurf,
            'rsurf': self.rsurf
        }
        lib.chkfile.save(self.surfile, 'atom' + str(self.inuc), atom_dic)
        logger.info(self, 'Surface of atom %d saved', self.inuc)
        logger.timer(self, 'BaderSurf build', *t0)

        return self
Ejemplo n.º 7
0
    def build(self):

        t0 = (time.clock(), time.time())
        lib.logger.TIMER_LEVEL = 3

        self.mol = lib.chkfile.load_mol(self.chkfile)
        self.nelectron = self.mol.nelectron 
        self.charge = self.mol.charge    
        self.spin = self.mol.spin      
        self.natm = self.mol.natm		
        self.coords = numpy.asarray([(numpy.asarray(atom[1])).tolist() for atom in self.mol._atom])
        self.charges = self.mol.atom_charges()
        self.mo_coeff = lib.chkfile.load(self.chkfile, 'scf/mo_coeff')
        self.mo_occ = lib.chkfile.load(self.chkfile, 'scf/mo_occ')
        nprims, nmo = self.mo_coeff.shape 
        self.nprims = nprims
        self.nmo = nmo
        if self.charges[self.inuc] == 1:
            self.rad = grid.BRAGG[self.charges[self.inuc]]
        else:
            self.rad = grid.BRAGG[self.charges[self.inuc]]*0.5

        self.n2c = nprims/2
        nocc = self.mo_occ[abs(self.mo_occ)>self.occdrop]
        self.nocc = len(nocc)
        pos = abs(self.mo_occ) > self.occdrop
        n2c = self.n2c
        self.mo_coeffL = self.mo_coeff[:n2c,pos]
        c1 = 0.5/self.cspeed
        self.mo_coeffS = self.mo_coeff[n2c:,n2c:n2c+self.nocc] * c1

        idx = 'atom'+str(self.inuc)
        with h5py.File(self.surfile) as f:
            self.xnuc = f[idx+'/xnuc'].value
            self.xyzrho = f[idx+'/xyzrho'].value
            self.npang = f[idx+'/npang'].value
            self.ntrial = f[idx+'/ntrial'].value
            self.rmin = f[idx+'/rmin'].value
            self.rmax = f[idx+'/rmax'].value
            self.rsurf = f[idx+'/rsurf'].value
            self.nlimsurf = f[idx+'/nlimsurf'].value
            self.agrids = f[idx+'/coords'].value

        self.brad = self.rmin*self.betafac

        if self.verbose >= logger.WARN:
            self.check_sanity()
        if self.verbose > logger.NOTE:
            self.dump_input()

        if (self.iqudr == 'legendre'):
            self.iqudr = 1
        if (self.biqudr == 'legendre'):
            self.biqudr = 1

        if (self.mapr == 'becke'):
            self.mapr = 1
        elif (self.mapr == 'exp'):
            self.mapr = 2
        elif (self.mapr == 'none'):
            self.mapr = 0 
        if (self.bmapr == 'becke'):
            self.bmapr = 1
        elif (self.bmapr == 'exp'):
            self.bmapr = 2
        elif (self.bmapr == 'none'):
            self.bmapr = 0

        with lib.with_omp_threads(self.nthreads):
            brprops = int_beta(self)
            rprops = out_beta(self)

        logger.info(self,'Write info to HDF5 file')
        atom_dic = {'inprops':brprops,
                    'outprops':rprops,
                    'totprops':(brprops+rprops)}
        lib.chkfile.save(self.surfile, 'atom_props'+str(self.inuc), atom_dic)
        for i in range(NPROPS):
            logger.info(self,'*-> Total %s density %8.5f ', PROPS[i], (rprops[i]+brprops[i]))    
        logger.info(self,'')
        logger.info(self,'Basim properties of atom %d done',self.inuc)
        logger.timer(self,'Basin build', *t0)

        return self
Ejemplo n.º 8
0
def kernel(myci, h1e, eri, norb, nelec, ci0=None,
           tol=None, lindep=None, max_cycle=None, max_space=None,
           nroots=None, davidson_only=None, 
           max_memory=None, verbose=None, ecore=0, **kwargs):

    if tol is None: tol = myci.conv_tol
    if lindep is None: lindep = myci.lindep
    if max_cycle is None: max_cycle = myci.max_cycle
    if max_space is None: max_space = myci.max_space
    if max_memory is None: max_memory = myci.max_memory
    if nroots is None: nroots = myci.nroots
    if verbose is None: verbose = logger.Logger(myci.stdout, myci.verbose)
    tol_residual = None #getattr(fci, 'conv_tol_residual', None)
    myci.dump_flags()

    nelec = direct_spin1._unpack_nelec(nelec, myci.spin)
    eri = ao2mo.restore(1, eri, norb)
    eri = eri.ravel()

    logger.info(myci, 'CI in the selected space')
    # Initial guess
    if ci0 is None:
        t_start = time.time()
        if (myci.model == 'fci'):
            dets = cistring.gen_full_space(range(norb), nelec) 
            ndets = dets.shape[0]
            if (myci.noise):
                numpy.random.seed()
                ci0 = [cistring.as_SCIvector(numpy.random.uniform(low=1e-3,high=1e-2,size=ndets), dets)]
                ci0[0][0] = 0.99
                ci0[0] *= 1./numpy.linalg.norm(ci0[0])
            else:
                ci0 = [cistring.as_SCIvector(numpy.zeros(ndets), dets)]
                ci0[0][0] = 1.0
        else:
            raise RuntimeError('''Unknown CI model''')
        t_current = time.time() - t_start
        #logger.info(myci, 'Initial CI vector = %s', ci0[0][:])
        logger.info(myci, 'Timing for generating strings: %10.3f', t_current)
    else:
        assert(nroots == len(ci0))

    def hop(c):
        hc = myci.contract_2e((h1e, eri), cistring.as_SCIvector(c, ci_strs), norb, nelec, hdiag)
        return hc.ravel()
    precond = lambda x, e, *args: x/(hdiag-e+myci.level_shift)

    ci_strs = ci0[0]._strs
    logger.info(myci, 'Number of CI configurations: %d', ci_strs.shape[0])
    t_start = time.time()
    hdiag = myci.make_hdiag(h1e, eri, ci_strs, norb, nelec)
    t_current = time.time() - t_start
    logger.info(myci, 'Timing for diagonal hamiltonian: %10.3f', t_current)

    t_start = time.time()
    with lib.with_omp_threads(myci.threads):
        #e, c = myci.eig(hop, ci0, precond, tol=tol, lindep=lindep,
        #                max_cycle=max_cycle, max_space=max_space, nroots=nroots,
        #                max_memory=max_memory, verbose=verbose, **kwargs)
        #
        e, c = myci.eig(hop, ci0, precond, tol=tol, lindep=lindep,
                       max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                       max_memory=max_memory, verbose=verbose, follow_state=True,
                       tol_residual=tol_residual, **kwargs)
    t_current = time.time() - t_start
    logger.info(myci, 'Timing for solving the eigenvalue problem: %10.3f', t_current)
    if not isinstance(c, (tuple, list)):
        c = [c]
        e = [e]
    logger.info(myci, 'CI  E = %s', numpy.array(e)+ecore)
    #myci.eci = e+ecore
    #myci.ci = e
    #for i in range(nroots):
    #    norm = numpy.einsum('i,i->', ci0[i][:], ci0[i][:])
    #    s = myci.spin_square(ci0[i], norb, nelec)
    #    logger.info(myci, 'E(CI) = %10.5f, CI E = %10.5f, Norm = %1.3f, Spin = %s'\
    #    % (numpy.array(e[i]), numpy.array(e[i])+ecore, norm, s))
    #    #logger.info(myci, 'CI E = %s', numpy.array(e)+ecore)
    #    #logger.info(mc,"* Norm info for state %d : %s" % (i,norm))    
    #    #logger.info(mc,"* Spin info for state %d : %s" % (i,s))    

    return (numpy.array(e)+ecore), [cistring.as_SCIvector(ci, ci_strs) for ci in c]
Ejemplo n.º 9
0
def kernel_ms1(fci,
               h1e,
               eri,
               norb,
               nelec,
               ci0=None,
               link_index=None,
               tol=None,
               lindep=None,
               max_cycle=None,
               max_space=None,
               nroots=None,
               davidson_only=None,
               pspace_size=None,
               max_memory=None,
               verbose=None,
               ecore=0,
               **kwargs):
    if nroots is None: nroots = fci.nroots
    if davidson_only is None: davidson_only = fci.davidson_only
    if pspace_size is None: pspace_size = fci.pspace_size
    if max_memory is None:
        max_memory = fci.max_memory - lib.current_memory()[0]
    log = logger.new_logger(fci, verbose)

    nelec = _unpack_nelec(nelec, fci.spin)
    assert (0 <= nelec[0] <= norb and 0 <= nelec[1] <= norb)
    link_indexa, link_indexb = _unpack(norb, nelec, link_index)
    na = link_indexa.shape[0]
    nb = link_indexb.shape[0]

    if max_memory < na * nb * 6 * 8e-6:
        log.warn(
            'Not enough memory for FCI solver. '
            'The minimal requirement is %.0f MB', na * nb * 60e-6)

    hdiag = fci.make_hdiag(h1e, eri, norb, nelec)
    nroots = min(hdiag.size, nroots)

    try:
        addr, h0 = fci.pspace(h1e, eri, norb, nelec, hdiag,
                              max(pspace_size, nroots))
        if pspace_size > 0:
            pw, pv = fci.eig(h0)
        else:
            pw = pv = None

        if pspace_size >= na * nb and ci0 is None and not davidson_only:
            # The degenerated wfn can break symmetry.  The davidson iteration with proper
            # initial guess doesn't have this issue
            if na * nb == 1:
                return pw[0] + ecore, pv[:, 0].reshape(1, 1)
            elif nroots > 1:
                civec = numpy.empty((nroots, na * nb))
                civec[:, addr] = pv[:, :nroots].T
                return pw[:nroots] + ecore, [c.reshape(na, nb) for c in civec]
            elif abs(pw[0] - pw[1]) > 1e-12:
                civec = numpy.empty((na * nb))
                civec[addr] = pv[:, 0]
                return pw[0] + ecore, civec.reshape(na, nb)
    except NotImplementedError:
        addr = [0]
        pw = pv = None

    precond = fci.make_precond(hdiag, pw, pv, addr)

    h2e = fci.absorb_h1e(h1e, eri, norb, nelec, .5)

    def hop(c):
        hc = fci.contract_2e(h2e, c, norb, nelec, (link_indexa, link_indexb))
        return hc.ravel()

    if ci0 is None:
        if callable(getattr(fci, 'get_init_guess', None)):
            ci0 = lambda: fci.get_init_guess(norb, nelec, nroots, hdiag)
        else:

            def ci0():  # lazy initialization to reduce memory footprint
                x0 = []
                for i in range(nroots):
                    x = numpy.zeros(na * nb)
                    x[addr[i]] = 1
                    x0.append(x)
                return x0
    elif not callable(ci0):
        if isinstance(ci0, numpy.ndarray) and ci0.size == na * nb:
            ci0 = [ci0.ravel()]
        else:
            ci0 = [x.ravel() for x in ci0]
        # Add vectors if not enough initial guess is given
        if len(ci0) < nroots:
            if callable(getattr(fci, 'get_init_guess', None)):
                ci0.extend(
                    fci.get_init_guess(norb, nelec, nroots, hdiag)[len(ci0):])
            else:
                for i in range(len(ci0), nroots):
                    x = numpy.zeros(na * nb)
                    x[addr[i]] = 1
                    ci0.append(x)

    if tol is None: tol = fci.conv_tol
    if lindep is None: lindep = fci.lindep
    if max_cycle is None: max_cycle = fci.max_cycle
    if max_space is None: max_space = fci.max_space
    tol_residual = getattr(fci, 'conv_tol_residual', None)

    with lib.with_omp_threads(fci.threads):
        #e, c = lib.davidson(hop, ci0, precond, tol=fci.conv_tol, lindep=fci.lindep)
        e, c = fci.eig(hop,
                       ci0,
                       precond,
                       tol=tol,
                       lindep=lindep,
                       max_cycle=max_cycle,
                       max_space=max_space,
                       nroots=nroots,
                       max_memory=max_memory,
                       verbose=log,
                       follow_state=True,
                       tol_residual=tol_residual,
                       **kwargs)
    if nroots > 1:
        return e + ecore, [ci.reshape(na, nb) for ci in c]
    else:
        return e + ecore, c.reshape(na, nb)
Ejemplo n.º 10
0
    def build(self):

        t0 = (time.clock(), time.time())
        lib.logger.TIMER_LEVEL = 3

        self.cell = libpbc.chkfile.load_cell(self.chkfile)
        self.a = self.cell.lattice_vectors()
        self.b = self.cell.reciprocal_vectors()
        self.vol = self.cell.vol
        self.nelectron = self.cell.nelectron
        self.charge = self.cell.charge
        self.spin = self.cell.spin
        self.natm = self.cell.natm
        self.ls = self.cell.get_lattice_Ls(dimension=self.cell.dimension)
        self.ls = self.ls[numpy.argsort(lib.norm(self.ls, axis=1))]
        self.kpts = lib.chkfile.load(self.chkfile, 'kcell/kpts')
        self.nkpts = len(self.kpts)
        self.coords = numpy.asarray([(numpy.asarray(atom[1])).tolist()
                                     for atom in self.cell._atom])
        self.charges = self.cell.atom_charges()
        self.mo_coeff = lib.chkfile.load(self.chkfile, 'scf/mo_coeff')
        self.mo_occ = lib.chkfile.load(self.chkfile, 'scf/mo_occ')
        nprims, nmo = self.mo_coeff[0].shape
        self.nprims = nprims
        self.nmo = nmo
        if self.charges[self.inuc] == 1:
            self.rad = grid.BRAGG[self.charges[self.inuc]]
        else:
            self.rad = grid.BRAGG[self.charges[self.inuc]] * 0.5

        idx = 'atom' + str(self.inuc)
        with h5py.File(self.surfile) as f:
            self.xnuc = f[idx + '/xnuc'].value
            self.xyzrho = f[idx + '/xyzrho'].value
            self.npang = f[idx + '/npang'].value
            self.ntrial = f[idx + '/ntrial'].value
            self.rmin = f[idx + '/rmin'].value
            self.rmax = f[idx + '/rmax'].value
            self.rsurf = f[idx + '/rsurf'].value
            self.nlimsurf = f[idx + '/nlimsurf'].value
            self.agrids = f[idx + '/coords'].value

        self.brad = self.rmin * self.betafac

        if self.verbose >= logger.WARN:
            self.check_sanity()
        if self.verbose > logger.NOTE:
            self.dump_input()

        if (self.iqudr == 'legendre'):
            self.iqudr = 1
        if (self.biqudr == 'legendre'):
            self.biqudr = 1

        if (self.mapr == 'becke'):
            self.mapr = 1
        elif (self.mapr == 'exp'):
            self.mapr = 2
        elif (self.mapr == 'none'):
            self.mapr = 0
        if (self.bmapr == 'becke'):
            self.bmapr = 1
        elif (self.bmapr == 'exp'):
            self.bmapr = 2
        elif (self.bmapr == 'none'):
            self.bmapr = 0

        with lib.with_omp_threads(self.nthreads):
            brprops = int_beta(self)
            rprops = out_beta(self)

        logger.info(self, 'Write info to HDF5 file')
        atom_dic = {
            'inprops': brprops,
            'outprops': rprops,
            'totprops': (brprops + rprops)
        }
        lib.chkfile.save(self.surfile, 'atom_props' + str(self.inuc), atom_dic)
        for i in range(NPROPS):
            logger.info(self, '*-> Total %s %8.5f ', PROPS[i],
                        (rprops[i] + brprops[i]))
        logger.info(self, 'Basim properties of atom %d done', self.inuc)
        logger.timer(self, 'Basin build', *t0)

        return self
Ejemplo n.º 11
0
    def build(self):

        t0 = (time.clock(), time.time())
        lib.logger.TIMER_LEVEL = 3

        self.cell = libpbc.chkfile.load_cell(self.chkfile)
        self.a = self.cell.lattice_vectors()
        self.b = self.cell.reciprocal_vectors()
        self.vol = self.cell.vol
        self.nelectron = self.cell.nelectron
        self.charge = self.cell.charge
        self.spin = self.cell.spin
        self.natm = self.cell.natm
        self.ls = self.cell.get_lattice_Ls(dimension=self.cell.dimension)
        self.ls = self.ls[numpy.argsort(lib.norm(self.ls, axis=1))]
        self.kpts = lib.chkfile.load(self.chkfile, 'kcell/kpts')
        self.nkpts = len(self.kpts)
        self.coords = numpy.asarray([(numpy.asarray(atom[1])).tolist()
                                     for atom in self.cell._atom])
        self.charges = self.cell.atom_charges()
        if self.charges[self.inuc] == 1:
            self.rad = grid.BRAGG[self.charges[self.inuc]]
        else:
            self.rad = grid.BRAGG[self.charges[self.inuc]] * 0.5

        idx = 'atom' + str(self.inuc)
        with h5py.File(self.surfile) as f:
            self.xnuc = f[idx + '/xnuc'].value
            self.xyzrho = f[idx + '/xyzrho'].value
            self.npang = f[idx + '/npang'].value
            self.ntrial = f[idx + '/ntrial'].value
            self.rmin = f[idx + '/rmin'].value
            self.rmax = f[idx + '/rmax'].value
            self.rsurf = f[idx + '/rsurf'].value
            self.nlimsurf = f[idx + '/nlimsurf'].value
            self.agrids = f[idx + '/coords'].value

        self.brad = self.rmin * self.betafac

        # TODO: general orbitals
        mo_coeff = lib.chkfile.load(self.chkfile, 'scf/mo_coeff')
        nprims, nmo = mo_coeff[0].shape
        if (self.orbs == -1):
            self.orbs = nmo
        self.nprims = nprims
        self.nmo = self.orbs * self.nkpts
        self.mo_coeff = numpy.zeros((self.nprims, self.nmo),
                                    dtype=numpy.complex128)
        self.tags = numpy.zeros(self.nmo, dtype=numpy.int32)
        ii = 0
        for k in range(self.nkpts):
            for i in range(self.orbs):
                self.mo_coeff[:, ii] = mo_coeff[k][:, i]
                self.tags[ii] = k
                ii += 1

        if self.verbose >= logger.WARN:
            self.check_sanity()
        if self.verbose > logger.NOTE:
            self.dump_input()

        if (self.iqudr == 'legendre'):
            self.iqudr = 1
        if (self.biqudr == 'legendre'):
            self.biqudr = 1

        if (self.mapr == 'becke'):
            self.mapr = 1
        elif (self.mapr == 'exp'):
            self.mapr = 2
        elif (self.mapr == 'none'):
            self.mapr = 0
        if (self.bmapr == 'becke'):
            self.bmapr = 1
        elif (self.bmapr == 'exp'):
            self.bmapr = 2
        elif (self.bmapr == 'none'):
            self.bmapr = 0

        self.aom = numpy.zeros((self.nmo, self.nmo), dtype=numpy.complex128)
        with lib.with_omp_threads(self.nthreads):
            aomb = int_beta(self)
            aoma = out_beta(self)

        idx = 0
        for i in range(self.nmo):
            for j in range(i + 1):
                self.aom[i, j] = aoma[idx] + aomb[idx]
                self.aom[j, i] = self.aom[i, j].conj()
                idx += 1
        norm = float(1.0 / self.nkpts)
        self.aom = self.aom * norm
        if (self.nmo <= 30):
            dump_tri(self.stdout, self.aom, ncol=NCOL, digits=DIGITS, start=0)

        logger.info(self, 'Write info to HDF5 file')
        atom_dic = {'aom': self.aom}
        lib.chkfile.save(self.surfile, 'ovlp' + str(self.inuc), atom_dic)
        logger.info(self, '')

        logger.info(self, 'AOM of atom %d done', self.inuc)
        logger.timer(self, 'AOM build', *t0)

        return self
Ejemplo n.º 12
0
from dftpart.eda import scfeda
from pyscf import lib

with lib.with_omp_threads(4):
    test1 = scfeda.EDA()
    test1.gjf = 'c8b_nofrg.gjf'
    test1.method = ['pbe0', '6-31gss']
    test1.output = 'c8b_nofrg'
    test1.verbose = 9
    #test1.build()
    #test1.showinter=True
    #test1.lso = 'c8b/c8b.lso'
    test1.kernel()
Ejemplo n.º 13
0
from dftpart import gfea3
from pyscf import lib

par = 8
with lib.with_omp_threads(par):
    fr0 = gfea3.GFEA()
    fr0.inputstyle = 'frg'
    fr0.method = ['hf', '6-31gs', 'cart', 'charge']
    fr0.gjfname = 'w19'
    fr0.output = 'w19'
    fr0.verbose = 9
    fr0.showinter = True
    #fr0.do_deriv = True
    fr0.kernel()
Ejemplo n.º 14
0
def kernel_ms1(fci,
               h1e,
               eri,
               norb,
               nelec,
               ci0=None,
               link_index=None,
               tol=None,
               lindep=None,
               max_cycle=None,
               max_space=None,
               nroots=None,
               davidson_only=None,
               pspace_size=None,
               max_memory=None,
               verbose=None,
               ecore=0,
               **kwargs):
    '''
    Args:
        h1e: ndarray
            1-electron Hamiltonian
        eri: ndarray
            2-electron integrals in chemist's notation
        norb: int
            Number of orbitals
        nelec: int or (int, int)
            Number of electrons of the system

    Kwargs:
        ci0: ndarray
            Initial guess
        link_index: ndarray
            A lookup table to cache the addresses of CI determinants in
            wave-function vector
        tol: float
            Convergence tolerance
        lindep: float
            Linear dependence threshold
        max_cycle: int
            Max. iterations for diagonalization
        max_space: int
            Max. trial vectors to store for sub-space diagonalization method
        nroots: int
            Number of states to solve
        davidson_only: bool
            Whether to call subspace diagonlization (davidson solver) or do a
            full diagonlization (lapack eigh) for small systems
        pspace_size: int
            Number of determinants as the threshold of "small systems",

    Note: davidson solver requires more arguments. For the parameters not
    dispatched, they can be passed to davidson solver via the extra keyword
    arguments **kwargs
    '''
    if nroots is None: nroots = fci.nroots
    if davidson_only is None: davidson_only = fci.davidson_only
    if pspace_size is None: pspace_size = fci.pspace_size
    if max_memory is None:
        max_memory = fci.max_memory - lib.current_memory()[0]
    log = logger.new_logger(fci, verbose)

    nelec = _unpack_nelec(nelec, fci.spin)
    assert (0 <= nelec[0] <= norb and 0 <= nelec[1] <= norb)
    link_indexa, link_indexb = _unpack(norb, nelec, link_index)
    na = link_indexa.shape[0]
    nb = link_indexb.shape[0]

    if max_memory < na * nb * 6 * 8e-6:
        log.warn(
            'Not enough memory for FCI solver. '
            'The minimal requirement is %.0f MB', na * nb * 60e-6)

    hdiag = fci.make_hdiag(h1e, eri, norb, nelec)
    nroots = min(hdiag.size, nroots)

    try:
        addr, h0 = fci.pspace(h1e, eri, norb, nelec, hdiag,
                              max(pspace_size, nroots))
        if pspace_size > 0:
            pw, pv = fci.eig(h0)
        else:
            pw = pv = None

        if pspace_size >= na * nb and ci0 is None and not davidson_only:
            # The degenerated wfn can break symmetry.  The davidson iteration with proper
            # initial guess doesn't have this issue
            if na * nb == 1:
                return pw[0] + ecore, pv[:, 0].reshape(1, 1)
            elif nroots > 1:
                civec = numpy.empty((nroots, na * nb))
                civec[:, addr] = pv[:, :nroots].T
                return pw[:nroots] + ecore, [c.reshape(na, nb) for c in civec]
            elif abs(pw[0] - pw[1]) > 1e-12:
                civec = numpy.empty((na * nb))
                civec[addr] = pv[:, 0]
                return pw[0] + ecore, civec.reshape(na, nb)
    except NotImplementedError:
        addr = [0]
        pw = pv = None

    precond = fci.make_precond(hdiag, pw, pv, addr)

    h2e = fci.absorb_h1e(h1e, eri, norb, nelec, .5)

    def hop(c):
        hc = fci.contract_2e(h2e, c, norb, nelec, (link_indexa, link_indexb))
        return hc.ravel()

    if ci0 is None:
        if callable(getattr(fci, 'get_init_guess', None)):
            ci0 = lambda: fci.get_init_guess(norb, nelec, nroots, hdiag)
        else:

            def ci0():  # lazy initialization to reduce memory footprint
                x0 = []
                for i in range(nroots):
                    x = numpy.zeros(na * nb)
                    x[addr[i]] = 1
                    x0.append(x)
                return x0
    elif not callable(ci0):
        if isinstance(ci0, numpy.ndarray) and ci0.size == na * nb:
            ci0 = [ci0.ravel()]
        else:
            ci0 = [x.ravel() for x in ci0]
        # Add vectors if not enough initial guess is given
        if len(ci0) < nroots:
            if callable(getattr(fci, 'get_init_guess', None)):
                ci0.extend(
                    fci.get_init_guess(norb, nelec, nroots, hdiag)[len(ci0):])
            else:
                for i in range(len(ci0), nroots):
                    x = numpy.zeros(na * nb)
                    x[addr[i]] = 1
                    ci0.append(x)

    if tol is None: tol = fci.conv_tol
    if lindep is None: lindep = fci.lindep
    if max_cycle is None: max_cycle = fci.max_cycle
    if max_space is None: max_space = fci.max_space
    tol_residual = getattr(fci, 'conv_tol_residual', None)

    with lib.with_omp_threads(fci.threads):
        #e, c = lib.davidson(hop, ci0, precond, tol=fci.conv_tol, lindep=fci.lindep)
        e, c = fci.eig(hop,
                       ci0,
                       precond,
                       tol=tol,
                       lindep=lindep,
                       max_cycle=max_cycle,
                       max_space=max_space,
                       nroots=nroots,
                       max_memory=max_memory,
                       verbose=log,
                       follow_state=True,
                       tol_residual=tol_residual,
                       **kwargs)
    if nroots > 1:
        return e + ecore, [ci.reshape(na, nb) for ci in c]
    else:
        return e + ecore, c.reshape(na, nb)
Ejemplo n.º 15
0
def kernel_ms1(fci,
               h1e,
               eri,
               norb,
               nelec,
               ci0=None,
               link_index=None,
               tol=None,
               lindep=None,
               max_cycle=None,
               max_space=None,
               nroots=None,
               davidson_only=None,
               pspace_size=None,
               max_memory=None,
               verbose=None,
               ecore=0,
               **kwargs):
    if nroots is None: nroots = fci.nroots
    if davidson_only is None: davidson_only = fci.davidson_only
    if pspace_size is None: pspace_size = fci.pspace_size

    nelec = _unpack_nelec(nelec, fci.spin)
    link_indexa, link_indexb = _unpack(norb, nelec, link_index)
    na = link_indexa.shape[0]
    nb = link_indexb.shape[0]
    hdiag = fci.make_hdiag(h1e, eri, norb, nelec)

    try:
        addr, h0 = fci.pspace(h1e, eri, norb, nelec, hdiag,
                              max(pspace_size, nroots))
        if pspace_size > 0:
            pw, pv = fci.eig(h0)
        else:
            pw = pv = None

        if pspace_size >= na * nb and ci0 is None and not davidson_only:
            # The degenerated wfn can break symmetry.  The davidson iteration with proper
            # initial guess doesn't have this issue
            if na * nb == 1:
                return pw[0] + ecore, pv[:, 0].reshape(1, 1)
            elif nroots > 1:
                civec = numpy.empty((nroots, na * nb))
                civec[:, addr] = pv[:, :nroots].T
                return pw[:nroots] + ecore, [c.reshape(na, nb) for c in civec]
            elif abs(pw[0] - pw[1]) > 1e-12:
                civec = numpy.empty((na * nb))
                civec[addr] = pv[:, 0]
                return pw[0] + ecore, civec.reshape(na, nb)
    except NotImplementedError:
        addr = [0]
        pw = pv = None

    precond = fci.make_precond(hdiag, pw, pv, addr)

    h2e = fci.absorb_h1e(h1e, eri, norb, nelec, .5)

    def hop(c):
        hc = fci.contract_2e(h2e, c, norb, nelec, (link_indexa, link_indexb))
        return hc.ravel()

    if ci0 is None:
        if hasattr(fci, 'get_init_guess'):
            ci0 = fci.get_init_guess(norb, nelec, nroots, hdiag)
        else:
            ci0 = []
            for i in range(nroots):
                x = numpy.zeros(na * nb)
                x[addr[i]] = 1
                ci0.append(x)
    else:
        if isinstance(ci0, numpy.ndarray) and ci0.size == na * nb:
            ci0 = [ci0.ravel()]
        else:
            ci0 = [x.ravel() for x in ci0]

    if tol is None: tol = fci.conv_tol
    if lindep is None: lindep = fci.lindep
    if max_cycle is None: max_cycle = fci.max_cycle
    if max_space is None: max_space = fci.max_space
    if max_memory is None: max_memory = fci.max_memory
    if verbose is None: verbose = logger.Logger(fci.stdout, fci.verbose)

    with lib.with_omp_threads(fci.threads):
        #e, c = lib.davidson(hop, ci0, precond, tol=fci.conv_tol, lindep=fci.lindep)
        e, c = fci.eig(hop,
                       ci0,
                       precond,
                       tol=tol,
                       lindep=lindep,
                       max_cycle=max_cycle,
                       max_space=max_space,
                       nroots=nroots,
                       max_memory=max_memory,
                       verbose=verbose,
                       follow_state=True,
                       **kwargs)
    if nroots > 1:
        return e + ecore, [ci.reshape(na, nb) for ci in c]
    else:
        return e + ecore, c.reshape(na, nb)
Ejemplo n.º 16
0
def kernel_ms1(fci, h1e, eri, norb, nelec, ci0=None, link_index=None,
               tol=None, lindep=None, max_cycle=None, max_space=None,
               nroots=None, davidson_only=None, pspace_size=None,
               max_memory=None, verbose=None, ecore=0, **kwargs):
    if nroots is None: nroots = fci.nroots
    if davidson_only is None: davidson_only = fci.davidson_only
    if pspace_size is None: pspace_size = fci.pspace_size

    nelec = _unpack_nelec(nelec, fci.spin)
    assert(0 <= nelec[0] <= norb and 0 <= nelec[1] <= norb)
    link_indexa, link_indexb = _unpack(norb, nelec, link_index)
    na = link_indexa.shape[0]
    nb = link_indexb.shape[0]
    hdiag = fci.make_hdiag(h1e, eri, norb, nelec)
    nroots = min(hdiag.size, nroots)

    try:
        addr, h0 = fci.pspace(h1e, eri, norb, nelec, hdiag, max(pspace_size,nroots))
        if pspace_size > 0:
            pw, pv = fci.eig(h0)
        else:
            pw = pv = None

        if pspace_size >= na*nb and ci0 is None and not davidson_only:
# The degenerated wfn can break symmetry.  The davidson iteration with proper
# initial guess doesn't have this issue
            if na*nb == 1:
                return pw[0]+ecore, pv[:,0].reshape(1,1)
            elif nroots > 1:
                civec = numpy.empty((nroots,na*nb))
                civec[:,addr] = pv[:,:nroots].T
                return pw[:nroots]+ecore, [c.reshape(na,nb) for c in civec]
            elif abs(pw[0]-pw[1]) > 1e-12:
                civec = numpy.empty((na*nb))
                civec[addr] = pv[:,0]
                return pw[0]+ecore, civec.reshape(na,nb)
    except NotImplementedError:
        addr = [0]
        pw = pv = None

    precond = fci.make_precond(hdiag, pw, pv, addr)

    h2e = fci.absorb_h1e(h1e, eri, norb, nelec, .5)
    def hop(c):
        hc = fci.contract_2e(h2e, c, norb, nelec, (link_indexa,link_indexb))
        return hc.ravel()

    if ci0 is None:
        if callable(getattr(fci, 'get_init_guess', None)):
            ci0 = lambda: fci.get_init_guess(norb, nelec, nroots, hdiag)
        else:
            def ci0():  # lazy initialization to reduce memory footprint
                x0 = []
                for i in range(nroots):
                    x = numpy.zeros(na*nb)
                    x[addr[i]] = 1
                    x0.append(x)
                return x0
    elif not callable(ci0):
        if isinstance(ci0, numpy.ndarray) and ci0.size == na*nb:
            ci0 = [ci0.ravel()]
        else:
            ci0 = [x.ravel() for x in ci0]

    if tol is None: tol = fci.conv_tol
    if lindep is None: lindep = fci.lindep
    if max_cycle is None: max_cycle = fci.max_cycle
    if max_space is None: max_space = fci.max_space
    if max_memory is None: max_memory = fci.max_memory
    if verbose is None: verbose = logger.Logger(fci.stdout, fci.verbose)
    tol_residual = getattr(fci, 'conv_tol_residual', None)

    with lib.with_omp_threads(fci.threads):
        #e, c = lib.davidson(hop, ci0, precond, tol=fci.conv_tol, lindep=fci.lindep)
        e, c = fci.eig(hop, ci0, precond, tol=tol, lindep=lindep,
                       max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                       max_memory=max_memory, verbose=verbose, follow_state=True,
                       tol_residual=tol_residual, **kwargs)
    if nroots > 1:
        return e+ecore, [ci.reshape(na,nb) for ci in c]
    else:
        return e+ecore, c.reshape(na,nb)
Ejemplo n.º 17
0
def kernel_ms0(fci,
               h1e,
               eri,
               norb,
               nelec,
               ci0=None,
               link_index=None,
               tol=None,
               lindep=None,
               max_cycle=None,
               max_space=None,
               nroots=None,
               davidson_only=None,
               pspace_size=None,
               max_memory=None,
               verbose=None,
               ecore=0,
               **kwargs):
    if nroots is None: nroots = fci.nroots
    if davidson_only is None: davidson_only = fci.davidson_only
    if pspace_size is None: pspace_size = fci.pspace_size
    if max_memory is None:
        max_memory = fci.max_memory - lib.current_memory()[0]
    log = logger.new_logger(fci, verbose)

    assert (fci.spin is None or fci.spin == 0)
    assert (0 <= numpy.sum(nelec) <= norb * 2)

    link_index = _unpack(norb, nelec, link_index)
    h1e = numpy.ascontiguousarray(h1e)
    eri = numpy.ascontiguousarray(eri)
    na = link_index.shape[0]

    if max_memory < na**2 * 6 * 8e-6:
        log.warn(
            'Not enough memory for FCI solver. '
            'The minimal requirement is %.0f MB', na**2 * 60e-6)

    hdiag = fci.make_hdiag(h1e, eri, norb, nelec)
    nroots = min(hdiag.size, nroots)

    try:
        addr, h0 = fci.pspace(h1e, eri, norb, nelec, hdiag,
                              max(pspace_size, nroots))
        if pspace_size > 0:
            pw, pv = fci.eig(h0)
        else:
            pw = pv = None

        if pspace_size >= na * na and ci0 is None and not davidson_only:
            # The degenerated wfn can break symmetry.  The davidson iteration with proper
            # initial guess doesn't have this issue
            if na * na == 1:
                return pw[0] + ecore, pv[:, 0].reshape(1, 1)
            elif nroots > 1:
                civec = numpy.empty((nroots, na * na))
                civec[:, addr] = pv[:, :nroots].T
                civec = civec.reshape(nroots, na, na)
                try:
                    return pw[:nroots] + ecore, [_check_(ci) for ci in civec]
                except ValueError:
                    pass
            elif abs(pw[0] - pw[1]) > 1e-12:
                civec = numpy.empty((na * na))
                civec[addr] = pv[:, 0]
                civec = civec.reshape(na, na)
                civec = lib.transpose_sum(civec) * .5
                # direct diagonalization may lead to triplet ground state
                ##TODO: optimize initial guess.  Using pspace vector as initial guess may have
                ## spin problems.  The 'ground state' of psapce vector may have different spin
                ## state to the true ground state.
                try:
                    return pw[0] + ecore, _check_(civec.reshape(na, na))
                except ValueError:
                    pass
    except NotImplementedError:
        addr = [0]
        pw = pv = None

    precond = fci.make_precond(hdiag, pw, pv, addr)

    h2e = fci.absorb_h1e(h1e, eri, norb, nelec, .5)

    def hop(c):
        hc = fci.contract_2e(h2e, c.reshape(na, na), norb, nelec, link_index)
        return hc.ravel()


#TODO: check spin of initial guess

    if ci0 is None:
        if callable(getattr(fci, 'get_init_guess', None)):
            ci0 = lambda: fci.get_init_guess(norb, nelec, nroots, hdiag)
        else:

            def ci0():
                x0 = []
                for i in range(nroots):
                    x = numpy.zeros((na, na))
                    addra = addr[i] // na
                    addrb = addr[i] % na
                    if addra == addrb:
                        x[addra, addrb] = 1
                    else:
                        x[addra, addrb] = x[addrb, addra] = numpy.sqrt(.5)
                    x0.append(x.ravel())
                return x0
    elif not callable(ci0):
        if isinstance(ci0, numpy.ndarray) and ci0.size == na * na:
            ci0 = [ci0.ravel()]
        else:
            ci0 = [x.ravel() for x in ci0]

    if tol is None: tol = fci.conv_tol
    if lindep is None: lindep = fci.lindep
    if max_cycle is None: max_cycle = fci.max_cycle
    if max_space is None: max_space = fci.max_space
    tol_residual = getattr(fci, 'conv_tol_residual', None)

    with lib.with_omp_threads(fci.threads):
        #e, c = lib.davidson(hop, ci0, precond, tol=fci.conv_tol, lindep=fci.lindep)
        e, c = fci.eig(hop,
                       ci0,
                       precond,
                       tol=tol,
                       lindep=lindep,
                       max_cycle=max_cycle,
                       max_space=max_space,
                       nroots=nroots,
                       max_memory=max_memory,
                       verbose=log,
                       follow_state=True,
                       tol_residual=tol_residual,
                       **kwargs)
    if nroots > 1:
        return e + ecore, [_check_(ci.reshape(na, na)) for ci in c]
    else:
        return e + ecore, _check_(c.reshape(na, na))
Ejemplo n.º 18
0
    def build(self):

        t0 = (time.clock(), time.time())
        lib.logger.TIMER_LEVEL = 3

        self.mol = lib.chkfile.load_mol(self.chkfile)
        self.nelectron = self.mol.nelectron
        self.charge = self.mol.charge
        self.spin = self.mol.spin
        self.natm = self.mol.natm
        self.coords = numpy.asarray([(numpy.asarray(atom[1])).tolist()
                                     for atom in self.mol._atom])
        self.charges = self.mol.atom_charges()
        self.mo_coeff = lib.chkfile.load(self.chkfile, 'scf/mo_coeff')
        self.mo_occ = lib.chkfile.load(self.chkfile, 'scf/mo_occ')
        nprims, nmo = self.mo_coeff.shape
        self.nprims = nprims
        self.nmo = nmo
        if self.charges[self.inuc] == 1:
            self.rad = grid.BRAGG[self.charges[self.inuc]]
        else:
            self.rad = grid.BRAGG[self.charges[self.inuc]] * 0.5

        if (self.corr):
            self.rdm1 = lib.chkfile.load(self.chkfile, 'rdm/rdm1')
            natocc, natorb = numpy.linalg.eigh(self.rdm1)
            natorb = numpy.dot(self.mo_coeff, natorb)
            self.mo_coeff = natorb
            self.mo_occ = natocc
        nocc = self.mo_occ[abs(self.mo_occ) > self.occdrop]
        nocc = len(nocc)
        self.nocc = nocc

        idx = 'atom' + str(self.inuc)
        with h5py.File(self.surfile) as f:
            self.xnuc = f[idx + '/xnuc'].value
            self.xyzrho = f[idx + '/xyzrho'].value
            self.npang = f[idx + '/npang'].value
            self.ntrial = f[idx + '/ntrial'].value
            self.rmin = f[idx + '/rmin'].value
            self.rmax = f[idx + '/rmax'].value
            self.rsurf = f[idx + '/rsurf'].value
            self.nlimsurf = f[idx + '/nlimsurf'].value
            self.agrids = f[idx + '/coords'].value

        self.brad = self.rmin * self.betafac

        if self.verbose >= logger.WARN:
            self.check_sanity()
        if self.verbose > logger.NOTE:
            self.dump_input()

        if (self.iqudr == 'legendre'):
            self.iqudr = 1
        if (self.biqudr == 'legendre'):
            self.biqudr = 1

        if (self.mapr == 'becke'):
            self.mapr = 1
        elif (self.mapr == 'exp'):
            self.mapr = 2
        elif (self.mapr == 'none'):
            self.mapr = 0
        if (self.bmapr == 'becke'):
            self.bmapr = 1
        elif (self.bmapr == 'exp'):
            self.bmapr = 2
        elif (self.bmapr == 'none'):
            self.bmapr = 0

        with lib.with_omp_threads(self.nthreads):
            brprops = int_beta(self)
            rprops = out_beta(self)

        logger.info(self, 'Write info to HDF5 file')
        atom_dic = {
            'inprops': brprops,
            'outprops': rprops,
            'blmax': self.blmax,
            'lmax': self.lmax,
            'totprops': (brprops + rprops)
        }
        lib.chkfile.save(self.surfile, 'qlm' + str(self.inuc), atom_dic)

        logger.info(
            self, '*-> Total Qlm(0,0)  (s)      %f' % (rprops[0] + brprops[0]))
        logger.info(
            self, '*-> Total Qlm(1,-1) (py)     %f' % (rprops[1] + brprops[1]))
        logger.info(
            self, '*-> Total Qlm(1,0)  (pz)     %f' % (rprops[2] + brprops[2]))
        logger.info(
            self, '*-> Total Qlm(1,1)  (px)     %f' % (rprops[3] + brprops[3]))
        logger.info(
            self, '*-> Total Qlm(2,-2) (dxy)    %f' % (rprops[4] + brprops[4]))
        logger.info(
            self, '*-> Total Qlm(2,-1) (dyz)    %f' % (rprops[5] + brprops[5]))
        logger.info(
            self, '*-> Total Qlm(2,0)  (dz2)    %f' % (rprops[6] + brprops[6]))
        logger.info(
            self, '*-> Total Qlm(2,1)  (xz)     %f' % (rprops[7] + brprops[7]))
        logger.info(
            self, '*-> Total Qlm(2,2)  (dx2-y2) %f' % (rprops[8] + brprops[8]))
        logger.info(self, '')

        logger.info(self, 'Qlm of atom %d done', self.inuc)
        logger.timer(self, 'Qlm build', *t0)

        return self
Ejemplo n.º 19
0
    def build(self):

        t0 = (time.clock(), time.time())
        lib.logger.TIMER_LEVEL = 3

        cell = libpbc.chkfile.load_cell(self.chkfile)
        cell.ecp = None
        self.cell = cell
        self.a = self.cell.lattice_vectors()
        self.b = self.cell.reciprocal_vectors()
        self.vol = self.cell.vol
        self.nelectron = self.cell.nelectron 
        self.charge = self.cell.charge    
        self.spin = self.cell.spin      
        self.natm = self.cell.natm		
        self.kpts = lib.chkfile.load(self.chkfile, 'kcell/kpts')
        self.nkpts = len(self.kpts)
        self.ls = cell.get_lattice_Ls(dimension=3)
        self.ls = self.ls[numpy.argsort(lib.norm(self.ls, axis=1))]
        self.atm = numpy.asarray(cell._atm, dtype=numpy.int32, order='C')
        self.bas = numpy.asarray(cell._bas, dtype=numpy.int32, order='C')
        self.env = numpy.asarray(cell._env, dtype=numpy.double, order='C')
        self.nbas = self.bas.shape[0]
        self.ao_loc = cell.ao_loc_nr()
        self.shls_slice = (0, self.nbas)
        sh0, sh1 = self.shls_slice
        self.nao = self.ao_loc[sh1] - self.ao_loc[sh0]
        self.non0tab = numpy.empty((1,self.nbas), dtype=numpy.int8)
        # non0tab stores the number of images to be summed in real space.
        # Initializing it to 255 means all images are summed
        self.non0tab[:] = 0xff
        self.coords = numpy.asarray([(numpy.asarray(atom[1])).tolist() for atom in cell._atom])
        self.charges = cell.atom_charges()
        self.mo_coeff = lib.chkfile.load(self.chkfile, 'scf/mo_coeff')
        self.mo_occ = lib.chkfile.load(self.chkfile, 'scf/mo_occ')
        nprims, nmo = self.mo_coeff[0].shape 
        self.nprims = nprims
        self.nmo = nmo
        self.cart = cell.cart
        if (not self.leb):
            self.npang = self.npphi*self.nptheta

        self.rcut = _estimate_rcut(self)
        kpts = numpy.reshape(self.kpts, (-1,3))
        kpts_lst = numpy.reshape(kpts, (-1,3))
        self.explk = numpy.exp(1j * numpy.asarray(numpy.dot(self.ls, kpts_lst.T), order='C'))

        if (self.ntrial%2 == 0): self.ntrial += 1
        geofac = numpy.power(((self.rmaxsurf-0.1)/self.rprimer),(1.0/(self.ntrial-1.0)))
        self.rpru = numpy.zeros((self.ntrial))
        for i in range(self.ntrial): 
            self.rpru[i] = self.rprimer*numpy.power(geofac,(i+1)-1)
        self.rsurf = numpy.zeros((self.npang,self.ntrial), order='C')
        self.nlimsurf = numpy.zeros((self.npang), dtype=numpy.int32)

        if self.verbose >= logger.WARN:
            self.check_sanity()
        if self.verbose > logger.NOTE:
            self.dump_input()

        if (self.iqudt == 'legendre'):
            self.iqudt = 1
        
        if (self.leb):
            self.grids = grid.lebgrid(self.npang)
        else:
            self.grids = grid.anggrid(self.iqudt,self.nptheta,self.npphi)
         
        self.xyzrho = numpy.zeros((self.natm,3))
        t = time.time()
        logger.info(self,'Time finding nucleus %.3f (sec)' % (time.time()-t))

        if (self.backend == 'rkck'):
            backend = 1
        elif (self.backend == 'rkdp'):
            backend = 2
        else:
            raise NotImplementedError('Only rkck or rkdp ODE solver yet available') 
         
        ct_ = numpy.asarray(self.grids[:,0], order='C')
        st_ = numpy.asarray(self.grids[:,1], order='C')
        cp_ = numpy.asarray(self.grids[:,2], order='C')
        sp_ = numpy.asarray(self.grids[:,3], order='C')

        mo_coeff = numpy.zeros((self.nkpts,self.nprims,self.nmo), dtype=numpy.complex128)
        mo_occ = numpy.zeros((self.nkpts,self.nmo))
        for k in range(self.nkpts):
            mo_coeff[k,:,:] = self.mo_coeff[k][:,:]
            mo_occ[k,:] = self.mo_occ[k][:]
        
        t = time.time()
        feval = 'surf_driver'
        drv = getattr(libaim, feval)
        with lib.with_omp_threads(self.nthreads):
            drv(ctypes.c_int(self.inuc), 
                self.xyzrho.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_int(self.npang), 
                ct_.ctypes.data_as(ctypes.c_void_p),
                st_.ctypes.data_as(ctypes.c_void_p),
                cp_.ctypes.data_as(ctypes.c_void_p),
                sp_.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_int(self.ntrial), 
                self.rpru.ctypes.data_as(ctypes.c_void_p), 
                ctypes.c_double(self.epsiscp), 
                ctypes.c_double(self.epsroot), 
                ctypes.c_double(self.rmaxsurf), 
                ctypes.c_int(backend),
                ctypes.c_double(self.epsilon), 
                ctypes.c_double(self.step), 
                ctypes.c_int(self.mstep),
                ctypes.c_int(self.natm), 
                self.coords.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_int(self.cart),
                ctypes.c_int(self.nmo),  
                ctypes.c_int(self.nprims), 
                self.atm.ctypes.data_as(ctypes.c_void_p), 
                ctypes.c_int(self.nbas), 
                self.bas.ctypes.data_as(ctypes.c_void_p), 
                self.env.ctypes.data_as(ctypes.c_void_p), 
                self.ao_loc.ctypes.data_as(ctypes.c_void_p),
                mo_coeff.ctypes.data_as(ctypes.c_void_p),
                mo_occ.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_double(self.occdrop), 
                #
                self.a.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_int(len(self.ls)), 
                self.ls.ctypes.data_as(ctypes.c_void_p),
                ctypes.c_int(self.nkpts), 
                self.explk.ctypes.data_as(ctypes.c_void_p),
                self.rcut.ctypes.data_as(ctypes.c_void_p),
                self.non0tab.ctypes.data_as(ctypes.c_void_p),
                #
                self.nlimsurf.ctypes.data_as(ctypes.c_void_p),
                self.rsurf.ctypes.data_as(ctypes.c_void_p))
        for i in range(self.nkpts):
            print k,self.mo_occ[k][:]
        logger.info(self,'Time finding surface %.3f (sec)' % (time.time()-t))
        r = numpy.array([0.00000, 0.00000, 0.00000]) 
        r = numpy.reshape(r, (-1,3))
        ao = dft.numint.eval_ao_kpts(self.cell, r, kpts=self.kpts, deriv=1)
        print rhograd(self,[0,0,0]) 
             
        logger.info(self,'Surface of atom %d saved',self.inuc)
        logger.timer(self,'BaderSurf build', *t0)

        return self
Ejemplo n.º 20
0
def kernel_ms0(fci, h1e, eri, norb, nelec, ci0=None, link_index=None,
               tol=None, lindep=None, max_cycle=None, max_space=None,
               nroots=None, davidson_only=None, pspace_size=None,
               max_memory=None, verbose=None, ecore=0, **kwargs):
    if nroots is None: nroots = fci.nroots
    if davidson_only is None: davidson_only = fci.davidson_only
    if pspace_size is None: pspace_size = fci.pspace_size

    assert(fci.spin is None or fci.spin == 0)
    assert(0 <= numpy.sum(nelec) <= norb*2)

    link_index = _unpack(norb, nelec, link_index)
    h1e = numpy.ascontiguousarray(h1e)
    eri = numpy.ascontiguousarray(eri)
    na = link_index.shape[0]
    hdiag = fci.make_hdiag(h1e, eri, norb, nelec)
    nroots = min(hdiag.size, nroots)

    try:
        addr, h0 = fci.pspace(h1e, eri, norb, nelec, hdiag, max(pspace_size,nroots))
        if pspace_size > 0:
            pw, pv = fci.eig(h0)
        else:
            pw = pv = None

        if pspace_size >= na*na and ci0 is None and not davidson_only:
# The degenerated wfn can break symmetry.  The davidson iteration with proper
# initial guess doesn't have this issue
            if na*na == 1:
                return pw[0]+ecore, pv[:,0].reshape(1,1)
            elif nroots > 1:
                civec = numpy.empty((nroots,na*na))
                civec[:,addr] = pv[:,:nroots].T
                civec = civec.reshape(nroots,na,na)
                try:
                    return pw[:nroots]+ecore, [_check_(ci) for ci in civec]
                except ValueError:
                    pass
            elif abs(pw[0]-pw[1]) > 1e-12:
                civec = numpy.empty((na*na))
                civec[addr] = pv[:,0]
                civec = civec.reshape(na,na)
                civec = lib.transpose_sum(civec) * .5
                # direct diagonalization may lead to triplet ground state
##TODO: optimize initial guess.  Using pspace vector as initial guess may have
## spin problems.  The 'ground state' of psapce vector may have different spin
## state to the true ground state.
                try:
                    return pw[0]+ecore, _check_(civec.reshape(na,na))
                except ValueError:
                    pass
    except NotImplementedError:
        addr = [0]
        pw = pv = None

    precond = fci.make_precond(hdiag, pw, pv, addr)

    h2e = fci.absorb_h1e(h1e, eri, norb, nelec, .5)
    def hop(c):
        hc = fci.contract_2e(h2e, c.reshape(na,na), norb, nelec, link_index)
        return hc.ravel()

#TODO: check spin of initial guess
    if ci0 is None:
        if callable(getattr(fci, 'get_init_guess', None)):
            ci0 = lambda: fci.get_init_guess(norb, nelec, nroots, hdiag)
        else:
            def ci0():
                x0 = []
                for i in range(nroots):
                    x = numpy.zeros((na,na))
                    addra = addr[i] // na
                    addrb = addr[i] % na
                    if addra == addrb:
                        x[addra,addrb] = 1
                    else:
                        x[addra,addrb] = x[addrb,addra] = numpy.sqrt(.5)
                    x0.append(x.ravel())
                return x0
    elif not callable(ci0):
        if isinstance(ci0, numpy.ndarray) and ci0.size == na*na:
            ci0 = [ci0.ravel()]
        else:
            ci0 = [x.ravel() for x in ci0]

    if tol is None: tol = fci.conv_tol
    if lindep is None: lindep = fci.lindep
    if max_cycle is None: max_cycle = fci.max_cycle
    if max_space is None: max_space = fci.max_space
    if max_memory is None: max_memory = fci.max_memory
    if verbose is None: verbose = logger.Logger(fci.stdout, fci.verbose)
    tol_residual = getattr(fci, 'conv_tol_residual', None)

    with lib.with_omp_threads(fci.threads):
        #e, c = lib.davidson(hop, ci0, precond, tol=fci.conv_tol, lindep=fci.lindep)
        e, c = fci.eig(hop, ci0, precond, tol=tol, lindep=lindep,
                       max_cycle=max_cycle, max_space=max_space, nroots=nroots,
                       max_memory=max_memory, verbose=verbose, follow_state=True,
                       tol_residual=tol_residual, **kwargs)
    if nroots > 1:
        return e+ecore, [_check_(ci.reshape(na,na)) for ci in c]
    else:
        return e+ecore, _check_(c.reshape(na,na))