예제 #1
0
    def simulate(self):
        """
        Simulate the mechanism with RMS
        """
        if not HAS_RMS:
            self.logger.error('Missing diffeqpy and/or pyrms. Please ensure these dependencies were'
                              'correctly installed.')

        if len(self.observable_list):
            self.logger.info('Running a simulation with SA using RMSConstantTP...')
        else:
            self.logger.info('Running a simulation using RMSConstantTP...')

        solver = de.CVODE_BDF()
        t_final = convert_termination_time_to_seconds(self.rmg['reactors'][0]['termination_time'])

        if len(self.observable_list):
            react = rms.Reactor(self.domain, self.y0, (0.0, t_final), forwardsensitivities=True, p=self.p)
            atol = [self.atol] * self.domain.indexes[-1]  # set atol for the variables being simulated
            total_variables = self.domain.indexes[-1] + len(self.p) * self.domain.indexes[-1]
            atol.extend([self.sa_atol] * (total_variables - self.domain.indexes[-1]))  # set atol for SA
            self.sol = de.solve(react.ode, solver, abstol=atol, reltol=self.rtol)
        else:
            react = rms.Reactor(self.domain, self.y0, (0.0, t_final), forwardsensitivities=False, p=self.p)
            self.sol = de.solve(react.ode, solver, abstol=self.atol, reltol=self.rtol)
        self.bsol = rms.Simulation(self.sol, self.domain)
    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
예제 #3
0
 def test_simulate(self):
     phaseDict = rms.readinput("pyrms/testing/superminimal.rms")
     spcs = phaseDict["gas"]["Species"]
     rxns = phaseDict["gas"]["Reactions"]
     ig = rms.IdealGas(spcs, rxns, name="gas")
     initialconds = {"T": 1000.0, "P": 10.0e5, "H2": 2.0, "O2": 1.0}
     domain, y0 = rms.ConstantTPDomain(phase=ig, initialconds=initialconds)
     react = rms.Reactor(domain, y0, (0.0, 10.001))
     sol = de.solve(react.ode, de.CVODE_BDF(), abstol=1e-20, reltol=1e-8)
     sim = rms.Simulation(sol, domain)
     self.assertAlmostEqual(rms.molefractions(sim, "H2", 3.0),
                            0.34445669,
                            places=3)
####################################
### Running Experiment
####################################

experiment_header([epsilon, delta])
start = tm.time()

for i in range(number_of_searches):  # Looped Search for Transitions

    print(f'Solving for {prob.tspan}\n')

    # Integrate only saving T variable
    sol = de.solve(prob,
                   de.EM(),
                   saveat=dt,
                   callback=cb,
                   save_idxs=np.array([K + 1]),
                   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:
예제 #5
0
    return f(u, p, t)


if __name__ == '__main__':
    u0 = [1.0, 0.0, 0.0]
    #u0 = 0.5
    jul_f = Main.eval(
        "(u,p,t)->[p[1]*(u[2]-u[1]),u[1]*(p[2]-u[3])-u[2], u[1]*u[2]-p[3]*u[3]]"
    )
    #jul_f = Main.eval("(u,p,t) -> -u")
    tspan = (0., 100.)
    p = [10.0, 28.0, 8 / 3]
    for i in range(10):
        t_start = time.time()
        prob = de.ODEProblem(jul_f, u0, tspan, p)
        sol = de.solve(prob)
        t_end = time.time()
        with open('out.txt', 'a') as f_out:
            s = f'julia took {t_end-t_start}\n'
            f_out.write(s)
            print(s)
    for i in range(10):
        t_start = time.time()
        eff_p = solve_ivp(wrapped, tspan, u0, method='BDF')
        t_end = time.time()
        with open('out.txt', 'a') as f_out:
            s = f'scipy took {t_end - t_start}\n'
            f_out.write(s)
            print(s)
    #prob = de.ODEProblem(jul_f, u0, tspan, p)
    #sol = de.solve(prob)
adj = nx.to_numpy_array(G, dtype=int)


if __name__ == "__main__":

    ind_transition = int(T_trans/dt)
    theta_0 = np.random.uniform(-pi, pi, size=N)
    omega_0 = np.random.normal(mu, sigma, size=N)

    tspan = (0.0, T)
    p = [K/N, N, omega_0, adj]

    start = time()

    for i in range(len(K)):
        p[0] = K[i] / N
        prob = de.ODEProblem(julia_f, theta_0, tspan, p)
        sol = de.solve(prob, de.Tsit5(), saveat=dt, abstol=1e-6, reltol=1e-6);

        print("K = {:.3f}".format(K[i]))

    print("pyjulia Done in {} seconds.".format(time() - start))
    
    
    # print(type(theta))
    # print(sol.shape)
    # print(type(sol.t), len(sol.t))
    # print(type(sol.u), len(sol.u), len(sol.u[0]), type(sol.u[0]))
    

# print(type(sol.t), type(sol.u), type(sol.u[0]))

looker.dump_count = get_max_end_number(sd)

##########################################
## Looped Search For Transitions
##########################################

for i in range(number_of_searches):
    print(
        f'Solving for {prob.tspan}. Search number {i + 1} of {number_of_searches}.\n'
    )

    # Integrate
    sol = de.solve(prob,
                   de.SRIW1(),
                   reltol=1e-3,
                   abstol=1e-3,
                   callback=entry_cb,
                   maxiters=1e20)
    print(f'Integration ended due to {sol.retcode}\n')

    # If callback ended the integration, save results
    if sol.retcode == 'Terminated':
        print(f'Found Transition during search number {i + 1}.')
        looker.look(sol)
        looker.dump(sd, name=file_name)

    # Reset Integration
    prob = de.remake(prob, u0=ic, tspan=tspan)
            max_end_number = int(end_number)
    return max_end_number


looker.dump_count = get_max_end_number(sd)

##########################################
## Looped Search For Transitions
##########################################

from experiment_utilities import experiment_header
experiment_header(eps, S, start_cold)

for i in range(number_of_searches):
    print(
        f'Solving for {prob.tspan}. Search number {i + 1} of {number_of_searches}.\n'
    )

    # Integrate
    sol = de.solve(prob, de.SOSRI(), callback=cb, maxiters=1e20)
    print(f'Integration ended due to {sol.retcode}\n')

    # If callback ended the integration, save results
    if sol.retcode == 'Terminated':
        print(f'Found Transition during search number {i + 1}.')
        looker.look(sol)
        looker.dump(sd, name=file_name)

    # Reset Integration
    prob = de.remake(prob, u0=ic, tspan=tspan)
예제 #9
0
            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))
