Beispiel #1
0
def rotate_orb_cc(casscf,
                  mo,
                  fcasdm1,
                  fcasdm2,
                  eris,
                  x0_guess=None,
                  conv_tol_grad=1e-4,
                  max_stepsize=None,
                  verbose=None):
    if isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(casscf.stdout, casscf.verbose)
    if max_stepsize is None:
        max_stepsize = casscf.max_stepsize

    t3m = (time.clock(), time.time())
    u = 1
    g_orb, gorb_update, h_op, h_diag = \
            casscf.gen_g_hop(mo, u, fcasdm1(), fcasdm2(), eris)
    g_kf0 = g_kf = g_orb
    norm_gkf0 = norm_gkf = norm_gorb = numpy.linalg.norm(g_orb)
    log.debug('    |g|=%5.3g', norm_gorb)
    t3m = log.timer('gen h_op', *t3m)

    def precond(x, e):
        if callable(h_diag):
            x = h_diag(x, e - casscf.ah_level_shift)
        else:
            hdiagd = h_diag - (e - casscf.ah_level_shift)
            hdiagd[abs(hdiagd) < 1e-8] = 1e-8
            x = x / hdiagd
        norm_x = numpy.linalg.norm(x)
        x *= 1 / norm_x
        #if norm_x < 1e-2:
        #    x *= 1e-2/norm_x
        return x


# Dynamically increase the number of micro cycles when approach convergence?
#    if norm_gorb < 0.01:
#        max_cycle = casscf.max_cycle_micro_inner-int(numpy.log10(norm_gorb+1e-9))
#    else:
#        max_cycle = casscf.max_cycle_micro_inner

    max_cycle = casscf.max_cycle_micro_inner
    dr = 0
    jkcount = 0
    norm_dr = 0
    if x0_guess is None:
        x0_guess = g_orb
    ah_conv_tol = casscf.ah_conv_tol
    #ah_start_cycle = max(casscf.ah_start_cycle, int(-numpy.log10(norm_gorb)))
    ah_start_cycle = casscf.ah_start_cycle
    while True:
        # increase the AH accuracy when approach convergence
        ah_start_tol = min(norm_gorb * casscf.ah_grad_trust_region,
                           casscf.ah_start_tol)
        log.debug1('Set ah_start_tol %g, ah_start_cycle %d, max_cycle %d',
                   ah_start_tol, ah_start_cycle, max_cycle)
        g_orb0 = g_orb
        imic = 0

        g_op = lambda: g_orb

        for ah_end, ihop, w, dxi, hdxi, residual, seig \
                in iah.davidson_cc(h_op, g_op, precond, x0_guess,
                                   tol=ah_conv_tol, max_cycle=casscf.ah_max_cycle,
                                   lindep=casscf.ah_lindep, verbose=log):
            # residual = v[0] * (g+(h-e)x) ~ v[0] * grad
            norm_residual = numpy.linalg.norm(residual)
            if (ah_end or ihop == casscf.ah_max_cycle
                    or  # make sure to use the last step
                ((norm_residual < ah_start_tol) and
                 (ihop >= ah_start_cycle)) or (seig < casscf.ah_lindep)):
                imic += 1
                dxmax = numpy.max(abs(dxi))
                if dxmax > max_stepsize:
                    scale = max_stepsize / dxmax
                    log.debug1('... scale rotation size %g', scale)
                    dxi *= scale
                    hdxi *= scale
                else:
                    scale = None

                g_orb = g_orb + hdxi
                dr = dr + dxi
                norm_gorb0, norm_gorb = norm_gorb, numpy.linalg.norm(g_orb)
                norm_dxi = numpy.linalg.norm(dxi)
                norm_dr = numpy.linalg.norm(dr)
                log.debug(
                    '    imic %d(%d)  |g[o]|=%5.3g  |dxi|=%5.3g  '
                    'max(|x|)=%5.3g  |dr|=%5.3g  eig=%5.3g  seig=%5.3g', imic,
                    ihop, norm_gorb, norm_dxi, dxmax, norm_dr, w, seig)

                if imic > 1 and norm_gorb > norm_gkf * casscf.ah_grad_trust_region:
                    break

                elif (imic >= max_cycle or norm_gorb < conv_tol_grad * .3):
                    break

        u = casscf.update_rotate_matrix(dr)
        jkcount += ihop
        gorb_update = h_op = h_diag = None
        t3m = log.timer('aug_hess in %d inner iters' % imic, *t3m)

        yield u, g_orb0, jkcount

        t3m = (time.clock(), time.time())
        g_kf1, gorb_update, h_op, h_diag = \
                casscf.gen_g_hop(mo, u, fcasdm1(), fcasdm2(), eris)
        g_kf1 = gorb_update(u, casscf.with_dep4)
        jkcount += 1

        norm_gkf1 = numpy.linalg.norm(g_kf1)
        norm_dg = numpy.linalg.norm(g_kf1 - g_orb)
        log.debug('    |g|=%5.3g (keyframe), |g-correction|=%5.3g', norm_gkf1,
                  norm_dg)
        #
        # Special treatment if out of trust region
        #
        if (norm_dg > norm_gorb * casscf.ah_grad_trust_region
                and norm_gkf1 > norm_gkf
                and norm_gkf1 > norm_gkf0 * casscf.ah_grad_trust_region):
            log.debug(
                '    Keyframe |g|=%5.3g  |g_last| =%5.3g out of trust region',
                norm_gkf1, norm_gorb)
            if ((not casscf.with_dep4 and norm_gkf > 5e-4) or
                (hasattr(casscf._scf, 'with_df') and casscf._scf.with_df)
                    or isinstance(casscf._scf, scf.uhf.UHF)):
                #TODO:  transformation for DF integrals
                u = casscf.update_rotate_matrix(dr - dxi)
                yield u, g_kf - hdxi, jkcount
                break
            else:
                g_kf1 = gorb_update(u, True)
                jkcount += 1
                norm_gkf1 = numpy.linalg.norm(g_kf1)
                norm_dg = numpy.linalg.norm(g_kf1 - g_orb)
                log.debug(
                    'With dep4 |g|=%5.3g (keyframe), |g-correction|=%5.3g',
                    norm_gkf1, norm_dg)
        t3m = log.timer('gen h_op', *t3m)
        g_orb = g_kf = g_kf1
        norm_gorb = norm_gkf = norm_gkf1
        x0_guess = dxi
        ah_start_cycle -= 1
