def run_transition_search(eps, cold_ic, sd): # L96 EBM Parameters K = 50 S = 10 a0 = 0.5 a1 = 0.4 sigma = 1 / 180**4 F = 0.5 Tref = 270. delT = 60. alpha = 2. beta = 1. delta = 1. p = np.array([K, S, a0, a1, sigma, F, Tref, delT, alpha, beta, eps, delta]) if cold_ic: ic = cold_attractor transition_cb = de.DiscreteCallback(near_hot_attractor, de.terminate_b) else: ic = hot_attractor transition_cb = de.DiscreteCallback(near_cold_attractor, de.terminate_b) transition_search = l96_ebm_transition_search(p, ic, transition_cb, sd, transition_limit=100, dt=1, number_of_blocks=10000, block_length=1000) transition_search.run()
# Setting up SDEProblem Object prob = de.SDEProblem(numba_f, numba_g, ic, tspan, p, saveat=time_points) # Callbacks determine when we end integrations def entered_hot_condition(u, t, integrator): return np.any(np.array(u).flatten() > 295) def entered_cold_condition(u, t, integrator): return np.any(np.array(u)[K].flatten() < 258) if start_cold: entry_cb = de.DiscreteCallback(entered_hot_condition, de.terminate_b) else: entry_cb = de.DiscreteCallback(entered_cold_condition, de.terminate_b) # Creating Save directory if not os.path.exists(sd): os.makedirs(sd) print(f'Made directory at {sd}') # Looker object setup looker = SolutionObserver(prob.p) def get_max_end_number(sd): max_end_number = 0 for f in os.listdir(sd):
sigma = 1 / 180**4 F = 8. Tref = 270. delT = 60. alpha = 2. beta = 1. delta = 1. p = np.array([K, S, a0, a1, sigma, F, Tref, delT, alpha, beta, eps, delta]) # Set Initial Condition and callback from experiment_utilities import get_random_hot_point, get_random_cold_point, get_entered_hot_condition, get_entered_cold_condition if start_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 SDEProblem Object prob = de.SDEProblem(numba_f, numba_additive_g, ic, tspan, p, saveat=time_points) # Creating Save directory if not os.path.exists(sd):
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
numba_g = numba.jit(g) ######################################################################## ### Callback test for detecting transition ######################################################################## def hot_callback_condition(u, t, integrator): return np.any(np.array(u).flatten() > 270) def affect_b(integrator): return de.terminate_b(integrator) cb = de.DiscreteCallback(hot_callback_condition, de.terminate_b) ######################################################################## ### Functions that save/look at results ######################################################################## def save_directory(): "Returns different if we're on cluster or not" if str(Path.home()) == '/Users/cfn18': return '/Users/cfn18/Documents/PhD-Work/Third-Year/Instanton-Work/L96-EBM-Instanton/Stochastic-Model/Transitions/Transition-Time-Test/Results-Corrected-S-EM-TEST/' else: return '/rds/general/user/cfn18/home/Instantons/L96-EBM-Instanton/Stochastic-Model/Transitions/Transition-Time-Test/Long-Timing-Results/' def experiment_header(p): eps, delta = p