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
Пример #5
0
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