示例#1
0
def test(xc, tol=5e-10):
    N_c = np.array([10, 6, 4])
    # This test is totally serial.
    gd = GridDescriptor(N_c,
                        N_c * 0.2,
                        pbc_c=(1, 0, 1),
                        comm=world.new_communicator([world.rank]))
    actual_n = N_c - (1 - gd.pbc_c)

    gen = np.random.RandomState(17)
    n_sg = gd.zeros(2)
    n_sg[:] = gen.rand(*n_sg.shape)
    #sigma_xg = gd.zeros(3)
    #sigma_xg[:] = gen.random.rand(*sigma_xg.shape)

    if hasattr(xc, 'libvdwxc'):
        xc._nspins = 2
        xc.initialize_backend(gd)

    v_sg = gd.zeros(2)
    E = xc.calculate(gd, n_sg, v_sg)
    print('E', E)

    dn = 1e-6

    all_indices = itertools.product(range(2), range(1, actual_n[0], 2),
                                    range(0, actual_n[1], 2),
                                    range(0, actual_n[2], 2))

    for testindex in all_indices:
        n1_sg = n_sg.copy()
        n2_sg = n_sg.copy()
        v = v_sg[testindex] * gd.dv
        n1_sg[testindex] -= dn
        n2_sg[testindex] += dn

        E1 = xc.calculate(gd, n1_sg, v_sg.copy())
        E2 = xc.calculate(gd, n2_sg, v_sg.copy())

        dedn = 0.5 * (E2 - E1) / dn
        err = abs(dedn - v)
        print('{}{} v={} fd={} err={}'.format(xc.name, list(testindex), v,
                                              dedn, err))
        assert err < tol, err
示例#2
0
def f(n, p):
    N = 2 * n
    gd = GridDescriptor((N, N, N), (L, L, L))
    a = gd.zeros()
    print(a.shape)
    #p = PoissonSolver(nn=1, relax=relax)
    p.set_grid_descriptor(gd)
    cut = N / 2.0 * 0.9
    s = Spline(l=0, rmax=cut, f_g=np.array([1, 0.5, 0.0]))
    c = LFC(gd, [[s], [s]])
    c.set_positions([(0, 0, 0), (0.5, 0.5, 0.5)])
    c.add(a)

    I0 = gd.integrate(a)
    a -= I0 / L**3

    b = gd.zeros()
    p.solve(b, a, charge=0, eps=1e-20)
    return gd.collect(b, broadcast=1)
示例#3
0
 def __init__(self, gd, spline_j, spos_c, index=None):
     rcut = max([spline.get_cutoff() for spline in spline_j])
     corner_c = np.ceil(spos_c * gd.N_c - rcut / gd.h_c).astype(int)
     size_c = np.ceil(spos_c * gd.N_c + rcut / gd.h_c).astype(int) - corner_c
     smallgd = GridDescriptor(N_c=size_c + 1, cell_cv=gd.h_c * (size_c + 1), pbc_c=False, comm=mpi.serial_comm)
     lfc = LFC(smallgd, [spline_j])
     lfc.set_positions((spos_c[np.newaxis, :] * gd.N_c - corner_c + 1) / smallgd.N_c)
     ni = lfc.Mmax
     f_iG = smallgd.zeros(ni)
     lfc.add(f_iG, {0: np.eye(ni)})
     LocalizedFunctions.__init__(self, gd, f_iG, corner_c, index=index)
def f(n, p):
    N = 2 * n
    gd = GridDescriptor((N, N, N), (L, L, L))
    a = gd.zeros()
    print(a.shape)
    #p = PoissonSolver(nn=1, relax=relax)
    p.set_grid_descriptor(gd)
    p.initialize()
    cut = N / 2.0 * 0.9
    s = Spline(l=0, rmax=cut, f_g=np.array([1, 0.5, 0.0]))
    c = LFC(gd, [[s], [s]])
    c.set_positions([(0, 0, 0), (0.5, 0.5, 0.5)])
    c.add(a)

    I0 = gd.integrate(a)
    a -= gd.integrate(a) / L**3

    I = gd.integrate(a)
    b = gd.zeros()
    p.solve(b, a, charge=0)#, eps=1e-20)
    return gd.collect(b, broadcast=1)
示例#5
0
def main():
    from gpaw.grid_descriptor import GridDescriptor
    from gpaw.mpi import world

    serial = world.new_communicator([world.rank])

    # Generator which must run on all ranks
    gen = np.random.RandomState(0)

    # This one is just used by master
    gen_serial = np.random.RandomState(17)

    maxsize = 5
    for i in range(1):
        N1_c = gen.randint(1, maxsize, 3)
        N2_c = gen.randint(1, maxsize, 3)

        gd1 = GridDescriptor(N1_c, N1_c)
        gd2 = GridDescriptor(N2_c, N2_c)
        serial_gd1 = gd1.new_descriptor(comm=serial)
        serial_gd2 = gd2.new_descriptor(comm=serial)

        a1_serial = serial_gd1.empty()
        a1_serial.flat[:] = gen_serial.rand(a1_serial.size)

        if world.rank == 0:
            print('r0: a1 serial', a1_serial.ravel())

        a1 = gd1.empty()
        a1[:] = -1

        grid2grid(world, serial_gd1, gd1, a1_serial, a1)

        print(world.rank, 'a1 distributed', a1.ravel())
        world.barrier()

        a2 = gd2.zeros()
        a2[:] = -2
        grid2grid(world, gd1, gd2, a1, a2)
        print(world.rank, 'a2 distributed', a2.ravel())
        world.barrier()

        #grid2grid(world, gd2, gd2_serial

        gd1 = GridDescriptor(N1_c, N1_c * 0.2)
        #serialgd = gd2.new_descriptor(

        a1 = gd1.empty()
        a1.flat[:] = gen.rand(a1.size)

        #print a1
        grid2grid(world, gd1, gd2, a1, a2)
示例#6
0
def interpolate_2d(mat):
    from gpaw.grid_descriptor import GridDescriptor
    from gpaw.transformers import Transformer
    nn = 10
    N_c = np.zeros([3], dtype=int)
    N_c[1:] = mat.shape[:2]
    N_c[0] = nn
    bmat = np.resize(mat, N_c)
    gd = GridDescriptor(N_c, N_c)
    finegd = GridDescriptor(N_c * 2, N_c)
    interpolator = Transformer(gd, finegd, 3)
    fine_bmat = finegd.zeros()
    interpolator.apply(bmat, fine_bmat)
    return fine_bmat[0]
示例#7
0
 def __init__(self, gd, spline_j, spos_c, index=None):
     rcut = max([spline.get_cutoff() for spline in spline_j])
     corner_c = np.ceil(spos_c * gd.N_c - rcut / gd.h_c).astype(int)
     size_c = np.ceil(spos_c * gd.N_c + rcut / gd.h_c).astype(int) - corner_c
     smallgd = GridDescriptor(N_c=size_c + 1,
                              cell_cv=gd.h_c * (size_c + 1),
                              pbc_c=False,
                              comm=mpi.serial_comm)
     lfc = LFC(smallgd, [spline_j])
     lfc.set_positions((spos_c[np.newaxis, :] * gd.N_c - corner_c + 1) /
                       smallgd.N_c)
     ni = lfc.Mmax
     f_iG = smallgd.zeros(ni)
     lfc.add(f_iG, {0: np.eye(ni)})
     LocalizedFunctions.__init__(self, gd, f_iG, corner_c, 
                                  index=index)
示例#8
0
def make_dummy_kpt_reference(l, function, k_c,
                             rcut=6., a=10., n=60, dtype=complex):
    r = np.linspace(0., rcut, 300)
    mcount = 2*l + 1
    fcount = 1
    kcount = 1
    gd = GridDescriptor((n, n, n), (a, a, a), (True, True, True))
    kpt = KPoint([], gd, 1., 0, 0, 0, k_c, dtype)
    spline = Spline(l, r[-1], function(r))
    center = (.5, .5, .5)
    lf = create_localized_functions([spline], gd, center, dtype=dtype)
    lf.set_phase_factors([kpt.k_c])
    psit_nG = gd.zeros(mcount, dtype=dtype)
    coef_xi = np.identity(mcount * fcount, dtype=dtype)
    lf.add(psit_nG, coef_xi, k=0)
    kpt.psit_nG = psit_nG
    print 'Number of boxes', len(lf.box_b)
    print 'Phase kb factors shape', lf.phase_kb.shape
    return gd, kpt, center
示例#9
0
def test():
    from gpaw.grid_descriptor import GridDescriptor

    ngpts = 40
    h = 1 / ngpts
    N_c = (ngpts, ngpts, ngpts)
    a = h * ngpts
    gd = GridDescriptor(N_c, (a, a, a))

    from gpaw.spline import Spline
    a = np.array([1, 0.9, 0.8, 0.0])
    s = Spline(0, 0.2, a)
    x = LocalizedFunctionsCollection(gd, [[s], [s]])
    x.set_positions([(0.5, 0.45, 0.5), (0.5, 0.55, 0.5)])
    n_G = gd.zeros()
    x.add(n_G)
    import pylab as plt
    plt.contourf(n_G[20, :, :])
    plt.axis('equal')
    plt.show()
示例#10
0
def test():
    from gpaw.grid_descriptor import GridDescriptor

    ngpts = 40
    h = 1.0 / ngpts
    N_c = (ngpts, ngpts, ngpts)
    a = h * ngpts
    gd = GridDescriptor(N_c, (a, a, a))
    
    from gpaw.spline import Spline
    a = np.array([1, 0.9, 0.8, 0.0])
    s = Spline(0, 0.2, a)
    x = LocalizedFunctionsCollection(gd, [[s], [s]])
    x.set_positions([(0.5, 0.45, 0.5), (0.5, 0.55, 0.5)])
    n_G = gd.zeros()
    x.add(n_G)
    import pylab as plt
    plt.contourf(n_G[20, :, :])
    plt.axis('equal')
    plt.show()
示例#11
0
def make_dummy_reference(l, function=None, rcut=6., a=12., n=60, dtype=float):
    """Make a mock reference wave function using a made-up radial function
    as reference"""
    #print 'Dummy reference: l=%d, rcut=%.02f, alpha=%.02f' % (l, rcut, alpha)
    r = np.arange(0., rcut, .01)

    if function is None:
        function = QuasiGaussian(4., rcut)

    norm = get_norm(r, function(r), l)
    function.renormalize(norm)
    #g = QuasiGaussian(alpha, rcut)

    mcount = 2 * l + 1
    fcount = 1
    gd = GridDescriptor((n, n, n), (a, a, a), (False, False, False))
    spline = Spline(l, r[-1], function(r), points=50)
    center = (.5, .5, .5)
    lf = create_localized_functions([spline], gd, center, dtype=dtype)
    psit_k = gd.zeros(mcount, dtype=dtype)
    coef_xi = np.identity(mcount * fcount, dtype=dtype)
    lf.add(psit_k, coef_xi)
    return gd, psit_k, center, function
示例#12
0
def make_dummy_reference(l, function=None, rcut=6., a=12., n=60,
                         dtype=float):
    """Make a mock reference wave function using a made-up radial function
    as reference"""
    #print 'Dummy reference: l=%d, rcut=%.02f, alpha=%.02f' % (l, rcut, alpha)
    r = np.arange(0., rcut, .01)

    if function is None:
        function = QuasiGaussian(4., rcut)

    norm = get_norm(r, function(r), l)
    function.renormalize(norm)
    #g = QuasiGaussian(alpha, rcut)
    
    mcount = 2*l + 1
    fcount = 1
    gd = GridDescriptor((n, n, n), (a, a, a), (False, False, False))
    spline = Spline(l, r[-1], function(r), points=50)
    center = (.5, .5, .5)
    lf = create_localized_functions([spline], gd, center, dtype=dtype)
    psit_k = gd.zeros(mcount, dtype=dtype)
    coef_xi = np.identity(mcount * fcount, dtype=dtype)
    lf.add(psit_k, coef_xi)
    return gd, psit_k, center, function
示例#13
0
def make_dummy_kpt_reference(l,
                             function,
                             k_c,
                             rcut=6.,
                             a=10.,
                             n=60,
                             dtype=complex):
    r = np.linspace(0., rcut, 300)
    mcount = 2 * l + 1
    fcount = 1
    kcount = 1
    gd = GridDescriptor((n, n, n), (a, a, a), (True, True, True))
    kpt = KPoint([], gd, 1., 0, 0, 0, k_c, dtype)
    spline = Spline(l, r[-1], function(r))
    center = (.5, .5, .5)
    lf = create_localized_functions([spline], gd, center, dtype=dtype)
    lf.set_phase_factors([kpt.k_c])
    psit_nG = gd.zeros(mcount, dtype=dtype)
    coef_xi = np.identity(mcount * fcount, dtype=dtype)
    lf.add(psit_nG, coef_xi, k=0)
    kpt.psit_nG = psit_nG
    print 'Number of boxes', len(lf.box_b)
    print 'Phase kb factors shape', lf.phase_kb.shape
    return gd, kpt, center
示例#14
0
from gpaw.poisson import NonPeriodicLauePoissonSolver, GeneralizedLauePoissonSolver, FDPoissonSolver, idst2, dst2
from gpaw.grid_descriptor import GridDescriptor
import numpy as np

gd = GridDescriptor((10,12,42), (4, 5, 20), pbc_c=(True,True,False))
poisson = GeneralizedLauePoissonSolver(nn=2)
poisson.set_grid_descriptor(gd)

poisson2 = FDPoissonSolver(nn=2, eps=1e-28)
poisson2.set_grid_descriptor(gd)

phi_g = gd.zeros()
phi2_g = gd.zeros()
rho_g = gd.zeros()
rho_g[4,5,6] = 1.0
rho_g[4,5,7] = -1.0

poisson.solve(phi_g, rho_g)
poisson2.solve(phi2_g, rho_g)
print("this", phi_g[4,5,:])
print("ref", phi2_g[4,5,:])
print("diff", phi_g[4,5,:]-phi2_g[4,5,:])

assert np.linalg.norm(phi_g-phi2_g) < 1e-10

gd = GridDescriptor((10,12,42), (10, 12, 42), pbc_c=(False,False,False))
poisson = NonPeriodicLauePoissonSolver(nn=1)
poisson.set_grid_descriptor(gd)
print("eigs", poisson.eigs_c[0])
poisson2 = FDPoissonSolver(nn=1, eps=1e-24)
poisson2.set_grid_descriptor(gd)
示例#15
0
    Ep = xc.calculate(gd, n, v)
    if here:
        n[-1, 1, 2, 3] -= 0.000002
    Em = xc.calculate(gd, n, v)
    x2 = (Ep - Em) / 0.000002
    if here:
        print(xc.name, E, x, x2, x - x2)
        equal(x, x2, 1e-11)
        n[-1, 1, 2, 3] += 0.000001

    if 0:#xc.type == 'LDA':
        xc = XC(NonCollinearLDAKernel())
    else:
        xc = NonCollinearFunctional(xc)

    n2 = gd.zeros(4)
    n2[0] = n.sum(0)
    n2[3] = n[0] - n[1]
    E2 = xc.calculate(gd, n2)
    print(E, E2-E)
    assert abs(E2 - E) < 1e-11
    n2[1] = 0.1 * n2[3]
    n2[2] = 0.2 * n2[3]
    n2[3] *= (1 - 0.1**2 - 0.2**2)**0.5
    v = n2 * 0
    E2 = xc.calculate(gd, n2, v)
    print(E, E2-E)
    assert abs(E2 - E) < 1e-11

    for i in range(4):
        if here:
示例#16
0
文件: lf.py 项目: thonmaker/gpaw
from gpaw.test import equal
from gpaw.grid_descriptor import GridDescriptor
from gpaw.spline import Spline
import gpaw.mpi as mpi
from gpaw.lfc import LocalizedFunctionsCollection as LFC

s = Spline(0, 1.0, [1.0, 0.5, 0.0])
n = 40
a = 8.0
gd = GridDescriptor((n, n, n), (a, a, a), comm=mpi.serial_comm)
c = LFC(gd, [[s], [s], [s]])
c.set_positions([(0.5, 0.5, 0.25 + 0.25 * i) for i in [0, 1, 2]])
b = gd.zeros()
c.add(b)
x = gd.integrate(b)

gd = GridDescriptor((n, n, n), (a, a, a), comm=mpi.serial_comm)
c = LFC(gd, [[s], [s], [s]])
c.set_positions([(0.5, 0.5, 0.25 + 0.25 * i) for i in [0, 1, 2]])
b = gd.zeros()
c.add(b)
y = gd.integrate(b)
equal(x, y, 1e-13)
示例#17
0
from gpaw.grid_descriptor import GridDescriptor
from gpaw.spline import Spline
a = 4.0
gd = GridDescriptor(N_c=[16, 20, 20], cell_cv=[a, a + 1, a + 2],
                    pbc_c=(0, 1, 1))
spos_ac = np.array([[0.25, 0.15, 0.35], [0.5, 0.5, 0.5]])
kpts_kc = None
s = Spline(l=0, rmax=2.0, f_g=np.array([1, 0.9, 0.1, 0.0]))
p = Spline(l=1, rmax=2.0, f_g=np.array([1, 0.9, 0.1, 0.0]))
spline_aj = [[s], [s, p]]
c = LFC(gd, spline_aj, cut=True, forces=True)
c.set_positions(spos_ac)
C_ani = c.dict(3, zero=True)
if 1 in C_ani:
    C_ani[1][:, 1:] = np.eye(3)
