示例#1
0
 def initialize_clgd(self):
     N_c = get_number_of_grid_points(self.cl.cell, self.cl.spacing)
     self.cl.spacing = np.diag(self.cl.cell) / N_c
     self.cl.gd = GridDescriptor(N_c, self.cl.cell, False, self.cl.dcomm,
                                 self.cl.dparsize)
     self.cl.gd_global = GridDescriptor(N_c, self.cl.cell, False,
                                        serial_comm, None)
     self.cl.extrapolated_qm_phi = self.cl.gd.empty()
示例#2
0
    def setUp(self):
        for virtvar in ['boundaries']:
            assert getattr(self,
                           virtvar) is not None, 'Virtual "%s"!' % virtvar

        # Basic unit cell information:
        res, N_c = shapeopt(100, self.G**3, 3, 0.2)
        #N_c = 4*np.round(np.array(N_c)/4) # makes domain decomposition easier
        cell_cv = self.h * np.diag(N_c)
        pbc_c = {'zero'    : (False,False,False), \
                 'periodic': (True,True,True), \
                 'mixed'   : (True, False, True)}[self.boundaries]

        # Create randomized gas-like atomic configuration on interim grid
        tmpgd = GridDescriptor(N_c, cell_cv, pbc_c)
        self.atoms = create_random_atoms(tmpgd)

        # Create setups
        Z_a = self.atoms.get_atomic_numbers()
        assert 1 == self.nspins
        self.setups = Setups(Z_a, p.setups, p.basis, p.lmax, xc)
        self.natoms = len(self.setups)

        # 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)
        self.bzk_kc = kpts2ndarray(kpts_c)

        # Set up k-point descriptor
        self.kd = KPointDescriptor(self.bzk_kc, self.nspins)
        self.kd.set_symmetry(self.atoms, self.setups, p.usesymm)

        # Set the dtype
        if self.kd.gamma:
            self.dtype = float
        else:
            self.dtype = complex

        # Create communicators
        parsize, parsize_bands = self.get_parsizes()
        assert self.nbands % np.prod(parsize_bands) == 0
        domain_comm, kpt_comm, band_comm = distribute_cpus(
            parsize, parsize_bands, self.nspins, self.kd.nibzkpts)

        self.kd.set_communicator(kpt_comm)

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

        # Set up grid descriptor:
        self.gd = GridDescriptor(N_c, cell_cv, pbc_c, domain_comm, parsize)

        # Set up kpoint/spin descriptor (to be removed):
        self.kd_old = KPointDescriptorOld(self.nspins, self.kd.nibzkpts,
                                          kpt_comm, self.kd.gamma, self.dtype)
示例#3
0
    def get_combined_data(self, qmdata=None, cldata=None, spacing=None):

        if qmdata is None:
            qmdata = self.density.rhot_g

        if cldata is None:
            cldata = self.classical_material.charge_density

        if spacing is None:
            spacing = self.cl.gd.h_cv[0, 0]

        spacing_au = spacing / Bohr  # from Angstroms to a.u.

        # Collect data from different processes
        cln = self.cl.gd.collect(cldata)
        qmn = self.qm.gd.collect(qmdata)

        clgd = GridDescriptor(self.cl.gd.N_c, self.cl.cell, False, serial_comm,
                              None)

        if world.rank == 0:
            cln *= self.classical_material.sign
            # refine classical part
            while clgd.h_cv[0, 0] > spacing_au * 1.50:  # 45:
                cln = Transformer(clgd, clgd.refine()).apply(cln)
                clgd = clgd.refine()

            # refine quantum part
            qmgd = GridDescriptor(self.qm.gd.N_c, self.qm.cell, False,
                                  serial_comm, None)
            while qmgd.h_cv[0, 0] < clgd.h_cv[0, 0] * 0.95:
                qmn = Transformer(qmgd, qmgd.coarsen()).apply(qmn)
                qmgd = qmgd.coarsen()

            assert np.all(qmgd.h_cv == clgd.h_cv
                          ), " Spacings %.8f (qm) and %.8f (cl) Angstroms" % (
                              qmgd.h_cv[0][0] * Bohr, clgd.h_cv[0][0] * Bohr)

            # now find the corners
            r_gv_cl = clgd.get_grid_point_coordinates().transpose((1, 2, 3, 0))
            cind = self.qm.corner1 / np.diag(clgd.h_cv) - 1

            n = qmn.shape

            # print 'Corner points:     ', self.qm.corner1*Bohr,      ' - ', self.qm.corner2*Bohr
            # print 'Calculated points: ', r_gv_cl[tuple(cind)]*Bohr, ' - ', r_gv_cl[tuple(cind+n+1)]*Bohr

            cln[cind[0] + 1:cind[0] + n[0] + 1, cind[1] + 1:cind[1] + n[1] + 1,
                cind[2] + 1:cind[2] + n[2] + 1] += qmn

        world.barrier()
        return cln, clgd
