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