Révision 16
prepareQMX/qmx.in (revision 16) | ||
---|---|---|
1 |
high-level.program : TURBOMOLE |
|
2 |
high-level.options : opt |
|
3 |
low-level.program : VASP |
|
4 |
|
|
5 |
cluster.program : TURBOMOLE |
|
6 |
cluster.options : clusterX |
|
7 |
system.program : VASP |
|
8 |
|
|
9 |
|
|
10 |
job.program : QuasiNewton |
prepareQMX/qmx.py (revision 16) | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
from ase.embed import Embed |
|
3 |
from ase.io.vasp import read_vasp |
|
4 |
from ase.calculators.qmx import Qmx |
|
5 |
from ase.calculators.vasp import Vasp |
|
6 |
from ase.optimize import QuasiNewton |
|
7 |
|
|
8 |
high_level=Vasp(write_input=False) |
|
9 |
low_level=Vasp(write_input=False) |
|
10 |
qmx=Qmx(high_level, low_level) |
|
11 |
|
|
12 |
system=read_vasp('POSCAR') |
|
13 |
cluster=read_vasp('POSCAR') |
|
14 |
embed=Embed(system, cluster, cell_cluster="Auto") |
|
15 |
embed.embed() |
|
16 |
embed.set_calculator(qmx) |
|
17 |
|
|
18 |
job=QuasiNewton(embed, trajectory="embed.traj") |
|
19 |
job.run(fmax=0.01, steps=100) |
prepareQMX/qmxCALC.py (revision 16) | ||
---|---|---|
48 | 48 |
self.keywords['class.options']='high_level, low_level' |
49 | 49 |
|
50 | 50 |
#------------------------------------------------------------------------------- |
51 |
calcDefinitions = [VASPCalcDefinition(), TURBOMOLECalcDefinition(), MOPACCalcDefinition()] |
|
51 |
class LJCalcDefinition(Definition): |
|
52 |
def __init__(self): |
|
53 |
self.name='Lennard Jones' |
|
54 |
self.system='LJ' |
|
55 |
self.keywords = {} |
|
56 |
self.keywords['import']='ase.calculators.lj' |
|
57 |
self.keywords['class']='LennardJones' |
|
58 |
|
|
59 |
#------------------------------------------------------------------------------- |
|
60 |
class EMTCalcDefinition(Definition): |
|
61 |
def __init__(self): |
|
62 |
self.name='EMT' |
|
63 |
self.system='EMT' |
|
64 |
self.keywords = {} |
|
65 |
self.keywords['import']='ase.calculators.emt' |
|
66 |
self.keywords['class']='EMT' |
|
67 |
|
|
68 |
#------------------------------------------------------------------------------- |
|
69 |
class SiestaCalcDefinition(Definition): |
|
70 |
def __init__(self): |
|
71 |
self.name='Siesta' |
|
72 |
self.system='Siesta' |
|
73 |
self.keywords = {} |
|
74 |
self.keywords['import']='ase.calculators.siesta' |
|
75 |
self.keywords['class']='Siesta' |
|
76 |
|
|
77 |
#------------------------------------------------------------------------------- |
|
78 |
class DacapoCalcDefinition(Definition): |
|
79 |
def __init__(self): |
|
80 |
self.name='Dacapo' |
|
81 |
self.system='Dacapo' |
|
82 |
self.keywords = {} |
|
83 |
self.keywords['import']='ase.calculators.dacapo' |
|
84 |
self.keywords['class']='Dacapo' |
|
85 |
|
|
86 |
#------------------------------------------------------------------------------- |
|
87 |
class AimsCubeCalcDefinition(Definition): |
|
88 |
def __init__(self): |
|
89 |
self.name='AimsCube' |
|
90 |
self.system='AimsCube' |
|
91 |
self.keywords = {} |
|
92 |
self.keywords['import']='ase.calculators.ase' |
|
93 |
self.keywords['class']='AimsCube' |
|
94 |
|
|
95 |
#------------------------------------------------------------------------------- |
|
96 |
class AimsCalcDefinition(Definition): |
|
97 |
def __init__(self): |
|
98 |
self.name='Aims' |
|
99 |
self.system='Aims' |
|
100 |
self.keywords = {} |
|
101 |
self.keywords['import']='ase.calculators.aims' |
|
102 |
self.keywords['class']='Aims' |
|
103 |
|
|
104 |
#------------------------------------------------------------------------------- |
|
105 |
class ExcitingCalcDefinition(Definition): |
|
106 |
def __init__(self): |
|
107 |
self.name='Exciting' |
|
108 |
self.system='Exciting' |
|
109 |
self.keywords = {} |
|
110 |
self.keywords['import']='ase.calculators.exciting' |
|
111 |
self.keywords['class']='Exciting' |
|
112 |
|
|
113 |
#------------------------------------------------------------------------------- |
|
114 |
class DftbCalcDefinition(Definition): |
|
115 |
def __init__(self): |
|
116 |
self.name='Dftb' |
|
117 |
self.system='Dftb' |
|
118 |
self.keywords = {} |
|
119 |
self.keywords['import']='ase.calculators.dftb' |
|
120 |
self.keywords['class']='Dftb' |
|
121 |
|
|
122 |
#------------------------------------------------------------------------------- |
|
123 |
class GaussianCalcDefinition(Definition): |
|
124 |
def __init__(self): |
|
125 |
self.name='Gaussian' |
|
126 |
self.system='Gaussian' |
|
127 |
self.keywords = {} |
|
128 |
self.keywords['import']='ase.calculators.gaussian' |
|
129 |
self.keywords['class']='Gaussian' |
|
130 |
|
|
131 |
calcDefinitions = \ |
|
132 |
[ VASPCalcDefinition(), TURBOMOLECalcDefinition(), MOPACCalcDefinition(), LJCalcDefinition(), \ |
|
133 |
EMTCalcDefinition(), SiestaCalcDefinition(), DacapoCalcDefinition(), AimsCubeCalcDefinition(), \ |
|
134 |
AimsCalcDefinition(), ExcitingCalcDefinition(), DftbCalcDefinition(), GaussianCalcDefinition() ] |
prepareQMX/qmxSTR.py (revision 16) | ||
---|---|---|
28 | 28 |
self.keywords['import']='ase.io.turbomole' |
29 | 29 |
self.keywords['class']='read_turbomole' |
30 | 30 |
self.keywords['class.options']='coord' |
31 |
|
|
32 | 31 |
#------------------------------------------------------------------------------- |
33 |
strDefinitions = [VASPStrDefinition(), TURBOMOLEStrDefintion()] |
|
32 |
class CLUSTERStrDefintion(Definition): |
|
33 |
def __init__(self): |
|
34 |
self.name='CLUSTER' |
|
35 |
self.keywords = {} |
|
36 |
#------------------------------------------------------------------------------- |
|
37 |
strSystemDefinitions = [VASPStrDefinition(), TURBOMOLEStrDefintion()] |
|
38 |
strClusterDefinitions = [VASPStrDefinition(), TURBOMOLEStrDefintion(), CLUSTERStrDefintion()] |
prepareQMX/qmxWRITE.py (revision 16) | ||
---|---|---|
25 | 25 |
arrImports.append(s) |
26 | 26 |
|
27 | 27 |
stream.write("\n") |
28 |
for name in ['high-level', 'low-level', 'qmx']:
|
|
28 |
for name in ['high-level', 'low-level', 'hybrid']:
|
|
29 | 29 |
for definition in definitions: |
30 | 30 |
if definition.system.lower() != name: |
31 | 31 |
continue |
... | ... | |
37 | 37 |
stream.write(strSystem+'='+strClass+'('+strOptions+')\n') |
38 | 38 |
|
39 | 39 |
stream.write("\n") |
40 |
for name in ['system', 'cluster', 'embed']: |
|
40 |
|
|
41 |
extraOptions = '' |
|
42 |
for name in ['cluster', 'system', 'embed']: |
|
41 | 43 |
for definition in definitions: |
42 | 44 |
if definition.system.lower() != name: |
43 | 45 |
continue |
... | ... | |
46 | 48 |
strOptions=definition.getValue('class.options') |
47 | 49 |
|
48 | 50 |
if (strClass is not ''): |
49 |
stream.write(strSystem+'='+strClass+"('"+strOptions+"')\n") |
|
51 |
if name is 'embed': |
|
52 |
if strOptions is not '': |
|
53 |
strOptions += ', ' |
|
54 |
strOptions += extraOptions |
|
55 |
stream.write(strSystem+'='+strClass+"("+strOptions+")\n") |
|
50 | 56 |
|
57 |
if name is 'cluster' and definition.name is 'CLUSTER': |
|
58 |
stream.write(strSystem+'=['+strOptions+']'+'\n') |
|
59 |
extraOptions='cluster_pos=False' |
|
60 |
|
|
51 | 61 |
if name is 'embed': |
52 |
strMethod=definition.getValue('method') |
|
53 |
strOptions=definition.getValue('method.options') |
|
54 |
stream.write(strSystem+'.'+strMethod+'('+strOptions+')\n') |
|
62 |
strOptions=definition.getValue('set_calculator') |
|
63 |
stream.write(strSystem+'.set_calculator('+strOptions+')\n') |
|
55 | 64 |
|
56 |
strOptions=definition.getValue('calculator') |
|
57 |
stream.write(strSystem+'.set_calculator('+strOptions+')\n') |
|
58 |
|
|
59 | 65 |
stream.write("\n") |
60 | 66 |
for definition in definitions: |
61 | 67 |
if (definition.system.lower() == 'job'): |
prepareQMX/qmxEMBED.py (revision 16) | ||
---|---|---|
20 | 20 |
self.keywords['import']='ase.embed' |
21 | 21 |
self.keywords['class']='Embed' |
22 | 22 |
self.keywords['class.options']='system, cluster, cell_cluster="Auto"' |
23 |
self.keywords['method']='embed' |
|
24 |
self.keywords['calculator']='qmx' |
|
23 |
self.keywords['set_calculator']='qmx' |
|
25 | 24 |
|
26 | 25 |
#------------------------------------------------------------------------------- |
27 | 26 |
embedDefinitions = [EmbedDefinition()] |
prepareQMX/prepareQMX.py (revision 16) | ||
---|---|---|
15 | 15 |
#--------------------------------------------------------------------------------------------------- |
16 | 16 |
from qmxEMBED import embedDefinitions |
17 | 17 |
from qmxJOB import jobDefinitions |
18 |
from qmxSTR import strDefinitions |
|
18 |
from qmxSTR import strSystemDefinitions, strClusterDefinitions
|
|
19 | 19 |
from qmxCALC import calcDefinitions, QmxCalcDefinition |
20 | 20 |
|
21 | 21 |
from qmxWRITE import writeData |
... | ... | |
121 | 121 |
definitions.append(analyzeSection(calcDefinitions, section, lines_section)) |
122 | 122 |
|
123 | 123 |
#structures (atoms) |
124 |
if section == "cluster" or section == "system":
|
|
125 |
definitions.append(analyzeSection(strDefinitions, section, lines_section)) |
|
124 |
if section == "cluster": |
|
125 |
definitions.append(analyzeSection(strClusterDefinitions, section, lines_section))
|
|
126 | 126 |
|
127 |
#structures (atoms) |
|
128 |
if section == "system": |
|
129 |
definitions.append(analyzeSection(strSystemDefinitions, section, lines_section)) |
|
130 |
|
|
127 | 131 |
#job |
128 | 132 |
if section == "job": |
129 | 133 |
definitions.append(analyzeSection(jobDefinitions, section, lines_section)) |
prepareQMX/prepareQMX.GUI.py (revision 16) | ||
---|---|---|
10 | 10 |
#--------------------------------------------------------------------------------------------------- |
11 | 11 |
from Tkinter import * |
12 | 12 |
from copy import deepcopy |
13 |
import tkFileDialog |
|
13 | 14 |
import StringIO, os |
14 | 15 |
|
15 | 16 |
#--------------------------------------------------------------------------------------------------- |
16 | 17 |
from qmxEMBED import embedDefinitions |
17 | 18 |
from qmxJOB import jobDefinitions |
18 |
from qmxSTR import strDefinitions |
|
19 |
from qmxSTR import strClusterDefinitions, strSystemDefinitions
|
|
19 | 20 |
from qmxCALC import calcDefinitions, QmxCalcDefinition |
20 | 21 |
|
21 | 22 |
from qmxWRITE import writeData |
... | ... | |
24 | 25 |
#--------------------------------------------------------------------------------------------------- |
25 | 26 |
#--------------------------------------------------------------------------------------------------- |
26 | 27 |
class MyLabelFrame(LabelFrame): |
27 |
def __init__(self, mainWnd, master, title, def_list, extras):
|
|
28 |
def __init__(self, mainWnd, master, title, name, def_list, fields):
|
|
28 | 29 |
LabelFrame.__init__(self, master, text=title) |
29 | 30 |
self.mainWnd = mainWnd |
30 | 31 |
self.definitions=[] |
31 |
self.title = title |
|
32 | 32 |
|
33 | 33 |
for definition in def_list: |
34 | 34 |
definition_new = deepcopy(definition) |
35 |
definition_new.system = title
|
|
35 |
definition_new.system = name
|
|
36 | 36 |
self.definitions.append(definition_new) |
37 | 37 |
|
38 |
fields=['import', 'class', 'class.options'] |
|
39 |
if extras is not None: |
|
40 |
for key in extras: |
|
41 |
fields.append(key) |
|
38 |
if fields is None: |
|
39 |
fields = [''] |
|
42 | 40 |
|
43 | 41 |
self.entries=[] |
44 | 42 |
for key in fields: |
45 | 43 |
text=StringVar() |
46 | 44 |
text.set('') |
47 |
self.entries.append((key, text, Entry(self, textvariable=text, width=15)))
|
|
45 |
self.entries.append((key, text, Entry(self, textvariable=text, width=25)))
|
|
48 | 46 |
|
49 | 47 |
def grid(self, **arguments): |
50 | 48 |
LabelFrame.grid(self, arguments, sticky=(N+W+E)) |
... | ... | |
54 | 52 |
def doLayout(self): |
55 | 53 |
irow=0 |
56 | 54 |
for (key, text, textfield) in self.entries: |
57 |
Label(self, text=key, width=15, anchor=W).grid(row=irow) |
|
58 |
textfield.grid(row=irow, column=1)
|
|
55 |
Label(self, text=key, width=15, anchor=W).grid(row=irow, column=2)
|
|
56 |
textfield.grid(row=irow, column=3)
|
|
59 | 57 |
textfield.bind("<KeyRelease>", self.update) |
60 | 58 |
irow+=1 |
61 | 59 |
|
62 | 60 |
scrollbar=Scrollbar(self, orient=VERTICAL) |
63 |
self.listbox=Listbox(self, yscrollcommand=scrollbar.set, height=0, width=15, selectmode=SINGLE)
|
|
64 |
self.listbox.grid(row=0, column=2, rowspan=irow, columnspan=2, sticky=NS)
|
|
61 |
self.listbox=Listbox(self, yscrollcommand=scrollbar.set, height=5, width=15, selectmode=SINGLE, exportselection=0)
|
|
62 |
self.listbox.grid(row=0, column=0, rowspan=irow, sticky=NS)
|
|
65 | 63 |
self.listbox.bind('<ButtonRelease-1>', self.select) |
66 | 64 |
|
67 | 65 |
scrollbar.config(command=self.listbox.yview) |
68 |
scrollbar.grid(row=0, column=4, rowspan=irow, sticky=NS)
|
|
66 |
scrollbar.grid(row=0, column=1, rowspan=irow, sticky=NS)
|
|
69 | 67 |
|
70 | 68 |
for item in self.definitions: |
71 | 69 |
self.listbox.insert(END, item.name) |
... | ... | |
93 | 91 |
def __init__(self, master): |
94 | 92 |
Frame.__init__(self, master) |
95 | 93 |
|
96 |
#--- Structures --- |
|
97 |
bigFrame = LabelFrame(self, text='Structures') |
|
98 |
irow=0; icol=0 |
|
99 |
def_list=embedDefinitions |
|
100 |
extras=['method', 'method.options', 'calculator'] |
|
101 |
frame=MyLabelFrame(self, bigFrame, 'Embed', def_list, extras) |
|
102 |
frame.doLayout() |
|
103 |
frame.grid(row=irow, column=icol) |
|
104 |
self.frames.append(frame) |
|
105 |
|
|
106 |
icol+=1; |
|
107 |
for label in ['System', 'Cluster']: |
|
108 |
def_list=strDefinitions |
|
109 |
frame=MyLabelFrame(self, bigFrame, label, def_list, None) |
|
110 |
frame.doLayout() |
|
111 |
frame.grid(row=irow, column=icol) |
|
112 |
self.frames.append(frame) |
|
113 |
icol+=1 |
|
114 |
bigFrame.grid(row=0, columnspan=3) |
|
115 |
|
|
116 |
#--- Methods --- |
|
117 |
bigFrame = LabelFrame(self, text='Methods') |
|
118 |
irow=0; icol=0 |
|
119 |
def_list=[QmxCalcDefinition()] |
|
120 |
frame=MyLabelFrame(self, bigFrame, 'Qmx', def_list, None) |
|
121 |
frame.doLayout() |
|
122 |
frame.grid(row=irow, column=icol) |
|
123 |
self.frames.append(frame) |
|
124 |
|
|
125 |
icol+=1 |
|
126 |
for label in ['Low-Level', 'High-Level']: |
|
127 |
def_list=calcDefinitions |
|
128 |
frame=MyLabelFrame(self, bigFrame, label, def_list, None) |
|
129 |
frame.doLayout() |
|
130 |
frame.grid(row=irow, column=icol) |
|
131 |
self.frames.append(frame) |
|
132 |
icol+=1 |
|
133 |
bigFrame.grid(row=1, columnspan=3) |
|
94 |
fields=['import', 'class', 'class.options'] |
|
134 | 95 |
|
135 |
#--- General --- |
|
136 |
bigFrame = LabelFrame(self, text='General') |
|
137 |
extras=['method', 'method.options'] |
|
138 |
frame=MyLabelFrame(self, bigFrame, 'Job', jobDefinitions, extras) |
|
139 |
frame.doLayout() |
|
140 |
frame.grid() |
|
141 |
self.frames.append(frame) |
|
142 |
bigFrame.grid(row=2, sticky=NW) |
|
143 |
|
|
144 |
frame=LabelFrame(self, text="PREVIEW") |
|
145 |
scrollbar=Scrollbar(frame, orient=VERTICAL) |
|
96 |
irow=0 |
|
97 |
for calcLabel, strLabel, strDefinitions in ( |
|
98 |
("high-level", "cluster", strClusterDefinitions), |
|
99 |
("low-level", "system", strSystemDefinitions)): |
|
100 |
#column |
|
101 |
icolLocal=0; |
|
102 |
#build outFrame |
|
103 |
outFrame = LabelFrame(self, text=calcLabel+" method - "+strLabel) |
|
104 |
outFrame.grid(row=irow, columnspan=3, sticky=W, pady=5) |
|
105 |
irow+=1 |
|
106 |
|
|
107 |
for title, def_list in ((calcLabel, calcDefinitions), (strLabel, strDefinitions)): |
|
108 |
# build frame |
|
109 |
myFrame=MyLabelFrame(self, outFrame, title, title, def_list, fields) |
|
110 |
myFrame.doLayout() |
|
111 |
myFrame.grid(row=0, column=icolLocal, padx=5, pady=5) |
|
112 |
# add frame for analyssis |
|
113 |
self.frames.append(myFrame) |
|
114 |
# move column |
|
115 |
icolLocal += 1 |
|
116 |
|
|
117 |
outFrame = LabelFrame(self, text="General") |
|
118 |
outFrame.grid(row=irow, columnspan=3, pady=5); irow+=1 |
|
119 |
for title, name, def_list, extra_list, irowLocal, icolLocal, irspan in ( |
|
120 |
("Optimization Method", "job", jobDefinitions, fields + ['method', 'method.options'], 0, 0, 2), |
|
121 |
("Embedding Method", "embed", embedDefinitions, fields + ['set_calculator'], 0, 1, 1), |
|
122 |
("Hybrid Method", "hybrid", [QmxCalcDefinition()], fields, 1, 1, 1)): |
|
123 |
# build frame |
|
124 |
myFrame=MyLabelFrame(self, outFrame, title, name, def_list, extra_list) |
|
125 |
myFrame.doLayout() |
|
126 |
myFrame.grid(row=irowLocal, column=icolLocal, rowspan=irspan, padx=5, pady=5) |
|
127 |
# add frame for analyssis |
|
128 |
self.frames.append(myFrame) |
|
129 |
|
|
130 |
outFrame=LabelFrame(self, text="PREVIEW") |
|
131 |
scrollbar=Scrollbar(outFrame, orient=VERTICAL) |
|
146 | 132 |
scrollbar.set(0.0, 1.0) |
147 |
self.text=Text(frame, yscrollcommand=scrollbar.set, width=60, heigh=10, state=DISABLED)
|
|
133 |
self.text=Text(outFrame, yscrollcommand=scrollbar.set, width=80, heigh=10, state=DISABLED)
|
|
148 | 134 |
self.text.grid(sticky=(N+W+S+E)) |
149 | 135 |
scrollbar.config(command=self.text.yview) |
150 | 136 |
scrollbar.grid(row=0, column=1, sticky=NS) |
151 |
frame.grid(row=2, column=1)
|
|
137 |
outFrame.grid(row=irow, column=0, sticky=W, pady=5);
|
|
152 | 138 |
|
153 |
frame = Frame(self) |
|
154 |
|
|
155 |
#image = PhotoImage(file="exit.gif") |
|
156 |
buttonExit=Button(frame, text="Quit!", command=self.quit) |
|
157 |
#buttonExit.image = image |
|
139 |
myFrame = Frame(self) |
|
140 |
buttonExit=Button(myFrame, text="Quit!", command=self.quit) |
|
158 | 141 |
buttonExit.grid(row=1, column = 1, rowspan=3, sticky= W+E+N+S) |
159 | 142 |
|
160 |
buttonSave=Button(frame, text='save settings', state=DISABLED)
|
|
143 |
buttonSave=Button(myFrame, text='save settings', state=DISABLED)
|
|
161 | 144 |
buttonSave.grid(row=1, column = 2, sticky=(EW)) |
162 | 145 |
|
163 |
buttonScript=Button(frame, text='Write qmx.in input file', command=self.writeScript)
|
|
146 |
buttonScript=Button(myFrame, text='Write SCRIPT file', command=self.writeScript)
|
|
164 | 147 |
buttonScript.grid(row=2, column = 2, sticky=EW) |
165 | 148 |
|
166 |
buttonPython=Button(frame, text='Write qmx.py script file', command=self.writePython)
|
|
149 |
buttonPython=Button(myFrame, text='Write PYTHON file', command=self.writePython)
|
|
167 | 150 |
buttonPython.grid(row=3, column = 2, sticky=EW) |
168 | 151 |
|
169 |
frame.grid(row=2, column=2, sticky=SE)
|
|
152 |
myFrame.grid(row=irow, column=2, sticky=SE)
|
|
170 | 153 |
|
171 | 154 |
#--- MainWindow --- |
172 | 155 |
self.grid(sticky=(W+N+S+E)) |
... | ... | |
176 | 159 |
quit() |
177 | 160 |
|
178 | 161 |
def writePython(self): |
179 |
file = open("qmx.py","w") |
|
162 |
fileName = tkFileDialog.asksaveasfile(mode='w') |
|
163 |
if fileName is None: |
|
164 |
return |
|
165 |
file = open(fileName,"w") |
|
180 | 166 |
definitions=[] |
181 | 167 |
for frame in self.frames: |
182 | 168 |
definition = frame.getSelection() |
... | ... | |
189 | 175 |
|
190 | 176 |
|
191 | 177 |
def writeScript(self): |
192 |
file = open("qmx.in","w") |
|
178 |
fileName = tkFileDialog.asksaveasfile(mode='w') |
|
179 |
if fileName is None: |
|
180 |
return |
|
181 |
file = open(fileName,"w") |
|
193 | 182 |
for frame in self.frames: |
194 | 183 |
definition = frame.getSelection() |
195 | 184 |
if definition is None: |
ase/embed.py (revision 16) | ||
---|---|---|
16 | 16 |
|
17 | 17 |
class Embed(Atoms): |
18 | 18 |
#--- constructor of the Embed class --- |
19 |
def __init__(self, system, cluster, cell_cluster = "Auto", cluster_pos = True): |
|
19 |
def __init__(self, system, cluster, cell_cluster = "Auto", cluster_pos = True, linkType = 'H'):
|
|
20 | 20 |
super(Embed, self).__init__() |
21 | 21 |
# define the atom map |
22 | 22 |
self.atom_map_sys_cl = [] |
... | ... | |
39 | 39 |
# set the cell of the system |
40 | 40 |
self.set_cell(system.get_cell()) |
41 | 41 |
self.cell_cluster = cell_cluster |
42 |
|
|
43 |
self.embed(linkType) |
|
42 | 44 |
return |
43 | 45 |
|
44 | 46 |
#--- set the cluster --- |
... | ... | |
98 | 100 |
return self.atoms_system |
99 | 101 |
|
100 | 102 |
#--- Embedding --- |
101 |
def embed(self): |
|
103 |
def embed(self, linkType):
|
|
102 | 104 |
# is the cluster and the host system definied ? |
103 | 105 |
if self.atoms_cluster is None or self.atoms_system is None: |
104 | 106 |
return |
105 | 107 |
self.find_cluster() |
106 |
self.set_linkatoms() |
|
108 |
self.set_linkatoms(linkType)
|
|
107 | 109 |
print "link atoms found: ", len(self.linkatoms) |
108 | 110 |
if self.cell_cluster == "System": |
109 | 111 |
self.atoms_cluster.set_cell(self.atoms_system.get_cell()) |
... | ... | |
165 | 167 |
if bSysOnly: |
166 | 168 |
self.atom_map_sys_cl[iat_sys] = -1 |
167 | 169 |
|
168 |
def set_linkatoms(self, tol=15., linkAtom=None, debug=False):
|
|
170 |
def set_linkatoms(self, linkType, tol=15.):
|
|
169 | 171 |
# local copies of xyz coordinates to avoid massive copying of xyz objects |
170 | 172 |
xyzs_cl=[] |
171 | 173 |
for atom_cl in self.atoms_cluster: |
... | ... | |
173 | 175 |
xyzs_sys=[] |
174 | 176 |
for atom_sys in self.atoms_system: |
175 | 177 |
xyzs_sys.append(atom_sys.get_position()) |
176 |
# set the standard link atom |
|
177 |
if linkAtom is None: |
|
178 |
linkAtom ='H' |
|
179 | 178 |
# number of atoms in the cluster and the system |
180 | 179 |
nat_cl=len(self.atoms_cluster) |
181 | 180 |
nat_sys=len(self.atoms_system) |
... | ... | |
235 | 234 |
r = np.sqrt(np.dot(xyz_diff, xyz_diff)) |
236 | 235 |
# ratio of the distance to the sum of covalent radius |
237 | 236 |
f = r / (r_cl + r_sys) |
238 |
if debug: |
|
239 |
print "Covalent radii = ",r_cl, r_sys |
|
240 |
print "Distance ", f |
|
241 |
print "tol = ",(1+tol/100.),(1-tol/100.),(1-2*tol/100.) |
|
242 | 237 |
if f <= (1+tol/100.) and f >= (1-2*tol/100.): |
243 | 238 |
s = cell_L, self.atom_map_cl_sys[iat_cl], iat_sys, r_cl |
244 | 239 |
bonds.append(s) |
... | ... | |
246 | 241 |
if f <= (1-2*tol/100.): |
247 | 242 |
raise RuntimeError("QMX: The cluster atom", iat_cl, " and the system atom", iat_sys, "came too close") |
248 | 243 |
|
249 |
r_h = covalent_radii[atomic_numbers[linkAtom]]
|
|
244 |
r_h = covalent_radii[atomic_numbers[linkType]]
|
|
250 | 245 |
for bond in bonds: |
251 | 246 |
cell_L, iat_cl_sys, iat_sys, r_cl = bond |
252 | 247 |
# assign the tags for the border atoms |
... | ... | |
259 | 254 |
# determine position of the link atom |
260 | 255 |
xyz_diff += xyzs_sys[iat_cl_sys] |
261 | 256 |
# create link atom |
262 |
atom = Atom(symbol=linkAtom, position=xyz_diff, tag=50)
|
|
257 |
atom = Atom(symbol=linkType, position=xyz_diff, tag=50)
|
|
263 | 258 |
# add atom to cluster |
264 | 259 |
self.atoms_cluster.append(atom) |
265 | 260 |
# add atom to the linkatoms |
ase/calculators/__init__.py (revision 16) | ||
---|---|---|
16 | 16 |
from ase.calculators.test import numeric_force, numeric_forces, TestPotential |
17 | 17 |
from ase.calculators.qmx import Qmx |
18 | 18 |
from ase.calculators.mopac import Mopac |
19 |
from ase.calculators.gaussian import Gaussian |
|
19 | 20 |
|
20 | 21 |
if _deprecate_things_from_ase_module: |
21 | 22 |
from ase.utils.deprecate import Deprecate |
22 | 23 |
_locals = locals() |
23 | 24 |
for name in ['LennardJones', 'EMT', 'Siesta', 'Dacapo', 'Vasp', |
24 |
'Aims', 'AimsCube', 'Turbomole', 'Exciting', 'Dftb', 'Qmx', |
|
25 |
'Aims', 'AimsCube', 'Turbomole', 'Exciting', 'Dftb', 'Qmx', 'Gaussian',
|
|
25 | 26 |
'SinglePointCalculator', 'numeric_force', 'numeric_forces', |
26 | 27 |
'TestPotential']: |
27 | 28 |
obj = _locals[name] |
ase/calculators/qmx.py (revision 16) | ||
---|---|---|
30 | 30 |
self.print_forces = print_forces |
31 | 31 |
|
32 | 32 |
def get_energy_subsystem(self, path, calculator, atoms, force_consistent): |
33 |
# writing output |
|
34 |
line = "running energy in: " + path + "\n" |
|
35 |
sys.stderr.write(line) |
|
33 | 36 |
# go to directory and calculate energies |
34 |
print "running energy in: ", path |
|
35 | 37 |
os.chdir(path) |
36 | 38 |
atoms.set_calculator(calculator) |
37 | 39 |
energy = atoms.get_potential_energy() |
40 |
# return path and result |
|
38 | 41 |
os.chdir("..") |
39 | 42 |
return energy |
40 | 43 |
|
41 | 44 |
def get_forces_subsystem(self, path, calculator, atoms): |
45 |
# writing output |
|
46 |
line = "running forces in: " + path + "\n" |
|
47 |
sys.stderr.write(line) |
|
42 | 48 |
# go to directory and calculate forces |
43 |
print "running forces in: ", path |
|
44 | 49 |
os.chdir(path) |
45 | 50 |
atoms.set_calculator(calculator) |
46 | 51 |
forces = atoms.get_forces() |
52 |
# return path and result |
|
47 | 53 |
os.chdir("..") |
48 | 54 |
return forces |
49 | 55 |
|
... | ... | |
55 | 61 |
# calculate energies |
56 | 62 |
energy = e_sys_lo - e_cl_lo + e_cl_hi |
57 | 63 |
# print energies |
58 |
print "%20s = %15s - %15s + %15s" %("E(C:S)", "E(S-MM)", "E(C-MM)", "E(C-QM)")
|
|
64 |
print "%20s = %15s - %15s + %15s" %("E(C:S)", "E(S,LL)", "E(C,LL)", "E(C,HL)")
|
|
59 | 65 |
print "%20f = %15f - %15f + %15f" %(energy, e_sys_lo, e_cl_lo, e_cl_hi) |
60 | 66 |
# set energies and return |
61 | 67 |
if force_consistent: |
... | ... | |
145 | 151 |
|
146 | 152 |
|
147 | 153 |
return f_sys_lo |
154 |
|
|
155 |
def get_stress(self, atoms): |
|
156 |
return None |
ase/calculators/gaussian.py (revision 16) | ||
---|---|---|
1 |
""" |
|
2 |
This module is the Gaussian module for ASE, based on the PyMD Gaussian Module by R. Bulo, |
|
3 |
implemented by T. Kerber |
|
4 |
|
|
5 |
@author: Rosa Bulo |
|
6 |
@organization: Vrije Universiteit Amsterdam |
|
7 |
@contact: bulo@few.vu.nl |
|
8 |
|
|
9 |
Torsten Kerber, ENS LYON: 2011, 07, 11 |
|
10 |
|
|
11 |
This work is supported by Award No. UK-C0017, made by King Abdullah |
|
12 |
University of Science and Technology(KAUST) |
|
13 |
""" |
|
14 |
import os, sys, string |
|
15 |
|
|
16 |
import numpy as np |
|
17 |
from ase.units import Hartree, Bohr |
|
18 |
from ase.calculators.general import Calculator |
|
19 |
import os, sys, re, math, commands, subprocess, time |
|
20 |
|
|
21 |
class Gaussian(Calculator): |
|
22 |
""" |
|
23 |
Class for representing the settings of a ReaxffForceJob |
|
24 |
|
|
25 |
It contains the following variables: |
|
26 |
|
|
27 |
basis: |
|
28 |
A string representing the basisset to be used |
|
29 |
|
|
30 |
functional: |
|
31 |
A string representing the DFT functional or wavefunction |
|
32 |
method to be used. |
|
33 |
|
|
34 |
""" |
|
35 |
|
|
36 |
def __init__(self, functional='BP86', basis='TZVP', atoms=None, inputfile=None): |
|
37 |
self.functional = functional |
|
38 |
self.basis = basis |
|
39 |
self.restartdata = None |
|
40 |
self.forces = None |
|
41 |
self.atoms_old = None |
|
42 |
if inputfile != None: |
|
43 |
self = self.get_settings(inputfile) |
|
44 |
self.atoms = atoms |
|
45 |
|
|
46 |
def set_functional(self, functional): |
|
47 |
self.functional = functional |
|
48 |
|
|
49 |
def set_basis(self, basis): |
|
50 |
self.basis = basis |
|
51 |
|
|
52 |
def setup_job(self, type='force'): |
|
53 |
ForceJob.setup_job(self, type=type) |
|
54 |
|
|
55 |
os.chdir(self.dirname) |
|
56 |
self.myfiles = GaussianFileManager() |
|
57 |
# Add the restart restuls to the filemanager. The checksum will be empty('') |
|
58 |
if self.restartdata != None: |
|
59 |
self.r_m = GaussianResults(self.myfiles) |
|
60 |
self.myfiles.add_results(self.r_m, dir=self.restartdata+'/') |
|
61 |
|
|
62 |
os.chdir(self.dir) |
|
63 |
|
|
64 |
def write_parfile(self, filename): |
|
65 |
parfile = open(filename, 'w') |
|
66 |
parfile.write(self.prm) |
|
67 |
parfile.close() |
|
68 |
|
|
69 |
def write_moldata(self, type='force'): |
|
70 |
out = commands.getoutput('mkdir SETUP') |
|
71 |
out = commands.getoutput('ls SETUP/coord.*').split() |
|
72 |
pdb = False |
|
73 |
psf = False |
|
74 |
prm = False |
|
75 |
|
|
76 |
# Change labels variable if necessary |
|
77 |
norderats = 0 |
|
78 |
# for el in self.labels: |
|
79 |
# norderats += 1 |
|
80 |
# if norderats != self.atoms.pdb.get_number_of_atoms(): |
|
81 |
# self.labels = self.get_labels() |
|
82 |
|
|
83 |
self.write_input(type) |
|
84 |
|
|
85 |
def write_input(self, type): |
|
86 |
input = self.get_input_block(type) |
|
87 |
pyfile = open('ASE-gaussian.com', 'w') |
|
88 |
pyfile.write(input) |
|
89 |
pyfile.close() |
|
90 |
|
|
91 |
def get_inp(self, filename): |
|
92 |
input = None |
|
93 |
lis = commands.getoutput('ls %s'%(filename)).split('\n') |
|
94 |
if not re.search('ls:', lis[0]): |
|
95 |
infile = open(filename) |
|
96 |
input = infile.readlines() |
|
97 |
infile.close() |
|
98 |
return input |
|
99 |
|
|
100 |
def run(self, type='force'): |
|
101 |
startrun = time.time() |
|
102 |
# I have to write the input every timestep, because that is where the coordinates are |
|
103 |
# self.write_input(type) |
|
104 |
self.write_moldata(type) |
|
105 |
|
|
106 |
# Make sure that restart data is copied to the current directory |
|
107 |
# if self.r_m != None: |
|
108 |
# self.r_m.files.copy_job_result_files(self.r_m.fileid) |
|
109 |
|
|
110 |
out = commands.getoutput('g09 ASE-gaussian.com') |
|
111 |
endrun = time.time() |
|
112 |
#print 'timings: ', endrun-startrun |
|
113 |
# Write the output |
|
114 |
# outputfile = open('ASE-gaussian.log') |
|
115 |
# outfile = open('ASE-gaussian.out', 'w') |
|
116 |
# for line in outputfile: |
|
117 |
# outfile.write(line) |
|
118 |
# outputfile.close() |
|
119 |
# outfile.close() |
|
120 |
# End write output |
|
121 |
self.energy = self.read_energy() |
|
122 |
if type == 'force': |
|
123 |
self.forces = self.read_forces() |
|
124 |
self.energy_zero = self.energy |
|
125 |
|
|
126 |
# Change the results object to the new results |
|
127 |
input = self.get_input_block(type) |
|
128 |
|
|
129 |
def read_energy(self, charges=True): |
|
130 |
hartree2kcal = 627.5095 |
|
131 |
|
|
132 |
outfile = open('ASE-gaussian.log') |
|
133 |
lines = outfile.readlines() |
|
134 |
outfile.close() |
|
135 |
|
|
136 |
chargelines = 0 |
|
137 |
if charges: |
|
138 |
nats = len(self.atoms) |
|
139 |
block = '' |
|
140 |
for line in lines: |
|
141 |
if re.search('SCF Done', line): |
|
142 |
words = line.split() |
|
143 |
energy = float(words[4]) * hartree2kcal |
|
144 |
if charges: |
|
145 |
if re.search(' Mulliken atomic charges:', line): |
|
146 |
chargelines += 1 |
|
147 |
if chargelines > 0 and chargelines <= nats+2: |
|
148 |
chargelines += 1 |
|
149 |
block += line |
|
150 |
|
|
151 |
if charges: |
|
152 |
chargefile = open('charge.out', 'a') |
|
153 |
chargefile.write(block) |
|
154 |
chargefile.close() |
|
155 |
|
|
156 |
return energy |
|
157 |
|
|
158 |
def read_forces(self): |
|
159 |
factor = Hartree / Bohr |
|
160 |
factor = 1.0 |
|
161 |
|
|
162 |
outfile = open('ASE-gaussian.log') |
|
163 |
lines = outfile.readlines() |
|
164 |
outfile.close() |
|
165 |
|
|
166 |
outputforces = None |
|
167 |
forces = None |
|
168 |
nats = len(self.atoms) |
|
169 |
|
|
170 |
for iline, line in enumerate(lines): |
|
171 |
if re.search('Forces \(Ha', line): |
|
172 |
forces = np.zeros((nats, 3), float) |
|
173 |
for iat in range(nats): |
|
174 |
forceline = lines[iline+iat+3] |
|
175 |
words = forceline.split() |
|
176 |
for idir, word in enumerate(words[2:5]): |
|
177 |
forces[iat, idir] = float(word) * factor |
|
178 |
break |
|
179 |
return forces |
|
180 |
|
|
181 |
def get_input_block(self, type): |
|
182 |
block = '' |
|
183 |
block += '%chk=ASE-gaussian.chk\n' |
|
184 |
block += '%Mem=256MB\n' |
|
185 |
block += '%nproc=32\n' |
|
186 |
block += 'MaxDisk=16gb\n' |
|
187 |
|
|
188 |
block += '#' |
|
189 |
block += '%s'%(self.functional) |
|
190 |
block += '/' |
|
191 |
block += '%s'%(self.basis) |
|
192 |
|
|
193 |
if type == 'force': |
|
194 |
block += 'Force ' |
|
195 |
# if self.r_m != None: |
|
196 |
# block += 'Guess=Read' |
|
197 |
|
|
198 |
block += '\n\nGaussian job\n\n' |
|
199 |
|
|
200 |
charge = sum(self.atoms.get_charges()) |
|
201 |
block += '%i '%(charge) |
|
202 |
block += '%i '%(1) |
|
203 |
block += '\n' |
|
204 |
|
|
205 |
coords = self.atoms.get_positions() |
|
206 |
for i, at in enumerate(self.atoms.get_chemical_symbols()): |
|
207 |
block += ' %2s'%(at) |
|
208 |
coord = coords[i] |
|
209 |
block += ' %16.5f %16.5f %16.5f'%(coord[0], coord[1], coord[2]) |
|
210 |
block += '\n' |
|
211 |
|
|
212 |
if self.atoms.get_pbc().any(): |
|
213 |
cell = self.atoms.get_cell() |
|
214 |
|
|
215 |
for v in cell: |
|
216 |
block += 'TV %8.3f %8.3f %8.3f\n'%(v[0], v[1], v[2]) |
|
217 |
block += '\n' |
|
218 |
|
|
219 |
return block |
|
220 |
|
|
221 |
|
|
222 |
def get_settings(self, filename=None): |
|
223 |
settings = GaussianSettings() |
|
224 |
|
|
225 |
if filename != None or filename == '': |
|
226 |
input = self.get_inp(filename) |
|
227 |
else: |
|
228 |
settings.set_functional("") |
|
229 |
return settings |
|
230 |
|
|
231 |
if input == None: |
|
232 |
settings.set_functional("") |
|
233 |
return settings |
|
234 |
|
|
235 |
for i, line in enumerate(input): |
|
236 |
if len(line.strip()) == 0: |
|
237 |
continue |
|
238 |
if line[0] == '#': |
|
239 |
keyline = i |
|
240 |
words = line[1:].split() |
|
241 |
else: |
|
242 |
settings.functional = words[0].split('/')[0] |
|
243 |
settings.basis = words[0].split('/')[1] |
|
244 |
break |
|
245 |
return settings |
|
246 |
|
|
247 |
def update(self, atoms): |
|
248 |
if self.atoms_old != atoms: |
|
249 |
self.atoms = atoms.copy() |
|
250 |
self.atoms_old = atoms.copy() |
|
251 |
self.run() |
Formats disponibles : Unified diff