Coverage for gpaw/test/gllb/test_response.py: 100%

63 statements  

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

1import pytest 

2import numpy as np 

3from ase.build import molecule 

4from gpaw import GPAW 

5from gpaw.mpi import world, serial_comm, broadcast_exception 

6 

7from gpaw.test.lcaotddft.test_molecule import only_on_master 

8 

9pytestmark = [pytest.mark.usefixtures('module_tmp_path'), 

10 pytest.mark.gllb, 

11 pytest.mark.libxc 

12 ] 

13 

14 

15def check_asp(ref_asp, D_asp, atol): 

16 assert ref_asp is not D_asp, \ 

17 'Trying to compare same objects. Is the test broken?' 

18 assert np.allclose(ref_asp.toarray(), D_asp.toarray(), atol=atol, rtol=0) 

19 

20 

21def check_response(ref_response, response, atol=1e-12): 

22 # Collect response in master 

23 D_asp = response.D_asp.copy() 

24 D_asp.redistribute(D_asp.partition.as_serial()) 

25 Dresp_asp = response.Dresp_asp.copy() 

26 Dresp_asp.redistribute(Dresp_asp.partition.as_serial()) 

27 vt_sG = response.gd.collect(response.vt_sG) 

28 

29 with broadcast_exception(world): 

30 if world.rank == 0: 

31 check_asp(ref_response.D_asp, D_asp, atol=atol) 

32 check_asp(ref_response.Dresp_asp, Dresp_asp, atol=atol) 

33 assert np.allclose(ref_response.vt_sG, vt_sG, rtol=0, atol=atol) 

34 

35 

36def check_partitions(response, gs_calc): 

37 partition = response.D_asp.partition 

38 assert response.Dresp_asp.partition is partition 

39 assert partition == gs_calc.wfs.atom_partition 

40 assert partition == gs_calc.density.atom_partition 

41 

42 

43def calculate_ground_state(**kwargs): 

44 atoms = molecule('H2O') 

45 atoms.center(vacuum=4) 

46 gs_calc = GPAW(mode='lcao', basis='sz(dzp)', h=0.4, 

47 xc='GLLBSC', 

48 txt='gs.out', 

49 **kwargs) 

50 atoms.calc = gs_calc 

51 atoms.get_potential_energy() 

52 return gs_calc 

53 

54 

55@pytest.fixture(scope='module') 

56@only_on_master(world) 

57def ground_state_calculation(): 

58 gs_calc = calculate_ground_state(communicator=serial_comm) 

59 gs_calc.write('gs.gpw', mode='all') 

60 return gs_calc.hamiltonian.xc.response 

61 

62 

63def test_read(ground_state_calculation, module_tmp_path): 

64 ref_response = ground_state_calculation 

65 

66 gs_calc = GPAW(module_tmp_path / 'gs.gpw', txt=None) 

67 response = gs_calc.hamiltonian.xc.response 

68 check_response(ref_response, response) 

69 check_partitions(response, gs_calc) 

70 

71 

72def test_calculate(ground_state_calculation, in_tmp_dir): 

73 ref_response = ground_state_calculation 

74 

75 parallel = {'band': 2 if world.size >= 4 else 1} 

76 gs_calc = calculate_ground_state(parallel=parallel) 

77 response = gs_calc.hamiltonian.xc.response 

78 check_response(ref_response, response) 

79 check_partitions(response, gs_calc) 

80 

81 

82def test_fixed_density(ground_state_calculation, module_tmp_path, in_tmp_dir): 

83 ref_response = ground_state_calculation 

84 

85 parallel = {'band': 2 if world.size >= 4 else 1} 

86 bs_calc = GPAW(module_tmp_path / 'gs.gpw', txt=None) \ 

87 .fixed_density(parallel=parallel, 

88 txt='unocc.out', 

89 ) 

90 response = bs_calc.hamiltonian.xc.response 

91 check_response(ref_response, response) 

92 # check_partitions(response, bs_calc) # Fails. Should it work? 

93 bs_calc.write('unocc.gpw', mode='all') 

94 

95 bs_calc = GPAW('unocc.gpw', txt=None) 

96 response = bs_calc.hamiltonian.xc.response 

97 check_response(ref_response, response) 

98 check_partitions(response, bs_calc)