示例#1
0
def convert_to_rhf(mf, out=None):
    '''Convert the given mean-field object to the corresponding restricted
    HF/KS object
    '''
    from pyscf.pbc import scf
    from pyscf.pbc import dft

    def update_mo_(mf, mf1):
        _keys = mf._keys.union(mf1._keys)
        mf1.__dict__.update(mf.__dict__)
        mf1._keys = _keys
        if mf.mo_energy is not None:
            mf1.mo_energy = mf.mo_energy[0]
            mf1.mo_coeff = mf.mo_coeff[0]
            mf1.mo_occ = numpy.asarray(mf.mo_occ[0]) + numpy.asarray(
                mf.mo_occ[1])
        return mf1

    if out is not None:
        assert (isinstance(out, (scf.hf.RHF, scf.khf.KRHF)))
        if isinstance(mf, (scf.hf.RHF, scf.khf.KRHF)):
            out.__dict.__update(mf)
        else:  # UHF
            out = update_mo_(mf, out)
        return out

    else:
        scf_class = {
            scf.uhf.UHF: scf.hf.RHF,
            scf.kuhf.KUHF: scf.khf.KRHF,
            dft.uks.UKS: dft.rks.RKS,
            dft.kuks.KUKS: dft.krks.KRKS
        }

        if isinstance(mf, (scf.hf.RHF, scf.khf.KRHF)):
            out = copy.copy(mf)

        elif mf.__class__ in scf_class:
            out = update_mo_(mf, scf_class[mf.__class__](mf.cell))

        else:
            msg = ('Warn: Converting a decorated UHF object to the decorated '
                   'RHF object is unsafe.\nIt is recommended to create a '
                   'decorated RHF object explicitly and pass it to '
                   'convert_to_rhf function eg:\n'
                   '    convert_to_rhf(mf, out=density_fit(scf.RHF(cell)))\n')
            sys.stderr.write(msg)
            # Python resolve the subclass inheritance dynamically based on MRO.  We can
            # change the subclass inheritance order to substitute RHF/RKS with UHF/UKS.
            mro = mf.__class__.__mro__
            mronew = None
            for i, cls in enumerate(mro):
                if cls in scf_class:
                    mronew = mro[:i] + scf_class[cls].__mro__
                    break
            if mronew is None:
                raise RuntimeError('%s object is not SCF object')
            out = update_mo_(mf, lib.overwrite_mro(mf, mronew))

        return out
示例#2
0
def convert_to_rhf(mf, out=None, convert_df=None):
    '''Convert the given mean-field object to the corresponding restricted
    HF/KS object

    Args:
        mf : SCF object

    Kwargs
        convert_df : bool
            Whether to convert the DF-SCF object to the normal SCF object.
            This conversion is not applied by default.

    Returns:
        An unrestricted SCF object
    '''
    from pyscf import scf
    from pyscf import dft

    def update_mo_(mf, mf1):
        _keys = mf._keys.union(mf1._keys)
        mf1.__dict__.update(mf.__dict__)
        mf1._keys = _keys
        if mf.mo_energy is not None:
            mf1.mo_energy = mf.mo_energy[0]
            mf1.mo_coeff = mf.mo_coeff[0]
            mf1.mo_occ = mf.mo_occ[0] + mf.mo_occ[1]
        return mf1

    if out is not None:
        assert (isinstance(out, scf.hf.RHF))
        if isinstance(mf, scf.hf.RHF):
            out.__dict.__update(mf)
        else:  # UHF
            out = update_mo_(mf, out)

    else:
        hf_class = {
            scf.uhf.UHF: scf.rohf.ROHF,
            scf.uhf_symm.UHF: scf.hf_symm.ROHF
        }
        dft_class = {
            dft.uks.UKS: dft.roks.ROKS,
            dft.uks_symm.UKS: dft.rks_symm.ROKS
        }

        if isinstance(mf, scf.hf.RHF):
            out = copy.copy(mf)

        elif mf.__class__ in hf_class:
            out = update_mo_(mf, scf.RHF(mf.mol))

        elif mf.__class__ in dft_class:
            out = update_mo_(mf, dft.RKS(mf.mol))

        else:
            msg = ('Warn: Converting a decorated UHF object to the decorated '
                   'RHF object is unsafe.\nIt is recommended to create a '
                   'decorated RHF object explicitly and pass it to '
                   'convert_to_rhf function eg:\n'
                   '    convert_to_rhf(mf, out=scf.RHF(mol).density_fit())\n')
            sys.stderr.write(msg)
            # Python resolve the subclass inheritance dynamically based on MRO.  We can
            # change the subclass inheritance order to substitute RHF/RKS with UHF/UKS.
            mro = mf.__class__.__mro__
            mronew = None
            for i, cls in enumerate(mro):
                if cls in hf_class:
                    mronew = mro[:i] + hf_class[cls].__mro__
                    break
                elif cls in dft_class:
                    mronew = mro[:i] + dft_class[cls].__mro__
                    break
            if mronew is None:
                raise RuntimeError('%s object is not SCF object')
            out = update_mo_(mf, lib.overwrite_mro(mf, mronew))

    if convert_df is None:
        if isinstance(mf, scf.newton_ah._CIAH_SCF):
            # To handle the case that mf is newton scf with approximate orbital hessian
            if hasattr(mf._scf, 'with_df') and mf._scf.with_df:
                convert_df = False
            else:
                # The mf should not be treated as DFHF since the underlying
                # scf object is regular SCF object
                convert_df = True
        else:
            convert_df = False
    if convert_df and getattr(out, 'with_df', None):
        out.with_df = False

    return out