예제 #10
0
MaxDelay = max(Delay)

DefaultStartTime = 0.0
DefaultVPEndTime = 1000.0
tspan = (DefaultStartTime, DefaultVPEndTime)

vpinit = [
    VP_tau1, VP_tau2, VP_tau3, VP_Gin, VP_di, VP_sig1, VP_a1, VP_r1, VP_sig2,
    VP_a2, VP_sig4, VP_U0, VP_a4, VP_sig5, VP_a5, VP_r5, 1
]

tmph, tmp0 = initData(MaxDelay)
vp0 = vpinit + list(tmph)
u0 = tmp0
prob0 = de.DDEProblem(mmodel, u0, history, tspan, p=vp0)
sol0 = de.solve(prob0)

##############################################
vp1 = vp0
u1 = u0
tspan1 = (DefaultStartTime, 500)
prob1 = de.DDEProblem(mmodel, u1, history, tspan1, p=vp1)
sol1 = de.solve(prob1)
ut1 = np.transpose(sol1.u)

tmp = SoltoInit(sol1.t, ut1, MaxDelay, 500)
vp2 = vpinit + list(tmp)
vp2[5] = 1.2 * vp2[5]
u2 = sol1.u[len(sol1.u) - 1]
tspan2 = (500, 1000)
prob2 = de.DDEProblem(mmodel, u2, history, tspan1, p=vp2)
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
예제 #12
0
def electron_onerxn(params,
                    protocol,
                    times,
                    num_electrons=1,
                    capacitance_func=lambda x: 1,
                    u0=[0.5, 0.0],
                    du0=[0.0, 0.0]):
    """Simulate current data from electron transfer reaction.

    Parameters
    ----------
    params : list
        A list containing the parameter values. The first elements should take
        the form [e_0, alpha, k_0, rho, zeta, gamma,], followed by any extra
        parameters required for the capacitance model.
    protocol : function
        Function which takes as input times (float or 1d np.ndarray) and
        returns the value of the potential at that time
    times : np.ndarray
        Time points on which to solve for the current
    num_electrons : int, optional (1)
        Integer number of electrons transferred per reaction
    capacitance_func : function, optional (constant)
        The capacitance model. The first, required argument is the real
        potential, subsequent optional arguments are extra capacitance
        constants which must then be appended to params. Example of third order
        polynomial model for capacitive current:

        def capacitance_func(e, c1, c2, c3):
            return 1 + c1 * e + c2 * e**2 + c3 * e**3

        By default, the capacitance function is just a constant 1, which
        corresponds to a single parameter capacitance model with the
        capacitance parameter gamma from params.
    u0 : list, optional ([0.5, 0.0])
        Initial conditions for [theta, i]. Corresponds to t=0, not the first
        point in times
    du0 : list, optional ([0.0, 0.0])
        Initial conditions for [dtheta/dt, di/dt]. Corresponds to t=0, not the
        first point in times

    Returns
    -------
    np.ndarray
        Current over time
    np.ndarray
        Proportion of A over time
    """

    def f(du, u, p, t):
        """Calculate the two equations.

        Parameters
        ----------
        du : list
            time derivatives, [dtheta/dt, di/dt]
        u : list
            variables, [theta, i]
        p : list
            Model parameters
        t : float
            time value

        Returns
        -------
        list
            The residuals for dtheta/dt and current
        """
        # Unpack the parameters
        e0, alpha, k0, rho, zeta, gamma, *cap_params = p

        # Get the value of the protocol at given time
        e = protocol(t)

        # Approximate de/dt using finite differences
        dt = 1e-5
        dedt = (protocol(t) - protocol(t - dt)) / dt

        # Calculate the equation for current
        resid1 = -u[1] + gamma \
                  * capacitance_func(e - rho * u[1], *cap_params) * dedt \
                 - gamma * capacitance_func(e - rho * u[1], *cap_params) \
            * rho * du[1] + zeta * du[0] * num_electrons

        # Calculate the equation for proportion of A
        resid2 = -du[0] + k0 \
            * ((1 - u[0]) * np.exp((1 - alpha)
                                   * (e - rho * u[1] - e0))
                - u[0] * np.exp(-alpha * (e - rho * u[1] - e0)))

        return [resid1, resid2]

    differential_vars = [True, True]

    # Time points for solving, start at zero
    # It will return only on the user supplied time points in times
    tspan = (0, max(times))

    problem = de.DAEProblem(
        f,
        du0,
        u0,
        tspan,
        params,
        differential_vars=differential_vars
    )

    sol = de.solve(problem, saveat=times, reltol=1e-10)

    results = np.array(sol.u)
    theta = results[:, 0]
    i = results[:, 1]

    return i[1:], theta[1:]
