def get_occ(self, mo_energy=None, mo_coeff=None): ''' We assumed mo_energy are grouped by symmetry irreps, (see function self.eig). The orbitals are sorted after SCF. ''' if mo_energy is None: mo_energy = self.mo_energy mol = self.mol if not mol.symmetry: return ghf.GHF.get_occ(self, mo_energy, mo_coeff) orbsym = get_orbsym(mol, mo_coeff) mo_occ = numpy.zeros_like(mo_energy) rest_idx = numpy.ones(mo_occ.size, dtype=bool) nelec_fix = 0 for i, ir in enumerate(mol.irrep_id): irname = mol.irrep_name[i] ir_idx = numpy.where(orbsym == ir)[0] if irname in self.irrep_nelec: n = self.irrep_nelec[irname] occ_sort = numpy.argsort(mo_energy[ir_idx].round(9), kind='mergesort') occ_idx = ir_idx[occ_sort[:n]] mo_occ[occ_idx] = 1 nelec_fix += n rest_idx[ir_idx] = False nelec_float = mol.nelectron - nelec_fix assert(nelec_float >= 0) if nelec_float > 0: rest_idx = numpy.where(rest_idx)[0] occ_sort = numpy.argsort(mo_energy[rest_idx].round(9), kind='mergesort') occ_idx = rest_idx[occ_sort[:nelec_float]] mo_occ[occ_idx] = 1 vir_idx = (mo_occ==0) if self.verbose >= logger.INFO and numpy.count_nonzero(vir_idx) > 0: ehomo = max(mo_energy[~vir_idx]) elumo = min(mo_energy[ vir_idx]) noccs = [] for i, ir in enumerate(mol.irrep_id): irname = mol.irrep_name[i] ir_idx = (orbsym == ir) noccs.append(int(mo_occ[ir_idx].sum())) if ehomo in mo_energy[ir_idx]: irhomo = irname if elumo in mo_energy[ir_idx]: irlumo = irname logger.info(self, 'H**O (%s) = %.15g LUMO (%s) = %.15g', irhomo, ehomo, irlumo, elumo) logger.debug(self, 'irrep_nelec = %s', noccs) hf_symm._dump_mo_energy(mol, mo_energy, mo_occ, ehomo, elumo, orbsym, verbose=self.verbose) if mo_coeff is not None and self.verbose >= logger.DEBUG: ss, s = self.spin_square(mo_coeff[:,mo_occ>0], self.get_ovlp()) logger.debug(self, 'multiplicity <S^2> = %.8g 2S+1 = %.8g', ss, s) return mo_occ
def get_occ(self, mo_energy=None, mo_coeff=None, orbsym=None): ''' We assumed mo_energy are grouped by symmetry irreps, (see function self.eig). The orbitals are sorted after SCF. ''' if mo_energy is None: mo_energy = self.mo_energy mol = self.mol if orbsym is None: if mo_coeff is not None: # due to linear-dep ovlp_ao = self.get_ovlp() orbsyma = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb, mo_coeff[0], ovlp_ao, False) orbsymb = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb, mo_coeff[1], ovlp_ao, False) orbsyma = numpy.asarray(orbsyma) orbsymb = numpy.asarray(orbsymb) else: ovlp_ao = None orbsyma = [numpy.repeat(ir, mol.symm_orb[i].shape[1]) for i, ir in enumerate(mol.irrep_id)] orbsyma = orbsymb = numpy.hstack(orbsyma) else: orbsyma = numpy.asarray(orbsym[0]) orbsymb = numpy.asarray(orbsym[1]) assert(mo_energy[0].size == orbsyma.size) mo_occ = numpy.zeros_like(mo_energy) idx_ea_left = [] idx_eb_left = [] neleca_fix = nelecb_fix = 0 for i, ir in enumerate(mol.irrep_id): irname = mol.irrep_name[i] ir_idxa = numpy.where(orbsyma == ir)[0] ir_idxb = numpy.where(orbsymb == ir)[0] if irname in self.irrep_nelec: if isinstance(self.irrep_nelec[irname], (int, numpy.integer)): nelecb = self.irrep_nelec[irname] // 2 neleca = self.irrep_nelec[irname] - nelecb else: neleca, nelecb = self.irrep_nelec[irname] ea_idx = numpy.argsort(mo_energy[0][ir_idxa].round(9)) eb_idx = numpy.argsort(mo_energy[1][ir_idxb].round(9)) mo_occ[0,ir_idxa[ea_idx[:neleca]]] = 1 mo_occ[1,ir_idxb[eb_idx[:nelecb]]] = 1 neleca_fix += neleca nelecb_fix += nelecb else: idx_ea_left.append(ir_idxa) idx_eb_left.append(ir_idxb) neleca_float = self.nelec[0] - neleca_fix nelecb_float = self.nelec[1] - nelecb_fix assert(neleca_float >= 0) assert(nelecb_float >= 0) if len(idx_ea_left) > 0: idx_ea_left = numpy.hstack(idx_ea_left) ea_left = mo_energy[0][idx_ea_left] ea_sort = numpy.argsort(ea_left.round(9)) occ_idx = idx_ea_left[ea_sort][:neleca_float] mo_occ[0][occ_idx] = 1 if len(idx_eb_left) > 0: idx_eb_left = numpy.hstack(idx_eb_left) eb_left = mo_energy[1][idx_eb_left] eb_sort = numpy.argsort(eb_left.round(9)) occ_idx = idx_eb_left[eb_sort][:nelecb_float] mo_occ[1][occ_idx] = 1 vir_idx = (mo_occ[0]==0) if self.verbose >= logger.INFO and numpy.count_nonzero(vir_idx) > 0: ehomoa = max(mo_energy[0][mo_occ[0]>0 ]) elumoa = min(mo_energy[0][mo_occ[0]==0]) ehomob = max(mo_energy[1][mo_occ[1]>0 ]) elumob = min(mo_energy[1][mo_occ[1]==0]) noccsa = [] noccsb = [] p0 = 0 for i, ir in enumerate(mol.irrep_id): irname = mol.irrep_name[i] ir_idxa = orbsyma == ir ir_idxb = orbsymb == ir noccsa.append(numpy.count_nonzero(mo_occ[0][ir_idxa])) noccsb.append(numpy.count_nonzero(mo_occ[1][ir_idxb])) if ehomoa in mo_energy[0][ir_idxa]: irhomoa = irname if elumoa in mo_energy[0][ir_idxa]: irlumoa = irname if ehomob in mo_energy[1][ir_idxb]: irhomob = irname if elumob in mo_energy[1][ir_idxb]: irlumob = irname logger.info(self, 'alpha H**O (%s) = %.15g LUMO (%s) = %.15g', irhomoa, ehomoa, irlumoa, elumoa) logger.info(self, 'beta H**O (%s) = %.15g LUMO (%s) = %.15g', irhomob, ehomob, irlumob, elumob) ehomo = max(ehomoa,ehomob) elumo = min(elumoa,elumob) logger.debug(self, 'alpha irrep_nelec = %s', noccsa) logger.debug(self, 'beta irrep_nelec = %s', noccsb) hf_symm._dump_mo_energy(mol, mo_energy[0], mo_occ[0], ehomo, elumo, orbsyma, 'alpha-', verbose=self.verbose) hf_symm._dump_mo_energy(mol, mo_energy[1], mo_occ[1], ehomo, elumo, orbsymb, 'beta-', verbose=self.verbose) if mo_coeff is not None and self.verbose >= logger.DEBUG: if ovlp_ao is None: ovlp_ao = self.get_ovlp() ss, s = self.spin_square((mo_coeff[0][:,mo_occ[0]>0], mo_coeff[1][:,mo_occ[1]>0]), ovlp_ao) logger.debug(self, 'multiplicity <S^2> = %.8g 2S+1 = %.8g', ss, s) return mo_occ
def get_occ(self, mo_energy, mo_coeff=None): ''' We cannot assume default mo_energy value, because the orbital energies are sorted after doing SCF. But in this function, we need the orbital energies are grouped by symmetry irreps ''' mol = self.mol mo_occ = numpy.zeros_like(mo_energy) nirrep = mol.symm_orb.__len__() idx_ea_left = [] idx_eb_left = [] neleca_fix = nelecb_fix = 0 p0 = 0 for ir in range(nirrep): irname = mol.irrep_name[ir] nso = mol.symm_orb[ir].shape[1] if irname in self.irrep_nelec: n = self.irrep_nelec[irname][0] mo_occ[0][p0:p0+n] = 1 neleca_fix += n n = self.irrep_nelec[irname][1] mo_occ[1][p0:p0+n] = 1 nelecb_fix += n else: idx_ea_left.append(range(p0,p0+nso)) idx_eb_left.append(range(p0,p0+nso)) p0 += nso neleca_float = self.nelectron_alpha - neleca_fix nelecb_float = mol.nelectron - self.nelectron_alpha - nelecb_fix assert(neleca_float >= 0) assert(nelecb_float >= 0) if len(idx_ea_left) > 0: idx_ea_left = numpy.hstack(idx_ea_left) ea_left = mo_energy[0][idx_ea_left] ea_sort = numpy.argsort(ea_left) occ_idx = idx_ea_left[ea_sort][:neleca_float] mo_occ[0][occ_idx] = 1 if len(idx_eb_left) > 0: idx_eb_left = numpy.hstack(idx_eb_left) eb_left = mo_energy[1][idx_eb_left] eb_sort = numpy.argsort(eb_left) occ_idx = idx_eb_left[eb_sort][:nelecb_float] mo_occ[1][occ_idx] = 1 ehomoa = max(mo_energy[0][mo_occ[0]>0 ]) elumoa = min(mo_energy[0][mo_occ[0]==0]) ehomob = max(mo_energy[1][mo_occ[1]>0 ]) elumob = min(mo_energy[1][mo_occ[1]==0]) noccsa = [] noccsb = [] p0 = 0 for ir in range(nirrep): irname = mol.irrep_name[ir] nso = mol.symm_orb[ir].shape[1] noccsa.append(int(mo_occ[0][p0:p0+nso].sum())) noccsb.append(int(mo_occ[1][p0:p0+nso].sum())) if ehomoa in mo_energy[0][p0:p0+nso]: irhomoa = irname if elumoa in mo_energy[0][p0:p0+nso]: irlumoa = irname if ehomob in mo_energy[1][p0:p0+nso]: irhomob = irname if elumob in mo_energy[1][p0:p0+nso]: irlumob = irname p0 += nso logger.info(self, 'alpha H**O (%s) = %.15g, LUMO (%s) = %.15g', irhomoa, ehomoa, irlumoa, elumoa) logger.info(self, 'beta H**O (%s) = %.15g, LUMO (%s) = %.15g', irhomob, ehomob, irlumob, elumob) if self.verbose >= logger.DEBUG: ehomo = max(ehomoa,ehomob) elumo = min(elumoa,elumob) logger.debug(self, 'alpha irrep_nelec = %s', noccsa) logger.debug(self, 'beta irrep_nelec = %s', noccsb) hf_symm._dump_mo_energy(mol, mo_energy[0], mo_occ[0], ehomo, elumo, 'alpha-') hf_symm._dump_mo_energy(mol, mo_energy[1], mo_occ[1], ehomo, elumo, 'beta-') return mo_occ
def get_occ(self, mo_energy=None, mo_coeff=None): ''' We assumed mo_energy are grouped by symmetry irreps, (see function self.eig). The orbitals are sorted after SCF. ''' if mo_energy is None: mo_energy = self.mo_energy mol = self.mol if not mol.symmetry: return uhf.UHF.get_occ(self, mo_energy, mo_coeff) orbsyma, orbsymb = get_orbsym(mol, mo_coeff) mo_occ = numpy.zeros_like(mo_energy) idx_ea_left = [] idx_eb_left = [] neleca_fix = nelecb_fix = 0 for i, ir in enumerate(mol.irrep_id): irname = mol.irrep_name[i] ir_idxa = numpy.where(orbsyma == ir)[0] ir_idxb = numpy.where(orbsymb == ir)[0] if irname in self.irrep_nelec: if isinstance(self.irrep_nelec[irname], (int, numpy.integer)): nelecb = self.irrep_nelec[irname] // 2 neleca = self.irrep_nelec[irname] - nelecb else: neleca, nelecb = self.irrep_nelec[irname] ea_idx = numpy.argsort(mo_energy[0][ir_idxa].round(9), kind='mergesort') eb_idx = numpy.argsort(mo_energy[1][ir_idxb].round(9), kind='mergesort') mo_occ[0,ir_idxa[ea_idx[:neleca]]] = 1 mo_occ[1,ir_idxb[eb_idx[:nelecb]]] = 1 neleca_fix += neleca nelecb_fix += nelecb else: idx_ea_left.append(ir_idxa) idx_eb_left.append(ir_idxb) nelec = self.nelec neleca_float = nelec[0] - neleca_fix nelecb_float = nelec[1] - nelecb_fix assert(neleca_float >= 0) assert(nelecb_float >= 0) if len(idx_ea_left) > 0: idx_ea_left = numpy.hstack(idx_ea_left) ea_left = mo_energy[0][idx_ea_left] ea_sort = numpy.argsort(ea_left.round(9), kind='mergesort') occ_idx = idx_ea_left[ea_sort][:neleca_float] mo_occ[0][occ_idx] = 1 if len(idx_eb_left) > 0: idx_eb_left = numpy.hstack(idx_eb_left) eb_left = mo_energy[1][idx_eb_left] eb_sort = numpy.argsort(eb_left.round(9), kind='mergesort') occ_idx = idx_eb_left[eb_sort][:nelecb_float] mo_occ[1][occ_idx] = 1 vir_idx = (mo_occ[0]==0) if self.verbose >= logger.INFO and numpy.count_nonzero(vir_idx) > 0: noccsa = [] noccsb = [] p0 = 0 for i, ir in enumerate(mol.irrep_id): irname = mol.irrep_name[i] ir_idxa = orbsyma == ir ir_idxb = orbsymb == ir noccsa.append(numpy.count_nonzero(mo_occ[0][ir_idxa])) noccsb.append(numpy.count_nonzero(mo_occ[1][ir_idxb])) ir_id2name = dict(zip(mol.irrep_id, mol.irrep_name)) ehomo = ehomoa = max(mo_energy[0][mo_occ[0]>0 ]) elumo = elumoa = min(mo_energy[0][mo_occ[0]==0]) irhomoa = ir_id2name[orbsyma[mo_energy[0] == ehomoa][0]] irlumoa = ir_id2name[orbsyma[mo_energy[0] == elumoa][0]] logger.info(self, 'alpha H**O (%s) = %.15g LUMO (%s) = %.15g', irhomoa, ehomoa, irlumoa, elumoa) if nelecb_float > 0: ehomob = max(mo_energy[1][mo_occ[1]>0 ]) elumob = min(mo_energy[1][mo_occ[1]==0]) irhomob = ir_id2name[orbsymb[mo_energy[1] == ehomob][0]] irlumob = ir_id2name[orbsymb[mo_energy[1] == elumob][0]] logger.info(self, 'beta H**O (%s) = %.15g LUMO (%s) = %.15g', irhomob, ehomob, irlumob, elumob) ehomo = max(ehomoa,ehomob) elumo = min(elumoa,elumob) logger.debug(self, 'alpha irrep_nelec = %s', noccsa) logger.debug(self, 'beta irrep_nelec = %s', noccsb) hf_symm._dump_mo_energy(mol, mo_energy[0], mo_occ[0], ehomo, elumo, orbsyma, 'alpha-', verbose=self.verbose) hf_symm._dump_mo_energy(mol, mo_energy[1], mo_occ[1], ehomo, elumo, orbsymb, 'beta-', verbose=self.verbose) if mo_coeff is not None and self.verbose >= logger.DEBUG: ovlp_ao = self.get_ovlp() ss, s = self.spin_square((mo_coeff[0][:,mo_occ[0]>0], mo_coeff[1][:,mo_occ[1]>0]), ovlp_ao) logger.debug(self, 'multiplicity <S^2> = %.8g 2S+1 = %.8g', ss, s) return mo_occ
def get_occ(self, mo_energy=None, mo_coeff=None, orbsym=None): ''' We assumed mo_energy are grouped by symmetry irreps, (see function self.eig). The orbitals are sorted after SCF. ''' if mo_energy is None: mo_energy = self.mo_energy mol = self.mol if orbsym is None: if mo_coeff is not None: # due to linear-dep ovlp_ao = self.get_ovlp() orbsyma = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb, mo_coeff[0], ovlp_ao, False) orbsymb = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb, mo_coeff[1], ovlp_ao, False) orbsyma = numpy.asarray(orbsyma) orbsymb = numpy.asarray(orbsymb) else: ovlp_ao = None orbsyma = [numpy.repeat(ir, mol.symm_orb[i].shape[1]) for i, ir in enumerate(mol.irrep_id)] orbsyma = orbsymb = numpy.hstack(orbsyma) else: orbsyma = numpy.asarray(orbsym[0]) orbsymb = numpy.asarray(orbsym[1]) assert(mo_energy[0].size == orbsyma.size) mo_occ = numpy.zeros_like(mo_energy) idx_ea_left = [] idx_eb_left = [] neleca_fix = nelecb_fix = 0 for i, ir in enumerate(mol.irrep_id): irname = mol.irrep_name[i] ir_idxa = numpy.where(orbsyma == ir)[0] ir_idxb = numpy.where(orbsymb == ir)[0] if irname in self.irrep_nelec: if isinstance(self.irrep_nelec[irname], (int, numpy.integer)): nelecb = self.irrep_nelec[irname] // 2 neleca = self.irrep_nelec[irname] - nelecb else: neleca, nelecb = self.irrep_nelec[irname] ea_idx = numpy.argsort(mo_energy[0][ir_idxa]) eb_idx = numpy.argsort(mo_energy[1][ir_idxb]) mo_occ[0,ir_idxa[ea_idx[:neleca]]] = 1 mo_occ[1,ir_idxb[eb_idx[:nelecb]]] = 1 neleca_fix += neleca nelecb_fix += nelecb else: idx_ea_left.append(ir_idxa) idx_eb_left.append(ir_idxb) neleca_float = self.nelec[0] - neleca_fix nelecb_float = self.nelec[1] - nelecb_fix assert(neleca_float >= 0) assert(nelecb_float >= 0) if len(idx_ea_left) > 0: idx_ea_left = numpy.hstack(idx_ea_left) ea_left = mo_energy[0][idx_ea_left] ea_sort = numpy.argsort(ea_left) occ_idx = idx_ea_left[ea_sort][:neleca_float] mo_occ[0][occ_idx] = 1 if len(idx_eb_left) > 0: idx_eb_left = numpy.hstack(idx_eb_left) eb_left = mo_energy[1][idx_eb_left] eb_sort = numpy.argsort(eb_left) occ_idx = idx_eb_left[eb_sort][:nelecb_float] mo_occ[1][occ_idx] = 1 vir_idx = (mo_occ[0]==0) if self.verbose >= logger.INFO and numpy.count_nonzero(vir_idx) > 0: ehomoa = max(mo_energy[0][mo_occ[0]>0 ]) elumoa = min(mo_energy[0][mo_occ[0]==0]) ehomob = max(mo_energy[1][mo_occ[1]>0 ]) elumob = min(mo_energy[1][mo_occ[1]==0]) noccsa = [] noccsb = [] p0 = 0 for i, ir in enumerate(mol.irrep_id): irname = mol.irrep_name[i] ir_idxa = orbsyma == ir ir_idxb = orbsymb == ir noccsa.append(numpy.count_nonzero(mo_occ[0][ir_idxa])) noccsb.append(numpy.count_nonzero(mo_occ[1][ir_idxb])) if ehomoa in mo_energy[0][ir_idxa]: irhomoa = irname if elumoa in mo_energy[0][ir_idxa]: irlumoa = irname if ehomob in mo_energy[1][ir_idxb]: irhomob = irname if elumob in mo_energy[1][ir_idxb]: irlumob = irname logger.info(self, 'alpha H**O (%s) = %.15g LUMO (%s) = %.15g', irhomoa, ehomoa, irlumoa, elumoa) logger.info(self, 'beta H**O (%s) = %.15g LUMO (%s) = %.15g', irhomob, ehomob, irlumob, elumob) ehomo = max(ehomoa,ehomob) elumo = min(elumoa,elumob) logger.debug(self, 'alpha irrep_nelec = %s', noccsa) logger.debug(self, 'beta irrep_nelec = %s', noccsb) hf_symm._dump_mo_energy(mol, mo_energy[0], mo_occ[0], ehomo, elumo, orbsyma, 'alpha-', verbose=self.verbose) hf_symm._dump_mo_energy(mol, mo_energy[1], mo_occ[1], ehomo, elumo, orbsymb, 'beta-', verbose=self.verbose) if mo_coeff is not None and self.verbose >= logger.DEBUG: if ovlp_ao is None: ovlp_ao = self.get_ovlp() ss, s = self.spin_square((mo_coeff[0][:,mo_occ[0]>0], mo_coeff[1][:,mo_occ[1]>0]), ovlp_ao) logger.debug(self, 'multiplicity <S^2> = %.8g 2S+1 = %.8g', ss, s) return mo_occ
def get_occ(self, mo_energy, mo_coeff=None): ''' We cannot assume default mo_energy value, because the orbital energies are sorted after doing SCF. But in this function, we need the orbital energies are grouped by symmetry irreps ''' mol = self.mol nirrep = len(mol.symm_orb) if mo_coeff is not None: ovlp_ao = self.get_ovlp() orbsyma = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb, mo_coeff[0], ovlp_ao, False) orbsymb = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb, mo_coeff[1], ovlp_ao, False) orbsyma = numpy.asarray(orbsyma) orbsymb = numpy.asarray(orbsymb) else: orbsyma = [numpy.repeat(ir, mol.symm_orb[i].shape[1]) for i, ir in enumerate(mol.irrep_id)] orbsyma = orbsymb = numpy.hstack(orbsyma) mo_occ = numpy.zeros_like(mo_energy) idx_ea_left = [] idx_eb_left = [] neleca_fix = nelecb_fix = 0 for i, ir in enumerate(mol.irrep_id): irname = mol.irrep_name[i] ir_idxa = numpy.where(orbsyma == ir)[0] ir_idxb = numpy.where(orbsymb == ir)[0] if irname in self.irrep_nelec: n = self.irrep_nelec[irname][0] e_idx = numpy.argsort(mo_energy[0][ir_idxa]) mo_occ[0][ir_idxa[e_idx[:n]]] = 1 neleca_fix += n n = self.irrep_nelec[irname][1] e_idx = numpy.argsort(mo_energy[1][ir_idxb]) mo_occ[1][ir_idxb[e_idx[:n]]] = 1 nelecb_fix += n else: idx_ea_left.append(ir_idxa) idx_eb_left.append(ir_idxb) neleca_float = self.nelec[0] - neleca_fix nelecb_float = self.nelec[1] - nelecb_fix assert(neleca_float >= 0) assert(nelecb_float >= 0) if len(idx_ea_left) > 0: idx_ea_left = numpy.hstack(idx_ea_left) ea_left = mo_energy[0][idx_ea_left] ea_sort = numpy.argsort(ea_left) occ_idx = idx_ea_left[ea_sort][:neleca_float] mo_occ[0][occ_idx] = 1 if len(idx_eb_left) > 0: idx_eb_left = numpy.hstack(idx_eb_left) eb_left = mo_energy[1][idx_eb_left] eb_sort = numpy.argsort(eb_left) occ_idx = idx_eb_left[eb_sort][:nelecb_float] mo_occ[1][occ_idx] = 1 viridx = (mo_occ[0]==0) if self.verbose < logger.INFO or viridx.sum() == 0: return mo_occ ehomoa = max(mo_energy[0][mo_occ[0]>0 ]) elumoa = min(mo_energy[0][mo_occ[0]==0]) ehomob = max(mo_energy[1][mo_occ[1]>0 ]) elumob = min(mo_energy[1][mo_occ[1]==0]) noccsa = [] noccsb = [] p0 = 0 for i, ir in enumerate(mol.irrep_id): irname = mol.irrep_name[i] ir_idxa = orbsyma == ir ir_idxb = orbsymb == ir noccsa.append(int(mo_occ[0][ir_idxa].sum())) noccsb.append(int(mo_occ[1][ir_idxb].sum())) if ehomoa in mo_energy[0][ir_idxa]: irhomoa = irname if elumoa in mo_energy[0][ir_idxa]: irlumoa = irname if ehomob in mo_energy[1][ir_idxb]: irhomob = irname if elumob in mo_energy[1][ir_idxb]: irlumob = irname logger.info(self, 'alpha H**O (%s) = %.15g LUMO (%s) = %.15g', irhomoa, ehomoa, irlumoa, elumoa) logger.info(self, 'beta H**O (%s) = %.15g LUMO (%s) = %.15g', irhomob, ehomob, irlumob, elumob) if self.verbose >= logger.DEBUG: ehomo = max(ehomoa,ehomob) elumo = min(elumoa,elumob) logger.debug(self, 'alpha irrep_nelec = %s', noccsa) logger.debug(self, 'beta irrep_nelec = %s', noccsb) hf_symm._dump_mo_energy(mol, mo_energy[0], mo_occ[0], ehomo, elumo, orbsyma, 'alpha-', verbose=self.verbose) hf_symm._dump_mo_energy(mol, mo_energy[1], mo_occ[1], ehomo, elumo, orbsymb, 'beta-', verbose=self.verbose) if mo_coeff is not None: ss, s = self.spin_square((mo_coeff[0][:,mo_occ[0]>0], mo_coeff[1][:,mo_occ[1]>0]), ovlp_ao) logger.debug(self, 'multiplicity <S^2> = %.8g 2S+1 = %.8g', ss, s) return mo_occ
def get_occ(self, mo_energy=None, mo_coeff=None): ''' We assumed mo_energy are grouped by symmetry irreps, (see function self.eig). The orbitals are sorted after SCF. ''' if mo_energy is None: mo_energy = self.mo_energy mol = self.mol if not mol.symmetry: return uhf.UHF.get_occ(self, mo_energy, mo_coeff) orbsyma, orbsymb = get_orbsym(mol, mo_coeff) mo_occ = numpy.zeros_like(mo_energy) idx_ea_left = [] idx_eb_left = [] neleca_fix = nelecb_fix = 0 for i, ir in enumerate(mol.irrep_id): irname = mol.irrep_name[i] ir_idxa = numpy.where(orbsyma == ir)[0] ir_idxb = numpy.where(orbsymb == ir)[0] if irname in self.irrep_nelec: if isinstance(self.irrep_nelec[irname], (int, numpy.integer)): nelecb = self.irrep_nelec[irname] // 2 neleca = self.irrep_nelec[irname] - nelecb else: neleca, nelecb = self.irrep_nelec[irname] ea_idx = numpy.argsort(mo_energy[0][ir_idxa].round(9), kind='mergesort') eb_idx = numpy.argsort(mo_energy[1][ir_idxb].round(9), kind='mergesort') mo_occ[0, ir_idxa[ea_idx[:neleca]]] = 1 mo_occ[1, ir_idxb[eb_idx[:nelecb]]] = 1 neleca_fix += neleca nelecb_fix += nelecb else: idx_ea_left.append(ir_idxa) idx_eb_left.append(ir_idxb) nelec = self.nelec neleca_float = nelec[0] - neleca_fix nelecb_float = nelec[1] - nelecb_fix assert (neleca_float >= 0) assert (nelecb_float >= 0) if len(idx_ea_left) > 0: idx_ea_left = numpy.hstack(idx_ea_left) ea_left = mo_energy[0][idx_ea_left] ea_sort = numpy.argsort(ea_left.round(9), kind='mergesort') occ_idx = idx_ea_left[ea_sort][:neleca_float] mo_occ[0][occ_idx] = 1 if len(idx_eb_left) > 0: idx_eb_left = numpy.hstack(idx_eb_left) eb_left = mo_energy[1][idx_eb_left] eb_sort = numpy.argsort(eb_left.round(9), kind='mergesort') occ_idx = idx_eb_left[eb_sort][:nelecb_float] mo_occ[1][occ_idx] = 1 vir_idx = (mo_occ[0] == 0) if self.verbose >= logger.INFO and numpy.count_nonzero(vir_idx) > 0: noccsa = [] noccsb = [] for i, ir in enumerate(mol.irrep_id): irname = mol.irrep_name[i] ir_idxa = orbsyma == ir ir_idxb = orbsymb == ir noccsa.append(numpy.count_nonzero(mo_occ[0][ir_idxa])) noccsb.append(numpy.count_nonzero(mo_occ[1][ir_idxb])) ir_id2name = dict(zip(mol.irrep_id, mol.irrep_name)) ehomo = ehomoa = max(mo_energy[0][mo_occ[0] > 0]) elumo = elumoa = min(mo_energy[0][mo_occ[0] == 0]) irhomoa = ir_id2name[orbsyma[mo_energy[0] == ehomoa][0]] irlumoa = ir_id2name[orbsyma[mo_energy[0] == elumoa][0]] logger.info(self, 'alpha H**O (%s) = %.15g LUMO (%s) = %.15g', irhomoa, ehomoa, irlumoa, elumoa) if nelecb_float > 0: ehomob = max(mo_energy[1][mo_occ[1] > 0]) elumob = min(mo_energy[1][mo_occ[1] == 0]) irhomob = ir_id2name[orbsymb[mo_energy[1] == ehomob][0]] irlumob = ir_id2name[orbsymb[mo_energy[1] == elumob][0]] logger.info(self, 'beta H**O (%s) = %.15g LUMO (%s) = %.15g', irhomob, ehomob, irlumob, elumob) ehomo = max(ehomoa, ehomob) elumo = min(elumoa, elumob) logger.debug(self, 'alpha irrep_nelec = %s', noccsa) logger.debug(self, 'beta irrep_nelec = %s', noccsb) hf_symm._dump_mo_energy(mol, mo_energy[0], mo_occ[0], ehomo, elumo, orbsyma, 'alpha-', verbose=self.verbose) hf_symm._dump_mo_energy(mol, mo_energy[1], mo_occ[1], ehomo, elumo, orbsymb, 'beta-', verbose=self.verbose) if mo_coeff is not None and self.verbose >= logger.DEBUG: ovlp_ao = self.get_ovlp() ss, s = self.spin_square((mo_coeff[0][:, mo_occ[0] > 0], mo_coeff[1][:, mo_occ[1] > 0]), ovlp_ao) logger.debug(self, 'multiplicity <S^2> = %.8g 2S+1 = %.8g', ss, s) return mo_occ