示例#4
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)
示例#5
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]
示例#6
0
文件: vdw.py 项目: thonmaker/gpaw
    def initialize_more_things(self):
        if self.alphas:
            from gpaw.mpi import SerialCommunicator
            scale_c1 = (self.shape / (1.0 * self.gd.N_c))[:, np.newaxis]
            gdfft = GridDescriptor(self.shape,
                                   self.gd.cell_cv * scale_c1,
                                   True,
                                   comm=SerialCommunicator())
            k_k = construct_reciprocal(gdfft)[0][:, :, :self.shape[2] // 2 +
                                                 1]**0.5
            k_k[0, 0, 0] = 0.0

            self.dj_k = k_k / (2 * pi / self.rcut)
            self.j_k = self.dj_k.astype(int)
            self.dj_k -= self.j_k
            self.dj_k *= 2 * pi / self.rcut

            if self.verbose:
                print('VDW: density array size:',
                      self.gd.get_size_of_global_array())
                print('VDW: zero-padded array size:', self.shape)
                print(('VDW: maximum kinetic energy: %.3f Hartree' %
                       (0.5 * k_k.max()**2)))

            assert self.j_k.max() < self.Nr // 2, ('Use larger Nr than %i.' %
                                                   self.Nr)

        else:
            self.dj_k = None
            self.j_k = None
示例#7
0
    def __init__(self, cell_cv, nk_c, txt=sys.stdout):
        self.nk_c = nk_c
        bigcell_cv = cell_cv * nk_c[:, np.newaxis]
        L_c = (np.linalg.inv(bigcell_cv)**2).sum(0)**-0.5

        rc = 0.5 * L_c.min()
        print('Inner radius for %dx%dx%d Wigner-Seitz cell: %.3f Ang' %
              (tuple(nk_c) + (rc * Bohr, )),
              file=txt)

        self.a = 5 / rc
        print('Range-separation parameter: %.3f Ang^-1' % (self.a / Bohr),
              file=txt)

        #        nr_c = [get_efficient_fft_size(2 * int(L * self.a * 1.5))
        nr_c = [get_efficient_fft_size(2 * int(L * self.a * 3.0)) for L in L_c]
        print('FFT size for calculating truncated Coulomb: %dx%dx%d' %
              tuple(nr_c),
              file=txt)

        self.gd = GridDescriptor(nr_c, bigcell_cv, comm=mpi.serial_comm)
        v_R = self.gd.empty()
        v_i = v_R.ravel()

        pos_iv = self.gd.get_grid_point_coordinates().reshape((3, -1)).T
        corner_jv = np.dot(np.indices((2, 2, 2)).reshape((3, 8)).T, bigcell_cv)
        for i, pos_v in enumerate(pos_iv):
            r = ((pos_v - corner_jv)**2).sum(axis=1).min()**0.5
            if r == 0:
                v_i[i] = 2 * self.a / pi**0.5
            else:
                v_i[i] = erf(self.a * r) / r

        self.K_Q = np.fft.fftn(v_R) * self.gd.dv