psi = gd.zeros(3)
c.add(psi, C_ani)
c.integrate(psi, C_ani)
if 1 in C_ani:
    d = C_ani[1][:, 1:].diagonal()
    assert d.ptp() < 4e-6
    C_ani[1][:, 1:] -= np.diag(d)
    assert abs(C_ani[1]).max() < 5e-17
d_aniv = c.dict(3, derivative=True)
c.derivative(psi, d_aniv)
if 1 in d_aniv:
    for v in range(3):
        assert abs(d_aniv[1][v - 1, 0, v] + 0.2144) < 5e-5
        d_aniv[1][v - 1, 0, v] = 0
    assert abs(d_aniv[1]).max() < 3e-16
eps = 0.0001
示例#18
0
from gpaw.response.math_func import two_phi_planewave_integrals

# Initialize s, p, d (9 in total) wave and put them on grid
rc = 2.0
a = 2.5 * rc
n = 64
lmax = 2
b = 8.0
m = (lmax + 1)**2
gd = GridDescriptor([n, n, n], [a, a, a])
r = np.linspace(0, rc, 200)
g = np.exp(-(r / rc * b)**2)
splines = [Spline(l=l, rmax=rc, f_g=g) for l in range(lmax + 1)]
c = LFC(gd, [splines])
c.set_positions([(0.5, 0.5, 0.5)])
psi = gd.zeros(m)
d0 = c.dict(m)
if 0 in d0:
    d0[0] = np.identity(m)
c.add(psi, d0)

# Calculate on 3d-grid < phi_i | e**(-ik.r) | phi_j >
R_a = np.array([a/2,a/2,a/2])
rr = gd.get_grid_point_coordinates()
for dim in range(3):
    rr[dim] -= R_a[dim]

k_G = np.array([[11.,0.2,0.1],[10., 0., 10.]])
nkpt = k_G.shape[0]

d0 = np.zeros((nkpt,m,m), dtype=complex)
示例#19
0
文件: df0.py 项目: eojons/gpaw-scme
class DF(CHI):
    """This class defines dielectric function related physical quantities."""

    def __init__(self,
                 calc=None,
                 nbands=None,
                 w=None,
                 q=None,
                 eshift=None,
                 ecut=10.,
                 density_cut=None,
                 G_plus_q=False,
                 eta=0.2,
                 rpad=None,
                 vcut=None,
                 ftol=1e-7,
                 txt=None,
                 xc='ALDA',
                 print_xc_scf=False,
                 hilbert_trans=True,
                 time_ordered=False,
                 optical_limit=False,
                 comm=None,
                 kcommsize=None):

        CHI.__init__(self, calc=calc, nbands=nbands, w=w, q=q, eshift=eshift,
                     ecut=ecut, density_cut=density_cut,
                     G_plus_q=G_plus_q, eta=eta, rpad=rpad, vcut=vcut,
                     ftol=ftol, txt=txt, xc=xc, hilbert_trans=hilbert_trans,
                     time_ordered=time_ordered, optical_limit=optical_limit,
                     comm=comm, kcommsize=kcommsize)

        self.df_flag = False
        self.print_bootstrap = print_xc_scf
        self.df1_w = None  # NLF RPA
        self.df2_w = None  # LF RPA
        self.df3_w = None  # NLF ALDA
        self.df4_w = None  # LF ALDA

    def get_dielectric_matrix(self,
                              xc='RPA',
                              overwritechi0=False,
                              symmetric=True,
                              chi0_wGG=None,
                              calc=None,
                              vcut=None,
                              dir=None):
	if self.chi0_wGG is None and chi0_wGG is None:
            self.initialize()
            self.calculate()
        elif self.chi0_wGG is None and chi0_wGG is not None:
            #Read from file and reinitialize 
            self.xc = xc

            from gpaw.response.parallel import par_read 
            self.chi0_wGG = par_read(chi0_wGG, 'chi0_wGG')
            self.nvalbands = self.nbands
            #self.parallel_init() # parallelization not yet implemented
            self.Nw_local = self.Nw  # parallelization not yet implemented
            if self.calc is None:
                from gpaw import GPAW
                self.calc = GPAW(calc,txt=None)
            if self.xc == 'ALDA' or self.xc == 'ALDA_X':
                from gpaw.response.kernel import calculate_Kxc
                from gpaw.grid_descriptor import GridDescriptor
                from gpaw.mpi import world, rank, size, serial_comm
                    
                self.pbc = self.calc.atoms.pbc
                self.gd = GridDescriptor(self.calc.wfs.gd.N_c*self.rpad, self.acell_cv,
                                         pbc_c=True, comm=serial_comm)

                R_av = self.calc.atoms.positions / Bohr
                nt_sg = self.calc.density.nt_sG
                    
                if (self.rpad > 1).any() or (self.pbc - True).any():
                    nt_sG = self.gd.zeros(self.nspins)
                    #nt_sG = np.zeros([self.nspins, self.nG[0], self.nG[1], self.nG[2]])
                    for s in range(self.nspins):
                        nt_G = self.pad(nt_sg[s])
                        nt_sG[s] = nt_G
                else:
                    nt_sG = nt_sg
                        
                self.Kxc_sGG = calculate_Kxc(self.gd, 
                                             nt_sG,
                                             self.npw, self.Gvec_Gc,
                                             self.gd.N_c, self.vol,
                                             self.bcell_cv, R_av,
                                             self.calc.wfs.setups,
                                             self.calc.density.D_asp,
                                             functional=self.xc,
                                             density_cut=self.density_cut)

        if overwritechi0:
            dm_wGG = self.chi0_wGG
        else:
            dm_wGG = np.zeros_like(self.chi0_wGG)

        if dir is None:
            q_c = self.q_c
        else:
            q_c = np.diag((1,1,1))[dir] * self.qopt
            self.chi0_wGG[:,0,:] = self.chi00G_wGv[:,:,dir]
            self.chi0_wGG[:,:,0] = self.chi0G0_wGv[:,:,dir]
        
        from gpaw.response.kernel import calculate_Kc, CoulombKernel
        kernel = CoulombKernel(vcut=self.vcut,
                               pbc=self.calc.atoms.pbc,
                               cell=self.acell_cv)
        self.Kc_GG = kernel.calculate_Kc(q_c,
                                         self.Gvec_Gc,
                                         self.bcell_cv,
                                         symmetric=symmetric)
        #self.Kc_GG = calculate_Kc(q_c,
        #                          self.Gvec_Gc,
        #                          self.acell_cv,
        #                          self.bcell_cv,
        #                          self.pbc,
        #                          self.vcut,
        #                          symmetric=symmetric)

        tmp_GG = np.eye(self.npw, self.npw)

        if xc == 'RPA':
            self.printtxt('Use RPA.')
            for iw in range(self.Nw_local):
                dm_wGG[iw] = tmp_GG - self.Kc_GG * self.chi0_wGG[iw]
                
        elif xc == 'ALDA':
            self.printtxt('Use ALDA kernel.')
            # E_LDA = 1 - v_c chi0 (1-fxc chi0)^-1
            # http://prb.aps.org/pdf/PRB/v33/i10/p7017_1 eq. 4
            A_wGG = self.chi0_wGG.copy()
            for iw in range(self.Nw_local):
                A_wGG[iw] = np.dot(self.chi0_wGG[iw], np.linalg.inv(tmp_GG - np.dot(self.Kxc_sGG[0], self.chi0_wGG[iw])))
    
            for iw in range(self.Nw_local):
                dm_wGG[iw] = tmp_GG - self.Kc_GG * A_wGG[iw]                

        return dm_wGG


    def get_inverse_dielectric_matrix(self, xc='RPA'):

        dm_wGG = self.get_dielectric_matrix(xc=xc)
        dminv_wGG = np.zeros_like(dm_wGG)
        for iw in range(self.Nw_local):
            dminv_wGG[iw] = np.linalg.inv(dm_wGG[iw])
        return dminv_wGG


    def get_chi(self, xc='RPA'):
        """Solve Dyson's equation."""

	if self.chi0_wGG is None:
            self.initialize()
            self.calculate()
        else:
            pass # read from file and re-initializing .... need to be implemented

        kernel_GG = np.zeros((self.npw, self.npw), dtype=complex)
        chi_wGG = np.zeros_like(self.chi0_wGG)

        # Coulomb kernel
        for iG in range(self.npw):
            qG = np.dot(self.q_c + self.Gvec_Gc[iG], self.bcell_cv)
            kernel_GG[iG,iG] = 4 * pi / np.dot(qG, qG)
            
        if xc == 'ALDA':
            kernel_GG += self.Kxc_sGG[0]

        for iw in range(self.Nw_local):
            tmp_GG = np.eye(self.npw, self.npw) - np.dot(self.chi0_wGG[iw], kernel_GG)
            chi_wGG[iw] = np.dot(np.linalg.inv(tmp_GG) , self.chi0_wGG[iw])

        return chi_wGG
    

    def get_dielectric_function(self, xc='RPA', dir=None):
        """Calculate the dielectric function. Returns df1_w and df2_w.

        Parameters:

        df1_w: ndarray
            Dielectric function without local field correction.
        df2_w: ndarray
            Dielectric function with local field correction.
        """

        if not self.optical_limit:
            assert dir is None
            
        if self.df_flag is False:
            dm_wGG = self.get_dielectric_matrix(xc=xc, dir=dir)

            Nw_local = dm_wGG.shape[0]
            dfNLF_w = np.zeros(Nw_local, dtype = complex)
            dfLFC_w = np.zeros(Nw_local, dtype = complex)
            df1_w = np.zeros(self.Nw, dtype = complex)
            df2_w = np.zeros(self.Nw, dtype = complex)

            for iw in range(Nw_local):
                tmp_GG = dm_wGG[iw]
                dfLFC_w[iw] = 1. / np.linalg.inv(tmp_GG)[0, 0]
                dfNLF_w[iw] = tmp_GG[0, 0]

            self.wcomm.all_gather(dfNLF_w, df1_w)
            self.wcomm.all_gather(dfLFC_w, df2_w)

            if xc == 'RPA':
                self.df1_w = df1_w
                self.df2_w = df2_w
            elif xc=='ALDA' or xc=='ALDA_X':
                self.df3_w = df1_w
                self.df4_w = df2_w                

        if xc == 'RPA':
            return self.df1_w, self.df2_w
        elif xc == 'ALDA' or xc=='ALDA_X':
            return self.df3_w, self.df4_w


    def get_surface_response_function(self, z0=0., filename='surf_EELS'):
        """Calculate surface response function."""

	if self.chi0_wGG is None:
            self.initialize()
            self.calculate()


        g_w2 = np.zeros((self.Nw,2), dtype=complex)
        assert self.acell_cv[0, 2] == 0. and self.acell_cv[1, 2] == 0.

        Nz = self.gd.N_c[2] # number of points in z direction
        tmp = np.zeros(Nz, dtype=int)
        nGz = 0         # number of G_z 
        for i in range(self.npw):
            if self.Gvec_Gc[i, 0] == 0 and self.Gvec_Gc[i, 1] == 0:
                tmp[nGz] = self.Gvec_Gc[i, 2]
                nGz += 1
        assert (np.abs(self.Gvec_Gc[:nGz, :2]) < 1e-10).all()

        for id, xc in enumerate(['RPA', 'ALDA']):
            chi_wGG = self.get_chi(xc=xc)
    
            # The first nGz are all Gx=0 and Gy=0 component
            chi_wgg_LFC = chi_wGG[:, :nGz, :nGz]
            del chi_wGG
            chi_wzz_LFC = np.zeros((self.Nw_local, Nz, Nz), dtype=complex)        
    
            # Fourier transform of chi_wgg to chi_wzz
            Gz_g = tmp[:nGz] * self.bcell_cv[2,2]
            z_z = np.linspace(0, self.acell_cv[2,2]-self.gd.h_cv[2,2], Nz)
            phase1_zg = np.exp(1j  * np.outer(z_z, Gz_g))
            phase2_gz = np.exp(-1j * np.outer(Gz_g, z_z))
    
            for iw in range(self.Nw_local):
                chi_wzz_LFC[iw] = np.dot(np.dot(phase1_zg, chi_wgg_LFC[iw]), phase2_gz)
            chi_wzz_LFC /= self.acell_cv[2,2]        
    
            # Get surface response function
    
            z_z -= z0 / Bohr
            q_v = np.dot(self.q_c, self.bcell_cv)
            qq = sqrt(np.inner(q_v, q_v))
            phase1_1z = np.array([np.exp(qq*z_z)])
            phase2_z1 = np.exp(qq*z_z)
    
            tmp_w = np.zeros(self.Nw_local, dtype=complex)        
            for iw in range(self.Nw_local):
                tmp_w[iw] = np.dot(np.dot(phase1_1z, chi_wzz_LFC[iw]), phase2_z1)[0]            
    
            tmp_w *= -2 * pi / qq * self.gd.h_cv[2,2]**2        
            g_w = np.zeros(self.Nw, dtype=complex)
            self.wcomm.all_gather(tmp_w, g_w)
            g_w2[:, id] = g_w
    
        if rank == 0:
            f = open(filename,'w')
            for iw in range(self.Nw):
                energy = iw * self.dw * Hartree
                print >> f, energy, np.imag(g_w2[iw, 0]), np.imag(g_w2[iw, 1])
            f.close()

        # Wait for I/O to finish
        self.comm.barrier()


    def check_sum_rule(self, df1_w=None, df2_w=None):
        """Check f-sum rule."""

	if df1_w is None:
            df1_w = self.df1_w
            df2_w = self.df2_w

        N1 = N2 = 0
        for iw in range(self.Nw):
            w = iw * self.dw
            N1 += np.imag(df1_w[iw]) * w
            N2 += np.imag(df2_w[iw]) * w
        N1 *= self.dw * self.vol / (2 * pi**2)
        N2 *= self.dw * self.vol / (2 * pi**2)

        self.printtxt('')
        self.printtxt('Sum rule for ABS:')
        nv = self.nvalence
        self.printtxt('Without local field: N1 = %f, %f  %% error' %(N1, (N1 - nv) / nv * 100) )
        self.printtxt('Include local field: N2 = %f, %f  %% error' %(N2, (N2 - nv) / nv * 100) )

        N1 = N2 = 0
        for iw in range(self.Nw):
            w = iw * self.dw
            N1 -= np.imag(1/df1_w[iw]) * w
            N2 -= np.imag(1/df2_w[iw]) * w
        N1 *= self.dw * self.vol / (2 * pi**2)
        N2 *= self.dw * self.vol / (2 * pi**2)
                
        self.printtxt('')
        self.printtxt('Sum rule for EELS:')
        nv = self.nvalence
        self.printtxt('Without local field: N1 = %f, %f  %% error' %(N1, (N1 - nv) / nv * 100) )
        self.printtxt('Include local field: N2 = %f, %f  %% error' %(N2, (N2 - nv) / nv * 100) )


    def get_macroscopic_dielectric_constant(self, xc='RPA'):
        """Calculate macroscopic dielectric constant. Returns eM1 and eM2

        Macroscopic dielectric constant is defined as the real part of dielectric function at w=0.
        
        Parameters:

        eM1: float
            Dielectric constant without local field correction. (RPA, ALDA)
        eM2: float
            Dielectric constant with local field correction.

        """

        assert self.optical_limit
        self.printtxt('')
        self.printtxt('%s Macroscopic Dielectric Constant:' % xc)
        dirstr = ['x', 'y', 'z']

        for dir in range(3):
        
            eM = np.zeros(2)
            df1, df2 = self.get_dielectric_function(xc=xc, dir=dir)
            eps0 = np.real(df1[0])
            eps = np.real(df2[0])
            self.printtxt('  %s direction' %(dirstr[dir]))
            self.printtxt('    Without local field: %f' % eps0 )
            self.printtxt('    Include local field: %f' % eps )        
            
        return eps0, eps


    def get_absorption_spectrum(self, filename='Absorption.dat'):
        """Calculate optical absorption spectrum. By default, generate a file 'Absorption.dat'.

        Optical absorption spectrum is obtained from the imaginary part of dielectric function.
        """

        assert self.optical_limit
        for dir in range(3):
            df1, df2 = self.get_dielectric_function(xc='RPA', dir=dir)
            if self.xc == 'ALDA':
                df3, df4 = self.get_dielectric_function(xc='ALDA', dir=dir)
            if self.xc is 'ALDA_X':
                df3, df4 = self.get_dielectric_function(xc='ALDA_X', dir=dir)
    
            Nw = df1.shape[0]
    
            if self.xc == 'Bootstrap':
                # bootstrap doesnt support all direction spectra yet
                from gpaw.response.fxc import Bootstrap
                Kc_GG = np.zeros((self.npw, self.npw))
                q_c = np.diag((1, 1, 1))[dir] * self.qopt

                for iG in range(self.npw):
                    qG = np.dot(q_c + self.Gvec_Gc[iG], self.bcell_cv)
                    Kc_GG[iG,iG] = 4 * pi / np.dot(qG, qG)
    
                from gpaw.mpi import world
                assert self.wcomm.size == world.size
                df3 = Bootstrap(self.chi0_wGG, Nw, Kc_GG, self.printtxt, self.print_bootstrap, self.wcomm)
    
            if rank == 0:
                f = open('%s.%s' % (filename, 'xyz'[dir]), 'w')
                #f = open(filename+'.%s'%(dirstr[dir]),'w') # ????
                for iw in range(Nw):
                    energy = iw * self.dw * Hartree
                    if self.xc == 'RPA':
                        print >> f, energy, np.real(df1[iw]), np.imag(df1[iw]), \
                              np.real(df2[iw]), np.imag(df2[iw])
                    elif self.xc == 'ALDA':
                        print >> f, energy, np.real(df1[iw]), np.imag(df1[iw]), \
                          np.real(df2[iw]), np.imag(df2[iw]), \
                          np.real(df3[iw]), np.imag(df3[iw]), \
                          np.real(df4[iw]), np.imag(df4[iw])
                    elif self.xc == 'Bootstrap':
                        print >> f, energy, np.real(df1[iw]), np.imag(df1[iw]), \
                          np.real(df2[iw]), np.imag(df2[iw]), \
                          np.real(df3[iw]), np.imag(df3[iw])
                f.close()
    
            # Wait for I/O to finish
            self.comm.barrier()


    def get_EELS_spectrum(self, filename='EELS.dat'):
        """Calculate EELS spectrum. By default, generate a file 'EELS.dat'.

        EELS spectrum is obtained from the imaginary part of the inverse of dielectric function.
        """

        # calculate RPA dielectric function
        df1, df2 = self.get_dielectric_function(xc='RPA')
        if self.xc == 'ALDA':
            df3, df4 = self.get_dielectric_function(xc='ALDA')
        Nw = df1.shape[0]

        if rank == 0:
            f = open(filename,'w')
            for iw in range(self.Nw):
                energy = iw * self.dw * Hartree
                if self.xc == 'RPA':
                    print >> f, energy, -np.imag(1./df1[iw]), -np.imag(1./df2[iw])
                elif self.xc == 'ALDA':
                    print >> f, energy, -np.imag(1./df1[iw]), -np.imag(1./df2[iw]), \
                       -np.imag(1./df3[iw]), -np.imag(1./df4[iw])
            f.close()

        # Wait for I/O to finish
        self.comm.barrier()


    def get_jdos(self, f_skn, e_skn, kd, kq, dw, Nw, sigma):
        """Calculate Joint density of states"""

        JDOS_w = np.zeros(Nw)
        nbands = f_skn[0].shape[1]

        for k in range(kd.nbzkpts):
            print k
            ibzkpt1 = kd.bz2ibz_k[k]
            ibzkpt2 = kd.bz2ibz_k[kq[k]]
            for n in range(nbands):
                for m in range(nbands):
                    focc = f_skn[0][ibzkpt1, n] - f_skn[0][ibzkpt2, m]
                    w0 = e_skn[0][ibzkpt2, m] - e_skn[0][ibzkpt1, n]
                    if focc > 0 and w0 >= 0:
                        w0_id = int(w0 / dw)
                        if w0_id + 1 < Nw:
                            alpha = (w0_id + 1 - w0/dw) / dw
                            JDOS_w[w0_id] += focc * alpha
                            alpha = (w0/dw-w0_id) / dw
                            JDOS_w[w0_id+1] += focc * alpha
                            
        w = np.arange(Nw) * dw * Hartree

        return w, JDOS_w


    def calculate_induced_density(self, q, w):
        """ Evaluate induced density for a certain q and w.

        Parameters:

        q: ndarray
            Momentum tranfer at reduced coordinate.
        w: scalar
            Energy (eV).
        """

        if type(w) is int:
            iw = w
            w = self.wlist[iw] / Hartree
        elif type(w) is float:
            w /= Hartree
            iw = int(np.round(w / self.dw))
        else:
            raise ValueError('Frequency not correct !')

        self.printtxt('Calculating Induced density at q, w (iw)')
        self.printtxt('(%f, %f, %f), %f(%d)' %(q[0], q[1], q[2], w*Hartree, iw))

        # delta_G0
        delta_G = np.zeros(self.npw)
        delta_G[0] = 1.

        # coef is (q+G)**2 / 4pi
        coef_G = np.zeros(self.npw)
        for iG in range(self.npw):
            qG = np.dot(q + self.Gvec_Gc[iG], self.bcell_cv)
            coef_G[iG] = np.dot(qG, qG)
        coef_G /= 4 * pi

        # obtain chi_G0(q,w)
        dm_wGG = self.get_RPA_dielectric_matrix()
        tmp_GG = dm_wGG[iw]
        del dm_wGG
        chi_G = (np.linalg.inv(tmp_GG)[:, 0] - delta_G) * coef_G

        gd = self.gd
        r = gd.get_grid_point_coordinates()

        # calculate dn(r,q,w)
        drho_R = gd.zeros(dtype=complex)
        for iG in range(self.npw):
            qG = np.dot(q + self.Gvec_Gc[iG], self.bcell_cv)
            qGr_R = np.inner(qG, r.T).T
            drho_R += chi_G[iG] * np.exp(1j * qGr_R)

        # phase = sum exp(iq.R_i)
        return drho_R


    def get_induced_density_z(self, q, w):
        """Get induced density on z axis (summation over xy-plane). """

        drho_R = self.calculate_induced_density(q, w)

        drho_z = np.zeros(self.gd.N_c[2],dtype=complex)
