Coverage for gpaw/test/noncollinear/test_soc.py: 98%
58 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
1"""Test HOMO and LUMO band-splitting for MoS2.
3See:
5 https://journals.aps.org/prb/abstract/10.1103/PhysRevB.98.155433
6"""
8import numpy as np
9import pytest
10from ase.build import mx2
11from gpaw import GPAW
12import gpaw.mpi as mpi
13from gpaw.spinorbit import soc_eigenstates
14from gpaw.berryphase import polarization_phase
15from pathlib import Path
18def check(E, hsplit, lsplit):
19 print(E)
20 h1, h2, l1, l2 = E[24:28] # HOMO-1, HOMO, LUMO, LUMO+1
21 print(h2 - h1)
22 print(l2 - l1)
23 assert abs(h2 - h1 - hsplit) < 0.01
24 assert abs(l2 - l1 - lsplit) < 0.002
27def check_pol(phi_c):
28 pol_c = (phi_c / (2 * np.pi)) % 1
29 assert abs(pol_c[0] - 2 / 3) < 0.01
30 assert abs(pol_c[1] - 1 / 3) < 0.01
33params = dict(mode={'name': 'pw', 'ecut': 350},
34 kpts={'size': (3, 3, 1), 'gamma': True})
37@pytest.mark.soc
38@pytest.mark.skipif(mpi.size > 2, reason='May not work in parallel')
39def test_soc_self_consistent(gpaw_new, in_tmp_dir):
40 """Self-consistent SOC."""
41 gpw_wfs = Path('mos2.gpw')
42 a = mx2('MoS2')
43 a.center(vacuum=3, axis=2)
45 if gpaw_new:
46 kwargs = {**params, 'symmetry': 'off',
47 'magmoms': np.zeros((3, 3)), 'soc': True}
48 else:
49 kwargs = {**params, 'symmetry': 'off',
50 'experimental': {'magmoms': np.zeros((3, 3)), 'soc': True}}
52 a.calc = GPAW(convergence={'bands': 28}, **kwargs)
53 a.get_potential_energy()
54 eigs = a.calc.get_eigenvalues(kpt=0)
55 check(eigs, 0.15, 0.002)
57 a.calc.write(gpw_wfs, 'all')
58 GPAW(gpw_wfs)
60 if mpi.size == 1:
61 phases_c = polarization_phase(gpw_wfs, comm=mpi.world)
62 phi_c = phases_c['electronic_phase_c']
63 check_pol(phi_c)
66@pytest.mark.soc
67@pytest.mark.skipif(mpi.size > 2,
68 reason='Does not work with more than 2 cores')
69def test_non_collinear_plus_soc():
70 a = mx2('MoS2')
71 a.center(vacuum=3, axis=2)
73 a.calc = GPAW(experimental={'magmoms': np.zeros((3, 3)), 'soc': False},
74 convergence={'bands': 28}, symmetry='off',
75 parallel={'domain': 1}, **params)
76 a.get_potential_energy()
78 bzwfs = soc_eigenstates(a.calc, n2=28)
79 eigs = bzwfs.eigenvalues()[8]
80 check(eigs, 0.15, 0.007)
83@pytest.mark.soc
84def test_soc_non_self_consistent():
85 """Non self-consistent SOC."""
86 a = mx2('MoS2')
87 a.center(vacuum=3, axis=2)
89 a.calc = GPAW(convergence={'bands': 14}, **params)
90 a.get_potential_energy()
92 bzwfs = soc_eigenstates(a.calc, n2=14)
93 eigs = bzwfs.eigenvalues()[8]
94 check(eigs, 0.15, 0.007)