示例#8
0
    def set_grid_descriptor(self, gd):
        if (self.gd is not None and (self.gd.N_c == gd.N_c).all()
                and (self.gd.pbc_c == gd.pbc_c).all()
                and (self.gd.cell_cv == gd.cell_cv).all()):
            return

        VDWFunctional.set_grid_descriptor(self, gd)
        if self.size is None:
            self.shape = gd.N_c.copy()
            for c, n in enumerate(self.shape):
                if not gd.pbc_c[c]:
                    self.shape[c] = int(2**ceil(log(n) / log(2)))
        else:
            self.shape = np.array(self.size)

        scale_c1 = (self.shape / (1.0 * gd.N_c))[:, np.newaxis]
        gdfft = GridDescriptor(self.shape, gd.cell_cv * scale_c1, True)
        k_k = construct_reciprocal(gdfft)[0][:, :, :self.shape[2] // 2 +
                                             1]**0.5
        k_k[0, 0, 0] = 0.0

        self.dj_k = k_k / (2 * pi / self.rcut)
        self.j_k = self.dj_k.astype(int)
        self.dj_k -= self.j_k
        self.dj_k *= 2 * pi / self.rcut

        assert self.j_k.max() < self.Nr // 2, 'Use larger Nr.'

        if self.verbose:
            print 'VDW: density array size:', gd.get_size_of_global_array()
            print 'VDW: zero-padded array size:', self.shape
            print('VDW: maximum kinetic energy: %.3f Hartree' %
                  (0.5 * k_k.max()**2))
示例#9
0
    def setUp(self):
        for virtvar in ['dtype', 'parstride_bands']:
            assert getattr(self,
                           virtvar) is not None, 'Virtual "%s"!' % virtvar

        parsize, parsize_bands = create_parsize_maxbands(
            self.nbands, world.size)
        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, self.parstride_bands)

        # Set up grid descriptor:
        res, ngpts = shapeopt(100, self.G**3, 3, 0.2)
        cell_c = self.h * np.array(ngpts)
        pbc_c = (True, False, True)
        self.gd = GridDescriptor(ngpts, cell_c, pbc_c, domain_comm, parsize)

        # Create Kohn-Sham layouts for these band and grid descriptors:
        self.ksl = self.create_kohn_sham_layouts()

        # What to do about kpoints?
        self.kpt_comm = kpt_comm
示例#10
0
def go(comm, ngpts, repeat, narrays, out, prec):
    N_c = np.array((ngpts, ngpts, ngpts))
    a = 10.0
    gd = GridDescriptor(N_c, (a, a, a), comm=comm))
    gdcoarse = gd.coarsen()
    gdfine = gd.refine()
    kin1 = Laplace(gd, -0.5, 1).apply
    laplace = Laplace(gd, -0.5, 2)
    kin2 = laplace.apply
    restrict = Transformer(gd, gdcoarse, 1).apply
    interpolate = Transformer(gd, gdfine, 1).apply
    precondition = Preconditioner(gd, laplace, np_float)
    a1 = gd.empty(narrays)
    a1[:] = 1.0
    a2 = gd.empty(narrays)
    c = gdcoarse.empty(narrays)
    f = gdfine.empty(narrays)

    T = [0, 0, 0, 0, 0]
    for i in range(repeat):
        comm.barrier()
        kin1(a1, a2)
        comm.barrier()
        t0a = time()
        kin1(a1, a2)
        t0b = time()
        comm.barrier()
        t1a = time()
        kin2(a1, a2)
        t1b = time()
        comm.barrier()
        t2a = time()
        for A, C in zip(a1,c):
            restrict(A, C)
        t2b = time()
        comm.barrier()
        t3a = time()
        for A, F in zip(a1,f):
            interpolate(A, F)
        t3b = time()
        comm.barrier()
        if prec:
            t4a = time()
            for A in a1:
                precondition(A, None, None, None)
            t4b = time()
            comm.barrier()

        T[0] += t0b - t0a
        T[1] += t1b - t1a
        T[2] += t2b - t2a
        T[3] += t3b - t3a
        if prec:
            T[4] += t4b - t4a

    if mpi.rank == 0:
        out.write(' %2d %2d %2d' % tuple(gd.parsize_c))
        out.write(' %12.6f %12.6f %12.6f %12.6f %12.6f\n' %
                  tuple([t / repeat / narrays for t in T]))
        out.flush()
