def test_dipole_prepared_continuum():
    """
    see 
    G. Fronzoni, M. Stener, S. Furlan, P. Decleva
    Chemical Physics 273 (2001) 117-133
    """
    from DFTB.LR_TDDFTB import LR_TDDFTB
    from DFTB import XYZ
    from DFTB.Scattering import slako_tables_scattering

    # BOUND ORBITAL = H**O
    atomlist = XYZ.read_xyz("./water.xyz")[0]
    tddftb = LR_TDDFTB(atomlist)
    tddftb.setGeometry(atomlist, charge=0)
    options = {"nstates": 1}
    tddftb.getEnergies(**options)

    valorbs, radial_val = load_pseudo_atoms(atomlist)

    H**O, LUMO = tddftb.dftb2.getFrontierOrbitals()
    bound_orbs = tddftb.dftb2.getKSCoefficients()

    # polarization direction of E-field
    epol = np.array([0.0, 1.0, 0.0])

    # according to Koopman's theorem the electron is ionized from the H**O
    mo_indx = range(0, len(bound_orbs))
    nmo = len(mo_indx)
    for imo in range(0, nmo):
        mo_bound = bound_orbs[:, mo_indx[imo]]

        # CONTINUUM ORBITALS at energy E
        for E in slako_tables_scattering.energies:
            bs = AtomicScatteringBasisSet(atomlist, E)
            SKT_bf, SKT_ff = load_slako_scattering(atomlist, E)
            Dipole = ScatteringDipoleMatrix(atomlist, valorbs, SKT_bf)
            # projection of dipoles onto polarization direction
            Dipole_projected = np.zeros((Dipole.shape[0], Dipole.shape[1]))
            for xyz in [0, 1, 2]:
                Dipole_projected += Dipole[:, :, xyz] * epol[xyz]
            # unnormalized coefficients of dipole-prepared continuum orbitals
            mo_scatt = np.dot(mo_bound, Dipole_projected)
            nrm2 = np.dot(mo_scatt, mo_scatt)
            # normalized coefficients
            mo_scatt /= np.sqrt(nrm2)

            Cube.orbital2grid(atomlist, bs.bfs, mo_scatt, \
                          filename="/tmp/scattering_orbital_%d_to_%s.cube" % (imo, str(E).replace(".", "p")), dbuff=25.0)
            delattr(Cube.orbital_amplitude, "cached_grid")
    PAD.asymptotic_density(wavefunction2, 20.0, E)

    plt.show()

    # build LCAO of two atomic s-waves with PKE=5 eV
    from DFTB.Scattering.SlakoScattering import AtomicScatteringBasisSet
    bs = AtomicScatteringBasisSet(atomlist, E)
    lcao_continuum = np.array([
        +1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        -1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
    ])
    lcao_continuum /= la.norm(lcao_continuum)
    Cube.orbital2grid(atomlist, bs.bfs, lcao_continuum, \
                      filename="/tmp/h2+_lcao_continuum_orbital_%s.cube" % str(E).replace(".", "p"), dbuff=15.0, ppb=2.5)
def test_scattering_orbitals():
    from DFTB.LR_TDDFTB import LR_TDDFTB
    from DFTB import XYZ

    atomlist = XYZ.read_xyz("h2.xyz")[0]

    tddftb = LR_TDDFTB(atomlist)
    tddftb.setGeometry(atomlist, charge=0)
    options = {"nstates": 1}
    tddftb.getEnergies(**options)

    valorbs, radial_val = load_pseudo_atoms(atomlist)

    E = 5.0 / 27.211
    bs = AtomicScatteringBasisSet(atomlist, E)
    print bs.bfs

    SKT_bf, SKT_ff = load_slako_scattering(atomlist, E)
    S_bb, H0_bb = tddftb.dftb2._constructH0andS()
    S_bf, H0_bf = ScatteringHamiltonianMatrix(atomlist, valorbs, SKT_bf)
    #
    invS_bb = la.inv(S_bb)
    # (H-E*S)^t . Id . (H-E*S)
    HmE2 = np.dot(H0_bf.conjugate().transpose(), np.dot(invS_bb, H0_bf)) \
           - E * np.dot( S_bf.conjugate().transpose(), np.dot(invS_bb, H0_bf)) \
           - E * np.dot(H0_bf.conjugate().transpose(), np.dot(invS_bb,  S_bf)) \
           + E**2 * np.dot(S_bf.conjugate().transpose(), np.dot(invS_bb, S_bf))
    Scont = continuum_flux(atomlist, SKT_bf)
    S2 = np.dot(S_bf.conjugate().transpose(), np.dot(la.inv(S_bb), S_bf))
    """
    #
    H2 = np.dot(H0_bf.transpose(), np.dot(la.inv(S_bb), H0_bf))
    S2 = np.dot( S_bf.transpose(), np.dot(la.inv(S_bb), S_bf))
    print "H2"
    print H2
    print "S2"
    print S2
    scat_orbe2, scat_orbs = sla.eig(H2) #, S2)
    print "PKE = %s" % E
    print "Energies^2 = %s" % scat_orbe2
    scat_orbe = np.sqrt(scat_orbe2)
    sort_indx = np.argsort(scat_orbe)
    scat_orbe = scat_orbe[sort_indx]
    scat_orbs = scat_orbs[:,sort_indx]
    print "Energies of scattering orbitals: %s" % scat_orbe
    orbE = np.argmin(abs(scat_orbe-E))
    """
    assert np.sum(abs(HmE2.conjugate().transpose() - HmE2)) < 1.0e-10
    assert np.sum(abs(S2.conjugate().transpose() - S2)) < 1.0e-10
    lambdas, scat_orbs = sla.eigh(HmE2)
    print "lambdas = %s" % lambdas

    from DFTB.Scattering import PAD

    for i in range(0, len(lambdas)):
        if abs(lambdas[i]) > 1.0e-8:
            print "%d  lambda = %s" % (i, lambdas[i])

            ###
            def wavefunction(grid, dV):
                # evaluate orbital
                amp = Cube.orbital_amplitude(grid,
                                             bs.bfs,
                                             scat_orbs[:, i],
                                             cache=False)
                return amp

            PAD.asymptotic_density(wavefunction, 20, E)
            ###

            for (flm, l, m) in classify_lm(bs, scat_orbs[:, i]):
                if abs(flm).max() > 1.0e-4:
                    print " %s %s     %s" % (l, m, abs(flm))
            Cube.orbital2grid(atomlist, bs.bfs, scat_orbs[:,i], \
                          filename="/tmp/scattering_orbital_%d.cube" % i, dbuff=25.0)
            delattr(Cube.orbital_amplitude, "cached_grid")