Beispiel #2
0
def rotate_orb_cc(mf, mo_coeff, mo_occ, fock_ao, h1e,
                  conv_tol_grad=None, verbose=None):
    from pyscf.scf import iah
    if isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(mf.stdout, mf.verbose)

    if conv_tol_grad is None:
        conv_tol_grad = numpy.sqrt(mf.conv_tol*.1)

    t2m = (time.clock(), time.time())
    if isinstance(mo_coeff, numpy.ndarray) and mo_coeff.ndim == 2:
        nmo = mo_coeff.shape[1]
    else:
        nmo = mo_coeff[0].shape[1]
    g_orb, h_op, h_diag = mf.gen_g_hop(mo_coeff, mo_occ, fock_ao)
    g_kf = g_orb
    norm_gkf = norm_gorb = numpy.linalg.norm(g_orb)
    log.debug('    |g|= %4.3g (keyframe)', norm_gorb)
    t3m = log.timer('gen h_op', *t2m)

    def precond(x, e):
        hdiagd = h_diag-(e-mf.ah_level_shift)
        hdiagd[abs(hdiagd)<1e-8] = 1e-8
        x = x/hdiagd
## Because of DFT, donot norm to 1 which leads 1st DM too large.
#        norm_x = numpy.linalg.norm(x)
#        if norm_x < 1e-2:
#            x *= 1e-2/norm_x
        return x

    kf_compensate = 0
    kf_trust_region = 0.25
    g_op = lambda: g_orb
    x0_guess = g_orb
    while True:
        ah_conv_tol = min(norm_gorb**2, mf.ah_conv_tol)
        # increase the AH accuracy when approach convergence
        ah_start_tol = min(norm_gorb*5, mf.ah_start_tol)
        #ah_start_cycle = max(mf.ah_start_cycle, int(-numpy.log10(norm_gorb)))
        ah_start_cycle = mf.ah_start_cycle
        g_orb0 = g_orb
        imic = 0
        dr = 0
        jkcount = 0
        ikf = 0
        dm0 = mf.make_rdm1(mo_coeff, mo_occ)
        vhf0 = fock_ao - h1e

        for ah_end, ihop, w, dxi, hdxi, residual, seig \
                in iah.davidson_cc(h_op, g_op, precond, x0_guess,
                                   tol=ah_conv_tol, max_cycle=mf.ah_max_cycle,
                                   lindep=mf.ah_lindep, verbose=log):
            norm_residual = numpy.linalg.norm(residual)
            if (ah_end or ihop == mf.ah_max_cycle or # make sure to use the last step
                ((norm_residual < ah_start_tol) and (ihop >= ah_start_cycle)) or
                (seig < mf.ah_lindep)):
                imic += 1
                dxmax = numpy.max(abs(dxi))
                if dxmax > mf.max_stepsize * max(1,norm_gorb):
                    scale = mf.max_stepsize * max(1,norm_gorb) / dxmax
                    log.debug1('... scale rotation size %g', scale)
                    dxi *= scale
                    hdxi *= scale
                else:
                    scale = None

                dr = dr + dxi
                g_orb = g_orb + hdxi
                norm_dr = numpy.linalg.norm(dr)
                norm_gorb = numpy.linalg.norm(g_orb)
                norm_dxi = numpy.linalg.norm(dxi)
                log.debug('    imic %d(%d)  |g|= %4.3g  |dxi|= %4.3g  '
                          'max(|x|)= %4.3g  |dr|= %4.3g  eig= %4.3g  seig= %4.3g',
                          imic, ihop, norm_gorb, norm_dxi,
                          dxmax, norm_dr, w, seig)

                max_cycle = mf.max_cycle_inner-int(numpy.log(norm_gkf+1e-9)*2)
                log.debug1('Set ah_start_tol %g, ah_start_cycle %d, max_cycle %d',
                           ah_start_tol, ah_start_cycle, max_cycle)
                ikf += 1
                if imic > 3 and norm_gorb > norm_gkf*mf.ah_grad_trust_region:
                    g_orb = g_orb - hdxi
                    dr = dr - dxi
                    norm_gorb = numpy.linalg.norm(g_orb)
                    log.debug('|g| >> keyframe, Restore previouse step')
                    break

                elif (imic >= max_cycle or norm_gorb < conv_tol_grad*.5):
                    break

                elif (ikf > 2 and # avoid frequent keyframe
                      (ikf > (mf.keyframe_interval - kf_compensate
                              -numpy.log(norm_dr)*mf.keyframe_interval_rate) or
                       norm_gorb < norm_gkf*kf_trust_region)):
                    ikf = 0
                    u = mf.update_rotate_matrix(dr, mo_occ)
                    mo1 = mf.rotate_mo(mo_coeff, u)
                    dm = mf.make_rdm1(mo1, mo_occ)
