def integCompute(): global x0Arr global y0Arr y0Arr.clear() x0Arr.clear() x0 = float(parametersEntry['x0'].get()) x1 = float(parametersEntry['x1'].get()) y0 = float(parametersEntry['y0'].get()) y1 = float(parametersEntry['y1'].get()) t_min = 0 t_max = 15 max_st = 0.02 # tworzymy obiekt calkujacy (RK45 - Dormand–Prince) integrator = inte.RK45(wahadlo, t_min, [x0, x1,y0,y1], t_max, max_step = max_st) # listy zbierajace wyniki do wykresu times = [t_min] x0Arr = [x0] y0Arr = [y0] # kolejne kroki symulacji while integrator.t < t_max: integrator.step() times.append(integrator.t) x0Arr.append(integrator.y[0]) y0Arr.append(integrator.y[2]) '''
def __init__(self, car): self.t_step = .001 self.t0 = 0 self.t1 = 30 self.solution = inte.RK45(car.update_state, t0=0, y0=car.ics, t_bound=self.t1, vectorized=True, max_step=self.t_step) self.result_g = { 'time': [], 'ax': [], 'ay': [], 'vx': [], 'vy': [], 'x': [], 'y': [], 'theta': []} while self.solution.status == 'running': # car.FrontAxle.delta = np.cos(self.solution.t*.7) * .1 car.FrontAxle.delta = .1 self.solution.step() car.frame_ag.pos[0], car.frame_ag.v[0], car.frame_ag.pos[1], car.frame_ag.v[1], car.frame_a.theta, car.frame_a.omega = self.solution.y # rotate and return global self.result_g ['time'].append(self.solution.t) self.result_g ['x'].append(car.frame_ag.pos[0]) self.result_g ['y'].append(car.frame_ag.pos[1]) self.result_g ['ax'].append(car.frame_ag.a[0]) self.result_g ['ay'].append(car.frame_ag.a[1]) self.result_g ['vx'].append(car.frame_ag.v[0]) self.result_g ['vy'].append(car.frame_ag.v[1]) self.result_g ['theta'].append(car.frame_ag.theta)
def propagate(): x, p = getInitialConditions(c.xmethod) if len(x) != c.N: raise ValueError( "length of x is not equal to the number of progpagated points") initialConditions = np.concatenate([x, p], axis=0) # initialise stepping object stepper = odeint.RK45(lambda t, y: num.equation_of_motion(t, y), c.ts, initialConditions, c.tf, max_step=c.maxstep, rtol=c.rtol, atol=c.atol) x = stepper.y[:c.N] p = stepper.y[c.N:] H = num.Hamiltonian(x, p) # array to store trajectories trajectory = [] trajectory.append([stepper.t] + stepper.y.tolist() + H.tolist()) maxstep = 0. countstep = 0 # propragate Hamilton's eqn's while stepper.t < c.tf: try: stepper.step() x = stepper.y[:c.N] p = stepper.y[c.N:] H = num.Hamiltonian(x, p) # force small step for close-encounters # if Rmax < 10.: # stepper.max_step = 1e-1 # else: # stepper.max_step = c.maxstep trajectory.append([stepper.t] + stepper.y.tolist() + H.tolist()) maxstep = np.max([stepper.step_size, maxstep]) countstep = countstep + 1 except RuntimeError as e: print(e) break trajectory = np.array(trajectory) return trajectory
def integrate_(state0, t0, tmax): """Integrates ODE from a given initial state and returns the final state. """ rk = integrate.RK45(rhs, t0, state0, tmax, rtol=1e-9) while (rk.status == 'running'): rk.step() return rk.y
def dv (t): current = [0,1,0,1] derivs = [1,.5,1,.5] for i in range(0,365 * 24 * 60 * 60): x = integrate.RK45(current,dydt,i,1,yout,derivs) y = y=yout print (current[0] + " " + current[2]) derivs = get_derivs(t,current,derivs) scipy.integrate.RK45(fun, t0, y0, t_bound)
def count2(t): b = integrate.RK45( fun2, 0, np.array([ ShIZO.coordinates[1], ShIZO.speeds[1], ShIZO.coordinates[0], ShIZO.speeds[0] ]), t) while b.status != 'finished' and b.status != 'failed': b.step() if b.status == 'finished': return b.y else: return "failed"
def rk45(dxdt, x_0, t0, tf, max_step): """ Explicitly use RK45 scheme to solve an ODE. This is a lower level function that gives more control than the one liner solver that is also included in scipy. :param dxdt: Function to integrate :param x_0: initial conditions :param t0: initial time :param tf: final time :param step: time steps :return: times, solution array [x, y, z, u, v, w] """ integrator = integrate.RK45(dxdt, t0, x_0, tf, max_step) times = np.array([[t0]]) soln = np.array([x_0]) while integrator.status != 'finished': integrator.step() soln = np.append(soln, np.array([integrator.y]), axis=0) times = np.append(times, np.array([[integrator.t]]), axis=0) return times, soln
def step(self, a, s=None): s = self.state if s is None else s torque = bound(a, -self.TORQUE_LIMIT, self.TORQUE_LIMIT) # Add noise to the force action if self.torque_noise_max > 0: torque += self.np_random.uniform(-self.torque_noise_max, self.torque_noise_max) # Now, augment the state with our force action so it can be passed to # _dsdt s_augmented = np.append(s, torque) s_augmented[0] = wrap(s_augmented[0], 0, 2*pi) s_augmented[1] = wrap(s_augmented[1], -pi, pi) integrator = integrate.RK45(self._dsdt, 0, s_augmented, self.dt) while not integrator.status == 'finished': integrator.step() ns = integrator.y #ns = rk4(self._dsdt, s_augmented, [0, self.dt]) # only care about final timestep of integration returned by integrator #ns = ns[-1] ns = ns[:4] # omit action # ODEINT IS TOO SLOW! # ns_continuous = integrate.odeint(self._dsdt, self.s_continuous, [0, self.dt]) # self.s_continuous = ns_continuous[-1] # We only care about the state # at the ''final timestep'', self.dt #ns[0] = wrap(ns[0], -pi, pi) #ns[1] = wrap(ns[1], -pi, pi) ns[0] = wrap(ns[0], 0, 2*pi) ns[1] = wrap(ns[1], -pi, pi) ns[2] = bound(ns[2], -self.MAX_VEL_1, self.MAX_VEL_1) ns[3] = bound(ns[3], -self.MAX_VEL_2, self.MAX_VEL_2) self.state = ns terminal = self._terminal() reward = -1. if not terminal else 0. #return (self._get_ob(), reward, terminal, {}) return (self.state, reward, terminal, {})
def trajectory_generator(self, proptime_end, proptime_start=0, step_size=1e-3): """ Generator for solving the next time step of the geodesic's ODE system. Arguments: proptime_end -- end of interval [s] proptime_start -- start proper time [s] step_size -- step size [s] Yields: proper time, vector composed of the updated 4-vector and 4-velocity => [t, r, theta, phi, dt/dtau, dr/dtau, dtheta/dtau, dphi/dtau] """ ode_solver = integrate.RK45( self._calc_next_velo_and_acc_vec, t0=proptime_start, y0=self.initial_vec_x_u, t_bound=1e100, rtol=0.25 * step_size, first_step=0.75 * step_size, max_step=5 * step_size, ) while True: yield ode_solver.t, ode_solver.y ode_solver.step() current_radius = ode_solver.y[1] rs = -self.a rs_border = rs * 1.01 if ode_solver.t >= proptime_end: break if current_radius <= rs_border: logger.warning( "Nearly reached event horizon at r={}m. Stopping here!".format(rs) ) break
def nonlinear_propagation(x, u, world_dim, num_ownship_states, my_id): x_state = deepcopy(x) u_input = deepcopy(u) x_state[my_id * num_ownship_states + 4, 0] = u_input[0, 0] # speed x_state[my_id * num_ownship_states + 6, 0] = u_input[1, 0] # z_dot x_state[my_id * num_ownship_states + 7, 0] = u_input[2, 0] # angular velocity num_states = x_state.size num_assets = int(num_states / num_ownship_states) G = np.zeros((num_states, num_states)) for a in range(num_assets): start_index = a * num_ownship_states s = x_state[start_index + 4, 0] theta_dot = x_state[start_index + 7, 0] theta_initial = x_state[start_index + 3, 0] def dynamics(t, z): _x_dot = s * np.cos(z[2]) _y_dot = s * np.sin(z[2]) _theta_dot = theta_dot return np.array([_x_dot, _y_dot, _theta_dot]) t_init, t_final = 0, 1 z_init = np.concatenate((x_state[start_index:start_index + 2, 0], np.array([theta_initial]))) r = integrate.RK45(dynamics, t_init, z_init, t_final) while r.status == "running": status = r.step() x_state[start_index:start_index + 2, 0] = r.y[:2] x_state[start_index + 3, 0] = r.y[2] # Depth state change x_state[start_index + 2, 0] = x_state[start_index + 2, 0] + x_state[start_index + 6, 0] return x_state
def run(self, tDur=5000, max_step=1): """Integrator Receives required simulation duration. Integrates trajectories and records data to particle logs r, v, a logs.""" # Initial value state vector state0 = np.zeros((2 * len(self.sysP), 3)) for indP in range(0, len(self.sysP)): state0[2 * indP] = self.sysP[indP].r[-1] state0[2 * indP + 1] = self.sysP[indP].v[-1] state0 = state0.reshape(1, 6 * len(self.sysP))[0] # Trajectory integration solution object. integrator = integrate.RK45(self.gravitate, self.t[-1], state0, self.t[-1] + 500000, max_step=max_step, vectorized=True) integrator.step() t = self.t[-1] while t < tDur: integrator.step() for indP in range(0, len(self.sysP)): self.sysP[indP].r = np.append( self.sysP[indP].r, np.array([integrator.y[6 * indP:6 * indP + 3]]), axis=0) self.sysP[indP].v = np.append( self.sysP[indP].v, np.array([integrator.y[6 * indP + 3:6 * indP + 6]]), axis=0) t += integrator.step_size self.t = np.append(self.t, self.t[-1] + integrator.step_size)
def simpleODESolver(model, t0, state0, t_bound, max_step): if not callable(model): raise ValueError('Model must be callable') solver = integrate.RK45(fun=model, t0=t0, y0=state0, t_bound=t_bound, max_step=max_step) currentItem = { 'time': solver.t, 'y': [*state0], 'yd': [*model(t0, state0)] } while True: yield currentItem # send signal, inform about current result message = solver.step() currentItem = { 'time': solver.t, 'y': [*solver.y], 'yd': [*model(solver.t, solver.y)] } if (not (solver.status == 'running')): break
def run_filter(self): self.lock.acquire(True) """ Prediction Step """ if self.mean.size == 0: self.mean = np.array([self.meas_queue]).T print(self.mean) self.last_update_time = rospy.get_time() self.lock.release() return # Turtle stops moving 1s after last control input, # ... check if it's been a sec and set input to 0's if self.control_queue == [ 0, 0 ]: # Only on startup & after 1s of no control input self.control_queue = [0, 0] else: if rospy.get_time() - self.last_control_time >= 1.0: # print("Emptying control queue") self.control_queue = [0, 0] # empty the queue # Calculate delta_t & set new update time now = rospy.get_time() dt = now - self.last_update_time self.last_update_time = now s = self.control_queue[0] theta_dot = self.control_queue[1] x_initial = float(self.mean[0]) y_initial = float(self.mean[1]) theta_initial = float(self.mean[2]) # Runge-Kutta integrate mean prediction def dynamics(t, z): _x_dot = s * np.cos(z[2]) _y_dot = s * np.sin(z[2]) _theta_dot = theta_dot return np.array([_x_dot, _y_dot, _theta_dot]) t_init, t_final = 0, dt z_init = np.array([x_initial, y_initial, theta_initial]) r = integrate.RK45(dynamics, t_init, z_init, t_final) while r.status == "running": status = r.step() mean_bar = np.reshape(r.y, (r.y.size, 1)) mean_bar[2] = self.normalize_angle(mean_bar[2]) # Euler Intergrate the covariance # Jacobian of motion model, use Euler Integration (Runge-kutta for mean estimate) G = np.array([[1, 0, -dt*s*np.sin(theta_initial)],\ [0, 1, dt*s*np.cos(theta_initial)],\ [0, 0, 1]]) sigma_bar = np.dot(np.dot(G, self.sigma), G.T) + (self.motion_noise * dt) if not self.meas_queue: self.mean = mean_bar self.sigma = sigma_bar else: x_meas = self.meas_queue[0] y_meas = self.meas_queue[1] theta_meas = self.meas_queue[2] meas = np.array([[x_meas, y_meas, theta_meas]]).T H = np.eye(3) tmp = np.dot(np.dot(H, sigma_bar), H.T) + self.meas_noise tmp_inv = np.linalg.inv(tmp) K = np.dot(np.dot(sigma_bar, H), tmp_inv) inn = meas - mean_bar self.mean = mean_bar + np.dot(K, inn) self.sigma = np.dot(np.eye(3) - np.dot(K, H), sigma_bar) self.meas_queue = [] # empty the queue print(self.mean) print(self.sigma) print("--------") self.pub_estimates(self.mean, self.sigma) self.lock.release()
def apply_rf_field_nummerical(self, time=None, initial_condition=None, omega_rf=2 * np.pi * 61.79 * MHz, with_relaxation=False): """Solves the Bloch Equation numerically for a RF pulse with length `time` and frequency `omega_rf`. Parameters: * time: Length of RF pulse (e.g. a pi/2 pulse time or pi pulse time) If time is None, the pi/2 is estimated. Default: None * initial_condition: Inital mu_x, mu_y, mu_z of cells. Given as arrays of shap [3,N_cells] If None the inital condition is assumed to be in equilibrium and calculated from external B_field Default: None * omega_rf: RF pulse frequency If omega_rf is None, no RF pulse is applied and a Free Induction Decay is happening Default: 2 pi 61.79 MHz * with_relaxation: If true the relaxation terms are considered in the Bloch equations. If false the relaxation terms are neglected. Default: False Returns: * history: array of shape (7, N_time_steps) times, mean_Mx, mean_My, mean_Mz, Mx(0,0,0), My(0,0,0), Mz(0,0,0) Note: all magnetizations are treated as relative parameters wrt to the equalibrium magnetization, i.e. all values are without units and restricted to -1 and 1. """ if time is None: # if no time is given we estimate the pi/2 pulse duration and use that time = self.t_90() if initial_condition is None: # if no initial condition for the magnetization is given, we use the # equilibrium magnetization, which is aligned with the direction of # the external field. initial_condition = [ self.cells_B0_x / self.cells_B0, self.cells_B0_y / self.cells_B0, self.cells_B0_z / self.cells_B0 ] if not hasattr(self, "cells_B1"): # if cells B1 is not yet calculated, calculate B1 components self.initialize_coil_field() #def Bloch_equation(M, t, Îłâ‚š, Bz, Brf, omega, T1=np.inf, T2=np.inf): # # M is a vector of length 3 and is: M = [Mx, My, My]. # # Return dM_dt, that is a vector of length 3 as well. # Mx, My, Mz = M # M0 = 1 # dM_dt = Îłâ‚š*np.cross(M, [Brf*np.sin(omega*t), Brf*np.cos(omega*t), Bz]) #+ relaxation # return dM_dt #solution = integrate.odeint(Bloch_equation_with_RF_field, # y0=[0.3, 0.3, 0.3], # t=np.linspace(0., t_90, 100000), # args=(Îłâ‚š, B0, nmr_coil.B_field_mag(0*mm,0*mm,0*mm), omega_NMR )) # pulse frequency def Bloch_equation(t, M): M = M.reshape((3, self.N_cells)) Mx, My, Mz = M[0], M[1], M[2] Bx = self.cells_B0_x By = self.cells_B0_y Bz = self.cells_B0_z if omega_rf is not None: rf_osci = np.sin(omega_rf * t) Bx = Bx + rf_osci * self.cells_B1_x By = By + rf_osci * self.cells_B1_y Bz = Bz + rf_osci * self.cells_B1_z dMx = self.material.gyromagnetic_ratio * (My * Bz - Mz * By) dMy = self.material.gyromagnetic_ratio * (Mz * Bx - Mx * Bz) dMz = self.material.gyromagnetic_ratio * (Mx * By - My * Bx) if with_relaxation: # note we approximate here that the external field is in y direction # in the ideal case we would calculate the B0_field direct and the ortogonal plane dMx -= Mx / self.material.T2 dMy -= (My - 1) / self.material.T2 dMz -= Mz / self.material.T2 return np.array([dMx, dMy, dMz]).flatten() rk_res = integrate.RK45(Bloch_equation, t0=0, y0=np.array(initial_condition).flatten(), t_bound=time, max_step=1 * ns) # about 10 points per oscillation history = [] idx = np.argmin(self.cells_x**2 + self.cells_y**2 + self.cells_z**2) M = None while rk_res.status == "running": M = rk_res.y.reshape((3, self.N_cells)) Mx, My, Mz = M[0], M[1], M[2] # 1 history.append([ rk_res.t, np.mean(Mx), np.mean(My), np.mean(Mz), Mx[idx], My[idx], Mz[idx] ]) rk_res.step() self.cells_mu_x = M[0] self.cells_mu_y = M[1] self.cells_mu_z = M[2] self.cells_mu_T = np.sqrt(self.cells_mu_x**2 + self.cells_mu_z**2) return history
def solve_bloch_eq_nummerical(self, time=None, initial_condition=None, omega_rf=2 * np.pi * 61.79 * MHz, with_relaxation=False, time_step=1. * ns, with_self_contribution=True, phase_rf=0): (r"""Solves the Bloch Equation numerically for a RF pulse with length `time` and frequency `omega_rf`. Parameters: * time: Length of RF pulse (e.g. a pi/2 pulse time or pi pulse time) If time is None, the pi/2 is estimated. Default: None * initial_condition: Inital mu_x, mu_y, mu_z of cells. Given as arrays of shap [3,N_cells] If None the inital condition is assumed to be in equilibrium and calculated from external B_field Default: None * omega_rf: RF pulse frequency If omega_rf is None, no RF pulse is applied and a Free Induction Decay is happening Default: 2 pi 61.79 MHz * with_relaxation: If true the relaxation terms are considered in the Bloch equations. If false the relaxation terms are neglected. Default: False * time_step: Float, maximal time step used in nummerical solution of the Differential equation. Note that this value should be sufficient smaller than the oscillation time scale. Default: 1 ns * with_self_contribution: Boolean, if True we consider the additional B-field from the magnetization of the cell. Default: True Returns: * history: array of shape (7, N_time_steps) times, mean_Mx, mean_My, mean_Mz, Mx(0,0,0), My(0,0,0), Mz(0,0,0) Note: all magnetizations are treated as relative parameters wrt to the equalibrium magnetization, i.e. all values are without units and restricted to -1 and 1. """) if time is None: # if no time is given we estimate the pi/2 pulse duration and use that time = self.estimate_rf_pulse() if initial_condition is None: # if no initial condition for the magnetization is given, we use the # latest state of mu initial_condition = [ self.cells_mu.x, self.cells_mu.y, self.cells_mu.z ] # pulse frequency def Bloch_equation(t, M): M = M.reshape((3, self.N_cells)) Mx, My, Mz = M[0], M[1], M[2] Bx = self.cells_B0_x By = self.cells_B0_y Bz = self.cells_B0_z if with_self_contribution: Bx = Bx + mu0 * self.cells_magnetization * Mx By = By + mu0 * self.cells_magnetization * My Bz = Bz + mu0 * self.cells_magnetization * Mz if omega_rf is not None: rf_osci = np.sin(omega_rf * t + phase_rf) Bx = Bx + rf_osci * self.cells_B1_x By = By + rf_osci * self.cells_B1_y Bz = Bz + rf_osci * self.cells_B1_z dMx = self.probe.material.gyromagnetic_ratio * (My * Bz - Mz * By) dMy = self.probe.material.gyromagnetic_ratio * (Mz * Bx - Mx * Bz) dMz = self.probe.material.gyromagnetic_ratio * (Mx * By - My * Bx) if with_relaxation: # note we approximate here that the external field is in y direction # in the ideal case we would calculate the B0_field direct and the ortogonal plane # note that we use relative magnetization , so the -1 is -M0 dMx -= Mx / self.probe.material.T2 dMy -= (My - 1) / self.probe.material.T1 dMz -= Mz / self.probe.material.T2 return np.array([dMx, dMy, dMz]).flatten() rk_res = integrate.RK45(Bloch_equation, t0=0, y0=np.array(initial_condition).flatten(), t_bound=time, max_step=0.1 * ns) # about 10 points per oscillation history = [] central_cell = np.argmin(self.cells_x**2 + self.cells_y**2 + self.cells_z**2) M = None while rk_res.status == "running": M = rk_res.y.reshape((3, self.N_cells)) Mx, My, Mz = M[0], M[1], M[2] w = self.cells_B1 / np.mean(self.cells_B1) history.append( (rk_res.t, np.mean(w * Mx), np.mean(w * My), np.mean(w * Mz), Mx[central_cell], My[central_cell], Mz[central_cell])) rk_res.step() M = rk_res.y.reshape((3, self.N_cells)) self.cells_mu.set_x_y_z(M[0], M[1], M[2]) return np.array(history, dtype=[(k, np.float) for k in [ "time", "Mx_mean", "My_mean", "Mz_mean", "Mx_center", "My_center", "Mz_center" ]])
from __future__ import division from scipy import integrate import numpy as np # simple example: dydx = x --> y = (1/2)*x^2 def diff_eq(x, y): print("calculating... " + str(y)) return np.array([x]) x0, x1 = 0, 5 y0 = np.array([0]) r = integrate.RK45(diff_eq, x0, y0, x1) # r = integrate.RK45(lambda x,y : np.array([x]), x0, y0, x1) # w/ lambda while r.status == "running": status = r.step() print(r.y) # plt.show(y,x_seq) # plt.show()
# defining ODEs dxdt = f_x * y - c_x * x + e_x dydt = f_y * x - c_y * y + e_y # returning array dzdt = np.array([dxdt, dydt]) return dzdt # initialize time and x and y expenditure at initial time t_0 = 0 init_data = np.array([14, 5]) # starting RK45 integration method sys_1 = integrate.RK45(model, t_0, init_data, 1000, 0.001) # storing initial data sol_x = [sys_1.y[0]] sol_y = [sys_1.y[1]] time = [t_0] for i in range(5000): sys_1.step() # performing integration step sol_x.append( sys_1.y[0] ) # storing the results in our solution list, y is the attribute current state sol_y.append(sys_1.y[1]) time.append(sys_1.t) plt.figure(figsize=(20, 10))
#save results at each dtout def saveres(t, y): ukres.resize((ukres.shape[0] + 1, ) + ukres.shape[1:]) tres.resize((tres.shape[0] + 1, )) ukres[-1, ] = y tres[-1, ] = t fl.flush() #Initialize the ODE Solver r = spi.RK45(f, t0, uk.ravel().view(dtype=float), t1, rtol=1e-8, atol=1e-6, max_step=dtstep) print(f"running {__file__}") print(f"resolution: {Nx}x{Ny}") print(f"parameters: nu={nu}, FA={FA}") ct = time() print("t=", r.t) print(time() - ct, "secs elapsed") t = t0 toldout = t toldstep = t Fnm0 = np.abs(Fnm).copy() #Main ODE solver loop
# km0=4*2**(1/4) # u0[:,0]=np.exp(-np.linalg.norm(k-k[int(k.shape[0]/2)],axis=0)**2/4**2)*np.exp(1j*np.pi*np.random.random(N)) # u0[:,1]=np.exp(-np.linalg.norm(k-k[int(k.shape[0]/2)],axis=0)**2/4**2)*np.exp(1j*np.pi*np.random.random(N)) # u0=np.sqrt(6*np.sqrt(2/np.pi)*km0**(-5)*np.abs(k)**4*np.exp(-2*(np.abs(k)/km0)**2))*np.exp(1j*np.pi*np.random.random(Nh)) if (save_network): gr = nx.Graph() strs = [np.str(l) for l in trs] gr.add_nodes_from(kn, bipartite=0) gr.add_nodes_from(strs, bipartite=1) for l in range(len(trs)): gr.add_edges_from([(kn[trs[l][0]], strs[l]), (kn[trs[l][1]], strs[l]), (kn[trs[l][2]], strs[l])]) nx.write_gpickle(gr, 'nwfile.pkl') r = spi.RK45(func, t0, u0.ravel().view(dtype=float), t1, max_step=dt) epst = 1e-12 ct = time.time() if (random_forcing == True): force_update() #dtff,dtf,dts,dtss=np.sort((dt,dtr,dtrw,dtout)) toldr = -1.0e12 toldrw = -1.0e12 toldout = -1.0e12 while (r.status == 'running'): told = r.t if (r.t >= toldout + dtout - epst and r.status == 'running'): toldout = r.t print("t=", r.t) u = r.y.view(dtype=complex)
def run(flname, wecontinue=False, fc_phi=f_phik0, fc_n=f_phik0, nuf=lambda nu, ksqr: nu * ksqr, atol=1e-12, rtol=1e-6, ncpu=8, pure_python=False, save_preview=True, prev_size=10): global kx, ky, ksqr, linmat, dat, fftw_obj_dat6b, fftw_obj_dat2f, N, Npad, r, dydt set_res(nx, ny) dat = pyfw.empty_aligned( (8, int(Nx + 2 * npadx), int((Ny + 2 * npady) / 2 + 1)), dtype=complex) dat.fill(0) indsx = np.int_(np.round(np.fft.fftfreq(Nx) * Nx)) indsy = np.arange(0, int(Ny / 2 + 1)) dkx, dky = 2 * np.pi / Lx, 2 * np.pi / Ly kx, ky = np.meshgrid(indsx * dkx, indsy * dky, indexing='ij') ksqr = (kx**2 + ky**2) linmat = np.zeros((Nx, int(Ny / 2 + 1), 2, 2), dtype=complex) N = Nx * Ny Npad = nx * ny if (wecontinue == True): fl = h5.File(flname, "r+") for l in pars: pars[l] = fl['pars/' + l] for l in tvars: tvars[l] = fl['pars/' + l] phires = fl["fields/phi"] nres = fl["fields/n"] tres = fl["fields/t"] tvars['t0'] = tres[-1] phi0 = phires[-1, :, :] nf0 = nres[-1, :, :] phik0 = pyfw.empty_aligned((Nx, int(Ny / 2 + 1)), 'complex') nk0 = pyfw.empty_aligned((Nx, int(Ny / 2 + 1)), 'complex') fftw_objf = pyfw.FFTW(phi0.copy(), phik0, axes=(0, 1)) phik0 = fftw_objf(phi0.copy(), phik0) nk0 = fftw_objf(nf0.copy(), nk0) u0 = np.stack((phik0, nk0), 0) fftw_obj = pyfw.FFTW(phik0.copy(), phi0, axes=(0, 1), direction='FFTW_BACKWARD') i = phires.shape[0] grp = fl["fields"] else: phik0 = fc_phi(kx, ky) phi0 = pyfw.empty_aligned( phik0.view(dtype=float)[:, :-2].shape, 'float') fftw_obj = pyfw.FFTW(phik0.copy(), phi0, axes=(0, 1), direction='FFTW_BACKWARD') phi0 = fftw_obj() nk0 = fc_n(kx, ky) nf0 = pyfw.empty_aligned(nk0.view(dtype=float)[:, :-2].shape, 'float') nf0 = fftw_obj(nk0.copy(), nf0) u0 = np.stack((phik0, nk0), 0) fftw_obj = pyfw.FFTW(phik0.copy(), phi0, axes=(0, 1), direction='FFTW_BACKWARD') i = 0 if os.path.exists(flname): os.remove(flname) fl = h5.File(flname, "w") gpars = fl.create_group("pars") for l in pars: gpars.create_dataset(l, data=pars[l]) for l in tvars: gpars.create_dataset(l, data=tvars[l]) grp = fl.create_group("fields") grp.create_dataset("kx", data=kx) grp.create_dataset("ky", data=ky) phires = grp.create_dataset("phi", (1, Nx, Ny), maxshape=(None, Nx, Ny), dtype=float) nres = grp.create_dataset("n", (1, Nx, Ny), maxshape=(None, Nx, Ny), dtype=float) tres = grp.create_dataset("t", (1, ), maxshape=(None, ), dtype=float) if (save_preview): prn, prex = os.path.splitext(flname) prfln = prn + '_prev' + prex if os.path.exists(prfln): os.remove(prfln) pfl = h5.File(prfln, "w") pgrp = pfl.create_group("fields") pgrp.create_dataset("kx", data=kx) pgrp.create_dataset("ky", data=ky) phipr = pgrp.create_dataset("phi", (prev_size, Nx, Ny), dtype=float) npr = pgrp.create_dataset("n", (prev_size, Nx, Ny), dtype=float) tpr = pgrp.create_dataset("t", (prev_size, ), dtype=float) C = pars['C'] kap = pars['kap'] nu = pars['nu'] D = pars['D'] nuZF = pars['nuZF'] DZF = pars['DZF'] linmat[ksqr > 0, 0, 0] = -C / (ksqr[ksqr > 0]) - nuf(nu, ksqr)[ksqr > 0] linmat[ksqr > 0, 0, 1] = C / (ksqr[ksqr > 0]) linmat[:, :, 1, 0] = -1j * kap * ky + C linmat[:, :, 1, 1] = -C - nuf(D, ksqr) if (pars['modified']): linmat[:, 0, 0, 0] = -nuZF linmat[:, 0, 0, 1] = 0.0 linmat[:, 0, 1, 0] = 0.0 linmat[:, 0, 1, 1] = -DZF if (pure_python): fftw_obj_dat6b = pyfw.FFTW(dat[:6, :, :], dat[:6, :, :].view(dtype=float)[:, :, :-2], axes=(1, 2), direction='FFTW_BACKWARD', threads=ncpu) fftw_obj_dat2f = pyfw.FFTW(dat[6:, :, :].view(dtype=float)[:, :, :-2], dat[6:, :, :], axes=(1, 2), direction='FFTW_FORWARD', threads=ncpu) fhwak = fhwak_python else: dydt = np.zeros(Nx * (int(Ny / 2 + 1)) * 4) fk_phi = np.zeros_like(phik0) fk_n = np.zeros_like(nk0) fhw.fhwak_init(Nx, Ny, npadx, npady, dat.ctypes, linmat.ctypes, kx.ctypes, ky.ctypes, fk_phi.ctypes, fk_n.ctypes) fhwak = fhwak_c dt = tvars['dt'] dtout = tvars['dtout'] dtr = tvars['dtr'] t0 = tvars['t0'] t1 = tvars['t1'] r = spi.RK45(fhwak, t0, u0.view(dtype=float).ravel(), t1, max_step=dt, atol=atol, rtol=rtol) epst = 1e-12 ct = time.time() toldr = -1.0e12 toldout = -1.0e12 while (r.status == 'running'): told = r.t if (r.t >= toldout + dtout - epst and r.status == 'running'): toldout = r.t print("t=", r.t) phik, nk = r.y.view(dtype=complex).reshape(2, Nx, int(Ny / 2 + 1)) phires.resize((i + 1, Nx, Ny)) nres.resize((i + 1, Nx, Ny)) tres.resize((i + 1, )) phik = phik.squeeze() nk = nk.squeeze() phi = pyfw.empty_aligned((Nx, Ny), 'float') nf = pyfw.empty_aligned((Nx, Ny), 'float') phi = fftw_obj(phik.copy(), phi) nf = fftw_obj(nk.copy(), nf) phires[i, :, :] = phi nres[i, :, :] = nf tres[i] = r.t fl.flush() if (save_preview and i > prev_size): phipr[:, :, :] = phires[i - prev_size:i, :, :] npr[:, :, :] = nres[i - prev_size:i, :, :] tpr[:] = tres[i - prev_size:i] pfl.flush() i = i + 1 print(time.time() - ct, "seconds elapsed.") if (r.t >= toldr + dtr - epst and r.status == 'running' and pars['random_forcing'] == True): toldr = r.t # force_update() # linmat_update() while (r.t < told + dt - epst and r.status == 'running'): res = r.step() fl.close()
def propagate(ri, pi, Ri, Pi, returnTraj=False): """Propagate trajectory from a given intial condition based on Hamilton's Equations. ri -- Initial C.o.M position for diatom (BC) pi -- Initial C.o.M conjugate momentum for diatom (BC) Ri -- Initial C.o.M position for scattering particle and diatom (BC) Pi -- Initial C.o.M conjugate momentum for scattering particle and diatom (BC) returnTraj -- flag to return trajectory for plotting (default False) """ initialConditions = np.concatenate([ri, pi, Ri, Pi], axis=0) epsilon = Pi @ Pi / (2. * c.MU) # initialise stepping object stepper = odeint.RK45(lambda t, y: num.equation_of_motion(t, y), c.ts, initialConditions, c.tf, max_step=c.maxstep, rtol=c.rtol, atol=c.atol) r, p, R, P = getPropCoords(stepper.y) H = num.Hamiltonian(r, p, R, P) # array to store trajectories trajectory = [] trajectory.append([stepper.t] + stepper.y.tolist() + [H]) maxstep, maxErr = 0., 0. Rmax = 0. countstep = 0 failed = False # propragate Hamilton's eqn's while stepper.t < c.tf: try: stepper.step() r, p, R, P = getPropCoords(stepper.y) R1, R2, R3 = internuclear(r, R) Rmax = np.max([R1, R2, R3]) # force small step for close-encounters # if Rmax < 10.: # stepper.max_step = 1e-1 # else: # stepper.max_step = c.maxstep trajectory.append([stepper.t] + stepper.y.tolist() + [H]) maxstep = np.max([stepper.step_size, maxstep]) maxErr = np.max( [np.abs((H - num.Hamiltonian(r, p, R, P) / epsilon)), maxErr]) countstep = countstep + 1 if isConverged(Rmax): break H = num.Hamiltonian(r, p, R, P) except RuntimeError as e: print(e) failed = True break if returnTraj: trajectory = np.array(trajectory) return trajectory else: assignment = assignClassical(r=r, p=p, R=R, P=P) nq, lq = assignQuantum(Ec=assignment["Ec"], lc=assignment["lc"]) assignment["n"] = nq assignment["l"] = lq names = [ 'r', 'p', 'R', 'P', 'tf', 'maxErr', 'countstep', 'maxstep', 'converge', 'fail', "n", "l", "case", ] objects = [ r, p, R, P, stepper.t, maxErr, countstep, maxstep, isConverged(Rmax), failed, assignment["n"], assignment["l"], assignment["case"], ] result = dict(zip(names, objects)) return result
import numpy as np, scipy.integrate as spi, matplotlib.pyplot as plt, time import pygame G = 9.8 L = 1 def pendulumHamiltonian(t, cvs): """Takes in the values for the canonical variables for the pendulum in 2D (i.e. [theta, omega]) and returns the time derivates (i.e. [dtheta/dt, domega/dt]""" return [cvs[1], -(G / L) * np.sin(cvs[0])] if __name__ == "__main__": cvs = [np.pi / 2, 0] #theta = 1 rad, omega = 0 rad/s solution = spi.RK45(pendulumHamiltonian, t0=0, y0=cvs, t_bound=100, max_step=1 / 100) xs = [] ys = [] for i in range(100): solution.step() x, y = np.sin(solution.y[0]), 1 - np.cos(solution.y[0]) xs.append(x) ys.append(y) plt.plot(xs, ys, 'o') plt.show()
def solve(y0: Input): # Derivative equations # Inputs # t: time # y: [ # position_x, # position_y, # position_z, # velocity_x, # velocity_y, # velocity_z # ] def derivative(t, y) -> List[float]: # t: float, y: List[float] # Create data model data_der = Data(position=Vector(x=y[0], y=y[1], z=y[2]), velocity=Vector(x=y[3], y=y[4], z=y[5]), time=t) y_dot = [0] * len(y) # Velocity y_dot[0], y_dot[1], y_dot[2] = y[3], y[4], y[5] # Acceleration y_dot[3], y_dot[4], y_dot[5] = acceleration.value(data=data_der) return y_dot print('\n01 - Simulation Initialized\n') # Initial simulation time start_time = time() # Create class acceleration = Acceleration(inputs=y0) # Initial conditions output = OutputModel( position=[y0.initial_condition.position], velocity=[y0.initial_condition.position], time=[0.0], ) # Solve solution = ode.RK45(derivative, t0=0.0, y0=y0.initial_condition.toList(), t_bound=MAX_SIMULATION_TIME, max_step=MAX_TIME_STEP) print_data = 0 data = Data(position=Vector(x=0.0, y=0.0, z=0.0), velocity=Vector(x=0.0, y=0.0, z=0.0), time=0.0) printHeader() while True: solution.step() output.insertFromList(t=solution.t, y=solution.y) if output.position[len(output.position) - 1].z <= 0.0: data.updateFromList(t=solution.t, y=solution.y) printData(data=data) break if solution.t - print_data >= PRINT_INTERVAL or print_data == 0: print_data = solution.t + PRINT_INTERVAL data.updateFromList(t=solution.t, y=solution.y) printData(data=data) # End simulation time end_time = time() print('\n Simulation ended in %.4f seconds' % (end_time - start_time)) print('\n04 - Generating Log') print('\n05 - Generating Plots') makePlots(output=output) print('\n06 - Generating Report')
def get_traj_with_scipy(date, runtime, max_delta_time, particle_grid_step, stream_data_fname, R=EQUATORIAL_EARTH_RADIUS): """Compute trajectories of particles in the sea using scipy library. Compute trajectories of particles in the sea at a given date, in a static 2D field of stream. Trajectories are saved in a .nc file. Args: date (int) : Day in number of days relatively to the data time origin at which the stream data should be taken. runtime (int) : Total duration in hours of the field integration. Trajectories length increases with the runtime. max_delta_time (int) : Maximum time step in hours of the integration. The integration function used can use smaller time step if needed. particle_grid_step (int) : Grid step size for the initial positions of the particles. The unit is the data index step, ie data dx and dy. stream_data_fname (str) : Complete name of the stream data file. R (float) : Radius of the Earth in meter in the data area. The exact value can be used to reduce Earth shape related conversion and computation error. Default is the equatorial radius. Returns: stream_line_list (list of classes.StreamLine) : The list of trajectories Notes: The input file is expected to contain the daily mean fields of east- and northward ocean current velocity (uo,vo) in a format as described here: http://marine.copernicus.eu/documents/PUM/CMEMS-GLO-PUM-001-024.pdf. """ # Loading data data_set = nc.Dataset(stream_data_fname) u_1day = data_set['uo'][date, 0, :] v_1day = data_set['vo'][date, 0, :] # Data sizes data_time_size, data_depth_size, data_lat_size, data_lon_size = np.shape( data_set['uo']) longitudes = np.array(data_set['longitude']) - 1 / 24 latitudes = np.array(data_set['latitude']) - 1 / 24 # Replace the mask (ie the ground areas) with a null vector field. U = np.array(u_1day) U[U == -32767] = 0 V = np.array(v_1day) V[V == -32767] = 0 # Conversion of u and v from m.s**-1 to degree.s**-1 conversion_coeff = 360 / (2 * np.pi * R) U *= conversion_coeff V *= conversion_coeff for lat in range(data_lat_size): U[lat, :] *= 1 / np.cos(latitudes[lat] / 360) # Interpolize continuous u,v from the data array u_interpolized = sp_interp.RectBivariateSpline(longitudes, latitudes, U.T) v_interpolized = sp_interp.RectBivariateSpline(longitudes, latitudes, V.T) def stream(t, pos_vect): # pos = (long,lat) u = u_interpolized.ev(pos_vect[0], pos_vect[1]) v = v_interpolized.ev(pos_vect[0], pos_vect[1]) return np.array([u, v]) # List of initial positions of the particles. Particles on the ground are # removed. init_pos = [] for lon in range(0, data_lon_size, particle_grid_step): for lat in range(0, data_lat_size, particle_grid_step): if not u_1day[lat, lon] is np.ma.masked: init_pos.append([longitudes[lon], latitudes[lat]]) init_pos = np.array(init_pos) nb_stream_line = len(init_pos) # Integrate each positions stream_line_list = [] progression = 0 for sl_id in range(nb_stream_line): if int(sl_id / nb_stream_line * 100) - progression >= 5: progression += 5 print(progression, "% ", end="", sep="") coord_list = [np.array(init_pos[sl_id])] dt_list = [] previous_t = 0 integration_instance = sp_integ.RK45(stream, 0, init_pos[sl_id], runtime * 3600, rtol=1e-4, atol=1e-7, max_step=max_delta_time * 3600) # Integrate the trajectory dt by dt while integration_instance.status == 'running': previous_pt = coord_list[-1] is_between_limit_lat = latitudes[0] <= previous_pt[1] <= latitudes[ -1] is_between_limit_long = longitudes[0] <= previous_pt[ 0] <= longitudes[-1] if is_between_limit_lat and is_between_limit_long: integration_instance.step() coord_list.append(integration_instance.y) else: integration_instance.status = 'finished' coord_list.append(previous_pt) dt_list.append(integration_instance.t - previous_t) previous_t = integration_instance.t dt_list = np.array(dt_list) stream_line_list.append(StreamLine(coord_list, dt_list)) print() return stream_line_list
t1 = np.array([y[i][0] for i in range(len(y))]) t2 = np.array([y[i][2] for i in range(len(y))]) x1 = l1 * np.sin(t1) x2 = l2 * np.sin(t2) + x1 y1 = - l1 * np.cos(t1) y2 = - l2 * np.cos(t2) + y1 art1.set_data(x2, y2) art2.set_data([0, x1[-1]], [0, y1[-1]]) art3.set_data([x1[-1], x2[-1]], [y1[-1], y2[-1]]) return art1, art2, art3 np.random.seed() initial_conditions = np.pi * np.random.rand(4) y = [initial_conditions] integrator = int.RK45(f, 0, initial_conditions, t_bound = np.inf, max_step = 1e-2) t1 = np.array([y[i][0] for i in range(len(y))]) t2 = np.array([y[i][2] for i in range(len(y))]) x1 = l1 * np.sin(t1) x2 = l2 * np.sin(t2) + x1 y1 = - l1 * np.cos(t1) y2 = - l2 * np.cos(t2) + y1 fig1, ax1 = plt.subplots() art1, = ax1.plot(x2, y2, color = "k", linewidth = 0.1) art2, = ax1.plot([0, x1[-1]], [0, y1[-1]], color = "r", linewidth = 1) art3, = ax1.plot([x1[-1], x2[-1]], [y1[-1], y2[-1]], color = "b", linewidth = 1) arts = (art1, art2, art3) ax1.set_xlim(- l1 - l2 - 0.1 * l1, l1 + l2 + 0.1 * l1) ax1.set_ylim(- l1 - l2 - 0.1 * l1, + l1 + l2 + 0.1 * l1) ax1.set_xlabel("x (m)")
return t_values, x_values, dx_values # Define the initial conditions and integration boundaries: # ------------------------------------------------------------------ time_step = 0.01 t_upper = 1.5 t_lower = 0 initial_conditions = np.array([0, 0 ]) # [displacement(t=0) = 0, velocity(t=0) = 0] solution1 = inte.RK45(fun=MassSpringDamper, t0=t_lower, y0=initial_conditions, t_bound=t_upper, vectorized=True) solution2 = inte.Radau(fun=MassSpringDamper, t0=t_lower, y0=initial_conditions, t_bound=t_upper, vectorized=True) solution3 = inte.LSODA(fun=MassSpringDamper, t0=t_lower, y0=initial_conditions, t_bound=t_upper, vectorized=True) plt.figure()
dy = k * x + f * y - x * z dz = c * z + x * y - e * x**2 return np.array([dx, dy, dz]) #------------Part a-------------- #initial conditions state0 = [1, 2, 3] t0 = 0 tmax = 100 time = [t0] state = np.array(state0) rk = integrate.RK45(rhs, t0, state0, tmax, rtol=1e-9) while (rk.status == 'running'): rk.step() time.append(rk.t) state = np.vstack((state, rk.y)) plt.figure(1) plt.scatter(state[:, 0], state[:, 1], s=0.1, cmap='jet', c=state[:, 2]) plt.xlabel('x') plt.ylabel('y') plt.title('Trajectory') #----------Part b-----------------
break return t_values, y_values # Define the initial conditions and integration boundaries: # ------------------------------------------------------------------ time_step = 0.01 t_upper = 10.5 t_lower = 0 initial_conditions = np.array([0, 0 ]) # [displacement(t=0) = 0, velocity(t=0) = 0] solution = inte.RK45(fun=model, t0=t_lower, y0=initial_conditions, t_bound=t_upper, vectorized=True) solution2 = inte.Radau(fun=model, t0=t_lower, y0=initial_conditions, t_bound=t_upper, vectorized=True) solution3 = inte.LSODA(fun=model, t0=t_lower, y0=initial_conditions, t_bound=t_upper, vectorized=True) plt.figure() x, y = get_data(solution)
moon_vy = 1.366348632018184E-02*au_per_day_to_m_per_sec moon_vz = -1.903435427371054E-05*au_per_day_to_m_per_sec state0 = [sun_x,sun_y,sun_z,earth_x,earth_y,earth_z,moon_x,moon_y,moon_z, sun_vx,sun_vy,sun_vz,earth_vx,earth_vy,earth_vz,moon_vx,moon_vy,moon_vz] #time parameters t0 = 0 tmax = 31536000 time = [t0] state = np.array(state0) #Integrate rk = integrate.RK45(rhs,t0,state0,tmax,rtol = 1e-5) while(rk.status == 'running'): rk.step() time.append(rk.t) state = np.vstack((state,rk.y)) #print(state) #Plot plt.figure(1) plt.plot(state[:,3],state[:,4]) plt.title('Trajectory of the earth around the sun') plt.xlabel('x (meters)') plt.ylabel('y (meters)') plt.plot(state[:,0],state[:,1])