22import warnings
33from .integrators import BaseIntegrator
44from .integrators import euler_step , runge_kutta_step
5+ from itertools import cycle
56
67import fidimag .extensions .nebm_clib as nebm_clib
78
@@ -149,7 +150,7 @@ def _step(self, t, y, h, f):
149150class FSIntegrator (BaseIntegrator ):
150151 """A step integrator considering the action of the band
151152 """
152- def __init__ (self , band , forces , action , rhs_fun , n_images , n_dofs_image ,
153+ def __init__ (self , band , forces , action , rhs_fun , action_fun , n_images , n_dofs_image ,
153154 max_steps = 1000 ,
154155 maxCreep = 5 , eta_scale = 1.0 , stopping_dE = 1e-6 , dEta = 2 ,
155156 etaMin = 0.001 ,
@@ -158,6 +159,8 @@ def __init__(self, band, forces, action, rhs_fun, n_images, n_dofs_image,
158159 ):
159160 super (FSIntegrator , self ).__init__ (band , rhs_fun )
160161
162+ self .action_fun = action_fun
163+
161164 self .i_step = 0
162165 self .n_images = n_images
163166 self .n_dofs_image = n_dofs_image
@@ -175,15 +178,18 @@ def run_until(self, t):
175178
176179 def run_for (self , n_steps ):
177180
181+ t = 0.0
178182 nStart = 0
179183 exitFlag = False
180184 totalRestart = True
181185 resetCount = 0
182186 creepCount = 0
183- self .trailE = np .zeros (nTrail )
187+ self .trailAction = np .zeros (nTrail )
184188 trailPool = cycle (range (nTrail )) # cycle through 0,1,...,(nTrail-1),0,1,...
185189 eta = 1.0
186190
191+ INNER_DOFS = slice (self .n_dofs_image , - self .n_dofs_image )
192+
187193 while not exitFlag :
188194
189195 if totalRestart :
@@ -194,15 +200,17 @@ def run_for(self, n_steps):
194200 # Compute from self.band. Do not update the step at this stage:
195201 # This step updates the forces in the G array of the nebm module,
196202 # using the current band state self.y
203+ # TODO: remove time from chain method rhs
204+ # make a specific function to update G??
197205 self .rhs (t , self .y )
198-
206+ self . action = self . action_fun ()
199207
200208 # self.step += 1
201- self .gradE_last [:] = - self .field # Scale field??
202- self .gradE_last [~ _material ] = 0.0
203- self .gradE [:] = self .gradE_last
204- self .totalE_last = self .totalE
205- self .trailE [nStart ] = self .totalE
209+ self .forces_last [:] = self .forces # Scale field??
210+ # self.gradE_last[~_material] = 0.0
211+ # self.gradE[:] = self.gradE_last
212+ self .action_last = self .action
213+ self .trailAction [nStart ] = self .action
206214 nStart = next (trailPool )
207215 eta = 1.0
208216 totalRestart = False
@@ -212,10 +220,28 @@ def run_for(self, n_steps):
212220 # Creep stage: minimise with a fixed eta
213221 while creepCount < maxCreep :
214222 # Update spin. Avoid pinned or zero-Ms sites
215- self .y [:] = self .y_last - eta * eta_scale * self .forces_images
223+ self .y [:] = self .y_last + eta * eta_scale * self .forces
224+ normalise_spins (self .y )
225+
226+ self .trailAction
227+
228+ self .rhs (t , self .y )
229+ self .action = self .action_fun ()
230+
231+ self .trailAction [nStart ] = self .action
232+ nStart = next (trailPool )
216233
234+ bandNormSquared = 0.0
235+ # Getting averages of forces from the INNER images in the band (no extrema)
236+ # (forces are given by vector G in the chain method code)
237+ G_norms = np .linalg .norm (self .forces [INNER_DOFS ].reshape (- 1 , 3 ), axis = 1 )
238+ # Compute the root mean square per image
239+ rms_G_norms_per_image = np .sqrt (np .mean (G_norms .reshape (self .n_images - 2 , - 1 ), axis = 1 ))
240+ mean_rms_G_norms_per_image = np .mean (rms_G_norms_per_image )
217241
218242
243+ # 10 seems like a magic number; we set here a minimum number of evaulations
244+ if (nStart > nTrail * 10 ) and :
219245
220246
221247
0 commit comments