#        dxdy = np.cross(self.h_c[0], self.h_c[1])

        for iz in range(self.gd.N_c[2]):
            drho_z[iz] = drho_R[:,:,iz].sum()

        return drho_z

    def get_eigenmodes(self,filename = None, chi0 = None, calc = None, dm = None, 
                       xc = 'RPA', sum = None, vcut = None, checkphase = False, 
                       return_full = False):
        """
        Calculate the plasmonic eigenmodes as eigenvectors of the dielectric matrix.  

        Parameters:

        filename:  pckl file
                   output from response calculation.
         
        chi0:  gpw file
               chi0_wGG from response calculation.

        calc:  gpaw calculator instance
               ground state calculator used in response calculation.
               Wavefunctions only needed if chi0 is calculated from scratch

        dm:  gpw file
             dielectric matrix from response calculation

        xc:  str 'RPA'or 'ALDA' XC- Kernel
        
        sum:  str
              '2D': sum in the x and y directions
              '1D': To be implemented

        vcut:  str '0D','1D' or '2D'
               Cut the Coulomb potential 

        checkphase:   Bool
                      if True, the eigenfunctions id rotated in the complex
                      plane, to be made as real as posible

        return_full:  Bool
                      if True, the eigenvectors in reciprocal space is also
                      returned. 
           
        """
        self.read(filename)
        self.pbc = [1,1,1]
        #self.calc.atoms.pbc = [1,1,1]
        npw = self.npw
        self.w_w = np.linspace(0, self.dw * (self.Nw - 1)*Hartree, self.Nw)
        self.vcut = vcut
        dm_wGG = self.get_dielectric_matrix(xc=xc,
                                            symmetric=False,
                                            chi0_wGG=chi0,
                                            calc=calc,
                                            vcut=vcut)
    
        q = self.q_c
        

        # get grid on which the eigenmodes are calculated
        #gd = self.calc.wfs.gd
        #r = gd.get_grid_point_coordinates()
        #rrr = r*Bohr 
        from gpaw.utilities.gpts import get_number_of_grid_points
        from gpaw.grid_descriptor import GridDescriptor
        grid_size = [1,1,1]
        h=0.2
        cell_cv = self.acell_cv*np.diag(grid_size)
        mode = 'fd'
        realspace = True
        h /= Bohr
        N_c = get_number_of_grid_points(cell_cv, h, mode, realspace)
        gd = GridDescriptor(N_c, cell_cv, self.pbc) 
        #gd = self.calc.wfs.gd
        r = gd.get_grid_point_coordinates()
        rrr = r*Bohr
        
        eig_0 = np.array([], dtype = complex)
        eig_left = np.array([], dtype = complex)
        eig_right = np.array([], dtype = complex)
        vec_modes = np.zeros([1, self.npw], dtype = complex)
        vec_modes_dual = np.zeros([1, self.npw], dtype = complex)
        vec_modes_density = np.zeros([1, self.npw], dtype = complex)
        vec_modes_norm = np.zeros([1, self.npw], dtype = complex)
        eig_all = np.zeros([1, self.npw], dtype = complex)
        eig_dummy = np.zeros([1, self.npw], dtype = complex)
        v_dummy = np.zeros([1, self.npw], dtype = complex)
        vec_dummy = np.zeros([1, self.npw], dtype = complex)
        vec_dummy2 = np.zeros([1, self.npw], dtype = complex)
        w_0 = np.array([]) 
        w_left = np.array([])
        w_right = np.array([])
     
        if sum == '2D':
            v_ind = np.zeros([1, r.shape[-1]], dtype = complex)
            n_ind = np.zeros([1, r.shape[-1]], dtype = complex)
        elif sum == '1D':            
            self.printtxt('1D sum not implemented')
            return 
        else:
            v_ind = np.zeros([1, r.shape[1], r.shape[2], r.shape[3]], dtype = complex)
            n_ind = np.zeros([1, r.shape[1], r.shape[2], r.shape[3]], dtype = complex)

        eps_GG_plus = dm_wGG[0]
        eig_plus, vec_plus = np.linalg.eig(eps_GG_plus)  # find eigenvalues and eigenvectors
        vec_plus_dual = np.linalg.inv(vec_plus)
        
        # loop over frequencies, where the eigenvalues for the 2D matrix in G,G' are found.
        for i in np.array(range(self.Nw-1))+1:
            eps_GG = eps_GG_plus
            eig, vec = eig_plus,vec_plus
            vec_dual = vec_plus_dual
            eps_GG_plus = dm_wGG[i] # epsilon_GG'(omega + d-omega)
            eig_plus, vec_plus = np.linalg.eig(eps_GG_plus)
            vec_plus_dual = np.linalg.inv(vec_plus)
            eig_dummy[0,:] = eig
            eig_all = np.append(eig_all, eig_dummy, axis=0) # append all eigenvalues to array         
            # loop to check find the eigenvalues that crosses zero from negative to positive values:
            for k in range(self.npw):
                for m in range(self.npw):
                    if eig[k]< 0 and 0 < eig_plus[m]:
                        # check it's the same mode - Overlap between eigenvectors should be large:
                        if abs(np.inner(vec[:,k], vec_plus_dual[m,:])) > 0.95:                             
                            self.printtxt('crossing found at w = %1.1f eV'%self.w_w[i-1])
                            eig_left = np.append(eig_left, eig[k])   
                            eig_right = np.append(eig_right, eig_plus[m])

                            vec_dummy[0, :] = vec[:,k]
                            vec_modes = np.append(vec_modes, vec_dummy, axis = 0)
                            vec_dummy[0, :] = vec_dual[k, :].T
                            vec_modes_dual = np.append(vec_modes_dual, vec_dummy, axis = 0)
                                                   
                            w1 = self.w_w[i-1]
                            w2 = self.w_w[i]
                            a = np.real((eig_plus[m]-eig[k]) / (w2-w1))
                            w0 = np.real(-eig[k]) / a + w1
                            eig0 = a*(w0-w1)+eig[k]

                            w_0 = np.append(w_0,w0)
                            w_left = np.append(w_left, w1)
                            eig_0 = np.append(eig_0,eig0)                           

                            n_dummy = np.zeros([1, r.shape[1], r.shape[2],
                                                r.shape[3]], dtype = complex)
                            v_dummy = np.zeros([1, r.shape[1], r.shape[2],
                                                r.shape[3]], dtype = complex)    

                            vec_n = np.zeros([self.npw])
                            
                            for iG in range(self.npw):  # Fourier transform
                                qG = np.dot((q + self.Gvec_Gc[iG]), self.bcell_cv)
                                coef_G = np.dot(qG, qG) / (4 * pi)
                                qGr_R = np.inner(qG, r.T).T
                                v_dummy += vec[iG, k] * np.exp(1j * qGr_R) 
                                n_dummy += vec[iG, k] * np.exp(1j * qGr_R) * coef_G
                                                        
                            if checkphase: # rotate eigenvectors in complex plane 
                                integral = np.zeros([81])
                                phases = np.linspace(0,2,81)
                                for ip in range(81):
                                    v_int = v_dummy * np.exp(1j * pi * phases[ip])
                                    integral[ip] = abs(np.imag(v_int)).sum()                                     
                                phase = phases[np.argsort(integral)][0]
                                
                                v_dummy *= np.exp(1j * pi * phase)
                                n_dummy *= np.exp(1j * pi * phase)
                                

                            if sum == '2D':
                                i_xyz = 3 
                                v_dummy_z = np.zeros([1,v_dummy.shape[i_xyz]],
                                                     dtype = complex)
                                n_dummy_z = np.zeros([1,v_dummy.shape[i_xyz]],
                                                     dtype = complex)
                                v_dummy_z[0,:] = np.sum(np.sum(v_dummy, axis = 1),
                                                        axis = 1)[0,:]
                                n_dummy_z[0,:] = np.sum(np.sum(n_dummy, axis = 1),
                                                        axis = 1)[0,:]

                                v_ind = np.append(v_ind, v_dummy_z, axis=0)
                                n_ind = np.append(n_ind, n_dummy_z, axis=0)
                                                    
                            elif sum == '1D':
                                self.printtxt('1D sum not implemented')
                            else :
                                v_ind = np.append(v_ind, v_dummy, axis=0)
                                n_ind = np.append(n_ind, n_dummy, axis=0)
            
        """                        
        returns: grid points, frequency grid, all eigenvalues, mode energies, left point energies,
                 mode eigenvalues, eigenvalues of left and right-side points,
                 (mode eigenvectors, mode dual eigenvectors,)
                 induced potential in real space, induced density in real space
        """
        
        if return_full:
            return rrr, self.w_w, eig_all[1:], w_0, eig_0, w_left, eig_left, \
               eig_right, vec_modes[1:], vec_modes_dual[1:], v_ind[1:], n_ind[1:]
            
        else:
            return rrr, self.w_w, eig_all[1:], w_0, eig_0, w_left, eig_left, \
               eig_right, v_ind[1:], n_ind[1:]
                        
        
    def project_chi_to_LCAO_pair_orbital(self, orb_MG):

        nLCAO = orb_MG.shape[0]
        N = np.zeros((self.Nw, nLCAO, nLCAO), dtype=complex)

        kcoulinv_GG = np.zeros((self.npw, self.npw))
        for iG in range(self.npw):
            qG = np.dot(self.q_c + self.Gvec_Gc[iG], self.bcell_cv)
            kcoulinv_GG[iG, iG] = np.dot(qG, qG)

        kcoulinv_GG /= 4.*pi

        dm_wGG = self.get_RPA_dielectric_matrix()

        for mu in range(nLCAO):
            for nu in range(nLCAO):
                pairorb_R = orb_MG[mu] * orb_MG[nu]
                if not (pairorb_R * pairorb_R.conj() < 1e-10).all():
                    tmp_G = np.fft.fftn(pairorb_R) * self.vol / self.nG0

                    pairorb_G = np.zeros(self.npw, dtype=complex)
                    for iG in range(self.npw):
                        index = self.Gindex[iG]
                        pairorb_G[iG] = tmp_G[index[0], index[1], index[2]]

                    for iw in range(self.Nw):
                        chi_GG = (dm_wGG[iw] - np.eye(self.npw)) * kcoulinv_GG
                        N[iw, mu, nu] = (np.outer(pairorb_G.conj(), pairorb_G) * chi_GG).sum()
#                        N[iw, mu, nu] = np.inner(pairorb_G.conj(),np.inner(pairorb_G, chi_GG))

        return N


    def write(self, filename, all=False):
        """Dump essential data"""

        data = {'nbands': self.nbands,
                'acell': self.acell_cv, #* Bohr,
                'bcell': self.bcell_cv, #/ Bohr,
                'h_cv' : self.gd.h_cv,   #* Bohr,
                'nG'   : self.gd.N_c,
                'nG0'  : self.nG0,
                'vol'  : self.vol,   #* Bohr**3,
                'BZvol': self.BZvol, #/ Bohr**3,
                'nkpt' : self.kd.nbzkpts,
                'ecut' : self.ecut,  #* Hartree,
                'npw'  : self.npw,
                'eta'  : self.eta,   #* Hartree,
                'ftol' : self.ftol,
                'Nw'   : self.Nw,
                'NwS'  : self.NwS,
                'dw'   : self.dw,    # * Hartree,
                'q_red': self.q_c,
                'q_car': self.qq_v,    # / Bohr,
                'qmod' : np.dot(self.qq_v, self.qq_v), # / Bohr
                'vcut' : self.vcut,
                'pbc'  : self.pbc,
                'nvalence'     : self.nvalence,                
                'hilbert_trans' : self.hilbert_trans,
                'optical_limit' : self.optical_limit,
                'e_skn'         : self.e_skn,          # * Hartree,
                'f_skn'         : self.f_skn,
                'bzk_kc'       : self.kd.bzk_kc,
                'ibzk_kc'      : self.kd.ibzk_kc,
                'kq_k'         : self.kq_k,
                'Gvec_Gc'      : self.Gvec_Gc,
                'dfNLFRPA_w'   : self.df1_w,
                'dfLFCRPA_w'   : self.df2_w,
                'dfNLFALDA_w'  : self.df3_w,
                'dfLFCALDA_w'  : self.df4_w,
                'df_flag'      : True}

        if all:
            from gpaw.response.parallel import par_write
            par_write('chi0' + filename,'chi0_wGG',self.wcomm,self.chi0_wGG)
        
        if rank == 0:
            pickle.dump(data, open(filename, 'w'), -1)

        self.comm.barrier()


    def read(self, filename):
        """Read data from pickle file"""

        data = pickle.load(open(filename))
        
        self.nbands = data['nbands']
        self.acell_cv = data['acell']
        self.bcell_cv = data['bcell']
        self.nG0   = data['nG0']
        self.vol   = data['vol']
        self.BZvol = data['BZvol']
        self.ecut  = data['ecut']
        self.npw   = data['npw']
        self.eta   = data['eta']
        self.ftol  = data['ftol']
        self.Nw    = data['Nw']
        self.NwS   = data['NwS']
        self.dw    = data['dw']
        self.q_c   = data['q_red']
        self.qq_v  = data['q_car']
        self.qmod  = data['qmod']
        #self.vcut  = data['vcut']
        #self.pbc = data['pbc']
        
        self.hilbert_trans = data['hilbert_trans']
        self.optical_limit = data['optical_limit']
      
        self.e_skn  = data['e_skn']
        self.f_skn  = data['f_skn']
                
        self.nvalence= data['nvalence']
        self.kq_k    = data['kq_k']
        self.Gvec_Gc  = data['Gvec_Gc']
        self.df1_w   = data['dfNLFRPA_w']
        self.df2_w   = data['dfLFCRPA_w']
        self.df3_w   = data['dfNLFALDA_w']
        self.df4_w   = data['dfLFCALDA_w']
        self.df_flag = data['df_flag']
        
        self.printtxt('Read succesfully !')
