Coverage for gpaw/atom/gpaw_setup.py: 3%

93 statements  

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

1from optparse import OptionParser 

2 

3 

4def build_parser(): 

5 parser = OptionParser(usage='%prog [options] [elements]', 

6 version='%prog 0.1') 

7 parser.add_option('-f', '--xcfunctional', type='string', default='LDA', 

8 help='Exchange-Correlation functional ' + 

9 '(default value LDA)', metavar='<XC>') 

10 parser.add_option('-n', '--non-scalar-relativistic', action='store_true', 

11 default=False, 

12 help='Do *not* do a scalar-relativistic calculation.') 

13 parser.add_option('-x', '--exact-exchange', action='store_true', 

14 default=False, 

15 help='Calculate exact exchange integrals.') 

16 parser.add_option('--gamma', type='float', 

17 help='Set gamma for Yukawa dampening.') 

18 parser.add_option('-r', '--radius', type='string', default=None, 

19 help='Cutoff radius or radii (comma separated).', 

20 metavar='<rcut>') 

21 parser.add_option('-v', '--zero-potential', metavar='type,radius', 

22 help='Type of zero-potential - type must be either ' + 

23 '"poly" or "f".') 

24 parser.add_option('--filter', metavar='h,x', 

25 help='Parameters used for Fourier-filtering and ' 

26 'projector functions and zero-potential. "h" is ' 

27 'the cutoff grid-spacing (in Bohr) and "x" is the ' 

28 'ratio between outer and inner radii.') 

29 parser.add_option('-l', '--logarithmic-derivatives', action='store_true', 

30 help='Calculate logarithmic derivatives.') 

31 parser.add_option('-a', '--all-electron-only', action='store_true', 

32 help='Skip generation of PAW setup.') 

33 parser.add_option('-e', '--extra-projectors', type='string', default=None, 

34 help='Extra projectors. Use ";" to separate s, p and ' + 

35 'd channels. Examples: "0.0,1.0" for two extra ' + 

36 's-type. "0.0;1.0" for extra s and p. ";1.0" for ' + 

37 'extra p.', metavar='0.0;0.0,1.0;0.0') 

38 parser.add_option('-c', '--core', type='string', default=None, 

39 help='Frozen core. Examples: "[Ne]", "[Ar]3d".', 

40 metavar='<core>') 

41 parser.add_option('--normconserving', type='string', 

42 help='Examples: s, sp.') 

43 parser.add_option('--core-hole', metavar='state,occ', 

44 help='Add core hole. Examples: "1s,0.5", "2p,1".') 

45 parser.add_option('--configuration', metavar='config', 

46 help='Specify non-groundstate configuration. ' 

47 'Na+ ion: "Ne,3s0", O2- ion: "1s2,2s2,2p6" or ' + 

48 '"He,2s2,2p6".') 

49 parser.add_option('--compensation-charge-radius', metavar='rcut', 

50 type=float, 

51 help='Cutoff radius for compensation charges.') 

52 parser.add_option('--name', type='string', metavar='<id>', 

53 help='Name to use for setup file: <symbol>.<id>.<xc>. ' 

54 'Default name is <symbol>.<xc>.') 

55 parser.add_option('-w', '--write-files', action='store_true', 

56 help='Write wave functions and other things to files.') 

57 parser.add_option('-p', '--plot', action='store_true', 

58 help='Show plot and generate reStructuredText.') 

59 parser.add_option('-g', '--points-per-node', metavar='<gpernode>', 

60 type=int, default=150, 

61 help='Number of radial grid points per node.') 

62 parser.add_option('--empty-states', type='string', default=None, 

63 help='Add empty state(s). Example: 5p.', 

64 metavar='<states>') 

65 parser.add_option('--tw-coefficient', type='float', default=1, 

66 help='Sets value of coefficient in Thomas-Fermi ' + 

67 'calculations. Default is 1', 

68 metavar='<tw-coefficient>') 

