def solver(alpha, ic, T, dt=0.05): def f(u, t): x_A, vx_A, y_A, vy_A, x_B, vx_B, y_B, vy_B = u distance3 = np.sqrt((x_B - x_A)**2 + (y_B - y_A)**2)**3 system = [ vx_A, 1 / (1.0 + alpha) * (x_B - x_A) / distance3, vy_A, 1 / (1.0 + alpha) * (y_B - y_A) / distance3, vx_B, -1 / (1.0 + alpha**(-1)) * (x_B - x_A) / distance3, vy_B, -1 / (1.0 + alpha**(-1)) * (y_B - y_A) / distance3, ] return system Nt = int(round(T / dt)) t_mesh = np.linspace(0, Nt * dt, Nt + 1) solver = odespy.RK4(f) solver.set_initial_condition(ic) u, t = solver.solve(t_mesh) x_A = u[:, 0] x_B = u[:, 2] y_A = u[:, 4] y_B = u[:, 6] return x_A, x_B, y_A, y_B, t
def varying_gravity(epsilon): def ode_a(u, t): h, v = u return [v, -epsilon**(-2) / (1 + h)**2] def ode_b(u, t): h, v = u return [v, -1.0 / (1 + h)**2] def ode_c(u, t): h, v = u return [v, -1.0 / (1 + epsilon**2 * h)**2] problems = [ode_a, ode_b, ode_c] # right-hand sides ics = [[0, 1], [0, epsilon], [0, 1]] # initial conditions for problem, ic, legend in zip(problems, ics, ['a', 'b', 'c']): solver = odespy.RK4(problem) solver.set_initial_condition(ic) t = np.linspace(0, 5, 5001) # Solve ODE until h < 0 (h is in u[:,0]) u, t = solver.solve(t, terminate=lambda u, t, n: u[n, 0] < 0) h = u[:, 0] plt.figure() plt.plot(t, h) plt.legend(legend, loc='upper left') plt.title(r'$\epsilon^2=%g$' % epsilon**2) plt.xlabel(r'$\bar t$') plt.ylabel(r'$\bar h(\bar t)$') plt.savefig('tmp_%s.png' % legend) plt.savefig('tmp_%s.pdf' % legend)
def solver(R0, alpha, gamma, delta, T, dt=0.1): def f(u, t): S, I, R, V = u return [ -R0 * S * I - delta(t) * S + gamma * R, R0 * S * I - I, I - gamma * R, delta(t) * S ] Nt = int(round(T / dt)) t_mesh = np.linspace(0, Nt * dt, Nt + 1) solver = odespy.RK4(f) solver.set_initial_condition([1 - alpha, alpha, 0, 0]) u, t = solver.solve(t_mesh) S = u[:, 0] I = u[:, 1] R = u[:, 2] V = u[:, 3] # Consistency check N = 1 tol = 1E-13 for i in range(len(S)): if abs(S[i] + I[i] + R[i] + V[i] - N) > tol: print 'Consistency error: S+I+R+V=%g != %g' % \ (S[i] + I[i] + R[i] + V[i], N) return S, I, R, V, t
def run_solvers_and_plot(solvers, timesteps_per_period=20, num_periods=1, b=0): w = 2 * np.pi # frequency of undamped free oscillations P = 2 * np.pi / w # duration of one period dt = P / timesteps_per_period Nt = num_periods * timesteps_per_period T = Nt * dt t_mesh = np.linspace(0, T, Nt + 1) t_fine = np.linspace(0, T, 8 * Nt + 1) # used for very accurate solution legends = [] solver_exact = odespy.RK4(f) for solver in solvers: solver.set_initial_condition([solver.users_f.I, 0]) u, t = solver.solve(t_mesh) solver_name = 'CrankNicolson' if solver.__class__.__name__ == \ 'MidpointImplicit' else solver.__class__.__name__ # Make plots (plot last 10 periods????) if num_periods <= 80: plt.figure(1) if len(t_mesh) <= 50: plt.plot(t, u[:, 0]) # markers by default else: plt.plot(t, u[:, 0], '-2') # no markers plt.hold('on') legends.append(solver_name) # Compare with exact solution plotted on a very fine mesh #t_fine = np.linspace(0, T, 10001) #u_e = solver.users_f.exact(t_fine) # Compare with RK4 on a much finer mesh solver_exact.set_initial_condition([solver.users_f.I, 0]) u_e, t_e = solver_exact.solve(t_fine) if num_periods < 80: plt.figure(1) plt.plot(t_e, u_e[:, 0], '-') # avoid markers by spec. line type legends.append('exact (RK4)') plt.legend(legends, loc='upper left') plt.xlabel('t') plt.ylabel('u') plt.title('Time step: %g' % dt) plt.savefig('vib_%d_%d_u.png' % (timesteps_per_period, num_periods)) plt.savefig('vib_%d_%d_u.pdf' % (timesteps_per_period, num_periods)) plt.savefig('vib_%d_%d_u.eps' % (timesteps_per_period, num_periods))
def get_solver(self, func): """ Returns the solver method from odespy package. Args: func: function function with ODE system. Returns: an instance of odeSolver """ if self.solverMethod is solverMethod.LSODA: solver = odespy.Lsoda(func) elif self.solverMethod is solverMethod.LSODAR: solver = odespy.Lsodar(func) elif self.solverMethod is solverMethod.LSODE: solver = odespy.Lsode(func) elif self.solverMethod is solverMethod.HEUN: solver = odespy.Heun(func) elif self.solverMethod is solverMethod.EULER: solver = odespy.Euler(func) elif self.solverMethod is solverMethod.RK4: solver = odespy.RK4(func) elif self.solverMethod is solverMethod.DORMAN_PRINCE: solver = odespy.DormandPrince(func) elif self.solverMethod is solverMethod.RKFehlberg: solver = odespy.RKFehlberg(func) elif self.solverMethod is solverMethod.Dopri5: solver = odespy.Dopri5(func) elif self.solverMethod is solverMethod.Dop853: solver = odespy.Dop853(func) elif self.solverMethod is solverMethod.Vode: solver = odespy.Vode(func) elif self.solverMethod is solverMethod.AdamsBashforth2: solver = odespy.AdamsBashforth2(func, method='bdf') elif self.solverMethod is solverMethod.Radau5: solver = odespy.Radau5(func) elif self.solverMethod is solverMethod.AdamsBashMoulton2: solver = odespy.AdamsBashMoulton2(func) # update default parameters solver.nsteps = SolverConfigurations.N_STEPS solver.atol = SolverConfigurations.ABSOLUTE_TOL solver.rtol = SolverConfigurations.RELATIVE_TOL return solver
def simulate_pendulum(alpha, theta0, dt, T): import odespy def f(u, t, alpha): omega, theta = u return [-alpha * omega * abs(omega) - sin(theta), omega] import numpy as np Nt = int(round(T / float(dt))) t = np.linspace(0, Nt * dt, Nt + 1) solver = odespy.RK4(f, f_args=[alpha]) solver.set_initial_condition([0, theta0]) u, t = solver.solve(t, terminate=lambda u, t, n: abs(u[n, 1]) < 1E-3) omega = u[:, 0] theta = u[:, 1] S = omega**2 + np.cos(theta) drag = -alpha * np.abs(omega) * omega return t, theta, omega, S, drag
def simulate(alpha, beta=0, num_periods=8, time_steps_per_period=60): # Use oscillations without friction to set dt and T P = 2 * np.pi dt = P / time_steps_per_period T = num_periods * P t = np.linspace(0, T, time_steps_per_period * num_periods + 1) import odespy def f(u, t, alpha): # Note the sequence of unknowns: v, u (v=du/dt) v, u = u return [-alpha * np.sign(v) - u, v] solver = odespy.RK4(f, f_args=[alpha]) solver.set_initial_condition([beta, 1]) # sequence must match f uv, t = solver.solve(t) u = uv[:, 1] # recall sequence in f: v, u v = uv[:, 0] return u, t
def simulate(Theta, num_periods=8, time_steps_per_period=60, scaling=1): # Use oscillations for small Theta to set dt and T P = 2 * np.pi dt = P / time_steps_per_period T = num_periods * P t = np.linspace(0, T, time_steps_per_period * num_periods + 1) import odespy def f(u, t, Theta): # Note the sequence of unknowns: omega, theta # omega = d(theta)/dt, angular velocity omega, theta = u return [-Theta**(-1) * np.sin(Theta * theta), omega] solver = odespy.RK4(f, f_args=[Theta]) solver.set_initial_condition([0, 1]) # sequence must match f u, t = solver.solve(t) theta = u[:, 1] # recall sequence in f: omega, theta return theta, t
def solver(alpha, beta, epsilon, T, dt=0.1): def f(u, t): Q, P, S, E = u return [ alpha*(E*S - Q), beta*Q, -E*S + (1-beta/alpha)*Q, (-E*S + Q)/epsilon, ] Nt = int(round(T/dt)) t_mesh = np.linspace(0, Nt*dt, Nt+1) solver = odespy.RK4(f) solver.set_initial_condition([0, 0, 1, 1]) u, t = solver.solve(t_mesh) Q = u[:,0] P = u[:,1] S = u[:,2] E = u[:,3] return Q, P, S, E
def simulate2(mu, nu, omega, T=20): def f(u, t, mu): H, L = u return [H * (1 - L), mu * L * (H - 1)] t = np.linspace(0, T, 1501) solver = odespy.RK4(f, f_args=(mu, )) solver.set_initial_condition([nu, omega]) u, t = solver.solve(t) H = u[:, 0] L = u[:, 1] plt.figure() global fig_counter fig_counter += 1 plt.plot(t, H, t, L) plt.legend(['H', 'L']) plt.title(r'$\mu=%g$, $\nu=%g$, $\omega=%g$' % (mu, nu, omega)) plt.savefig('tmp%d.png' % fig_counter) plt.savefig('tmp%d.pdf' % fig_counter) return H, L, t
def solver(alpha, ic, T, dt=0.05): def f(u, t): x, vx, y, vy = u v = np.sqrt(vx**2 + vy**2) # magnitude of velocity system = [ vx, -alpha * np.abs(v) * vx, vy, -2 - alpha * np.abs(v) * vy, ] return system Nt = int(round(T / dt)) t_mesh = np.linspace(0, Nt * dt, Nt + 1) solver = odespy.RK4(f) solver.set_initial_condition(ic) u, t = solver.solve(t_mesh, terminate=lambda u, t, n: u[n][2] < 0) x = u[:, 0] y = u[:, 2] return x, y, t
def run_solvers_and_plot(solvers, rhs, T, dt, title='', filename='tmp'): """ Run solvers from the `solvers` list and plot solution curves in the same figure. """ Nt = int(round(T / float(dt))) t_mesh = np.linspace(0, T, Nt + 1) t_fine = np.linspace(0, T, 8 * Nt + 1) # used for very accurate solution legends = [] for solver in solvers: solver.set_initial_condition([rhs.I, 0]) u, t = solver.solve(t_mesh) solver_name = 'CrankNicolson' if solver.__class__.__name__ == \ 'MidpointImplicit' else solver.__class__.__name__ if len(t_mesh) <= 50: plt.plot(t, u[:, 0]) # markers by default else: plt.plot(t, u[:, 0], '-2') # no markers plt.hold('on') legends.append(solver_name) # Compare with RK4 on a much finer mesh solver_exact = odespy.RK4(rhs) solver_exact.set_initial_condition([rhs.I, 0]) u_e, t_e = solver_exact.solve(t_fine) plt.plot(t_e, u_e[:, 0], '-') # avoid markers by spec. line type legends.append('RK4, dt=%g' % (t_fine[1] - t_fine[0])) plt.legend(legends, loc='lower left') plt.xlabel('t') plt.ylabel('u') plt.title(title) plotfilestem = '_'.join(legends) plt.savefig('%s.png' % filename) plt.savefig('%s.pdf' % filename)
def simulate(alpha, beta, gamma, delta, T=20): def f(u, t, alpha, beta, gamma): H, L = u return [alpha * H - L * H, beta * L * H - gamma * L] t = np.linspace(0, T, 1501) solver = odespy.RK4(f, f_args=(alpha, beta, gamma)) solver.set_initial_condition([1, delta]) u, t = solver.solve(t) H = u[:, 0] L = u[:, 1] plt.figure() global fig_counter fig_counter += 1 plt.plot(t, H, t, L) plt.legend(['H', 'L']) plt.title(r'$\alpha=%g$, $\beta=%g$, $\gamma=%g$, $\delta=%g$' % (alpha, beta, gamma, delta)) plt.savefig('tmp%d.png' % fig_counter) plt.savefig('tmp%d.pdf' % fig_counter) return H, L, t
def biochemical_solver(alpha, beta, epsilon, T, dt=0.1): def f(u, t): Q, P, S, E = u # Consistency checks conservation1 = abs(Q/(alpha*epsilon) + E - 1) conservation2 = abs(alpha*S + Q + P - alpha) tol = 1E-14 if conservation1 > tol or conservation2 > tol: print 't=%g *** conservations:' % t, \ conservation1, conservation2 if Q < 0: print 't=%g *** Q=%g < 0' % (t, Q) if P < 0: print 't=%g *** P=%g < 0' % (t, P) if S < 0 or S > 1: print 't=%g *** S=%g' % (t, S) if E < 0 or S > 1: print 't=%g *** E=%g' % (t, E) return [ alpha*(E*S - Q), beta*Q, -E*S + (1-beta/alpha)*Q, (-E*S + Q)/epsilon, ] import numpy as np Nt = int(round(T/dt)) t_mesh = np.linspace(0, Nt*dt, Nt+1) solver = odespy.RK4(f) solver.set_initial_condition([0, 0, 1, 1]) u, t = solver.solve(t_mesh) Q = u[:,0] P = u[:,1] S = u[:,2] E = u[:,3] return Q, P, S, E, t
def demo(): from numpy import pi, linspace, cos omega = 2 P = 2 * pi / omega dt = P / 20 T = 40 * P X_0 = 2 RK4 = odespy.RK4(f, f_args=[omega]) RK4.set_initial_condition([X_0, 0]) N_t = int(round(T / dt)) u, t = RK4.solve(linspace(0, T, N_t + 1)) u, v = u[:, 0], u[:, 1] # Last p periods p = 10 m = p * 20 fig = plt.figure() l1, l2 = plt.plot(t[-m:], u[-m:], 'b-', t[-m:], X_0 * cos(omega * t)[-m:], 'r--') fig.legend((l1, l2), ('numerical', 'exact'), 'lower left') plt.xlabel('t') plt.show() plt.savefig('tmp.pdf') plt.savefig('tmp.png')
"""As exde1.py, but y and x as names instead of u and t.""" def myrhs(y, x): return -y import odespy solver = odespy.RK4(myrhs) solver.set_initial_condition(1) import numpy # Make sure integration interval [0, L] is large enough N = 50 L = 10 x_points = numpy.linspace(0, L, N + 1) def terminate(y, x, stepnumber): tol = 0.001 return True if abs(y[stepnumber]) < tol else False y, x = solver.solve(x_points, terminate) print 'Final y(x=%g)=%g' % (x[-1], y[-1]) from matplotlib.pyplot import * plot(x, y) show()
import odespy, numpy, time w = 2 * numpy.pi n = 600 # no of periods r = 40 # resolution of each period tp = numpy.linspace(0, n, n * r + 1) solvers = [ odespy.Vode(f, complex_valued=True, atol=1E-7, rtol=1E-6, adams_or_bdf='adams'), odespy.RK4(f, complex_valued=True), odespy.RKFehlberg(f, complex_valued=True, atol=1E-7, rtol=1E-6) ] cpu = [] for solver in solvers: solver.set_initial_condition(1 + 0j) t0 = time.clock() solver.solve(tp) t1 = time.clock() cpu.append(t1 - t0) # Compare solutions at the end point: exact = numpy.exp(1j * w * tp).real[-1] min_cpu = min(cpu) cpu = [c / min_cpu for c in cpu] # normalize print 'Exact: u(%g)=%g' % (tp[-1], exact)
#f = RHS(b=0.4, A_F=1, w_F=2) f = RHS(b=0.4, A_F=0, w_F=2) f = RHS(b=0.4, A_F=1, w_F=np.pi) f = RHS(b=0.4, A_F=20, w_F=2 * np.pi) # qualitatively wrong FE, almost ok BE, smaller T #f = RHS(b=0.4, A_F=20, w_F=0.5*np.pi) # cool, FE almost there, BE good # Define different sets of experiments solvers_theta = [ odespy.ForwardEuler(f), # Implicit methods must use Newton solver to converge odespy.BackwardEuler(f, nonlinear_solver='Newton'), odespy.CrankNicolson(f, nonlinear_solver='Newton'), ] solvers_RK = [odespy.RK2(f), odespy.RK4(f)] solvers_accurate = [ odespy.RK4(f), odespy.CrankNicolson(f, nonlinear_solver='Newton'), odespy.DormandPrince(f, atol=0.001, rtol=0.02) ] solvers_CN = [odespy.CrankNicolson(f, nonlinear_solver='Newton')] if __name__ == '__main__': timesteps_per_period = 20 solver_collection = 'theta' num_periods = 1 try: # Example: python vib_odespy.py 30 accurate 50 timesteps_per_period = int(sys.argv[1]) solver_collection = sys.argv[2]
self.period = 2 * pi / self.freq def __call__(self, u, t): theta, omega = u c = self.c return [omega, -c * theta] problem = Problem(c=1, Theta=pi / 4) import odespy solvers = [ odespy.ThetaRule(problem, theta=0), # Forward Euler odespy.ThetaRule(problem, theta=0.5), # Midpoint odespy.ThetaRule(problem, theta=1), # Backward Euler odespy.RK4(problem), odespy.RK2(problem), odespy.MidpointIter(problem, max_iter=5, eps_iter=0.01), odespy.Leapfrog(problem), odespy.LeapfrogFiltered(problem), ] theta_exact = lambda t: problem.Theta * numpy.cos(sqrt(problem.c) * t) import sys try: num_periods = int(sys.argv[1]) except IndexError: num_periods = 8 # default T = num_periods * problem.period # final time
self.a = a self.R = R self.A = A def f(self, u, t): a, R = self.a, self.R # short form return a * u * (1 - u / R) def u_exact(self, t): a, R, A = self.a, self.R, self.A # short form return R * A * exp(a * t) / (R + A * (exp(a * t) - 1)) import odespy problem = Logistic(a=2, R=1E+5, A=1) solver = odespy.RK4(problem.f) solver.set_initial_condition(problem.A) T = 10 # end of simulation N = 30 # no of time steps time_points = linspace(0, T, N + 1) u, t = solver.solve(time_points) from matplotlib.pyplot import * plot(t, u, 'r-', t, problem.u_exact(t), 'bo') savefig('tmppng') savefig('tmp.pdf') show()
plt.savefig('vib_%d_%d_p.png' % (timesteps_per_period, num_periods)) plt.figure(4) plt.legend(legends, loc='center right') plt.title('Empirically estimated amplitudes') plt.savefig('vib_%d_%d_a.pdf' % (timesteps_per_period, num_periods)) plt.savefig('vib_%d_%d_a.png' % (timesteps_per_period, num_periods)) # Define different sets of experiments solvers_theta = [ odespy.ForwardEuler(f), # Implicit methods must use Newton solver to converge odespy.BackwardEuler(f, nonlinear_solver='Newton'), odespy.CrankNicolson(f, nonlinear_solver='Newton'), ] solvers_RK = [odespy.RK2(f), odespy.RK4(f)] solvers_accurate = [odespy.RK4(f), odespy.CrankNicolson(f, nonlinear_solver='Newton'), odespy.DormandPrince(f, atol=0.001, rtol=0.02)] solvers_CN = [odespy.CrankNicolson(f, nonlinear_solver='Newton')] solvers_EC = [odespy.EulerCromer(f)] if __name__ == '__main__': # Default values timesteps_per_period = 20 solver_collection = 'theta' num_periods = 1 # Override from command line try: # Example: python vib_undamped_odespy.py 30 accurate 50 timesteps_per_period = int(sys.argv[1])
self.period = 2 * pi / self.freq def f(self, u, t): theta, omega = u c = self.c return [omega, -c * theta] problem = Problem(c=1, Theta=pi / 4) import odespy solvers = [ odespy.ThetaRule(problem.f, theta=0), # Forward Euler odespy.ThetaRule(problem.f, theta=0.5), # Midpoint method odespy.ThetaRule(problem.f, theta=1), # Backward Euler odespy.RK4(problem.f), odespy.MidpointIter(problem.f, max_iter=2, eps_iter=0.01), odespy.LeapfrogFiltered(problem.f), ] N_per_period = 20 T = 3 * problem.period # final time import numpy import matplotlib.pyplot as plt legends = [] for solver in solvers: solver_name = str(solver) # short description of solver print solver_name solver.set_initial_condition([problem.Theta, 0])
def f(u, t, a=1, R=1): return a * u * (1 - u / R) A = 1 import odespy, numpy from matplotlib.pyplot import plot, hold, show, axis solver = odespy.RK4(f, f_kwargs=dict(a=2, R=1E+5)) # Split time domain into subdomains and # integrate the ODE in each subdomain T = [0, 1, 4, 8, 12] # subdomain boundaries N_tot = 30 # total no of time steps dt = float(T[-1]) / N_tot # time step, kept fixed u = [] t = [] # collectors for u and t in each domain for i in range(len(T) - 1): T_interval = T[i + 1] - T[i] N = int(round(T_interval / dt)) time_points = numpy.linspace(T[i], T[i + 1], N + 1) solver.set_initial_condition(A) # at time_points[0] print 'Solving in [%s, %s] with %d intervals' % \ (T[i], T[i+1], N) ui, ti = solver.solve(time_points) A = ui[-1] # newest ui value is next initial condition
def model_free_lift(duration, bal_mass, bal_diam, bal_mat='rubber', bal_gas='helium', payload=0, plot_show=False, plot_save_as='', show_debug_msg=False, ): """ Моделирование процесса свободного подъёма для шара с полезной нагрузкой Функция создаёт изображение-график, если в аргументе <plot_save_as> для него передано имя --------------------------------------------------------------------------- :param duration: продолжительность моделируемого процесса, с :param bal_mass: масса метеошара, кг :param bal_diam: диаметр метеошара в состоянии без растяжения, м :param bal_mat: наименование материала метеошара. Варианты: {'rubber', } (см пакет <material>) :param bal_gas: наименование наполняющего газа метеошара. Варианты: {'helium', } (см пакет <gas>) :param payload: полезная нагрузка, поднимаемая метеошаром, кг :param plot_show: True/False отображение графика процесса :param plot_save_as: путь к сохраняемому файлу графика, с расширением. '' - пустая строка - не сохранять изображение :param show_debug_msg: отображать отладочные сообщения выводом print() --------------------------------------------------------------------------- :return: exit_status: 0 - успешное завршение 1 - некорректные входные данные 2 - ошибка создания объекта метеошара 3 - ошибка интегрирования системы ОДУ 4 - ошибка создания графика решения Примеры вызова: >>> model_free_lift(duration=180*60, ... bal_mass=3.0, ... bal_diam=2.164, ... payload=1.05, ... plot_save_as='doctest.png', ... plot_show=True, ... show_debug_msg=True) Called function: model_free_lift( duration=10800, bal_mass=3.0, bal_diam=2.164, bal_mat=rubber, bal_gas=helium, payload=1.05, plot_show=True, plot_save_as=doctest.png, show_debug_msg=True) RK4 terminated at t=7018 Successfull end. 0 >>> kwargs = {'duration': 180*60, ... 'bal_mass': 3.0, ... 'bal_diam':2.164, ... 'payload': 1.05, ... 'plot_save_as': 'doctest.png'} >>> model_free_lift(**kwargs) RK4 terminated at t=7018 0 """ # Send inputs to log if show_debug_msg: log_msg = "Called function:\n" \ " model_free_lift(\n" \ " duration={0},\n" \ " bal_mass={1},\n" \ " bal_diam={2},\n" \ " bal_mat={3},\n" \ " bal_gas={4},\n" \ " payload={5},\n" \ " plot_show={6},\n" \ " plot_save_as={7},\n" \ " show_debug_msg={8})".\ format(duration, bal_mass, bal_diam, bal_mat, bal_gas, payload, plot_show, plot_save_as, show_debug_msg) print(log_msg) # Create ODE-function for model def odefun(y, time, balloon, payload): """ Дифф. закон Ньютона - уравнение процесса свободного подъёма для шара с полезной нагрузкой В форме Коши: dy/dt = f(y, t) Внимание! Условие разрыва шара должно проверяться извне функции. """ alt = y[0] vel = y[1] # Model equations f_sum_bal = balloon.get_forces_sum(alt, vel) f_sum_pl = - payload*const.g f_sum = f_sum_bal + f_sum_pl mass = balloon.get_mass() + payload return [vel, f_sum/mass] def terminator(y, t, step_no): # Функция, останавливающая интегрирование при разрыве метеошара h = y[step_no][0] tf = balloon.is_burst(h) return tf # Check inputs. # ----------------------------------------------------------- try: # Confirm input numeric types duration = float(duration) if duration <= 0: raise ValueError('duration must be positive') bal_mass = float(bal_mass) if bal_mass <= 0: raise ValueError('bal_mass must be positive') bal_diam = float(bal_diam) if bal_diam <= 0: raise ValueError('bal_diam must be positive') payload = float(payload) if payload < 0: raise ValueError('payload must be non-negative') # Define material if not (bal_mat in material.__all__): raise ValueError("Unknown balloon material name ", bal_mat) # Define gas if not (bal_gas in gas.__all__): raise ValueError("Unknown gas name ", bal_gas) except ValueError as err: print(err, file=sys.stderr) return 1 # Create balloon instance # ----------------------------------------------------------- try: balloon = BalloonStatic( bal_mass=bal_mass, bal_diam=bal_diam, bal_mat=material.BY_NAME[bal_mat], gas=gas.BY_NAME[bal_gas]) except Exception as err: print(err, file=sys.stderr) return 2 # Шаг детализации процесса по времени, с tstep = duration/100.0 if duration < 100.0 else 1 time_points = np.arange(0, duration, tstep) # solve the DEs # ----------------------------------------------------------- try: # Create solver (Runge-Kutta, 4th order) solver = odespy.RK4( odefun, f_args=(balloon, payload), rtol=1E-2) solver.set_initial_condition([0, 0]) y_sln, time = solver.solve( time_points, terminate=terminator) alt = y_sln[:, 0] vel = y_sln[:, 1] # Максимальная высота alt_max = max(alt) # Момент достижения макс. высоты time_alt_max = time[np.where(alt == alt_max)][0] # Индекс высшей точки в массиве ind_max = np.argmax(alt) # Скрыть некорректные точки расчёта после разрыва шара time = time[:ind_max] alt = alt[:ind_max] vel = vel[:ind_max] except Exception as err: print(err, file=sys.stderr) return 3 # Plot # ----------------------------------------------------------- if plot_show or plot_save_as: try: # масштаб отображения scale_v = 1.0 # скорости scale_h = 1.0/1000.0 # высоты scale_t = 1.0/60.0 # времени time *= scale_t time_alt_max *= scale_t alt *= scale_h alt_max *= scale_h vel *= scale_v # Построение графика matplotlib.rcParams['font.size'] = 14 matplotlib.rcParams['font.family'] = utils.get_font() matplotlib.rcParams["axes.grid"] = True plt.figure() plt.plot( time, alt, 'b-', linewidth=2.0, label=u'Высота, км') plt.plot( time, vel, 'r-', linewidth=2.0, label=u'Скорость, м/с') plt.xlabel(u'Время, мин') matplotlib.pyplot.ylim([0.0, alt_max*1.2]) plt.legend(loc='upper left', shadow=True) plt.title( u"Полёт метеошара\n" u"(m = {0} кг; Ø = {1} м, нагрузка {2} кг)\n" u"Макс. высота {3} км достигнута спустя {4} мин".format( balloon.bal_mass, balloon.d0, payload, round(alt_max), round(time_alt_max) )) if plot_save_as: plt.savefig(plot_save_as, bbox_inches='tight') if plot_show: plt.show() plt.close() except Exception as err: print(err, file=sys.stderr) return 4 else: warnings.warn("All output's disabled.") if show_debug_msg: print('Successfull end.') return 0
line_color = ['k', 'm', 'b', 'r'] figure(figsize=(20, 8)) hold('on') LNWDT = 4 FNT = 18 rcParams['lines.linewidth'] = LNWDT rcParams['font.size'] = FNT # computing and plotting # smooth ball with drag for i in range(0, N2): z0 = np.zeros(4) z0[2] = v0 * np.cos(angle[i]) z0[3] = v0 * np.sin(angle[i]) solver = odespy.RK4(f) solver.set_initial_condition(z0) z, t = solver.solve(time) plot(z[:, 0], z[:, 1], ':', color=line_color[i]) legends.append('angle=' + str(alfa[i]) + ', smooth ball') # golf ball with drag for i in range(0, N2): z0 = np.zeros(4) z0[2] = v0 * np.cos(angle[i]) z0[3] = v0 * np.sin(angle[i]) solver = odespy.RK4(f2) solver.set_initial_condition(z0) z, t = solver.solve(time) plot(z[:, 0], z[:, 1], '-.', color=line_color[i]) legends.append('angle=' + str(alfa[i]) + ', golf ball')
def f(u, t): return a * u * (1 - u / R) a = 2 R = 1E+5 A = 1 import odespy solver = odespy.RK4(f) solver.set_initial_condition(A) from numpy import linspace, exp T = 10 # end of simulation N = 30 # no of time steps time_points = linspace(0, T, N + 1) u, t = solver.solve(time_points) def u_exact(t): return R * A * exp(a * t) / (R + A * (exp(a * t) - 1)) from matplotlib.pyplot import * plot(t, u, 'r-', t, u_exact(t), 'bo') savefig('tmppng') savefig('tmp.pdf') show()
dist = cp.J(dist_a, dist_I) # joint multivariate dist P, norms = cp.orth_ttr(2, dist, retall=True) variable_a, variable_I = cp.variable(2) PP = cp.outer(P, P) E_aPP = cp.E(variable_a * PP, dist) E_IP = cp.E(variable_I * P, dist) def right_hand_side(c, x): # c' = right_hand_side(c, x) return -np.dot(E_aPP, c) / norms # -M*c initial_condition = E_IP / norms solver = odespy.RK4(right_hand_side) solver.set_initial_condition(initial_condition) x = np.linspace(0, 10, 1000) c = solver.solve(x)[0] u_hat = cp.dot(P, c) #Rosenblat transformation using point collocation def u(x, a, I): return I * np.exp(-a * x) dist_R = cp.J(cp.Normal(), cp.Normal()) C = [[1, 0.5], [0.5, 1]] mu = [0, 0]
def f(u, t): return -a * u I = 1 a = 2 T = 6 dt = float(sys.argv[1]) if len(sys.argv) >= 2 else 0.75 Nt = int(round(T / dt)) t_mesh = np.linspace(0, Nt * dt, Nt + 1) solvers = [ odespy.RK2(f), odespy.RK3(f), odespy.RK4(f), # BackwardEuler must use Newton solver to converge # (Picard is default and leads to divergence) odespy.BackwardEuler(f, nonlinear_solver='Newton') ] legends = [] for solver in solvers: solver.set_initial_condition(I) u, t = solver.solve(t_mesh) plt.plot(t, u) plt.hold('on') legends.append(solver.__class__.__name__) # Compare with exact solution plotted on a very fine mesh
def fblasius(y, x): """ODE-system for the Blasius-equation""" return [y[1],y[2], -y[0]*y[2]] import odespy solvers=[] solvers.append(odespy.RK4(fblasius)) solvers.append(odespy.RK2(fblasius)) solvers.append(odespy.RK3(fblasius)) from numpy import linspace, exp xmin = 0 xmax = 5.75 N = 150 # no x-values xspan = linspace(xmin, xmax, N+1) smin=0.1 smax=0.8 Ns=30 srange = linspace(smin,smax,Ns) from matplotlib.pyplot import * #change some default values to make plots more readable on the screen LNWDT=5; FNT=25 matplotlib.rcParams['lines.linewidth'] = LNWDT; matplotlib.rcParams['font.size'] = FNT figure() legends=[] linet=['r-',':','.','-.','--']
k4 = func(z[i, :] + k3 * dt, t + dt) # predictor step 4 z[i + 1, :] = z[i, :] + dt / 6.0 * (k1 + 2.0 * k2 + 2.0 * k3 + k4 ) # Corrector step return z # Main program starts here from numpy import linspace T = 10 # end of simulation N = 20 # no of time steps time = linspace(0, T, N + 1) solvers = [] solvers.append(odespy.RK3(f2)) solvers.append(odespy.RK4(f2)) legends = [] z0 = np.zeros(2) z0[0] = 2.0 for i, solver in enumerate(solvers): solver.set_initial_condition(z0) z, t = solver.solve(time) plot(t, z[:, 1]) legends.append(str(solver)) scheme_list = [euler, heun, rk4_own] for scheme in scheme_list: