Example #1
0
    def get_occ(self, mo_energy=None, mo_coeff=None, orbsym=None):
        if mo_energy is None: mo_energy = self.mo_energy
        mol = self.mol
        if mo_coeff is None or self._focka_ao is None:
            mo_ea = mo_eb = mo_energy
        else:
            mo_ea = numpy.einsum('ik,ik->k', mo_coeff,
                                 self._focka_ao.dot(mo_coeff))
            mo_eb = numpy.einsum('ik,ik->k', mo_coeff,
                                 self._fockb_ao.dot(mo_coeff))
        nmo = mo_ea.size
        mo_occ = numpy.zeros(nmo)
        if orbsym is None:
            if mo_coeff is not None:
                orbsym = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                             mo_coeff, self.get_ovlp(), False)
                orbsym = numpy.asarray(orbsym)
            else:
                orbsym = [
                    numpy.repeat(ir, mol.symm_orb[i].shape[1])
                    for i, ir in enumerate(mol.irrep_id)
                ]
                orbsym = numpy.hstack(orbsym)
        else:
            orbsym = numpy.asarray(orbsym)
        assert (mo_energy.size == orbsym.size)

        float_idx = []
        neleca_fix = 0
        nelecb_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:
                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]
                mo_occ[ir_idx] = rohf._fill_rohf_occ(mo_energy[ir_idx],
                                                     mo_ea[ir_idx],
                                                     mo_eb[ir_idx], nelecb,
                                                     neleca - nelecb)
                neleca_fix += neleca
                nelecb_fix += nelecb
            else:
                float_idx.append(ir_idx)

        nelec_float = mol.nelectron - neleca_fix - nelecb_fix
        assert (nelec_float >= 0)
        if len(float_idx) > 0:
            float_idx = numpy.hstack(float_idx)
            nopen = mol.spin - (neleca_fix - nelecb_fix)
            ncore = (nelec_float - nopen) // 2
            mo_occ[float_idx] = rohf._fill_rohf_occ(mo_energy[float_idx],
                                                    mo_ea[float_idx],
                                                    mo_eb[float_idx], ncore,
                                                    nopen)

        ncore = self.nelec[1]
        nocc = self.nelec[0]
        nopen = nocc - ncore
        vir_idx = (mo_occ == 0)
        if self.verbose >= logger.INFO and nocc < nmo and ncore > 0:
            ehomo = max(mo_energy[mo_occ > 0])
            elumo = min(mo_energy[mo_occ == 0])
            ndoccs = []
            nsoccs = []
            for i, ir in enumerate(mol.irrep_id):
                irname = mol.irrep_name[i]
                ir_idx = (orbsym == ir)

                ndoccs.append(numpy.count_nonzero(mo_occ[ir_idx] == 2))
                nsoccs.append(numpy.count_nonzero(mo_occ[ir_idx] == 1))
                if ehomo in mo_energy[ir_idx]:
                    irhomo = irname
                if elumo in mo_energy[ir_idx]:
                    irlumo = irname

            # to help self.eigh compute orbital energy
            self._irrep_doccs = ndoccs
            self._irrep_soccs = nsoccs

            logger.info(self, 'H**O (%s) = %.15g  LUMO (%s) = %.15g', irhomo,
                        ehomo, irlumo, elumo)

            logger.debug(self, 'double occ irrep_nelec = %s', ndoccs)
            logger.debug(self, 'single occ irrep_nelec = %s', nsoccs)
            #_dump_mo_energy(mol, mo_energy, mo_occ, ehomo, elumo, orbsym,
            #                verbose=self.verbose)
            if nopen > 0:
                core_idx = mo_occ == 2
                open_idx = mo_occ == 1
                vir_idx = mo_occ == 0
                logger.debug(
                    self,
                    '                  Roothaan           | alpha              | beta'
                )
                logger.debug(self,
                             '  Highest 2-occ = %18.15g | %18.15g | %18.15g',
                             max(mo_energy[core_idx]), max(mo_ea[core_idx]),
                             max(mo_eb[core_idx]))
                logger.debug(self,
                             '  Lowest 0-occ =  %18.15g | %18.15g | %18.15g',
                             min(mo_energy[vir_idx]), min(mo_ea[vir_idx]),
                             min(mo_eb[vir_idx]))
                for i in numpy.where(open_idx)[0]:
                    logger.debug(
                        self, '  1-occ =         %18.15g | %18.15g | %18.15g',
                        mo_energy[i], mo_ea[i], mo_eb[i])

            numpy.set_printoptions(threshold=nmo)
            logger.debug(self, '  Roothaan mo_energy =\n%s', mo_energy)
            logger.debug1(self, '  alpha mo_energy =\n%s', mo_ea)
            logger.debug1(self, '  beta  mo_energy =\n%s', mo_eb)
            numpy.set_printoptions(threshold=1000)
        return mo_occ