예제 #13
0
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
예제 #14
0
def fiber_orientation(a0,
                      t,
                      L,
                      ci,
                      ar,
                      kappa=1,
                      D3=None,
                      closure="orthotropic",
                      method="RK45",
                      debug=False,
                      **kwargs):
    """
    Compute fiber orientation tensor evolution using the Folgar-Tucker model
    as its variants

    Args:
        a0 (ndarray of shape (3, 3)): Initial fiber orientation tensor
        t (ndarray of shape (1, )): Time instants
        L (ndarray of shape (3, 3)): Velocity gradient
        ci (float): Interaction coefficient
        ar (float): Aspect ratio
        kappa (float): Reduction coefficient when using the RSC model, ``0 < kappa <= 1``
        D3 (ndarray of shape (3, )): Coefficients :math:`(D_1,D_2,D_3)` when using the MRD model
        closure (str): 4th-order fiber orientation closure model ``A4_*``, see :py:mod:`fiberpy.closure`
        method (str): Numerical method to integrate the IVP, see :py:func:`scipy.integrate.solve_ivp`, or ``julia``
        debug (bool): Return instead the ``sol`` object and ``dadt``
    """
    D_ = 0.5 * (L + L.T)
    W_ = 0.5 * (L - L.T)
    lmbda = (ar**2 - 1) / (ar**2 + 1)
    gamma = np.sqrt(2) * np.linalg.norm(D_)
    a0_ = a0.flatten()

    # MRD model
    if D3 is not None:
        trD3 = np.sum(D3)
        D3 = np.diag(D3)
        kappa = 1

    def dadt(t, a):
        a_ = a.reshape((3, 3))
        e, v = np.linalg.eigh(a_)
        e = e[::-1]
        v = v[:, ::-1]
        A = eval("A4_" + closure + "(e)")
        if not np.isclose(kappa, 1):
            A[:3, :3] = kappa * A[:3, :3]
            A[:3, :3] += (1 - kappa) * np.diag(e)

        # Folgar-Tucker or RSC
        if D3 is None:
            diffusion_part = np.eye(3) - 3 * a_
        else:
            # MRD
            diffusion_part = v @ D3 @ v.T - trD3 * a_

        dadt_ = (W_ @ a_ - a_ @ W_ + lmbda *
                 (D_ @ a_ + a_ @ D_ - 2 * apply_Ax(v, A, D_)) +
                 2 * kappa * ci * gamma * diffusion_part)
        return dadt_.flatten()

    if method != "julia":
        sol = integrate.solve_ivp(dadt, (t[0], t[-1]),
                                  a0_,
                                  t_eval=t,
                                  method=method,
                                  **kwargs)
        y = sol.y
    else:
        from diffeqpy import de

        def dadt_julia(a, p, t):
            return dadt(t, a)

        prob = de.ODEProblem(dadt_julia, a0_, (t[0], t[-1]))
        sol = de.solve(prob)
        y = np.asarray(sol(t))

    if not debug:
        return y
    else:
        return sol, dadt