示例#20
0
from __future__ import print_function
from math import sqrt, pi
import numpy as np
from gpaw.setup import create_setup
from gpaw.grid_descriptor import GridDescriptor
from gpaw.localized_functions import create_localized_functions
from gpaw.xc import XC

n = 60  #40 /8 * 10
a = 10.0
gd = GridDescriptor((n, n, n), (a, a, a))
c_LL = np.identity(9, float)
a_Lg = gd.zeros(9)
nspins = 2
xc = XC('LDA')
for soft in [False]:
    s = create_setup('Cu', xc, lmax=2)
    ghat_l = s.ghat_l
    ghat_Lg = create_localized_functions(ghat_l, gd, (0.54321, 0.5432, 0.543))
    a_Lg[:] = 0.0
    ghat_Lg.add(a_Lg, c_LL)
    for l in range(3):
        for m in range(2 * l + 1):
            L = l**2 + m
            a_g = a_Lg[L]
            Q0 = gd.integrate(a_g) / sqrt(4 * pi)
            Q1_m = -gd.calculate_dipole_moment(a_g) / sqrt(4 * pi / 3)
            print(Q0)
            if l == 0:
                Q0 -= 1.0
                Q1_m[:] = 0.0
示例#21
0
from __future__ import print_function
import numpy as np
from gpaw.lfc import LocalizedFunctionsCollection as LFC
from gpaw.grid_descriptor import GridDescriptor
from gpaw.spline import Spline
gd = GridDescriptor([20, 16, 16], [(4, 2, 0), (0, 4, 0), (0, 0, 4)])
spos_ac = np.array([[0.252, 0.15, 0.35], [0.503, 0.5, 0.5]])
s = Spline(l=0, rmax=2.0, f_g=np.array([1, 0.9, 0.1, 0.0]))
spline_aj = [[s], [s]]
c = LFC(gd, spline_aj)
c.set_positions(spos_ac)
c_ai = c.dict(zero=True)
if 1 in c_ai:
    c_ai[1][0] = 2.0
psi = gd.zeros()
c.add(psi, c_ai)

d_avv = dict([(a, np.zeros((3, 3))) for a in c.my_atom_indices])
c.second_derivative(psi, d_avv)

if 0 in d_avv:
    print(d_avv[0])

eps = 0.000001
d_aiv = c.dict(derivative=True)
pos_av = np.dot(spos_ac, gd.cell_cv)
for v in range(3):
    pos_av[0, v] += eps
    c.set_positions(np.dot(pos_av, gd.icell_cv.T))
    c.derivative(psi, d_aiv)
    if 0 in d_aiv:
示例#22
0
from gpaw.spline import Spline
a = 4.0
gd = GridDescriptor(N_c=[16, 20, 20],
                    cell_cv=[a, a + 1, a + 2],
                    pbc_c=(0, 1, 1))
spos_ac = np.array([[0.25, 0.15, 0.35], [0.5, 0.5, 0.5]])
kpts_kc = None
s = Spline(l=0, rmax=2.0, f_g=np.array([1, 0.9, 0.1, 0.0]))
p = Spline(l=1, rmax=2.0, f_g=np.array([1, 0.9, 0.1, 0.0]))
spline_aj = [[s], [s, p]]
c = LFC(gd, spline_aj, cut=True, forces=True)
c.set_positions(spos_ac)
C_ani = c.dict(3, zero=True)
if 1 in C_ani:
    C_ani[1][:, 1:] = np.eye(3)
psi = gd.zeros(3)
c.add(psi, C_ani)
c.integrate(psi, C_ani)
if 1 in C_ani:
    d = C_ani[1][:, 1:].diagonal()
    assert d.ptp() < 4e-6
    C_ani[1][:, 1:] -= np.diag(d)
    assert abs(C_ani[1]).max() < 5e-17
d_aniv = c.dict(3, derivative=True)
c.derivative(psi, d_aniv)
if 1 in d_aniv:
    for v in range(3):
        assert abs(d_aniv[1][v - 1, 0, v] + 0.2144) < 5e-5
        d_aniv[1][v - 1, 0, v] = 0
    assert abs(d_aniv[1]).max() < 3e-16
eps = 0.0001
示例#23
0
文件: timing.py 项目: yihsuanliu/gpaw
# Copyright (C) 2003  CAMP
# Please see the accompanying LICENSE file for further information.

from gpaw.grid_descriptor import GridDescriptor
from gpaw.transformers import Transformer
import time


n = 6
gda = GridDescriptor((n,n,n))
gdb = gda.refine()
gdc = gdb.refine()
a = gda.zeros()
b = gdb.zeros()
c = gdc.zeros()

inter = Transformer(gdb, gdc, 2).apply
restr = Transformer(gdb, gda, 2).apply

t = time.clock()
for i in range(8*300):
    inter(b, c)
print time.clock() - t

t = time.clock()
for i in range(8*3000):
    restr(b, a)
print time.clock() - t
示例#24
0
def dummy_kpt_test():
    l = 0
    rcut = 6.
    a = 5.
    k_kc = [(.5, .5, .5)]#[(0., 0., 0.), (0.5, 0.5, 0.5)]
    kcount = len(k_kc)
    dtype = complex
    r = np.arange(0., rcut, .01)

    spos_ac_ref = [(0., 0., 0.)]#, (.2, .2, .2)]
    spos_ac = [(0., 0., 0.), (.2, .2, .2)]


    ngaussians = 4
    realgaussindex = (ngaussians - 1) / 2

    rchars = np.linspace(1., rcut, ngaussians)
    splines = []
    gaussians = [QuasiGaussian(1./rch**2., rcut) for rch in rchars]
    for g in gaussians:
        norm = get_norm(r, g(r), l)
        g.renormalize(norm)
        spline = Spline(l, r[-1], g(r))
        splines.append(spline)

    refgauss = gaussians[realgaussindex]
    refspline = splines[realgaussindex]

    gd = GridDescriptor((60, 60, 60), (a,a,a), (1,1,1))

    reflf_a = [create_localized_functions([refspline], gd, spos_c, dtype=dtype)
               for spos_c in spos_ac_ref]
    for reflf in reflf_a:
        reflf.set_phase_factors(k_kc)

    kpt_u = [KPoint([], gd, 1., 0, k, k, k_c, dtype)
             for k, k_c in enumerate(k_kc)]
    
    for kpt in kpt_u:
        kpt.allocate(1)
        kpt.f_n[0] = 1.
        psit_nG = gd.zeros(1, dtype=dtype)
        coef_xi = np.identity(1, dtype=dtype)
        integral = np.zeros((1, 1), dtype=dtype)
        for reflf in reflf_a:
            reflf.add(psit_nG, coef_xi, k=kpt.k)
            reflf.integrate(psit_nG, integral, k=kpt.k)
        kpt.psit_nG = psit_nG
        print 'ref norm', integral

    print 'calculating overlaps'
    os_kmii, oS_kmii = overlaps(l, gd, splines, kpt_u,
                                spos_ac=spos_ac_ref)
    print 'done'

    lf_a = [create_localized_functions(splines, gd, spos_c, dtype=dtype)
            for spos_c in spos_ac]
    for lf in lf_a:
        lf.set_phase_factors(k_kc)

    s_kii = np.zeros((kcount, ngaussians, ngaussians), dtype=dtype)
    S_kii = np.zeros((kcount, ngaussians, ngaussians), dtype=dtype)

    for kpt in kpt_u:
        k = kpt.k
        all_integrals = np.zeros((1, ngaussians), dtype=dtype)
        tempgrids = gd.zeros(ngaussians, dtype=dtype)
        tempcoef_xi = np.identity(ngaussians, dtype=dtype)
        for lf in lf_a:
            lf.integrate(kpt.psit_nG, all_integrals, k=k)
            lf.add(tempgrids, tempcoef_xi, k=k)
            lf.integrate(tempgrids, s_kii[k], k=k)

        print 'all <phi|psi>'
        print all_integrals

        conj_integrals = np.conj(all_integrals)
        for i in range(ngaussians):
            for j in range(ngaussians):
                S_kii[k, i, j] = conj_integrals[0, i] * all_integrals[0, j]

    print 'handmade s_kmii'
    print s_kii

    print 'handmade S_ii'
    print S_kii

    s_kmii = s_kii.reshape(kcount, 1, ngaussians, ngaussians)
    S_kmii = S_kii.reshape(kcount, 1, ngaussians, ngaussians)

    print 'matrices from overlap function'
    print 's_kmii'
    print os_kmii
    print 'S_kmii'
    print oS_kmii

    optimizer = CoefficientOptimizer(s_kmii, S_kmii, ngaussians)
    coefficients = optimizer.find_coefficients()

    optimizer2 = CoefficientOptimizer(os_kmii, oS_kmii, ngaussians)
    coefficients2 = optimizer2.find_coefficients()

    print 'coefs'
    print coefficients
    print 'overlaps() coefs'
    print coefficients2
    print 'badness'
    print optimizer.evaluate(coefficients)
    exactsolution = [0.] * ngaussians
    exactsolution[realgaussindex] = 1.
    print 'badness of exact solution'
    print optimizer.evaluate(exactsolution)

    orbital = LinearCombination(coefficients, gaussians)
    orbital2 = LinearCombination(coefficients2, gaussians)
    norm = get_norm(r, orbital(r), l)
    norm2 = get_norm(r, orbital2(r), l)
    orbital.renormalize(norm)
    orbital2.renormalize(norm2)

    import pylab
    pylab.plot(r, refgauss(r), label='ref')
    pylab.plot(r, orbital(r), label='opt')
    pylab.plot(r, orbital2(r), '--', label='auto')
    pylab.legend()
    pylab.show()
示例#25
0
from math import sqrt, pi
import numpy as np
from gpaw.setup import create_setup
from gpaw.grid_descriptor import GridDescriptor
from gpaw.localized_functions import create_localized_functions
from gpaw.xc import XC

n = 60#40 /8 * 10
a = 10.0
gd = GridDescriptor((n, n, n), (a, a, a))
c_LL = np.identity(9, float)
a_Lg = gd.zeros(9)
nspins = 2
xc = XC('LDA')
for soft in [False]:
    s = create_setup('Cu', xc, lmax=2)
    ghat_l = s.ghat_l
    ghat_Lg = create_localized_functions(ghat_l, gd, (0.54321, 0.5432, 0.543))
    a_Lg[:] = 0.0
    ghat_Lg.add(a_Lg, c_LL)
    for l in range(3):
        for m in range(2 * l + 1):
            L = l**2 + m
            a_g = a_Lg[L]
            Q0 = gd.integrate(a_g) / sqrt(4 * pi)
            Q1_m = -gd.calculate_dipole_moment(a_g) / sqrt(4 * pi / 3)
            print Q0
            if l == 0:
                Q0 -= 1.0
                Q1_m[:] = 0.0
            elif l == 1:
示例#26
0
           ]])]

for name, D, cell in cells:
    if name == 'Jelver':
        # Strange one!
        continue

    print('------------------')
    print(name, D)
    print(cell[0])
    print(cell[1])
    print(cell[2])
    for n in range(1, 6):
        N = 2 * n + 2
        gd = GridDescriptor((N, N, N), cell)
        b_g = gd.zeros()
        r_gv = gd.get_grid_point_coordinates().transpose((1, 2, 3, 0))
        c_v = gd.cell_cv.sum(0) / 2
        r_gv -= c_v
        lap = Laplace(gd, n=n)
        grad_v = [Gradient(gd, v, n=n) for v in range(3)]
        assert lap.npoints == D * 2 * n + 1
        for m in range(0, 2 * n + 1):
            for ix in range(m + 1):
                for iy in range(m - ix + 1):
                    iz = m - ix - iy
                    a_g = (r_gv**(ix, iy, iz)).prod(3)
                    if ix + iy + iz == 2 and max(ix, iy, iz) == 2:
                        r = 2.0
                    else:
                        r = 0.0
示例#27
0
class UTDomainParallelSetup(TestCase):
    """
    Setup a simple domain parallel calculation."""

    # Number of bands
    nbands = 1

    # Spin-paired
    nspins = 1

    # Mean spacing and number of grid points per axis
    h = 0.2 / Bohr

    # Generic lattice constant for unit cell
    a = 5.0 / Bohr

    # Type of boundary conditions employed
    boundaries = None

    # Type of unit cell employed
    celltype = None

    def setUp(self):
        for virtvar in ['boundaries', 'celltype']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        # Basic unit cell information:
        pbc_c = {'zero'    : (False,False,False), \
                 'periodic': (True,True,True), \
                 'mixed'   : (True, False, True)}[self.boundaries]
        a, b = self.a, 2**0.5*self.a
        cell_cv = {'general'   : np.array([[0,a,a],[a/2,0,a/2],[a/2,a/2,0]]),
                   'rotated'   : np.array([[0,0,b],[b/2,0,0],[0,b/2,0]]),
                   'inverted'   : np.array([[0,0,b],[0,b/2,0],[b/2,0,0]]),
                   'orthogonal': np.diag([b, b/2, b/2])}[self.celltype]
        cell_cv = np.array([(4-3*pbc)*c_v for pbc,c_v in zip(pbc_c, cell_cv)])

        # Decide how many kpoints to sample from the 1st Brillouin Zone
        kpts_c = np.ceil((10/Bohr)/np.sum(cell_cv**2,axis=1)**0.5).astype(int)
        kpts_c = tuple(kpts_c*pbc_c + 1-pbc_c)
        bzk_kc = kpts2ndarray(kpts_c)
        self.gamma = len(bzk_kc) == 1 and not bzk_kc[0].any()

        #p = InputParameters()
        #Z_a = self.atoms.get_atomic_numbers()
        #xcfunc = XC(p.xc)
        #setups = Setups(Z_a, p.setups, p.basis, p.lmax, xcfunc)
        #symmetry, weight_k, self.ibzk_kc = reduce_kpoints(self.atoms, bzk_kc,
        #                                                  setups, p.usesymm)

        self.ibzk_kc = bzk_kc.copy() # don't use symmetry reduction of kpoints
        self.nibzkpts = len(self.ibzk_kc)
        self.ibzk_kv = kpoint_convert(cell_cv, skpts_kc=self.ibzk_kc)

        # Parse parallelization parameters and create suitable communicators.
        #parsize, parsize_bands = create_parsize_minbands(self.nbands, world.size)
        parsize, parsize_bands = world.size//gcd(world.size, self.nibzkpts), 1
        assert self.nbands % np.prod(parsize_bands) == 0
        domain_comm, kpt_comm, band_comm = distribute_cpus(parsize,
            parsize_bands, self.nspins, self.nibzkpts)

        # Set up band descriptor:
        self.bd = BandDescriptor(self.nbands, band_comm)

        # Set up grid descriptor:
        N_c = np.round(np.sum(cell_cv**2, axis=1)**0.5 / self.h)
        N_c += 4-N_c % 4 # makes domain decomposition easier
        self.gd = GridDescriptor(N_c, cell_cv, pbc_c, domain_comm, parsize)
        self.assertEqual(self.gamma, np.all(~self.gd.pbc_c))

        # What to do about kpoints?
        self.kpt_comm = kpt_comm

        if debug and world.rank == 0:
            comm_sizes = tuple([comm.size for comm in [world, self.bd.comm, \
                                                   self.gd.comm, self.kpt_comm]])
            print '%d world, %d band, %d domain, %d kpt' % comm_sizes

    def tearDown(self):
        del self.ibzk_kc, self.ibzk_kv, self.bd, self.gd, self.kpt_comm

    # =================================

    def verify_comm_sizes(self):
        if world.size == 1:
            return
        comm_sizes = tuple([comm.size for comm in [world, self.bd.comm, \
                                                   self.gd.comm, self.kpt_comm]])
        self._parinfo =  '%d world, %d band, %d domain, %d kpt' % comm_sizes
        self.assertEqual(self.nbands % self.bd.comm.size, 0)
        self.assertEqual((self.nspins*self.nibzkpts) % self.kpt_comm.size, 0)

    def verify_grid_volume(self):
        gdvol = np.prod(self.gd.get_size_of_global_array())*self.gd.dv
        self.assertAlmostEqual(self.gd.integrate(1+self.gd.zeros()), gdvol, 10)

    def verify_grid_point(self):
        # Volume integral of cartesian coordinates of all available grid points
        gdvol = np.prod(self.gd.get_size_of_global_array())*self.gd.dv
        cmr_v = self.gd.integrate(self.gd.get_grid_point_coordinates()) / gdvol

        # Theoretical center of cell based on all available grid data
        cm0_v = np.dot((0.5*(self.gd.get_size_of_global_array()-1.0) \
            + 1.0-self.gd.pbc_c) / self.gd.N_c, self.gd.cell_cv)

        self.assertAlmostEqual(np.abs(cmr_v-cm0_v).max(), 0, 10)

    def verify_non_pbc_spacing(self):
        atoms = create_random_atoms(self.gd, 1000, 'NH3', self.a/2)
        pos_ac = atoms.get_positions()
        cellvol = np.linalg.det(self.gd.cell_cv)
        if debug: print 'cell volume:', np.abs(cellvol)*Bohr**3, 'Ang^3', cellvol>0 and '(right handed)' or '(left handed)'

        # Loop over non-periodic axes and check minimum distance requirement
        for c in np.argwhere(~self.gd.pbc_c).ravel():
            a_v = self.gd.cell_cv[(c+1)%3]
            b_v = self.gd.cell_cv[(c+2)%3]
            c_v = np.cross(a_v, b_v)
            for d in range(2):
                # Inwards unit normal vector of d'th cell face of c'th axis
                # and point intersected by this plane (d=0,1 / bottom,top).
                n_v = np.sign(cellvol) * (1-2*d) * c_v / np.linalg.norm(c_v)
                if debug: print {0:'x',1:'y',2:'z'}[c]+'-'+{0:'bottom',1:'top'}[d]+':', n_v, 'Bohr'
                if debug: print 'gd.xxxiucell_cv[%d]~' % c, self.gd.xxxiucell_cv[c] / np.linalg.norm(self.gd.xxxiucell_cv[c]), 'Bohr'
                origin_v = np.dot(d * np.eye(3)[c], self.gd.cell_cv)
                d_a = np.dot(pos_ac/Bohr - origin_v[np.newaxis,:], n_v)
                if debug: print 'a:', self.a/2*Bohr, 'min:', np.min(d_a)*Bohr, 'max:', np.max(d_a)*Bohr
                self.assertAlmostEqual(d_a.min(), self.a/2, 0) #XXX digits!