# use mf._scf.get_veff to avoid density-fit mf polluting get_veff
                    vhf0 = mf._scf.get_veff(mf._scf.mol, dm, dm_last=dm0, vhf_last=vhf0)
                    dm0 = dm
                    g_kf1 = mf.get_grad(mo1, mo_occ, h1e+vhf0)
                    norm_gkf1 = numpy.linalg.norm(g_kf1)
                    norm_dg = numpy.linalg.norm(g_kf1-g_orb)
                    jkcount += 1
                    log.debug('Adjust keyframe g_orb to |g|= %4.3g  '
                              '|g-correction|= %4.3g', norm_gkf1, norm_dg)
# kf_compensate:  If the keyframe and the esitimated g_orb are too different,
# insert more keyframes for the following optimization
                    kf_compensate = norm_dg / norm_gorb
                    if (kf_compensate > mf.ah_grad_trust_region and
                        norm_gkf1 > norm_gkf and
                        # More iters when close to local minimum
                        norm_gkf1 > conv_tol_grad*mf.ah_grad_trust_region):
                        g_orb = g_orb - hdxi
                        dr = dr - dxi
                        norm_gorb = numpy.linalg.norm(g_orb)
                        log.debug('Out of trust region. Restore previouse step')
                        break
                    else:
                        kf_trust_region = max(min(kf_compensate, 0.25), .05)
                        log.debug1('... kf_compensate = %g  kf_trust_region = %g',
                                   kf_compensate, kf_trust_region)
                        g_orb = g_kf = g_kf1
                        norm_gorb = norm_gkf = norm_gkf1


        u = mf.update_rotate_matrix(dr, mo_occ)
        jkcount += ihop + 1
        log.debug('    tot inner=%d  %d JK  |g|= %4.3g  |u-1|= %4.3g',
                  imic, jkcount, norm_gorb,
                  numpy.linalg.norm(u-numpy.eye(nmo)))
        h_op = h_diag = None
        t3m = log.timer('aug_hess in %d inner iters' % imic, *t3m)
        mo_coeff, mo_occ, fock_ao = (yield u, g_kf, jkcount)

        g_kf, h_op, h_diag = mf.gen_g_hop(mo_coeff, mo_occ, fock_ao)
        norm_gkf = numpy.linalg.norm(g_kf)
        norm_dg = numpy.linalg.norm(g_kf-g_orb)
        log.debug('    |g|= %4.3g (keyframe), |g-correction|= %4.3g',
                  norm_gkf, norm_dg)
        kf_compensate = norm_dg / norm_gorb
        kf_trust_region = max(min(kf_compensate, 0.25), .05)
        log.debug1('... kf_compensate = %g  kf_trust_region = %g',
                   kf_compensate, kf_trust_region)
        g_orb = g_kf
        norm_gorb = norm_gkf
        x0_guess = dxi