示例#11
0
def test_coulomb(N=2**6, a=20):
    Nc = (N, N, N)  # Number of grid point
    gd = GridDescriptor(Nc, (a, a, a), True)  # grid-descriptor object
    xyz, r2 = coordinates(
        gd)  # matrix with the square of the radial coordinate
    r = np.sqrt(r2)  # matrix with the values of the radial coordinate
    nH = np.exp(-2 * r) / pi  # density of the hydrogen atom
    C = Coulomb(gd)  # coulomb calculator

    if world.size > 1:
        C.load('real')
        t0 = time.time()
        print('Processor %s of %s: %s Ha in %s sec' %
              (gd.comm.rank + 1, gd.comm.size,
               -0.5 * C.coulomb(nH, method='real'), time.time() - t0))
        return
    else:
        C.load('recip_ewald')
        C.load('recip_gauss')
        C.load('real')
        test = {}
        t0 = time.time()
        test['dual density'] = (-0.5 * C.coulomb(nH, nH.copy()),
                                time.time() - t0)
        for method in ('real', 'recip_gauss', 'recip_ewald'):
            t0 = time.time()
            test[method] = (-0.5 * C.coulomb(nH, method=method),
                            time.time() - t0)
        return test
示例#12
0
    def read_3D(self, file, filetype=None):
        """Read the density from a 3D file"""

        if filetype is None:
            # estimate file type from name ending
            filetype = file.split('.')[-1]
        filetype.lower()

        if filetype == 'plt':
            data, cell = read_plt(file)

            pbc_c = [True, True, True]
            N_c = np.array(data.shape)
            for c in range(3):
                if N_c[c] % 2 == 1:
                    pbc_c[c] = False
                    N_c[c] += 1
            self.gd = GridDescriptor(N_c, cell.diagonal() / Bohr, pbc_c)
            self.offset_c = [int(not a) for a in self.gd.pbc_c]

        else:
            raise NotImplementedError('unknown file type "' + filetype + '"')

        self.file = file
        self.ldos = np.array(data * Bohr**3, np.float)
示例#13
0
    def setUp(self):
        for virtvar in ['boundaries']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        parsize_domain, parsize_bands = create_parsize_minbands(self.nbands, world.size)
        assert self.nbands % np.prod(parsize_bands) == 0
        comms = distribute_cpus(parsize_domain,
                                parsize_bands, self.nspins, self.nibzkpts)
        domain_comm, kpt_comm, band_comm, block_comm = \
            [comms[name] for name in 'dkbK']

        self.block_comm = block_comm

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

        # Set up grid descriptor:
        res, ngpts = shapeopt(300, self.G**3, 3, 0.2)
        cell_c = self.h * np.array(ngpts)
        pbc_c = {'zero'    : False, \
                 'periodic': True, \
                 'mixed'   : (True, False, True)}[self.boundaries]
        self.gd = GridDescriptor(ngpts, cell_c, pbc_c, domain_comm, parsize_domain)

        # What to do about kpoints?
        self.kpt_comm = kpt_comm
示例#14
0
    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
