def label_symmetry_(mc, mo_coeff): #irrep_name = mc.mol.irrep_name irrep_name = mc.mol.irrep_id s = mc._scf.get_ovlp() try: mc.orbsym = symm.label_orb_symm(mc.mol, irrep_name, mc.mol.symm_orb, mo_coeff, s=s) except ValueError: logger.warn(mc, 'mc1step_symm symmetrizes input orbitals') ncore = mc.ncore nocc = mc.ncore + mc.ncas mo_cor = symm.symmetrize_space(mc.mol, mo_coeff[:, :ncore], s=s, check=False) mo_act = symm.symmetrize_space(mc.mol, mo_coeff[:,ncore:nocc], s=s, check=False) mo_vir = symm.symmetrize_space(mc.mol, mo_coeff[:,nocc: ], s=s, check=False) mo_coeff = numpy.hstack((mo_cor,mo_act,mo_vir)) mc.orbsym = symm.label_orb_symm(mc.mol, irrep_name, mc.mol.symm_orb, mo_coeff, s=s) if (not hasattr(mc.fcisolver, 'orbsym') or (isinstance(mc.fcisolver.orbsym, numpy.ndarray) and len(mc.fcisolver.orbsym) == 0) or not mc.fcisolver.orbsym): ncore = mc.ncore nocc = mc.ncore + mc.ncas mc.fcisolver.orbsym = mc.orbsym[ncore:nocc] logger.debug(mc, 'Active space irreps %s', str(mc.fcisolver.orbsym))
def label_symmetry_(mc, mo_coeff): #irrep_name = mc.mol.irrep_name irrep_name = mc.mol.irrep_id s = mc._scf.get_ovlp() try: orbsym = scf.hf_symm.get_orbsym(mc._scf.mol, mo_coeff, s, True) except ValueError: logger.warn(mc, 'mc1step_symm symmetrizes input orbitals') ncore = mc.ncore nocc = mc.ncore + mc.ncas mo_cor = symm.symmetrize_space(mc.mol, mo_coeff[:, :ncore], s=s, check=False) mo_act = symm.symmetrize_space(mc.mol, mo_coeff[:,ncore:nocc], s=s, check=False) mo_vir = symm.symmetrize_space(mc.mol, mo_coeff[:,nocc: ], s=s, check=False) mo_coeff = numpy.hstack((mo_cor,mo_act,mo_vir)) orbsym = symm.label_orb_symm(mc.mol, irrep_name, mc.mol.symm_orb, mo_coeff, s=s) mo_coeff = lib.tag_array(mo_coeff, orbsym=orbsym) if (not hasattr(mc.fcisolver, 'orbsym') or mc.fcisolver.orbsym is None or (hasattr(mc.fcisolver.orbsym, '__len__') and len(mc.fcisolver.orbsym) == 0)): ncore = mc.ncore nocc = mc.ncore + mc.ncas mc.fcisolver.orbsym = orbsym[ncore:nocc] logger.debug(mc, 'Active space irreps %s', str(mc.fcisolver.orbsym)) return mo_coeff
def test_symmetrize_space(self): from pyscf import gto, symm, scf mol = gto.M(atom = 'C 0 0 0; H 1 1 1; H -1 -1 1; H 1 -1 -1; H -1 1 -1', basis = 'sto3g', verbose=0) mf = scf.RHF(mol).run() mol.build(0, 0, symmetry='D2') mo = symm.symmetrize_space(mol, mf.mo_coeff) irreps = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo) self.assertEqual(irreps, ['A','A','A','B1','B1','B2','B2','B3','B3'])
def test_symmetrize_space(self): from pyscf import gto, symm, scf mol = gto.M(atom = 'C 0 0 0; H 1 1 1; H -1 -1 1; H 1 -1 -1; H -1 1 -1', basis = 'sto3g', verbose=0) mf = scf.RHF(mol).run() mol.build(0, 0, symmetry='D2') mo = symm.symmetrize_space(mol, mf.mo_coeff) irreps = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo) self.assertEqual(irreps, ['A','A','B1','B3','B2','A','B1','B3','B2'])
def _svd (self, mo_lspace, mo_rspace, s=None, **kwargs): if s is None: s = self._scf.get_ovlp () lsymm = getattr (mo_lspace, 'orbsym', None) if lsymm is None: mo_lspace = symm.symmetrize_space (self.mol, mo_lspace) lsymm = symm.label_orb_symm(self.mol, self.mol.irrep_id, self.mol.symm_orb, mo_lspace, s=s) rsymm = getattr (mo_rspace, 'orbsym', None) if rsymm is None: mo_rspace = symm.symmetrize_space (self.mol, mo_rspace) rsymm = symm.label_orb_symm(self.mol, self.mol.irrep_id, self.mol.symm_orb, mo_rspace, s=s) decomp = matrix_svd_control_options (s, lspace=mo_lspace, rspace=mo_rspace, lspace_symmetry=lsymm, rspace_symmetry=rsymm, full_matrices=True, strong_symm=True) mo_lvecs, svals, mo_rvecs, lsymm, rsymm = decomp mo_lvecs = tag_array (mo_lvecs, orbsym=lsymm) mo_rvecs = tag_array (mo_rvecs, orbsym=rsymm) return mo_lvecs, svals, mo_rvecs
def label_symmetry_(mc, mo_coeff): #irrep_name = mc.mol.irrep_name irrep_name = mc.mol.irrep_id s = mc._scf.get_ovlp() try: mc.orbsym = symm.label_orb_symm(mc.mol, irrep_name, mc.mol.symm_orb, mo_coeff, s=s) except ValueError: logger.warn(mc, 'mc1step_symm symmetrizes input orbitals') ncore = mc.ncore nocc = mc.ncore + mc.ncas mo_cor = symm.symmetrize_space(mc.mol, mo_coeff[:, :ncore], s=s) mo_act = symm.symmetrize_space(mc.mol, mo_coeff[:,ncore:nocc], s=s) mo_vir = symm.symmetrize_space(mc.mol, mo_coeff[:,nocc: ], s=s) mo_coeff = numpy.hstack((mo_cor,mo_act,mo_vir)) mc.orbsym = symm.label_orb_symm(mc.mol, irrep_name, mc.mol.symm_orb, mo_coeff, s=s) if not hasattr(mc.fcisolver, 'orbsym') or not mc.fcisolver.orbsym: ncore = mc.ncore nocc = mc.ncore + mc.ncas mc.fcisolver.orbsym = mc.orbsym[ncore:nocc] logger.debug(mc, 'Active space irreps %s', str(mc.fcisolver.orbsym))
def label_symmetry_(mc, mo_coeff, ci0=None): log = logger.Logger(mc.stdout, mc.verbose) #irrep_name = mc.mol.irrep_name irrep_name = mc.mol.irrep_id s = mc._scf.get_ovlp() ncore = mc.ncore nocc = ncore + mc.ncas try: orbsym = scf.hf_symm.get_orbsym(mc._scf.mol, mo_coeff, s, True) except ValueError: log.warn('mc1step_symm symmetrizes input orbitals') mo_cor = symm.symmetrize_space(mc.mol, mo_coeff[:, :ncore], s=s, check=False) mo_act = symm.symmetrize_space(mc.mol, mo_coeff[:, ncore:nocc], s=s, check=False) mo_vir = symm.symmetrize_space(mc.mol, mo_coeff[:, nocc:], s=s, check=False) mo_coeff = numpy.hstack((mo_cor, mo_act, mo_vir)) orbsym = symm.label_orb_symm(mc.mol, irrep_name, mc.mol.symm_orb, mo_coeff, s=s) mo_coeff_with_orbsym = lib.tag_array(mo_coeff, orbsym=orbsym) active_orbsym = getattr(mc.fcisolver, 'orbsym', []) if (not getattr(active_orbsym, '__len__', None)) or len(active_orbsym) == 0: mc.fcisolver.orbsym = orbsym[ncore:nocc] log.info( 'Symmetries of active orbitals: %s', ' '.join([ symm.irrep_id2name(mc.mol.groupname, irrep) for irrep in mc.fcisolver.orbsym ])) wfnsym = 0 if getattr(mc.fcisolver, 'wfnsym', None) is not None: wfnsym = mc.fcisolver.wfnsym log.debug('Use fcisolver.wfnsym %s', wfnsym) elif ci0 is None: # Guess wfnsym based on HF determinant. mo_coeff may not be HF # canonical orbitals. Some checks are needed to ensure that mo_coeff # are derived from the symmetry adapted SCF calculations. if mo_coeff is mc._scf.mo_coeff: wfnsym = 0 orbsym_in_d2h = numpy.asarray(orbsym) % 10 # convert to D2h irreps for ir in orbsym_in_d2h[mc._scf.mo_occ == 1]: wfnsym ^= ir mc.fcisolver.wfnsym = wfnsym log.debug('Set CASCI wfnsym %s based on HF determinant', wfnsym) elif getattr(mo_coeff, 'orbsym', None) is not None: # It may be reordered SCF orbitals cas_orb = mo_coeff[:, ncore:nocc] s = reduce( numpy.dot, (cas_orb.conj().T, mc._scf.get_ovlp(), mc._scf.mo_coeff)) if numpy.all(numpy.max(s, axis=1) > 1 - 1e-9): idx = numpy.argmax(s, axis=1) cas_orbsym_in_d2h = numpy.asarray(orbsym[ncore:nocc]) % 10 cas_occ = mc._scf.mo_occ[idx] wfnsym = 0 for ir in cas_orbsym_in_d2h[cas_occ == 1]: wfnsym ^= ir mc.fcisolver.wfnsym = wfnsym log.debug( 'Active space are constructed from canonical SCF ' 'orbitals %s', idx) log.debug('Set CASCI wfnsym %s based on HF determinant', wfnsym) elif getattr(mc.fcisolver, 'guess_wfnsym', None): wfnsym = mc.fcisolver.guess_wfnsym(mc.ncas, mc.nelecas, ci0, verbose=log) log.debug('CASCI wfnsym %s (based on CI initial guess)', wfnsym) if isinstance(wfnsym, (int, numpy.integer)): try: wfnsym = symm.irrep_id2name(mc.mol.groupname, wfnsym) except KeyError: log.warn( 'mwfnsym Id %s not found in group %s. This might be caused by ' 'the projection from high-symmetry group to D2h symmetry.', wfnsym, mc.mol.groupname) log.info('Active space CI wfn symmetry = %s', wfnsym) return mo_coeff_with_orbsym
def label_symmetry_(mc, mo_coeff, ci0=None): log = logger.Logger(mc.stdout, mc.verbose) #irrep_name = mc.mol.irrep_name irrep_name = mc.mol.irrep_id s = mc._scf.get_ovlp() ncore = mc.ncore nocc = ncore + mc.ncas try: orbsym = scf.hf_symm.get_orbsym(mc._scf.mol, mo_coeff, s, True) except ValueError: log.warn('mc1step_symm symmetrizes input orbitals') mo_cor = symm.symmetrize_space(mc.mol, mo_coeff[:, :ncore], s=s, check=False) mo_act = symm.symmetrize_space(mc.mol, mo_coeff[:,ncore:nocc], s=s, check=False) mo_vir = symm.symmetrize_space(mc.mol, mo_coeff[:,nocc: ], s=s, check=False) mo_coeff = numpy.hstack((mo_cor,mo_act,mo_vir)) orbsym = symm.label_orb_symm(mc.mol, irrep_name, mc.mol.symm_orb, mo_coeff, s=s) mo_coeff_with_orbsym = lib.tag_array(mo_coeff, orbsym=orbsym) active_orbsym = getattr(mc.fcisolver, 'orbsym', []) if (not getattr(active_orbsym, '__len__', None)) or len(active_orbsym) == 0: mc.fcisolver.orbsym = orbsym[ncore:nocc] log.debug('Active space irreps %s', str(mc.fcisolver.orbsym)) wfnsym = 0 if getattr(mc.fcisolver, 'wfnsym', None) is not None: wfnsym = mc.fcisolver.wfnsym elif ci0 is None: # Guess wfnsym based on HF determinant. mo_coeff may not be HF # canonical orbitals. Some checks are needed to ensure that mo_coeff # are derived from the symmetry adapted SCF calculations. if mo_coeff is mc._scf.mo_coeff: wfnsym = 0 for ir in orbsym[mc._scf.mo_occ == 1]: wfnsym ^= ir mc.fcisolver.wfnsym = wfnsym log.debug('Set CASCI wfnsym %s based on HF determinant', wfnsym) elif getattr(mo_coeff, 'orbsym', None) is not None: # It may be reordered SCF orbitals cas_orb = mo_coeff[:,ncore:nocc] s = reduce(numpy.dot, (cas_orb.T, mc._scf.get_ovlp(), mc._scf.mo_coeff)) if numpy.all(numpy.max(s, axis=1) > 1-1e-9): idx = numpy.argmax(s, axis=1) cas_orbsym = orbsym[ncore:nocc] cas_occ = mc._scf.mo_occ[idx] wfnsym = 0 for ir in cas_orbsym[cas_occ == 1]: wfnsym ^= ir mc.fcisolver.wfnsym = wfnsym log.debug('Active space are constructed from canonical SCF ' 'orbitals %s', idx) log.debug('Set CASCI wfnsym %s based on HF determinant', wfnsym) elif getattr(mc.fcisolver, 'guess_wfnsym', None): wfnsym = mc.fcisolver.guess_wfnsym(mc.ncas, mc.nelecas, ci0, verbose=log) log.debug('CASCI wfnsym %s (based on CI initial guess)', wfnsym) if isinstance(wfnsym, (int, numpy.integer)): wfnsym = symm.irrep_id2name(mc.mol.groupname, wfnsym) log.info('Active space CI wfn symmetry = %s', wfnsym) return mo_coeff_with_orbsym
# # call mol.build to construct symmetry adapted basis. # # NOTE the molecule orientation. Simply assigning mol.build(symmetry=True) # may change the orientation of the molecule. If the orientation is different # to the orientation of the orbital space, the orbitals cannot be symmetrized. # To keep the molecule orientation fixed, we need specify the molecular # symmetry. # mol.build(0, 0, symmetry='D2') # # H**O-2 H**O-1 H**O are degenerated. They may not be properly symmetrized. # try: irrep_ids = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo) except ValueError: print('The orbital symmetry cannot be labelled because some ' 'degenerated orbitals are not symmetrized.\n' 'Degenerated H**O energy: %s' % mf.mo_energy[2:5]) nocc = mol.nelectron // 2 occ_orb = symm.symmetrize_space(mol, mo[:,:nocc]) irrep_ids = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, occ_orb) print('Occupied orbital symmetry: %s' % irrep_ids) virt_orb = symm.symmetrize_space(mol, mo[:,nocc:]) irrep_ids = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, virt_orb) print('Virtual orbital symmetry: %s' % irrep_ids)