Coverage for gpaw/test/poisson/test_poisson_extravacuum.py: 72%
105 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-19 00:19 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-19 00:19 +0000
1import pytest
2from gpaw.mpi import world
3import time
4import numpy as np
6from gpaw.poisson import PoissonSolver
7from gpaw.poisson_extravacuum import ExtraVacuumPoissonSolver
8from gpaw.grid_descriptor import GridDescriptor
11pytestmark = pytest.mark.skipif(world.size > 4,
12 reason='world.size > 4')
15def test_poisson_poisson_extravacuum():
16 do_output = False
17 do_plot = False
18 poissoneps = 1e-16
20 # Model grid
21 N = 16
22 N_c = np.array((1, 1, 3)) * N
23 cell_c = N_c / float(N)
24 gd = GridDescriptor(N_c, cell_c, False)
26 # Construct model density
27 coord_vg = gd.get_grid_point_coordinates()
28 z_g = coord_vg[2, :]
29 rho_g = gd.zeros()
30 for z0 in [1, 2]:
31 rho_g += 10 * (z_g - z0) * \
32 np.exp(-20 * np.sum((coord_vg.T - np.array([.5, .5, z0])).T**2,
33 axis=0))
35 if do_plot:
36 big_rho_g = gd.collect(rho_g)
37 if gd.comm.rank == 0:
38 import matplotlib.pyplot as plt
39 fig, ax_ij = plt.subplots(3, 4, figsize=(20, 10))
40 ax_i = ax_ij.ravel()
41 ploti = 0
42 Ng_c = gd.get_size_of_global_array()
43 plt.sca(ax_i[ploti])
44 ploti += 1
45 plt.pcolormesh(big_rho_g[Ng_c[0] / 2])
46 plt.sca(ax_i[ploti])
47 ploti += 1
48 plt.plot(big_rho_g[Ng_c[0] / 2, Ng_c[1] / 2])
50 def plot_phi(phi_g):
51 if do_plot:
52 big_phi_g = gd.collect(phi_g)
53 if gd.comm.rank == 0:
54 global ploti
55 if ploti == 4:
56 ploti -= 2
57 plt.sca(ax_i[ploti])
58 ploti += 1
59 plt.pcolormesh(big_phi_g[Ng_c[0] / 2])
60 plt.sca(ax_i[ploti])
61 ploti += 1
62 plt.plot(big_phi_g[Ng_c[0] / 2, Ng_c[1] / 2])
63 plt.ylim(np.array([-1, 1]) * 0.15)
65 def poisson_solve(gd, rho_g, poisson):
66 phi_g = gd.zeros()
67 rho_g = rho_g
68 t0 = time.time()
69 npoisson = poisson.solve(phi_g, rho_g)
70 t1 = time.time()
71 if do_output:
72 if gd.comm.rank == 0:
73 print('Iterations: %s, Time: %.3f s' %
74 (str(npoisson), t1 - t0))
75 return phi_g, npoisson
77 def poisson_init_solve(gd, rho_g, poisson):
78 poisson.set_grid_descriptor(gd)
79 phi_g, npoisson = poisson_solve(gd, rho_g, poisson)
80 plot_phi(phi_g)
81 return phi_g, npoisson
83 def compare(phi1_g, phi2_g, val, eps=np.sqrt(poissoneps)):
84 big_phi1_g = gd.collect(phi1_g)
85 big_phi2_g = gd.collect(phi2_g)
86 if gd.comm.rank == 0:
87 diff = np.max(np.absolute(big_phi1_g - big_phi2_g))
88 else:
89 diff = 0.0
90 diff = np.array([diff])
91 gd.comm.broadcast(diff, 0)
92 assert diff[0] == pytest.approx(val, abs=eps)
94 # Get reference from default poissonsolver
95 poisson = PoissonSolver('fd', eps=poissoneps)
96 phiref_g, npoisson = poisson_init_solve(gd, rho_g, poisson)
98 # Test agreement with default
99 poisson = ExtraVacuumPoissonSolver(
100 N_c, PoissonSolver('fd', eps=poissoneps))
101 phi_g, npoisson = poisson_init_solve(gd, rho_g, poisson)
102 compare(phi_g, phiref_g, 0.0, 1e-15)
104 # New reference with extra vacuum
105 gpts = N_c * 4
106 poisson = ExtraVacuumPoissonSolver(
107 gpts, PoissonSolver('fd', eps=poissoneps))
108 phi_g, npoisson = poisson_init_solve(gd, rho_g, poisson)
109 # print poisson.get_description()
110 compare(phi_g, phiref_g, 2.6485385144e-02)
111 phiref_g = phi_g
113 # Test with single coarsening
114 poisson = ExtraVacuumPoissonSolver(
115 gpts,
116 PoissonSolver('fd', eps=poissoneps),
117 PoissonSolver('fd', eps=poissoneps),
118 1)
119 phi_g, npoisson = poisson_init_solve(gd, rho_g, poisson)
120 compare(phi_g, phiref_g, 1.5043946611e-04)
122 # Test with two coarsenings
123 poisson = ExtraVacuumPoissonSolver(
124 gpts,
125 PoissonSolver('fd', eps=poissoneps),
126 PoissonSolver('fd', eps=poissoneps),
127 2)
128 phi_g, npoisson = poisson_init_solve(gd, rho_g, poisson)
129 compare(phi_g, phiref_g, 1.2980906205e-03)
131 # Test with cascaded single coarsenings
132 poisson1 = ExtraVacuumPoissonSolver(gpts / 2,
133 PoissonSolver('fd', eps=poissoneps),
134 PoissonSolver('fd', eps=poissoneps), 1)
135 poisson = ExtraVacuumPoissonSolver(gpts / 2, poisson1,
136 PoissonSolver('fd', eps=poissoneps), 1)
137 phi_g, npoisson = poisson_init_solve(gd, rho_g, poisson)
138 # print poisson.get_description()
139 compare(phi_g, phiref_g, 1.7086531461e-04)
141 # Test auxgrid
142 gpts = N_c * 4
143 for coarses in [1, 2, 3]:
144 for nn_refine in [1, 3]:
145 for nn_laplace in [1, 3]:
146 EVPS = ExtraVacuumPoissonSolver
147 poisson = EVPS(gpts, PoissonSolver('fd', eps=poissoneps),
148 PoissonSolver('fd', eps=poissoneps), coarses,
149 use_aux_grid=False,
150 nn_refine=nn_refine, nn_laplace=nn_laplace)
151 phiref_g, npoisson = poisson_init_solve(gd, rho_g, poisson)
153 poisson = EVPS(gpts, PoissonSolver('fd', eps=poissoneps),
154 PoissonSolver('fd', eps=poissoneps), coarses,
155 use_aux_grid=True,
156 nn_refine=nn_refine, nn_laplace=nn_laplace)
157 phi_g, npoisson = poisson_init_solve(gd, rho_g, poisson)
158 compare(phi_g, phiref_g, 0.0, 1e-14)
160 if do_plot:
161 if gd.comm.rank == 0:
162 plt.show()