示例#15
0
    def solve_mesh(self, X, Y, Z, pot, dens0, permitivity):

        gd = GridDescriptor([X.shape[0] + 1, X.shape[1] + 1, X.shape[2] + 1],
                            cell_cv=[
                                X[0, -1, 0] - X[0, 0, 0],
                                Y[-1, 0, 0] - Y[0, 0, 0],
                                Z[0, 0, -1] - Z[0, 0, 0]
                            ],
                            pbc_c=False)
        self.set_grid_descriptor(gd)
        self.solve(pot, dens0, permitivity)
示例#16
0
def interpolate_weight(calc, weight, h=0.05, n=2):
    '''interpolates cdft weight function,
    gd is the fine grid '''
    gd = calc.density.finegd

    weight = gd.collect(weight, broadcast=True)
    weight = gd.zero_pad(weight)

    w = np.zeros_like(weight)
    gd1 = GridDescriptor(gd.N_c, gd.cell_cv, comm=serial_comm)
    gd1.distribute(weight, w)

    N_c = h2gpts(h / Bohr, gd.cell_cv)
    N_c = np.array([get_efficient_fft_size(N, n) for N in N_c])
    gd2 = GridDescriptor(N_c, gd.cell_cv, comm=serial_comm)

    interpolator = Interpolator(gd1, gd2)
    W = interpolator.interpolate(w)

    return W
示例#17
0
def extend_grid(gd, N_cd):
    N_cd = np.array(N_cd)

    N_c = gd.N_c + N_cd.sum(axis=1)
    cell_cv = gd.h_cv * N_c

    move_c = gd.get_grid_spacings() * N_cd[:, 0]

    egd = GridDescriptor(N_c, cell_cv, gd.pbc_c, gd.comm)
    egd.extend_N_cd = N_cd

    return egd, cell_cv * Bohr, move_c * Bohr
示例#18
0
    def __init__(self, calc, h=0.05, n=2):
        """Create transformation object.

        calc: GPAW calculator object
            The calcalator that has the wave functions.
        h: float
            Desired grid-spacing in Angstrom.
        n: int
            Force number of points to be a mulitiple of n.
        """
        self.calc = calc
        gd = calc.wfs.gd

        gd1 = GridDescriptor(gd.N_c, gd.cell_cv, comm=serial_comm)

        # Descriptor for the final grid:
        N_c = h2gpts(h / Bohr, gd.cell_cv)
        N_c = np.array([get_efficient_fft_size(N, n) for N in N_c])
        gd2 = self.gd = GridDescriptor(N_c, gd.cell_cv, comm=serial_comm)
        self.interpolator = Interpolator(gd1, gd2, self.calc.wfs.dtype)

        self.dphi = None  # PAW correction (will be initialized when needed)
示例#19
0
def rigorous_testing():
    from itertools import product, permutations, cycle
    from gpaw.mpi import world
    gridpointcounts = [1, 2, 10, 21]
    cpucounts = np.arange(1, world.size + 1)
    pbc = cycle(product([0, 1], [0, 1], [0, 1]))

    # This yields all possible parallelizations!
    for parsize_c in product(cpucounts, cpucounts, cpucounts):
        if np.prod(parsize_c) != world.size:
            continue

        # All possible grid point counts
        for N_c in product(gridpointcounts, gridpointcounts, gridpointcounts):

            # We simply can't be bothered to also do all possible
            # combinations with PBCs.  Trying every possible set of
            # boundary conditions at least ones should be quite fine
            # enough.
            pbc_c = next(pbc)
            for dirs in permutations([0, 1, 2]):
                independent_dir, distribute_dir, reduce_dir = dirs

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

                try:
                    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)

                    #gd2 = gd.new_descriptor(parsize_c=parsize2_c)
                except ValueError:  # Skip illegal distributions
                    continue

                if gd.comm.rank == 1:
                    #print(gd, gd2)
                    print(
                        'N_c=%s[%s] redist %s -> %s [ind=%d dist=%d red=%d]' %
                        (N_c, pbc_c, parsize_c, parsize2_c, independent_dir,
                         distribute_dir, reduce_dir))
                gd.comm.barrier()
                test(N_c, gd, gd2, reduce_dir, distribute_dir, verbose=False)
