Example #1
0
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
Example #2
0
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)
Example #3
0
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
Example #4
0
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))
Example #5
0
    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
Example #6
0
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
Example #7
0
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
Example #8
0
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
Example #9
0
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
Example #10
0
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
Example #11
0
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
Example #12
0
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)
Example #13
0
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
Example #14
0
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')
Example #16
0
"""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()
Example #17
0

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)
Example #18
0
#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]
Example #19
0
        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
Example #20
0
        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()
Example #21
0
        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])
Example #22
0
        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])
Example #23
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
Example #24
0
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
Example #25
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')
Example #26
0
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()
Example #27
0
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]
Example #28
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
Example #29
0
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-',':','.','-.','--']
Example #30
0
        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: