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 readOMF(path): # Read OMF file header = magneto.OMFHeader() mat = magneto.readOMF(path, header) # Convert (header, mat) to VectorField. mesh = RectangularMesh((header.xnodes, header.ynodes, header.znodes), (header.xstepsize, header.ystepsize, header.zstepsize)) vector_field = VectorField(mesh) vector_field.assign(mat) logger.debug("Read file %s", path) return vector_field