示例#20
0
 def apply_t(self):
     """Apply kinetic energy operator and return new object."""
     p = 2  # padding
     newsize_c = self.size_c + 2 * p
     gd = GridDescriptor(N_c=newsize_c + 1,
                         cell_cv=self.gd.h_c * (newsize_c + 1),
                         pbc_c=False,
                         comm=mpi.serial_comm)
     T = Laplace(gd, scale =1/2., n=p)
     f_ig = np.zeros((len(self.f_iG),) + tuple(newsize_c))
     f_ig[:, p:-p, p:-p, p:-p] = self.f_iG
     Tf_iG = np.empty_like(f_ig)
     T.apply(f_ig, Tf_iG)
     return LocalizedFunctions(self.gd, Tf_iG, self.corner_c - p,
                               self.index)
示例#21
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)
示例#22
0
    def get_electrostatic_potential(self, ae=True, rcgauss=0.02):
        ham = self.calc.hamiltonian

        if ham.vHt_g is None:
            self.calc.restore_state()
            
        gd = ham.finegd
        v_r = gd.zero_pad(ham.vHt_g)
        gd1 = GridDescriptor(gd.N_c, gd.cell_cv, comm=serial_comm)
        interpolator = Interpolator(gd1, self.gd)
        v_R = interpolator.interpolate(v_r)

        if ae:
            alpha = 1 / (rcgauss / Bohr)**2
            self.add_potential_correction(v_R, alpha)
            
        return v_R * Hartree
示例#23
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
示例#24
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)
示例#25
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()
示例#26
0
    def set_grid_descriptor(self, gd):
        if self.size is None:
            self.shape = gd.N_c.copy()
            for c, n in enumerate(self.shape):
                if not gd.pbc_c[c]:
                    # self.shape[c] = get_efficient_fft_size(n)
                    self.shape[c] = int(2**ceil(log(n) / log(2)))
        else:
            self.shape = np.array(self.size)
            for c, n in enumerate(self.shape):
                if gd.pbc_c[c]:
                    assert n == gd.N_c[c]
                else:
                    assert n >= gd.N_c[c]

        if self.alphas:
            scale_c1 = (self.shape / (1.0 * gd.N_c))[:, np.newaxis]
            gdfft = GridDescriptor(self.shape, gd.cell_cv * scale_c1, True)
            k_k = construct_reciprocal(gdfft)[0][:, :, :self.shape[2] // 2 +
                                                 1]**0.5
            k_k[0, 0, 0] = 0.0

            self.dj_k = k_k / (2 * pi / self.rcut)
            self.j_k = self.dj_k.astype(int)
            self.dj_k -= self.j_k
            self.dj_k *= 2 * pi / self.rcut

            if self.verbose:
                print('VDW: density array size:',
                      gd.get_size_of_global_array())
                print('VDW: zero-padded array size:', self.shape)
                print(('VDW: maximum kinetic energy: %.3f Hartree' %
                       (0.5 * k_k.max()**2)))

            assert self.j_k.max(
            ) < self.Nr // 2, 'Use larger Nr than %i.' % self.Nr

        else:
            self.dj_k = None
            self.j_k = None
示例#27
0
    def get_electrostatic_potential(self, ae=True, rcgauss=0.02):
        """Interpolate electrostatic potential.

        Return value in eV.

        ae: bool
            Add PAW correction to get the all-electron potential.
        rcgauss: float
            Width of gaussian (in Angstrom) used to represent the nuclear
            charge.
        """
        gd = self.calc.hamiltonian.finegd
        v_r = self.calc.get_electrostatic_potential() / Ha
        gd1 = GridDescriptor(gd.N_c, gd.cell_cv, comm=serial_comm)
        interpolator = Interpolator(gd1, self.gd)
        v_R = interpolator.interpolate(v_r)

        if ae:
            alpha = 1 / (rcgauss / Bohr)**2
            self.add_potential_correction(v_R, alpha)

        return v_R * Ha
