root / ase / optimize / oldqn.py @ 1
Historique | Voir | Annoter | Télécharger (14,44 ko)
1 | 1 | tkerber | # Copyright (C) 2003 CAMP
|
---|---|---|---|
2 | 1 | tkerber | # Please see the accompanying LICENSE file for further information.
|
3 | 1 | tkerber | |
4 | 1 | tkerber | """
|
5 | 1 | tkerber | Quasi-Newton algorithm
|
6 | 1 | tkerber | """
|
7 | 1 | tkerber | |
8 | 1 | tkerber | __docformat__ = 'reStructuredText'
|
9 | 1 | tkerber | |
10 | 1 | tkerber | import numpy as np |
11 | 1 | tkerber | import weakref,time,sys |
12 | 1 | tkerber | |
13 | 1 | tkerber | |
14 | 1 | tkerber | def f(lamda,Gbar,b,radius): |
15 | 1 | tkerber | b1 = b - lamda |
16 | 1 | tkerber | g = radius**2 - np.dot(Gbar/b1, Gbar/b1)
|
17 | 1 | tkerber | return g
|
18 | 1 | tkerber | |
19 | 1 | tkerber | |
20 | 1 | tkerber | |
21 | 1 | tkerber | def scale_radius_energy(f,r): |
22 | 1 | tkerber | scale = 1.0
|
23 | 1 | tkerber | # if(r<=0.01):
|
24 | 1 | tkerber | # return scale
|
25 | 1 | tkerber | |
26 | 1 | tkerber | if f<0.01: scale*=1.4 |
27 | 1 | tkerber | if f<0.05: scale*=1.4 |
28 | 1 | tkerber | if f<0.10: scale*=1.4 |
29 | 1 | tkerber | if f<0.40: scale*=1.4 |
30 | 1 | tkerber | |
31 | 1 | tkerber | if f>0.5: scale *= 1./1.4 |
32 | 1 | tkerber | if f>0.7: scale *= 1./1.4 |
33 | 1 | tkerber | if f>1.0: scale *= 1./1.4 |
34 | 1 | tkerber | |
35 | 1 | tkerber | return scale
|
36 | 1 | tkerber | |
37 | 1 | tkerber | def scale_radius_force(f,r): |
38 | 1 | tkerber | scale = 1.0
|
39 | 1 | tkerber | # if(r<=0.01):
|
40 | 1 | tkerber | # return scale
|
41 | 1 | tkerber | g = abs(f -1) |
42 | 1 | tkerber | if g<0.01: scale*=1.4 |
43 | 1 | tkerber | if g<0.05: scale*=1.4 |
44 | 1 | tkerber | if g<0.10: scale*=1.4 |
45 | 1 | tkerber | if g<0.40: scale*=1.4 |
46 | 1 | tkerber | |
47 | 1 | tkerber | if g>0.5: scale *= 1./1.4 |
48 | 1 | tkerber | if g>0.7: scale *= 1./1.4 |
49 | 1 | tkerber | if g>1.0: scale *= 1./1.4 |
50 | 1 | tkerber | |
51 | 1 | tkerber | return scale
|
52 | 1 | tkerber | |
53 | 1 | tkerber | def find_lamda(upperlimit,Gbar,b,radius): |
54 | 1 | tkerber | lowerlimit = upperlimit |
55 | 1 | tkerber | eps = 1e-12
|
56 | 1 | tkerber | step = 0.1
|
57 | 1 | tkerber | while f(lowerlimit,Gbar,b,radius) < 0: |
58 | 1 | tkerber | lowerlimit -= step |
59 | 1 | tkerber | |
60 | 1 | tkerber | converged = False
|
61 | 1 | tkerber | |
62 | 1 | tkerber | while not converged: |
63 | 1 | tkerber | |
64 | 1 | tkerber | midt = (upperlimit+lowerlimit)/2.
|
65 | 1 | tkerber | lamda = midt |
66 | 1 | tkerber | fmidt = f(midt,Gbar,b,radius) |
67 | 1 | tkerber | fupper = f(upperlimit,Gbar,b,radius) |
68 | 1 | tkerber | flower = f(lowerlimit,Gbar,b,radius) |
69 | 1 | tkerber | |
70 | 1 | tkerber | if fupper*fmidt<0: |
71 | 1 | tkerber | lowerlimit = midt |
72 | 1 | tkerber | else:
|
73 | 1 | tkerber | upperlimit = midt |
74 | 1 | tkerber | |
75 | 1 | tkerber | if abs(upperlimit-lowerlimit)<1e-6: |
76 | 1 | tkerber | converged = True
|
77 | 1 | tkerber | |
78 | 1 | tkerber | return lamda
|
79 | 1 | tkerber | |
80 | 1 | tkerber | def get_hessian_inertia(eigenvalues): |
81 | 1 | tkerber | # return number of negative modes
|
82 | 1 | tkerber | n = 0
|
83 | 1 | tkerber | print 'eigenvalues ',eigenvalues[0],eigenvalues[1],eigenvalues[2] |
84 | 1 | tkerber | while eigenvalues[n]<0: |
85 | 1 | tkerber | n+=1
|
86 | 1 | tkerber | return n
|
87 | 1 | tkerber | |
88 | 1 | tkerber | |
89 | 1 | tkerber | from numpy.linalg import eigh, solve |
90 | 1 | tkerber | |
91 | 1 | tkerber | from ase.optimize.optimize import Optimizer |
92 | 1 | tkerber | |
93 | 1 | tkerber | |
94 | 1 | tkerber | |
95 | 1 | tkerber | class GoodOldQuasiNewton(Optimizer): |
96 | 1 | tkerber | |
97 | 1 | tkerber | def __init__(self, atoms, restart=None, logfile='-', trajectory=None, |
98 | 1 | tkerber | fmax=None, converged=None, |
99 | 1 | tkerber | hessianupdate='BFGS',hessian=None,forcemin=True, |
100 | 1 | tkerber | verbosity=None,maxradius=None, |
101 | 1 | tkerber | diagonal=20.,radius=None, |
102 | 1 | tkerber | transitionstate = False):
|
103 | 1 | tkerber | |
104 | 1 | tkerber | Optimizer.__init__(self, atoms, restart, logfile, trajectory)
|
105 | 1 | tkerber | |
106 | 1 | tkerber | self.eps = 1e-12 |
107 | 1 | tkerber | self.hessianupdate = hessianupdate
|
108 | 1 | tkerber | self.forcemin = forcemin
|
109 | 1 | tkerber | self.verbosity = verbosity
|
110 | 1 | tkerber | self.diagonal = diagonal
|
111 | 1 | tkerber | |
112 | 1 | tkerber | self.atoms = atoms
|
113 | 1 | tkerber | |
114 | 1 | tkerber | n = len(self.atoms) * 3 |
115 | 1 | tkerber | if radius is None: |
116 | 1 | tkerber | self.radius = 0.05*np.sqrt(n)/10.0 |
117 | 1 | tkerber | else:
|
118 | 1 | tkerber | self.radius = radius
|
119 | 1 | tkerber | |
120 | 1 | tkerber | if maxradius is None: |
121 | 1 | tkerber | self.maxradius = 0.5*np.sqrt(n) |
122 | 1 | tkerber | else:
|
123 | 1 | tkerber | self.maxradius = maxradius
|
124 | 1 | tkerber | |
125 | 1 | tkerber | # 0.01 < radius < maxradius
|
126 | 1 | tkerber | self.radius = max(min( self.radius, self.maxradius ), 0.0001) |
127 | 1 | tkerber | |
128 | 1 | tkerber | self.transitionstate = transitionstate
|
129 | 1 | tkerber | |
130 | 1 | tkerber | # check if this is a nudged elastic band calculation
|
131 | 1 | tkerber | if hasattr(atoms,'springconstant'): |
132 | 1 | tkerber | self.forcemin=False |
133 | 1 | tkerber | |
134 | 1 | tkerber | self.t0 = time.time()
|
135 | 1 | tkerber | |
136 | 1 | tkerber | def initialize(self):pass |
137 | 1 | tkerber | |
138 | 1 | tkerber | def write_log(self,text): |
139 | 1 | tkerber | if self.logfile is not None: |
140 | 1 | tkerber | self.logfile.write(text + '\n') |
141 | 1 | tkerber | self.logfile.flush()
|
142 | 1 | tkerber | |
143 | 1 | tkerber | def set_max_radius(self, maxradius): |
144 | 1 | tkerber | self.maxradius = maxradius
|
145 | 1 | tkerber | self.radius = min(self.maxradius, self.radius) |
146 | 1 | tkerber | |
147 | 1 | tkerber | def set_hessian(self,hessian): |
148 | 1 | tkerber | self.hessian = hessian
|
149 | 1 | tkerber | |
150 | 1 | tkerber | def get_hessian(self): |
151 | 1 | tkerber | if not hasattr(self,'hessian'): |
152 | 1 | tkerber | self.set_default_hessian()
|
153 | 1 | tkerber | return self.hessian |
154 | 1 | tkerber | |
155 | 1 | tkerber | def set_default_hessian(self): |
156 | 1 | tkerber | # set unit matrix
|
157 | 1 | tkerber | n = len(self.atoms) * 3 |
158 | 1 | tkerber | hessian = np.zeros((n,n)) |
159 | 1 | tkerber | for i in range(n): |
160 | 1 | tkerber | hessian[i][i] = self.diagonal
|
161 | 1 | tkerber | self.set_hessian(hessian)
|
162 | 1 | tkerber | |
163 | 1 | tkerber | def read_hessian(self,filename): |
164 | 1 | tkerber | import cPickle |
165 | 1 | tkerber | f = open(filename,'r') |
166 | 1 | tkerber | self.set_hessian(cPickle.load(f))
|
167 | 1 | tkerber | f.close() |
168 | 1 | tkerber | |
169 | 1 | tkerber | def write_hessian(self,filename): |
170 | 1 | tkerber | import cPickle |
171 | 1 | tkerber | f = paropen(filename,'w')
|
172 | 1 | tkerber | cPickle.dump(self.get_hessian(),f)
|
173 | 1 | tkerber | f.close() |
174 | 1 | tkerber | |
175 | 1 | tkerber | def write_to_restartfile(self): |
176 | 1 | tkerber | import cPickle |
177 | 1 | tkerber | f = paropen(self.restartfile,'w') |
178 | 1 | tkerber | cPickle.dump((self.oldpos,
|
179 | 1 | tkerber | self.oldG,
|
180 | 1 | tkerber | self.oldenergy,
|
181 | 1 | tkerber | self.radius,
|
182 | 1 | tkerber | self.hessian,
|
183 | 1 | tkerber | self.energy_estimate),f)
|
184 | 1 | tkerber | f.close() |
185 | 1 | tkerber | |
186 | 1 | tkerber | |
187 | 1 | tkerber | |
188 | 1 | tkerber | def update_hessian(self,pos,G): |
189 | 1 | tkerber | import copy |
190 | 1 | tkerber | if hasattr(self,'oldG'): |
191 | 1 | tkerber | if self.hessianupdate=='BFGS': |
192 | 1 | tkerber | self.update_hessian_bfgs(pos,G)
|
193 | 1 | tkerber | elif self.hessianupdate== 'Powell': |
194 | 1 | tkerber | self.update_hessian_powell(pos,G)
|
195 | 1 | tkerber | else:
|
196 | 1 | tkerber | self.update_hessian_bofill(pos,G)
|
197 | 1 | tkerber | else:
|
198 | 1 | tkerber | if not hasattr(self,'hessian'): |
199 | 1 | tkerber | self.set_default_hessian()
|
200 | 1 | tkerber | |
201 | 1 | tkerber | self.oldpos = copy.copy(pos)
|
202 | 1 | tkerber | self.oldG = copy.copy(G)
|
203 | 1 | tkerber | |
204 | 1 | tkerber | if self.verbosity: |
205 | 1 | tkerber | print 'hessian ',self.hessian |
206 | 1 | tkerber | |
207 | 1 | tkerber | |
208 | 1 | tkerber | |
209 | 1 | tkerber | def update_hessian_bfgs(self,pos,G): |
210 | 1 | tkerber | n = len(self.hessian) |
211 | 1 | tkerber | dgrad = G - self.oldG
|
212 | 1 | tkerber | dpos = pos - self.oldpos
|
213 | 1 | tkerber | absdpos = np.sqrt(np.dot(dpos, dpos)) |
214 | 1 | tkerber | dotg = np.dot(dgrad,dpos) |
215 | 1 | tkerber | tvec = np.dot(dpos,self.hessian)
|
216 | 1 | tkerber | dott = np.dot(dpos,tvec) |
217 | 1 | tkerber | if (abs(dott)>self.eps) and (abs(dotg)>self.eps): |
218 | 1 | tkerber | for i in range(n): |
219 | 1 | tkerber | for j in range(n): |
220 | 1 | tkerber | h = dgrad[i]*dgrad[j]/dotg - tvec[i]*tvec[j]/dott |
221 | 1 | tkerber | self.hessian[i][j] += h
|
222 | 1 | tkerber | |
223 | 1 | tkerber | |
224 | 1 | tkerber | |
225 | 1 | tkerber | def update_hessian_powell(self,pos,G): |
226 | 1 | tkerber | n = len(self.hessian) |
227 | 1 | tkerber | dgrad = G - self.oldG
|
228 | 1 | tkerber | dpos = pos - self.oldpos
|
229 | 1 | tkerber | absdpos = np.dot(dpos, dpos) |
230 | 1 | tkerber | if absdpos<self.eps: |
231 | 1 | tkerber | return
|
232 | 1 | tkerber | |
233 | 1 | tkerber | dotg = np.dot(dgrad,dpos) |
234 | 1 | tkerber | tvec = dgrad-np.dot(dpos,self.hessian)
|
235 | 1 | tkerber | tvecdot = np.dot(tvec,tvec) |
236 | 1 | tkerber | tvecdpos = np.dot(tvec,dpos) |
237 | 1 | tkerber | ddot = tvecdpos/absdpos |
238 | 1 | tkerber | |
239 | 1 | tkerber | dott = np.dot(dpos,tvec) |
240 | 1 | tkerber | if (abs(dott)>self.eps) and (abs(dotg)>self.eps): |
241 | 1 | tkerber | for i in range(n): |
242 | 1 | tkerber | for j in range(n): |
243 | 1 | tkerber | h = tvec[i]*dpos[j] + dpos[i]*tvec[j]-ddot*dpos[i]*dpos[j] |
244 | 1 | tkerber | h *= 1./absdpos
|
245 | 1 | tkerber | self.hessian[i][j] += h
|
246 | 1 | tkerber | |
247 | 1 | tkerber | |
248 | 1 | tkerber | def update_hessian_bofill(self,pos,G): |
249 | 1 | tkerber | print 'update Bofill' |
250 | 1 | tkerber | n = len(self.hessian) |
251 | 1 | tkerber | dgrad = G - self.oldG
|
252 | 1 | tkerber | dpos = pos - self.oldpos
|
253 | 1 | tkerber | absdpos = np.dot(dpos, dpos) |
254 | 1 | tkerber | if absdpos<self.eps: |
255 | 1 | tkerber | return
|
256 | 1 | tkerber | dotg = np.dot(dgrad,dpos) |
257 | 1 | tkerber | tvec = dgrad-np.dot(dpos,self.hessian)
|
258 | 1 | tkerber | tvecdot = np.dot(tvec,tvec) |
259 | 1 | tkerber | tvecdpos = np.dot(tvec,dpos) |
260 | 1 | tkerber | ddot = tvecdpos/absdpos |
261 | 1 | tkerber | |
262 | 1 | tkerber | coef1 = 1. - tvecdpos*tvecdpos/(absdpos*tvecdot)
|
263 | 1 | tkerber | coef2 = (1. - coef1)*absdpos/tvecdpos
|
264 | 1 | tkerber | coef3 = coef1*tvecdpos/absdpos |
265 | 1 | tkerber | |
266 | 1 | tkerber | dott = np.dot(dpos,tvec) |
267 | 1 | tkerber | if (abs(dott)>self.eps) and (abs(dotg)>self.eps): |
268 | 1 | tkerber | for i in range(n): |
269 | 1 | tkerber | for j in range(n): |
270 | 1 | tkerber | h = coef1*(tvec[i]*dpos[j] + dpos[i]*tvec[j])-dpos[i]*dpos[j]*coef3 + coef2*tvec[i]*tvec[j] |
271 | 1 | tkerber | h *= 1./absdpos
|
272 | 1 | tkerber | self.hessian[i][j] += h
|
273 | 1 | tkerber | |
274 | 1 | tkerber | |
275 | 1 | tkerber | |
276 | 1 | tkerber | def step(self, f): |
277 | 1 | tkerber | """ Do one QN step
|
278 | 1 | tkerber | """
|
279 | 1 | tkerber | |
280 | 1 | tkerber | pos = self.atoms.get_positions().ravel()
|
281 | 1 | tkerber | G = -self.atoms.get_forces().ravel()
|
282 | 1 | tkerber | energy = self.atoms.get_potential_energy()
|
283 | 1 | tkerber | |
284 | 1 | tkerber | |
285 | 1 | tkerber | self.write_iteration(energy,G)
|
286 | 1 | tkerber | |
287 | 1 | tkerber | if hasattr(self,'oldenergy'): |
288 | 1 | tkerber | |
289 | 1 | tkerber | self.write_log('energies ' + str(energy) + ' ' + str(self.oldenergy)) |
290 | 1 | tkerber | |
291 | 1 | tkerber | if self.forcemin: |
292 | 1 | tkerber | de = 1e-4
|
293 | 1 | tkerber | else:
|
294 | 1 | tkerber | de = 1e-2
|
295 | 1 | tkerber | |
296 | 1 | tkerber | if self.transitionstate: |
297 | 1 | tkerber | de = 0.2
|
298 | 1 | tkerber | |
299 | 1 | tkerber | if (energy-self.oldenergy)>de: |
300 | 1 | tkerber | self.write_log('reject step') |
301 | 1 | tkerber | self.atoms.set_positions(self.oldpos.reshape((-1, 3))) |
302 | 1 | tkerber | G = self.oldG
|
303 | 1 | tkerber | energy = self.oldenergy
|
304 | 1 | tkerber | self.radius *= 0.5 |
305 | 1 | tkerber | else:
|
306 | 1 | tkerber | self.update_hessian(pos,G)
|
307 | 1 | tkerber | de = energy - self.oldenergy
|
308 | 1 | tkerber | f = 1.0
|
309 | 1 | tkerber | if self.forcemin: |
310 | 1 | tkerber | self.write_log("energy change; actual: %f estimated: %f "%(de,self.energy_estimate)) |
311 | 1 | tkerber | if abs(self.energy_estimate)>self.eps: |
312 | 1 | tkerber | f = abs((de/self.energy_estimate)-1) |
313 | 1 | tkerber | self.write_log('Energy prediction factor ' + str(f)) |
314 | 1 | tkerber | # fg = self.get_force_prediction(G)
|
315 | 1 | tkerber | self.radius *= scale_radius_energy(f,self.radius) |
316 | 1 | tkerber | |
317 | 1 | tkerber | else:
|
318 | 1 | tkerber | self.write_log("energy change; actual: %f "%(de)) |
319 | 1 | tkerber | self.radius*=1.5 |
320 | 1 | tkerber | |
321 | 1 | tkerber | fg = self.get_force_prediction(G)
|
322 | 1 | tkerber | self.write_log("Scale factors %f %f "%(scale_radius_energy(f,self.radius), |
323 | 1 | tkerber | scale_radius_force(fg,self.radius)))
|
324 | 1 | tkerber | |
325 | 1 | tkerber | |
326 | 1 | tkerber | self.radius = max(min(self.radius,self.maxradius), 0.0001) |
327 | 1 | tkerber | else:
|
328 | 1 | tkerber | self.update_hessian(pos,G)
|
329 | 1 | tkerber | |
330 | 1 | tkerber | self.write_log("new radius %f "%(self.radius)) |
331 | 1 | tkerber | self.oldenergy = energy
|
332 | 1 | tkerber | |
333 | 1 | tkerber | b,V = eigh(self.hessian)
|
334 | 1 | tkerber | V=V.T.copy() |
335 | 1 | tkerber | self.V = V
|
336 | 1 | tkerber | |
337 | 1 | tkerber | # calculate projection of G onto eigenvectors V
|
338 | 1 | tkerber | Gbar = np.dot(G,np.transpose(V)) |
339 | 1 | tkerber | |
340 | 1 | tkerber | lamdas = self.get_lambdas(b,Gbar)
|
341 | 1 | tkerber | |
342 | 1 | tkerber | D = -Gbar/(b-lamdas) |
343 | 1 | tkerber | n = len(D)
|
344 | 1 | tkerber | step = np.zeros((n)) |
345 | 1 | tkerber | for i in range(n): |
346 | 1 | tkerber | step += D[i]*V[i] |
347 | 1 | tkerber | |
348 | 1 | tkerber | pos = self.atoms.get_positions().ravel()
|
349 | 1 | tkerber | pos += step |
350 | 1 | tkerber | |
351 | 1 | tkerber | energy_estimate = self.get_energy_estimate(D,Gbar,b)
|
352 | 1 | tkerber | self.energy_estimate = energy_estimate
|
353 | 1 | tkerber | self.gbar_estimate = self.get_gbar_estimate(D,Gbar,b) |
354 | 1 | tkerber | self.old_gbar = Gbar
|
355 | 1 | tkerber | |
356 | 1 | tkerber | self.atoms.set_positions(pos.reshape((-1, 3))) |
357 | 1 | tkerber | |
358 | 1 | tkerber | |
359 | 1 | tkerber | |
360 | 1 | tkerber | |
361 | 1 | tkerber | def get_energy_estimate(self,D,Gbar,b): |
362 | 1 | tkerber | |
363 | 1 | tkerber | de = 0.0
|
364 | 1 | tkerber | for n in range(len(D)): |
365 | 1 | tkerber | de += D[n]*Gbar[n] + 0.5*D[n]*b[n]*D[n]
|
366 | 1 | tkerber | return de
|
367 | 1 | tkerber | |
368 | 1 | tkerber | def get_gbar_estimate(self,D,Gbar,b): |
369 | 1 | tkerber | gbar_est = (D*b) + Gbar |
370 | 1 | tkerber | self.write_log('Abs Gbar estimate ' + str(np.dot(gbar_est,gbar_est))) |
371 | 1 | tkerber | return gbar_est
|
372 | 1 | tkerber | |
373 | 1 | tkerber | def get_lambdas(self,b,Gbar): |
374 | 1 | tkerber | lamdas = np.zeros((len(b)))
|
375 | 1 | tkerber | |
376 | 1 | tkerber | D = -Gbar/b |
377 | 1 | tkerber | #absD = np.sqrt(np.sum(D**2))
|
378 | 1 | tkerber | absD = np.sqrt(np.dot(D, D)) |
379 | 1 | tkerber | |
380 | 1 | tkerber | eps = 1e-12
|
381 | 1 | tkerber | nminus = self.get_hessian_inertia(b)
|
382 | 1 | tkerber | |
383 | 1 | tkerber | if absD < self.radius: |
384 | 1 | tkerber | if not self.transitionstate: |
385 | 1 | tkerber | self.write_log('Newton step') |
386 | 1 | tkerber | return lamdas
|
387 | 1 | tkerber | else:
|
388 | 1 | tkerber | if nminus==1: |
389 | 1 | tkerber | self.write_log('Newton step') |
390 | 1 | tkerber | return lamdas
|
391 | 1 | tkerber | else:
|
392 | 1 | tkerber | self.write_log("Wrong inertia of Hessian matrix: %2.2f %2.2f "%(b[0],b[1])) |
393 | 1 | tkerber | |
394 | 1 | tkerber | else:
|
395 | 1 | tkerber | self.write_log("Corrected Newton step: abs(D) = %2.2f "%(absD)) |
396 | 1 | tkerber | |
397 | 1 | tkerber | if not self.transitionstate: |
398 | 1 | tkerber | # upper limit
|
399 | 1 | tkerber | upperlimit = min(0,b[0])-eps |
400 | 1 | tkerber | lowerlimit = upperlimit |
401 | 1 | tkerber | lamda = find_lamda(upperlimit,Gbar,b,self.radius)
|
402 | 1 | tkerber | lamdas += lamda |
403 | 1 | tkerber | else:
|
404 | 1 | tkerber | # upperlimit
|
405 | 1 | tkerber | upperlimit = min(-b[0],b[1],0)-eps |
406 | 1 | tkerber | lamda = find_lamda(upperlimit,Gbar,b,self.radius)
|
407 | 1 | tkerber | lamdas += lamda |
408 | 1 | tkerber | lamdas[0] -= 2*lamda |
409 | 1 | tkerber | |
410 | 1 | tkerber | return lamdas
|
411 | 1 | tkerber | |
412 | 1 | tkerber | |
413 | 1 | tkerber | |
414 | 1 | tkerber | def print_hessian(self): |
415 | 1 | tkerber | hessian = self.get_hessian()
|
416 | 1 | tkerber | n = len(hessian)
|
417 | 1 | tkerber | for i in range(n): |
418 | 1 | tkerber | for j in range(n): |
419 | 1 | tkerber | print "%2.4f " %(hessian[i][j]), |
420 | 1 | tkerber | print " " |
421 | 1 | tkerber | |
422 | 1 | tkerber | |
423 | 1 | tkerber | |
424 | 1 | tkerber | |
425 | 1 | tkerber | def get_hessian_inertia(self,eigenvalues): |
426 | 1 | tkerber | # return number of negative modes
|
427 | 1 | tkerber | self.write_log("eigenvalues %2.2f %2.2f %2.2f "%(eigenvalues[0], |
428 | 1 | tkerber | eigenvalues[1],
|
429 | 1 | tkerber | eigenvalues[2]))
|
430 | 1 | tkerber | n = 0
|
431 | 1 | tkerber | while eigenvalues[n]<0: |
432 | 1 | tkerber | n+=1
|
433 | 1 | tkerber | return n
|
434 | 1 | tkerber | |
435 | 1 | tkerber | def get_force_prediction(self,G): |
436 | 1 | tkerber | # return measure of how well the forces are predicted
|
437 | 1 | tkerber | Gbar = np.dot(G,np.transpose(self.V))
|
438 | 1 | tkerber | dGbar_actual = Gbar-self.old_gbar
|
439 | 1 | tkerber | dGbar_predicted = Gbar-self.gbar_estimate
|
440 | 1 | tkerber | |
441 | 1 | tkerber | f = np.dot(dGbar_actual,dGbar_predicted)/np.dot(dGbar_actual,dGbar_actual) |
442 | 1 | tkerber | self.write_log('Force prediction factor ' + str(f)) |
443 | 1 | tkerber | return f
|
444 | 1 | tkerber | |
445 | 1 | tkerber | def write_iteration(self,energy,G):pass |