def comparison_plot(f, u, Omega, filename='tmp.pdf', plot_title='', ymin=None, ymax=None, u_legend='approximation'): """Compare f(x) and u(x) for x in Omega in a plot.""" x = sm.Symbol('x') print 'f:', f f = sm.lambdify([x], f, modules="numpy") u = sm.lambdify([x], u, modules="numpy") if len(Omega) != 2: raise ValueError('Omega=%s must be an interval (2-list)' % str(Omega)) # 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 if not isinstance(Omega[0], (int,float)): Omega[0] = float(Omega[0].evalf()) if not isinstance(Omega[1], (int,float)): Omega[1] = float(Omega[1].evalf()) resolution = 401 # no of points in plot xcoor = linspace(Omega[0], Omega[1], resolution) # Vectorized functions expressions does not work with # lambdify'ed functions without the modules="numpy" exact = f(xcoor) approx = u(xcoor) plot(xcoor, approx, '-') hold('on') plot(xcoor, exact, '-') legend([u_legend, 'exact']) title(plot_title) xlabel('x') if ymin is not None and ymax is not None: axis([xcoor[0], xcoor[-1], ymin, ymax]) savefig(filename)
def run_solvers_and_check_amplitudes(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) file_name = 'Amplitudes' # initialize filename for plot for solver in solvers: solver.set(f_kwargs={'w': w}) solver.set_initial_condition([0, I]) u, t = solver.solve(t_mesh) solver_name = \ 'CrankNicolson' if solver.__class__.__name__ == \ 'MidpointImplicit' else solver.__class__.__name__ file_name = file_name + '_' + solver_name minima, maxima = minmax(t, u[:,0]) a = amplitudes(minima, maxima) plt.plot(range(len(a)), a, '-', label=solver_name) plt.hold('on') plt.xlabel('Number of periods') plt.ylabel('Amplitude (absolute value)') plt.legend(loc='upper left') plt.savefig(file_name + '.png') plt.savefig(file_name + '.pdf') plt.show()
def plot(self, include_exact=True, plt=None): """ Add solver.u curve to the plotting object plt, and include the exact solution if include_exact is True. This plot function can be called several times (if the solver object has computed new solutions). """ if plt is None: import scitools.std as plt # can use matplotlib as well plt.plot(self.solver.t, self.solver.u, '--o') plt.hold('on') theta2name = {0: 'FE', 1: 'BE', 0.5: 'CN'} name = theta2name.get(self.solver.theta, '') legends = ['numerical %s' % name] if include_exact: t_e = linspace(0, self.problem.T, 1001) u_e = self.problem.exact_solution(t_e) plt.plot(t_e, u_e, 'b-') legends.append('exact') plt.legend(legends) plt.xlabel('t') plt.ylabel('u') plt.title('theta=%g, dt=%g' % (self.solver.theta, self.solver.dt)) plt.savefig('%s_%g.png' % (name, self.solver.dt)) return plt
def comparison_plot(u, Omega, u_e=None, filename='tmp.eps', plot_title='', ymin=None, ymax=None): x = sp.Symbol('x') u = sp.lambdify([x], u, modules="numpy") if len(Omega) != 2: raise ValueError('Omega=%s must be an interval (2-list)' % str(Omega)) # 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 if not isinstance(Omega[0], (int,float)): Omega[0] = float(Omega[0].evalf()) if not isinstance(Omega[1], (int,float)): Omega[1] = float(Omega[1].evalf()) resolution = 401 # no of points in plot xcoor = linspace(Omega[0], Omega[1], resolution) # Vectorized functions expressions does not work with # lambdify'ed functions without the modules="numpy" approx = u(xcoor) plot(xcoor, approx) legends = ['approximation'] if u_e is not None: exact = u_e(xcoor) hold('on') plot(xcoor, exact) legends = ['exact'] legend(legends) title(plot_title) xlabel('x') if ymin is not None and ymax is not None: axis([xcoor[0], xcoor[-1], ymin, ymax]) savefig(filename)
def non_physical_behavior(I, a, T, dt, theta): """ Given lists/arrays a and dt, and numbers I, dt, and theta, make a two-dimensional contour line B=0.5, where B=1>0.5 means oscillatory (unstable) solution, and B=0<0.5 means monotone solution of u'=-au. """ a = np.asarray(a); dt = np.asarray(dt) # must be arrays B = np.zeros((len(a), len(dt))) # results for i in range(len(a)): for j in range(len(dt)): u, t = solver(I, a[i], T, dt[j], theta) # Does u have the right monotone decay properties? correct_qualitative_behavior = True for n in range(1, len(u)): if u[n] > u[n-1]: # Not decaying? correct_qualitative_behavior = False break # Jump out of loop B[i,j] = float(correct_qualitative_behavior) a_, dt_ = st.ndgrid(a, dt) # make mesh of a and dt values st.contour(a_, dt_, B, 1) st.grid('on') st.title('theta=%g' % theta) st.xlabel('a'); st.ylabel('dt') st.savefig('osc_region_theta_%s.png' % theta) st.savefig('osc_region_theta_%s.pdf' % theta)
def run_solvers_and_plot(solvers, rhs, T, dt, title=''): 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 = [] solver_exact = odespy.RK4(rhs) 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.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('exact (RK4, dt=%g)' % (t_fine[1] - t_fine[0])) plt.legend(legends, loc='upper right') plt.xlabel('t') plt.ylabel('u') plt.title(title) plotfilestem = '_'.join(legends) plt.savefig('tmp_%s.png' % plotfilestem) plt.savefig('tmp_%s.pdf' % plotfilestem)
def run_solvers_and_check_amplitudes(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) file_name = 'Amplitudes' # initialize filename for plot for solver in solvers: solver.set(f_kwargs={'w': w}) solver.set_initial_condition([0, I]) u, t = solver.solve(t_mesh) solver_name = \ 'CrankNicolson' if solver.__class__.__name__ == \ 'MidpointImplicit' else solver.__class__.__name__ file_name = file_name + '_' + solver_name minima, maxima = minmax(t, u[:, 0]) a = amplitudes(minima, maxima) plt.plot(range(len(a)), a, '-', label=solver_name) plt.hold('on') plt.xlabel('Number of periods') plt.ylabel('Amplitude (absolute value)') plt.legend(loc='upper left') plt.savefig(file_name + '.png') plt.savefig(file_name + '.pdf') plt.show()
def non_physical_behavior(I, a, T, dt, theta): """ Given lists/arrays a and dt, and numbers I, dt, and theta, make a two-dimensional contour line B=0.5, where B=1>0.5 means oscillatory (unstable) solution, and B=0<0.5 means monotone solution of u'=-au. """ a = np.asarray(a) dt = np.asarray(dt) # must be arrays B = np.zeros((len(a), len(dt))) # results for i in range(len(a)): for j in range(len(dt)): u, t = solver(I, a[i], T, dt[j], theta) # Does u have the right monotone decay properties? correct_qualitative_behavior = True for n in range(1, len(u)): if u[n] > u[n - 1]: # Not decaying? correct_qualitative_behavior = False break # Jump out of loop B[i, j] = float(correct_qualitative_behavior) a_, dt_ = st.ndgrid(a, dt) # make mesh of a and dt values st.contour(a_, dt_, B, 1) st.grid('on') st.title('theta=%g' % theta) st.xlabel('a') st.ylabel('dt') st.savefig('osc_region_theta_%s.png' % theta) st.savefig('osc_region_theta_%s.eps' % theta)
def run_solvers_and_plot(solvers, rhs, T, dt, title=''): 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 = [] solver_exact = odespy.RK4(rhs) 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.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('exact (RK4, dt=%g)' % (t_fine[1]-t_fine[0])) plt.legend(legends, loc='upper right') plt.xlabel('t'); plt.ylabel('u') plt.title(title) plotfilestem = '_'.join(legends) plt.savefig('tmp_%s.png' % plotfilestem) plt.savefig('tmp_%s.pdf' % plotfilestem)
def plot(self, include_exact=True, plt=None): """ Add solver.u curve to scitools plotting object plt, and include the exact solution if include_exact is True. This plot function can be called several times (if the solver object has computed new solutions). """ if plt is None: import scitools.std as plt plt.plot(self.solver.t, self.solver.u, '--o') plt.hold('on') theta = self.solver.get('theta') theta2name = {0: 'FE', 1: 'BE', 0.5: 'CN'} name = theta2name.get(theta, '') legends = ['numerical %s' % name] if include_exact: t_e = np.linspace(0, self.problem.get('T'), 1001) u_e = self.problem.exact_solution(t_e) plt.plot(t_e, u_e, 'b-') legends.append('exact') plt.legend(legends) plt.xlabel('t') plt.ylabel('u') dt = self.solver.get('dt') plt.title('theta=%g, dt=%g' % (theta, dt)) plt.savefig('%s_%g.png' % (name, dt)) return plt
def visualize(u, t, title='', filename='tmp'): plt.plot(t, u, 'b-') plt.xlabel('t') plt.ylabel('u') dt = t[1] - t[0] plt.title('dt=%g' % dt) umin = 1.2*u.min(); umax = 1.2*u.max() plt.axis([t[0], t[-1], umin, umax]) plt.title(title) plt.savefig(filename + '.png') plt.savefig(filename + '.pdf') plt.show()
def plot(self, plt = None): if plt is None: import scitools.std as plt plt.plot(self.solver.t, self.solver.v, 'b--o') plt.hold("on") plt.xlabel("t") plt.ylabel("v") plt.savefig("%g.png" % (self.solver.dt)) return plt
def visualize(list_of_curves, legends, title='', filename='tmp'): """Plot list of curves: (u, t).""" for u, t in list_of_curves: plt.plot(t, u) plt.hold('on') plt.legend(legends) plt.xlabel('t') plt.ylabel('u') plt.title(title) plt.savefig(filename + '.png') plt.savefig(filename + '.pdf') plt.show()
def plot(self, plt=None): if plt is None: import scitools.std as plt plt.plot(self.solver.t, self.solver.v, 'b--o') plt.hold("on") plt.xlabel("t") plt.ylabel("v") plt.savefig("%g.png" % (self.solver.dt)) return plt
def visualize(u, t, title="", filename="tmp"): plt.plot(t, u, "b-") plt.xlabel("t") plt.ylabel("u") dt = t[1] - t[0] plt.title("dt=%g" % dt) umin = 1.2 * u.min() umax = 1.2 * u.max() plt.axis([t[0], t[-1], umin, umax]) plt.title(title) plt.savefig(filename + ".png") plt.savefig(filename + ".pdf") plt.show()
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 run_solver_and_plot(solver, 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) solver.set(f_kwargs={'w': w}) solver.set_initial_condition([0, I]) u, t = solver.solve(t_mesh) from vib_undamped import solver u2, t2 = solver(I, w, dt, T) plt.plot(t, u[:,1], 'r-', t2, u2, 'b-') plt.legend(['Euler-Cromer', '2nd-order ODE']) plt.xlabel('t'); plt.ylabel('u') plt.savefig('tmp1.png'); plt.savefig('tmp1.pdf')
def logistic(): problem = Logistic(0.2, 1, 0.1) T = 40 dt = 0.1 method = ForwardEuler(problem, dt) method.set_initial_condition(problem.u0, 0) u, t = method.solve(T) # note that import * is not legal inside functions so we # have to import each specific function: from scitools.std import plot, hardcopy, xlabel, ylabel, title plot(t, u) xlabel('t'); ylabel('u') title('Logistic growth: alpha=0.2, dt=%g, %d steps' \ % (dt, len(u)-1)) # compare with exponential growth: #from scitools.std import hold, linspace, exp #te = linspace(0, dt*N, N+1) #ue = 0.1*exp(0.2*te) #hold('on') #plot(te, ue) hardcopy('tmp.eps')
def logistic(): problem = Logistic(alpha=0.2, R=1, U0=0.1) T = 40 solver = ForwardEuler(problem) solver.set_initial_condition(problem.U0) t = np.linspace(0, T, 401) # 400 intervals in [0,T] u, t = solver.solve(t) # Note that import * is not legal inside functions so we # have to import each specific function. from scitools.std import plot, hardcopy, xlabel, ylabel, title plot(t, u) xlabel('t'); ylabel('u') title('Logistic growth: alpha=%s, R=%g, dt=%g' \ % (problem.alpha, problem.R, t[1]-t[0])) # Compare with exponential growth #from scitools.std import hold, linspace, exp #te = linspace(0, dt*N, N+1) #ue = 0.1*exp(0.2*te) #hold('on') #plot(te, ue) hardcopy('tmp.eps')
def logistic(): problem = Logistic(alpha=0.2, R=1, U0=0.1) T = 40 method = ForwardEuler(problem) method.set_initial_condition(problem.U0) t = np.linspace(0, T, 401) # 400 intervals in [0,T] u, t = method.solve(t) # Note that import * is not legal inside functions so we # have to import each specific function. from scitools.std import plot, hardcopy, xlabel, ylabel, title plot(t, u) xlabel('t'); ylabel('u') title('Logistic growth: alpha=%s, R=%g, dt=%g' \ % (problem.alpha, problem.R, t[1]-t[0])) # Compare with exponential growth #from scitools.std import hold, linspace, exp #te = linspace(0, dt*N, N+1) #ue = 0.1*exp(0.2*te) #hold('on') #plot(te, ue) hardcopy('tmp.eps')
def run_solver_and_plot(solver, 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) solver.set(f_kwargs={'w': w}) solver.set_initial_condition([0, I]) u, t = solver.solve(t_mesh) from vib_undamped import solver u2, t2 = solver(I, w, dt, T) plt.plot(t, u[:, 1], 'r-', t2, u2, 'b-') plt.legend(['Euler-Cromer', '2nd-order ODE']) plt.xlabel('t') plt.ylabel('u') plt.savefig('tmp1.png') plt.savefig('tmp1.pdf')
def viz(I, V, f, c, L, Nx, 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 corresponding 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, Nx, 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')
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))
# -*- coding: utf-8 -*- """ Created on Mon Oct 19 21:13:30 2015 @author: antalcides """ from ForwardEuleruni import * from LogisticUni import * problem = Logistic(0.2, 1, 0.1) T = 40 dt = 0.1 method = ForwardEuler(problem, dt) method.set_initial_condition(problem.u0, 0) u, t = method.solve(T) from scitools.std import plot, hardcopy, xlabel, ylabel, title plot(t, u) xlabel('t') ylabel('u') title('Logistic growth: alpha=0.2, dt=%g, %d steps' \ % (dt, len(u)-1))
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))
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 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))
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 if __name__ == "__main__": alpha_values = [0, 0.05, 0.1] for alpha in alpha_values: u, t = simulate(alpha, 0, 6, 60) plt.plot(t, u) plt.hold("on") plt.legend([r"$\alpha=%g$" % alpha for alpha in alpha_values]) plt.xlabel(r"$\bar t$") plt.ylabel(r"$\bar u$") plt.savefig("tmp.png") plt.savefig("tmp.pdf") plt.show() raw_input() # for scitools' matplotlib engine
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)
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 if __name__ == '__main__': alpha_values = [0, 0.05, 0.1] for alpha in alpha_values: u, t = simulate(alpha, 0, 6, 60) plt.plot(t, u) plt.hold('on') plt.legend([r'$\alpha=%g$' % alpha for alpha in alpha_values]) plt.xlabel(r'$\bar t$') plt.ylabel(r'$\bar u$') plt.savefig('tmp.png') plt.savefig('tmp.pdf') plt.show() raw_input() # for scitools' matplotlib engine
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))