Example #2
0
    def get_occ(self, mo_energy=None, mo_coeff=None, orbsym=None):
        if mo_energy is None: mo_energy = self.mo_energy
        mol = self.mol
        if mo_coeff is None or self._focka_ao is None:
            mo_ea = mo_eb = mo_energy
        else:
            mo_ea = numpy.einsum('ik,ik->k', mo_coeff, self._focka_ao.dot(mo_coeff))
            mo_eb = numpy.einsum('ik,ik->k', mo_coeff, self._fockb_ao.dot(mo_coeff))
        nmo = mo_ea.size
        mo_occ = numpy.zeros(nmo)
        if orbsym is None:
            if mo_coeff is not None:
                orbsym = symm.label_orb_symm(self, mol.irrep_id, mol.symm_orb,
                                             mo_coeff, self.get_ovlp(), False)
                orbsym = numpy.asarray(orbsym)
            else:
                orbsym = [numpy.repeat(ir, mol.symm_orb[i].shape[1])
                          for i, ir in enumerate(mol.irrep_id)]
                orbsym = numpy.hstack(orbsym)
        else:
            orbsym = numpy.asarray(orbsym)
        assert(mo_energy.size == orbsym.size)

        float_idx = []
        neleca_fix = 0
        nelecb_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:
                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]
                mo_occ[ir_idx] = rohf._fill_rohf_occ(mo_energy[ir_idx],
                                                     mo_ea[ir_idx], mo_eb[ir_idx],
                                                     nelecb, neleca-nelecb)
                neleca_fix += neleca
                nelecb_fix += nelecb
            else:
                float_idx.append(ir_idx)

        nelec_float = mol.nelectron - neleca_fix - nelecb_fix
        assert(nelec_float >= 0)
        if len(float_idx) > 0:
            float_idx = numpy.hstack(float_idx)
            nopen = mol.spin - (neleca_fix - nelecb_fix)
            ncore = (nelec_float - nopen)//2
            mo_occ[float_idx] = rohf._fill_rohf_occ(mo_energy[float_idx],
                                                    mo_ea[float_idx],
                                                    mo_eb[float_idx],
                                                    ncore, nopen)

        ncore = self.nelec[1]
        nocc  = self.nelec[0]
        nopen = nocc - ncore
        vir_idx = (mo_occ==0)
        if self.verbose >= logger.INFO and nocc < nmo and ncore > 0:
            ehomo = max(mo_energy[mo_occ> 0])
            elumo = min(mo_energy[mo_occ==0])
            ndoccs = []
            nsoccs = []
            for i, ir in enumerate(mol.irrep_id):
                irname = mol.irrep_name[i]
                ir_idx = (orbsym == ir)

                ndoccs.append(numpy.count_nonzero(mo_occ[ir_idx]==2))
                nsoccs.append(numpy.count_nonzero(mo_occ[ir_idx]==1))
                if ehomo in mo_energy[ir_idx]:
                    irhomo = irname
                if elumo in mo_energy[ir_idx]:
                    irlumo = irname

            # to help self.eigh compute orbital energy
            self._irrep_doccs = ndoccs
            self._irrep_soccs = nsoccs

            logger.info(self, 'H**O (%s) = %.15g  LUMO (%s) = %.15g',
                        irhomo, ehomo, irlumo, elumo)

            logger.debug(self, 'double occ irrep_nelec = %s', ndoccs)
            logger.debug(self, 'single occ irrep_nelec = %s', nsoccs)
            #_dump_mo_energy(mol, mo_energy, mo_occ, ehomo, elumo, orbsym,
            #                verbose=self.verbose)
            if nopen > 0:
                core_idx = mo_occ == 2
                open_idx = mo_occ == 1
                vir_idx = mo_occ == 0
                logger.debug(self, '                  Roothaan           | alpha              | beta')
                logger.debug(self, '  Highest 2-occ = %18.15g | %18.15g | %18.15g',
                             max(mo_energy[core_idx]),
                             max(mo_ea[core_idx]), max(mo_eb[core_idx]))
                logger.debug(self, '  Lowest 0-occ =  %18.15g | %18.15g | %18.15g',
                             min(mo_energy[vir_idx]),
                             min(mo_ea[vir_idx]), min(mo_eb[vir_idx]))
                for i in numpy.where(open_idx)[0]:
                    logger.debug(self, '  1-occ =         %18.15g | %18.15g | %18.15g',
                                 mo_energy[i], mo_ea[i], mo_eb[i])

            numpy.set_printoptions(threshold=nmo)
            logger.debug(self, '  Roothaan mo_energy =\n%s', mo_energy)
            logger.debug1(self, '  alpha mo_energy =\n%s', mo_ea)
            logger.debug1(self, '  beta  mo_energy =\n%s', mo_eb)
            numpy.set_printoptions(threshold=1000)
        return mo_occ