Beispiel #3
0
def rotate_orb_cc(mf,
                  mo_coeff,
                  mo_occ,
                  fock_ao,
                  h1e,
                  conv_tol_grad=None,
                  verbose=None):
    from pyscf.scf import iah
    if isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(mf.stdout, mf.verbose)

    if conv_tol_grad is None:
        conv_tol_grad = numpy.sqrt(mf.conv_tol * .1)

    t2m = (time.clock(), time.time())
    if isinstance(mo_coeff, numpy.ndarray) and mo_coeff.ndim == 2:
        nmo = mo_coeff.shape[1]
    else:
        nmo = mo_coeff[0].shape[1]
    g_orb, h_op, h_diag = mf.gen_g_hop(mo_coeff, mo_occ, fock_ao)
    g_kf = g_orb
    norm_gkf = norm_gorb = numpy.linalg.norm(g_orb)
    log.debug('    |g|= %4.3g (keyframe)', norm_gorb)
    t3m = log.timer('gen h_op', *t2m)

    def precond(x, e):
        hdiagd = h_diag - (e - mf.ah_level_shift)
        hdiagd[abs(hdiagd) < 1e-8] = 1e-8
        x = x / hdiagd
        ## Because of DFT, donot norm to 1 which leads 1st DM too large.
        #        norm_x = numpy.linalg.norm(x)
        #        if norm_x < 1e-2:
        #            x *= 1e-2/norm_x
        return x

    kf_compensate = 0
    kf_trust_region = 0.25
    g_op = lambda: g_orb
    x0_guess = g_orb
    while True:
        ah_conv_tol = min(norm_gorb**2, mf.ah_conv_tol)
        # increase the AH accuracy when approach convergence
        ah_start_tol = min(norm_gorb * 5, mf.ah_start_tol)
        #ah_start_cycle = max(mf.ah_start_cycle, int(-numpy.log10(norm_gorb)))
        ah_start_cycle = mf.ah_start_cycle
        g_orb0 = g_orb
        imic = 0
        dr = 0
        jkcount = 0
        ikf = 0
        dm0 = mf.make_rdm1(mo_coeff, mo_occ)
        vhf0 = fock_ao - h1e

        for ah_end, ihop, w, dxi, hdxi, residual, seig \
                in iah.davidson_cc(h_op, g_op, precond, x0_guess,
                                   tol=ah_conv_tol, max_cycle=mf.ah_max_cycle,
                                   lindep=mf.ah_lindep, verbose=log):
            norm_residual = numpy.linalg.norm(residual)
            if (ah_end or ihop == mf.ah_max_cycle
                    or  # make sure to use the last step
                ((norm_residual < ah_start_tol) and
                 (ihop >= ah_start_cycle)) or (seig < mf.ah_lindep)):
                imic += 1
                dxmax = numpy.max(abs(dxi))
                if dxmax > mf.max_stepsize * max(1, norm_gorb):
                    scale = mf.max_stepsize * max(1, norm_gorb) / dxmax
                    log.debug1('... scale rotation size %g', scale)
                    dxi *= scale
                    hdxi *= scale
                else:
                    scale = None

                dr = dr + dxi
                g_orb = g_orb + hdxi
                norm_dr = numpy.linalg.norm(dr)
                norm_gorb = numpy.linalg.norm(g_orb)
                norm_dxi = numpy.linalg.norm(dxi)
                log.debug(
                    '    imic %d(%d)  |g|= %4.3g  |dxi|= %4.3g  '
                    'max(|x|)= %4.3g  |dr|= %4.3g  eig= %4.3g  seig= %4.3g',
                    imic, ihop, norm_gorb, norm_dxi, dxmax, norm_dr, w, seig)

                max_cycle = mf.max_cycle_inner - int(
                    numpy.log(norm_gkf + 1e-9) * 2)
                log.debug1(
                    'Set ah_start_tol %g, ah_start_cycle %d, max_cycle %d',
                    ah_start_tol, ah_start_cycle, max_cycle)
                ikf += 1
                if imic > 3 and norm_gorb > norm_gkf * mf.ah_grad_trust_region:
                    g_orb = g_orb - hdxi
                    dr = dr - dxi
                    norm_gorb = numpy.linalg.norm(g_orb)
                    log.debug('|g| >> keyframe, Restore previouse step')
                    break

                elif (imic >= max_cycle or norm_gorb < conv_tol_grad * .5):
                    break

                elif (ikf > 2 and  # avoid frequent keyframe
                      (ikf > (mf.keyframe_interval - kf_compensate -
                              numpy.log(norm_dr) * mf.keyframe_interval_rate)
                       or norm_gorb < norm_gkf * kf_trust_region)):
                    ikf = 0
                    u = mf.update_rotate_matrix(dr, mo_occ)
                    mo1 = mf.rotate_mo(mo_coeff, u)
                    dm = mf.make_rdm1(mo1, mo_occ)
                    # use mf._scf.get_veff to avoid density-fit mf polluting get_veff
                    vhf0 = mf._scf.get_veff(mf._scf.mol,
                                            dm,
                                            dm_last=dm0,
                                            vhf_last=vhf0)
                    dm0 = dm
                    g_kf1 = mf.get_grad(mo1, mo_occ, h1e + vhf0)
                    norm_gkf1 = numpy.linalg.norm(g_kf1)
                    norm_dg = numpy.linalg.norm(g_kf1 - g_orb)
                    jkcount += 1
                    log.debug(
                        'Adjust keyframe g_orb to |g|= %4.3g  '
                        '|g-correction|= %4.3g', norm_gkf1, norm_dg)
                    # kf_compensate:  If the keyframe and the esitimated g_orb are too different,
                    # insert more keyframes for the following optimization
                    kf_compensate = norm_dg / norm_gorb
                    if (kf_compensate > mf.ah_grad_trust_region
                            and norm_gkf1 > norm_gkf and
                            # More iters when close to local minimum
                            norm_gkf1 >
                            conv_tol_grad * mf.ah_grad_trust_region):
                        g_orb = g_orb - hdxi
                        dr = dr - dxi
                        norm_gorb = numpy.linalg.norm(g_orb)
                        log.debug(
                            'Out of trust region. Restore previouse step')
                        break
                    else:
                        kf_trust_region = max(min(kf_compensate, 0.25), .05)
                        log.debug1(
                            '... kf_compensate = %g  kf_trust_region = %g',
                            kf_compensate, kf_trust_region)
                        g_orb = g_kf = g_kf1
                        norm_gorb = norm_gkf = norm_gkf1

        u = mf.update_rotate_matrix(dr, mo_occ)
        jkcount += ihop + 1
        log.debug('    tot inner=%d  %d JK  |g|= %4.3g  |u-1|= %4.3g', imic,
                  jkcount, norm_gorb, numpy.linalg.norm(u - numpy.eye(nmo)))
        h_op = h_diag = None
        t3m = log.timer('aug_hess in %d inner iters' % imic, *t3m)
        mo_coeff, mo_occ, fock_ao = (yield u, g_kf, jkcount)

        g_kf, h_op, h_diag = mf.gen_g_hop(mo_coeff, mo_occ, fock_ao)
        norm_gkf = numpy.linalg.norm(g_kf)
        norm_dg = numpy.linalg.norm(g_kf - g_orb)
        log.debug('    |g|= %4.3g (keyframe), |g-correction|= %4.3g', norm_gkf,
                  norm_dg)
        kf_compensate = norm_dg / norm_gorb
        kf_trust_region = max(min(kf_compensate, 0.25), .05)
        log.debug1('... kf_compensate = %g  kf_trust_region = %g',
                   kf_compensate, kf_trust_region)
        g_orb = g_kf
        norm_gorb = norm_gkf
        x0_guess = dxi
