def single_block_search(self): print() print( f'Search number {self.current_block + 1}/{self.number_of_blocks}. Solving for {self.tspan}.\n' ) print() start = tm.time() # CPU Clock begins # Stochastic integration using diffeqpy self.sol = de.solve(self.prob, de.SOSRI(), callback=self.transition_cb, saveat=self.dt, maxiters=self.max_iters) # Update results if we find a transition if self.sol.retcode == 'Terminated': print( f'Found transition in search number {self.current_block + 1}. Saving Results.\n' ) # CPU Time Since Last Success end = tm.time() cpu_time = end - start # Time results updated self.experiment_time_results['cpu_times(s)'].append(cpu_time) self.experiment_time_results['residence_times'].append( self.current_residence_time) self.experiment_time_results['number_of_transitions'] += 1 # Saving Path and Residence time print(self.current_residence_time) self.looker.look(self.sol) self.looker._parameters[ 'residence_time'] = self.current_residence_time print(self.looker.observations.attrs) self.save_results() # Check if we have found enough samples and can stop if self.experiment_time_results[ 'number_of_transitions'] == self.transition_limit: print( f'Found {self.transition_limit} transitions - will quit.') sys.exit() # Reset Experiment self.last_successful_block = self.current_block self.prob = de.remake(self.prob, u0=self.ic, tspan=self.tspan) # If we don't find a transition, remake the problem else: print(f'Exited due to {self.sol.retcode}\n') self.prob = de.remake(self.prob, u0=self.sol.u[-1], tspan=self.tspan) self.current_block += 1 return
maxiters=max_iters) # If we find a transtions, save the result if sol.retcode == 'Terminated': #i.e. callback ended the integration, so we save results end = tm.time() cpu_time = end - start integration_time = sol.t[-1] update_results() save_results() last_success_block = i # Check if we have found enough samples and can stop if experiment_results['number_of_transitions'] == 100: print(f'Found 100 transitions - will quit.') quit() elif sol.retcode == 'MaxIters': print( f'Integration ended due to {sol.retcode}. Will reset and try increasing max_iters.\n' ) max_iters = max_iters * 2 else: print(f'Exited due to {sol.retcode}\n') # Reset Experiment ic = get_random_point(cold_file) start = tm.time() prob = de.remake(prob, u0=ic, tspan=tspan)
pd = save_directory + 'cold_ic/' else: pd = save_directory + 'hot_ic/' sd = pd + f'{run_number}/' if not os.path.exists(sd): os.makedirs(sd) # Setting up diffeqpy solver t = 0. tspan = (0., block_length) prob = de.SDEProblem(numba_f, numba_g, u0, tspan, p) looker = SolutionObserver(prob.p) for i in range(number_of_blocks): print(prob.tspan) # Integrate sol = de.solve(prob, de.SRIW1(), reltol=1e-3, abstol=1e-3, saveat=0.1) looker.look(sol) # Save Observations looker.dump(sd) # Update Step t += block_length prob = de.remake(prob, u0=sol.u[-1], tspan=(t, t + block_length))
def run_experiment(S=10, epsilon=5, delta=1, cold=True): """ S, float - reduced solar constant. epsilon, float - noise strength. cold, boolean - whether we start on cold attractor or not. """ #################################### ### Fixed Experiment Settings #################################### # Time Set Up end_time = 1000. # Length of integration where we look for a transitions dt = 1.0 # How often output is saved, since we're not saving integrations it can be coarse number_of_searches = int(1.e4) # How many integration runs we do tspan = (0., end_time) max_iters = 1.e20 # Fixed L96 EBM Parameters K = 50 a0 = 0.5 a1 = 0.4 sigma = 1 / 180**4 F = 8. Tref = 270. delT = 60. alpha = 2. beta = 1. p = np.array( [K, S, a0, a1, sigma, F, Tref, delT, alpha, beta, epsilon, delta]) # Initialising Dictionary to Store Experiment Results global experiment_results global cpu_time global integration_time experiment_results = { 'epsilon': epsilon, 'delta': delta, 'S': S, 'cpu_times(s)': [], 'integration_times': [], 'number_of_transitions': 0, 'parameters': p } # Setting IC & Callbacks, File locations will need updating for cluster run if cold: ic = get_random_cold_point(S=S) cb_condition = get_entered_hot_condition(S, K) cb = de.DiscreteCallback(cb_condition, de.terminate_b) else: ic = get_random_hot_point(S=S) cb_condition = get_entered_cold_condition(S, K) cb = de.DiscreteCallback(cb_condition, de.terminate_b) # Setting up diffeqpy solver prob = de.SDEProblem(numba_f, numba_multiplicative_g, ic, tspan, p) #################################### ### Looped Search for Transitions #################################### experiment_header(epsilon, delta, S, cold) start = tm.time() # CPU Clock begins last_successful_block = -1 for i in range(number_of_searches): print() print( f'Search number {i + 1}/{number_of_searches}. Solving for {prob.tspan}.\n' ) # Integrate only saving T variable sol = de.solve(prob, de.SOSRI(), saveat=dt, callback=cb, maxiters=max_iters) # If we find a transition, save the result & reset experiment if sol.retcode == 'Terminated': print( f'Found transition in search number {i + 1}. Saving Results.\n' ) # CPU Time Since Last Success end = tm.time() cpu_time = end - start # Integration Time Since Last Success completed_blocks_since_last_success = i - (last_successful_block + 1) block_length = end_time integration_time_in_this_block = sol.t[-1] integration_time = completed_blocks_since_last_success * block_length + integration_time_in_this_block update_results() save_results(pd=experiment_results_pd, S=S, epsilon=epsilon, cold=cold, delta=delta) # Check if we have found enough samples and can stop if experiment_results['number_of_transitions'] == 100: print(f'Found 100 transitions - will quit.') quit() # Reset Experiment start = tm.time() last_successful_block = i if cold: ic = get_random_cold_point(S=S) else: ic = get_random_hot_point(S=S) prob = de.remake(prob, u0=ic, tspan=tspan) # If we don't find a transition, remake the problem else: print(f'Exited due to {sol.retcode}\n') prob = de.remake(prob, u0=sol.u[-1], tspan=(0, end_time)) return
def run_l96_ebm_multiplicative(p, u0, block_length, number_of_blocks, sd=None, dt=0.1): """ Use diffeqpy solver to stochastically integrate the L96 EBM Equations w multiplicative noise. Arguments ------------ p, list: Parameters for the model run. ic, np array: The intial condition for the model run. block_length, int: How often model output is saved. number_of_blocks, int: How many times we save model output. Note no. of obs = (blocklength * number of blocks)/dt sd, string: Where model output is saved. dt, float: Time between model observations. Note integrator uses adaptive timestepper that may be smaller. """ # Setting up diffeqpy solver t = 0. tspan = (0., block_length) prob = de.SDEProblem(numba_f, numba_g, u0, tspan, p) # Creating Observer Object to do saving looker = SolutionObserver(prob.p) # Loop with intermitment saves for i in range(number_of_blocks): print(f'Solving for {prob.tspan}\n') # Integrate sol = de.solve(prob, de.SRIW1(), reltol=1e-3, abstol=1e-3, saveat=dt) looker.look(sol) # Save Observations if sd is not None: looker.dump(sd) # Update Step t += block_length prob = de.remake(prob, u0=sol.u[-1], tspan=(t, t + block_length)) # Output results if no save directory if sd is None: return looker.observations else: return