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 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_empirical_freq_and_amplitude(u, t, I, w): minima, maxima = minmax(t, u) p = periods(maxima) a = amplitudes(minima, maxima) figure() plot(range(len(p)), 2*pi/p, 'r-') hold('on') plot(range(len(a)), a, 'b-') plot(range(len(p)), [w]*len(p), 'r--') plot(range(len(a)), [I]*len(a), 'b--') legend(['numerical frequency', 'numerical amplitude', 'analytical frequency', 'anaytical amplitude'], loc='center right')
def plot_empirical_freq_and_amplitude(u, t, I, w): """ Find the empirical angular frequency and amplitude of simulations in u and t. u and t can be arrays or (in the case of multiple simulations) multiple arrays. One plot is made for the amplitude and one for the angular frequency (just called frequency in the legends). """ from vib_empirical_analysis import minmax, periods, amplitudes from math import pi if not isinstance(u, (list, tuple)): u = [u] t = [t] legends1 = [] legends2 = [] for i in range(len(u)): minima, maxima = minmax(t[i], u[i]) p = periods(maxima) a = amplitudes(minima, maxima) plt.figure(1) plt.plot(range(len(p)), 2 * pi / p) legends1.append("frequency, case%d" % (i + 1)) plt.hold("on") plt.figure(2) plt.plot(range(len(a)), a) plt.hold("on") legends2.append("amplitude, case%d" % (i + 1)) plt.figure(1) plt.plot(range(len(p)), [w] * len(p), "k--") legends1.append("exact frequency") plt.legend(legends1, loc="lower left") plt.axis([0, len(a) - 1, 0.8 * w, 1.2 * w]) plt.savefig("tmp1.png") plt.savefig("tmp1.pdf") plt.figure(2) plt.plot(range(len(a)), [I] * len(a), "k--") legends2.append("exact amplitude") plt.legend(legends2, loc="lower left") plt.axis([0, len(a) - 1, 0.8 * I, 1.2 * I]) plt.savefig("tmp2.png") plt.savefig("tmp2.pdf") plt.show()
def plot_empirical_freq_and_amplitude(u, t, I, w): """ Find the empirical angular frequency and amplitude of simulations in u and t. u and t can be arrays or (in the case of multiple simulations) multiple arrays. One plot is made for the amplitude and one for the angular frequency (just called frequency in the legends). """ from vib_empirical_analysis import minmax, periods, amplitudes from math import pi if not isinstance(u, (list, tuple)): u = [u] t = [t] legends1 = [] legends2 = [] for i in range(len(u)): minima, maxima = minmax(t[i], u[i]) p = periods(maxima) a = amplitudes(minima, maxima) plt.figure(1) plt.plot(range(len(p)), 2 * pi / p) legends1.append('frequency, case%d' % (i + 1)) plt.hold('on') plt.figure(2) plt.plot(range(len(a)), a) plt.hold('on') legends2.append('amplitude, case%d' % (i + 1)) plt.figure(1) plt.plot(range(len(p)), [w] * len(p), 'k--') legends1.append('exact frequency') plt.legend(legends1, loc='lower left') plt.axis([0, len(a) - 1, 0.8 * w, 1.2 * w]) plt.savefig('tmp1.png') plt.savefig('tmp1.pdf') plt.figure(2) plt.plot(range(len(a)), [I] * len(a), 'k--') legends2.append('exact amplitude') plt.legend(legends2, loc='lower left') plt.axis([0, len(a) - 1, 0.8 * I, 1.2 * I]) plt.savefig('tmp2.png') plt.savefig('tmp2.pdf') plt.show()
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 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))