def guess_wfnsym(self, norb, nelec, fcivec=None, orbsym=None, wfnsym=None, **kwargs): if orbsym is None: orbsym = self.orbsym if fcivec is None: wfnsym = direct_spin1_symm._id_wfnsym(self, norb, nelec, orbsym, wfnsym) elif wfnsym is None: strsa, strsb = getattr(fcivec, '_strs', self._strs) if isinstance(fcivec, numpy.ndarray) and fcivec.ndim <= 2: wfnsym = addons._guess_wfnsym(fcivec, strsa, strsb, orbsym) else: wfnsym = [ addons._guess_wfnsym(c, strsa, strsb, orbsym) for c in fcivec ] if any(wfnsym[0] != x for x in wfnsym): warnings.warn( 'Different wfnsym %s found in different CI vecotrs' % wfnsym) wfnsym = wfnsym[0] else: strsa, strsb = getattr(fcivec, '_strs', self._strs) na, nb = strsa.size, strsb.size orbsym_in_d2h = numpy.asarray(orbsym) % 10 # convert to D2h irreps airreps = numpy.zeros(na, dtype=numpy.int32) birreps = numpy.zeros(nb, dtype=numpy.int32) for i, ir in enumerate(orbsym_in_d2h): airreps[numpy.bitwise_and(strsa, 1 << i) > 0] ^= ir birreps[numpy.bitwise_and(strsb, 1 << i) > 0] ^= ir wfnsym = direct_spin1_symm._id_wfnsym(self, norb, nelec, orbsym, wfnsym) mask = (airreps.reshape(-1, 1) ^ birreps) == wfnsym if isinstance(fcivec, numpy.ndarray) and fcivec.ndim <= 2: fcivec = [fcivec] if all(abs(c.reshape(na, nb)[mask]).max() < 1e-5 for c in fcivec): raise RuntimeError( 'Input wfnsym is not consistent with fcivec coefficients') verbose = kwargs.get('verbose', None) log = logger.new_logger(self, verbose) log.debug('Guessing CI wfn symmetry = %s', wfnsym) return wfnsym
def get_init_guess(self, ci_strs, norb, nelec, nroots, hdiag): '''Initial guess is the single Slater determinant ''' wfnsym = direct_spin1_symm._id_wfnsym(self, norb, nelec, self.wfnsym) ci0 = direct_spin1_symm._get_init_guess(ci_strs[0], ci_strs[1], nroots, hdiag, self.orbsym, wfnsym) return [select_ci._as_SCIvector(x, ci_strs) for x in ci0]
def kernel(h1e, eri, norb, nelec, ci0=None, level_shift=1e-3, tol=1e-10, lindep=1e-14, max_cycle=50, max_space=12, nroots=1, davidson_only=False, pspace_size=400, orbsym=None, wfnsym=None, ecore=0, **kwargs): assert(len(orbsym) == norb) cis = FCISolver(None) cis.level_shift = level_shift cis.conv_tol = tol cis.lindep = lindep cis.max_cycle = max_cycle cis.max_space = max_space cis.nroots = nroots cis.davidson_only = davidson_only cis.pspace_size = pspace_size cis.orbsym = orbsym cis.wfnsym = wfnsym unknown = {} for k, v in kwargs.items(): setattr(cis, k, v) if not hasattr(cis, k): unknown[k] = v if unknown: sys.stderr.write('Unknown keys %s for FCI kernel %s\n' % (str(unknown.keys()), __name__)) wfnsym = direct_spin1_symm._id_wfnsym(cis, norb, nelec, cis.wfnsym) if cis.wfnsym is not None and ci0 is None: ci0 = addons.symm_initguess(norb, nelec, orbsym, wfnsym) e, c = cis.kernel(h1e, eri, norb, nelec, ci0, ecore=ecore, **unknown) return e, c
def kernel(h1e, eri, norb, nelec, ci0=None, level_shift=.001, tol=1e-10, lindep=1e-14, max_cycle=50, nroots=1, orbsym=[], wfnsym=None, **kwargs): cis = FCISolver(None) cis.level_shift = level_shift cis.orbsym = orbsym cis.conv_tol = tol cis.lindep = lindep cis.max_cycle = max_cycle cis.wfnsym = wfnsym cis.nroots = nroots unknown = [] for k, v in kwargs.items(): setattr(cis, k, v) if not hasattr(cis, k): unknown.append(k) if unknown: sys.stderr.write('Unknown keys %s for FCI kernel %s\n' % (str(unknown), __name__)) wfnsym = direct_spin1_symm._id_wfnsym(cis, norb, nelec, cis.wfnsym) if cis.wfnsym is not None and ci0 is None: ci0 = addons.symm_initguess(norb, nelec, orbsym, wfnsym) e, c = direct_spin0.kernel_ms0(cis, h1e, eri, norb, nelec, ci0=ci0) if cis.wfnsym is not None: if cis.nroots > 1: c = [addons.symmetrize_wfn(ci, norb, nelec, orbsym, wfnsym) for ci in c] else: c = addons.symmetrize_wfn(c, norb, nelec, orbsym, wfnsym) return e, c
def get_init_guess(self, norb, nelec, nroots, hdiag_csf): ''' The existing _get_init_guess function will work in the csf basis if I pass it with na, nb = ncsf, 1. This might change in future PySCF versions though. ...For point-group symmetry, I pass the direct_spin1.py version of _get_init_guess with na, nb = ncsf_sym, 1 and hdiag_csf including only csfs of the right point-group symmetry. This should clean up the symmetry-breaking "noise" in direct_spin0_symm.py! ''' wfnsym = _id_wfnsym(self, norb, nelec, self.orbsym, self.wfnsym) wfnsym_str = symm.irrep_id2name (self.mol.groupname, wfnsym) self.check_mask_cache () idx_sym = self.confsym[self.econf_csf_mask] == wfnsym return get_init_guess (norb, nelec, nroots, hdiag_csf, smult=self.smult, csd_mask=self.csd_mask, wfnsym_str=wfnsym_str, idx_sym=idx_sym)
def guess_wfnsym(self, norb, nelec, fcivec=None, wfnsym=None, **kwargs): if fcivec is None: wfnsym = direct_spin1_symm._id_wfnsym(self, norb, nelec, wfnsym) else: wfnsym = addons.guess_wfnsym(fcivec, norb, nelec, self.orbsym) if 'verbose' in kwargs: if isinstance(kwargs['verbose'], logger.Logger): log = kwargs['verbose'] else: log = logger.Logger(self.stdout, kwargs['verbose']) log.debug('Guessing CI wfn symmetry = %s', wfnsym) else: logger.debug(self, 'Guessing CI wfn symmetry = %s', wfnsym) return wfnsym
def contract_2e(self, eri, fcivec, norb, nelec, link_index=None, orbsym=None, wfnsym=None, **kwargs): if orbsym is None: orbsym = self.orbsym if wfnsym is None: wfnsym = self.wfnsym wfnsym = direct_spin1_symm._id_wfnsym(self, norb, nelec, wfnsym) return contract_2e(eri, fcivec, norb, nelec, link_index, orbsym, wfnsym, **kwargs)
def guess_wfnsym(self, norb, nelec, fcivec=None, orbsym=None, wfnsym=None, **kwargs): if orbsym is None: orbsym = self.orbsym if fcivec is None: wfnsym = direct_spin1_symm._id_wfnsym(self, norb, nelec, orbsym, wfnsym) else: strsa, strsb = getattr(fcivec, '_strs', self._strs) wfnsym = addons._guess_wfnsym(fcivec, strsa, strsb, orbsym) verbose = kwargs.get('verbose', None) log = logger.new_logger(self, verbose) log.debug('Guessing CI wfn symmetry = %s', wfnsym) return wfnsym
def kernel(self, h1e, eri, norb, nelec, ci0=None, tol=None, lindep=None, max_cycle=None, max_space=None, nroots=None, davidson_only=None, pspace_size=None, orbsym=None, wfnsym=None, **kwargs): if nroots is None: nroots = self.nroots if orbsym is not None: self.orbsym, orbsym_bak = orbsym, self.orbsym if wfnsym is not None: self.wfnsym, wfnsym_bak = wfnsym, self.wfnsym else: wfnsym_bak = None if self.verbose > logger.QUIET: pyscf.gto.mole.check_sanity(self, self._keys, self.stdout) wfnsym = direct_spin1_symm._id_wfnsym(self, norb, nelec, self.wfnsym) if 'verbose' in kwargs: if isinstance(kwargs['verbose'], logger.Logger): log = kwargs['verbose'] else: log = logger.Logger(self.stdout, kwargs['verbose']) log.debug('total symmetry = %s', wfnsym) else: logger.debug(self, 'total symmetry = %s', wfnsym) e, c = direct_spin0.kernel_ms0(self, h1e, eri, norb, nelec, ci0, tol, lindep, max_cycle, max_space, nroots, davidson_only, pspace_size, **kwargs) if self.wfnsym is not None: if self.nroots > 1: c = [addons.symmetrize_wfn(ci, norb, nelec, self.orbsym, wfnsym) for ci in c] else: c = addons.symmetrize_wfn(c, norb, nelec, self.orbsym, wfnsym) if orbsym is not None: self.orbsym = orbsym_bak if wfnsym_bak is not None: self.wfnsym = wfnsym_bak return e, c
def kernel(self, h1e, eri, norb, nelec, ci0=None, **kwargs): if self.verbose > logger.QUIET: pyscf.gto.mole.check_sanity(self, self._keys, self.stdout) wfnsym = direct_spin1_symm._id_wfnsym(self, norb, nelec, self.wfnsym) if 'verbose' in kwargs: if isinstance(kwargs['verbose'], logger.Logger): log = kwargs['verbose'] else: log = logger.Logger(self.stdout, kwargs['verbose']) log.debug('total symmetry = %s', symm.irrep_id2name(self.mol.groupname, wfnsym)) else: logger.debug(self, 'total symmetry = %s', symm.irrep_id2name(self.mol.groupname, wfnsym)) e, c = direct_spin0.kernel_ms0(self, h1e, eri, norb, nelec, ci0, **kwargs) if self.wfnsym is not None: if self.nroots > 1: c = [addons.symmetrize_wfn(ci, norb, nelec, self.orbsym, wfnsym) for ci in c] else: c = addons.symmetrize_wfn(c, norb, nelec, self.orbsym, wfnsym) return e, c
def get_init_guess(self, norb, nelec, nroots, hdiag): wfnsym = direct_spin1_symm._id_wfnsym(self, norb, nelec, self.wfnsym) return get_init_guess(norb, nelec, nroots, hdiag, self.orbsym, wfnsym)