Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1"""This is the implementation of the exciting I/O functions. 

2 

3The main roles these functions do is write exciting ground state 

4input files and read exciting ground state ouput files. 

5 

6Right now these functions all written without a class to wrap them. This 

7could change in the future but was done to make things simpler. 

8 

9These functions are primarily called by the exciting caculator in 

10ase/calculators/exciting/exciting.py. 

11 

12See the correpsonding test file in ase/test/io/test_exciting.py. 

13 

14Plan is to add parsing of eigenvalues in the next iteration using 

15excitingtools.exciting_dict_parsers.groundstate_parser.parse_eigval 

16 

17Note: excitingtools must be installed using `pip install excitingtools` for 

18the exciting io to work. 

19""" 

20from pathlib import Path 

21from typing import Dict, Union 

22 

23import ase 

24 

25 

26def parse_output(info_out_file_path): 

27 """Parse exciting INFO.OUT output file using excitingtools. 

28 

29 Note, excitingtools works by returning a dictionary that contains 

30 two high level keys. Initialization and results. Initialization 

31 contains data about how the calculation was setup (e.g. structure, 

32 maximum number of planewaves, etc...) and the results 

33 gives SCF cycle result information (e.g. total energy). 

34 

35 Args: 

36 info_out_file_path: path to an INFO.out exciting output file. 

37 Returns: 

38 A dictionary containing information about how the calculation was setup 

39 and results from the calculations SCF cycles. 

40 """ 

41 from excitingtools.exciting_dict_parsers.groundstate_parser import ( 

42 parse_info_out) 

43 # Check for the file: 

44 if not Path(info_out_file_path).is_file(): 

45 raise FileNotFoundError 

46 return parse_info_out(info_out_file_path) 

47 

48 

49def write_input_xml_file( 

50 file_name, atoms: ase.Atoms, input_parameters: Dict, 

51 species_path, title=None): 

52 """Write input xml file for exciting calculation. 

53 

54 Args: 

55 file_name: where to save the input xml file. 

56 atoms: ASE Atoms object. 

57 input_parameters: Ground state parameters to affect exciting calc. 

58 """ 

59 from excitingtools.input.ground_state import ExcitingGroundStateInput 

60 from excitingtools.input.input_xml import ExcitingInputXML 

61 from excitingtools.input.structure import ExcitingStructure 

62 # Convert ground state dictionary into expected input object. 

63 ground_state = ExcitingGroundStateInput(**input_parameters) 

64 structure = ExcitingStructure(atoms, species_path=species_path) 

65 

66 input_xml = ExcitingInputXML(structure, ground_state, title=title) 

67 input_xml.write(file_name) 

68 

69 

70def ase_atoms_from_exciting_input_xml( 

71 input_xml_path: Union[Path, str]) -> ase.Atoms: 

72 """Helper function to read structure from input.xml file. 

73 

74 Note, this function operates on the input.xml file that is the input 

75 to an exciting calculation. It parses the structure data given in the file 

76 and returns it in an ase Atoms object. Note this information can also be 

77 taken from an INFO.out file using parse_output. This script is more 

78 lightweight than parse_output since the input xml is significantly smaller 

79 than an INFO.out file and is XML structured making the parsing easier. 

80 

81 Args: 

82 input_xml_path: Path where input.xml file lives. 

83 

84 Returns: 

85 ASE atoms object with all the relevant fields filled. 

86 """ 

87 from excitingtools.exciting_dict_parsers.input_parser import ( 

88 parse_structure) 

89 struct_dict = parse_structure(input_xml_path) 

90 symbols_list = [] 

91 positions_list = [] 

92 for atom in struct_dict['atoms']: 

93 symbols_list.append(atom['species']) 

94 positions_list.append(atom['position']) 

95 

96 atoms_object = ase.Atoms( 

97 symbols=symbols_list, 

98 cell=struct_dict['lattice'], 

99 positions=positions_list) 

100 

101 atoms_object.set_pbc(True) 

102 return atoms_object