Coverage for gpaw/test/fd_ops/test_laplace.py: 100%
47 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-08 00:17 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-08 00:17 +0000
1import pytest
2from gpaw.mpi import world
3from math import sin, cos, pi
4import numpy as np
5from gpaw.fd_operators import GUCLaplace as Laplace
6from gpaw.fd_operators import Gradient
7from gpaw.grid_descriptor import GridDescriptor
9pytestmark = pytest.mark.skipif(world.size > 1,
10 reason='world.size > 1')
13def test_fd_ops_laplace():
14 cells = [
15 ('distorted hexagonal', 4,
16 [(1, 0, 0),
17 (1.02 * cos(pi / 3 - 0.02), 1.02 * sin(pi / 3 - 0.02), 0),
18 (0, 0, 1.0)]),
19 ('hexagonal', 4,
20 [(1, 0, 0),
21 (0.5, 3**0.5 / 2, 0),
22 (0, 0, 1.1)]),
23 ('fcc', 6,
24 [(0, 1, 1),
25 (1, 0, 1),
26 (1, 1, 0)]),
27 ('fcc-alternative', 6,
28 [(1, 0, 0),
29 (0.5, 3**0.5 / 2, 0),
30 (0.5, 3**0.5 / 6, (2 / 3)**0.5)]),
31 ('bcc', 4,
32 [(-1, 1, 1),
33 (1, -1, 1),
34 (1, 1, -1)]),
35 ('sc', 3,
36 [1.1, 1.02, 1.03]),
37 ('distorted sc', 6,
38 [(1, 0, 0),
39 (0.01, 1, 0),
40 (0, 0.02, 1)]),
41 ('rocksalt', 6,
42 [(2 * np.sqrt(1 / 3), np.sqrt(1 / 8), -np.sqrt(1 / 24)),
43 (2 * np.sqrt(1 / 3), -np.sqrt(1 / 8), -np.sqrt(1 / 24)),
44 (2 * np.sqrt(1 / 3), 0, np.sqrt(1 / 6))]),
45 ('nasty', 6,
46 [(1, 0, 0),
47 (0.0001, 1.03, 0),
48 (0.0001, 0.0001, 1.0)]),
49 ('Mike', 6,
50 5 * np.array([(5.565 / 28, 0, 0),
51 (0.0001 / 28, 5.565 / 28, 0),
52 (0.0001 / 24, 0.0001 / 24, 4.684 / 24)])),
53 ('MnO', 6,
54 [(1, 0.5, 0.5), (0.5, 1, 0.5), (0.5, 0.5, 1)]),
55 ('Jelver', 6,
56 [[6.658433626216136, 0.1711724130951983, -0.04300038284455887],
57 [3.4774564712755938, 5.843379292501022, 0.01599293966594096],
58 [-0.10777038306906983 * 0.43, 0.10850460815311265 * 0.43,
59 15.26098014321118 * 0.43]])]
61 for name, D, cell in cells:
62 if name == 'Jelver':
63 # Strange one!
64 continue
66 print('------------------')
67 print(name, D)
68 print(cell[0])
69 print(cell[1])
70 print(cell[2])
71 for n in range(1, 5):
72 N = 2 * n + 2
73 gd = GridDescriptor((N, N, N), cell)
74 b_g = gd.zeros()
75 r_gv = gd.get_grid_point_coordinates().transpose((1, 2, 3, 0))
76 c_v = gd.cell_cv.sum(0) / 2
77 r_gv -= c_v
78 lap = Laplace(gd, n=n)
79 grad_v = [Gradient(gd, v, n=n) for v in range(3)]
80 assert lap.npoints == D * 2 * n + 1
81 print([g.npoints for g in grad_v], n, D)
82 for m in range(0, 2 * n + 1):
83 for ix in range(m + 1):
84 for iy in range(m - ix + 1):
85 iz = m - ix - iy
86 a_g = (r_gv**(ix, iy, iz)).prod(3)
87 if ix + iy + iz == 2 and max(ix, iy, iz) == 2:
88 r = 2.0
89 else:
90 r = 0.0
91 lap.apply(a_g, b_g)
92 e = b_g[n + 1, n + 1, n + 1] - r
93 assert abs(e) < 2e-12, e
94 for v in range(3):
95 grad_v[v].apply(a_g, b_g)
96 if m == 1 and [ix, iy, iz][v] == 1:
97 r = 1
98 else:
99 r = 0
100 e = b_g[n + 1, n + 1, n + 1] - r
101 assert abs(e) < 4e-12, (n, ix, iy, iz, r, v, e)