示例#28
0
    def setUp(self):
        for virtvar in ['equipartition']:
            assert getattr(self,virtvar) is not None, 'Virtual "%s"!' % virtvar

        kpts = {'even' : (12,1,2), \
                'prime': (23,1,1)}[self.equipartition]

        #primes = [i for i in xrange(50,1,-1) if ~np.any(i%np.arange(2,i)==0)]
        bzk_kc = kpts2ndarray(kpts)
        assert p.usesymm == None
        self.nibzkpts = len(bzk_kc)

        #parsize, parsize_bands = create_parsize_minbands(self.nbands, world.size)
        parsize, parsize_bands = 1, 1 #XXX
        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, p.parallel['stridebands'])

        # Set up grid descriptor:
        res, ngpts = shapeopt(300, self.G**3, 3, 0.2)
        cell_c = self.h * np.array(ngpts)
        pbc_c = (True, False, True)
        self.gd = GridDescriptor(ngpts, cell_c, pbc_c, domain_comm, parsize)

        # Create randomized gas-like atomic configuration
        self.atoms = create_random_atoms(self.gd)

        # Create setups
        Z_a = self.atoms.get_atomic_numbers()
        self.setups = Setups(Z_a, p.setups, p.basis, p.lmax, xc)
        self.natoms = len(self.setups)

        # Set up kpoint descriptor:
        self.kd = KPointDescriptor(bzk_kc, self.nspins)
        self.kd.set_symmetry(self.atoms, self.setups, p.usesymm)
        self.kd.set_communicator(kpt_comm)
示例#29
0
文件: wstc.py 项目: thonmaker/gpaw
    def __init__(self, cell_cv, nk_c, txt=None):
        txt = txt or sys.stdout
        self.nk_c = nk_c
        bigcell_cv = cell_cv * nk_c[:, np.newaxis]
        L_c = (np.linalg.inv(bigcell_cv)**2).sum(0)**-0.5

        rc = 0.5 * L_c.min()
        print('Inner radius for %dx%dx%d Wigner-Seitz cell: %.3f Ang' %
              (tuple(nk_c) + (rc * Bohr,)), file=txt)

        self.a = 5 / rc
        print('Range-separation parameter: %.3f Ang^-1' % (self.a / Bohr),
              file=txt)

        nr_c = [get_efficient_fft_size(2 * int(L * self.a * 3.0))
                for L in L_c]
        print('FFT size for calculating truncated Coulomb: %dx%dx%d' %
              tuple(nr_c), file=txt)

        self.gd = GridDescriptor(nr_c, bigcell_cv, comm=mpi.serial_comm)
        v_ijk = self.gd.empty()

        pos_ijkv = self.gd.get_grid_point_coordinates().transpose((1, 2, 3, 0))
        corner_xv = np.dot(np.indices((2, 2, 2)).reshape((3, 8)).T, bigcell_cv)

        # Ignore division by zero (in 0,0,0 corner):
        with seterr(invalid='ignore'):
            # Loop over first dimension to avoid too large ndarrays.
            for pos_jkv, v_jk in zip(pos_ijkv, v_ijk):
                # Distances to the 8 corners:
                d_jkxv = pos_jkv[:, :, np.newaxis] - corner_xv
                r_jk = (d_jkxv**2).sum(axis=3).min(2)**0.5
                v_jk[:] = erf(self.a * r_jk) / r_jk

        # Fix 0/0 corner value:
        v_ijk[0, 0, 0] = 2 * self.a / pi**0.5

        self.K_Q = np.fft.fftn(v_ijk) * self.gd.dv
示例#30
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