def test_t_eval_dense_output(): rtol = 1e-3 atol = 1e-6 y0 = [1/3, 2/9] t_span = [5, 9] t_eval = np.linspace(t_span[0], t_span[1], 10) res = solve_ivp(fun_rational, t_span, y0, rtol=rtol, atol=atol, t_eval=t_eval) res_d = solve_ivp(fun_rational, t_span, y0, rtol=rtol, atol=atol, t_eval=t_eval, dense_output=True) assert_equal(res.t, t_eval) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) assert_equal(res.t, res_d.t) assert_equal(res.y, res_d.y) assert_(res_d.t_events is None) assert_(res_d.success) assert_equal(res_d.status, 0) # if t and y are equal only test values for one case y_true = sol_rational(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5))
def test_t_eval(): rtol = 1e-3 atol = 1e-6 y0 = [1/3, 2/9] for t_span in ([5, 9], [5, 1]): t_eval = np.linspace(t_span[0], t_span[1], 10) res = solve_ivp(fun_rational, t_span, y0, rtol=rtol, atol=atol, t_eval=t_eval) assert_equal(res.t, t_eval) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) y_true = sol_rational(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5)) t_eval = [5, 5.01, 7, 8, 8.01, 9] res = solve_ivp(fun_rational, [5, 9], y0, rtol=rtol, atol=atol, t_eval=t_eval) assert_equal(res.t, t_eval) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) y_true = sol_rational(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5)) t_eval = [5, 4.99, 3, 1.5, 1.1, 1.01, 1] res = solve_ivp(fun_rational, [5, 1], y0, rtol=rtol, atol=atol, t_eval=t_eval) assert_equal(res.t, t_eval) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) t_eval = [5.01, 7, 8, 8.01] res = solve_ivp(fun_rational, [5, 9], y0, rtol=rtol, atol=atol, t_eval=t_eval) assert_equal(res.t, t_eval) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) y_true = sol_rational(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5)) t_eval = [4.99, 3, 1.5, 1.1, 1.01] res = solve_ivp(fun_rational, [5, 1], y0, rtol=rtol, atol=atol, t_eval=t_eval) assert_equal(res.t, t_eval) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) t_eval = [4, 6] assert_raises(ValueError, solve_ivp, fun_rational, [5, 9], y0, rtol=rtol, atol=atol, t_eval=t_eval)
def cowell(orbit, tof, rtol=1e-11, *, ad=None, **ad_kwargs): """Propagates orbit using Cowell's formulation. Parameters ---------- orbit : ~poliastro.twobody.orbit.Orbit the Orbit object to propagate. ad : function(t0, u, k), optional Non Keplerian acceleration (km/s2), default to None. tof : Multiple options Time to propagate, float (s), Times to propagate, array of float (s). rtol : float, optional Maximum relative error permitted, default to 1e-10. Raises ------ RuntimeError If the algorithm didn't converge. Note ----- This method uses a Dormand & Prince method of order 8(5,3) available in the :py:class:`poliastro.integrators` module. If multiple tofs are provided, the method propagates to the maximum value and calculates the other values via dense output """ k = orbit.attractor.k.to(u.km ** 3 / u.s ** 2).value x, y, z = orbit.r.to(u.km).value vx, vy, vz = orbit.v.to(u.km / u.s).value u0 = np.array([x, y, z, vx, vy, vz]) # Set the non Keplerian acceleration if ad is None: ad = lambda t0, u_, k_: (0, 0, 0) f_with_ad = functools.partial(func_twobody, k=k, ad=ad, ad_kwargs=ad_kwargs) multiple_input = hasattr(tof, "__len__") if not multiple_input: tof = [tof] result = solve_ivp(f_with_ad, (0, max(tof)), u0, rtol=rtol, atol=1e-12, method=DOP835, dense_output=True) if not result.success: raise RuntimeError("Integration failed") rrs = [] vvs = [] for i in range(len(tof)): y = result.sol(tof[i]) rrs.append(y[:3]) vvs.append(y[3:]) if not multiple_input: return rrs[0], vvs[0] return rrs, vvs
def test_integration_complex(): rtol = 1e-3 atol = 1e-6 y0 = [0.5 + 1j] t_span = [0, 1] tc = np.linspace(t_span[0], t_span[1]) with warnings.catch_warnings(): warnings.simplefilter('ignore') for method, jac in product(['RK23', 'RK45', 'BDF'], [None, jac_complex, jac_complex_sparse]): res = solve_ivp(fun_complex, t_span, y0, method=method, dense_output=True, rtol=rtol, atol=atol, jac=jac) assert_equal(res.t[0], t_span[0]) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) assert_(res.nfev < 25) if method == 'BDF': assert_equal(res.njev, 1) assert_(res.nlu < 6) else: assert_equal(res.njev, 0) assert_equal(res.nlu, 0) y_true = sol_complex(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5)) yc_true = sol_complex(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, rtol, atol) assert_(np.all(e < 5))
def __call__(self, model, rtol): def collected_ode(t, y): return model.f(t, y, model.k) sol = solve_ivp(collected_ode, [0.0, np.max(model.ts)], model.y0, method=self.name, rtol=rtol, t_eval=model.ts) return sol.y.transpose()
def integrate_hier_init_cond(self, rho_0_hier, times, method='BDF'): r"""Integrate the equation for a list of times with given initial conditions, expressed as a full hierarchy density matrix rather than only a system density matrix. Handles non-hermitian initial conditions to facilitate applications involving the quantum regression theorem (this means the vectorized solutions will be complex in general). :param rho_0_hier: The initial state of the system as a matrix :type rho_0_hier: `numpy.array` :param times: A sequence of time points for which to solve for rho :type times: `list(real)` :param method: The integration method for `scipy.integrate.solve_ivp` to use. :type method: String :returns: The components of the vecorized :math:`\rho` for all specified times :rtype: `Solution` """ rho_0_vec = sb.vectorize(rho_0_hier, self.basis) ivp_soln = solve_ivp(lambda t, rho: self.a_fn(rho, t), (times[0], times[-1]), rho_0_vec, method=method, t_eval=times, jac=lambda t, rho: self.Dfun(t)) return integ.Solution(ivp_soln.y.T, self.basis)
def test_integration_const_jac(): rtol = 1e-3 atol = 1e-6 y0 = [0, 2] t_span = [0, 2] J = jac_linear() J_sparse = csc_matrix(J) for method, jac in product(['Radau', 'BDF'], [J, J_sparse]): res = solve_ivp(fun_linear, t_span, y0, rtol=rtol, atol=atol, method=method, dense_output=True, jac=jac) assert_equal(res.t[0], t_span[0]) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) assert_(res.nfev < 100) assert_equal(res.njev, 0) assert_(0 < res.nlu < 15) y_true = sol_linear(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 10)) tc = np.linspace(*t_span) yc_true = sol_linear(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, rtol, atol) assert_(np.all(e < 15)) assert_allclose(res.sol(res.t), res.y, rtol=1e-14, atol=1e-14)
def test_integration(): rtol = 1e-3 atol = 1e-6 y0 = [1/3, 2/9] for vectorized, method, t_span, jac in product( [False, True], ['RK23', 'RK45', 'Radau', 'BDF', 'LSODA'], [[5, 9], [5, 1]], [None, jac_rational, jac_rational_sparse]): if vectorized: fun = fun_rational_vectorized else: fun = fun_rational with suppress_warnings() as sup: sup.filter(UserWarning, "The following arguments have no effect for a chosen solver: `jac`") res = solve_ivp(fun, t_span, y0, rtol=rtol, atol=atol, method=method, dense_output=True, jac=jac, vectorized=vectorized) assert_equal(res.t[0], t_span[0]) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) assert_(res.nfev < 40) if method in ['RK23', 'RK45', 'LSODA']: assert_equal(res.njev, 0) assert_equal(res.nlu, 0) else: assert_(0 < res.njev < 3) assert_(0 < res.nlu < 10) y_true = sol_rational(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5)) tc = np.linspace(*t_span) yc_true = sol_rational(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, rtol, atol) assert_(np.all(e < 5)) tc = (t_span[0] + t_span[-1]) / 2 yc_true = sol_rational(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, rtol, atol) assert_(np.all(e < 5)) # LSODA for some reasons doesn't pass the polynomial through the # previous points exactly after the order change. It might be some # bug in LSOSA implementation or maybe we missing something. if method != 'LSODA': assert_allclose(res.sol(res.t), res.y, rtol=1e-15, atol=1e-15)
def test_max_step(): rtol = 1e-3 atol = 1e-6 y0 = [1/3, 2/9] for method in [RK23, RK45, Radau, BDF, LSODA]: for t_span in ([5, 9], [5, 1]): res = solve_ivp(fun_rational, t_span, y0, rtol=rtol, max_step=0.5, atol=atol, method=method, dense_output=True) assert_equal(res.t[0], t_span[0]) assert_equal(res.t[-1], t_span[-1]) assert_(np.all(np.abs(np.diff(res.t)) <= 0.5)) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) y_true = sol_rational(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5)) tc = np.linspace(*t_span) yc_true = sol_rational(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, rtol, atol) assert_(np.all(e < 5)) # See comment in test_integration. if method is not LSODA: assert_allclose(res.sol(res.t), res.y, rtol=1e-15, atol=1e-15) assert_raises(ValueError, method, fun_rational, t_span[0], y0, t_span[1], max_step=-1) if method is not LSODA: solver = method(fun_rational, t_span[0], y0, t_span[1], rtol=rtol, atol=atol, max_step=1e-20) message = solver.step() assert_equal(solver.status, 'failed') assert_("step size is less" in message) assert_raises(RuntimeError, solver.step)
def lab3(): # f = lambda x, y: x**2 + y**2 f = lambda x, y: x**2 + 3*x*y # x_start = -2 # x_end = 2 # x0 = 0 # y0 = [0.3] x_start = request.args.get('x_start', type=float) x_end = request.args.get('x_end', type=float) x0 = request.args.get('x0', type=float) y0 = request.args.getlist('y0', type=float) xs = ys = np.array([]) if x_start != None and x_end != None and x0 != None and y0 != None: solution = integrate.solve_ivp(f, (x_start, x_end), y0, max_step=0.1, min_step=0.1) ys = solution.y[0] xs = solution.t return render_template('lab3.html', x0=x0, y0=y0 , xs=xs, ys=ys)
def integrate(self, rho_0, times, method='BDF'): r"""Integrate the equation for a list of times with given initial conditions. :param rho_0: The initial state of the system :type rho_0: `numpy.array` :param times: A sequence of time points for which to solve for rho :type times: `list(real)` :returns: The components of the vecorized :math:`\rho` for all specified times :rtype: `Solution` """ rho_0_vec = sb.vectorize(np.kron(rho_0, np.eye(self.n_max + 1, dtype=np.complex)), self.basis).real ivp_soln = solve_ivp(lambda t, rho: self.a_fn(rho, t), (times[0], times[-1]), rho_0_vec, method=method, t_eval=times, jac=lambda t, rho: self.Dfun(t)) return integ.Solution(ivp_soln.y.T, self.basis)
def guess(problem): def u(x): return 4*constants.degree - x[[2]] def xdot(t, x): return problem.model.f(x, u(x), [1]) tf = 400 x0 = [0, 424.26, 0, 42e3] tspan = [0, tf] sol = integrate.solve_ivp(xdot, tspan, x0, max_step=1) x = interpolate.interp1d(sol.t / tf, sol.y)(problem.tc).T u = interpolate.interp1d(sol.t / tf, u(sol.y))(problem.tc).T p = np.array([tf]) dec0 = np.zeros(problem.ndec) problem.set_decision('p', p, dec0) problem.set_decision('u', u, dec0) problem.set_decision('x', x, dec0) return dec0
def integrate_non_herm(self, rho_0, times, method='BDF'): r"""Integrate the equation for a list of times with given initial conditions that may be non hermitian (useful for applications involving the quantum regression theorem). :param rho_0: The initial state of the system :type rho_0: `numpy.array` :param times: A sequence of time points for which to solve for rho :type times: `list(real)` :param method: The integration method for `scipy.integrate.solve_ivp` to use. :type method: String :returns: The components of the vecorized :math:`\rho` for all specified times :rtype: `Solution` """ rho_0_vec = sb.vectorize(rho_0, self.basis) ivp_soln = solve_ivp(lambda t, rho: self.a_fn(rho, t), (times[0], times[-1]), rho_0_vec, method=method, t_eval=times, jac=lambda t, rho: self.Dfun(rho, t)) return Solution(ivp_soln.y.T, self.basis)
def test_first_step(): rtol = 1e-3 atol = 1e-6 y0 = [1/3, 2/9] first_step = 0.1 for method in [RK23, RK45, Radau, BDF, LSODA]: for t_span in ([5, 9], [5, 1]): res = solve_ivp(fun_rational, t_span, y0, rtol=rtol, max_step=0.5, atol=atol, method=method, dense_output=True, first_step=first_step) assert_equal(res.t[0], t_span[0]) assert_equal(res.t[-1], t_span[-1]) assert_allclose(first_step, np.abs(res.t[1] - 5)) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) y_true = sol_rational(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5)) tc = np.linspace(*t_span) yc_true = sol_rational(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, rtol, atol) assert_(np.all(e < 5)) # See comment in test_integration. if method is not LSODA: assert_allclose(res.sol(res.t), res.y, rtol=1e-15, atol=1e-15) assert_raises(ValueError, method, fun_rational, t_span[0], y0, t_span[1], first_step=-1) assert_raises(ValueError, method, fun_rational, t_span[0], y0, t_span[1], first_step=5)
def test_integration_complex(): rtol = 1e-3 atol = 1e-6 y0 = [0.5 + 1j] t_span = [0, 1] tc = np.linspace(t_span[0], t_span[1]) for method, jac in product(['RK23', 'RK45', 'BDF'], [None, jac_complex, jac_complex_sparse]): with suppress_warnings() as sup: sup.filter(UserWarning, "The following arguments have no effect for a chosen solver: `jac`") res = solve_ivp(fun_complex, t_span, y0, method=method, dense_output=True, rtol=rtol, atol=atol, jac=jac) assert_equal(res.t[0], t_span[0]) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) assert_(res.nfev < 25) if method == 'BDF': assert_equal(res.njev, 1) assert_(res.nlu < 6) else: assert_equal(res.njev, 0) assert_equal(res.nlu, 0) y_true = sol_complex(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5)) yc_true = sol_complex(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, rtol, atol) assert_(np.all(e < 5))
def test_integration_sparse_difference(): n = 200 t_span = [0, 20] y0 = np.zeros(2 * n) y0[1::2] = 1 sparsity = medazko_sparsity(n) for method in ['BDF', 'Radau']: res = solve_ivp(fun_medazko, t_span, y0, method=method, jac_sparsity=sparsity) assert_equal(res.t[0], t_span[0]) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) assert_allclose(res.y[78, -1], 0.233994e-3, rtol=1e-2) assert_allclose(res.y[79, -1], 0, atol=1e-3) assert_allclose(res.y[148, -1], 0.359561e-3, rtol=1e-2) assert_allclose(res.y[149, -1], 0, atol=1e-3) assert_allclose(res.y[198, -1], 0.117374129e-3, rtol=1e-2) assert_allclose(res.y[199, -1], 0.6190807e-5, atol=1e-3) assert_allclose(res.y[238, -1], 0, atol=1e-3) assert_allclose(res.y[239, -1], 0.9999997, rtol=1e-2)
def calc_R(planet, R_guess, dr_coeff, EOS, R_guess_history, R_guess_max=None, R_guess_min=None, uniform=True, T_jump=False): ''' input: M_core: mass of core X: envelope mass / core mass # new X_He: Helium mass / envelope mass # new f_M: metal mass / core mass R_guess: initial guess of radius T_eff, P_eff: upper boundary condition # new dr_coeff: a coeffcient to set the maxium possible dr for the RK4 integrator uniform: uniform dissolved gas assumption T_jump: whether there is a temperature jump between the magma ocean and iron core EOS_H, EOS_He: input tables of H and He EOS EnvValueRecorder, ValueRecorder, MetalValueRecorder: value recorder of the integration values (for debugging purpose) EOS_Si_obj: input object of silicate EOS ''' # append to guess history logging.debug('Start calculating R') R_guess_history.r.append(R_guess) R_earth = 6371000 # define the range of R_guess to from 0.5*R_earth to 10*R_earth if not R_guess_max: R_guess_max = R_guess * 1e1 if not R_guess_min: R_guess_min = R_guess * 0.5 planet.reset() # integration details dr_max = dr_coeff * R_guess # set the max possible dr for the RK4 integrator r_lim = 5 # stop integration when r is smaller than 5 * dr # get constants G = gravitational_constant while True: # atmostpheric integration try: def reach_boundary(r, y, *args): return y[0] - ( planet.M_total - planet.M_env ) # when mass reaches the iron core boundary, stop integration reach_boundary.terminal = True sol = solve_ivp( func_env, t_span=(R_guess, r_lim * abs(dr_max)), # integrate from R_guess to 0 y0=(planet.M_total, planet.P_eff, planet.T_eff), # initial y method='RK45', # Explicit Runge-Kutta method of order 5(4) max_step=abs(dr_max), # maximum stepsize is dr events=[reach_boundary], args=[EOS, planet] # pass in additional args ) except: raise Exception("Integration fails for envelope.") break_, R_guess_max, R_guess_min = evaluate_boundary( planet.Env, planet.M_total - planet.M_env, R_guess, R_guess_max, R_guess_min) if break_: print("Break @ Env") R_guess_history.r_env_boundary_pair.append( (R_guess, None)) # ===== debugging purpose break planet.Env.cut_r(sol.t_events[0][0]) planet.Env = adjust_boundary_env(planet, planet.M_total - planet.M_env, EOS) # get T_EC, P_EC for mantle T_EC = planet.Env.T[-1] P_EC = planet.Env.P[-1] print("T_EC = {:.2f} K, P_EC = {:.2f} GPa".format(T_EC, P_EC / 1e9)) # for silicate, get S from T and P at the envelope-mantle boundary # then interpolate the EOS_Si with a fixed entropy S_Si S_Si = interpolate_S(T_EC, P_EC, EOS.EOS_Si_obj) EOS.get_EOS_Si(S_Si) # interpolate other initial conditions rho_Si = planet.Mantle.interpolate_curve_w_flag(P_EC, EOS.EOS_Si, target="rho", col1="P") rho_H = planet.Mantle.interpolate_df_w_flag(T_EC, P_EC, EOS.EOS_H, target="rho") rho_He = planet.Mantle.interpolate_df_w_flag(T_EC, P_EC, EOS.EOS_He, target="rho") # calculate the density of mixture at the envelope-mantle boundary rho = calc_rho(rho_Si, rho_H, rho_He, planet.f, planet.f_He) try: # integration over the mantle planet.Mantle.set_T(T_EC) def reach_boundary(r, y, *args): return y[ 0] - planet.M_metal # when mass reaches the iron core boundary, stop integration reach_boundary.terminal = True sol = solve_ivp( func_mantle, t_span=(planet.Env.r[-1], r_lim * abs(dr_max)), # integrate from R_guess to 0 y0=(planet.Env.M[-1], P_EC), # initial y method='RK45', # Explicit Runge-Kutta method of order 5(4) max_step=abs(dr_max), # maximum stepsize is dr events=[reach_boundary], args=[EOS, planet] # pass in additional args ) except: raise Exception("Integration fails for mantle.") # process_integration result break_, R_guess_max, R_guess_min = evaluate_boundary( planet.Mantle, planet.M_metal, R_guess, R_guess_max, R_guess_min) R_guess_history.r_env_boundary_pair.append( (R_guess, planet.Env.r[-1])) # ===== debugging purpose if break_: print("Break @ Mantle") break try: planet.Mantle.cut_r(sol.t_events[0][0]) except: print(sol.t_events) return R_guess, planet planet.Mantle = adjust_boundary(planet.Mantle, planet.M_metal, EOS.EOS_Si) # integration for metal core try: def reach_boundary(r, y, *args): return y[0] # when mass = 0 reach_boundary.terminal = True solve_ivp( func_metal, t_span=(planet.Mantle.r[-1], r_lim * abs(dr_max)), # integrate from R_guess to 0 y0=(planet.M_metal, planet.Mantle.P[-1]), # initial y method='RK45', # Explicit Runge-Kutta method of order 5(4) max_step=abs(dr_max), # maximum stepsize is dr events=[reach_boundary], args=[planet] # pass in additional args ) except: logging.error("Integration for metal ends at r = {}".format( planet.Metal.r[-1])) raise Exception("Integration fails for metal.") # post integration last_r = planet.Metal.r[-1] if last_r > 0: # if the last radius is small enough # calculate the mass for the last bit of metal component planet.Metal.M.append(planet.Metal.M[-1] - \ calc_M_Fe(planet.Metal.rho[-1], planet.Metal.r[-1])) planet.Metal.r.append(0) planet.Metal.P.append(planet.Metal.P[-1]) planet.Metal.rho.append(planet.Metal.rho[-1]) # evaluate the error of integration result last_layer_M = planet.Metal.M[-1] error_ratio = last_layer_M / planet.M_core print("M_error / M_core: {:.2f}%".format(error_ratio * 100)) logging.info("M_error / M_core: {:.2f}%".format(error_ratio * 100)) if abs(error_ratio) <= 0.01: if planet.Mantle.out_of_table or planet.Metal.out_of_table or planet.Env.out_of_table: logging.error( "Integration finishes out of table, at R = {}".format( R_guess)) raise Exception( "Integration finishes out of table, at R = {}".format( R_guess)) else: logging.info("Integration finishes at {}".format(R_guess)) return R_guess, planet #====== debugging purpose elif error_ratio > 0.001: R_guess_min = R_guess # increase R_guess R_guess_history.m_error_pair.append((R_guess, error_ratio)) break else: R_guess_max = R_guess # decrease R_guess R_guess_history.m_error_pair.append((R_guess, error_ratio)) break # if R_guess needs to be adjusted and re-integrated R_guess_next = np.sqrt(R_guess_max * R_guess_min) logging.info("\nnew_R_guess: {:.3f} R_E".format(R_guess_next / 6371000)) print("\nnew_R_guess: {:.3f} R_E".format(R_guess_next / 6371000)) return calc_R(planet, R_guess_next, dr_coeff, EOS, R_guess_history, R_guess_max, R_guess_min, uniform=True, T_jump=False)
def step(x0, p, prev_sol=None): ''' Take one step from apex to apex/failure. returns a sol object from integrate.solve_ivp, with all phases ''' # * nested functions - scroll down to step code * # # unpacking constants MAX_TIME = 5 MODEL_TYPE = p['model_type'] assert (MODEL_TYPE == 0 or MODEL_TYPE == 1) if MODEL_TYPE == 0: assert (len(x0) == 7) elif MODEL_TYPE == 1: assert (len(x0) == 10) else: raise Exception('model_type is not set correctly') AOA = p['angle_of_attack'] GRAVITY = p['gravity'] MASS = p['mass'] SPRING_RESTING_LENGTH = p['spring_resting_length'] STIFFNESS = p['stiffness'] SPECIFIC_STIFFNESS = p['stiffness'] / p['mass'] ACTUATOR_RESTING_LENGTH = p['actuator_resting_length'] DAMPING_TYPE = p['damping_type'] ACTUATOR_FORCE = 0 # @jit(nopython=True) def flight_dynamics(t, x): # swing leg retraction vfx = 0 vfy = 0 if p['swing_type'] == 1 and x[3] <= 0: alpha = np.arctan2(x[1] - x[5], x[0] - x[4]) - np.pi / 2.0 vPerp = p['swing_leg_angular_velocity'] * (SPRING_RESTING_LENGTH + ACTUATOR_RESTING_LENGTH) vfx = vPerp * np.cos(alpha) vfy = vPerp * np.sin(alpha) # code in flight dynamics, xdot_ = f() if (MODEL_TYPE == 0): return np.array( [x[2], x[3], 0, -GRAVITY, x[2] + vfx, x[3] + vfy, 0]) elif (MODEL_TYPE == 1): #The actuator length does not change, and no work is done. return np.array( [x[2], x[3], 0, -GRAVITY, x[2] + vfx, x[3] + vfy, 0, 0, 0, 0]) else: raise Exception('model_type is not set correctly') # @jit(nopython=True) def stance_dynamics(t, x): # stance dynamics alpha = np.arctan2(x[1] - x[5], x[0] - x[4]) - np.pi / 2.0 leg_length = np.hypot(x[0] - x[4], x[1] - x[5]) # output = x spring_length = compute_spring_length(x, p) spring_force = STIFFNESS * (SPRING_RESTING_LENGTH - spring_length) ldotdot = spring_force / MASS xdotdot = -ldotdot * np.sin(alpha) ydotdot = ldotdot * np.cos(alpha) - GRAVITY if MODEL_TYPE == 0: output = np.array([x[2], x[3], xdotdot, ydotdot, 0, 0, 0]) elif MODEL_TYPE == 1: actuator_open_loop_force = 0 if np.shape(p['actuator_force'])[0] > 0: actuator_open_loop_force = np.interp( t, p['actuator_force'][0, :], p['actuator_force'][1, :], period=p['actuator_force_period']) actuator_damping_coefficient = 0 if DAMPING_TYPE == 0: actuator_damping_coefficient = ( p['constant_normalized_damping'] * p['stiffness']) elif DAMPING_TYPE == 1: damping_min = (p['linear_normalized_damping_coefficient'] * p['mass'] * p['gravity'] * p['linear_minimum_normalized_damping']) damping_val = (actuator_open_loop_force * p['linear_normalized_damping_coefficient']) actuator_damping_coefficient = np.maximum([damping_min], [damping_val])[0] else: raise Exception('damping_type is not set correctly') actuator_damping_force = spring_force - actuator_open_loop_force ladot = -actuator_damping_force / actuator_damping_coefficient wadot = actuator_open_loop_force * ladot wddot = actuator_damping_force * ladot #These forces are identical to the slip: there's no (other) mass # between the spring and the point mass #ldotdot = (actuator_open_loop_force+actuator_damping_force)/MASS #xdotdot = -ldotdot*np.sin(alpha) #ydotdot = ldotdot*np.cos(alpha) - GRAVITY output = np.array( [x[2], x[3], xdotdot, ydotdot, 0, 0, ladot, wadot, wddot, 0]) else: raise Exception('model_type is not set correctly') return output # @jit(nopython=True) def fall_event(t, x): ''' Event function to detect the body hitting the floor (failure) ''' return x[1] fall_event.terminal = True fall_event.terminal = -1 # @jit(nopython=True) def touchdown_event(t, x): ''' Event function for foot touchdown (transition to stance) ''' # x[1]- np.cos(p['angle_of_attack'])*SPRING_RESTING_LENGTH # (which is = x[5]) return x[5] - x[-1] # final state is ground height touchdown_event.terminal = True # no longer actually necessary... touchdown_event.direction = -1 # @jit(nopython=True) def liftoff_event(t, x): ''' Event function to reach maximum spring extension (transition to flight) ''' spring_length = compute_spring_length(x, p) event_val = spring_length - SPRING_RESTING_LENGTH return event_val liftoff_event.terminal = True liftoff_event.direction = 1 # @jit(nopython=True) def apex_event(t, x): ''' Event function to reach apex ''' return x[3] apex_event.terminal = True # * Start of step code * # # TODO: properly update sol object with all info, not just the trajectories # take one step (apex to apex) # the "step" function in MATLAB # x is the state vector, a list or np.array # p is a dict with all the parameters # set integration options if prev_sol is not None: t0 = prev_sol.t[-1] else: t0 = 0 # starting time # * FLIGHT: simulate till touchdown events = [fall_event, touchdown_event] sol = integrate.solve_ivp(flight_dynamics, t_span=[t0, t0 + MAX_TIME], y0=x0, events=events, max_step=0.01) # TODO Put each part of the step into a list, so you can concat them # TODO programmatically, and reduce code length. # if you fell, stop now if sol.t_events[0].size != 0: # if empty if prev_sol is not None: sol.t = np.concatenate((prev_sol.t, sol.t)) sol.y = np.concatenate((prev_sol.y, sol.y), axis=1) sol.t_events = prev_sol.t_events + sol.t_events return sol # * STANCE: simulate till liftoff events = [fall_event, liftoff_event] x0 = sol.y[:, -1] sol2 = integrate.solve_ivp(stance_dynamics, t_span=[sol.t[-1], sol.t[-1] + MAX_TIME], y0=x0, events=events, max_step=0.001) # if you fell, stop now if sol2.t_events[0].size != 0: # if empty # concatenate all solutions sol.t = np.concatenate((sol.t, sol2.t)) sol.y = np.concatenate((sol.y, sol2.y), axis=1) sol.t_events += sol2.t_events if prev_sol is not None: # concatenate to previous solution sol.t = np.concatenate((prev_sol.t, sol.t)) sol.y = np.concatenate((prev_sol.y, sol.y), axis=1) sol.t_events = prev_sol.t_events + sol.t_events return sol # * FLIGHT: simulate till apex events = [fall_event, apex_event] x0 = reset_leg(sol2.y[:, -1], p) sol3 = integrate.solve_ivp(flight_dynamics, t_span=[sol2.t[-1], sol2.t[-1] + MAX_TIME], y0=x0, events=events, max_step=0.01) # concatenate all solutions sol.t = np.concatenate((sol.t, sol2.t, sol3.t)) sol.y = np.concatenate((sol.y, sol2.y, sol3.y), axis=1) sol.t_events += sol2.t_events + sol3.t_events if prev_sol is not None: sol.t = np.concatenate((prev_sol.t, sol.t)) sol.y = np.concatenate((prev_sol.y, sol.y), axis=1) sol.t_events = prev_sol.t_events + sol.t_events return sol
def result(self,t = None, anim = False, interval = 50, every_n_iter = 1): ''' Plot trainning process at animation Parameters ---------- t : array, optional evaluate at these points anim : bool, optional whether to plot animation or not, default set to False interval : integer, optional time duration between frames, in ms, default set to 50 ms every_n_iter : integer, optional plot every n iterations of the trainning process, if num of iteration if large, increase every_n_iter to save computing, default set to 1, plotting all the iterations ''' if t is None: t = self.t if anim: #training animation y_train = np.array([self.predict(t = t.reshape(-1,1), params_list=x) for x in self.x])[::-every_n_iter][::-1] n = y_train.shape[1] fig, ax = plt.subplots(1,2,figsize = (16,6)) #ground truth using scipy sol_cont = solve_ivp(self.f, [t.min(), t.max()], self.y0_list, method='Radau', rtol=1e-5) sol_dis = solve_ivp(self.f, t_span = [t.min(), t.max()], t_eval=t, y0 = self.y0_list, method='Radau', rtol=1e-5) y_diff = np.array([np.array(sol_dis.y[i]) for i in range(n)]) #set x y limit using min and max of the last iteration ax[0].set_xlim((t[0], t[-1])) ax[0].set_ylim((np.min(y_train[-1,:,:]), np.max(y_train[-1,:,:]))) ax[1].set_xlim((t[0], t[-1])) ax[1].set_ylim((np.min(y_train[-1,:,:] - y_diff), np.max(y_train[-1,:,:] - y_diff))) #plot ground truth for i in range(n): ax[0].plot(sol_cont.t, sol_cont.y[i], label='y{}'.format(i+1)) #plots of NN result scatters_pred = [] scatters_diff = [] for i in range(n): scat1 = ax[0].scatter([], [], label = 'y_pred{}'.format(i+1)) scatters_pred.append(scat1) scat2 = ax[1].scatter([], [], label = 'y{}'.format(i+1)) scatters_diff.append(scat2) ax[0].legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),fancybox=True, ncol=4) ax[1].legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),fancybox=True, ncol=4) ax[0].set_title("NN Prediction and Truth", fontsize = 18) ax[1].set_title("NN Prediction - Truth", fontsize = 18) # initialization function: plot the background of each frame def init(): for k in range(n): scatters_pred[k].set_offsets(np.hstack(([], []))) scatters_diff[k].set_offsets(np.hstack(([], []))) return (scatters_pred + scatters_diff) # animation function. This is called sequentially def animate(i): for k in range(n): scatters_pred[k].set_offsets(np.c_[t, y_train[i,k,:]]) scatters_diff[k].set_offsets(np.c_[t, y_train[i,k,:] - y_diff[k]]) return (scatters_pred + scatters_diff) # call the animator. blit=True means only re-draw the parts that have changed. anim_pred = animation.FuncAnimation(fig, animate, init_func=init, frames=y_train.shape[0], interval=interval, blit=True) return anim_pred
StartTime = 0.5 # Time the y(t) input will begin DistStart = 4.5 # Time the disturbance input will begin F_amp = 100.0 # Amplitude of Disturbance force (N) # Pack the parameters and initial conditions into arrays p = [m, k, c, Distance, StartTime, Amax, Vmax, DistStart, F_amp] x0 = [x_init, x_dot_init, y_init, y_dot_init] # Call the ODE solver. # TODO: 05/22/18 - JEV - What is the best set of solver parameters for # a baseline, default, 1st-try solution? solution = solve_ivp(eq_of_motion, [0, 10], x0, #dense_output=True, #t_eval=t, max_step=max_step, atol=abserr, rtol=relerr ) # Parse the time and response arrays from the OdeResult object sim_time = solution.t resp = solution.y #----- Plot the response # Make the figure pretty, then plot the results # "pretty" parameters selected based on pdf output, not screen output # Many of these setting could also be made default by the .matplotlibrc file fig = plt.figure(figsize=(6,4))
import numpy as np from scipy.integrate import odeint,solve_ivp import scipy from numpy import sqrt, exp import matplotlib.pyplot as plt def model(t,z): # print(z) y1=z[0] y2=z[1] return [y2,-y2+4*y1+t*exp(-t)] # initial condition z0 = np.array([1,0]) solve = solve_ivp(model,[0, 2],z0,method='LSODA',min_step=0.01,max_step=0.01) Time=solve.t z=solve.y # print(z) Y1=z[0] Y2=z[1] plt.subplot(221) plt.plot(Time,Y1) # plt.show() plt.subplot(222) plt.plot(Time,Y2) # plt.show() plt.subplot(223)
def single_reservoir_pump_pipe_tank_ode_solution(h20,D,d,L,C,tf,pA,pB,pC, dt_max,vcurve=None, include_pump_control=False, pump_off_level=0, pump_back_on_level=0): """This produces a numerical solution to a water network that involves 1 reservoir, 1 pump extracting water from the reservoir, a single pipe through which the water runs uphill with frictional losses, and a tank in which the water is stored. The solution involves a single ordinary differential equation which is derived from the energy balance, hazen williams head loss function, and the derivative of tank head as a function of time The pump is allowed to pump water until the pump head vs. the water tank head reach equillibrium The solution is units dependent and all inputs must be in SI! Inputs: h20 - elevation head of the water tank (w/r to the pump head) water surface at time 0 (meters) D - Diameter of the water tank (constant) (meters) d - pipe diameter leading to the water tank (meters) L - pipe length leading to the water tank (meters) C - pipe friction factor (unitless ratio) tf - final time to simulate (s) Returns Q - flow through the entire system as a function of time (m3/s) t - time (s) h2 - Water tank surface elevation height """ def S_hazen_will_si(Q,C,d): """ returns meters (water) per meter length of pipe""" return 10.67 * (Q/C) ** 1.852 / d ** 4.8702 def pump_func(Q,pA,pB,pC): return pA - pB * Q ** pC def energy_balance_time0(Q,h2,d,D,L,C,pA,pB,pC,vcurve,dh,h20): """ Should balance to zero """ H2 = h2 # velocity head is not included here.?? Because everything is initially at rest + v_head(Q,D,h2,vcurve,dh,h20) H1 = pump_func(Q,pA,pB,pC) return H1 - H2 - L * S_hazen_will_si(Q,C,d) def energy_balance_no_pump(Q,h2,d,D,L,C,vcurve,dh,h20): return (4.0*Q/(pi * d**2.0))**2/(2*9.81) - v_head(Q,d,h2,vcurve,dh,h20) - h2 + L * S_hazen_will_si(Q,C,d) def v_head(Q,diam,h2,vcurve,dh,h20): dVdh2 = dVdh2_func(D,h2,vcurve,dh,h20) return (Q/dVdh2)**2.0 / (2 * 9.81) def dVdh2_func(D,h2,vcurve,dh,h20): if vcurve is None: dVdh2 = pi * D ** 2.0 / 4.0 else: V0 = interp(h2-h20,vcurve[:,0],vcurve[:,1]) V1 = interp(h2-h20 + dh,vcurve[:,0],vcurve[:,1]) dVdh2 = (V1 - V0)/dh if dVdh2 == 0.0: raise ValueError("The depth-volume curve must not have a zero slope!") return dVdh2 def diff_eq(t,x,d,D,C,L,pA,pB,pC,vcurve,dh,h20,pump_on): # this can be derived from differentiating the energy balance and considering # the head gain integral of the tank becomes dh/dt = Q/A # the return is for dQ/dt and dh/dt Q = x[0] h2 = x[1] if pump_on: dVdh2 = dVdh2_func(D,h2,vcurve,dh,h20) HZ_WIL = L * 1.852 * 10.67 * Q**0.852 / (C**1.852 * d**4.8702) uu = ((Q/dVdh2) / (pB*pC * Q ** (pC-1.0) - (Q / (dVdh2)**2)/9.81 - HZ_WIL), Q / dVdh2 ) else: dVdh2 = dVdh2_func(D,h2,vcurve,-dh,h20) HZ_WIL = L * 1.852 * 10.67 * (-Q)**0.852 / (C**1.852 * d**4.8702) uu = (9.81*dVdh2 / (1.0 - (9.81*dVdh2**2*(HZ_WIL)/Q)), Q / dVdh2) return uu[0], uu[1] def choose_event(t,x,next_is_pump_on,event_1_threshold,event_2_threshold,include_pump_controls): if include_pump_controls: if not next_is_pump_on: return pump_off_if_above_thresh(t,x,event_1_threshold) else: return pump_on_if_below_thresh(t,x,event_2_threshold) else: return 1.0 def pump_off_if_above_thresh(t, x,thresh): h2 = x[1] if h2 < thresh: pump_on = 1.0 else: pump_on = -1.0 return pump_on def pump_on_if_below_thresh(t,x,thresh): h2 = x[1] if h2 > thresh: pump_off = 1.0 else: pump_off = -1.0 return pump_off if h20 > pA: raise ValueError("The selected pump is incapable of pumping water into the tank!") dh = 0.0000001 # first solve the initial state Q0_list = [exp(log((pA-h20)/pB)/pC)] # this is the solution with zero friction losses Q0 = fsolve(energy_balance_time0, Q0_list, args=(h20,d,D,L,C,pA,pB,pC,vcurve,dh,h20)) #Q0 = exp(log((pA-h20)/pB)/pC) # make sure the solution is valid! assert abs(energy_balance_time0(Q0,h20,d,D,L,C,pA,pB,pC,vcurve,dh,h20)) <= 0.00001 # now solve the differential equation pump_on = True sol = [] tmax = 0.0 next_is_1 = True h2_start = h20 while (tmax < tf): event_func = lambda t,x:choose_event(t,x,not pump_on,pump_off_level,pump_back_on_level,include_pump_control) event_func.terminal = True temp_sol = solve_ivp(lambda t,x:diff_eq(t,x,d,D,C,L,pA,pB,pC,vcurve,dh, h20,pump_on), (tmax,tf),array([Q0,h2_start]),max_step=dt_max, events=event_func) tmax = max(temp_sol.t) if tmax < tf: next_is_1 = not next_is_1 pump_on = not pump_on h2_start = temp_sol.y[1,-1] Q0_list = [0.1] if pump_on: Q0 = fsolve(energy_balance_time0, Q0_list, args=(h2_start,d,D,L,C,pA,pB,pC,vcurve,dh,h20)) assert abs(energy_balance_time0(Q0,h2_start,d,D,L,C,pA,pB,pC,vcurve,dh,h20)) <= 0.00001 else: try: Q0 = fsolve(energy_balance_no_pump, Q0_list,args=(h2_start,d,D,L,C,vcurve,dh,h20) ) except: raise RuntimeError("The nonlinear solver for no-pump conditions failed!") assert abs(energy_balance_no_pump(Q0,h2_start,d,D,L,C,vcurve,dh,h20)) <= 0.00001 Q0 = -Q0 sol.append(temp_sol) t = array([]) Q = array([]) h2 = array([]) for sl in sol: t = concatenate((t,sl.t),axis=0) Q = concatenate((Q,sl.y[0,:])) h2 = concatenate((h2,sl.y[1,:])) return Q,t,h2
print(Em) vals, vects = np.linalg.eig(Em) print(vals[np.abs(np.real(vals)) > 1]) Em = 1/(dx)*Em def odesys(t, y): dydt = np.zeros(2*N) #y[N] = (12.0/25)*(4*y[N+1]-3*y[N+2]+(4.0/3)*y[N+3]-(1.0/4)*y[N+4]) y = np.transpose(y) dydt[:N] = np.dot(Em, y[N:]) dydt[N:] = np.dot(Hm, y[:N]) return dydt T = 500 sol = solve_ivp(odesys, [0, T], initial, max_step=dx,rtol=1e-5,atol=1e-8, method='RK45') #sol = solve_ivp(odesys, [0, T], initial, max_step=dx, method='RK45') Herr=np.zeros(len(sol.t)) Eerr=np.zeros(len(sol.t)) Herrmin=np.zeros(len(sol.t)) Eerrmin=np.zeros(len(sol.t)) H = H00 + np.array([0.0 for i in range(N)]) E = np.array([0.0 for i in range(N)]) t = sol.t XX, TT = np.meshgrid(xx, t) for k in range(1,151): H = H + h.Hn(XX, TT, k, L) E = E + h.En(XX, TT, k, L) Herr = np.amax(np.abs(sol.y[:N] - np.transpose(H)), axis=0) Eerr = np.amax(np.abs(sol.y[N:] - np.transpose(E)), axis=0)
init_cond = [i0, a0, m0, z0, s0] # Parameters # There are no parameters in this model. params = None # Integration sol_BDF = solve_ivp( fun=system, t_span=t_span, y0=init_cond, method="BDF", dense_output=True, rtol=1e-6, atol=1e-8, first_step=(t_end - t_start) * 1e-5, args=params, ) t = np.logspace(start=-5, stop=np.log10(t_end), num=int(1e4)) y = sol_BDF.sol(t) # Save data in file data = np.stack((t, y[0], y[1], y[2], y[3], y[4]), axis=1) np.savetxt( join(dirname(abspath(__file__)), "plots/python.dat"), data, header="t \t i(t) \t a(t) \t m(t) \t z(t) \t s(t) \n",
def _integrate(self, model, t_eval, inputs=None): """ Solve a model defined by dydt with initial conditions y0. Parameters ---------- model : :class:`pybamm.BaseModel` The model whose solution to calculate. t_eval : :class:`numpy.array`, size (k,) The times at which to compute the solution inputs : dict, optional Any input parameters to pass to the model when solving Returns ------- object An object containing the times and values of the solution, as well as various diagnostic messages. """ if model.convert_to_format == "casadi": inputs = casadi.vertcat(*[x for x in inputs.values()]) extra_options = { **self.extra_options, "rtol": self.rtol, "atol": self.atol } # Initial conditions y0 = model.y0 if isinstance(y0, casadi.DM): y0 = y0.full().flatten() # check for user-supplied Jacobian implicit_methods = ["Radau", "BDF", "LSODA"] if np.any([self.method in implicit_methods]): if model.jacobian_eval: extra_options.update({ "jac": lambda t, y: model.jacobian_eval(t, y, inputs) }) # make events terminal so that the solver stops when they are reached if model.terminate_events_eval: def event_wrapper(event): def event_fn(t, y): return event(t, y, inputs) event_fn.terminal = True return event_fn events = [ event_wrapper(event) for event in model.terminate_events_eval ] extra_options.update({"events": events}) sol = it.solve_ivp(lambda t, y: model.rhs_eval(t, y, inputs), (t_eval[0], t_eval[-1]), y0, t_eval=t_eval, method=self.method, dense_output=True, **extra_options) if sol.success: # Set the reason for termination if sol.message == "A termination event occurred.": termination = "event" t_event = [] for time in sol.t_events: if time.size > 0: t_event = np.append(t_event, np.max(time)) t_event = np.array([np.max(t_event)]) y_event = sol.sol(t_event) elif sol.message.startswith( "The solver successfully reached the end"): termination = "final time" t_event = None y_event = np.array(None) return pybamm.Solution(sol.t, sol.y, t_event, y_event, termination) else: raise pybamm.SolverError(sol.message)
def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): idx = self.options['index'] gd = self.options['grid_data'] iface_prob = self.options['ode_integration_interface'].prob # Create the vector of initial state values self.initial_state_vec[:] = 0.0 pos = 0 for name, options in iteritems(self.options['state_options']): size = np.prod(options['shape']) self.initial_state_vec[pos:pos + size] = \ np.ravel(inputs['initial_states:{0}'.format(name)]) pos += size # Setup the control interpolants if self.options['control_options']: t0_seg = inputs['time'][0] tf_seg = inputs['time'][-1] for name, options in iteritems(self.options['control_options']): ctrl_vals = inputs['controls:{0}'.format(name)] self.options['ode_integration_interface'].control_interpolants[ name].setup(x0=t0_seg, xf=tf_seg, f_j=ctrl_vals) # Setup the polynomial control interpolants if self.options['polynomial_control_options']: t0_phase = inputs['t_initial'] tf_phase = inputs['t_initial'] + inputs['t_duration'] for name, options in iteritems( self.options['polynomial_control_options']): ctrl_vals = inputs['polynomial_controls:{0}'.format(name)] self.options[ 'ode_integration_interface'].polynomial_control_interpolants[ name].setup(x0=t0_phase, xf=tf_phase, f_j=ctrl_vals) # Set the values of t_initial and t_duration iface_prob.set_val('t_initial', value=inputs['t_initial'], units=self.options['time_options']['units']) iface_prob.set_val('t_duration', value=inputs['t_duration'], units=self.options['time_options']['units']) # Set the values of the phase design parameters if self.options['design_parameter_options']: for param_name, options in iteritems( self.options['design_parameter_options']): val = inputs['design_parameters:{0}'.format(param_name)] iface_prob.set_val('design_parameters:{0}'.format(param_name), value=val, units=options['units']) # Set the values of the phase input parameters if self.options['input_parameter_options']: for param_name, options in iteritems( self.options['input_parameter_options']): iface_prob.set_val( 'input_parameters:{0}'.format(param_name), value=inputs['input_parameters:{0}'.format(param_name)], units=options['units']) # Set the values of the trajectory parameters if self.options['traj_parameter_options']: for param_name, options in iteritems( self.options['traj_parameter_options']): iface_prob.set_val( 'traj_parameters:{0}'.format(param_name), value=inputs['traj_parameters:{0}'.format(param_name)], units=options['units']) # Setup the evaluation times. if self.options['output_nodes_per_seg'] is None: # Output nodes given as subset, convert segment tau of nodes to time i1, i2 = gd.subset_segment_indices['all'][idx, :] indices = gd.subset_node_indices['all'][i1:i2] nodes_eval = gd.node_stau[ indices] # evaluation nodes in segment tau space t_initial = inputs['time'][0] t_duration = inputs['time'][-1] - t_initial t_eval = t_initial + 0.5 * (nodes_eval + 1) * t_duration else: # Output nodes given as number, linspace them across the segment t_eval = np.linspace(inputs['time'][0], inputs['time'][-1], self.options['output_nodes_per_seg']) # Perform the integration using solve_ivp sol = solve_ivp(fun=self.options['ode_integration_interface'], t_span=(inputs['time'][0], inputs['time'][-1]), y0=self.initial_state_vec, method=self.options['method'], atol=self.options['atol'], rtol=self.options['rtol'], t_eval=t_eval) # Extract the solution pos = 0 for name, options in iteritems(self.options['state_options']): size = np.prod(options['shape']) outputs['states:{0}'.format(name)] = sol.y[pos:pos + size, :].T pos += size
# Integration tf = tf kwargs = { 'N': N, 'W': W, 'k_prior': k_prior, 'k_cue0': k_cue0, 'v_noise': v_noise, 'sigma2_W': sigma2_W, 'xNoise': xNoise, 'xTarget': xTarget, 'T_theta': T_theta } sol = solve_ivp(lambda t, y: mainode(t, y, **kwargs), (0, tf), x0, events=events, t_eval=t_eval) t = sol.t tNow = sol.t[-1] x_t = sol.y xNow = sol.y[:, -1] t_fire = sol.t_events # x_fire = [np.mod(ts/T_theta,1)*2*pi for ts in t_fire] print(sol.message) #%% # save result for current recall noise[:, :, k] = xNoise._xNoise_d.T recalled[:, :, k] = x_t t_fireList += [t_fire] #%%
def run_simulation(self, x0, y0, z0, lx0, lz0, theta, x_lim=[-50e3, 50e3], z_lim=-0.5e3): """ uses integrate.solve_ivp, with method='rk45' to solve the differential equations. """ theta = np.deg2rad(theta) kx0 = 2 * np.pi / lx0 * np.cos(theta) ky0 = 2 * np.pi / lx0 * np.sin(theta) kz0 = 2 * np.pi / lz0 # defining space limits for the rk45 algorithm def z_wall1(t, y): return y[2] - z_lim z_wall1.terminal = True def x_wall1(t, y): return y[0] - x_lim[0] x_wall1.terminal = True def x_wall2(t, y): return y[0] - x_lim[1] x_wall2.terminal = True # time_step = 0.1 * 60. # time_ = np.linspace(self.t0, self.t_final, int(self.t_final/time_step)+1) # for it in range(0, self.t_final, 1): # for jt in range(0,int(1/time_step),1): # tstart = it + jt*time_step # tend = it + jt*time_step + time_step # RK45 algorithm sol = integrate.solve_ivp(fun=self.odeparams, t_span=(self.t0, self.t_final), y0=(x0, y0, z0, kx0, ky0, kz0), method='RK45', t_eval=self.t_eval, events=[x_wall1, x_wall2, z_wall1]) #, max_step=100) # only for plotting purposes if x0 / 1000 == -20: x_, y_, z_ = [], [], [] print('len_t = ', len(sol.t)) # write to output file file_output = self.open_data_file() for i in range(len(sol.t)): x, y, z, kx, ky, kz = sol.y[:, i] # if x0/1000 == -20: # x_.extend(x) # y_.extend(y) # z_.extend(z) #print sol.t[i]/3600,sol.y[:,i] Lx = 2 * np.pi / kx Ly = 2 * np.pi / ky Lz = 2 * np.pi / kz omega, omega_0 = self.omega(x, y, z, kx, ky, kz) var = self.odeparams(sol.t[i], sol.y[:, i]) #print var file_output.write( self.output_line(sol.t[i], x, y, z, Lx, Ly, Lz, var, omega, omega_0)) file_output.close() # if x0/1000 == -20: # x_ = np.array(x_) # y_ = np.array(y_) # z_ = np.array(z_) # fig, ax = plt.subplots() # ax.plot( x/1e3, z ) # plt.show() return x, y, z, kx, ky, kz
# vit0R=c[4] Ifmincon = xsol.x[2] print("Ifmincom =", Ifmincon) mLfmincon = xsol.x[0] c = xsol.x paramR = (c[0:3]) pos0R = c[3] vit0R = c[4] mLI[num_Test] = [mLfmincon, Ifmincon] print("paramR = ", paramR) from scipy import integrate solEDR = integrate.solve_ivp(lambda t, y: EDCoulomb(t, y, paramR), (0, temp), (pos0R, vit0R), dense_output=True, max_step=0.001, rtol=1e-8, atol=1e-10) time = np.arange(0.0, len(a), 1) plt.figure(1) plt.figure(figsize=(8, 16)) #plt.gcf().subplots_adjust(wspace = 0, hspace = 4) plt.subplot(611) plt.ylabel('teta') plt.plot(time, a, 'k') plt.subplot(612) plt.ylabel('teta')
def update_seir(df, active_date, e_date, folder=None, l_date=None, confidence_interval=True): cols = list(df.columns) data = df[df["Date"] >= active_date] if l_date is None: l_date = active_date population = data["population"].min() N = population n_infected = data['InfectiousCases'].iloc[0] n_exposed = data['ExposedCases'].iloc[ 0] # data['ConfirmedCases_y'].iloc[0] n_hospitalized = data['HospitalizedCases'].iloc[0] n_critical = data['CriticalCases'].iloc[0] n_recovered = data['RecoveredCases'].iloc[0] n_deaths = data['ConfirmedDeaths'].iloc[0] # S, E, I, R, H, C, D initial_state = [(N - n_infected) / N, n_exposed / N, n_infected / N, n_recovered / N, n_hospitalized / N, n_critical / N, n_deaths / N] # t_hosp=7, t_crit=14, m_a=0.8, c_a=0.1, f_a=0.3 params = [7, 14, 0.8, 0.3, 0.3] params_name = ("t_hosp", "t_crit", "m", "c", "f") for i, param in enumerate(params_name): if param in cols: params[i] = data[param].mean() "decay_values" params.append(True) R_t = data['R'].values def time_varying_reproduction(t): index = np.min((int(t), len(R_t) - 1)) return R_t[index] args = (time_varying_reproduction, 5.6, 2.9, *params) init_date = datetime.combine(active_date, datetime.min.time()) max_days = ((e_date - pd.Timestamp(init_date)) / np.timedelta64(1, 'D')) max_days = int(max_days) sol = solve_ivp(SEIR_HCD_model, [0, max_days], initial_state, args=args, t_eval=np.arange(0, max_days)) sus, exp, inf, rec, hosp, crit, deaths = sol.y y_pred_cases = np.clip(inf + rec + hosp + crit + deaths, 0, np.inf) * population y_pred_critic = np.clip(crit, 0, np.inf) * population y_pred_hosp = np.clip(hosp, 0, np.inf) * population y_pred_deaths = np.clip(deaths, 0, np.inf) * population dates = data["Date"].iloc[1:] l = len(dates) dt = np.arange(l) ticks = dates.values # dt.strftime('%d/%m/%Y') fig_size = (20, 5) # print(l,len(y_pred_cases),y_pred_hosp_max.min(),y_pred_hosp_max.max() ) simulations = pd.DataFrame({ "Date": dates, "SimulationCases": y_pred_cases.astype(int), "SimulationHospital": y_pred_hosp.astype(int) + y_pred_critic.astype(int), "SimulationCritical": y_pred_critic.astype(int), "SimulationDeaths": y_pred_deaths.astype(int) }) simulations["R"] = data['R'].iloc[1:].values if confidence_interval: R_t = data['R_min'].values args = (time_varying_reproduction, 5.6, 2.9, *params) sol = solve_ivp(SEIR_HCD_model, [0, max_days], initial_state, args=args, t_eval=np.arange(0, max_days)) sus_min, exp_min, inf_min, rec_min, hosp_min, crit_min, deaths_min = sol.y R_t = data['R_max'].values args = (time_varying_reproduction, 5.6, 2.9, *params) sol = solve_ivp(SEIR_HCD_model, [0, max_days], initial_state, args=args, t_eval=np.arange(0, max_days)) sus_max, exp_max, inf_max, rec_max, hosp_max, crit_max, deaths_max = sol.y y_pred_cases_min = np.clip( inf_min + rec_min + hosp_min + crit_min + deaths_min, 0, np.inf) * population y_pred_critic_min = np.clip(crit_min, 0, np.inf) * population y_pred_hosp_min = np.clip(hosp_min, 0, np.inf) * population y_pred_deaths_min = np.clip(deaths_min, 0, np.inf) * population y_pred_cases_max = np.clip( inf_max + rec_max + hosp_max + crit_max + deaths_max, 0, np.inf) * population y_pred_critic_max = np.clip(crit_max, 0, np.inf) * population y_pred_hosp_max = np.clip(hosp_max, 0, np.inf) * population y_pred_deaths_max = np.clip(deaths_max, 0, np.inf) * population simulations_min = pd.DataFrame({ "Date": dates[:len(y_pred_hosp_min)], "SimulationCases_min": y_pred_cases_min.astype(int), "SimulationHospital_min": y_pred_hosp_min.astype(int) + y_pred_critic_min.astype(int), "SimulationCritical_min": y_pred_critic_min.astype(int), "SimulationDeaths_min": y_pred_deaths_min.astype(int) }) simulations_max = pd.DataFrame({ "Date": dates[:len(y_pred_hosp_max)], "SimulationCases_max": y_pred_cases_max.astype(int), "SimulationHospital_max": y_pred_hosp_max.astype(int) + y_pred_critic_max.astype(int), "SimulationCritical_max": y_pred_critic_max.astype(int), "SimulationDeaths_max": y_pred_deaths_max.astype(int) }) simulations = pd.merge(simulations, simulations_min, how="left", on="Date") simulations = pd.merge(simulations, simulations_max, how="left", on="Date") simulations = simulations.fillna(method='ffill') simulations["R_min"] = data['R_min'].iloc[1:].values simulations["R_max"] = data['R_max'].iloc[1:].values if folder is not None: simulations.to_csv("{}/out.csv".format(folder)) fig_hospitals = plt.figure(figsize=fig_size) plt.plot(dt, simulations["SimulationHospital"] + simulations["SimulationCritical"], label="Probable hospitalized") plt.plot(dt, y_pred_hosp_min + y_pred_critic_min, label="Best case hospitalized") plt.plot(dt, y_pred_hosp_max + y_pred_critic_max, label="Worst case hospitalized") plt.xticks(dt, ticks, rotation=90) plt.tight_layout() plt.legend() plt.savefig("{}/hospitals.png".format(folder)) plt.close(fig_hospitals) fig_hospitals.clf() fig_critical = plt.figure(figsize=fig_size) plt.plot(dt, simulations["SimulationCritical"], label="Probable critical") plt.plot(dt, y_pred_critic_min, label="Best case critical") plt.plot(dt, y_pred_critic_max, label="Worst case critical") plt.xticks(dt, ticks, rotation=90) plt.tight_layout() plt.legend() plt.savefig("{}/criticals.png".format(folder)) plt.close(fig_critical) fig_critical.clf() fig_deaths = plt.figure(figsize=fig_size) plt.plot(dt, simulations["SimulationDeaths"], label="Probable deaths") plt.plot(dt, y_pred_deaths_min, label="Best case deaths") plt.plot(dt, y_pred_deaths_max, label="Worst case deaths") plt.xticks(dt, ticks, rotation=90) plt.tight_layout() plt.legend() plt.savefig("{}/deaths.png".format(folder)) plt.close(fig_deaths) fig_deaths.clf() fig_cases = plt.figure(figsize=fig_size) plt.plot(dt, y_pred_cases, label="Probable cases") plt.plot(dt, y_pred_cases_min, label="Best case cases") plt.plot(dt, y_pred_cases_max, label="Worst case cases") plt.xticks(dt, ticks, rotation=90) plt.tight_layout() plt.legend() plt.savefig("{}/cases.png".format(folder)) plt.close(fig_cases) fig_cases.clf() return simulations
dro21dt = -gamma21 * ro21 - 1.0 * I * ( -dc1 * ro21 - dp * ro21 + 0.5 * oc1 * ro20 - 0.5 * oc2 * ro11 + 0.5 * oc2 * ro22 - 0.5 * op * ro01) dro22dt = -Gamma02 * ro22 - Gamma12 * ro22 - 1.0 * I * ( -0.5 * oc2 * ro12 + 0.5 * oc2 * ro21 - 0.5 * op * ro02 + 0.5 * op * ro20) dzdt = [ dro00dt, dro01dt, dro02dt, dro10dt, dro11dt, dro12dt, dro20dt, dro21dt, dro22dt ] return dzdt z0 = np.array([1., 0., 0., 0., 0., 0., 0., 0., 0.], dtype='complex') t = np.linspace(0, 5, 50000) z = solve_ivp(model, (0., 5.), resenje1) t = z.t z = np.transpose(z.y) ro00 = z[:, 0] ro01 = z[:, 1] ro02 = z[:, 2] ro10 = z[:, 3] ro11 = z[:, 4] ro12 = z[:, 5] ro20 = z[:, 6] ro21 = z[:, 7] ro22 = z[:, 8] plt.plot(t, ro00.real + ro11.real + ro22.real,
def ivp(ti, tf, all): """langes Array mit Lösungen für x1,x2,v1,v2""" solve_ivp(function_for_ivp, [ti, tf], initial_values_for_ivp(all))
[-0.03168, 0.02938, 0.0023] .. [1] https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html """ S, I, R = y return [ dS_dT(S, I, transm, recov), dI_dT(S, I, transm, death, recov), dD_dT(I, death), ] solution = solve_ivp( fun=SIR, # input function t_span=[0, maxT], # start at time 0 and continue until we get to maxT t_eval=np.arange(0, maxT, 0.1), # points at which to store the computed solutions y0=[Sstart, Istart, Rstart], # initial conditions ) solution def plot_curves(solution, xlim=[0, 10], title=None, add_background=True): """Helper function that takes a solution and optionally visualises it using official Numberphile brown paper. Args: solution (scipy.integrate._ivp.ivp.OdeResult): Output of solve_ivp() function. xlim (list): x-axis limits in format [min, max]. title (str): Optional graph title. add_background (bool): Add Numberphile brown paper background?
def olf_bulb_10(Nmitral, H_in, W_in, P_odor_in, dam): # Nmitral = 10 #number of mitral cells Ngranule = np.copy(Nmitral) #number of granule cells pg. 383 of Li/Hop Ndim = Nmitral + Ngranule #total number of cells t_inh = 25 # time when inhalation starts t_exh = 205 #time when exhalation starts finalt = 395 # end time of the cycle #y = zeros(ndim,1); Sx = 1.43 #Sx,Sx2,Sy,Sy2 are parameters for the activation functions Sx2 = 0.143 Sy = 2.86 #These are given in Li/Hopfield pg 382, slightly diff in her thesis Sy2 = 0.286 th = 1 #threshold for the activation function tau_exh = 33.3333 #Exhale time constant, pg. 382 of Li/Hop exh_rate = 1 / tau_exh alpha = .15 #decay rate for the neurons #Li/Hop have it as 1/7 or .142 on pg 383 P_odor0 = np.zeros((Nmitral, 1)) #odor pattern, no odor H0 = H_in #weight matrix: to mitral from granule W0 = W_in #weights: to granule from mitral Ib = np.ones((Nmitral, 1)) * .243 #initial external input to mitral cells Ic = np.ones( (Ngranule, 1)) * .1 #initial input to granule cells, these values are #given on pg 382 of Li/Hop signalflag = 1 # 0 for linear output, 1 for activation function noise = np.zeros((Ndim, 1)) #noise in inputs noiselevel = .00143 noisewidth = 7 #noise correlation time, given pg 383 Li/Hop as 9, but 7 in thesis lastnoise = np.zeros((Ndim, 1)) #initial time of last noise pule #****************************************************************************** #CALCULATE FIXED POINTS #Calculating equilibrium value with no input rest0 = np.zeros((Ndim, 1)) restequi = fsolve(lambda x: equi(x,Ndim,Nmitral,Sx,Sx2,Sy,Sy2,th,alpha,\ t_inh,H0,W0,P_odor0,Ib,Ic,dam),rest0) #about 20 ms to run this np.random.seed(seed=23) #init0 = restequi+np.random.rand(Ndim)*.00143 #initial conditions plus some noise #for no odor input init0 = restequi + np.random.rand( Ndim) * .00143 #initial conditions plus some noise #for no odor input np.random.seed() #Now calculate equilibrium value with odor input lastnoise = lastnoise + t_inh - noisewidth #initialize lastnoise value #But what is it for? to have some #kind of correlation in the noise #find eigenvalues of A to see if input produces oscillating signal xequi = fsolve(lambda x: equi(x,Ndim,Nmitral,Sx,Sx2,Sy,Sy2,th,alpha,\ t_inh,H0,W0,P_odor_in,Ib,Ic,dam),rest0) #equilibrium values with some input, about 20 ms to run #****************************************************************************** #CALCULATE A AND DETERMINE EXISTENCE OF OSCILLATIONS diffgy = celldiff(xequi[Nmitral:], Sy, Sy2, th) diffgx = celldiff(xequi[0:Nmitral], Sx, Sx2, th) H1 = np.dot(H0, diffgy) W1 = np.dot(W0, diffgx) #intermediate step in constructing A A = np.dot(H1, W1) #Construct A dA, vA = lin.eig(A) #about 20 ms to run this #Find eigenvalues of A diff = (1j) * (dA)**.5 - alpha #criteria for a growing oscillation negsum = -(1j) * (dA)**.5 - alpha #Same diff_re = np.real(diff) #Take the real part negsum_re = np.real(negsum) #do an argmax to return the eigenvalue that will cause the fastest growing oscillations #Then do a spectrograph to track the growth of the associated freq through time indices = np.where( diff_re > 0) #Find the indices where the criteria is met indices2 = np.where(negsum_re > 0) #eigenvalues that could lead to growing oscillations # candidates = np.append(np.real((dA[indices])**.5),np.real((dA[indices2])**.5)) largest = np.argmax(diff_re) check = np.size(indices) check2 = np.size(indices2) if check == 0 and check2 == 0: # print("No Odor Recognized") dominant_freq = 0 else: dominant_freq = np.real((dA[largest])**.5) / ( 2 * np.pi) #find frequency of the dominant mode #Divide by 2pi to get to cycles/ms # print("Odor detected. Eigenvalues:",dA[indices],dA[indices2],\ # "\nEigenvectors:",vA[indices],vA[indices2],\ # "\nDominant Frequency:",dominant_freq) #************************************************************************* #SOLVE DIFFERENTIAL EQUATIONS TO GET INPUT AND OUTPUTS AS FN'S OF t #differential equation to solve teval = np.r_[0:finalt] #solve the differential equation sol = solve_ivp(lambda t,y: diffeq(t,y,Nmitral,Ngranule,Ndim,lastnoise,\ noise,noisewidth,noiselevel, t_inh,t_exh,exh_rate,alpha,Sy,\ Sy2,Sx,Sx2,th,H0,W0,P_odor_in,Ic,Ib,dam),\ [0,395],init0,t_eval = teval,method = 'RK45') t = sol.t y = sol.y y = np.transpose(y) yout = np.copy(y) #convert signal into output signal given by the activation fn if signalflag == 1: for i in np.arange(np.size(t)): yout[i, :Nmitral] = cellout(y[i, :Nmitral], Sx, Sx2, th) yout[i, Nmitral:] = cellout(y[i, Nmitral:], Sy, Sy2, th) #solve diffeq for P_odor = 0 #first, reinitialize lastnoise & noise noise = np.zeros((Ndim, 1)) lastnoise = np.zeros((Ndim, 1)) lastnoise = lastnoise + t_inh - noisewidth sol0 = sol = solve_ivp(lambda t,y: diffeq(t,y,Nmitral,Ngranule,Ndim,lastnoise,\ noise,noisewidth,noiselevel, t_inh,t_exh,exh_rate,alpha,Sy,\ Sy2,Sx,Sx2,th,H0,W0,P_odor0,Ic,Ib,dam),\ [0,395],init0,t_eval = teval,method = 'RK45') y0 = sol0.y y0 = np.transpose(y0) y0out = np.copy(y0) #convert signal into output signal given by the activation fn if signalflag == 1: for i in np.arange(np.size(t)): y0out[i, :Nmitral] = cellout(y0[i, :Nmitral], Sx, Sx2, th) y0out[i, Nmitral:] = cellout(y0[i, Nmitral:], Sy, Sy2, th) #***************************************************************************** #SIGNAL PROCESSING #Filtering the signal - O_mean: Lowpass fitered signal, under 20 Hz #S_h: Highpass filtered signal, over 20 Hz fs = 1 / (.001 * (t[1] - t[0])) #sampling freq, converting from ms to sec f_c = 15 / fs # Cutoff freq at 20 Hz, written as a ratio of fc to sample freq flter = np.sinc(2 * f_c * (t - (finalt - 1) / 2)) * np.blackman(finalt) #creating the #windowed sinc filter #centered at the middle #of the time data flter = flter / np.sum(flter) #normalize hpflter = -np.copy(flter) hpflter[int( (finalt - 1) / 2)] += 1 #convert the LP filter into a HP filter Sh = np.zeros(np.shape(yout)) Sl = np.copy(Sh) Sl0 = np.copy(Sh) Sbp = np.copy(Sh) for i in np.arange(Ndim): Sh[:, i] = np.convolve(yout[:, i], hpflter, mode='same') Sl[:, i] = np.convolve(yout[:, i], flter, mode='same') Sl0[:, i] = np.convolve(y0out[:, i], flter, mode='same') #find the oscillation period Tosc (Tosc must be greater than 5 ms to exclude noise) Tosc0 = np.zeros(np.size(np.arange(5, 50))) for i in np.arange(5, 50): Sh_shifted = np.roll(Sh, i, axis=0) Tosc0[i - 5] = np.sum( np.diagonal( np.dot(np.transpose(Sh[:, :Nmitral]), Sh_shifted[:, :Nmitral]))) #That is, do the correlation matrix (time correlation), take the diagonal to #get the autocorrelations, and find the max Tosc = np.argmax(Tosc0) Tosc = Tosc + 5 f_c2 = 1000 * ( 1.3 / Tosc) / fs #Filter out components with frequencies higher than this #to get rid of noise effects in cross-correlation #times 1000 to get units right flter2 = np.sinc(2 * f_c2 * (t - (finalt - 1) / 2)) * np.blackman(finalt) flter2 = flter2 / np.sum(flter2) for i in np.arange(Ndim): Sbp[:, i] = np.convolve(Sh[:, i], flter2, mode='same') #CALCULATE THE DISTANCE MEASURES #calculate phase via cross-correlation with each cell phase = np.zeros(Nmitral) for i in np.arange(1, Nmitral): crosscor = signal.correlate(Sbp[:, 0], Sbp[:, i]) tdiff = np.argmax(crosscor) - (finalt - 1) phase[i] = tdiff / Tosc * 2 * np.pi #Problem with the method below is that it will only give values from 0 to pi #for i in np.arange(1,Nmitral): # phase[i]=np.arccos(np.dot(Sbp[:,0],Sbp[:,i])/(lin.norm(Sbp[:,0])*lin.norm(Sbp[:,i]))) OsciAmp = np.zeros(Nmitral) Oosci = np.copy(OsciAmp) * 0j Omean = np.zeros(Nmitral) for i in np.arange(Nmitral): OsciAmp[i] = np.sqrt( np.sum(Sh[125:250, i]**2) / np.size(Sh[125:250, i])) Oosci[i] = OsciAmp[i] * np.exp(1j * phase[i]) Omean[i] = np.average(Sl[:, i] - Sl0[:, i]) Omean = np.maximum(Omean, 0) Ooscibar = np.sqrt(np.dot( Oosci, np.conjugate(Oosci))) / Nmitral #can't just square b/c it's complex Omeanbar = np.sqrt(np.dot(Omean, Omean)) / Nmitral maxlam = np.max(np.abs(np.imag(np.sqrt(dA)))) return yout, y0out, Sh, t, OsciAmp, Omean, Oosci, Omeanbar, Ooscibar, dominant_freq, maxlam
J_C4, J_F, J_ANT, J_PiC ]) return dX, J ### Four State Model ### # State 1 - no substrates t_1 = np.linspace(0, 25, 25 * 2) X_AtC = 0. X_DH = 0.001 # Kept non-zero for solver stability activity_array = np.array( [X_DH, X_C1, X_C3, X_C4, X_F, E_ANT, E_PiC, X_H, X_AtC]) state_1_results = solve_ivp(dXdt, [0, 25], X_0, method='Radau', t_eval=t_1, args=( activity_array, 1, )) # State 2 - Add substrate (i.e. turn on X_DH) t_2 = np.linspace(25, 75, (75 - 25) * 2) X_DH = 0.0866 * 2 activity_array = np.array( [X_DH, X_C1, X_C3, X_C4, X_F, E_ANT, E_PiC, X_H, X_AtC]) state_2_results = solve_ivp(dXdt, [25, 75], state_1_results.y[:, -1], method='Radau', t_eval=t_2, args=( activity_array,
for i in np.arange(0, nr_neurons): statevar[i, :] = y0 t1 = 0 ts = np.zeros((nr_neurons, 1)) t_last = 0 Ie_local = Isyn[0] Ie_local = 0 #tspan_pre = [ts[0], ts[0]+10] plt.figure() plt.ion() tspan_pre = [ts[0], ts[0] + int_time] # presynaptic_neuron = solve_ivp(vecf, tspan_pre, y2,events= Vt_cross, method = 'RK45',rtol=1e-5,atol=1e-7) presynaptic_neuron = solve_ivp(vecf, tspan_pre, y0, events=Vt_cross, method='RK45', rtol=1e-5, atol=1e-7) if np.size(presynaptic_neuron.t_events) > 0: tspk = presynaptic_neuron.t_events[0] ts[0] = tspk[0] tspan_post = [t1, ts[0]] for i in np.arange(1, nr_neurons): Ie_local = Isyn[i] postsynaptic_neuron = solve_ivp(vecf, tspan_post, statevar[i, :], method='RK45', rtol=1e-5, atol=1e-7)
import numpy as np from scipy.integrate import solve_ivp import matplotlib.pyplot as plt def f(t, x, a, b): dxdt = a - (b+1) * x[0] + x[1] * x[0]**2 dydt = b * x[0] - x[1] * x[0]**2 return np.array([dxdt, dydt]) a, b = 1.0, 2.5 t0, t1 = 0.0, 50.0 x1 = [0.1,0.1] sol = solve_ivp(f, [t0, t1], x1, args=([a, b]), dense_output=True) fig = plt.figure(figsize=(8,5)) plt.xlim(t0,t1) plt.ylim(0,5) T = np.linspace(t0,t1,512) Z = sol.sol(T) plt.plot(T, Z.T[:,0],'-', label="$x(t)$") plt.plot(T, Z.T[:,1],'-', label="$y(t)$") plt.legend() plt.show()
def run_ode_solver(system, slope_func, **options): """Computes a numerical solution to a differential equation. `system` must contain `init` with initial conditions, `t_0` with the start time, and `t_end` with the end time. It can contain any other parameters required by the slope function. `options` can be any legal options of `scipy.integrate.solve_ivp` system: System object slope_func: function that computes slopes returns: TimeFrame """ # make sure `system` contains `init` if not hasattr(system, 'init'): msg = """It looks like `system` does not contain `init` as a system variable. `init` should be a State object that specifies the initial condition:""" raise ValueError(msg) # make sure `system` contains `t_end` if not hasattr(system, 't_end'): msg = """It looks like `system` does not contain `t_end` as a system variable. `t_end` should be the final time:""" raise ValueError(msg) # make the system parameters available as globals unpack(system) # the default value for t_0 is 0 t_0 = getattr(system, 't_0', 0) # try running the slope function with the initial conditions # try: # slope_func(init, t_0, system) # except Exception as e: # msg = """Before running scipy.integrate.solve_ivp, I tried # running the slope function you provided with the # initial conditions in `system` and `t=t_0` and I got # the following error:""" # logger.error(msg) # raise(e) # wrap the slope function to reverse the arguments and add `system` f = lambda t, y: slope_func(y, t, system) def wrap_event(event): """Wrap the event functions. Make events terminal by default. """ wrapped = lambda t, y: event(y, t, system) wrapped.terminal = getattr(event, 'terminal', True) wrapped.direction = getattr(event, 'direction', 0) return wrapped # wrap the event functions so they take the right arguments events = options.pop('events', []) try: events = [wrap_event(event) for event in events] except TypeError: events = wrap_event(events) # remove dimensions from the initial conditions. # we need this because otherwise `init` gets copied into the # results array along with its units y_0 = [magnitude(x) for x in init] # run the solver with units_off(): bunch = solve_ivp(f, [t_0, t_end], y_0, events=events, **options) # separate the results from the details y = bunch.pop('y') t = bunch.pop('t') details = ModSimSeries(bunch) # pack the results into a TimeFrame results = TimeFrame(np.transpose(y), index=t, columns=init.index) return results, details
def test_args(): # sys3 is actually two decoupled systems. (x, y) form a # linear oscillator, while z is a nonlinear first order # system with equilibria at z=0 and z=1. If k > 0, z=1 # is stable and z=0 is unstable. def sys3(t, w, omega, k, zfinal): x, y, z = w return [-omega*y, omega*x, k*z*(1 - z)] def sys3_jac(t, w, omega, k, zfinal): x, y, z = w J = np.array([[0, -omega, 0], [omega, 0, 0], [0, 0, k*(1 - 2*z)]]) return J def sys3_x0decreasing(t, w, omega, k, zfinal): x, y, z = w return x def sys3_y0increasing(t, w, omega, k, zfinal): x, y, z = w return y def sys3_zfinal(t, w, omega, k, zfinal): x, y, z = w return z - zfinal # Set the event flags for the event functions. sys3_x0decreasing.direction = -1 sys3_y0increasing.direction = 1 sys3_zfinal.terminal = True omega = 2 k = 4 tfinal = 5 zfinal = 0.99 # Find z0 such that when z(0) = z0, z(tfinal) = zfinal. # The condition z(tfinal) = zfinal is the terminal event. z0 = np.exp(-k*tfinal)/((1 - zfinal)/zfinal + np.exp(-k*tfinal)) w0 = [0, -1, z0] # Provide the jac argument and use the Radau method to ensure that the use # of the Jacobian function is exercised. # If event handling is working, the solution will stop at tfinal, not tend. tend = 2*tfinal sol = solve_ivp(sys3, [0, tend], w0, events=[sys3_x0decreasing, sys3_y0increasing, sys3_zfinal], dense_output=True, args=(omega, k, zfinal), method='Radau', jac=sys3_jac, rtol=1e-10, atol=1e-13) # Check that we got the expected events at the expected times. x0events_t = sol.t_events[0] y0events_t = sol.t_events[1] zfinalevents_t = sol.t_events[2] assert_allclose(x0events_t, [0.5*np.pi, 1.5*np.pi]) assert_allclose(y0events_t, [0.25*np.pi, 1.25*np.pi]) assert_allclose(zfinalevents_t, [tfinal]) # Check that the solution agrees with the known exact solution. t = np.linspace(0, zfinalevents_t[0], 250) w = sol.sol(t) assert_allclose(w[0], np.sin(omega*t), rtol=1e-9, atol=1e-12) assert_allclose(w[1], -np.cos(omega*t), rtol=1e-9, atol=1e-12) assert_allclose(w[2], 1/(((1 - z0)/z0)*np.exp(-k*t) + 1), rtol=1e-9, atol=1e-12) # Check that the state variables have the expected values at the events. x0events = sol.sol(x0events_t) y0events = sol.sol(y0events_t) zfinalevents = sol.sol(zfinalevents_t) assert_allclose(x0events[0], np.zeros_like(x0events[0]), atol=5e-14) assert_allclose(x0events[1], np.ones_like(x0events[1])) assert_allclose(y0events[0], np.ones_like(y0events[0])) assert_allclose(y0events[1], np.zeros_like(y0events[1]), atol=5e-14) assert_allclose(zfinalevents[2], [zfinal])
size_pop = size_pop_tot mutpb = copy(mutpb_start) cxpb = copy(cxpb_start) print(" ---------------Iter={}, V wind={}, Gust Height Start={}, Size Gust Zone={} -----------------".format(nt, round(v_wind,2), round(height_start-obj.Re,2), round(deltaH,2))) x_ini = [obj.Re, 0.0, 0.0, 0.0, obj.M0] idx = 0 def find_height(t, x): return height_start - x[0] find_height.terminal = True ####### integration to find where the gust zone starts ############### init = solve_ivp(partial(utils.sys_init, obj=obj, Trfun=Trfun, Ttfun=Ttfun), [0, tfin], x_ini, events=find_height) change_time = init.t[-1] ######## second integration to find out initial conditions after evaluation, assuming delta_eval as evaluation time ######### x_ini_1 = [init.y[0, :][-1], init.y[1, :][-1], init.y[2, :][-1], init.y[3, :][-1], init.y[4, :][-1]] init2 = solve_ivp(partial(utils.sys_ifnoC, height_start=height_start, delta=deltaH, v_wind=v_wind, Trfun=Trfun, Ttfun=Ttfun, obj=obj), [change_time, change_time+delta_eval], x_ini_1) x_ini_h = [init2.y[0, :][-1], init2.y[1, :][-1], init2.y[2, :][-1], init2.y[3, :][-1], init2.y[4, :][-1]] # initial conditions to be used by GP, since it has to find a law that starts after the evaluation time, ideally start = time() pop, log, hof = main(size_pop, size_gen, Mu, cxpb, mutpb, x_ini_h, height_start, deltaH, v_wind) end = time() if learning: old_hof.update(hof[-5:], for_feasible=True) t_offdesign = end - start print("Time elapsed: {}".format(t_offdesign))
def cowell(k, r, v, tofs, rtol=1e-11, *, ad=None, **ad_kwargs): """Propagates orbit using Cowell's formulation. Parameters ---------- k : ~astropy.units.Quantity Standard gravitational parameter of the attractor. r : ~astropy.units.Quantity Position vector. v : ~astropy.units.Quantity Velocity vector. tofs : ~astropy.units.Quantity Array of times to propagate. rtol : float, optional Maximum relative error permitted, default to 1e-10. ad : function(t0, u, k), optional Non Keplerian acceleration (km/s2), default to None. Returns ------- rr : ~astropy.units.Quantity Propagated position vectors. vv : ~astropy.units.Quantity Propagated velocity vectors. Raises ------ RuntimeError If the algorithm didn't converge. Note ----- This method uses a Dormand & Prince method of order 8(5,3) available in the :py:class:`poliastro.integrators` module. If multiple tofs are provided, the method propagates to the maximum value and calculates the other values via dense output """ k = k.to(u.km ** 3 / u.s ** 2).value x, y, z = r.to(u.km).value vx, vy, vz = v.to(u.km / u.s).value tofs = tofs.to(u.s).value u0 = np.array([x, y, z, vx, vy, vz]) # Set the non Keplerian acceleration if ad is None: def ad(t0, u_, k_): return 0, 0, 0 f_with_ad = functools.partial(func_twobody, k=k, ad=ad, ad_kwargs=ad_kwargs) result = solve_ivp( f_with_ad, (0, max(tofs)), u0, rtol=rtol, atol=1e-12, method=DOP835, dense_output=True, ) if not result.success: raise RuntimeError("Integration failed") rrs = [] vvs = [] for i in range(len(tofs)): y = result.sol(tofs[i]) rrs.append(y[:3]) vvs.append(y[3:]) return rrs * u.km, vvs * u.km / u.s
def integrate_angular_velocity(Omega, t0, t1, R0=None, tolerance=1e-12): """Compute frame with given angular velocity Parameters ========== Omega: tuple or callable Angular velocity from which to compute frame. Can be 1) a 2-tuple of float arrays (t, v) giving the angular velocity vector at a series of times, 2) a function of time that returns the 3-vector angular velocity, or 3) a function of time and orientation (t, R) that returns the 3-vector angular velocity In case 1, the angular velocity will be interpolated to the required times. Note that accuracy is poor in case 1. t0: float Initial time t1: float Final time R0: quaternion, optional Initial frame orientation. Defaults to 1 (the identity orientation). tolerance: float, optional Absolute tolerance used in integration. Defaults to 1e-12. Returns ======= t: float array R: quaternion array """ import warnings from scipy.integrate import ode if R0 is None: R0 = quaternion.one input_is_tabulated = False try: t_Omega, v = Omega from scipy.interpolate import InterpolatedUnivariateSpline Omega_x = InterpolatedUnivariateSpline(t_Omega, v[:, 0]) Omega_y = InterpolatedUnivariateSpline(t_Omega, v[:, 1]) Omega_z = InterpolatedUnivariateSpline(t_Omega, v[:, 2]) def Omega_func(t, R): return [Omega_x(t), Omega_y(t), Omega_z(t)] Omega_func(t0, R0) input_is_tabulated = True except (TypeError, ValueError): def Omega_func(t, R): return Omega(t, R) try: Omega_func(t0, R0) except TypeError: def Omega_func(t, R): return Omega(t) Omega_func(t0, R0) def RHS(t, y): R = quaternion.quaternion(*y) return (0.5 * quaternion.quaternion(0.0, *Omega_func(t, R)) * R).components y0 = R0.components if input_is_tabulated: from scipy.integrate import solve_ivp t = t_Omega t_span = [t_Omega[0], t_Omega[-1]] solution = solve_ivp(RHS, t_span, y0, t_eval=t_Omega, atol=tolerance, rtol=100*np.finfo(float).eps) R = quaternion.from_float_array(solution.y.T) else: solver = ode(RHS) solver.set_initial_value(y0, t0) solver.set_integrator('dop853', nsteps=1, atol=tolerance, rtol=0.0) solver._integrator.iwork[2] = -1 # suppress Fortran-printed warning t = appending_array((int(t1-t0),)) t.append(solver.t) R = appending_array((int(t1-t0), 4)) R.append(solver.y) warnings.filterwarnings("ignore", category=UserWarning) t_last = solver.t while solver.t < t1: solver.integrate(t1, step=True) if solver.t > t_last: t.append(solver.t) R.append(solver.y) t_last = solver.t warnings.resetwarnings() t = t.a R = quaternion.as_quat_array(R.a) return t, R
def test_events(): def event_rational_1(t, y): return y[0] - y[1] ** 0.7 def event_rational_2(t, y): return y[1] ** 0.6 - y[0] def event_rational_3(t, y): return t - 7.4 event_rational_3.terminal = True for method in ['RK23', 'RK45', 'Radau', 'BDF', 'LSODA']: res = solve_ivp(fun_rational, [5, 8], [1/3, 2/9], method=method, events=(event_rational_1, event_rational_2)) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 1) assert_equal(res.t_events[1].size, 1) assert_(5.3 < res.t_events[0][0] < 5.7) assert_(7.3 < res.t_events[1][0] < 7.7) event_rational_1.direction = 1 event_rational_2.direction = 1 res = solve_ivp(fun_rational, [5, 8], [1 / 3, 2 / 9], method=method, events=(event_rational_1, event_rational_2)) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 1) assert_equal(res.t_events[1].size, 0) assert_(5.3 < res.t_events[0][0] < 5.7) event_rational_1.direction = -1 event_rational_2.direction = -1 res = solve_ivp(fun_rational, [5, 8], [1 / 3, 2 / 9], method=method, events=(event_rational_1, event_rational_2)) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 0) assert_equal(res.t_events[1].size, 1) assert_(7.3 < res.t_events[1][0] < 7.7) event_rational_1.direction = 0 event_rational_2.direction = 0 res = solve_ivp(fun_rational, [5, 8], [1 / 3, 2 / 9], method=method, events=(event_rational_1, event_rational_2, event_rational_3), dense_output=True) assert_equal(res.status, 1) assert_equal(res.t_events[0].size, 1) assert_equal(res.t_events[1].size, 0) assert_equal(res.t_events[2].size, 1) assert_(5.3 < res.t_events[0][0] < 5.7) assert_(7.3 < res.t_events[2][0] < 7.5) res = solve_ivp(fun_rational, [5, 8], [1 / 3, 2 / 9], method=method, events=event_rational_1, dense_output=True) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 1) assert_(5.3 < res.t_events[0][0] < 5.7) # Also test that termination by event doesn't break interpolants. tc = np.linspace(res.t[0], res.t[-1]) yc_true = sol_rational(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, 1e-3, 1e-6) assert_(np.all(e < 5)) # Test in backward direction. event_rational_1.direction = 0 event_rational_2.direction = 0 for method in ['RK23', 'RK45', 'Radau', 'BDF', 'LSODA']: res = solve_ivp(fun_rational, [8, 5], [4/9, 20/81], method=method, events=(event_rational_1, event_rational_2)) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 1) assert_equal(res.t_events[1].size, 1) assert_(5.3 < res.t_events[0][0] < 5.7) assert_(7.3 < res.t_events[1][0] < 7.7) event_rational_1.direction = -1 event_rational_2.direction = -1 res = solve_ivp(fun_rational, [8, 5], [4/9, 20/81], method=method, events=(event_rational_1, event_rational_2)) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 1) assert_equal(res.t_events[1].size, 0) assert_(5.3 < res.t_events[0][0] < 5.7) event_rational_1.direction = 1 event_rational_2.direction = 1 res = solve_ivp(fun_rational, [8, 5], [4/9, 20/81], method=method, events=(event_rational_1, event_rational_2)) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 0) assert_equal(res.t_events[1].size, 1) assert_(7.3 < res.t_events[1][0] < 7.7) event_rational_1.direction = 0 event_rational_2.direction = 0 res = solve_ivp(fun_rational, [8, 5], [4/9, 20/81], method=method, events=(event_rational_1, event_rational_2, event_rational_3), dense_output=True) assert_equal(res.status, 1) assert_equal(res.t_events[0].size, 0) assert_equal(res.t_events[1].size, 1) assert_equal(res.t_events[2].size, 1) assert_(7.3 < res.t_events[1][0] < 7.7) assert_(7.3 < res.t_events[2][0] < 7.5) # Also test that termination by event doesn't break interpolants. tc = np.linspace(res.t[-1], res.t[0]) yc_true = sol_rational(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, 1e-3, 1e-6) assert_(np.all(e < 5))
"""Função de simulação para entrada senoidal.""" u = [0.3 * np.cos(t)] return f(x, u) def fm_ent_nula(t, x): """Função de simulação para entrada nula.""" u = [0] return f(x, u) if __name__ == '__main__': # Simula os sistemas tint = [0, 30] xini = [0, 1] opt = {'max_step': 0.05} sol_nula = integrate.solve_ivp(fm_ent_nula, tint, xini, **opt) sol_sen = integrate.solve_ivp(fm_ent_sen, tint, xini, **opt) # Plota o gráfico pyplot.plot(sol_nula.y[0], sol_nula.y[1], sol_sen.y[0], sol_sen.y[1]) pyplot.xlabel('t [s]') pyplot.title('Evolução temporal dos estados') pyplot.legend(['$u=0$', r'$u=0.3 \cos(t)$']) # Salva o gráfico pyplot.savefig('sim-duffing-py.svg')
N = 51.5 * 10**6 N_old = 0.15 S = [N] E = [20 * Init_inf] I = [Init_inf] R = [0] D = [0] for i in tqdm(range(intval)): t_start = time_list[i] t_end = time_list[i + 1] Y0 = [S[-1], E[-1], I[-1], R[-1], D[-1]] α = alpha(τ_inc) γ = gamma(τ_rec) answer = solve_ivp(SEIRS, [t_start, t_end], Y0, t_eval=[t_start, t_end], method='Radau', args=(σ, β, γ, α, Λ, μ, ξ, κ, κ_old, τ_ξ, τ_σ, N, N_old, time_list, I[:], S[:], R[:])) Sn = answer.y[0][-1] En = answer.y[1][-1] In = answer.y[2][-1] Rn = answer.y[3][-1] Dn = answer.y[4][-1] S.append(Sn) E.append(En) I.append(In) R.append(Rn) D.append(Dn) Sp = [(i / N) * 100.0 for i in S] Ep = [(i / N) * 100.0 for i in E]
def test_t_eval(): rtol = 1e-3 atol = 1e-6 y0 = [1 / 3, 2 / 9] for t_span in ([5, 9], [5, 1]): t_eval = np.linspace(t_span[0], t_span[1], 10) res = solve_ivp(fun_rational, t_span, y0, rtol=rtol, atol=atol, t_eval=t_eval) assert_equal(res.t, t_eval) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) y_true = sol_rational(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5)) t_eval = [5, 5.01, 7, 8, 8.01, 9] res = solve_ivp(fun_rational, [5, 9], y0, rtol=rtol, atol=atol, t_eval=t_eval) assert_equal(res.t, t_eval) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) y_true = sol_rational(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5)) t_eval = [5, 4.99, 3, 1.5, 1.1, 1.01, 1] res = solve_ivp(fun_rational, [5, 1], y0, rtol=rtol, atol=atol, t_eval=t_eval) assert_equal(res.t, t_eval) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) t_eval = [5.01, 7, 8, 8.01] res = solve_ivp(fun_rational, [5, 9], y0, rtol=rtol, atol=atol, t_eval=t_eval) assert_equal(res.t, t_eval) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) y_true = sol_rational(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5)) t_eval = [4.99, 3, 1.5, 1.1, 1.01] res = solve_ivp(fun_rational, [5, 1], y0, rtol=rtol, atol=atol, t_eval=t_eval) assert_equal(res.t, t_eval) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) t_eval = [4, 6] assert_raises(ValueError, solve_ivp, fun_rational, [5, 9], y0, rtol=rtol, atol=atol, t_eval=t_eval)
def sir_model_policy(t, y, CE, D, N, VF, QF): s, i, r, q = y β = CE / N λ = β * i VR = s * VF QR = i * QF QRR = q / D IR = s * λ RR = i / D ds = -(IR + VR) di = IR - (RR + QR) dr = RR + VR + QRR dq = QR - QRR return (ds, di, dr, dq) ts = 50 sol = solve_ivp(sir_model_policy, [0, ts], Y0, args=(CE, D, N, VF, QF), t_eval=np.arange(0, ts, 0.125)) plt.plot(sol.t, sol.y.T, label=['S' 'I', 'R', 'Q']) plt.legend(['S', 'I', 'R', 'Q'], loc='upper right') plt.show()
def comp_fcn(self, res_fname, solver_state, hist_fname=None): """evalute function being solved with Newton's method""" logger = logging.getLogger(__name__) logger.debug('res_fname="%s", hist_fname="%s"', res_fname, hist_fname) if solver_state is not None: fcn_complete_step = "comp_fcn complete for %s" % res_fname if solver_state.step_logged(fcn_complete_step): logger.debug('"%s" logged, returning result', fcn_complete_step) return ModelState(res_fname) logger.debug('"%s" not logged, proceeding', fcn_complete_step) # get dense output, if requested if hist_fname is not None: t_eval = np.linspace(self.time_range[0], self.time_range[1], 101) else: t_eval = np.array(self.time_range) # memory for result, use it initially for passing initial value to solve_ivp res_vals = self.get_tracer_vals_all() fptr_hist = self._hist_def_dimensions(hist_fname) self._hist_def_vars_tracer_module_independent(fptr_hist) # solve ODEs for each tracer module independently, using scipy.integrate ind0 = 0 for tracer_module in self.tracer_modules: self._hist_def_vars(tracer_module, fptr_hist) cnt = tracer_module.tracer_cnt sol = integrate.solve_ivp( tracer_module.comp_tend, self.time_range, res_vals[ind0:ind0 + cnt, :].reshape(-1), "Radau", t_eval, atol=1.0e-10, rtol=1.0e-10, args=(self.vert_mix, ), ) if ind0 == 0: self._hist_write_tracer_module_independent(sol, fptr_hist) self._hist_write(tracer_module, sol, fptr_hist) res_vals[ind0:ind0 + cnt, :] = (sol.y[:, -1].reshape( (cnt, -1)) - res_vals[ind0:ind0 + cnt, :]) ind0 = ind0 + cnt if fptr_hist is not None: fptr_hist.close() # ModelState instance for result res_ms = copy.copy(self) res_ms.set_tracer_vals_all(res_vals, reseat_vals=True) caller = class_name(self) + ".comp_fcn" res_ms.comp_fcn_postprocess(res_fname, caller) if solver_state is not None: solver_state.log_step(fcn_complete_step) modelinfo = self.model_config_obj.modelinfo if strtobool(modelinfo["reinvoke"]): cmd = [modelinfo["invoker_script_fname"], "--resume"] logger.info('cmd="%s"', " ".join(cmd)) # use Popen instead of run because we don't want to wait subprocess.Popen(cmd) raise SystemExit return res_ms
def step(self, state, action): # low-dimensional representation: # state is normalized height, state = m*g*h = m*g*x[1] state = np.atleast_1d(state) action = np.atleast_1d(action) # * set some simulation parameters MAX_TIME = 3 # * map to high-dimensional state # forward velocity y = state[0]*self.energy/self.mass/self.gravity v = np.sqrt(2/self.mass*(self.energy - self.energy*state[0])) x0 = np.array([0, y, # body position v, 0, # body velocity 0, 0]) # foot position (fill in below) x0[4] = x0[0] + np.sin(action)*self.resting_length x0[5] = x0[1] - np.cos(action)*self.resting_length # * define high-dimensional dynamics # Helper functions for traj dynamics def fall_event(t, y): return y[1] fall_event.terminal = True fall_event.direction = -1 def touchdown_event(t, y): return y[5] touchdown_event.terminal = True touchdown_event.direction = -1 def liftoff_event(t, y): return np.hypot(y[0]-y[4], y[1]-y[5]) - self.resting_length liftoff_event.terminal = True liftoff_event.direction = 1 def apex_event(t, y): return y[3] apex_event.terminal = True apex_event.direction = -1 def flight(t, y): return np.array([y[2], y[3], 0, -self.gravity, y[2], y[3]]) def stance(t, y): alpha = np.arctan2(y[1] - y[5], y[0] - y[4]) - np.pi/2.0 spring_length = np.hypot(y[0]-y[4], y[1]-y[5]) leg_force = self.stiffness/self.mass*(self.resting_length - spring_length) xdotdot = -leg_force*np.sin(alpha) ydotdot = leg_force*np.cos(alpha) - self.gravity return np.array([y[2], y[3], xdotdot, ydotdot, 0, 0]) # TODO: implement jacobian of stance # * simulate: while True: # while statement is just to allow breaks. It does not loop # * FLIGHT: simulate till touchdown events = [fall_event, touchdown_event] traj = solve_ivp(flight, t_span=[0, 0+MAX_TIME], y0=x0, events=events, max_step=0.01) # if you fell, stop now if traj.t_events[0].size != 0: # if empty break # * STANCE: simulate till liftoff events = [fall_event, liftoff_event] traj = solve_ivp(stance, t_span=[traj.t[-1], traj.t[-1]+MAX_TIME], y0=traj.y[:, -1], events=events, max_step=0.0005) # if you fell, stop now if traj.t_events[0].size != 0: # if empty break # * FLIGHT: simulate till apex events = [fall_event, apex_event] traj = solve_ivp(flight, t_span=[traj.t[-1], traj.t[-1]+MAX_TIME], y0=traj.y[:, -1], events=events, max_step=0.01) break # * Check if low-level failured conditions are triggered # point mass touches the ground, or reverses direction if traj.y[1, -1] < 1e-3 or traj.y[2, -1] < 0: self.failed = True # * map back to high-level state. new_state = self.mass*self.gravity*traj.y[1, -1]/self.energy new_state = np.atleast_1d(new_state) new_state = self.stateaction_space.state_space.closest_in(new_state) return new_state, self.is_feasible_state(new_state)
def test_scenario(name,fun,initial,times,rtol,atol): print(40*"-",name,40*"-",sep="\n") with timer("ode (%s)"%solver_ode): I = ode(fun) I.set_integrator(solver_ode,rtol=rtol,atol=atol,nsteps=10**8) I.set_initial_value(initial,0.0) result = np.vstack(I.integrate(time) for time in times) assert I.successful() inv_fun = lambda y,t: fun(t,y) with timer("odeint with suboptimal function (LSODA)"): result = odeint( func=inv_fun, y0=initial, t=[0.0]+list(times), rtol=rtol, atol=atol, mxstep=10**8 ) with timer("solve_ivp (%s) without result"%solver_ivp): I = solve_ivp( fun, t_span=(0,times[-1]), y0=initial, method=solver_ivp, rtol=rtol, atol=atol ) assert I.status != -1 with timer("solve_ivp (%s)"%solver_ivp): I = solve_ivp( fun, t_span=(0,times[-1]), t_eval=times, y0=initial, method=solver_ivp, rtol=rtol, atol=atol ) result = I.y assert I.status != -1 with timer("solve_ivp (%s) with dense_output"%solver_ivp): I = solve_ivp( fun, t_span=(0,times[-1]), y0=initial, method=solver_ivp, rtol=rtol, atol=atol, dense_output=True ) result = np.vstack(I.sol(time) for time in times) assert I.status != -1 with timer("%s with dense output"%solver_ivp): I = METHODS[solver_ivp]( fun=fun, y0=initial, t0=0.0, t_bound=times[-1], rtol=rtol, atol=atol ) def solutions(): for time in times: while I.t < time: I.step() yield I.dense_output()(time) result = np.vstack(solutions()) assert I.status != "failed" with timer("%s with manual resetting"%solver_ivp): I = METHODS[solver_ivp]( fun=fun, y0=initial, t0=0.0, t_bound=times[-1], rtol=rtol, atol=atol ) def solutions(): for time in times: I.t_bound = time I.status = "running" while I.status == "running": I.step() yield I.y result = np.vstack(solutions()) assert I.status != "failed" with timer("%s with reinitialising"%solver_ivp): def solutions(): current_time = 0.0 state = initial for time in times: I = METHODS[solver_ivp]( fun=fun, y0=state, t0=current_time, t_bound=time, rtol=rtol, atol=atol ) while I.status == "running": I.step() assert I.status != "failed" current_time = time state = I.y yield state result = np.vstack(solutions())
x_augment = np.concatenate((z, x, z)) left_of = x_augment[:-2] right_of = x_augment[2:] dif = -velocity * (right_of - left_of) / (2 * dx) dif[0] = 0 dif[-1] = 0 return dif tval = np.linspace(0, end_time, 100) sol = solve_ivp(x_prime, t_span=(0, end_time), t_eval=tval, y0=ic, vectorized=False, rtol=1e-12, atol=1e-12) t_plot = [0, 10, 20, 30] profile_dict = {} for t in t_plot: profile_dict[t] = sol.y[:, t] fig = go.Figure() for time, profile in profile_dict.items(): fig.add_trace( go.Scatter(x=list(range(size)), y=profile_dict[time], name=str(time))) plot(fig)
print('min real: %s' % np.min(vals.real)) print('max real: %s' % np.max(vals.real)) print('min imaginary: %s' % np.min(vals.imag)) print('max imaginary: %s' % np.max(vals.imag)) fig, ax = plt.subplots() ax.plot(vals.real, vals.imag, 'ko') ax.set_title('eigenvalues of the state differentiation matrix') ax.set_xlabel('real') ax.set_ylabel('imaginary') ax.grid(ls=':') plt.savefig('../figures/fd.d.1.png') print('performing time integration ...') soln = solve_ivp(fun=state_derivative, t_span=[times[0], times[-1]], y0=z_init, method='RK45', t_eval=times) print('done') ## PLOTTING # create the interpolation points xgrid, ygrid = np.meshgrid(np.linspace(0.0, 2.01, 100), np.linspace(0.0, 2.01, 100)) xy = np.array([xgrid.flatten(), ygrid.flatten()]).T # create an interpolation matrix that maps `u` to the displacements at `xy` I = weight_matrix(x=xy, p=nodes[groups['interior+boundary:all']], n=stencil_size, diffs=(0, 0),
ivps.append(ped.v_0[0]) ivps.append(ped.v_0[1]) return ivps def ivp(ti, tf, all): """langes Array mit Lösungen für x1,x2,v1,v2""" solve_ivp(function_for_ivp, [ti, tf], initial_values_for_ivp(all)) # %% Nl = 2 Nr = 0 all = make_pedestrians(Nl, Nr) solution = solve_ivp(function_for_ivp, [ti, tf], initial_values_for_ivp(all), method='LSODA') print(min(solution['y'][1])) print(max(solution['y'][1])) len(solution['y'][0]) solution # %% solution['y'][2, 0] # %% import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation fig = plt.figure(tight_layout=True) fig.subplots_adjust(left=0, right=1, bottom=0, top=1) ax = fig.add_subplot(111, aspect='equal',
def test_no_integration(): for method in ['RK23', 'RK45', 'Radau', 'BDF', 'LSODA']: sol = solve_ivp(lambda t, y: -y, [4, 4], [2, 3], method=method, dense_output=True) assert_equal(sol.sol(4), [2, 3]) assert_equal(sol.sol([4, 5, 6]), [[2, 2, 2], [3, 3, 3]])
def test_integration(): rtol = 1e-3 atol = 1e-6 y0 = [1 / 3, 2 / 9] with warnings.catch_warnings(): warnings.simplefilter('ignore') for vectorized, method, t_span, jac in product( [False, True], ['RK23', 'RK45', 'Radau', 'BDF', 'LSODA'], [[5, 9], [5, 1]], [None, jac_rational, jac_rational_sparse]): if vectorized: fun = fun_rational_vectorized else: fun = fun_rational res = solve_ivp(fun, t_span, y0, rtol=rtol, atol=atol, method=method, dense_output=True, jac=jac, vectorized=vectorized) assert_equal(res.t[0], t_span[0]) assert_(res.t_events is None) assert_(res.success) assert_equal(res.status, 0) assert_(res.nfev < 40) if method in ['RK23', 'RK45', 'LSODA']: assert_equal(res.njev, 0) assert_equal(res.nlu, 0) else: assert_(0 < res.njev < 3) assert_(0 < res.nlu < 10) y_true = sol_rational(res.t) e = compute_error(res.y, y_true, rtol, atol) assert_(np.all(e < 5)) tc = np.linspace(*t_span) yc_true = sol_rational(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, rtol, atol) assert_(np.all(e < 5)) tc = (t_span[0] + t_span[-1]) / 2 yc_true = sol_rational(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, rtol, atol) assert_(np.all(e < 5)) # LSODA for some reasons doesn't pass the polynomial through the # previous points exactly after the order change. It might be some # bug in LSOSA implementation or maybe we missing something. if method != 'LSODA': assert_allclose(res.sol(res.t), res.y, rtol=1e-15, atol=1e-15)
def test_events(): event_rational_3.terminal = True for method in ['RK23', 'RK45', 'Radau', 'BDF', 'LSODA']: res = solve_ivp(fun_rational, [5, 8], [1 / 3, 2 / 9], method=method, events=(event_rational_1, event_rational_2)) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 1) assert_equal(res.t_events[1].size, 1) assert_(5.3 < res.t_events[0][0] < 5.7) assert_(7.3 < res.t_events[1][0] < 7.7) event_rational_1.direction = 1 event_rational_2.direction = 1 res = solve_ivp(fun_rational, [5, 8], [1 / 3, 2 / 9], method=method, events=(event_rational_1, event_rational_2)) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 1) assert_equal(res.t_events[1].size, 0) assert_(5.3 < res.t_events[0][0] < 5.7) event_rational_1.direction = -1 event_rational_2.direction = -1 res = solve_ivp(fun_rational, [5, 8], [1 / 3, 2 / 9], method=method, events=(event_rational_1, event_rational_2)) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 0) assert_equal(res.t_events[1].size, 1) assert_(7.3 < res.t_events[1][0] < 7.7) event_rational_1.direction = 0 event_rational_2.direction = 0 res = solve_ivp(fun_rational, [5, 8], [1 / 3, 2 / 9], method=method, events=(event_rational_1, event_rational_2, event_rational_3), dense_output=True) assert_equal(res.status, 1) assert_equal(res.t_events[0].size, 1) assert_equal(res.t_events[1].size, 0) assert_equal(res.t_events[2].size, 1) assert_(5.3 < res.t_events[0][0] < 5.7) assert_(7.3 < res.t_events[2][0] < 7.5) res = solve_ivp(fun_rational, [5, 8], [1 / 3, 2 / 9], method=method, events=event_rational_1, dense_output=True) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 1) assert_(5.3 < res.t_events[0][0] < 5.7) # Also test that termination by event doesn't break interpolants. tc = np.linspace(res.t[0], res.t[-1]) yc_true = sol_rational(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, 1e-3, 1e-6) assert_(np.all(e < 5)) # Test in backward direction. event_rational_1.direction = 0 event_rational_2.direction = 0 for method in ['RK23', 'RK45', 'Radau', 'BDF', 'LSODA']: res = solve_ivp(fun_rational, [8, 5], [4 / 9, 20 / 81], method=method, events=(event_rational_1, event_rational_2)) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 1) assert_equal(res.t_events[1].size, 1) assert_(5.3 < res.t_events[0][0] < 5.7) assert_(7.3 < res.t_events[1][0] < 7.7) event_rational_1.direction = -1 event_rational_2.direction = -1 res = solve_ivp(fun_rational, [8, 5], [4 / 9, 20 / 81], method=method, events=(event_rational_1, event_rational_2)) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 1) assert_equal(res.t_events[1].size, 0) assert_(5.3 < res.t_events[0][0] < 5.7) event_rational_1.direction = 1 event_rational_2.direction = 1 res = solve_ivp(fun_rational, [8, 5], [4 / 9, 20 / 81], method=method, events=(event_rational_1, event_rational_2)) assert_equal(res.status, 0) assert_equal(res.t_events[0].size, 0) assert_equal(res.t_events[1].size, 1) assert_(7.3 < res.t_events[1][0] < 7.7) event_rational_1.direction = 0 event_rational_2.direction = 0 res = solve_ivp(fun_rational, [8, 5], [4 / 9, 20 / 81], method=method, events=(event_rational_1, event_rational_2, event_rational_3), dense_output=True) assert_equal(res.status, 1) assert_equal(res.t_events[0].size, 0) assert_equal(res.t_events[1].size, 1) assert_equal(res.t_events[2].size, 1) assert_(7.3 < res.t_events[1][0] < 7.7) assert_(7.3 < res.t_events[2][0] < 7.5) # Also test that termination by event doesn't break interpolants. tc = np.linspace(res.t[-1], res.t[0]) yc_true = sol_rational(tc) yc = res.sol(tc) e = compute_error(yc, yc_true, 1e-3, 1e-6) assert_(np.all(e < 5))
def integrate(self, k, q0, p0, a, rtol=1e-4): """ Solve the 3 fluid model from initial position and momentum q0, and p0, at times a. This can be slow if neutrino velocity and baryon velocity are non-zero. (200,000+ function evaluations with RK45, when rtol=1e-7) Parameters ---------- a : array_like scale factor requesting the output. k : array_like, k values to compute the solution, in h/Mpc. From classylss's transfer function. q0 : array_like (Nk, 3) initial position, -d, produced by `seed` from CLASSylss transfer function three species are cdm, baryon and ncdm. p0 : array_like (Nk, 3) initial momentum, a * v, from `seed`. three species are cdm, baryon and ncdm. rtol : float relative accuracy. It appears 1e-4 is good for k ~ 10 with reasonable velocities. Returns ------- a : array_like (Na), very close but not in general identical to input a. q : array_like (Na, Nk, 3) position (-d) at different requested a's p : array_like (Na, Nk, 3) momentum (a * v) at different requested a's. v is peculiar velocity. """ def marshal(q0, p0): vector = numpy.concatenate([q0.ravel(), p0.ravel()], axis=0) return vector # internally work with loga lna = numpy.log(a) def func(lna, vector): a = numpy.exp(lna) q = vector[: len(vector) // 2].reshape(q0.shape) p = vector[len(vector) // 2:].reshape(p0.shape) z = 1. / a - 1. dlna = 1. E = (self.efunc(z)) dt = dlna / E dp = - numpy.einsum('kij,kj->ki', self.J(k, a), q) * dt dq = p / a ** 2 * dt #print(a, dp[0] / q[0], p[0] / q[0]) return marshal(dq, dp) v0 = marshal(q0, p0) r = solve_ivp(func, (lna[0], lna[-1]), v0, method='RK45', t_eval=lna, rtol=rtol, atol=0, vectorized=False) q = r.y[: len(v0) // 2, ...].reshape(list(q0.shape) + [-1]) p = r.y[len(v0) // 2:, ...].reshape(list(p0.shape) + [-1]) #print('nfev=', r.nfev) return numpy.exp(r.t), q.transpose((2, 0, 1)), p.transpose((2, 0, 1))