def demo(): """ Demonstrate difference between Euler-Cromer and the scheme for the corresponding 2nd-order ODE. """ I = 1.2 V = 0.2 m = 4 b = 0.2 s = lambda u: 2 * u F = lambda t: 0 w = np.sqrt(2. / 4) # approx freq dt = 0.9 * 2 / w # longest possible time step w = 0.5 P = 2 * pi / w T = 4 * P from vib import solver as solver2 import scitools.std as plt for k in range(4): u2, t2 = solver2(I, V, m, b, s, F, dt, T, 'quadratic') u, v, t = solver(I, V, m, b, s, F, dt, T, 'quadratic') plt.figure() plt.plot(t, u, 'r-', t2, u2, 'b-') plt.legend(['Euler-Cromer', 'centered scheme']) plt.title('dt=%.3g' % dt) raw_input() plt.savefig('tmp_%d' % k + '.png') plt.savefig('tmp_%d' % k + '.pdf') dt /= 2
def _test5(): problem = Problem3() import argparse parser = argparse.ArgumentParser( description='Logistic ODE model') parser = problem.define_command_line_arguments(parser) # Try first with manual settings problem.set(alpha=0.1, U0=2, T=130, R=lambda t: 500 if t < 60 else 100) solver = AutoSolver(problem, tol=1) solver.solve(method=ODESolver.RungeKutta4) print 'dt:', solver.dt solver.plot() # New example with data from the command line # Try --alpha 0.11 --T 130 --U0 2 --R '500 if t < 60 else 300' args = parser.parse_args() problem.set(args=args) print problem.alpha, problem.R, problem.U0, problem.T solver = AutoSolver(problem, tol=1) solver.solve(method=ODESolver.RungeKutta4) print 'dt:', solver.dt figure() solver.plot()
def demo(): """ Demonstrate difference between Euler-Cromer and the scheme for the corresponding 2nd-order ODE. """ I = 1.2 w = 2.0 T = 5 dt = 2 / w # longest possible time step from vib_undamped import solver as solver2 # 2nd-order ODE import scitools.std as plt for k in range(4): dt /= 4 u2, t2 = solver2(I, w, dt, T) u, v, t = solver(I, w, dt, T) plt.figure() plt.plot(t, u, t2, u2, legend=('Euler-Cromer', 'center scheme for $u' '+u=0$'), title='dt=%.3g' % dt) raw_input() plt.savefig('ECvs2nd_%d' % k + '.png') plt.savefig('ECvs2nd_%d' % k + '.pdf')
def slides_waves(): L = 10. a = 0.5 B0 = 1. A = B0/5 t0 = 3. v = 1. x0 = lambda t: L/4 + v*t if t < t0 else L/4 + v*t0 sigma = 1.0 def bottom(x, t): return (B(x, a, L, B0) + S(x, A, x0(t), sigma)) def depth(x, t): return -bottom(x, t) import scitools.std as plt x = np.linspace(0, L, 101) plt.plot(x, bottom(x, 0), x, depth(x, 0), legend=['bottom', 'depth']) plt.show() raw_input() plt.figure() dt_b = 0.01 solver(I=0, V=0, f=lambda x, t: -(depth(x, t-dt_b) - 2*depth(x, t) + depth(x, t+dt_b))/dt_b**2, c=lambda x, t: np.sqrt(np.abs(depth(x, t))), U_0=None, U_L=None, L=L, dt=0.1, C=0.9, T=20, user_action=PlotSurfaceAndBottom(B, S, a, L, B0, A, x0, sigma, umin=-2, umax=2), stability_safety_factor=0.9)
def demo5(): problem = Problem3() import argparse parser = argparse.ArgumentParser( description='Logistic ODE model') parser = problem.define_command_line_arguments(parser) # Try first with manual settings problem.set(alpha=0.1, U0=2, T=130, R=lambda t: 500 if t < 60 else 100) solver = AutoSolver(problem, tol=1) solver.solve(method=ODESolver.RungeKutta4) print 'dt:', solver.dt solver.plot() # New example with data from the command line # Try --alpha 0.11 --T 130 --U0 2 --R '500 if t < 60 else 300' args = parser.parse_args() problem.set(args=args) print problem.alpha, problem.R, problem.U0, problem.T solver = AutoSolver(problem, tol=1) solver.solve(method=ODESolver.RungeKutta4) print 'dt:', solver.dt figure() solver.plot()
def comparison_plot(f, u, Omega, plotfile='tmp'): """Compare f(x,y) and u(x,y) for x,y in Omega in a plot.""" x, y = sm.symbols('x y') f = sm.lambdify([x,y], f, modules="numpy") u = sm.lambdify([x,y], u, modules="numpy") # When doing symbolics, Omega can easily contain symbolic expressions, # assume .evalf() will work in that case to obtain numerical # expressions, which then must be converted to float before calling # linspace below for r in range(2): for s in range(2): if not isinstance(Omega[r][s], (int,float)): Omega[r][s] = float(Omega[r][s].evalf()) resolution = 41 # no of points in plot xcoor = linspace(Omega[0][0], Omega[0][1], resolution) ycoor = linspace(Omega[1][0], Omega[1][1], resolution) xv, yv = ndgrid(xcoor, ycoor) # Vectorized functions expressions does not work with # lambdify'ed functions without the modules="numpy" exact = f(xv, yv) approx = u(xv, yv) figure() surfc(xv, yv, exact, title='f(x,y)', colorbar=True, colormap=hot(), shading='flat') if plotfile: savefig('%s_f.pdf' % plotfile, color=True) savefig('%s_f.png' % plotfile) figure() surfc(xv, yv, approx, title='f(x,y)', colorbar=True, colormap=hot(), shading='flat') if plotfile: savefig('%s_u.pdf' % plotfile, color=True) savefig('%s_u.png' % plotfile)
def demo(): """ Demonstrate difference between Euler-Cromer and the scheme for the corresponding 2nd-order ODE. """ I = 1.2 V = 0.2 m = 4 b = 0.2 s = lambda u: 2 * u F = lambda t: 0 w = np.sqrt(2.0 / 4) # approx freq dt = 0.9 * 2 / w # longest possible time step w = 0.5 P = 2 * pi / w T = 4 * P from vib import solver as solver2 import scitools.std as plt for k in range(4): u2, t2 = solver2(I, V, m, b, s, F, dt, T, "quadratic") u, v, t = solver(I, V, m, b, s, F, dt, T, "quadratic") plt.figure() plt.plot(t, u, "r-", t2, u2, "b-") plt.legend(["Euler-Cromer", "centered scheme"]) plt.title("dt=%.3g" % dt) raw_input() plt.savefig("tmp_%d" % k + ".png") plt.savefig("tmp_%d" % k + ".pdf") dt /= 2
def visualize(self): u = self.solver.u; t = self.solver.t # short forms num_periods = vib_plot_empirical_freq_and_amplitude(u, t) if num_periods <= 40: plt.figure() vib_visualize(u, t) else: vib_visualize_front(u, t, self.window_width, self.savefig) vib_visualize_front_ascii(u, t) plt.show()
def plotting(xu, xeta, u1, eta1, bpu, bpeta): sci.figure(1) sci.plot(xeta, eta1, xeta, -bpeta, axes=(xu[0], xu[-1], -1.1 * max(bpeta), 2.0 * max(bpeta))) sci.figure(2) sci.plot(xu, u1, xu, -bpu, axes=(xu[0], xu[-1], -1.1 * max(bpu), 2.0 * max(bpu)))
def draw_basis_functions(): """Illustrate P1, P2, and P3 basis functions on an element.""" for ext in 'pdf', 'png': for derivative in (0, 1): for labels in True, False: deriv = '' if derivative == 0 else 'd' philab = '' if not labels else '_lab' fe_basis_function_figure( d=1, target_elm=1, N_e=4, derivative=derivative, filename='fe_%sbasis_p1_4e%s.%s' % (deriv, philab, ext), labels=labels) plt.figure() fe_basis_function_figure( d=2, target_elm=1, N_e=4, derivative=derivative, filename='fe_%sbasis_p2_4e%s.%s' % (deriv, philab, ext), labels=labels) plt.figure() fe_basis_function_figure( d=1, target_elm=1, N_e=5, derivative=derivative, filename='fe_%sbasis_p1_5e%s.%s' % (deriv, philab, ext), labels=labels) plt.figure() fe_basis_function_figure( d=3, target_elm=1, N_e=4, derivative=derivative, filename='fe_%sbasis_p3_4e%s.%s' % (deriv, philab, ext), labels=labels) plt.figure() fe_basis_function_figure( d=3, target_elm=2, N_e=5, derivative=derivative, filename='fe_%sbasis_p3_5e%s.%s' % (deriv, philab, ext), labels=labels)
def case(nperiods=4, showplot=False): I = [1, 0] # Does not work well with float arrays and Cython I = [1., 0.] f = ode.Problem1() t0 = time.clock() time_points = np.linspace(0, nperiods*2*np.pi, nperiods*30+1) u, t = ode.solver(f, I, time_points, ode.RK2) t1 = time.clock() if showplot and nperiods < 8: from scitools.std import plot, figure plot(t[-200:], u[-200:,0]) figure() plot(u[-200:,0], u[-200:,1]) return t1-t0, time_points.size
def run_sines(help=False): for N in (4, 12): f = 10*(x-1)**2 - 1 psi = sines(x, N) Omega = [0, 1] if help: # u = 9 + sum f0 = 9; f1 = -1 term = f0*(1-x) + x*f1 u = term + least_squares_orth(f-term, psi, Omega) else: u = least_squares_orth(f, psi, Omega) figure() comparison_plot(f, u, Omega, 'parabola_ls_sines%d%s.pdf' % (N, '_wfterm' if help else ''))
def case(nperiods=4, showplot=False, ftype='class'): I = [1, 0] if ftype == 'class': f = ProblemOpt() else: f = problem t0 = time.clock() u, t = RK2(f, I, t=np.linspace(0, nperiods * np.pi, nperiods * 30 + 1)) t1 = time.clock() if showplot: plot(t[-200:], u[-200:, 0]) figure() plot(u[-200:, 0], u[-200:, 1]) return t1 - t0
def draw_basis_functions(): """Illustrate P1, P2, and P3 basis functions on an element.""" for ext in 'pdf', 'png': for derivative in (0, 1): for labels in True, False: deriv = '' if derivative == 0 else 'd' philab = '' if not labels else '_lab' fe_basis_function_figure( d=1, target_elm=1, n_e=4, derivative=derivative, filename='fe_%sbasis_p1_4e%s.%s' % (deriv, philab, ext), labels=labels) plt.figure() fe_basis_function_figure( d=2, target_elm=1, n_e=4, derivative=derivative, filename='fe_%sbasis_p2_4e%s.%s' % (deriv, philab, ext), labels=labels) plt.figure() fe_basis_function_figure( d=1, target_elm=1, n_e=5, derivative=derivative, filename='fe_%sbasis_p1_5e%s.%s' % (deriv, philab, ext), labels=labels) plt.figure() fe_basis_function_figure( d=3, target_elm=1, n_e=4, derivative=derivative, filename='fe_%sbasis_p3_4e%s.%s' % (deriv, philab, ext), labels=labels) plt.figure() fe_basis_function_figure( d=3, target_elm=2, n_e=5, derivative=derivative, filename='fe_%sbasis_p3_5e%s.%s' % (deriv, philab, ext), labels=labels)
def case(nperiods=4, showplot=False, ftype='class'): I = [1, 0] if ftype == 'class': f = ProblemOpt() else: f = problem t0 = time.clock() u, t = RK2(f, I, t=np.linspace(0, nperiods*np.pi, nperiods*30+1)) t1 = time.clock() if showplot: plot(t[-200:], u[-200:,0]) figure() plot(u[-200:,0], u[-200:,1]) return t1-t0
def plot_empirical_freq_and_amplitude(u, t): minima, maxima = minmax(t, u) p = periods(maxima) a = amplitudes(minima, maxima) plt.figure() from math import pi w = 2*pi/p plt.plot(range(len(p)), w, 'r-') plt.hold('on') plt.plot(range(len(a)), a, 'b-') ymax = 1.1*max(w.max(), a.max()) ymin = 0.9*min(w.min(), a.min()) plt.axis([0, max(len(p), len(a)), ymin, ymax]) plt.legend(['estimated frequency', 'estimated amplitude'], loc='upper right') return len(maxima)
def plot_empirical_freq_and_amplitude(u, t): minima, maxima = minmax(t, u) p = periods(maxima) a = amplitudes(minima, maxima) plt.figure() from math import pi w = 2 * pi / p plt.plot(range(len(p)), w, 'r-') plt.hold('on') plt.plot(range(len(a)), a, 'b-') ymax = 1.1 * max(w.max(), a.max()) ymin = 0.9 * min(w.min(), a.min()) plt.axis([0, max(len(p), len(a)), ymin, ymax]) plt.legend(['estimated frequency', 'estimated amplitude'], loc='upper right') return len(maxima)
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 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 main(): import argparse parser = argparse.ArgumentParser() parser.add_argument("--I", type=float, default=1.0) parser.add_argument("--V", type=float, default=0.0) parser.add_argument("--m", type=float, default=1.0) parser.add_argument("--b", type=float, default=0.0) parser.add_argument("--s", type=str, default="u") parser.add_argument("--F", type=str, default="0") parser.add_argument("--dt", type=float, default=0.05) # parser.add_argument('--T', type=float, default=10) parser.add_argument("--T", type=float, default=20) parser.add_argument("--window_width", type=float, default=30.0, help="Number of periods in a window") parser.add_argument("--damping", type=str, default="linear") parser.add_argument("--savefig", action="store_true") # Hack to allow --SCITOOLS options (scitools.std reads this argument # at import) parser.add_argument("--SCITOOLS_easyviz_backend", default="matplotlib") a = parser.parse_args() from scitools.std import StringFunction s = StringFunction(a.s, independent_variable="u") F = StringFunction(a.F, independent_variable="t") I, V, m, b, dt, T, window_width, savefig, damping = ( a.I, a.V, a.m, a.b, a.dt, a.T, a.window_width, a.savefig, a.damping, ) u, t = solver(I, V, m, b, s, F, dt, T, damping) num_periods = plot_empirical_freq_and_amplitude(u, t) if num_periods <= 40: plt.figure() visualize(u, t) else: visualize_front(u, t, window_width, savefig) visualize_front_ascii(u, t) plt.show()
def case(nperiods=4, showplot=False, ftype='class'): I = [1, 0] if ftype == 'class': f = Problem1() elif ftype == 'func2': f = problem2 elif ftype == 'func3': f = problem3 t0 = time.clock() time_points = np.linspace(0, nperiods*2*np.pi, nperiods*30+1) u, t = solver(f, I, time_points, RK2) t1 = time.clock() if showplot: plot(t[-200:], u[-200:,0]) figure() plot(u[-200:,0], u[-200:,1]) return t1-t0, time_points.size
def slides_waves(): L = 10. a = 0.5 B0 = 1. A = B0 / 5 t0 = 3. v = 1. x0 = lambda t: L / 4 + v * t if t < t0 else L / 4 + v * t0 sigma = 1.0 def bottom(x, t): return (B(x, a, L, B0) + S(x, A, x0(t), sigma)) def depth(x, t): return -bottom(x, t) import scitools.std as plt x = np.linspace(0, L, 101) plt.plot(x, bottom(x, 0), x, depth(x, 0), legend=['bottom', 'depth']) plt.show() raw_input() plt.figure() dt_b = 0.01 solver(I=0, V=0, f=lambda x, t: -(depth(x, t - dt_b) - 2 * depth(x, t) + depth( x, t + dt_b)) / dt_b**2, c=lambda x, t: np.sqrt(np.abs(depth(x, t))), U_0=None, U_L=None, L=L, dt=0.1, C=0.9, T=20, user_action=PlotSurfaceAndBottom(B, S, a, L, B0, A, x0, sigma, umin=-2, umax=2), stability_safety_factor=0.9)
def main(): import argparse parser = argparse.ArgumentParser() parser.add_argument('--I', type=float, default=1.0) parser.add_argument('--V', type=float, default=0.0) parser.add_argument('--m', type=float, default=1.0) parser.add_argument('--b', type=float, default=0.0) parser.add_argument('--s', type=str, default='4*pi**2*u') parser.add_argument('--F', type=str, default='0') parser.add_argument('--dt', type=float, default=0.05) parser.add_argument('--T', type=float, default=20) parser.add_argument('--window_width', type=float, default=30., help='Number of periods in a window') parser.add_argument('--damping', type=str, default='linear') parser.add_argument('--savefig', action='store_true') # Hack to allow --SCITOOLS options # (scitools.std reads this argument at import) parser.add_argument('--SCITOOLS_easyviz_backend', default='matplotlib') a = parser.parse_args() from scitools.std import StringFunction s = StringFunction(a.s, independent_variable='u') F = StringFunction(a.F, independent_variable='t') I, V, m, b, dt, T, window_width, savefig, damping = \ a.I, a.V, a.m, a.b, a.dt, a.T, a.window_width, a.savefig, \ a.damping # compute u by both methods and then visualize the difference u, t = solver2(I, V, m, b, s, F, dt, T, damping) u_bw, _ = solver_bwdamping(I, V, m, b, s, F, dt, T, damping) u_diff = u - u_bw num_periods = plot_empirical_freq_and_amplitude(u_diff, t) if num_periods <= 40: plt.figure() legends = [ '1st-2nd order method', '2nd order method', '1st order method' ] visualize([(u_diff, t), (u, t), (u_bw, t)], legends) else: visualize_front(u_diff, t, window_width, savefig) #visualize_front_ascii(u_diff, t) plt.show()
def main(): import argparse parser = argparse.ArgumentParser() parser.add_argument('--I', type=float, default=1.0) parser.add_argument('--V', type=float, default=0.0) parser.add_argument('--m', type=float, default=1.0) parser.add_argument('--b', type=float, default=0.0) parser.add_argument('--s', type=str, default='4*pi**2*u') parser.add_argument('--F', type=str, default='0') parser.add_argument('--dt', type=float, default=0.05) parser.add_argument('--T', type=float, default=20) parser.add_argument('--window_width', type=float, default=30., help='Number of periods in a window') parser.add_argument('--damping', type=str, default='linear') parser.add_argument('--savefig', action='store_true') # Hack to allow --SCITOOLS options # (scitools.std reads this argument at import) parser.add_argument('--SCITOOLS_easyviz_backend', default='matplotlib') a = parser.parse_args() from scitools.std import StringFunction s = StringFunction(a.s, independent_variable='u') F = StringFunction(a.F, independent_variable='t') I, V, m, b, dt, T, window_width, savefig, damping = \ a.I, a.V, a.m, a.b, a.dt, a.T, a.window_width, a.savefig, \ a.damping # compute u by both methods and then visualize the difference u, t = solver2(I, V, m, b, s, F, dt, T, damping) u_bw, _ = solver_bwdamping(I, V, m, b, s, F, dt, T, damping) u_diff = u - u_bw num_periods = plot_empirical_freq_and_amplitude(u_diff, t) if num_periods <= 40: plt.figure() legends = ['1st-2nd order method', '2nd order method', '1st order method'] visualize([(u_diff, t), (u, t), (u_bw, t)], legends) else: visualize_front(u_diff, t, window_width, savefig) #visualize_front_ascii(u_diff, t) plt.show()
def demo(): """ Demonstrate difference between Euler-Cromer and the scheme for the corresponding 2nd-order ODE. """ I = 1.2; w = 2.0; T = 5 dt = 2/w # longest possible time step from vib_undamped import solver as solver2 # 2nd-order ODE from scitools.std import plot, figure, savefig for k in range(4): dt /= 4 u2, t2 = solver2(I, w, dt, T) u, v, t = solver(I, w, dt, T) figure() plot(t, u, t2, u2, legend=('Euler-Cromer', 'center scheme for $u''+u=0$'), title='dt=%.3g' % dt) raw_input() savefig('ECvs2nd_%d' % k + '.png') savefig('ECvs2nd_%d' % k + '.pdf')
def demo(): """ Demonstrate difference between Euler-Cromer and the scheme for the corresponding 2nd-order ODE. """ I = 1.2 w = 2.0 T = 5 dt = 2 / w # longest possible time step from vib_undamped import solver as solver2 # 2nd-order ODE import scitools.std as plt for k in range(4): dt /= 4 u2, t2 = solver2(I, w, dt, T) u, v, t = solver(I, w, dt, T) plt.figure() plt.plot(t, u, t2, u2, legend=("Euler-Cromer", "center scheme for $u" "+u=0$"), title="dt=%.3g" % dt) raw_input() plt.savefig("ECvs2nd_%d" % k + ".png") plt.savefig("ECvs2nd_%d" % k + ".pdf")
def run_Lagrange_interp_abs(N, ymin=None, ymax=None): f = abs(1-2*x) psi, points = Lagrange_polynomials_01(x, N) u = interpolation(f, psi, points) comparison_plot(f, u, Omega=[0, 1], filename='Lagrange_interp_abs_%d.pdf' % (N+1), plot_title='Interpolation by Lagrange polynomials '\ 'of degree %d' % N, ymin=ymin, ymax=ymax) # Make figures of Lagrange polynomials (psi) figure() xcoor = linspace(0, 1, 1001) for i in (2, (N+1)/2+1): fn = lambdify([x], psi[i]) ycoor = fn(xcoor) plot(xcoor, ycoor) legend(r'\psi_%d' % i) hold('on') plot(points, [fn(xc) for xc in points], 'ro') #if ymin is not None and ymax is not None: # axis([xcoor[0], xcoor[-1], ymin, ymax]) savefig('Lagrange_basis_%d.pdf' % (N+1))
def main(): import argparse parser = argparse.ArgumentParser() parser.add_argument('--I', type=float, default=1.0) parser.add_argument('--V', type=float, default=0.0) parser.add_argument('--m', type=float, default=1.0) parser.add_argument('--b', type=float, default=0.0) parser.add_argument('--s', type=str, default='u') parser.add_argument('--F', type=str, default='0') parser.add_argument('--dt', type=float, default=0.05) #parser.add_argument('--T', type=float, default=10) parser.add_argument('--T', type=float, default=20) parser.add_argument('--window_width', type=float, default=30., help='Number of periods in a window') parser.add_argument('--damping', type=str, default='linear') parser.add_argument('--savefig', action='store_true') # Hack to allow --SCITOOLS options (scitools.std reads this argument # at import) parser.add_argument('--SCITOOLS_easyviz_backend', default='matplotlib') a = parser.parse_args() from scitools.std import StringFunction s = StringFunction(a.s, independent_variable='u') F = StringFunction(a.F, independent_variable='t') I, V, m, b, dt, T, window_width, savefig, damping = \ a.I, a.V, a.m, a.b, a.dt, a.T, a.window_width, a.savefig, \ a.damping u, t = solver(I, V, m, b, s, F, dt, T, damping) num_periods = plot_empirical_freq_and_amplitude(u, t) if num_periods <= 40: plt.figure() visualize(u, t) else: visualize_front(u, t, window_width, savefig) visualize_front_ascii(u, t) plt.show()
def amplification_factor(names): # Use SciTools since it adds markers to colored lines from scitools.std import (plot, title, xlabel, ylabel, hold, savefig, axis, legend, grid, show, figure) figure() curves = {} p = linspace(0, 3, 99) curves['exact'] = A_exact(p) plot(p, curves['exact']) hold('on') name2theta = dict(FE=0, BE=1, CN=0.5) for name in names: curves[name] = A(p, name2theta[name]) plot(p, curves[name]) axis([p[0], p[-1], -20, 20]) #semilogy(p, curves[name]) plot([p[0], p[-1]], [0, 0], '--') # A=0 line title('Amplification factors') grid('on') legend(['exact'] + names, loc='lower left', fancybox=True) xlabel(r'$p=-a\cdot dt$') ylabel('Amplification factor') savefig('A_growth.png') savefig('A_growth.pdf')
def amplification_factor(names): # Use SciTools since it adds markers to colored lines from scitools.std import ( plot, title, xlabel, ylabel, hold, savefig, axis, legend, grid, show, figure) figure() curves = {} p = linspace(0, 3, 99) curves['exact'] = A_exact(p) plot(p, curves['exact']) hold('on') name2theta = dict(FE=0, BE=1, CN=0.5) for name in names: curves[name] = A(p, name2theta[name]) plot(p, curves[name]) axis([p[0], p[-1], -20, 20]) #semilogy(p, curves[name]) plot([p[0], p[-1]], [0, 0], '--') # A=0 line title('Amplification factors') grid('on') legend(['exact'] + names, loc='lower left', fancybox=True) xlabel(r'$p=-a\cdot dt$') ylabel('Amplification factor') savefig('A_growth.png'); savefig('A_growth.pdf')
def solve3(self, exact=None, s=0, ax=[], navn="tmp"): if self.dim > 2: return None problem, dt, N = self.problem, self.dt, self.N f_text = problem.f alpha = problem.alpha rho = problem.rho I = problem.I nx, ny = self.nx, self.ny V, mesh = self.make_mesh() u = TrialFunction(V) v = TestFunction(V) I = Expression(I, s=s) # can take one parameter with the name s u_k = interpolate(I, V) a = (u * v + dt / rho * alpha(u_k) * inner(nabla_grad(u), nabla_grad(v))) * dx u = Function(V) if self.dim == 2: mlab.figure(1) self.plot2D(u_k, nx, ny, navn, -1) if self.dim == 1: sci.figure(1) self.plot1D(u_k, nx, ny, exact, mesh, ax) for n in range(N): time.sleep(0.2) t = (n + 1) * dt f = Expression(f_text, rho=rho, t=t, dt=dt) L = (u_k * v + dt * f * v / rho) * dx solve(a == L, u) numVec = self.make_numpy(u, nx, ny) if self.dim == 2: mlab.figure(1) self.plot2D(u, nx, ny, navn, n) if self.dim == 1: sci.figure(1) self.plot1D(u, nx, ny, exact, mesh, ax, t=t, n=n + 1) if exact != None: if ny == 0: sci.figure(2) else: mlab.figure(2) self.plotError(u, exact, nx, ny, mesh, t, navn, n=n) u_k.assign(u) if self.dim == 2: self.makemovie(navn) r = raw_input("Done solving!")
def simulate_n_paths(n, N, x0, p0, M, m): xm = np.zeros(N + 1) # mean of x pm = np.zeros(N + 1) # mean of p xs = np.zeros(N + 1) # standard deviation of x ps = np.zeros(N + 1) # standard deviation of p for i in range(n): x, p = simulate_one_path(N, x0, p0, M, m) # Accumulate paths xm += x pm += p xs += x**2 ps += p**2 # Show 5 random sample paths if i % (n / 5) == 0: figure(1) plot(x, title='sample paths of investment') hold('on') figure(2) plot(p, title='sample paths of interest rate') hold('on') figure(1) savefig('tmp_sample_paths_investment.pdf') figure(2) savefig('tmp_sample_paths_interestrate.pdf') # Compute average xm /= float(n) pm /= float(n) # Compute standard deviation xs = xs / float(n) - xm * xm # variance ps = ps / float(n) - pm * pm # variance # Remove small negative numbers (round off errors) print 'min variance:', xs.min(), ps.min() xs[xs < 0] = 0 ps[ps < 0] = 0 xs = np.sqrt(xs) ps = np.sqrt(ps) return xm, xs, pm, ps
def simulate_n_paths(n, N, x0, p0, M, m): xm = np.zeros(N+1) # mean of x pm = np.zeros(N+1) # mean of p xs = np.zeros(N+1) # standard deviation of x ps = np.zeros(N+1) # standard deviation of p for i in range(n): x, p = simulate_one_path(N, x0, p0, M, m) # Accumulate paths xm += x pm += p xs += x**2 ps += p**2 # Show 5 random sample paths if i % (n/5) == 0: figure(1) plot(x, title='sample paths of investment') hold('on') figure(2) plot(p, title='sample paths of interest rate') hold('on') figure(1); savefig('tmp_sample_paths_investment.eps') figure(2); savefig('tmp_sample_paths_interestrate.eps') # Compute average xm /= float(n) pm /= float(n) # Compute standard deviation xs = xs/float(n) - xm*xm # variance ps = ps/float(n) - pm*pm # variance # Remove small negative numbers (round off errors) print 'min variance:', xs.min(), ps.min() xs[xs < 0] = 0 ps[ps < 0] = 0 xs = np.sqrt(xs) ps = np.sqrt(ps) return xm, xs, pm, ps
def run_solvers_and_plot(solvers, timesteps_per_period=20, num_periods=1, I=1, w=2 * np.pi): P = 2 * np.pi / w # one period dt = P / timesteps_per_period N = num_periods * timesteps_per_period T = N * dt t_mesh = np.linspace(0, T, N + 1) legends = [] for solver in solvers: solver.set(f_kwargs={'w': w}) solver.set_initial_condition([I, 0]) u, t = solver.solve(t_mesh) # Make plots 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.__class__.__name__) plt.figure(2) if len(t_mesh) <= 50: plt.plot(u[:, 0], u[:, 1]) # markers by default else: plt.plot(u[:, 0], u[:, 1], '-2') # no markers plt.hold('on') if num_periods > 20: minima, maxima = minmax(t, u[:, 0]) p = periods(maxima) a = amplitudes(minima, maxima) plt.figure(3) plt.plot(range(len(p)), 2 * np.pi / p, '-') plt.hold('on') plt.figure(4) plt.plot(range(len(a)), a, '-') plt.hold('on') # Compare with exact solution plotted on a very fine mesh t_fine = np.linspace(0, T, 10001) u_e = I * np.cos(w * t_fine) v_e = -w * I * np.sin(w * t_fine) if num_periods < 80: plt.figure(1) plt.plot(t_fine, u_e, '-') # avoid markers by spec. line type legends.append('exact') plt.legend(legends, loc='upper left') plt.xlabel('t') plt.ylabel('u') plt.title('Time step: %g' % dt) plt.savefig('vb_%d_%d_u.png' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_u.pdf' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_u.eps' % (timesteps_per_period, num_periods)) plt.figure(2) plt.plot(u_e, v_e, '-') # avoid markers by spec. line type plt.legend(legends, loc='lower right') plt.xlabel('u(t)') plt.ylabel('v(t)') plt.title('Time step: %g' % dt) plt.savefig('vb_%d_%d_pp.png' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_pp.pdf' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_pp.eps' % (timesteps_per_period, num_periods)) del legends[-1] # fig 3 and 4 does not have exact value if num_periods > 20: plt.figure(3) plt.legend(legends, loc='center right') plt.title('Empirically estimated periods') plt.savefig('vb_%d_%d_p.eps' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_p.png' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_p.eps' % (timesteps_per_period, num_periods)) plt.figure(4) plt.legend(legends, loc='center right') plt.title('Empirically estimated amplitudes') plt.savefig('vb_%d_%d_a.eps' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_a.png' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_a.eps' % (timesteps_per_period, num_periods))
grad = [] h = alpha[1] - alpha[0] for i in range(1, len(alpha)-1): deriv = 1/(2*h)*(-E[i-1] + E[i+1]) grad.append(deriv); return grad aGrad = get_grad_1d(E, alpha) if two: aGrad2 = get_grad_1d(E2, alpha2) figure(1) plot(alpha, E, xlabel="alpha", legend="IS", hold="on") #figure(2) #plot(alpha, E, xlabel="alpha", legend="IS", hold="on") #figure(3) #plot(alpha, E, xlabel="alpha", legend="IS", hold="on") figure(4) plot(alpha[1:-1], aGrad, legend="IS", hold="on") if two: figure(1) plot(alpha2, E2, xlabel="alpha", ylabel="E", title="2p Qdot noInteraction",\ legend="BF", hardcopy=path+"full.eps") #figure(2) #plot(alpha2, E2, xlabel="alpha", ylabel="E", title="2p Qdot noInteraction",\ # legend="BF", axis=[1,1.5, 1,3], hardcopy=path+"closeToOne.eps")
p[mu-1][i+1] = eodsq - u[i+1]*r2d p[mu+1][nps-3], p[mu][nps-2] = eodsq + u[nps-2]*r2d, diag return p u0 = np.zeros(9, float) u0[1], u0[2:5], u0[5] = .5, 1., .5 t0, tn, n_points, ml, mu = 0., .4, 5, 1, 1 time_points = np.linspace(t0, tn, n_points) atol, rtol = 1e-3, 1e-3 exact_final = [1.07001457e-1, 2.77432492e-1, 5.02444616e-1, 7.21037157e-1, 9.01670441e-1, 8.88832048e-1, 4.96572850e-1, 9.46924362e-2, -6.90855199e-3] st.figure() method = Lsodi # Test case 1: Lsodi, with res, adda_full, & jac_full m = method(res=res, rtol=rtol, atol=atol, adda_lsodi=adda_full, jac_lsodi=jac_full) m.set_initial_condition(u0) u,t = m.solve(time_points) st.plot(t, u[:,0], 'r-', title="Lsodi with Python functions", legend="with res, adda_full & jac_full", hold="on") print('Max error with test case 1 is %g' % max(u[-1] - exact_final)) # Test case 2: Lsodi, with res & adda_full m = method(res=res, rtol=rtol, atol=atol, adda_lsodi=adda_full) m.set_initial_condition(u0)
import scitools.std as plt import sys import numpy as np import matplotlib.pyplot as plt x, y = np.loadtxt('volt.txt', delimiter=',', unpack=True) plt.figure(1) plt.plot(x, y, '*', linewidth=1) # avoid markers by spec. line type #plt.xlim([0.0, 10]) #plt.ylim([0.0, 2]) plt.legend(['Force-- Tip'], loc='upper right', prop={"family": "Times New Roman"}) plt.xlabel('Sampled time') plt.ylabel('$Force /m$') plt.savefig('volt1v.png') plt.savefig('volt1v.pdf') plt.hold(True)
def run_solvers_and_plot(solvers, timesteps_per_period=20, num_periods=1, I=1, w=2*np.pi): 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) legends = [] for solver in solvers: solver.set(f_kwargs={'w': w}) solver.set_initial_condition([I, 0]) u, t = solver.solve(t_mesh) # Compute energy dt = t[1] - t[0] E = 0.5*((u[2:,0] - u[:-2,0])/(2*dt))**2 + 0.5*w**2*u[1:-1,0]**2 # Compute error in energy E0 = 0.5*0**2 + 0.5*w**2*I**2 e_E = E - E0 solver_name = 'CrankNicolson' if solver.__class__.__name__ == \ 'MidpointImplicit' else solver.__class__.__name__ print '*** Relative max error in energy for %s [0,%g] with dt=%g: %.3E' % (solver_name, t[-1], dt, np.abs(e_E).max()/E0) # Make plots 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.__class__.__name__) plt.figure(2) if len(t_mesh) <= 50: plt.plot(u[:,0], u[:,1]) # markers by default else: plt.plot(u[:,0], u[:,1], '-2') # no markers plt.hold('on') if num_periods > 20: minima, maxima = minmax(t, u[:,0]) p = periods(maxima) a = amplitudes(minima, maxima) plt.figure(3) plt.plot(range(len(p)), 2*np.pi/p, '-') plt.hold('on') plt.figure(4) plt.plot(range(len(a)), a, '-') plt.hold('on') # Compare with exact solution plotted on a very fine mesh t_fine = np.linspace(0, T, 10001) u_e = I*np.cos(w*t_fine) v_e = -w*I*np.sin(w*t_fine) if num_periods < 80: plt.figure(1) plt.plot(t_fine, u_e, '-') # avoid markers by spec. line type legends.append('exact') 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)) plt.figure(2) plt.plot(u_e, v_e, '-') # avoid markers by spec. line type plt.legend(legends, loc='lower right') plt.xlabel('u(t)'); plt.ylabel('v(t)') plt.title('Time step: %g' % dt) plt.savefig('vib_%d_%d_pp.png' % (timesteps_per_period, num_periods)) plt.savefig('vib_%d_%d_pp.pdf' % (timesteps_per_period, num_periods)) plt.savefig('vib_%d_%d_pp.eps' % (timesteps_per_period, num_periods)) del legends[-1] # fig 3 and 4 does not have exact value if num_periods > 20: plt.figure(3) plt.legend(legends, loc='center right') plt.title('Empirically estimated periods') plt.savefig('vib_%d_%d_p.eps' % (timesteps_per_period, num_periods)) plt.savefig('vib_%d_%d_p.png' % (timesteps_per_period, num_periods)) plt.savefig('vib_%d_%d_p.eps' % (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.eps' % (timesteps_per_period, num_periods)) plt.savefig('vib_%d_%d_a.png' % (timesteps_per_period, num_periods)) plt.savefig('vib_%d_%d_a.eps' % (timesteps_per_period, num_periods))
def simulate( beta=0.9, Theta=30, epsilon=0, num_periods=6, time_steps_per_period=60, plot=True, ): from math import sin, cos, pi Theta = Theta*np.pi/180 #convert to radians #Initial position and velocity #(we order the equations such that Euler-Cromer in odespy #can be used, i.e., vx, x, vy, y) ic = [0, #x'=vx (1 + epsilon)*sin(Theta), #x 0, #y'=vy 1 - (1 + epsilon)*cos(Theta), #y ] def f(u, t, beta): vx, x, vy, y = u L = np.sqrt(x**2 + (y-1)**2) h = beta/(1-beta)*(1- beta/L) #help factor return [-h*x, vx, -h*(y-1) - beta, vy] #Non-elastic pendulum (scaled similarly in the limit beta=1) #Solution Theta*cos(t) P = 2*pi dt = P/time_steps_per_period T = num_periods*P omega = 2*pi/P time_points = np.linspace( 0, T, num_periods*time_steps_per_period+1) solver = odespy.EulerCromer(f, f_args=(beta,)) solver.set_initial_condition(ic) u, t = solver.solve(time_points) x = u[:,1] y = u[:,3] theta = np.arctan(x/(1-y)) if plot: plt.figure() plt.plot(x, y, 'b-', title='Pendulum motion', daspect=[1,1,1], daspectmode='equal', axis=[x.min(), x.max(), 1.3*y.min(), 1]) plt.savefig('tmp_xy.png') plt.savefig('tmp_xy.pdf') #plot theta in degrees plt.figure() plt.plot(t, theta*180/np.pi, 'b-', title='Angular displacement in degrees') plt.savefig('tmp_theta.png') plt.savefig('tmp_theta.pdf') if abs(Theta) < 10*pi/180: #compare theta and theta_e for small angles (< 10 degrees) theta_e = Theta*np.cos(omega*t) #non-elastic scaled sol. plt.figure() plt.plot(t, theta, t, theta_e, legend=['theta elastic', 'theta non-elastic'], title='Elastic vs non-elastic pendulum, '\ 'beta=%g' % beta) plt.savefig('tmp_compare.png') plt.savefig('tmp_compare.pdf') #Plot y vs x (the real physical motion) return x, y, theta, t
""" Exercise 5.25: Investigate the behaviour of Langrange's interpolating polynomials Author: Weiyun Lu """ import Lagrange_poly2 from scitools.std import hold, figure figure() for n in [2,4,6,10]: Lagrange_poly2.graph(abs, n, -2, 2) hold('on') hold('off') figure() for n in [13,20]: Lagrange_poly2.graph(abs, n, -2, 2) hold('on') hold('off')
def run(gamma, beta=10, delta=40, scaling=1, animate=False): """Run the scaled model for welding.""" gamma = float(gamma) # avoid integer division if scaling == 'a': v = gamma a = 1 L = 1.0 b = 0.5 * beta**2 elif scaling == 'b': v = 1 a = 1.0 / gamma L = 1.0 b = 0.5 * beta**2 elif scaling == 'c': v = 1 a = beta / gamma L = beta b = 0.5 elif scaling == 'd': # PDE: u_t = gamma**(-1)u_xx + gamma**(-1)*delta*f v = 1 a = 1.0 / gamma L = 1.0 b = 0.5 * beta**2 delta *= 1.0 / gamma ymin = 0 # Need global ymax to be able change ymax in closure process_u global ymax ymax = 1.2 I = lambda x: 0 f = lambda x, t: delta * np.exp(-b * (x - v * t)**2) import time import scitools.std as plt plot_arrays = [] if scaling == 'c': plot_times = [0.2 * beta, 0.5 * beta] else: plot_times = [0.2, 0.5] def process_u(u, x, t, n): """ Animate u, and store arrays in plot_arrays if t coincides with chosen times for plotting (plot_times). """ global ymax if animate: plt.plot(x, u, 'r-', x, f(x, t[n]) / delta, 'b-', axis=[0, L, ymin, ymax], title='t=%f' % t[n], xlabel='x', ylabel='u and f/%g' % delta) if t[n] == 0: time.sleep(1) plot_arrays.append(x) dt = t[1] - t[0] tol = dt / 10.0 if abs(t[n] - plot_times[0]) < tol or \ abs(t[n] - plot_times[1]) < tol: plot_arrays.append((u.copy(), f(x, t[n]) / delta)) if u.max() > ymax: ymax = u.max() Nx = 100 D = 10 if scaling == 'c': T = 0.5 * beta else: T = 0.5 u_L = u_R = 0 theta = 1.0 cpu = solver(I, a, f, L, Nx, D, T, theta, u_L, u_R, user_action=process_u) x = plot_arrays[0] plt.figure() for u, f in plot_arrays[1:]: plt.plot(x, u, 'r-', x, f, 'b--', axis=[x[0], x[-1], 0, ymax], xlabel='$x$', ylabel=r'$u, \ f/%g$' % delta) plt.hold('on') plt.legend([ '$u,\\ t=%g$' % plot_times[0], '$f/%g,\\ t=%g$' % (delta, plot_times[0]), '$u,\\ t=%g$' % plot_times[1], '$f/%g,\\ t=%g$' % (delta, plot_times[1]) ]) filename = 'tmp1_gamma%g_%s' % (gamma, scaling) plt.title(r'$\beta = %g,\ \gamma = %g,\ $' % (beta, gamma) + 'scaling=%s' % scaling) plt.savefig(filename + '.pdf') plt.savefig(filename + '.png') return cpu
D = 500 dt = dx**2*D dt = 1.25 D = dt/dx**2 T = 2.5 umin = u_R umax = u_L a_consts = [[0, 1]] a_consts = [[0, 1], [0.5, 8]] a_consts = [[0, 1], [0.5, 8], [0.75, 0.1]] a = fill_a(a_consts, L, Nx) #a = random.uniform(0, 10, Nx+1) from scitools.std import plot, hold, subplot, figure, show figure() subplot(2,1,1) u, x, cpu = viz(I, a, L, Nx, D, T, umin, umax, theta, u_L, u_R) v = u_exact_stationary(x, a, u_L, u_R) print 'v', v print 'u', u hold('on') symbol = 'bo' if Nx < 32 else 'b-' plot(x, v, symbol, legend='exact stationary') subplot(2,1,2) plot(x, a, legend='a') show()
def simulate( beta=0.9, # dimensionless parameter Theta=30, # initial angle in degrees epsilon=0, # initial stretch of wire num_periods=6, # simulate for num_periods time_steps_per_period=60, # time step resolution plot=True, # make plots or not ): from math import sin, cos, pi Theta = Theta*np.pi/180 # convert to radians # Initial position and velocity # (we order the equations such that Euler-Cromer in odespy # can be used, i.e., vx, x, vy, y) ic = [0, # x'=vx (1 + epsilon)*sin(Theta), # x 0, # y'=vy 1 - (1 + epsilon)*cos(Theta), # y ] def f(u, t, beta): vx, x, vy, y = u L = np.sqrt(x**2 + (y-1)**2) h = beta/(1-beta)*(1 - beta/L) # help factor return [-h*x, vx, -h*(y-1) - beta, vy] # Non-elastic pendulum (scaled similarly in the limit beta=1) # solution Theta*cos(t) P = 2*pi dt = P/time_steps_per_period T = num_periods*P omega = 2*pi/P time_points = np.linspace( 0, T, num_periods*time_steps_per_period+1) solver = odespy.EulerCromer(f, f_args=(beta,)) solver.set_initial_condition(ic) u, t = solver.solve(time_points) x = u[:,1] y = u[:,3] theta = np.arctan(x/(1-y)) if plot: plt.figure() plt.plot(x, y, 'b-', title='Pendulum motion', daspect=[1,1,1], daspectmode='equal', axis=[x.min(), x.max(), 1.3*y.min(), 1]) plt.savefig('tmp_xy.png') plt.savefig('tmp_xy.pdf') # Plot theta in degrees plt.figure() plt.plot(t, theta*180/np.pi, 'b-', title='Angular displacement in degrees') plt.savefig('tmp_theta.png') plt.savefig('tmp_theta.pdf') if abs(Theta) < 10*pi/180: # Compare theta and theta_e for small angles (<10 degrees) theta_e = Theta*np.cos(omega*t) # non-elastic scaled sol. plt.figure() plt.plot(t, theta, t, theta_e, legend=['theta elastic', 'theta non-elastic'], title='Elastic vs non-elastic pendulum, '\ 'beta=%g' % beta) plt.savefig('tmp_compare.png') plt.savefig('tmp_compare.pdf') # Plot y vs x (the real physical motion) return x, y, theta, t
def run_solvers_and_plot(solvers, timesteps_per_period=20, num_periods=1, I=1, w=2 * np.pi): 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) legends = [] for solver in solvers: solver.set(f_kwargs={'w': w}) solver.set_initial_condition([I, 0]) u, t = solver.solve(t_mesh) # Compute energy dt = t[1] - t[0] E = 0.5 * ((u[2:, 0] - u[:-2, 0]) / (2 * dt))**2 + 0.5 * w**2 * u[1:-1, 0]**2 # Compute error in energy E0 = 0.5 * 0**2 + 0.5 * w**2 * I**2 e_E = E - E0 solver_name = 'CrankNicolson' if solver.__class__.__name__ == \ 'MidpointImplicit' else solver.__class__.__name__ print '*** Relative max error in energy for %s [0,%g] with dt=%g: %.3E' % ( solver_name, t[-1], dt, np.abs(e_E).max() / E0) # Make plots 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) plt.figure(2) if len(t_mesh) <= 50: plt.plot(u[:, 0], u[:, 1]) # markers by default else: plt.plot(u[:, 0], u[:, 1], '-2') # no markers plt.hold('on') if num_periods > 20: minima, maxima = minmax(t, u[:, 0]) p = periods(maxima) a = amplitudes(minima, maxima) plt.figure(3) plt.plot(range(len(p)), 2 * np.pi / p, '-') plt.hold('on') plt.figure(4) plt.plot(range(len(a)), a, '-') plt.hold('on') # Compare with exact solution plotted on a very fine mesh t_fine = np.linspace(0, T, 10001) u_e = I * np.cos(w * t_fine) v_e = -w * I * np.sin(w * t_fine) if num_periods < 80: plt.figure(1) plt.plot(t_fine, u_e, '-') # avoid markers by spec. line type legends.append('exact') 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.figure(2) plt.plot(u_e, v_e, '-') # avoid markers by spec. line type plt.legend(legends, loc='lower right') plt.xlabel('u(t)') plt.ylabel('v(t)') plt.title('Time step: %g' % dt) plt.savefig('vib_%d_%d_pp.png' % (timesteps_per_period, num_periods)) plt.savefig('vib_%d_%d_pp.pdf' % (timesteps_per_period, num_periods)) del legends[-1] # fig 3 and 4 does not have exact value if num_periods > 20: plt.figure(3) plt.legend(legends, loc='center right') plt.title('Empirically estimated periods') plt.savefig('vib_%d_%d_p.pdf' % (timesteps_per_period, num_periods)) 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))
from __future__ import print_function # Stiff ODE: Van der Pol oscillator # u'' = 3*(1 - u**2)*u' - u from odespy import * import scitools.std as st solver_no = 1 # number of solvers in figure st.figure() exceptions=['RKC', 'Lsodes', 'Leapfrog', 'Lsodi', 'Lsodis', 'Lsoibt', 'MyRungeKutta', 'MySolver', 'AdaptiveResidual', 'EulerCromer'] solvers = [solver for solver in list_available_solvers() if solver not in exceptions] f = lambda (u00,u11),t: [u11, 3.*(1 - u00**2)*u11 - u00] jac = lambda (u00,u11),t: \ [[0., 1.], [-6.*u00*u11 - 1., 3.*(1. - u00**2)]] u0, time_points = [2., 0.], np.linspace(0., 10., 100) print("""Van der Pol oscillator problem: u'' = 3*(1 - u**2)*u' - u""") # Loop for all possible solvers for solver in solvers: try: method = eval(solver)(f) method.set_initial_condition(u0) u,t = method.solve(time_points) if solver_no == 8: # More than 8 solvers in current figure? st.figure() # Initialize new figure. solver_no = 1
# Stiff ODE: Van der Pol oscillator # u'' = 3*(1 - u**2)*u' - u from odespy import * import scitools.std as st solver_no = 1 # number of solvers in figure st.figure() exceptions=['RKC', 'Lsodes', 'Leapfrog', 'Lsodi', 'Lsodis', 'Lsoibt', 'MyRungeKutta', 'MySolver', 'AdaptiveResidual', 'EulerCromer'] solvers = [solver for solver in list_available_solvers() if solver not in exceptions] f = lambda (u00,u11),t: [u11, 3.*(1 - u00**2)*u11 - u00] jac = lambda (u00,u11),t: \ [[0., 1.], [-6.*u00*u11 - 1., 3.*(1. - u00**2)]] u0, time_points = [2., 0.], np.linspace(0., 10., 100) print """Van der Pol oscillator problem: u'' = 3*(1 - u**2)*u' - u""" # Loop for all possible solvers for solver in solvers: try: method = eval(solver)(f) method.set_initial_condition(u0) u,t = method.solve(time_points) if solver_no == 8: # More than 8 solvers in current figure? st.figure() # Initialize new figure. solver_no = 1 st.plot(t, u[:,0], hold="on", legend=solver, axis=[0.,10.,-4.,4.])
""" import sys try: n_points = int(sys.argv[1]) # Read from input except: n_points = 10 # default number of time-steps # Compile these Fortran subroutines f_f77, jac_f77 = compile_f77(f_str, jac_full_str) t0, tn, u0 = 0., 10., [2., 0.] time_points = np.linspace(t0, tn, n_points) atol, rtol = 1e-4, 1e-4 st.figure() method = Radau5Explicit # Test case 1: Radau5, with f & jac m = method(None, f_f77=f_f77, rtol=rtol, atol=atol, jac_f77_radau5=jac_f77) m.set_initial_condition(u0) u, t = m.solve(time_points) st.plot(t, u[:, 0], title="Van der Pol oscillator, with Radau5 & Lsoda", legend="Radau5 with f & jac", hold="on") # Test case 2: Radau5, with f m = method(None, f_f77=f_f77, rtol=rtol, atol=atol) m.set_initial_condition(u0)
def viz( I, V, f, c, L, dt, C, T, ymax, # y axis: [-ymax, ymax] u_exact, # u_exact(x, t) animate='u and u_exact', # or 'error' movie_filename='movie', ): """Run solver and visualize u at each time level.""" import scitools.std as plt import time, glob, os class Plot: def __init__(self, ymax, frame_name='frame'): self.max_error = [] # hold max amplitude errors self.max_error_t = [] # time points corresp. to max_error self.frame_name = frame_name self.ymax = ymax def __call__(self, u, x, t, n): """user_action function for solver.""" if animate == 'u and u_exact': plt.plot(x, u, 'r-', x, u_exact(x, t[n]), 'b--', xlabel='x', ylabel='u', axis=[0, L, -self.ymax, self.ymax], title='t=%f' % t[n], show=True) else: error = u_exact(x, t[n]) - u local_max_error = np.abs(error).max() # self.max_error holds the increasing amplitude error if self.max_error == [] or \ local_max_error > max(self.max_error): self.max_error.append(local_max_error) self.max_error_t.append(t[n]) # Use user's ymax until the error exceeds that value. # This gives a growing max value of the yaxis (but # never shrinking) self.ymax = max(self.ymax, max(self.max_error)) plt.plot(x, error, 'r-', xlabel='x', ylabel='error', axis=[0, L, -self.ymax, self.ymax], title='t=%f' % t[n], show=True) plt.savefig('%s_%04d.png' % (self.frame_name, n)) # Clean up old movie frames for filename in glob.glob('frame_*.png'): os.remove(filename) plot = Plot(ymax) u, x, t, cpu = solver(I, V, f, c, L, dt, C, T, plot) # Make plot of max error versus time plt.figure() plt.plot(plot.max_error_t, plot.max_error) plt.xlabel('time') plt.ylabel('max abs(error)') plt.savefig('error.png') plt.savefig('error.pdf') # Make .flv movie file fps = 4 # Frames per second codec2ext = dict(flv='flv') #, libx64='mp4', #libvpx='webm', libtheora='ogg') filespec = 'frame_%04d.png' movie_program = 'avconv' # or 'ffmpeg' for codec in codec2ext: ext = codec2ext[codec] cmd = '%(movie_program)s -r %(fps)d -i %(filespec)s '\ '-vcodec %(codec)s %(movie_filename)s.%(ext)s' % vars() os.system(cmd)
def estimate(truncation_error, T, N_0, m, makeplot=True): """ Compute the truncation error in a problem with one independent variable, using m meshes, and estimate the convergence rate of the truncation error. The user-supplied function truncation_error(dt, N) computes the truncation error on a uniform mesh with N intervals of length dt:: R, t, R_a = truncation_error(dt, N) where R holds the truncation error at points in the array t, and R_a are the corresponding theoretical truncation error values (None if not available). The truncation_error function is run on a series of meshes with 2**i*N_0 intervals, i=0,1,...,m-1. The values of R and R_a are restricted to the coarsest mesh. and based on these data, the convergence rate of R (pointwise) and time-integrated R can be estimated empirically. """ N = [2**i*N_0 for i in range(m)] R_I = np.zeros(m) # time-integrated R values on various meshes R = [None]*m # time series of R restricted to coarsest mesh R_a = [None]*m # time series of R_a restricted to coarsest mesh dt = np.zeros(m) legends_R = []; legends_R_a = [] # all legends of curves for i in range(m): dt[i] = T/float(N[i]) R[i], t, R_a[i] = truncation_error(dt[i], N[i]) R_I[i] = np.sqrt(dt[i]*np.sum(R[i]**2)) if i == 0: t_coarse = t # the coarsest mesh stride = N[i]/N_0 R[i] = R[i][::stride] # restrict to coarsest mesh R_a[i] = R_a[i][::stride] if makeplot: plt.figure(1) plt.plot(t_coarse, R[i], log='y') legends_R.append('N=%d' % N[i]) plt.hold('on') plt.figure(2) plt.plot(t_coarse, R_a[i] - R[i], log='y') plt.hold('on') legends_R_a.append('N=%d' % N[i]) if makeplot: plt.figure(1) plt.xlabel('time') plt.ylabel('pointwise truncation error') plt.legend(legends_R) plt.savefig('R_series.png') plt.savefig('R_series.pdf') plt.figure(2) plt.xlabel('time') plt.ylabel('pointwise error in estimated truncation error') plt.legend(legends_R_a) plt.savefig('R_error.png') plt.savefig('R_error.pdf') # Convergence rates r_R_I = convergence_rates(dt, R_I) print 'R integrated in time; r:', print ' '.join(['%.1f' % r for r in r_R_I]) R = np.array(R) # two-dim. numpy array r_R = [convergence_rates(dt, R[:,n])[-1] for n in range(len(t_coarse))] # Plot convergence rates if makeplot: plt.figure() plt.plot(t_coarse, r_R) plt.xlabel('time') plt.ylabel('r') plt.axis([t_coarse[0], t_coarse[-1], 0, 2.5]) plt.title('Pointwise rate $r$ in truncation error $\sim\Delta t^r$') plt.savefig('R_rate_series.png') plt.savefig('R_rate_series.pdf')
from scitools.std import plot, figure, hold, savefig random.seed(1) x0 = 1 # initial investment p0 = 5 # initial interest rate N = 10*12 # number of months M = 3 # p changes (on average) every M months n = 1000 # number of simulations m = 0.5 # adjustment of p # Verify x, p = simulate_one_path(3, 1, 10, M, 0) print '3 months with p=10:', x xm, xs, pm, ps = simulate_n_paths(n, N, x0, p0, M, m) figure(3) months = range(len(xm)) # indices along the x axis plot(months, xm, 'r', months, xm-xs, 'y', months, xm+xs, 'y', title='Mean +/- 1 st.dev. of investment', savefig='tmp_mean_investment.eps') figure(4) plot(months, pm, 'r', months, pm-ps, 'y', months, pm+ps, 'y', title='Mean +/- 1 st.dev. of annual interest rate', savefig='tmp_mean_interestrate.eps')
def run(gamma, beta=10, delta=40, scaling=1, animate=False): """Run the scaled model for welding.""" if scaling == 1: v = gamma a = 1 elif scaling == 2: v = 1 a = 1.0 / gamma b = 0.5 * beta**2 L = 1.0 ymin = 0 # Need gloal to be able change ymax in closure process_u global ymax ymax = 1.2 I = lambda x: 0 f = lambda x, t: delta * np.exp(-b * (x - v * t)**2) import time import scitools.std as plt plot_arrays = [] def process_u(u, x, t, n): global ymax if animate: plt.plot(x, u, 'r-', x, f(x, t[n]) / delta, 'b-', axis=[0, L, ymin, ymax], title='t=%f' % t[n], xlabel='x', ylabel='u and f/%g' % delta) if t[n] == 0: time.sleep(1) plot_arrays.append(x) dt = t[1] - t[0] tol = dt / 10.0 if abs(t[n] - 0.2) < tol or abs(t[n] - 0.5) < tol: plot_arrays.append((u.copy(), f(x, t[n]) / delta)) if u.max() > ymax: ymax = u.max() Nx = 100 D = 10 T = 0.5 u_L = u_R = 0 theta = 1.0 cpu = solver(I, a, f, L, Nx, D, T, theta, u_L, u_R, user_action=process_u) x = plot_arrays[0] plt.figure() for u, f in plot_arrays[1:]: plt.plot(x, u, 'r-', x, f, 'b--', axis=[x[0], x[-1], 0, ymax], xlabel='$x$', ylabel=r'$u, \ f/%g$' % delta) plt.hold('on') plt.legend([ '$u,\\ t=0.2$', '$f/%g,\\ t=0.2$' % delta, '$u,\\ t=0.5$', '$f/%g,\\ t=0.5$' % delta ]) filename = 'tmp1_gamma%g_s%d' % (gamma, scaling) s = 'diffusion' if scaling == 1 else 'source' plt.title(r'$\beta = %g,\ \gamma = %g,\ $' % (beta, gamma) + 'scaling=%s' % s) plt.savefig(filename + '.pdf') plt.savefig(filename + '.png') return cpu
def run_solvers_and_plot(solvers, timesteps_per_period=20, num_periods=1, I=1, w=2*np.pi): P = 2*np.pi/w # one period dt = P/timesteps_per_period N = num_periods*timesteps_per_period T = N*dt t_mesh = np.linspace(0, T, N+1) legends = [] for solver in solvers: solver.set(f_kwargs={'w': w}) solver.set_initial_condition([I, 0]) u, t = solver.solve(t_mesh) # Make plots 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.__class__.__name__) plt.figure(2) if len(t_mesh) <= 50: plt.plot(u[:,0], u[:,1]) # markers by default else: plt.plot(u[:,0], u[:,1], '-2') # no markers plt.hold('on') if num_periods > 20: minima, maxima = minmax(t, u[:,0]) p = periods(maxima) a = amplitudes(minima, maxima) plt.figure(3) plt.plot(range(len(p)), 2*np.pi/p, '-') plt.hold('on') plt.figure(4) plt.plot(range(len(a)), a, '-') plt.hold('on') # Compare with exact solution plotted on a very fine mesh t_fine = np.linspace(0, T, 10001) u_e = I*np.cos(w*t_fine) v_e = -w*I*np.sin(w*t_fine) if num_periods < 80: plt.figure(1) plt.plot(t_fine, u_e, '-') # avoid markers by spec. line type legends.append('exact') plt.legend(legends, loc='upper left') plt.xlabel('t'); plt.ylabel('u') plt.title('Time step: %g' % dt) plt.savefig('vb_%d_%d_u.png' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_u.pdf' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_u.eps' % (timesteps_per_period, num_periods)) plt.figure(2) plt.plot(u_e, v_e, '-') # avoid markers by spec. line type plt.legend(legends, loc='lower right') plt.xlabel('u(t)'); plt.ylabel('v(t)') plt.title('Time step: %g' % dt) plt.savefig('vb_%d_%d_pp.png' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_pp.pdf' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_pp.eps' % (timesteps_per_period, num_periods)) del legends[-1] # fig 3 and 4 does not have exact value if num_periods > 20: plt.figure(3) plt.legend(legends, loc='center right') plt.title('Empirically estimated periods') plt.savefig('vb_%d_%d_p.eps' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_p.png' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_p.eps' % (timesteps_per_period, num_periods)) plt.figure(4) plt.legend(legends, loc='center right') plt.title('Empirically estimated amplitudes') plt.savefig('vb_%d_%d_a.eps' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_a.png' % (timesteps_per_period, num_periods)) plt.savefig('vb_%d_%d_a.eps' % (timesteps_per_period, num_periods))