Example #3
0
    def get_occ(self, mo_energy=None, mo_coeff=None):
        if mo_energy is None: mo_energy = self.mo_energy
        mol = self.mol
        if not self.mol.symmetry:
            return rohf.ROHF.get_occ(self, mo_energy, mo_coeff)

        if hasattr(mo_energy, 'mo_ea'):
            mo_ea = mo_energy.mo_ea
            mo_eb = mo_energy.mo_eb
        else:
            mo_ea = mo_eb = mo_energy
        nmo = mo_ea.size
        mo_occ = numpy.zeros(nmo)

        orbsym = get_orbsym(self.mol, mo_coeff)

        rest_idx = numpy.ones(mo_occ.size, dtype=bool)
        neleca_fix = 0
        nelecb_fix = 0
        for i, ir in enumerate(mol.irrep_id):
            irname = mol.irrep_name[i]
            if irname in self.irrep_nelec:
                ir_idx = numpy.where(orbsym == ir)[0]
                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]
                mo_occ[ir_idx] = rohf._fill_rohf_occ(mo_energy[ir_idx],
                                                     mo_ea[ir_idx],
                                                     mo_eb[ir_idx], nelecb,
                                                     neleca - nelecb)
                neleca_fix += neleca
                nelecb_fix += nelecb
                rest_idx[ir_idx] = False

        nelec_float = mol.nelectron - neleca_fix - nelecb_fix
        assert (nelec_float >= 0)
        if len(rest_idx) > 0:
            rest_idx = numpy.where(rest_idx)[0]
            nopen = mol.spin - (neleca_fix - nelecb_fix)
            ncore = (nelec_float - nopen) // 2
            mo_occ[rest_idx] = rohf._fill_rohf_occ(mo_energy[rest_idx],
                                                   mo_ea[rest_idx],
                                                   mo_eb[rest_idx], ncore,
                                                   nopen)

        if self.nelec is None:
            nelec = self.mol.nelec
        else:
            nelec = self.nelec
        ncore = nelec[1]
        nocc = nelec[0]
        nopen = nocc - ncore
        vir_idx = (mo_occ == 0)
        if self.verbose >= logger.INFO and nocc < nmo and ncore > 0:
            ehomo = max(mo_energy[~vir_idx])
            elumo = min(mo_energy[vir_idx])
            ndoccs = []
            nsoccs = []
            for i, ir in enumerate(mol.irrep_id):
                irname = mol.irrep_name[i]
                ir_idx = (orbsym == ir)

                ndoccs.append(numpy.count_nonzero(mo_occ[ir_idx] == 2))
                nsoccs.append(numpy.count_nonzero(mo_occ[ir_idx] == 1))
                if ehomo in mo_energy[ir_idx]:
                    irhomo = irname
                if elumo in mo_energy[ir_idx]:
                    irlumo = irname

            # to help self.eigh compute orbital energy
            self._irrep_doccs = ndoccs
            self._irrep_soccs = nsoccs

            logger.info(self, 'H**O (%s) = %.15g  LUMO (%s) = %.15g', irhomo,
                        ehomo, irlumo, elumo)

            logger.debug(self, 'double occ irrep_nelec = %s', ndoccs)
            logger.debug(self, 'single occ irrep_nelec = %s', nsoccs)
            #_dump_mo_energy(mol, mo_energy, mo_occ, ehomo, elumo, orbsym,
            #                verbose=self.verbose)
            if nopen > 0:
                core_idx = mo_occ == 2
                open_idx = mo_occ == 1
                vir_idx = mo_occ == 0
                logger.debug(
                    self,
                    '                  Roothaan           | alpha              | beta'
                )
                logger.debug(self,
                             '  Highest 2-occ = %18.15g | %18.15g | %18.15g',
                             max(mo_energy[core_idx]), max(mo_ea[core_idx]),
                             max(mo_eb[core_idx]))
                logger.debug(self,
                             '  Lowest 0-occ =  %18.15g | %18.15g | %18.15g',
                             min(mo_energy[vir_idx]), min(mo_ea[vir_idx]),
                             min(mo_eb[vir_idx]))
                for i in numpy.where(open_idx)[0]:
                    logger.debug(
                        self, '  1-occ =         %18.15g | %18.15g | %18.15g',
                        mo_energy[i], mo_ea[i], mo_eb[i])

            numpy.set_printoptions(threshold=nmo)
            logger.debug(self, '  Roothaan mo_energy =\n%s', mo_energy)
            logger.debug1(self, '  alpha mo_energy =\n%s', mo_ea)
            logger.debug1(self, '  beta  mo_energy =\n%s', mo_eb)
            numpy.set_printoptions(threshold=1000)
        return mo_occ