示例#3
0
def convert_to_rhf(mf, out=None):
    '''Convert the given mean-field object to the corresponding restricted
    HF/KS object
    '''
    from pyscf import scf
    from pyscf import dft
    def update_mo_(mf, mf1):
        _keys = mf._keys.union(mf1._keys)
        mf1.__dict__.update(mf.__dict__)
        mf1._keys = _keys
        if mf.mo_energy is not None:
            mf1.mo_energy = mf.mo_energy[0]
            mf1.mo_coeff =  mf.mo_coeff[0]
            mf1.mo_occ = mf.mo_occ[0] + mf.mo_occ[1]
        return mf1

    if out is not None:
        assert(isinstance(out, scf.hf.RHF))
        if isinstance(mf, scf.hf.RHF):
            out.__dict.__update(mf)
        else:  # UHF
            out = update_mo_(mf, out)
        return out

    else:
        hf_class = {scf.uhf.UHF      : scf.rohf.ROHF,
                    scf.uhf_symm.UHF : scf.hf_symm.ROHF}
        dft_class = {dft.uks.UKS     : dft.roks.ROKS,
                     dft.uks_symm.UKS: dft.rks_symm.ROKS}

        if isinstance(mf, scf.hf.RHF):
            out = copy.copy(mf)

        elif mf.__class__ in hf_class:
            out = update_mo_(mf, scf.RHF(mf.mol))

        elif mf.__class__ in dft_class:
            out = update_mo_(mf, dft.RKS(mf.mol))

        else:
            msg =('Warn: Converting a decorated UHF object to the decorated '
                  'RHF object is unsafe.\nIt is recommended to create a '
                  'decorated RHF object explicitly and pass it to '
                  'convert_to_rhf function eg:\n'
                  '    convert_to_rhf(mf, out=density_fit(scf.RHF(mol)))\n')
            sys.stderr.write(msg)
# Python resolve the subclass inheritance dynamically based on MRO.  We can
# change the subclass inheritance order to substitute RHF/RKS with UHF/UKS.
            mro = mf.__class__.__mro__
            mronew = None
            for i, cls in enumerate(mro):
                if cls in hf_class:
                    mronew = mro[:i] + hf_class[cls].__mro__
                    break
                elif cls in dft_class:
                    mronew = mro[:i] + dft_class[cls].__mro__
                    break
            if mronew is None:
                raise RuntimeError('%s object is not SCF object')
            out = update_mo_(mf, lib.overwrite_mro(mf, mronew))

        return out
示例#4
0
def convert_to_uhf(mf, out=None):
    '''Convert the given mean-field object to the corresponding unrestricted
    HF/KS object
    '''
    from pyscf import scf
    from pyscf import dft

    def update_mo_(mf, mf1):
        _keys = mf._keys.union(mf1._keys)
        mf1.__dict__.update(mf.__dict__)
        mf1._keys = _keys
        if mf.mo_energy is not None:
            mf1.mo_energy = numpy.array((mf.mo_energy, mf.mo_energy))
            mf1.mo_coeff = numpy.array((mf.mo_coeff, mf.mo_coeff))
            mf1.mo_occ = numpy.array((mf.mo_occ > 0, mf.mo_occ == 2),
                                     dtype=numpy.double)
        return mf1

    if out is not None:
        assert (isinstance(out, scf.uhf.UHF))
        if isinstance(mf, scf.uhf.UHF):
            out.__dict.__update(mf)
        else:  # RHF
            out = update_mo_(mf, out)
        return out

    else:
        hf_class = {
            scf.hf.RHF: scf.uhf.UHF,
            scf.rohf.ROHF: scf.uhf.UHF,
            scf.hf_symm.RHF: scf.uhf_symm.UHF,
            scf.hf_symm.ROHF: scf.uhf_symm.UHF
        }
        dft_class = {
            dft.rks.RKS: dft.uks.UKS,
            dft.roks.ROKS: dft.uks.UKS,
            dft.rks_symm.RKS: dft.uks_symm.UKS,
            dft.rks_symm.ROKS: dft.uks_symm.UKS
        }

        if isinstance(mf, scf.uhf.UHF):
            out = copy.copy(mf)

        elif mf.__class__ in hf_class:
            out = update_mo_(mf, scf.UHF(mf.mol))

        elif mf.__class__ in dft_class:
            out = update_mo_(mf, dft.UKS(mf.mol))

        else:
            msg = ('Warn: Converting a decorated RHF object to the decorated '
                   'UHF object is unsafe.\nIt is recommended to create a '
                   'decorated UHF object explicitly and pass it to '
                   'convert_to_uhf function eg:\n'
                   '    convert_to_uhf(mf, out=density_fit(scf.UHF(mol)))\n')
            sys.stderr.write(msg)
            # Python resolve the subclass inheritance dynamically based on MRO.  We can
            # change the subclass inheritance order to substitute RHF/RKS with UHF/UKS.
            mro = mf.__class__.__mro__
            mronew = None
            for i, cls in enumerate(mro):
                if cls in hf_class:
                    mronew = mro[:i] + hf_class[cls].__mro__
                    break
                elif cls in dft_class:
                    mronew = mro[:i] + dft_class[cls].__mro__
                    break
            if mronew is None:
                raise RuntimeError('%s object is not SCF object')
            out = update_mo_(mf, lib.overwrite_mro(mf, mronew))

        return out