forked from CCQC/optavc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
161 lines (136 loc) · 6.07 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
"""
Wrapper's for running optavc with a single method call.
run_optavc() currently supports:
running finite differences of singlepoints to calculate Hessians
Running optimizations by performing finite differences of gradients.
run_optavc_mpi()
has never been used or tested all code is legacy for use on NERSC. Use WILL require work
"""
from optavc.options import Options
from . import optimize
from . import findifcalcs
from . import xtpl
from .template import TemplateFileProcessor
def run_optavc(jobtype, options_dict, restart_iteration=0, xtpl_restart=None, sow=True, path=".",
test_input=False):
""" optavc driver meant to unify input. Create options object, needed template objects, start
Hessian or Optimization calculation
Parameters
----------
jobtype: str
generous with available strings for optimziation / hessian
options_dict: dict
should contain BOTH optavc and psi4 options
restart_iteration: int
corresponds to the iteration we should begin trying to sow gradients for
xtpl_restart: str
should be ['high_corr', 'large_basis', 'med_basis', 'small_basis']
sow: bool
if False optavc will try to reap only
path: str
for Hessian jobs only
test_input: bool, optional
call test_singlepoints
Returns
-------
True : if job exited successfully
"""
options_obj = Options(**options_dict)
if options_obj.xtpl:
tfps = [TemplateFileProcessor(open(i).read(), options_obj) for i in
options_obj.xtpl_templates]
tfp = tfps[0]
xtpl_inputs = [i.input_file_object for i in tfps]
else:
template_file_string = open(options_obj.template_file_path).read()
tfp = TemplateFileProcessor(template_file_string, options_obj)
xtpl_inputs = None
input_obj = tfp.input_file_object
molecule = tfp.molecule
if test_input:
try:
test_singlepoints(jobtype, molecule, options_obj, input_obj, xtpl_inputs, path)
except AssertionError as e:
print("test_singlepoints has failed. Please check regexes after running pytest on "
"test_gradobjects.py")
print(str(e))
raise
if jobtype.upper() in ['OPT', "OPTIMIZATION"]:
opt_obj = optimize.Optimization(molecule, input_obj, options_obj, xtpl_inputs)
return opt_obj.run(restart_iteration, xtpl_restart)
elif jobtype.upper() in ["HESS", "FREQUENCY", "FREQUENCIES", "HESSIAN"]:
if path == '.':
path = './HESS'
if options_obj.xtpl:
findifcalcs.Hessian.xtpl_hessian(molecule, xtpl_inputs, options_obj, path, sow)
else:
hess_obj = findifcalcs.Hessian(molecule, input_obj, options_obj, path)
if sow:
hess_obj.compute_result()
else:
hess_obj.reap(force_resub=True)
return True
else:
raise ValueError(
"""Can only run deriv or optimizations. For gradients see findifcalcs.py to run or
add wrapper here""")
def test_singlepoints(jobtype, molecule, options_obj, input_obj, xtpl_inputs=None, path=""):
""" Method to test that the singlepoints which will be created in the course
`jobtype` and their regexes will work with the output generated by from the given templates.
Can be called from run_optavc by specifying test_input=True """
if jobtype.upper() in ['OPT', "OPTIMIZATION"]:
opt_obj = optimize.Optimization(molecule, input_obj, options_obj, xtpl_inputs)
if opt_obj.options.xtpl:
for gradient, _ in opt_obj.create_xtpl_gradients(iteration=0, restart_iteration=0,
user_xtpl_restart=False):
ref_singlepoint = gradient.singlepoints[0]
assert ref_singlepoint.check_status(ref_singlepoint.options.energy_regex)
assert ref_singlepoint.get_energy()
else:
# single gradient reap only
gradient = opt_obj.create_opt_gradient(iteration=0)
ref_singlepoint = gradient.singlepoints[0]
assert ref_singlepoint.check_status(ref_singlepoint.options.energy_regex)
assert ref_singlepoint.get_energy()
elif jobtype.upper() in ["HESS", "FREQUENCY", "FREQUENCIES", "HESSIAN"]:
if path == '.':
path = './HESS'
if options_obj.xtpl:
for hess_obj in xtpl.xtpl_wrapper("HESSIAN", molecule, xtpl_inputs, options_obj):
ref_singlepoint = hess_obj.singlepoints[0]
assert ref_singlepoint.check_status(ref_singlepoint.options.energy_regex)
assert ref_singlepoint.get_energy()
else:
hess_obj = findifcalcs.Hessian(molecule, input_obj, options_obj, path)
ref_singlepoint = hess_obj.singlepoints[0]
assert ref_singlepoint.check_status(ref_singlepoint.options.energy_regex)
assert ref_singlepoint.get_energy()
def run_optavc_mpi():
from optavc.mpi4py_iface import mpirun
options_kwargs = {
'template_file_path': "template.dat",
'queue': "shared",
'command': "qchem input.dat output.dat",
'time_limit': "48:00:00", # has no effect
# 'memory' : "10 GB", #calculator uses memory, number of nodes, and numcores to
# distribute resources
'energy_regex': r"CCSD\(T\) total energy[=\s]+(-\d+\.\d+)",
'success_regex': r"beer",
'fail_regex': r"coffee",
'input_name': "input.dat",
'output_name': "output.dat",
# 'readhess' : False,
'mpi': True, # set to true to use mpi, false to not
# 'submitter' : None,
'maxiter': 20,
'findif': {
'points': 3
}, # set to 5 if you want slightly better frequencies
# 'job_array' : True,
'optking': {
'max_force_g_convergence': 1e-7, # tighter than this is not recommended
'rms_force_g_convergence': 1e-7,
}
}
options_obj = Options(**options_kwargs)
mpirun(options_obj)