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
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
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
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
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
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
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
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]
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)
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
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
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()
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()
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)
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)
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)
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))
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
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
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))