Beispiel #4
0
def rotate_orb_cc(casscf, mo, fcasdm1, fcasdm2, eris, x0_guess=None,
                  conv_tol_grad=1e-4, max_stepsize=None, verbose=None):
    if isinstance(verbose, logger.Logger):
        log = verbose
    else:
        log = logger.Logger(casscf.stdout, casscf.verbose)
    if max_stepsize is None:
        max_stepsize = casscf.max_stepsize

    t3m = (time.clock(), time.time())
    u = 1
    g_orb, gorb_update, h_op, h_diag = \
            casscf.gen_g_hop(mo, u, fcasdm1(), fcasdm2(), eris)
    g_kf0 = g_kf = g_orb
    norm_gkf0 = norm_gkf = norm_gorb = numpy.linalg.norm(g_orb)
    log.debug('    |g|=%5.3g', norm_gorb)
    t3m = log.timer('gen h_op', *t3m)

    def precond(x, e):
        if callable(h_diag):
            x = h_diag(x, e-casscf.ah_level_shift)
        else:
            hdiagd = h_diag-(e-casscf.ah_level_shift)
            hdiagd[abs(hdiagd)<1e-8] = 1e-8
            x = x/hdiagd
        norm_x = numpy.linalg.norm(x)
        x *= 1/norm_x
        #if norm_x < 1e-2:
        #    x *= 1e-2/norm_x
        return x