示例#28
0
from __future__ import print_function
import numpy as np
from gpaw.grid_descriptor import GridDescriptor
from gpaw.xc.libvdwxc import vdw_df, vdw_df2, vdw_df_cx, \
    vdw_optPBE, vdw_optB88, vdw_C09, vdw_beef, \
    libvdwxc_has_mpi, libvdwxc_has_pfft

# This test verifies that the results returned by the van der Waals
# functionals implemented in libvdwxc do not change.

N_c = np.array([23, 10, 6])
gd = GridDescriptor(N_c, N_c * 0.2, pbc_c=(1, 0, 1))

n_sg = gd.zeros(1)
nG_sg = gd.collect(n_sg)
if gd.comm.rank == 0:
    gen = np.random.RandomState(0)
    nG_sg[:] = gen.rand(*nG_sg.shape)
gd.distribute(nG_sg, n_sg)

for mode in ['serial', 'mpi', 'pfft']:
    if mode == 'serial' and gd.comm.size > 1:
        continue
    if mode == 'mpi' and not libvdwxc_has_mpi():
        continue
    if mode == 'pfft' and not libvdwxc_has_pfft():
        continue

    def test(vdwxcclass, Eref=np.nan, nvref=np.nan):
        xc = vdwxcclass(mode=mode)
        xc._initialize(gd)
示例#29
0
from gpaw.fd_operators import Gradient
import numpy as np
from gpaw.grid_descriptor import GridDescriptor
from gpaw.mpi import world

if world.size > 4:
    # Grid is so small that domain decomposition cannot exceed 4 domains
    assert world.size % 4 == 0
    group, other = divmod(world.rank, 4)
    ranks = np.arange(4 * group, 4 * (group + 1))
    domain_comm = world.new_communicator(ranks)
else:
    domain_comm = world

gd = GridDescriptor((8, 1, 1), (8.0, 1.0, 1.0), comm=domain_comm)
a = gd.zeros()
dadx = gd.zeros()
a[:, 0, 0] = np.arange(gd.beg_c[0], gd.end_c[0])
gradx = Gradient(gd, v=0)
print a.itemsize, a.dtype, a.shape
print dadx.itemsize, dadx.dtype, dadx.shape
gradx.apply(a, dadx)

#   a = [ 0.  1.  2.  3.  4.  5.  6.  7.]
#
#   da
#   -- = [-2.5  1.   1.   1.   1.   1.  1.  -2.5]
#   dx

dadx = gd.collect(dadx, broadcast=True)
assert dadx[3, 0, 0] == 1.0 and np.sum(dadx[:, 0, 0]) == 0.0
示例#30
0
def dummy_kpt_test():
    l = 0
    rcut = 6.
    a = 5.
    k_kc = [(.5, .5, .5)]  #[(0., 0., 0.), (0.5, 0.5, 0.5)]
    kcount = len(k_kc)
    dtype = complex
    r = np.arange(0., rcut, .01)

    spos_ac_ref = [(0., 0., 0.)]  #, (.2, .2, .2)]
    spos_ac = [(0., 0., 0.), (.2, .2, .2)]

    ngaussians = 4
    realgaussindex = (ngaussians - 1) / 2

    rchars = np.linspace(1., rcut, ngaussians)
    splines = []
    gaussians = [QuasiGaussian(1. / rch**2., rcut) for rch in rchars]
    for g in gaussians:
        norm = get_norm(r, g(r), l)
        g.renormalize(norm)
        spline = Spline(l, r[-1], g(r))
        splines.append(spline)

    refgauss = gaussians[realgaussindex]
    refspline = splines[realgaussindex]

    gd = GridDescriptor((60, 60, 60), (a, a, a), (1, 1, 1))

    reflf_a = [
        create_localized_functions([refspline], gd, spos_c, dtype=dtype)
        for spos_c in spos_ac_ref
    ]
    for reflf in reflf_a:
        reflf.set_phase_factors(k_kc)

    kpt_u = [
        KPoint([], gd, 1., 0, k, k, k_c, dtype) for k, k_c in enumerate(k_kc)
    ]

    for kpt in kpt_u:
        kpt.allocate(1)
        kpt.f_n[0] = 1.
        psit_nG = gd.zeros(1, dtype=dtype)
        coef_xi = np.identity(1, dtype=dtype)
        integral = np.zeros((1, 1), dtype=dtype)
        for reflf in reflf_a:
            reflf.add(psit_nG, coef_xi, k=kpt.k)
            reflf.integrate(psit_nG, integral, k=kpt.k)
        kpt.psit_nG = psit_nG
        print 'ref norm', integral

    print 'calculating overlaps'
    os_kmii, oS_kmii = overlaps(l, gd, splines, kpt_u, spos_ac=spos_ac_ref)
    print 'done'

    lf_a = [
        create_localized_functions(splines, gd, spos_c, dtype=dtype)
        for spos_c in spos_ac
    ]
    for lf in lf_a:
        lf.set_phase_factors(k_kc)

    s_kii = np.zeros((kcount, ngaussians, ngaussians), dtype=dtype)
    S_kii = np.zeros((kcount, ngaussians, ngaussians), dtype=dtype)

    for kpt in kpt_u:
        k = kpt.k
        all_integrals = np.zeros((1, ngaussians), dtype=dtype)
        tempgrids = gd.zeros(ngaussians, dtype=dtype)
        tempcoef_xi = np.identity(ngaussians, dtype=dtype)
        for lf in lf_a:
            lf.integrate(kpt.psit_nG, all_integrals, k=k)
            lf.add(tempgrids, tempcoef_xi, k=k)
            lf.integrate(tempgrids, s_kii[k], k=k)

        print 'all <phi|psi>'
        print all_integrals

        conj_integrals = np.conj(all_integrals)
        for i in range(ngaussians):
            for j in range(ngaussians):
                S_kii[k, i, j] = conj_integrals[0, i] * all_integrals[0, j]

    print 'handmade s_kmii'
    print s_kii

    print 'handmade S_ii'
    print S_kii

    s_kmii = s_kii.reshape(kcount, 1, ngaussians, ngaussians)
    S_kmii = S_kii.reshape(kcount, 1, ngaussians, ngaussians)

    print 'matrices from overlap function'
    print 's_kmii'
    print os_kmii
    print 'S_kmii'
    print oS_kmii

    optimizer = CoefficientOptimizer(s_kmii, S_kmii, ngaussians)
    coefficients = optimizer.find_coefficients()

    optimizer2 = CoefficientOptimizer(os_kmii, oS_kmii, ngaussians)
    coefficients2 = optimizer2.find_coefficients()

    print 'coefs'
    print coefficients
    print 'overlaps() coefs'
    print coefficients2
    print 'badness'
    print optimizer.evaluate(coefficients)
    exactsolution = [0.] * ngaussians
    exactsolution[realgaussindex] = 1.
    print 'badness of exact solution'
    print optimizer.evaluate(exactsolution)

    orbital = LinearCombination(coefficients, gaussians)
    orbital2 = LinearCombination(coefficients2, gaussians)
    norm = get_norm(r, orbital(r), l)
    norm2 = get_norm(r, orbital2(r), l)
    orbital.renormalize(norm)
    orbital2.renormalize(norm2)

    import pylab
    pylab.plot(r, refgauss(r), label='ref')
    pylab.plot(r, orbital(r), label='opt')
    pylab.plot(r, orbital2(r), '--', label='auto')
    pylab.legend()
    pylab.show()
示例#31
0
from gpaw.transformers import Transformer
import numpy.random as ra
from gpaw.grid_descriptor import GridDescriptor

p = 0
n = 20
gd1 = GridDescriptor((n, n, n), (8.0, 8.0, 8.0), pbc_c=p)
a1 = gd1.zeros()
ra.seed(8)
a1[:] = ra.random(a1.shape)
gd2 = gd1.refine()
a2 = gd2.zeros()
i = Transformer(gd1, gd2).apply
i(a1, a2)
assert abs(gd1.integrate(a1) - gd2.integrate(a2)) < 1e-10
r = Transformer(gd2, gd1).apply
a2[0] = 0.0
a2[:, 0] = 0.0
a2[:, :, 0] = 0.0
a2[-1] = 0.0
a2[:, -1] = 0.0
a2[:, :, -1] = 0.0
r(a2, a1)
assert abs(gd1.integrate(a1) - gd2.integrate(a2)) < 1e-10
示例#32
0
def playground():
    np.set_printoptions(linewidth=176)
    #N_c = [4, 7, 9]
    N_c = [4, 4, 2]

    pbc_c = (1, 1, 1)

    # 210
    distribute_dir = 1
    reduce_dir = 0

    parsize_c = (2, 2, 2)
    parsize2_c = list(parsize_c)
    parsize2_c[reduce_dir] = 1
    parsize2_c[distribute_dir] *= parsize_c[reduce_dir]
    assert np.prod(parsize2_c) == np.prod(parsize_c)

    gd = GridDescriptor(N_c=N_c,
                        pbc_c=pbc_c,
                        cell_cv=0.2 * np.array(N_c),
                        parsize_c=parsize_c)

    gd2 = get_compatible_grid_descriptor(gd, distribute_dir, reduce_dir)

    src = gd.zeros(dtype=complex)
    src[:] = gd.comm.rank

    src_global = gd.collect(src)
    if gd.comm.rank == 0:
        ind = np.indices(src_global.shape)
        src_global += 1j * (ind[0] / 10. + ind[1] / 100. + ind[2] / 1000.)
        #src_global[1] += 0.5j
        print('GLOBAL ARRAY', src_global.shape)
        print(src_global.squeeze())
    gd.distribute(src_global, src)
    goal = gd2.zeros(dtype=float)
    goal[:] = gd.comm.rank  # get_members()[gd2.comm.rank]
    goal_global = gd2.collect(goal)
    if gd.comm.rank == 0:
        print('GOAL GLOBAL')
        print(goal_global.squeeze())
    gd.comm.barrier()
    #return

    recvbuf = redistribute(gd,
                           gd2,
                           src,
                           distribute_dir,
                           reduce_dir,
                           operation='forth')
    recvbuf_master = gd2.collect(recvbuf)
    if gd2.comm.rank == 0:
        print('RECV')
        print(recvbuf_master)
        err = src_global - recvbuf_master
        print('MAXERR', np.abs(err).max())

    hopefully_orig = redistribute(gd,
                                  gd2,
                                  recvbuf,
                                  distribute_dir,
                                  reduce_dir,
                                  operation='back')
    tmp = gd.collect(hopefully_orig)
    if gd.comm.rank == 0:
        print('FINALLY')
        print(tmp)
        err2 = src_global - tmp
        print('MAXERR', np.abs(err2).max())
示例#33
0
文件: fidi.py 项目: yihsuanliu/gpaw
from time import time
from gpaw.grid_descriptor import GridDescriptor
from gpaw.fd_operators import Laplace
import gpaw.mpi as mpi

n = 96
h = 0.1
L = n * h
gd = GridDescriptor((n, n, n), [L, L, L])

# Allocate arrays:
a = gd.zeros(100) + 1.2
b = gd.empty(100)

o = Laplace(gd, 2).apply

t0 = time()
for r in range(10):
    o(a, b)

if mpi.rank == 0:
    print time() - t0, a.shape
    
示例#34
0
文件: lfc.py 项目: thonmaker/gpaw
from gpaw.fftw import FFTPlan
print(FFTPlan)

for l in range(3):
    print(l)
    s = Spline(l, rc, 2 * x**1.5 / np.pi * np.exp(-x * r**2))

    lfc1 = LFC(gd, [[s]], kd, dtype=complex)
    lfc2 = PWLFC([[s]], pd)

    c_axi = {0: np.zeros((1, 2 * l + 1), complex)}
    c_axi[0][0, 0] = 1.9 - 4.5j
    c_axiv = {0: np.zeros((1, 2 * l + 1, 3), complex)}

    b1 = gd.zeros(1, dtype=complex)
    b2 = pd.zeros(1, dtype=complex)

    for lfc, b in [(lfc1, b1), (lfc2, b2)]:
        lfc.set_positions(spos_ac)
        lfc.add(b, c_axi, 0)

    b2 = pd.ifft(b2[0]) * eikr
    equal(abs(b2 - b1[0]).max(), 0, 0.001)

    b1 = eikr[None]
    b2 = pd.fft(b1[0] * 0 + 1).reshape((1, -1))

    results = []
    results2 = []
    for lfc, b in [(lfc1, b1), (lfc2, b2)]:
示例#35
0
from gpaw.fd_operators import Gradient
import numpy as np
from gpaw.grid_descriptor import GridDescriptor
from gpaw.mpi import world

if world.size > 4:
    # Grid is so small that domain decomposition cannot exceed 4 domains
    assert world.size % 4 == 0
    group, other = divmod(world.rank, 4)
    ranks = np.arange(4*group, 4*(group+1))
    domain_comm = world.new_communicator(ranks)
else:
    domain_comm = world

gd = GridDescriptor((8, 1, 1), (8.0, 1.0, 1.0), comm=domain_comm)
a = gd.zeros()
dadx = gd.zeros()
a[:, 0, 0] = np.arange(gd.beg_c[0], gd.end_c[0])
gradx = Gradient(gd, v=0)
print a.itemsize, a.dtype, a.shape
print dadx.itemsize, dadx.dtype, dadx.shape
gradx.apply(a, dadx)

#   a = [ 0.  1.  2.  3.  4.  5.  6.  7.]
#
#   da
#   -- = [-2.5  1.   1.   1.   1.   1.  1.  -2.5]
#   dx

dadx = gd.collect(dadx, broadcast=True)
assert dadx[3, 0, 0] == 1.0 and np.sum(dadx[:, 0, 0]) == 0.0
示例#36
0
from gpaw.response.math_func import two_phi_planewave_integrals

# Initialize s, p, d (9 in total) wave and put them on grid
rc = 2.0
a = 2.5 * rc
n = 64
lmax = 2
b = 8.0
m = (lmax + 1)**2
gd = GridDescriptor([n, n, n], [a, a, a])
r = np.linspace(0, rc, 200)
g = np.exp(-(r / rc * b)**2)
splines = [Spline(l=l, rmax=rc, f_g=g) for l in range(lmax + 1)]
c = LFC(gd, [splines])
c.set_positions([(0.5, 0.5, 0.5)])
psi = gd.zeros(m)
d0 = c.dict(m)
if 0 in d0:
    d0[0] = np.identity(m)
c.add(psi, d0)

# Calculate on 3d-grid < phi_i | e**(-ik.r) | phi_j >
R_a = np.array([a / 2, a / 2, a / 2])
rr = gd.get_grid_point_coordinates()
for dim in range(3):
    rr[dim] -= R_a[dim]

