def post_iteration(self): """Runs after each iteration""" self.normval = get_norm(self.workflow._system.vec['f'], self._norm_order) if self.iprint > 0: self.print_norm('NLN_GS', self.current_iteration-1, self.normval, self.norm0)
def _norm(self): """ Computes the norm of the linear residual """ system = self._system system.rhs_vec.array[:] = 0.0 system.applyJ(system.vector_vars.keys()) system.rhs_vec.array[:] *= -1.0 system.rhs_vec.array[:] += system.rhs_buf[:] return get_norm(system.rhs_vec)
def start_iteration(self): """ Commands run before any iterations """ self.current_iteration = 0 self.normval = 1.e99 self.norm0 = 1.e99 self.run_iteration() self.normval = get_norm(self.workflow._system.vec['f'], self._norm_order) self.norm0 = self.normval if self.normval != 0.0 else 1.0 if self.iprint > 0: self.print_norm('NLN_GS', 0, self.normval, self.norm0)
def execute(self): """ General Newton's method. """ if MPI: if self.workflow._system.mpi.comm == MPI.COMM_NULL: return system = self.workflow._system options = self.gradient_options fvec = system.vec['f'] dfvec = system.vec['df'] uvec = system.vec['u'] iterbase = self.workflow._iterbase() nstring = 'NEWTON' # perform an initial run system.evaluate(iterbase, case_uuid=Case.next_uuid()) f_norm = get_norm(fvec) f_norm0 = f_norm if self.iprint > 0: self.print_norm(nstring, 0, f_norm, f_norm0) itercount = 0 alpha = self.alpha while itercount < self.max_iteration and f_norm > self.atol and \ f_norm/f_norm0 > self.rtol: system.calc_newton_direction(options=options) #print "LS 1", uvec.array, '+', dfvec.array uvec.array += alpha*dfvec.array # Just evaluate the model with the new points system.evaluate(iterbase, case_uuid=Case.next_uuid()) f_norm = get_norm(fvec) if self.iprint > 0: self.print_norm(nstring, itercount+1, f_norm, f_norm0) itercount += 1 ls_itercount = 0 # Backtracking Line Search while ls_itercount < self.ls_max_iteration and \ f_norm > self.ls_atol and \ f_norm/f_norm0 > self.ls_rtol: alpha *= 0.5 uvec.array -= alpha*dfvec.array # Just evaluate the model with the new points system.evaluate(iterbase, case_uuid=Case.next_uuid()) f_norm = get_norm(fvec) if self.iprint> 1: self.print_norm('BK_TKG', itercount+1, f_norm, f_norm/f_norm0, indent=1, solver='LS') ls_itercount += 1 # Reset backtracking alpha = self.alpha # Need to make sure the whole workflow is executed at the final # point, not just evaluated. self.pre_iteration() self.run_iteration() self.post_iteration() if self.iprint > 0: self.print_norm(nstring, itercount, f_norm, f_norm0, msg='Converged')