Coverage for gpaw/test/gpu/test_pw.py: 87%
79 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 ase import Atoms
3from ase.units import Ha
5from gpaw.dft import DFT
6from gpaw.mpi import size
7from gpaw.poisson import FDPoissonSolver
8from gpaw.new.c import GPU_AWARE_MPI
11@pytest.mark.gpu
12@pytest.mark.serial
13@pytest.mark.parametrize('dtype', [float, complex])
14@pytest.mark.parametrize('gpu', [False, True])
15@pytest.mark.parametrize('mode', ['pw', 'fd'])
16@pytest.mark.parametrize('random', [False, True])
17def test_gpu(dtype, gpu, mode, random):
18 atoms = Atoms('H2')
19 atoms.positions[1, 0] = 0.75
20 atoms.center(vacuum=1.0)
21 if mode == 'fd':
22 kwargs = {'poissonsolver': FDPoissonSolver(),
23 'h': 0.17}
24 else:
25 kwargs = {}
26 dft = DFT(
27 atoms,
28 mode={'name': mode,
29 'force_complex_dtype': dtype == complex},
30 random=random,
31 convergence={'density': 1e-8},
32 parallel={'gpu': gpu},
33 setups='paw',
34 **kwargs)
35 dft.converge()
36 dft.energy()
37 energy = dft.results['energy'] * Ha
38 if mode == 'pw':
39 assert energy == pytest.approx(-16.032945, abs=1e-6)
40 else:
41 assert energy == pytest.approx(5.07197289, abs=1e-6)
44@pytest.mark.gpu
45@pytest.mark.skipif(size > 2, reason='Not implemented')
46@pytest.mark.parametrize('gpu', [False, True])
47@pytest.mark.parametrize('par', ['domain', 'kpt', 'band'])
48@pytest.mark.parametrize('mode', ['pw', 'fd'])
49@pytest.mark.parametrize('xc', ['LDA', 'PBE'])
50def test_gpu_k(gpu, par, mode, xc):
51 if gpu and size > 1 and not GPU_AWARE_MPI:
52 if mode == 'fd' and par == 'domain':
53 pytest.skip('Domain decomposition needs GPU-aware MPI')
54 if mode == 'pw' and par == 'domain' and xc == 'PBE':
55 pytest.skip('Domain decomposition needs GPU-aware MPI')
56 if mode == 'fd':
57 pytest.skip('???')
58 if mode == 'pw' and par in ['kpt', 'band'] and xc == 'PBE':
59 pytest.skip('???')
61 if gpu and size > 1:
62 if mode == 'fd' and par == 'band':
63 pytest.skip('FAILING')
65 if size == 1 and par in ['kpt', 'band']:
66 pytest.skip('Not testing parallelization on single core')
68 atoms = Atoms('H', pbc=True, cell=[1, 1.1, 1.1])
69 if mode == 'fd':
70 poisson = FDPoissonSolver()
71 h = 0.09
72 else:
73 poisson = None
74 h = None
76 dft = DFT(
77 atoms,
78 mode={'name': mode},
79 spinpol=True,
80 xc=xc,
81 h=h,
82 convergence={'density': 1e-8},
83 kpts=(4, 1, 1),
84 poissonsolver=poisson,
85 parallel={'gpu': gpu,
86 par: size},
87 setups='paw')
88 dft.converge()
89 dft.energy()
90 if mode == 'pw':
91 dft.forces()
92 dft.stress()
93 energy = dft.results['energy'] * Ha
94 ref = {'LDAfd': -17.685022604078714,
95 'PBEfd': -17.336991943070384,
96 'PBEpw': -17.304186,
97 'LDApw': -17.653433}[xc + mode]
98 assert energy == pytest.approx(ref, abs=1e-6)
101@pytest.mark.gpu
102def test_2d():
103 atoms = Atoms('H', pbc=[True, True, False], cell=[1, 1, 5])
104 atoms.center(axis=2)
106 dft = DFT(
107 atoms,
108 mode={'name': 'pw'},
109 spinpol=True,
110 xc='LDA',
111 convergence={'density': 1e-8},
112 kpts=(2, 2, 1),
113 parallel={'gpu': True})
114 dft.converge()
115 assert dft.potential.get_vacuum_level() == pytest.approx(2.9436, 1e-2)
116 dft.energy()
117 dft.forces()
118 dft.stress()
119 E = dft.results['energy']
120 F = dft.results['forces']
121 S = dft.results['stress']
122 assert E == pytest.approx(0.1769, 1e-2)
123 assert F[0] == pytest.approx([0, 0, 0], 1e-6)
124 assert S == pytest.approx([-0.0110, -0.0110, 0.0002,
125 0.0, 0.0, 0.0], abs=0.001)