k_G = np.array([[11., 0.2, 0.1], [10., 0., 10.]])
nkpt = k_G.shape[0]

d0 = np.zeros((nkpt, m, m), dtype=complex)
示例#37
0
if size == 1:
    for name, D, cell in cells:
        if name == 'Jelver':
            # Strange one!
            continue
            
        print('------------------')
        print(name, D)
        print(cell[0])
        print(cell[1])
        print(cell[2])
        for n in range(1, 6):
            N = 2 * n + 2
            gd = GridDescriptor((N, N, N), cell)
            b_g = gd.zeros()
            r_gv = gd.get_grid_point_coordinates().transpose((1, 2, 3, 0))
            c_v = gd.cell_cv.sum(0) / 2
            r_gv -= c_v
            lap = Laplace(gd, n=n)
            grad_v = [Gradient(gd, v, n=n) for v in range(3)]
            assert lap.npoints == D * 2 * n + 1
            for m in range(0, 2 * n + 1):
                for ix in range(m + 1):
                    for iy in range(m - ix + 1):
                        iz = m - ix - iy
                        a_g = (r_gv**(ix, iy, iz)).prod(3)
                        if ix + iy + iz == 2 and max(ix, iy, iz) == 2:
                            r = 2.0
                        else:
                            r = 0.0
示例#38
0
class DF(CHI):
    """This class defines dielectric function related physical quantities."""
    def __init__(self,
                 calc=None,
                 nbands=None,
                 w=None,
                 q=None,
                 eshift=None,
                 ecut=10.,
                 density_cut=None,
                 G_plus_q=False,
                 eta=0.2,
                 rpad=None,
                 vcut=None,
                 ftol=1e-7,
                 txt=None,
                 xc='ALDA',
                 print_xc_scf=False,
                 hilbert_trans=True,
                 time_ordered=False,
                 optical_limit=False,
                 comm=None,
                 kcommsize=None):

        CHI.__init__(self,
                     calc=calc,
                     nbands=nbands,
                     w=w,
                     q=q,
                     eshift=eshift,
                     ecut=ecut,
                     density_cut=density_cut,
                     G_plus_q=G_plus_q,
                     eta=eta,
                     rpad=rpad,
                     vcut=vcut,
                     ftol=ftol,
                     txt=txt,
                     xc=xc,
                     hilbert_trans=hilbert_trans,
                     time_ordered=time_ordered,
                     optical_limit=optical_limit,
                     comm=comm,
                     kcommsize=kcommsize)

        self.df_flag = False
        self.print_bootstrap = print_xc_scf
        self.df1_w = None  # NLF RPA
        self.df2_w = None  # LF RPA
        self.df3_w = None  # NLF ALDA
        self.df4_w = None  # LF ALDA

    def get_dielectric_matrix(self,
                              xc='RPA',
                              overwritechi0=False,
                              symmetric=True,
                              chi0_wGG=None,
                              calc=None,
                              vcut=None,
                              dir=None):
        if self.chi0_wGG is None and chi0_wGG is None:
            self.initialize()
            self.calculate()
        elif self.chi0_wGG is None and chi0_wGG is not None:
            #Read from file and reinitialize
            self.xc = xc

            from gpaw.response.parallel import par_read
            self.chi0_wGG = par_read(chi0_wGG, 'chi0_wGG')
            self.nvalbands = self.nbands
            #self.parallel_init() # parallelization not yet implemented
            self.Nw_local = self.Nw  # parallelization not yet implemented
            if self.calc is None:
                from gpaw import GPAW
                self.calc = GPAW(calc, txt=None)
            if self.xc == 'ALDA' or self.xc == 'ALDA_X':
                from gpaw.response.kernel import calculate_Kxc
                from gpaw.grid_descriptor import GridDescriptor
                from gpaw.mpi import world, rank, size, serial_comm

                self.pbc = self.calc.atoms.pbc
                self.gd = GridDescriptor(self.calc.wfs.gd.N_c * self.rpad,
                                         self.acell_cv,
                                         pbc_c=True,
                                         comm=serial_comm)

                R_av = self.calc.atoms.positions / Bohr
                nt_sg = self.calc.density.nt_sG

                if (self.rpad > 1).any() or (self.pbc - True).any():
                    nt_sG = self.gd.zeros(self.nspins)
                    #nt_sG = np.zeros([self.nspins, self.nG[0], self.nG[1], self.nG[2]])
                    for s in range(self.nspins):
                        nt_G = self.pad(nt_sg[s])
                        nt_sG[s] = nt_G
                else:
                    nt_sG = nt_sg

                self.Kxc_sGG = calculate_Kxc(self.gd,
                                             nt_sG,
                                             self.npw,
                                             self.Gvec_Gc,
                                             self.gd.N_c,
                                             self.vol,
                                             self.bcell_cv,
                                             R_av,
                                             self.calc.wfs.setups,
                                             self.calc.density.D_asp,
                                             functional=self.xc,
                                             density_cut=self.density_cut)

        if overwritechi0:
            dm_wGG = self.chi0_wGG
        else:
            dm_wGG = np.zeros_like(self.chi0_wGG)

        if dir is None:
            q_c = self.q_c
        else:
            q_c = np.diag((1, 1, 1))[dir] * self.qopt
            self.chi0_wGG[:, 0, :] = self.chi00G_wGv[:, :, dir]
            self.chi0_wGG[:, :, 0] = self.chi0G0_wGv[:, :, dir]

        from gpaw.response.kernel import calculate_Kc, CoulombKernel
        kernel = CoulombKernel(vcut=self.vcut,
                               pbc=self.calc.atoms.pbc,
                               cell=self.acell_cv)
        self.Kc_GG = kernel.calculate_Kc(q_c,
                                         self.Gvec_Gc,
                                         self.bcell_cv,
                                         symmetric=symmetric)
        #self.Kc_GG = calculate_Kc(q_c,
        #                          self.Gvec_Gc,
        #                          self.acell_cv,
        #                          self.bcell_cv,
        #                          self.pbc,
        #                          self.vcut,
        #                          symmetric=symmetric)

        tmp_GG = np.eye(self.npw, self.npw)

        if xc == 'RPA':
            self.printtxt('Use RPA.')
            for iw in range(self.Nw_local):
                dm_wGG[iw] = tmp_GG - self.Kc_GG * self.chi0_wGG[iw]

        elif xc == 'ALDA':
            self.printtxt('Use ALDA kernel.')
            # E_LDA = 1 - v_c chi0 (1-fxc chi0)^-1
            # http://prb.aps.org/pdf/PRB/v33/i10/p7017_1 eq. 4
            A_wGG = self.chi0_wGG.copy()
            for iw in range(self.Nw_local):
                A_wGG[iw] = np.dot(
                    self.chi0_wGG[iw],
                    np.linalg.inv(tmp_GG -
                                  np.dot(self.Kxc_sGG[0], self.chi0_wGG[iw])))

            for iw in range(self.Nw_local):
                dm_wGG[iw] = tmp_GG - self.Kc_GG * A_wGG[iw]

        return dm_wGG

    def get_inverse_dielectric_matrix(self, xc='RPA'):

        dm_wGG = self.get_dielectric_matrix(xc=xc)
        dminv_wGG = np.zeros_like(dm_wGG)
        for iw in range(self.Nw_local):
            dminv_wGG[iw] = np.linalg.inv(dm_wGG[iw])
        return dminv_wGG

    def get_chi(self, xc='RPA'):
        """Solve Dyson's equation."""

        if self.chi0_wGG is None:
            self.initialize()
            self.calculate()
        else:
            pass  # read from file and re-initializing .... need to be implemented

        kernel_GG = np.zeros((self.npw, self.npw), dtype=complex)
        chi_wGG = np.zeros_like(self.chi0_wGG)

        # Coulomb kernel
        for iG in range(self.npw):
            qG = np.dot(self.q_c + self.Gvec_Gc[iG], self.bcell_cv)
            kernel_GG[iG, iG] = 4 * pi / np.dot(qG, qG)

        if xc == 'ALDA':
            kernel_GG += self.Kxc_sGG[0]

        for iw in range(self.Nw_local):
            tmp_GG = np.eye(self.npw, self.npw) - np.dot(
                self.chi0_wGG[iw], kernel_GG)
            chi_wGG[iw] = np.dot(np.linalg.inv(tmp_GG), self.chi0_wGG[iw])

        return chi_wGG

    def get_dielectric_function(self, xc='RPA', dir=None):
        """Calculate the dielectric function. Returns df1_w and df2_w.

        Parameters:

        df1_w: ndarray
            Dielectric function without local field correction.
        df2_w: ndarray
            Dielectric function with local field correction.
        """

        if not self.optical_limit:
            assert dir is None

        if self.df_flag is False:
            dm_wGG = self.get_dielectric_matrix(xc=xc, dir=dir)

            Nw_local = dm_wGG.shape[0]
            dfNLF_w = np.zeros(Nw_local, dtype=complex)
            dfLFC_w = np.zeros(Nw_local, dtype=complex)
            df1_w = np.zeros(self.Nw, dtype=complex)
            df2_w = np.zeros(self.Nw, dtype=complex)

            for iw in range(Nw_local):
                tmp_GG = dm_wGG[iw]
                dfLFC_w[iw] = 1. / np.linalg.inv(tmp_GG)[0, 0]
                dfNLF_w[iw] = tmp_GG[0, 0]

            self.wcomm.all_gather(dfNLF_w, df1_w)
            self.wcomm.all_gather(dfLFC_w, df2_w)

            if xc == 'RPA':
                self.df1_w = df1_w
                self.df2_w = df2_w
            elif xc == 'ALDA' or xc == 'ALDA_X':
                self.df3_w = df1_w
                self.df4_w = df2_w

        if xc == 'RPA':
            return self.df1_w, self.df2_w
        elif xc == 'ALDA' or xc == 'ALDA_X':
            return self.df3_w, self.df4_w

    def get_surface_response_function(self, z0=0., filename='surf_EELS'):
        """Calculate surface response function."""

        if self.chi0_wGG is None:
            self.initialize()
            self.calculate()

        g_w2 = np.zeros((self.Nw, 2), dtype=complex)
        assert self.acell_cv[0, 2] == 0. and self.acell_cv[1, 2] == 0.

        Nz = self.gd.N_c[2]  # number of points in z direction
        tmp = np.zeros(Nz, dtype=int)
        nGz = 0  # number of G_z
        for i in range(self.npw):
            if self.Gvec_Gc[i, 0] == 0 and self.Gvec_Gc[i, 1] == 0:
                tmp[nGz] = self.Gvec_Gc[i, 2]
                nGz += 1
        assert (np.abs(self.Gvec_Gc[:nGz, :2]) < 1e-10).all()

        for id, xc in enumerate(['RPA', 'ALDA']):
            chi_wGG = self.get_chi(xc=xc)

            # The first nGz are all Gx=0 and Gy=0 component
            chi_wgg_LFC = chi_wGG[:, :nGz, :nGz]
            del chi_wGG
            chi_wzz_LFC = np.zeros((self.Nw_local, Nz, Nz), dtype=complex)

            # Fourier transform of chi_wgg to chi_wzz
            Gz_g = tmp[:nGz] * self.bcell_cv[2, 2]
            z_z = np.linspace(0, self.acell_cv[2, 2] - self.gd.h_cv[2, 2], Nz)
            phase1_zg = np.exp(1j * np.outer(z_z, Gz_g))
            phase2_gz = np.exp(-1j * np.outer(Gz_g, z_z))

            for iw in range(self.Nw_local):
                chi_wzz_LFC[iw] = np.dot(np.dot(phase1_zg, chi_wgg_LFC[iw]),
                                         phase2_gz)
            chi_wzz_LFC /= self.acell_cv[2, 2]

            # Get surface response function

            z_z -= z0 / Bohr
            q_v = np.dot(self.q_c, self.bcell_cv)
            qq = sqrt(np.inner(q_v, q_v))
            phase1_1z = np.array([np.exp(qq * z_z)])
            phase2_z1 = np.exp(qq * z_z)

            tmp_w = np.zeros(self.Nw_local, dtype=complex)
            for iw in range(self.Nw_local):
                tmp_w[iw] = np.dot(np.dot(phase1_1z, chi_wzz_LFC[iw]),
                                   phase2_z1)[0]

            tmp_w *= -2 * pi / qq * self.gd.h_cv[2, 2]**2
            g_w = np.zeros(self.Nw, dtype=complex)
            self.wcomm.all_gather(tmp_w, g_w)
            g_w2[:, id] = g_w

        if rank == 0:
            f = open(filename, 'w')
            for iw in range(self.Nw):
                energy = iw * self.dw * Hartree
                print(energy,
                      np.imag(g_w2[iw, 0]),
                      np.imag(g_w2[iw, 1]),
                      file=f)
            f.close()

        # Wait for I/O to finish
        self.comm.barrier()

    def check_sum_rule(self, df1_w=None, df2_w=None):
        """Check f-sum rule."""

        if df1_w is None:
            df1_w = self.df1_w
            df2_w = self.df2_w

        N1 = N2 = 0
        for iw in range(self.Nw):
            w = iw * self.dw
            N1 += np.imag(df1_w[iw]) * w
            N2 += np.imag(df2_w[iw]) * w
        N1 *= self.dw * self.vol / (2 * pi**2)
        N2 *= self.dw * self.vol / (2 * pi**2)

        self.printtxt('')
        self.printtxt('Sum rule for ABS:')
        nv = self.nvalence
        self.printtxt('Without local field: N1 = %f, %f  %% error' %
                      (N1, (N1 - nv) / nv * 100))
        self.printtxt('Include local field: N2 = %f, %f  %% error' %
                      (N2, (N2 - nv) / nv * 100))

        N1 = N2 = 0
        for iw in range(self.Nw):
            w = iw * self.dw
            N1 -= np.imag(1 / df1_w[iw]) * w
            N2 -= np.imag(1 / df2_w[iw]) * w
        N1 *= self.dw * self.vol / (2 * pi**2)
        N2 *= self.dw * self.vol / (2 * pi**2)

        self.printtxt('')
        self.printtxt('Sum rule for EELS:')
        nv = self.nvalence
        self.printtxt('Without local field: N1 = %f, %f  %% error' %
                      (N1, (N1 - nv) / nv * 100))
        self.printtxt('Include local field: N2 = %f, %f  %% error' %
                      (N2, (N2 - nv) / nv * 100))

    def get_macroscopic_dielectric_constant(self, xc='RPA'):
        """Calculate macroscopic dielectric constant. Returns eM1 and eM2

        Macroscopic dielectric constant is defined as the real part of dielectric function at w=0.
        
        Parameters:

        eM1: float
            Dielectric constant without local field correction. (RPA, ALDA)
        eM2: float
            Dielectric constant with local field correction.

        """

        assert self.optical_limit
        self.printtxt('')
        self.printtxt('%s Macroscopic Dielectric Constant:' % xc)
        dirstr = ['x', 'y', 'z']

        for dir in range(3):

            eM = np.zeros(2)
            df1, df2 = self.get_dielectric_function(xc=xc, dir=dir)
            eps0 = np.real(df1[0])
            eps = np.real(df2[0])
            self.printtxt('  %s direction' % (dirstr[dir]))
            self.printtxt('    Without local field: %f' % eps0)
            self.printtxt('    Include local field: %f' % eps)

        return eps0, eps

    def get_absorption_spectrum(self, filename='Absorption.dat'):
        """Calculate optical absorption spectrum. By default, generate a file 'Absorption.dat'.

        Optical absorption spectrum is obtained from the imaginary part of dielectric function.
        """

        assert self.optical_limit
        for dir in range(3):
            df1, df2 = self.get_dielectric_function(xc='RPA', dir=dir)
            if self.xc == 'ALDA':
                df3, df4 = self.get_dielectric_function(xc='ALDA', dir=dir)
            if self.xc == 'ALDA_X':
                df3, df4 = self.get_dielectric_function(xc='ALDA_X', dir=dir)

            Nw = df1.shape[0]

            if self.xc == 'Bootstrap':
                # bootstrap doesnt support all direction spectra yet
                from gpaw.response.fxc import Bootstrap
                Kc_GG = np.zeros((self.npw, self.npw))
                q_c = np.diag((1, 1, 1))[dir] * self.qopt

                for iG in range(self.npw):
                    qG = np.dot(q_c + self.Gvec_Gc[iG], self.bcell_cv)
                    Kc_GG[iG, iG] = 4 * pi / np.dot(qG, qG)

                from gpaw.mpi import world
                assert self.wcomm.size == world.size
                df3 = Bootstrap(self.chi0_wGG, Nw, Kc_GG, self.printtxt,
                                self.print_bootstrap, self.wcomm)

            if rank == 0:
                f = open('%s.%s' % (filename, 'xyz'[dir]), 'w')
                #f = open(filename+'.%s'%(dirstr[dir]),'w') # ????
                for iw in range(Nw):
                    energy = iw * self.dw * Hartree
                    if self.xc == 'RPA':
                        print(energy, np.real(df1[iw]), np.imag(df1[iw]), \
                              np.real(df2[iw]), np.imag(df2[iw]), file=f)
                    elif self.xc == 'ALDA':
                        print(energy, np.real(df1[iw]), np.imag(df1[iw]), \
                          np.real(df2[iw]), np.imag(df2[iw]), \
                          np.real(df3[iw]), np.imag(df3[iw]), \
                          np.real(df4[iw]), np.imag(df4[iw]), file=f)
                    elif self.xc == 'Bootstrap':
                        print(energy, np.real(df1[iw]), np.imag(df1[iw]), \
                          np.real(df2[iw]), np.imag(df2[iw]), \
                          np.real(df3[iw]), np.imag(df3[iw]), file=f)
                f.close()

            # Wait for I/O to finish
            self.comm.barrier()

    def get_EELS_spectrum(self, filename='EELS.dat'):
        """Calculate EELS spectrum. By default, generate a file 'EELS.dat'.

        EELS spectrum is obtained from the imaginary part of the inverse of dielectric function.
        """

        # calculate RPA dielectric function
        df1, df2 = self.get_dielectric_function(xc='RPA')
        if self.xc == 'ALDA':
            df3, df4 = self.get_dielectric_function(xc='ALDA')
        Nw = df1.shape[0]

        if rank == 0:
            f = open(filename, 'w')
            for iw in range(self.Nw):
                energy = iw * self.dw * Hartree
                if self.xc == 'RPA':
                    print(energy,
                          -np.imag(1. / df1[iw]),
                          -np.imag(1. / df2[iw]),
                          file=f)
                elif self.xc == 'ALDA':
                    print(energy, -np.imag(1./df1[iw]), -np.imag(1./df2[iw]), \
                       -np.imag(1./df3[iw]), -np.imag(1./df4[iw]), file=f)
            f.close()

        # Wait for I/O to finish
        self.comm.barrier()

    def get_jdos(self, f_skn, e_skn, kd, kq, dw, Nw, sigma):
        """Calculate Joint density of states"""

        JDOS_w = np.zeros(Nw)
        nbands = f_skn[0].shape[1]

        for k in range(kd.nbzkpts):
            print(k)
            ibzkpt1 = kd.bz2ibz_k[k]
            ibzkpt2 = kd.bz2ibz_k[kq[k]]
            for n in range(nbands):
                for m in range(nbands):
                    focc = f_skn[0][ibzkpt1, n] - f_skn[0][ibzkpt2, m]
                    w0 = e_skn[0][ibzkpt2, m] - e_skn[0][ibzkpt1, n]
                    if focc > 0 and w0 >= 0:
                        w0_id = int(w0 / dw)
                        if w0_id + 1 < Nw:
                            alpha = (w0_id + 1 - w0 / dw) / dw
                            JDOS_w[w0_id] += focc * alpha
                            alpha = (w0 / dw - w0_id) / dw
                            JDOS_w[w0_id + 1] += focc * alpha

        w = np.arange(Nw) * dw * Hartree

        return w, JDOS_w

    def calculate_induced_density(self, q, w):
        """ Evaluate induced density for a certain q and w.

        Parameters:

        q: ndarray
            Momentum tranfer at reduced coordinate.
        w: scalar
            Energy (eV).
        """

        if type(w) is int:
            iw = w
            w = self.wlist[iw] / Hartree
        elif type(w) is float:
            w /= Hartree
            iw = int(np.round(w / self.dw))
        else:
            raise ValueError('Frequency not correct !')

        self.printtxt('Calculating Induced density at q, w (iw)')
        self.printtxt('(%f, %f, %f), %f(%d)' %
                      (q[0], q[1], q[2], w * Hartree, iw))

        # delta_G0
        delta_G = np.zeros(self.npw)
        delta_G[0] = 1.

        # coef is (q+G)**2 / 4pi
        coef_G = np.zeros(self.npw)
        for iG in range(self.npw):
            qG = np.dot(q + self.Gvec_Gc[iG], self.bcell_cv)
            coef_G[iG] = np.dot(qG, qG)
        coef_G /= 4 * pi

        # obtain chi_G0(q,w)
        dm_wGG = self.get_RPA_dielectric_matrix()
        tmp_GG = dm_wGG[iw]
        del dm_wGG
        chi_G = (np.linalg.inv(tmp_GG)[:, 0] - delta_G) * coef_G

        gd = self.gd
        r = gd.get_grid_point_coordinates()

        # calculate dn(r,q,w)
        drho_R = gd.zeros(dtype=complex)
        for iG in range(self.npw):
            qG = np.dot(q + self.Gvec_Gc[iG], self.bcell_cv)
            qGr_R = np.inner(qG, r.T).T
            drho_R += chi_G[iG] * np.exp(1j * qGr_R)

        # phase = sum exp(iq.R_i)
        return drho_R

    def get_induced_density_z(self, q, w):
        """Get induced density on z axis (summation over xy-plane). """

        drho_R = self.calculate_induced_density(q, w)

        drho_z = np.zeros(self.gd.N_c[2], dtype=complex)
        #        dxdy = np.cross(self.h_c[0], self.h_c[1])

        for iz in range(self.gd.N_c[2]):
            drho_z[iz] = drho_R[:, :, iz].sum()

        return drho_z

    def get_eigenmodes(self,
                       filename=None,
                       chi0=None,
                       calc=None,
                       dm=None,
                       xc='RPA',
                       sum=None,
                       vcut=None,
                       checkphase=False,
                       return_full=False):
        """
        Calculate the plasmonic eigenmodes as eigenvectors of the dielectric matrix.  

        Parameters:

        filename:  pckl file
                   output from response calculation.
         
        chi0:  gpw file
               chi0_wGG from response calculation.

        calc:  gpaw calculator instance
               ground state calculator used in response calculation.
               Wavefunctions only needed if chi0 is calculated from scratch

        dm:  gpw file
             dielectric matrix from response calculation

        xc:  str 'RPA'or 'ALDA' XC- Kernel
        
        sum:  str
              '2D': sum in the x and y directions
              '1D': To be implemented

        vcut:  str '0D','1D' or '2D'
               Cut the Coulomb potential 

        checkphase:   Bool
                      if True, the eigenfunctions id rotated in the complex
                      plane, to be made as real as posible

        return_full:  Bool
                      if True, the eigenvectors in reciprocal space is also
                      returned. 
           
        """
        self.read(filename)
        self.pbc = [1, 1, 1]
        #self.calc.atoms.pbc = [1,1,1]
        npw = self.npw
        self.w_w = np.linspace(0, self.dw * (self.Nw - 1) * Hartree, self.Nw)
        self.vcut = vcut
        dm_wGG = self.get_dielectric_matrix(xc=xc,
                                            symmetric=False,
                                            chi0_wGG=chi0,
                                            calc=calc,
                                            vcut=vcut)

        q = self.q_c

        # get grid on which the eigenmodes are calculated
        #gd = self.calc.wfs.gd
        #r = gd.get_grid_point_coordinates()
        #rrr = r*Bohr
        from gpaw.utilities.gpts import get_number_of_grid_points
        from gpaw.grid_descriptor import GridDescriptor
        grid_size = [1, 1, 1]
        h = 0.2
        cell_cv = self.acell_cv * np.diag(grid_size)
        mode = 'fd'
        realspace = True
        h /= Bohr
        N_c = get_number_of_grid_points(cell_cv, h, mode, realspace)
        gd = GridDescriptor(N_c, cell_cv, self.pbc)
        #gd = self.calc.wfs.gd
        r = gd.get_grid_point_coordinates()
        rrr = r * Bohr

        eig_0 = np.array([], dtype=complex)
        eig_left = np.array([], dtype=complex)
        eig_right = np.array([], dtype=complex)
        vec_modes = np.zeros([1, self.npw], dtype=complex)
        vec_modes_dual = np.zeros([1, self.npw], dtype=complex)
        vec_modes_density = np.zeros([1, self.npw], dtype=complex)
        vec_modes_norm = np.zeros([1, self.npw], dtype=complex)
        eig_all = np.zeros([1, self.npw], dtype=complex)
        eig_dummy = np.zeros([1, self.npw], dtype=complex)
        v_dummy = np.zeros([1, self.npw], dtype=complex)
        vec_dummy = np.zeros([1, self.npw], dtype=complex)
        vec_dummy2 = np.zeros([1, self.npw], dtype=complex)
        w_0 = np.array([])
        w_left = np.array([])
        w_right = np.array([])

        if sum == '2D':
            v_ind = np.zeros([1, r.shape[-1]], dtype=complex)
            n_ind = np.zeros([1, r.shape[-1]], dtype=complex)
        elif sum == '1D':
            self.printtxt('1D sum not implemented')
            return
        else:
            v_ind = np.zeros([1, r.shape[1], r.shape[2], r.shape[3]],
                             dtype=complex)
            n_ind = np.zeros([1, r.shape[1], r.shape[2], r.shape[3]],
                             dtype=complex)

        eps_GG_plus = dm_wGG[0]
        eig_plus, vec_plus = np.linalg.eig(
            eps_GG_plus)  # find eigenvalues and eigenvectors
        vec_plus_dual = np.linalg.inv(vec_plus)

        # loop over frequencies, where the eigenvalues for the 2D matrix in G,G' are found.
        for i in np.array(range(self.Nw - 1)) + 1:
            eps_GG = eps_GG_plus
            eig, vec = eig_plus, vec_plus
            vec_dual = vec_plus_dual
            eps_GG_plus = dm_wGG[i]  # epsilon_GG'(omega + d-omega)
            eig_plus, vec_plus = np.linalg.eig(eps_GG_plus)
            vec_plus_dual = np.linalg.inv(vec_plus)
            eig_dummy[0, :] = eig
            eig_all = np.append(eig_all, eig_dummy,
                                axis=0)  # append all eigenvalues to array
            # loop to check find the eigenvalues that crosses zero from negative to positive values:
            for k in range(self.npw):
                for m in range(self.npw):
                    if eig[k] < 0 and 0 < eig_plus[m]:
                        # check it's the same mode - Overlap between eigenvectors should be large:
                        if abs(np.inner(vec[:, k],
                                        vec_plus_dual[m, :])) > 0.95:
                            self.printtxt('crossing found at w = %1.1f eV' %
                                          self.w_w[i - 1])
                            eig_left = np.append(eig_left, eig[k])
                            eig_right = np.append(eig_right, eig_plus[m])

                            vec_dummy[0, :] = vec[:, k]
                            vec_modes = np.append(vec_modes, vec_dummy, axis=0)
                            vec_dummy[0, :] = vec_dual[k, :].T
                            vec_modes_dual = np.append(vec_modes_dual,
                                                       vec_dummy,
                                                       axis=0)

                            w1 = self.w_w[i - 1]
                            w2 = self.w_w[i]
                            a = np.real((eig_plus[m] - eig[k]) / (w2 - w1))
                            w0 = np.real(-eig[k]) / a + w1
                            eig0 = a * (w0 - w1) + eig[k]

                            w_0 = np.append(w_0, w0)
                            w_left = np.append(w_left, w1)
                            eig_0 = np.append(eig_0, eig0)

                            n_dummy = np.zeros(
                                [1, r.shape[1], r.shape[2], r.shape[3]],
                                dtype=complex)
                            v_dummy = np.zeros(
                                [1, r.shape[1], r.shape[2], r.shape[3]],
                                dtype=complex)

                            vec_n = np.zeros([self.npw])

                            for iG in range(self.npw):  # Fourier transform
                                qG = np.dot((q + self.Gvec_Gc[iG]),
                                            self.bcell_cv)
                                coef_G = np.dot(qG, qG) / (4 * pi)
                                qGr_R = np.inner(qG, r.T).T
                                v_dummy += vec[iG, k] * np.exp(1j * qGr_R)
                                n_dummy += vec[iG, k] * np.exp(
                                    1j * qGr_R) * coef_G

                            if checkphase:  # rotate eigenvectors in complex plane
                                integral = np.zeros([81])
                                phases = np.linspace(0, 2, 81)
                                for ip in range(81):
                                    v_int = v_dummy * np.exp(
                                        1j * pi * phases[ip])
                                    integral[ip] = abs(np.imag(v_int)).sum()
                                phase = phases[np.argsort(integral)][0]

                                v_dummy *= np.exp(1j * pi * phase)
                                n_dummy *= np.exp(1j * pi * phase)

                            if sum == '2D':
                                i_xyz = 3
                                v_dummy_z = np.zeros([1, v_dummy.shape[i_xyz]],
                                                     dtype=complex)
                                n_dummy_z = np.zeros([1, v_dummy.shape[i_xyz]],
                                                     dtype=complex)
                                v_dummy_z[0, :] = np.sum(np.sum(v_dummy,
                                                                axis=1),
                                                         axis=1)[0, :]
                                n_dummy_z[0, :] = np.sum(np.sum(n_dummy,
                                                                axis=1),
                                                         axis=1)[0, :]

                                v_ind = np.append(v_ind, v_dummy_z, axis=0)
                                n_ind = np.append(n_ind, n_dummy_z, axis=0)

                            elif sum == '1D':
                                self.printtxt('1D sum not implemented')
                            else:
                                v_ind = np.append(v_ind, v_dummy, axis=0)
                                n_ind = np.append(n_ind, n_dummy, axis=0)
        """                        
        returns: grid points, frequency grid, all eigenvalues, mode energies, left point energies,
                 mode eigenvalues, eigenvalues of left and right-side points,
                 (mode eigenvectors, mode dual eigenvectors,)
                 induced potential in real space, induced density in real space
        """

        if return_full:
            return rrr, self.w_w, eig_all[1:], w_0, eig_0, w_left, eig_left, \
               eig_right, vec_modes[1:], vec_modes_dual[1:], v_ind[1:], n_ind[1:]

        else:
            return rrr, self.w_w, eig_all[1:], w_0, eig_0, w_left, eig_left, \
               eig_right, v_ind[1:], n_ind[1:]

    def project_chi_to_LCAO_pair_orbital(self, orb_MG):

        nLCAO = orb_MG.shape[0]
        N = np.zeros((self.Nw, nLCAO, nLCAO), dtype=complex)

        kcoulinv_GG = np.zeros((self.npw, self.npw))
        for iG in range(self.npw):
            qG = np.dot(self.q_c + self.Gvec_Gc[iG], self.bcell_cv)
            kcoulinv_GG[iG, iG] = np.dot(qG, qG)

        kcoulinv_GG /= 4. * pi

        dm_wGG = self.get_RPA_dielectric_matrix()

        for mu in range(nLCAO):
            for nu in range(nLCAO):
                pairorb_R = orb_MG[mu] * orb_MG[nu]
                if not (pairorb_R * pairorb_R.conj() < 1e-10).all():
                    tmp_G = np.fft.fftn(pairorb_R) * self.vol / self.nG0

                    pairorb_G = np.zeros(self.npw, dtype=complex)
                    for iG in range(self.npw):
                        index = self.Gindex[iG]
                        pairorb_G[iG] = tmp_G[index[0], index[1], index[2]]

                    for iw in range(self.Nw):
                        chi_GG = (dm_wGG[iw] - np.eye(self.npw)) * kcoulinv_GG
                        N[iw, mu,
                          nu] = (np.outer(pairorb_G.conj(), pairorb_G) *
                                 chi_GG).sum()
