Exemple #1
0
 def set_grid_descriptor(self, gd):
     if self.is_extended:
         self.gd_original = gd
         assert np.all(self.gd_original.N_c <= self.extended['finegpts']), \
             'extended grid has to be larger than the original one'
         gd, _, _ = extended_grid_descriptor(
             gd,
             N_c=self.extended['finegpts'],
             extcomm=self.extended.get('comm'))
     FDPoissonSolver.set_grid_descriptor(self, gd)
Exemple #2
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
Exemple #3
0
    phi_g = gd.zeros()
    npoisson = poisson.solve(phi_g, rho_g)
    return phi_g, npoisson


def compare(phi1_g, phi2_g, val):
    big_phi1_g = gd.collect(phi1_g)
    big_phi2_g = gd.collect(phi2_g)
    if gd.comm.rank == 0:
        equal(np.max(np.absolute(big_phi1_g - big_phi2_g)), val,
              np.sqrt(poissoneps))


# Get reference from default poissonsolver
poisson = PoissonSolver(eps=poissoneps)
poisson.set_grid_descriptor(gd)
phiref_g, npoisson = poisson_solve(gd, rho_g, poisson)

# Test agreement with default
poisson = ExtendedPoissonSolver(eps=poissoneps)
poisson.set_grid_descriptor(gd)
phi_g, npoisson = poisson_solve(gd, rho_g, poisson)
plot_phi(phi_g)
compare(phi_g, phiref_g, 0.0)

# Test moment_corrections=int
poisson = ExtendedPoissonSolver(eps=poissoneps, moment_corrections=4)
poisson.set_grid_descriptor(gd)
phi_g, npoisson = poisson_solve(gd, rho_g, poisson)
plot_phi(phi_g)
compare(phi_g, phiref_g, 4.1182101206e-02)