def minimize(self, max_dpns = 0.01, samples = 10, h_max = 1e-5, h_min = 1e-16): """ Minimizes the energy with a direct minimization strategy. """ counter = 0 # TODO make use of stephandlers for logging h = self.state.h dpnslist = [] log = ScreenLogMinimizer() # Reset step self.state.step = 0 while len(dpnslist) < samples or max(dpnslist) > max_dpns: # Calculate next M and dM for minimization step M_next = self.state.minimizer_M(h) dM = self.state.minimizer_dM counter += 2 # Get s^n-1 for step-size calculation M_diff = VectorField(self.mesh) M_diff.assign(M_next) M_diff.add(self.state.M, -1.0) # Set next M self.state.y = M_next self.state.finish_step() # normalize, TODO really need to do this every step? self.state.flush_cache() # Calculate deg per ns # TODO M.absMax might be the wrong choice if different materials are in use dp_timestep = (180.0 / math.pi) * math.atan2(M_diff.absMax(), self.state.M.absMax()) dpns = abs(1e-9 * dp_timestep / h) dpnslist.append(dpns) if len(dpnslist) > samples: dpnslist.pop(0) self.state.deg_per_ns_minimizer = dpns # Get y^n-1 for step-size calculation dM_diff = VectorField(self.mesh) dM_diff.assign(self.state.minimizer_dM) dM_diff.add(dM, -1.0) # Next stepsize (Alternate h1 and h2) try: if (self.state.step % 2 == 0): h = M_diff.dotSum(M_diff) / M_diff.dotSum(dM_diff) else: h = M_diff.dotSum(dM_diff) / dM_diff.dotSum(dM_diff) except ZeroDivisionError, ex: h = h_max h_sign = math.copysign(1, h) h = max(min(abs(h), h_max), h_min) * h_sign if (self.state.step % 100 == 0): log.handle(self.state) # Update step self.state.step += 1
def minimize(self, max_dpns = 0.01, samples = 10, h_max = 1e-5, h_min = 1e-16): """ Minimizes the energy with a direct minimization strategy. """ # TODO make use of stephandlers for logging h = self.state.h dpnslist = [] log = ScreenLogMinimizer() # Reset step self.state.step = 0 while len(dpnslist) < samples or max(dpnslist) > max_dpns: # Calculate next M and dM for minimization step M_next = self.state.minimizer_M(h) dM = self.state.minimizer_dM # Get s^n-1 for step-size calculation M_diff = VectorField(self.mesh) M_diff.assign(M_next) M_diff.add(self.state.M, -1.0) # Set next M self.state.y = M_next self.state.finish_step() # normalize, TODO really need to do this every step? self.state.flush_cache() # Calculate deg per ns # TODO M.absMax might be the wrong choice if different materials are in use dp_timestep = (180.0 / math.pi) * math.atan2(M_diff.absMax(), self.state.M.absMax()) dpns = abs(1e-9 * dp_timestep / h) dpnslist.append(dpns) if len(dpnslist) > samples: dpnslist.pop(0) self.state.deg_per_ns_minimizer = dpns # Get y^n-1 for step-size calculation dM_diff = VectorField(self.mesh) dM_diff.assign(self.state.minimizer_dM) dM_diff.add(dM, -1.0) # Next stepsize (Alternate h1 and h2) try: if (self.state.step % 2 == 0): h = M_diff.dotSum(M_diff) / M_diff.dotSum(dM_diff) else: h = M_diff.dotSum(dM_diff) / dM_diff.dotSum(dM_diff) except ZeroDivisionError, ex: h = h_max h_sign = math.copysign(1, h) h = max(min(abs(h), h_max), h_min) * h_sign if (self.state.step % 100 == 0): log.handle(self.state) # Update step self.state.step += 1
def calculate_strayfield(mesh, M, object_list): # mesh number of nodes and node size nx, ny, nz = mesh.num_nodes dx, dy, dz = mesh.delta # Calculate stray field for one object def calculate(obj, cub_M): cub_size = (10e-9, 10e-9, 10e-9) cub_center = (0,0,0) cub_inf = magneto.INFINITY_NONE return CalculateStrayfieldForCuboid(nx, ny, nz, dx, dy, dz, cub_M, cub_center, cub_size, cub_inf) # Return the sum of the stray fields of all objects. H = VectorField(mesh) H.clear() for obj in object_list: H.add(calculate(obj, M)) return H
def calculate_strayfield(mesh, M, object_list): # mesh number of nodes and node size nx, ny, nz = mesh.num_nodes dx, dy, dz = mesh.delta # Calculate stray field for one object def calculate(obj, cub_M): cub_size = (10e-9, 10e-9, 10e-9) cub_center = (0, 0, 0) cub_inf = magneto.INFINITY_NONE return CalculateStrayfieldForCuboid(nx, ny, nz, dx, dy, dz, cub_M, cub_center, cub_size, cub_inf) # Return the sum of the stray fields of all objects. H = VectorField(mesh) H.clear() for obj in object_list: H.add(calculate(obj, M)) return H