Coverage for gpaw/test/test_orbmag.py: 100%

40 statements  

« prev     ^ index     » next       coverage.py v7.7.1, created at 2025-07-08 00:17 +0000

1import pytest 

2 

3import numpy as np 

4 

5from gpaw.new.ase_interface import GPAW 

6from gpaw.new.calculation import CalculationModeError 

7from gpaw.spinorbit import soc_eigenstates 

8 

9 

10@pytest.mark.soc 

11def test_orbmag_Ni(gpw_files): 

12 # Parameters 

13 

14 easy_axis = 1 / np.sqrt(3) * np.ones(3) 

15 theta = np.rad2deg(np.arccos(easy_axis[2])) 

16 phi = 45 

17 

18 # Collinear calculation 

19 

20 calc_col = GPAW(gpw_files['fcc_Ni_col'], 

21 parallel={'domain': 1, 'band': 1}) 

22 

23 energy_col = calc_col.get_potential_energy(calc_col.atoms) 

24 density = calc_col.dft.density 

25 magmoms_col_v, _ = density.calculate_magnetic_moments() 

26 with pytest.raises(CalculationModeError, match='Calculator is in*'): 

27 calc_col.get_orbital_magnetic_moments() 

28 orbmag_col_v = soc_eigenstates(calc_col, 

29 theta=theta, 

30 phi=phi).get_orbital_magnetic_moments()[0] 

31 

32 # Non-collinear calculation without self-consistent spin–orbit 

33 

34 calc_ncol = GPAW(gpw_files['fcc_Ni_ncol'], 

35 parallel={'domain': 1, 'band': 1}) 

36 

37 energy_ncol = calc_ncol.get_potential_energy(calc_ncol.atoms) 

38 density = calc_ncol.dft.density 

39 magmoms_ncol_v, _ = density.calculate_magnetic_moments() 

40 with pytest.warns(UserWarning, match='Non-collinear calculation*'): 

41 calc_ncol.get_orbital_magnetic_moments() 

42 orbmag_ncol_v = soc_eigenstates( 

43 calc_ncol).get_orbital_magnetic_moments()[0] 

44 

45 # Test that col and ncol give the same groundstate (with rotated magmoms) 

46 # and the same orbital magnetic moments from the soc_eigenstates module 

47 

48 dif_energy = energy_ncol - energy_col 

49 dif_magmom = np.linalg.norm(magmoms_ncol_v) - magmoms_col_v[2] 

50 dif_orbmag = np.linalg.norm(orbmag_ncol_v - orbmag_col_v) 

51 

52 assert dif_energy == pytest.approx(0, abs=1.0e-6) 

53 assert dif_magmom == pytest.approx(0, abs=1.0e-6) 

54 assert dif_orbmag == pytest.approx(0, abs=1.0e-5) 

55 

56 # Non-collinear calculation with self-consistent spin–orbit 

57 calc_ncolsoc = GPAW(gpw_files['fcc_Ni_ncolsoc'], 

58 parallel={'domain': 1, 'band': 1}) 

59 

60 energy_ncolsoc = calc_ncolsoc.get_potential_energy(calc_ncolsoc.atoms) 

61 assert energy_ncolsoc == pytest.approx(-8.33016, abs=1.0e-5) 

62 orbmag_ncolsoc_v = calc_ncolsoc.get_orbital_magnetic_moments()[0] 

63 

64 # Assert direction and magnitude of orbital magnetic moment 

65 assert np.linalg.norm(orbmag_ncolsoc_v) == pytest.approx( 

66 0.044320880619364636, abs=2e-6) 

67 assert np.dot(orbmag_ncolsoc_v, easy_axis) == pytest.approx( 

68 0.044320880619364636, abs=2e-6) 

69 

70 # Get difference between orbital magnetic moments when soc is included 

71 # self-consistently. Assert that this difference doesn't change. 

72 

73 dif_orbmag2 = np.linalg.norm(orbmag_ncolsoc_v - orbmag_col_v) 

74 dif_orbmag3 = np.linalg.norm(orbmag_ncolsoc_v - orbmag_ncol_v) 

75 

76 assert dif_orbmag2 == pytest.approx(0.002409330194910108, abs=1e-5) 

77 assert dif_orbmag3 == pytest.approx(0.002409330194910108, abs=1e-5)