Coverage for /builds/kinetik161/ase/ase/calculators/orca.py: 50.00%

38 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-12-10 11:04 +0000

1import re 

2 

3import ase.io.orca as io 

4from ase.calculators.genericfileio import (CalculatorTemplate, 

5 GenericFileIOCalculator, 

6 BaseProfile) 

7 

8 

9def get_version_from_orca_header(orca_header): 

10 match = re.search(r'Program Version (\S+)', orca_header, re.M) 

11 return match.group(1) 

12 

13 

14class OrcaProfile(BaseProfile): 

15 def __init__(self, binary, **kwargs): 

16 """ 

17 Parameters 

18 ---------- 

19 binary : str 

20 Full path to the orca binary, if full path is not specified ORCA 

21 cannot run in parallel. 

22 """ 

23 # Because ORCA handles its parallelization without being called with 

24 # mpirun/mpiexec/etc parallel should be set to False. 

25 # Whether or not it is run in parallel is controlled by the orcablocks 

26 super().__init__(parallel=False, parallel_info={}) 

27 self.binary = binary 

28 

29 def version(self): 

30 # XXX Allow MPI in argv; the version call should not be parallel. 

31 from ase.calculators.genericfileio import read_stdout 

32 stdout = read_stdout([self.binary, "does_not_exist"]) 

33 return get_version_from_orca_header(stdout) 

34 

35 def get_calculator_command(self, inputfile): 

36 return [self.binary, inputfile] 

37 

38 

39class OrcaTemplate(CalculatorTemplate): 

40 _label = 'orca' 

41 

42 def __init__(self): 

43 super().__init__(name='orca', 

44 implemented_properties=['energy', 'free_energy', 

45 'forces']) 

46 

47 self.input_file = f'{self._label}.inp' 

48 self.output_file = f'{self._label}.out' 

49 

50 def execute(self, directory, profile) -> None: 

51 profile.run(directory, self.input_file, self.output_file) 

52 

53 def write_input(self, profile, directory, atoms, parameters, properties): 

54 parameters = dict(parameters) 

55 

56 kw = dict(charge=0, mult=1, orcasimpleinput='B3LYP def2-TZVP', 

57 orcablocks='%pal nprocs 1 end') 

58 kw.update(parameters) 

59 

60 io.write_orca(directory / self.input_file, atoms, kw) 

61 

62 def read_results(self, directory): 

63 return io.read_orca_outputs(directory, directory / self.output_file) 

64 

65 def load_profile(self, cfg, **kwargs): 

66 return OrcaProfile.from_config(cfg, self.name, **kwargs) 

67 

68 

69class ORCA(GenericFileIOCalculator): 

70 """Class for doing ORCA calculations. 

71 

72 Example: 

73 

74 calc = ORCA(charge=0, mult=1, orcasimpleinput='B3LYP def2-TZVP', 

75 orcablocks='%pal nprocs 16 end') 

76 """ 

77 

78 def __init__(self, *, profile=None, directory='.', parallel_info=None, 

79 parallel=None, **kwargs): 

80 """Construct ORCA-calculator object. 

81 

82 Parameters 

83 ========== 

84 charge: int 

85 

86 mult: int 

87 

88 orcasimpleinput : str 

89 

90 orcablocks: str 

91 

92 

93 Examples 

94 ======== 

95 Use default values: 

96 

97 >>> from ase.calculators.orca import ORCA 

98 >>> h = Atoms( 

99 ... 'H', 

100 ... calculator=ORCA( 

101 ... charge=0, 

102 ... mult=1, 

103 ... directory='water', 

104 ... orcasimpleinput='B3LYP def2-TZVP', 

105 ... orcablocks='%pal nprocs 16 end')) 

106 

107 """ 

108 

109 assert parallel is None, \ 

110 'ORCA does not support keyword parallel - use orcablocks' 

111 assert parallel_info is None, \ 

112 'ORCA does not support keyword parallel_info - use orcablocks' 

113 

114 super().__init__(template=OrcaTemplate(), 

115 profile=profile, directory=directory, 

116 parameters=kwargs)