Révision 5
ase/calculators/qmx.py (revision 5) | ||
---|---|---|
15 | 15 |
import sys, os |
16 | 16 |
|
17 | 17 |
class Qmx(Calculator): |
18 |
def __init__(self, calculator_high, calculator_low):
|
|
18 |
def __init__(self, calculator_high_cluster, calculator_low_cluster, calculator_low_system=None, print_forces=False):
|
|
19 | 19 |
self._constraints=None |
20 |
self.calculator_low_cluster = calculator_low |
|
21 |
self.calculator_low_system = deepcopy(calculator_low) |
|
22 |
self.calculator_high = calculator_high |
|
20 |
|
|
21 |
self.calculator_low_cluster = calculator_low_cluster |
|
22 |
self.calculator_low_system = calculator_low_system |
|
23 |
if self.calculator_low_system is None: |
|
24 |
self.calculator_low_system = deepcopy(calculator_low_cluster) |
|
25 |
self.calculator_high_cluster = calculator_high_cluster |
|
26 |
self.print_forces = print_forces |
|
23 | 27 |
|
24 | 28 |
def get_energy_subsystem(self, path, calculator, atoms, force_consistent): |
25 | 29 |
# go to directory and calculate energies |
... | ... | |
43 | 47 |
# perform energy calculations |
44 | 48 |
e_sys_lo = self.get_energy_subsystem("system.low-level", self.calculator_low_system, embed.get_system(), force_consistent) |
45 | 49 |
e_cl_lo = self.get_energy_subsystem("cluster.low-level", self.calculator_low_cluster, embed.get_cluster(), force_consistent) |
46 |
e_cl_hi = self.get_energy_subsystem("cluster.high-level", self.calculator_high, embed.get_cluster(), force_consistent) |
|
50 |
e_cl_hi = self.get_energy_subsystem("cluster.high-level", self.calculator_high_cluster, embed.get_cluster(), force_consistent)
|
|
47 | 51 |
# calculate energies |
48 | 52 |
energy = e_sys_lo - e_cl_lo + e_cl_hi |
49 | 53 |
# print energies |
50 |
print "%20s=%15s - %15s + %15s" %("E(C:S)", "E(S-MM)", "E(C-MM)", "E(C-QM)")
|
|
51 |
print "%20f=%15f - %15f + %15f" %(energy, e_sys_lo, e_cl_lo, e_cl_hi)
|
|
54 |
print "%20s = %15s - %15s + %15s" %("E(C:S)", "E(S-MM)", "E(C-MM)", "E(C-QM)")
|
|
55 |
print "%20f = %15f - %15f + %15f" %(energy, e_sys_lo, e_cl_lo, e_cl_hi)
|
|
52 | 56 |
# set energies and return |
53 | 57 |
if force_consistent: |
54 | 58 |
self.energy_free = energy |
... | ... | |
62 | 66 |
# get forces for the three systems |
63 | 67 |
f_sys_lo = self.get_forces_subsystem("system.low-level", self.calculator_low_system, embed.get_system()) |
64 | 68 |
f_cl_lo = self.get_forces_subsystem("cluster.low-level", self.calculator_low_cluster, embed.get_cluster()) |
65 |
f_cl_hi = self.get_forces_subsystem("cluster.high-level", self.calculator_high, embed.get_cluster()) |
|
69 |
f_cl_hi = self.get_forces_subsystem("cluster.high-level", self.calculator_high_cluster, embed.get_cluster()) |
|
70 |
|
|
66 | 71 |
# forces correction for the atoms |
67 | 72 |
f_cl = f_cl_hi - f_cl_lo |
68 |
# number of atoms |
|
69 |
nat_sys = len(embed) |
|
73 |
|
|
74 |
if self.print_forces: |
|
75 |
cluster=embed.get_cluster() |
|
76 |
print "Forces: System LOW - Cluster LOW + Cluster HIGH" |
|
77 |
for iat_sys in xrange(len(embed)): |
|
78 |
print "%-2s (" % embed[iat_sys].get_symbol(), |
|
79 |
for idir in xrange(3): |
|
80 |
print "%10.6f" % f_sys_lo[iat_sys][idir], |
|
81 |
print ") <system LOW>" |
|
82 |
|
|
83 |
iat_cl = atom_map_sys_cl[iat_sys] |
|
84 |
if iat_cl > -1: |
|
85 |
print "%s" % "- (", |
|
86 |
for idir in xrange(3): |
|
87 |
print "%10.6f" % f_cl_lo[iat_cl][idir], |
|
88 |
print ") <cluster LOW>" |
|
89 |
print "%s" % "+ (", |
|
90 |
for idir in xrange(3): |
|
91 |
print "%10.6f" % f_cl_hi[iat_cl][idir], |
|
92 |
print ") <cluster HIGH>" |
|
93 |
|
|
94 |
|
|
95 |
|
|
70 | 96 |
# lo-sys + (hi-lo) |
71 |
for iat_sys in xrange(nat_sys):
|
|
97 |
for iat_sys in xrange(len(embed)):
|
|
72 | 98 |
iat_cl = atom_map_sys_cl[iat_sys] |
73 | 99 |
if iat_cl > -1: |
74 | 100 |
f_sys_lo[iat_sys] += f_cl[iat_cl] |
75 |
|
|
101 |
# some settings for the output |
|
102 |
i_change = np.zeros(len(embed), int) |
|
103 |
if self.print_forces: |
|
104 |
f_sys_lo_orig = f_sys_lo.copy() |
|
76 | 105 |
# correct gradients |
77 | 106 |
# Reference: Eichler, Koelmel, Sauer, J. of Comput. Chem., 18(4). 1997, 463-477. |
78 | 107 |
for cell_L, iat_cl_sys, iat_sys, r, iat_link in embed.linkatoms: |
79 | 108 |
# calculate the bond distance (r_bond) at the border |
80 | 109 |
xyz = embed[iat_sys].get_position() - embed[iat_cl_sys].get_position() + cell_L |
81 |
|
|
82 | 110 |
# calculate the bond lenght and the factor f |
83 | 111 |
rbond = np.sqrt(np.dot(xyz, xyz)) |
84 | 112 |
f = r / rbond |
... | ... | |
87 | 115 |
# receive the gradients for the link atom |
88 | 116 |
fL = f_cl[iat_link] |
89 | 117 |
# dot product fL, xyz |
90 |
fs = np.dot(xyz, fL)
|
|
118 |
fs = np.dot(fL, xyz)
|
|
91 | 119 |
# apply corrections for each direction |
120 |
i_change[iat_sys] = 1 |
|
121 |
i_change[iat_cl_sys] = 1 |
|
92 | 122 |
for idir in xrange(3): |
93 | 123 |
# correct the atom in the system |
94 |
f_sys_lo[iat_sys][idir] += f*fL[idir] - f*fs*xyz[idir]
|
|
124 |
f_sys_lo[iat_sys][idir] = f_sys_lo[iat_sys][idir] + f*fL[idir] - f*fs*xyz[idir]
|
|
95 | 125 |
# correct the atom in the cluster |
96 |
f_sys_lo[iat_cl_sys][idir] += (1-f)*fL[idir] + f*fs*xyz[idir] |
|
126 |
f_sys_lo[iat_cl_sys][idir] = f_sys_lo[iat_cl_sys][idir] + (1-f)*fL[idir] + f*fs*xyz[idir] |
|
127 |
|
|
128 |
if self.print_forces: |
|
129 |
print " TOTAL FORCE (uncorrected : corrected) for link atoms" |
|
130 |
for iat_sys in xrange(len(embed)): |
|
131 |
print "%-2s (" % embed[iat_sys].get_symbol(), |
|
132 |
for idir in xrange(3): |
|
133 |
print "%10.6f" % f_sys_lo_orig[iat_sys][idir], |
|
134 |
print ") : (", |
|
135 |
for idir in xrange(3): |
|
136 |
print "%10.6f" % f_sys_lo[iat_sys][idir], |
|
137 |
print ")", |
|
138 |
if i_change[iat_sys]: |
|
139 |
print " *", |
|
140 |
|
|
141 |
|
|
142 |
|
|
97 | 143 |
return f_sys_lo |
ase/calculators/turbomole.py (revision 5) | ||
---|---|---|
1 | 1 |
"""This module defines an ASE interface to Turbomole |
2 |
|
|
3 | 2 |
http://www.turbomole.com/ |
4 | 3 |
""" |
5 | 4 |
import os, sys, string |
... | ... | |
11 | 10 |
import numpy as np |
12 | 11 |
|
13 | 12 |
class Turbomole(Calculator): |
14 |
"""Class for doing Turbomole calculations. |
|
15 |
""" |
|
16 | 13 |
def __init__(self, label='turbomole', calculate_energy="dscf", calculate_forces="grad", post_HF = False): |
17 |
"""Construct TURBOMOLE-calculator object. |
|
18 |
|
|
19 |
Parameters |
|
20 |
========== |
|
21 |
label: str |
|
22 |
Prefix to use for filenames (label.txt, ...). |
|
23 |
Default is 'turbomole'. |
|
24 |
|
|
25 |
Examples |
|
26 |
======== |
|
27 |
This is poor man's version of ASE-Turbomole: |
|
28 |
|
|
29 |
First you do a normal turbomole preparation using turbomole's |
|
30 |
define-program for the initial and final states. |
|
31 |
|
|
32 |
(for instance in subdirectories Initial and Final) |
|
33 |
|
|
34 |
Then relax the initial and final coordinates with desired constraints |
|
35 |
using standard turbomole. |
|
36 |
|
|
37 |
Copy the relaxed initial and final coordinates |
|
38 |
(initial.coord and final.coord) |
|
39 |
and the turbomole related files (from the subdirectory Initial) |
|
40 |
control, coord, alpha, beta, mos, basis, auxbasis etc to the directory |
|
41 |
you do the diffusion run. |
|
42 |
|
|
43 |
For instance: |
|
44 |
cd $My_Turbomole_diffusion_directory |
|
45 |
cd Initial; cp control alpha beta mos basis auxbasis ../; |
|
46 |
cp coord ../initial.coord; |
|
47 |
cd ../; |
|
48 |
cp Final/coord ./final.coord; |
|
49 |
mkdir Gz ; cp * Gz ; gzip -r Gz |
|
50 |
|
|
51 |
from ase.io import read |
|
52 |
from ase.calculators.turbomole import Turbomole |
|
53 |
a = read('coord', index=-1, format='turbomole') |
|
54 |
calc = Turbomole() |
|
55 |
a.set_calculator(calc) |
|
56 |
e = a.get_potential_energy() |
|
57 |
|
|
58 |
""" |
|
59 |
|
|
60 | 14 |
self.label = label |
61 | 15 |
self.converged = False |
62 | 16 |
|
... | ... | |
88 | 42 |
def execute(self, command): |
89 | 43 |
from subprocess import Popen, PIPE |
90 | 44 |
try: |
45 |
# the sub process gets started here |
|
91 | 46 |
proc = Popen([command], shell=True, stderr=PIPE) |
92 | 47 |
error = proc.communicate()[1] |
93 |
if "abnormally" in error: |
|
48 |
# check the error output |
|
49 |
if not " ended normally" in error: |
|
94 | 50 |
raise OSError(error) |
95 | 51 |
print "TM command: ", command, "successfully executed" |
96 | 52 |
except OSError, e: |
97 |
print >>sys.stderr, "Execution failed:", e |
|
53 |
print >>sys.stderr, "Execution failed: ", e
|
|
98 | 54 |
sys.exit(1) |
99 | 55 |
|
100 | 56 |
def get_potential_energy(self, atoms): |
... | ... | |
134 | 90 |
return self.forces.copy() |
135 | 91 |
|
136 | 92 |
def get_stress(self, atoms): |
137 |
return self.stress.copy()
|
|
93 |
return self.stress |
|
138 | 94 |
|
139 | 95 |
def set_atoms(self, atoms): |
140 | 96 |
if self.atoms == atoms: |
... | ... | |
162 | 118 |
energy_tmp = float(line.split()[1]) |
163 | 119 |
if self.post_HF: |
164 | 120 |
energy_tmp += float(line.split()[4]) |
121 |
# update energy units |
|
165 | 122 |
self.e_total = energy_tmp * Hartree |
166 | 123 |
|
167 | 124 |
|
... | ... | |
184 | 141 |
print 'Gradients not found' |
185 | 142 |
raise RuntimeError("Please check TURBOMOLE gradients") |
186 | 143 |
|
144 |
# next line |
|
187 | 145 |
iline += len(self.atoms) + 1 |
146 |
# $end line |
|
188 | 147 |
nline -= 1 |
148 |
# read gradients |
|
189 | 149 |
for i in xrange(iline, nline): |
190 | 150 |
line = string.replace(lines[i],'D','E') |
191 | 151 |
#tmp=np.append(forces_tmp,np.array\ |
ase/embed.py (revision 5) | ||
---|---|---|
225 | 225 |
# go over all pairs of atoms |
226 | 226 |
for iat_sys in xrange(nat_sys): |
227 | 227 |
xyz = positions_new[iat_sys] |
228 |
self.atoms_system[iat_sys].set_position(xyz) |
|
228 | 229 |
iat_cl = self.atom_map_sys_cl[iat_sys] |
229 |
self.atoms_system[iat_sys].set_position(xyz) |
|
230 | 230 |
if iat_cl > -1: |
231 | 231 |
self.atoms_cluster[iat_cl].set_position(xyz) |
232 | 232 |
|
233 | 233 |
for cell_L, iat_cl_sys, iat_sys, r, iat in self.linkatoms: |
234 | 234 |
# determine position of the link atom |
235 |
xyz_cl = self.atoms_system[iat_cl_sys].get_position()
|
|
236 |
xyz = self.atoms_system[iat_sys].get_position() - xyz_cl + cell_L
|
|
235 |
xyz_cl = positions_new[iat_cl_sys]
|
|
236 |
xyz = positions_new[iat_sys] - xyz_cl + cell_L
|
|
237 | 237 |
xyz *= r / np.sqrt(np.dot(xyz, xyz)) |
238 | 238 |
xyz += xyz_cl |
239 | 239 |
# update xyz coordinates of the cluster |
ase/io/turbomole.py (revision 5) | ||
---|---|---|
49 | 49 |
f.close() |
50 | 50 |
|
51 | 51 |
atoms = Atoms(positions = atoms_pos, symbols = atom_symbols, pbc = False) |
52 |
c = FixAtoms(myconstraints) |
|
53 |
atoms.set_constraint(c) |
|
52 |
# c = FixAtoms(myconstraints)
|
|
53 |
# atoms.set_constraint(c)
|
|
54 | 54 |
#print c |
55 | 55 |
|
56 | 56 |
|
... | ... | |
99 | 99 |
f.write('%20.14f %20.14f %20.14f %2s \n' |
100 | 100 |
% (x/Bohr, y/Bohr, z/Bohr, s.lower())) |
101 | 101 |
f.write("$end\n") |
102 |
|
prepareQMX.py (revision 5) | ||
---|---|---|
1 |
link ../../10-programming/ASE.QMX/prepareQMX.py |
|
0 | 2 |
prepareQMX.GUI.py (revision 5) | ||
---|---|---|
1 |
link ../../10-programming/ASE.QMX/prepareQMX.GUI.py |
|
0 | 2 |
Formats disponibles : Unified diff