@@ -160,10 +160,10 @@ def __init__(self, ChainObj,
160
160
# band, forces, distances, rhs_fun, action_fun,
161
161
# n_images, n_dofs_image,
162
162
maxSteps = 1000 ,
163
- maxCreep = 5 , actionTol = 1e-10 , forcesTol = 1e-6 ,
164
- etaScale = 1.0 , dEta = 2 , minEta = 0.001 ,
163
+ maxCreep = 6 , actionTol = 1e-10 , forcesTol = 1e-6 ,
164
+ etaScale = 1e-6 , dEta = 4. , minEta = 1e-6 ,
165
165
# perturbSeed=42, perturbFactor=0.1,
166
- nTrail = 10 , resetMax = 20
166
+ nTrail = 13 , resetMax = 20
167
167
):
168
168
# super(FSIntegrator, self).__init__(band, rhs_fun)
169
169
@@ -188,17 +188,16 @@ def __init__(self, ChainObj,
188
188
self .n_dofs_image = self .ChainObj .n_dofs_image
189
189
# self.forces_prev = np.zeros_like(band).reshape(n_images, -1)
190
190
# self.G :
191
- self .forces = self .ChainObj .forces
191
+ self .forces = self .ChainObj .G
192
192
self .distances = self .ChainObj .distances
193
- self .forces_old = np .zeros_like (self .ChainObj .forces )
193
+ self .forces_old = np .zeros_like (self .ChainObj .G )
194
194
195
195
# self.band should be just a reference to the band in the ChainObj
196
196
self .band = self .ChainObj .band
197
- self .band_old = np .zeros_like (self .band )
197
+ self .band_old = np .copy (self .band )
198
198
199
199
def run_for (self , n_steps ):
200
200
201
- t = 0.0
202
201
nStart = 0
203
202
exitFlag = False
204
203
totalRestart = True
@@ -214,19 +213,25 @@ def run_for(self, n_steps):
214
213
215
214
INNER_DOFS = slice (self .n_dofs_image , - self .n_dofs_image )
216
215
216
+ # Save data of energies on every step
217
+ self .ChainObj .tablewriter .save ()
218
+ self .ChainObj .tablewriter_dm .save ()
219
+
220
+ np .save (self .ChainObj .name + '_init.npy' , self .ChainObj .band )
221
+
217
222
while not exitFlag :
218
223
219
224
if totalRestart :
220
- if self .step > 0 :
225
+ if self .i_step > 0 :
221
226
print ('Restarting' )
222
227
self .band [:] = self .band_old
223
228
224
229
# Compute from self.band. Do not update the step at this stage:
225
230
# This step updates the forces and distances in the G array of the nebm module,
226
231
# using the current band state self.y
227
- # TODO: remove time from chain method rhs
228
- # make a specific function to update G??
229
- self .rhs ( t , self .y )
232
+ # TODO: make a specific function to update G??
233
+ print ( 'Computing forces' )
234
+ self .ChainObj . nebm_step ( self .band , ensure_zero_extrema = True )
230
235
self .action = self .ChainObj .compute_action ()
231
236
232
237
# self.step += 1
@@ -250,13 +255,17 @@ def run_for(self, n_steps):
250
255
self .trailAction
251
256
252
257
self .ChainObj .nebm_step (self .band , ensure_zero_extrema = True )
253
- self .action = self .ChainObj .action_fun ()
258
+ self .action = self .ChainObj .compute_action ()
254
259
255
260
self .trailAction [nStart ] = self .action
256
261
nStart = next (trailPool )
257
262
258
263
self .i_step += 1
259
264
265
+ # Save data of energies on every step
266
+ self .ChainObj .tablewriter .save ()
267
+ self .ChainObj .tablewriter_dm .save ()
268
+
260
269
# Getting averages of forces from the INNER images in the band (no extrema)
261
270
# (forces are given by vector G in the chain method code)
262
271
# TODO: we might use all band images, not only inner ones, although G is zero at the extrema
@@ -268,10 +277,14 @@ def run_for(self, n_steps):
268
277
# Average step difference between trailing action and new action
269
278
deltaAction = (np .abs (self .trailAction [nStart ] - self .action )) / self .nTrail
270
279
280
+ # print('trail Actions', self.trailAction)
281
+
271
282
# Print log
272
283
print (f'Step { self .i_step } ⟨RMS(G)〉= { mean_rms_G_norms_per_image :.5e} ' ,
273
284
f'deltaAction = { deltaAction :.5e} Creep n = { creepCount :>3} resetC = { resetCount :>3} ' ,
274
- f'eta = { eta :>5.4e} ' )
285
+ f'eta = { eta :>5.4e} '
286
+ f'action = { self .action :>5.4e} action_old = { self .action_old :>5.4e} '
287
+ )
275
288
276
289
# 10 seems like a magic number; we set here a minimum number of evaulations
277
290
if (nStart > self .nTrail * 10 ) and (deltaAction < self .actionTol ):
@@ -291,17 +304,25 @@ def run_for(self, n_steps):
291
304
eta = eta / (self .dEta * self .dEta )
292
305
293
306
# If eta is too small, reset and start again
294
- if (eta < 1e-3 ):
295
- print ('' )
307
+ if (eta < self . minEta ):
308
+ # print('')
296
309
resetCount += 1
297
310
# bestAction = self.action_old
298
- self .refine_path (self .ChainObj .distances , self .band ) # Resets the path to equidistant structures (smoothing kinks?)
311
+ print ('Refining path' )
312
+ self .refine_path (self .ChainObj .path_distances , self .band ) # Resets the path to equidistant structures (smoothing kinks?)
299
313
# PathChanged[:] = True
300
314
301
315
if resetCount > self .resetMax :
302
- print ('Failed to converge!' )
303
- # Otherwise, just
316
+ print ('Failed to converge! Reached max number of restarts' )
317
+ exitFlag = True
318
+ break # creep loop
319
+
320
+ totalRestart = True
321
+ break # creep loop
322
+
323
+ # Otherwise, just start again with smaller alpha
304
324
else :
325
+ print ('Decreasing alpha' )
305
326
self .band [:] = self .band_old
306
327
self .forces [:] = self .forces_old
307
328
# If action decreases, move to next creep step
@@ -318,20 +339,22 @@ def run_for(self, n_steps):
318
339
# END creep while loop
319
340
320
341
# After creep loop:
321
- self . eta = self . eta * self .dEta
342
+ eta = eta * self .dEta
322
343
resetCount = 0
323
344
345
+ np .save (self .ChainObj .name + '.npy' , self .ChainObj .band )
346
+
324
347
# Taken from the string method class
325
- def refine_path (self , distances , band ):
348
+ def refine_path (self , path_distances , band ):
326
349
"""
327
350
"""
328
- new_dist = np .linspace (distances [0 ], distances [- 1 ], distances .shape [0 ])
351
+ new_dist = np .linspace (path_distances [0 ], path_distances [- 1 ], path_distances .shape [0 ])
329
352
# Restructure the string by interpolating every spin component
330
353
# print(self.integrator.y[self.n_dofs_image:self.n_dofs_image + 10])
331
354
bandrs = band .reshape (self .n_images , self .n_dofs_image )
332
355
for i in range (self .n_dofs_image ):
333
356
334
- cs = si .CubicSpline (distances , bandrs [:, i ])
357
+ cs = si .CubicSpline (path_distances , bandrs [:, i ])
335
358
bandrs [:, i ] = cs (new_dist )
336
359
337
360
# def set_options(self):
0 commit comments