# Dynamically increase the number of micro cycles when approach convergence?
#    if norm_gorb < 0.01:
#        max_cycle = casscf.max_cycle_micro_inner-int(numpy.log10(norm_gorb+1e-9))
#    else:
#        max_cycle = casscf.max_cycle_micro_inner
    max_cycle = casscf.max_cycle_micro_inner
    dr = 0
    jkcount = 0
    norm_dr = 0
    if x0_guess is None:
        x0_guess = g_orb
    ah_conv_tol = casscf.ah_conv_tol
    #ah_start_cycle = max(casscf.ah_start_cycle, int(-numpy.log10(norm_gorb)))
    ah_start_cycle = casscf.ah_start_cycle
    while True:
        # increase the AH accuracy when approach convergence
        ah_start_tol = min(norm_gorb*casscf.ah_grad_trust_region, casscf.ah_start_tol)
        log.debug1('Set ah_start_tol %g, ah_start_cycle %d, max_cycle %d',
                   ah_start_tol, ah_start_cycle, max_cycle)
        g_orb0 = g_orb
        imic = 0

        g_op = lambda: g_orb

        for ah_end, ihop, w, dxi, hdxi, residual, seig \
                in iah.davidson_cc(h_op, g_op, precond, x0_guess,
                                   tol=ah_conv_tol, max_cycle=casscf.ah_max_cycle,
                                   lindep=casscf.ah_lindep, verbose=log):
            # residual = v[0] * (g+(h-e)x) ~ v[0] * grad
            norm_residual = numpy.linalg.norm(residual)
            if (ah_end or ihop == casscf.ah_max_cycle or # make sure to use the last step
                ((norm_residual < ah_start_tol) and (ihop >= ah_start_cycle)) or
                (seig < casscf.ah_lindep)):
                imic += 1
                dxmax = numpy.max(abs(dxi))
                if dxmax > max_stepsize:
                    scale = max_stepsize / dxmax
                    log.debug1('... scale rotation size %g', scale)
                    dxi *= scale
                    hdxi *= scale
                else:
                    scale = None

                g_orb = g_orb + hdxi
                dr = dr + dxi
                norm_gorb0, norm_gorb = norm_gorb, numpy.linalg.norm(g_orb)
                norm_dxi = numpy.linalg.norm(dxi)
                norm_dr = numpy.linalg.norm(dr)
                log.debug('    imic %d(%d)  |g[o]|=%5.3g  |dxi|=%5.3g  '
                          'max(|x|)=%5.3g  |dr|=%5.3g  eig=%5.3g  seig=%5.3g',
                          imic, ihop, norm_gorb, norm_dxi,
                          dxmax, norm_dr, w, seig)

                if imic > 1 and norm_gorb > norm_gkf*casscf.ah_grad_trust_region:
                    break

                elif (imic >= max_cycle or norm_gorb < conv_tol_grad*.3):
                    break

        u = casscf.update_rotate_matrix(dr)
        jkcount += ihop
        gorb_update = h_op = h_diag = None
        t3m = log.timer('aug_hess in %d inner iters' % imic, *t3m)

        yield u, g_orb0, jkcount

        t3m = (time.clock(), time.time())
        g_kf1, gorb_update, h_op, h_diag = \
                casscf.gen_g_hop(mo, u, fcasdm1(), fcasdm2(), eris)
        g_kf1 = gorb_update(u, casscf.with_dep4)
        jkcount += 1

        norm_gkf1 = numpy.linalg.norm(g_kf1)
        norm_dg = numpy.linalg.norm(g_kf1-g_orb)
        log.debug('    |g|=%5.3g (keyframe), |g-correction|=%5.3g',
                  norm_gkf1, norm_dg)