69 parser.add_option('--orbital-free', action='store_true', 

70 help='Generates orbital-free Thomas-Fermi setup') 

71 return parser 

72 

73 

74def main(): 

75 parser = build_parser() 

76 opt, args = parser.parse_args() 

77 

78 import sys 

79 

80 from gpaw.atom.generator import Generator 

81 from gpaw.atom.configurations import parameters, tf_parameters 

82 from gpaw.atom.all_electron import AllElectron 

83 from gpaw import ConvergenceError 

84 

85 if args: 

86 atoms = args 

87 else: 

88 atoms = parameters.keys() 

89 

90 bad_density_warning = """\ 

91 Problem with initial electron density guess! Try to run the program 

92 with the '-nw' option (non-scalar-relativistic calculation + write 

93 density) and then try again without the '-n' option (this will 

94 generate a good initial guess for the density).""" 

95 

96 for symbol in atoms: 

97 scalarrel = not opt.non_scalar_relativistic 

98 

99 corehole = None 

100 if opt.core_hole is not None: 

101 state, occ = opt.core_hole.split(',') 

102 # Translate corestate string ('1s') to n and l: 

103 ncorehole = int(state[0]) 

104 lcorehole = 'spdf'.find(state[1]) 

105 fcorehole = float(occ) 

106 corehole = (ncorehole, lcorehole, fcorehole) 

107 

108 if opt.all_electron_only: 

109 a = AllElectron(symbol, opt.xcfunctional, scalarrel, corehole, 

110 opt.configuration, not opt.write_files, '-', 

111 opt.points_per_node, 

112 opt.orbital_free, opt.tw_coefficient) 

113 try: 

114 a.run() 

115 except ConvergenceError: 

116 print(bad_density_warning, file=sys.stderr) 

117 continue 

118 g = Generator(symbol, opt.xcfunctional, scalarrel, corehole, 

119 opt.configuration, not opt.write_files, '-', 

120 opt.points_per_node, orbital_free=opt.orbital_free, 

121 tw_coeff=opt.tw_coefficient) 

122 

123 if opt.orbital_free: 

124 p = tf_parameters.get(symbol, {'rcut': 0.9}) 

125 else: 

126 p = parameters.get(symbol, {}) 

127 

128 if opt.core is not None: 

129 p['core'] = opt.core 

130 

131 if opt.radius is not None: 

132 p['rcut'] = [float(x) for x in opt.radius.split(',')] 

133 

134 if opt.extra_projectors is not None: 

135 extra = {} 

136 if opt.extra_projectors != '': 

137 for l, x in enumerate(opt.extra_projectors.split(';')): 

138 if x != '': 

139 extra[l] = [float(y) for y in x.split(',')] 

140 p['extra'] = extra 

141 

142 if opt.normconserving is not None: 

143 p['normconserving'] = opt.normconserving 

144 

145 if opt.filter is not None: 

146 p['filter'] = [float(x) for x in opt.filter.split(',')] 

147 

148 if opt.compensation_charge_radius is not None: 

149 p['rcutcomp'] = opt.compensation_charge_radius 

150 

151 if opt.zero_potential is not None: 

152 vbar = opt.zero_potential.split(',') 

153 p['vbar'] = (vbar[0], float(vbar[1])) 

154 

155 if opt.empty_states is not None: 

156 p['empty_states'] = opt.empty_states 

157 

158 if opt.gamma is not None: 

159 p['yukawa_gamma'] = opt.gamma 

160 

161 try: 

162 g.run(logderiv=opt.logarithmic_derivatives, 

163 exx=opt.exact_exchange, name=opt.name, 

164 **p) 

165 except ConvergenceError: 

166 print(bad_density_warning, file=sys.stderr) 

167 except RuntimeError as m: 

168 if len(m.__str__()) == 0: 

169 raise 

170 print(m) 

171 

172 if opt.plot: 

173 from gpaw.atom.analyse_setup import analyse 

174 analyse(g, show=True)