#                        N[iw, mu, nu] = np.inner(pairorb_G.conj(),np.inner(pairorb_G, chi_GG))

        return N

    def write(self, filename, all=False):
        """Dump essential data"""

        data = {
            'nbands': self.nbands,
            'acell': self.acell_cv,  #* Bohr,
            'bcell': self.bcell_cv,  #/ Bohr,
            'h_cv': self.gd.h_cv,  #* Bohr,
            'nG': self.gd.N_c,
            'nG0': self.nG0,
            'vol': self.vol,  #* Bohr**3,
            'BZvol': self.BZvol,  #/ Bohr**3,
            'nkpt': self.kd.nbzkpts,
            'ecut': self.ecut,  #* Hartree,
            'npw': self.npw,
            'eta': self.eta,  #* Hartree,
            'ftol': self.ftol,
            'Nw': self.Nw,
            'NwS': self.NwS,
            'dw': self.dw,  # * Hartree,
            'q_red': self.q_c,
            'q_car': self.qq_v,  # / Bohr,
            'qmod': np.dot(self.qq_v, self.qq_v),  # / Bohr
            'vcut': self.vcut,
            'pbc': self.pbc,
            'nvalence': self.nvalence,
            'hilbert_trans': self.hilbert_trans,
            'optical_limit': self.optical_limit,
            'e_skn': self.e_skn,  # * Hartree,
            'f_skn': self.f_skn,
            'bzk_kc': self.kd.bzk_kc,
            'ibzk_kc': self.kd.ibzk_kc,
            'kq_k': self.kq_k,
            'Gvec_Gc': self.Gvec_Gc,
            'dfNLFRPA_w': self.df1_w,
            'dfLFCRPA_w': self.df2_w,
            'dfNLFALDA_w': self.df3_w,
            'dfLFCALDA_w': self.df4_w,
            'df_flag': True
        }

        if all:
            from gpaw.response.parallel import par_write
            par_write('chi0' + filename, 'chi0_wGG', self.wcomm, self.chi0_wGG)

        if rank == 0:
            pickle.dump(data, open(filename, 'w'), -1)

        self.comm.barrier()

    def read(self, filename):
        """Read data from pickle file"""

        data = pickle.load(open(filename))

        self.nbands = data['nbands']
        self.acell_cv = data['acell']
        self.bcell_cv = data['bcell']
        self.nG0 = data['nG0']
        self.vol = data['vol']
        self.BZvol = data['BZvol']
        self.ecut = data['ecut']
        self.npw = data['npw']
        self.eta = data['eta']
        self.ftol = data['ftol']
        self.Nw = data['Nw']
        self.NwS = data['NwS']
        self.dw = data['dw']
        self.q_c = data['q_red']
        self.qq_v = data['q_car']
        self.qmod = data['qmod']
        #self.vcut  = data['vcut']
        #self.pbc = data['pbc']

        self.hilbert_trans = data['hilbert_trans']
        self.optical_limit = data['optical_limit']

        self.e_skn = data['e_skn']
        self.f_skn = data['f_skn']

        self.nvalence = data['nvalence']
        self.kq_k = data['kq_k']
        self.Gvec_Gc = data['Gvec_Gc']
        self.df1_w = data['dfNLFRPA_w']
        self.df2_w = data['dfLFCRPA_w']
        self.df3_w = data['dfNLFALDA_w']
        self.df4_w = data['dfLFCALDA_w']
        self.df_flag = data['df_flag']

        self.printtxt('Read succesfully !')
    print("  %s'th moment = %2.6f" % (L, m))
    equal(m, (L == 0) / sqrt(4 * pi), 1.5e-3)