#
# Special treatment if out of trust region
#
        if (norm_dg > norm_gorb*casscf.ah_grad_trust_region and
            norm_gkf1 > norm_gkf and
            norm_gkf1 > norm_gkf0*casscf.ah_grad_trust_region):
            log.debug('    Keyframe |g|=%5.3g  |g_last| =%5.3g out of trust region',
                      norm_gkf1, norm_gorb)
            if ((not casscf.with_dep4 and norm_gkf > 5e-4) or
                (hasattr(casscf._scf, 'with_df') and casscf._scf.with_df) or
                isinstance(casscf._scf, scf.uhf.UHF)):
#TODO:  transformation for DF integrals
                u = casscf.update_rotate_matrix(dr-dxi)
                yield u, g_kf-hdxi, jkcount
                break
            else:
                g_kf1 = gorb_update(u, True)
                jkcount += 1
                norm_gkf1 = numpy.linalg.norm(g_kf1)
                norm_dg = numpy.linalg.norm(g_kf1-g_orb)
                log.debug('With dep4 |g|=%5.3g (keyframe), |g-correction|=%5.3g',
                          norm_gkf1, norm_dg)
        t3m = log.timer('gen h_op', *t3m)
        g_orb = g_kf = g_kf1
        norm_gorb = norm_gkf = norm_gkf1
        x0_guess = dxi
        ah_start_cycle -= 1