# Check that it is removed correctly
v = gauss.remove_moment(nH, 0)
m = gauss.get_moment(nH, 0)
print("\nZero'th moment of compensated Hydrogen density =", m)
equal(m, 0.0, 1e-7)


# /-------------------------------------------------\
# | Check if Gaussian potentials are made correctly |
# \-------------------------------------------------/

# Array for storing the potential
pot = gd.zeros(dtype=float, global_array=False)
for L in range(7):  # Angular index of gaussian
    # Get analytic functions
    ng = gauss.get_gauss(L)
    vg = gauss.get_gauss_pot(L)

    # Solve potential numerically
    niter = solve(pot, ng, charge=None, zero_initial_phi=True)

    # Determine residual
    residual = norm(pot - vg)
    residual = gd.integrate((pot - vg) ** 2) ** 0.5

    # print result
    print("L=%s, processor %s of %s: %s" % (L, gd.comm.rank + 1, gd.comm.size, residual))
示例#40
0
class UTDomainParallelSetup(TestCase):
    """
    Setup a simple domain parallel calculation."""

    # Number of bands
    nbands = 1

    # Spin-paired
    nspins = 1

    # Mean spacing and number of grid points per axis
    h = 0.2 / Bohr

    # Generic lattice constant for unit cell
    a = 5.0 / Bohr

    # Type of boundary conditions employed
    boundaries = None

    # Type of unit cell employed
    celltype = None

    def setUp(self):
        for virtvar in ['boundaries', 'celltype']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        # Basic unit cell information:
        pbc_c = {'zero'    : (False,False,False), \
                 'periodic': (True,True,True), \
                 'mixed'   : (True, False, True)}[self.boundaries]
        a, b = self.a, 2**0.5*self.a
        cell_cv = {'general'   : np.array([[0,a,a],[a/2,0,a/2],[a/2,a/2,0]]),
                   'rotated'   : np.array([[0,0,b],[b/2,0,0],[0,b/2,0]]),
                   'inverted'   : np.array([[0,0,b],[0,b/2,0],[b/2,0,0]]),
                   'orthogonal': np.diag([b, b/2, b/2])}[self.celltype]
        cell_cv = np.array([(4-3*pbc)*c_v for pbc,c_v in zip(pbc_c, cell_cv)])

        # Decide how many kpoints to sample from the 1st Brillouin Zone
        kpts_c = np.ceil((10/Bohr)/np.sum(cell_cv**2,axis=1)**0.5).astype(int)
        kpts_c = tuple(kpts_c*pbc_c + 1-pbc_c)
        bzk_kc = kpts2ndarray(kpts_c)
        self.gamma = len(bzk_kc) == 1 and not bzk_kc[0].any()

        #p = InputParameters()
        #Z_a = self.atoms.get_atomic_numbers()
        #xcfunc = XC(p.xc)
        #setups = Setups(Z_a, p.setups, p.basis, p.lmax, xcfunc)
        #symmetry, weight_k, self.ibzk_kc = reduce_kpoints(self.atoms, bzk_kc,
        #                                                  setups, p.usesymm)

        self.ibzk_kc = bzk_kc.copy() # don't use symmetry reduction of kpoints
        self.nibzkpts = len(self.ibzk_kc)
        self.ibzk_kv = kpoint_convert(cell_cv, skpts_kc=self.ibzk_kc)

        # Parse parallelization parameters and create suitable communicators.
        #parsize_domain, parsize_bands = create_parsize_minbands(self.nbands, world.size)
        parsize_domain, parsize_bands = world.size//gcd(world.size, self.nibzkpts), 1
        assert self.nbands % np.prod(parsize_bands) == 0
        domain_comm, kpt_comm, band_comm = distribute_cpus(parsize_domain,
            parsize_bands, self.nspins, self.nibzkpts)

        # Set up band descriptor:
        self.bd = BandDescriptor(self.nbands, band_comm)

        # Set up grid descriptor:
        N_c = np.round(np.sum(cell_cv**2, axis=1)**0.5 / self.h)
        N_c += 4-N_c % 4 # makes domain decomposition easier
        self.gd = GridDescriptor(N_c, cell_cv, pbc_c, domain_comm, parsize_domain)
        self.assertEqual(self.gamma, np.all(~self.gd.pbc_c))

        # What to do about kpoints?
        self.kpt_comm = kpt_comm

        if debug and world.rank == 0:
            comm_sizes = tuple([comm.size for comm in [world, self.bd.comm, \
                                                   self.gd.comm, self.kpt_comm]])
            print '%d world, %d band, %d domain, %d kpt' % comm_sizes

    def tearDown(self):
        del self.ibzk_kc, self.ibzk_kv, self.bd, self.gd, self.kpt_comm

    # =================================

    def verify_comm_sizes(self):
        if world.size == 1:
            return
        comm_sizes = tuple([comm.size for comm in [world, self.bd.comm, \
                                                   self.gd.comm, self.kpt_comm]])
        self._parinfo =  '%d world, %d band, %d domain, %d kpt' % comm_sizes
        self.assertEqual(self.nbands % self.bd.comm.size, 0)
        self.assertEqual((self.nspins*self.nibzkpts) % self.kpt_comm.size, 0)

    def verify_grid_volume(self):
        gdvol = np.prod(self.gd.get_size_of_global_array())*self.gd.dv
        self.assertAlmostEqual(self.gd.integrate(1+self.gd.zeros()), gdvol, 10)

    def verify_grid_point(self):
        # Volume integral of cartesian coordinates of all available grid points
        gdvol = np.prod(self.gd.get_size_of_global_array())*self.gd.dv
        cmr_v = self.gd.integrate(self.gd.get_grid_point_coordinates()) / gdvol

        # Theoretical center of cell based on all available grid data
        cm0_v = np.dot((0.5*(self.gd.get_size_of_global_array()-1.0) \
            + 1.0-self.gd.pbc_c) / self.gd.N_c, self.gd.cell_cv)

        self.assertAlmostEqual(np.abs(cmr_v-cm0_v).max(), 0, 10)

    def verify_non_pbc_spacing(self):
        atoms = create_random_atoms(self.gd, 1000, 'NH3', self.a/2)
        pos_ac = atoms.get_positions()
        cellvol = np.linalg.det(self.gd.cell_cv)
        if debug: print 'cell volume:', np.abs(cellvol)*Bohr**3, 'Ang^3', cellvol>0 and '(right handed)' or '(left handed)'

        # Loop over non-periodic axes and check minimum distance requirement
        for c in np.argwhere(~self.gd.pbc_c).ravel():
            a_v = self.gd.cell_cv[(c+1)%3]
            b_v = self.gd.cell_cv[(c+2)%3]
            c_v = np.cross(a_v, b_v)
            for d in range(2):
                # Inwards unit normal vector of d'th cell face of c'th axis
                # and point intersected by this plane (d=0,1 / bottom,top).
                n_v = np.sign(cellvol) * (1-2*d) * c_v / np.linalg.norm(c_v)
                if debug: print {0:'x',1:'y',2:'z'}[c]+'-'+{0:'bottom',1:'top'}[d]+':', n_v, 'Bohr'
                if debug: print 'gd.xxxiucell_cv[%d]~' % c, self.gd.xxxiucell_cv[c] / np.linalg.norm(self.gd.xxxiucell_cv[c]), 'Bohr'
                origin_v = np.dot(d * np.eye(3)[c], self.gd.cell_cv)
                d_a = np.dot(pos_ac/Bohr - origin_v[np.newaxis,:], n_v)
                if debug: print 'a:', self.a/2*Bohr, 'min:', np.min(d_a)*Bohr, 'max:', np.max(d_a)*Bohr
                self.assertAlmostEqual(d_a.min(), self.a/2, 0) #XXX digits!
示例#41
0
    m = gauss.get_moment(nH, L)
    print('  %s\'th moment = %2.6f' % (L, m))
    equal(m, (L == 0) / sqrt(4 * pi), 1.5e-3)

# Check that it is removed correctly
v = gauss.remove_moment(nH, 0)
m = gauss.get_moment(nH, 0)
print('\nZero\'th moment of compensated Hydrogen density =', m)
equal(m, 0., 1e-7)

# /-------------------------------------------------\
# | Check if Gaussian potentials are made correctly |
# \-------------------------------------------------/

# Array for storing the potential
pot = gd.zeros(dtype=float, global_array=False)
for L in range(7):  # Angular index of gaussian
    # Get analytic functions
    ng = gauss.get_gauss(L)
    vg = gauss.get_gauss_pot(L)

    # Solve potential numerically
    niter = solve(pot, ng, charge=None, zero_initial_phi=True)

    # Determine residual
    residual = norm(pot - vg)
    residual = gd.integrate((pot - vg)**2)**0.5

    # print result
    print('L=%s, processor %s of %s: %s' %
          (L, gd.comm.rank + 1, gd.comm.size, residual))
示例#42
0
def test(cellno, cellname, cell_cv, idiv, pbc, nn):
    N_c = h2gpts(0.12, cell_cv, idiv=idiv)
    if idiv == 1:
        N_c += 1 - N_c % 2  # We want especially to test uneven grids
    gd = GridDescriptor(N_c, cell_cv, pbc_c=pbc)
    rho_g = gd.zeros()
    phi_g = gd.zeros()
    rho_g[:] = -0.3 + rng.rand(*rho_g.shape)

    # Neutralize charge:
    charge = gd.integrate(rho_g)
    magic = gd.get_size_of_global_array().prod()
    rho_g -= charge / gd.dv / magic
    charge = gd.integrate(rho_g)
    assert abs(charge) < 1e-12

    # Check use_cholesky=True/False ?
    from gpaw.poisson import FDPoissonSolver
    ps = FastPoissonSolver(nn=nn)
    #print('setgrid')

    # Will raise BadAxesError for some pbc/cell combinations
    ps.set_grid_descriptor(gd)

    ps.solve(phi_g, rho_g)

    laplace = Laplace(gd, scale=-1.0 / (4.0 * np.pi), n=nn)

    def get_residual_err(phi_g):
        rhotest_g = gd.zeros()
        laplace.apply(phi_g, rhotest_g)
        residual = np.abs(rhotest_g - rho_g)
        # Residual is not accurate at end of non-periodic directions
        # except for nn=1 (since effectively we use the right stencil
        # only for nn=1 at the boundary).
        #
        # To do this check correctly, the Laplacian should have lower
        # nn at the boundaries.  Therefore we do not test the residual
        # at these ends, only in between, by zeroing the bad ones:
        if nn > 1:
            exclude_points = nn - 1
            for c in range(3):
                if nn > 1 and not pbc[c]:
                    # get view ehere axis c refers becomes zeroth dimension:
                    X = residual.transpose(c, (c + 1) % 3, (c + 2) % 3)

                    if gd.beg_c[c] == 1:
                        X[:exclude_points] = 0.0
                    if gd.end_c[c] == gd.N_c[c]:
                        X[-exclude_points:] = 0.0
        return residual.max()

    maxerr = get_residual_err(phi_g)
    pbcstring = '{}{}{}'.format(*pbc)

    if 0:
        ps2 = FDPoissonSolver(relax='J', nn=nn, eps=1e-18)
        ps2.set_grid_descriptor(gd)
        phi2_g = gd.zeros()
        ps2.solve(phi2_g, rho_g)

        phimaxerr = np.abs(phi2_g - phi_g).max()
        maxerr2 = get_residual_err(phi2_g)
        msg = ('{:2d} {:8s} pbc={} err={:8.5e} err[J]={:8.5e} '
               'err[phi]={:8.5e} nn={:1d}'
               .format(cellno, cellname, pbcstring, maxerr, maxerr2,
                       phimaxerr, nn))

    state = 'ok' if maxerr < tolerance else 'FAIL'

    msg = ('{:2d} {:8s} grid={} pbc={} err[fast]={:8.5e} nn={:1d} {}'
           .format(cellno, cellname, N_c, pbcstring, maxerr, nn, state))
    if world.rank == 0:
        print(msg)

    return maxerr
示例#43
0
# Copyright (C) 2003  CAMP
# Please see the accompanying LICENSE file for further information.
from __future__ import print_function
from gpaw.grid_descriptor import GridDescriptor
from gpaw.transformers import Transformer
import time


n = 6
gda = GridDescriptor((n, n, n))
gdb = gda.refine()
gdc = gdb.refine()
a = gda.zeros()
b = gdb.zeros()
c = gdc.zeros()

inter = Transformer(gdb, gdc, 2).apply
restr = Transformer(gdb, gda, 2).apply

t = time.clock()
for i in range(8 * 300):
    inter(b, c)
print(time.clock() - t)

t = time.clock()
for i in range(8 * 3000):
    restr(b, a)
print(time.clock() - t)
示例#44
0
文件: lfc.py 项目: eojons/gpaw-scme
from gpaw.fftw import FFTPlan
print(FFTPlan)

for l in range(3):
    print(l)
    s = Spline(l, rc, 2 * x**1.5 / np.pi * np.exp(-x * r**2))

    lfc1 = LFC(gd, [[s]], kd, dtype=complex)
    lfc2 = PWLFC([[s]], pd)
    
    c_axi = {0: np.zeros((1, 2 * l + 1), complex)}
    c_axi[0][0, 0] = 1.9 - 4.5j
    c_axiv = {0: np.zeros((1, 2 * l + 1, 3), complex)}

    b1 = gd.zeros(1, dtype=complex)
    b2 = pd.zeros(1, dtype=complex)

    for lfc, b in [(lfc1, b1), (lfc2, b2)]:
        lfc.set_positions(spos_ac)
        lfc.add(b, c_axi, 0)

    b2 = pd.ifft(b2[0]) * eikr
    equal(abs(b2-b1[0]).max(), 0, 0.001)
    
    b1 = eikr[None]
    b2 = pd.fft(b1[0] * 0 + 1).reshape((1, -1))

    results = []
    results2 = []
    for lfc, b in [(lfc1, b1), (lfc2, b2)]:
示例#45
0
        print('%.10e vs %.10e at %.10e is %s' % (x, y, tol, res))
else:
    from gpaw.test import equal

# Model grid
N = 16
N_c = np.array((1, 1, 3)) * N
cell_c = N_c / float(N)
gd = GridDescriptor(N_c, cell_c, False)

# Construct model density
coord_vg = gd.get_grid_point_coordinates()
x_g = coord_vg[0, :]
y_g = coord_vg[1, :]
z_g = coord_vg[2, :]
rho_g = gd.zeros()
for z0 in [1, 2]:
    rho_g += 10 * (z_g - z0) * \
        np.exp(-20 * np.sum((coord_vg.T - np.array([.5, .5, z0])).T**2,
                            axis=0))

if do_plot:
    big_rho_g = gd.collect(rho_g)
    if gd.comm.rank == 0:
        import matplotlib.pyplot as plt
        fig, ax_ij = plt.subplots(3, 4, figsize=(20, 10))
        ax_i = ax_ij.ravel()
        ploti = 0
        Ng_c = gd.get_size_of_global_array()
        plt.sca(ax_i[ploti])
        ploti += 1
示例#46
0
import numpy as np
from gpaw.lfc import LocalizedFunctionsCollection as LFC
from gpaw.grid_descriptor import GridDescriptor
from gpaw.spline import Spline
gd = GridDescriptor([20, 16, 16], [(4, 2, 0), (0, 4, 0), (0, 0, 4)])
spos_ac = np.array([[0.252, 0.15, 0.35], [0.503, 0.5, 0.5]])
s = Spline(l=0, rmax=2.0, f_g=np.array([1, 0.9, 0.1, 0.0]))
spline_aj = [[s], [s]]
c = LFC(gd, spline_aj)
c.set_positions(spos_ac)
c_ai = c.dict(zero=True)
if 1 in c_ai:
    c_ai[1][0] = 2.0
psi = gd.zeros()
c.add(psi, c_ai)

d_avv = dict([(a, np.zeros((3, 3))) for a in c.my_atom_indices])
c.second_derivative(psi, d_avv)

if 0 in d_avv:
    print d_avv[0]

eps = 0.000001
d_aiv = c.dict(derivative=True)
pos_av = np.dot(spos_ac, gd.cell_cv)
for v in range(3):
    pos_av[0, v] += eps
    c.set_positions(np.dot(pos_av, gd.icell_cv.T))
    c.derivative(psi, d_aiv)
    if 0 in d_aiv:
        d0_v = d_aiv[0][0].copy()