Buckets:
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| def solver_memsave(I, a, T, dt, theta, filename='sol.dat'): | |
| """ | |
| Solve u'=-a*u, u(0)=I, for t in (0,T] with steps of dt. | |
| Minimum use of memory. The solution is stored in a file | |
| (with name filename) for later plotting. | |
| """ | |
| dt = float(dt) # avoid integer division | |
| Nt = int(round(T/dt)) # no of intervals | |
| outfile = open(filename, 'w') | |
| # u: time level n+1, u_1: time level n | |
| t = 0 | |
| u_1 = I | |
| outfile.write('%.16E %.16E\n' % (t, u_1)) | |
| for n in range(1, Nt+1): | |
| u = (1 - (1-theta)*a*dt)/(1 + theta*dt*a)*u_1 | |
| u_1 = u | |
| t += dt | |
| outfile.write('%.16E %.16E\n' % (t, u)) | |
| outfile.close() | |
| return u, t | |
| def read_file(filename='sol.dat'): | |
| infile = open(filename, 'r') | |
| u = []; t = [] | |
| for line in infile: | |
| words = line.split() | |
| if len(words) != 2: | |
| print 'Found more than two numbers on a line!', words | |
| sys.exit(1) # abort | |
| t.append(float(words[0])) | |
| u.append(float(words[1])) | |
| return np.array(t), np.array(u) | |
| def read_file_numpy(filename='sol.dat'): | |
| data = np.loadtxt(filename) | |
| t = data[:,0] | |
| u = data[:,1] | |
| return t, u | |
| def exact_solution(t, I, a): | |
| return I*np.exp(-a*t) | |
| def explore(I, a, T, dt, theta=0.5, makeplot=True): | |
| """ | |
| Run a case with the solver_memsave, load t and u data | |
| from file into arrays, compute error measure, | |
| and plot the numerical and exact solutions (if makeplot=True). | |
| """ | |
| filename = 'u.dat' | |
| u, t = solver_memsave(I, a, T, dt, theta, filename) | |
| t, u = read_file(filename) | |
| u_e = exact_solution(t, I, a) | |
| e = u_e - u | |
| E = np.sqrt(dt*np.sum(e**2)) | |
| if makeplot: | |
| plt.figure() # create new plot | |
| t_e = np.linspace(0, T, 1001) # very fine mesh for u_e | |
| u_e = exact_solution(t_e, I, a) | |
| plt.plot(t, u, 'r--o') # red dashes w/circles | |
| plt.plot(t_e, u_e, 'b-') # blue line for u_e | |
| plt.legend(['numerical', 'exact']) | |
| plt.xlabel('t') | |
| plt.ylabel('u') | |
| plt.title('Method: theta-rule, theta=%g, dt=%g' % | |
| (theta, dt)) | |
| theta2name = {0: 'FE', 1: 'BE', 0.5: 'CN'} | |
| plt.savefig('%s_%g.png' % (theta2name[theta], dt)) | |
| plt.show() | |
| return E | |
| def verify(): | |
| def exact_discrete_solution(n, I, a, theta, dt): | |
| A = (1 - (1-theta)*a*dt)/(1 + theta*dt*a) | |
| return I*A**n | |
| theta = 0.8; a = 2; I = 0.1; dt = 0.8 | |
| Nt = int(8/dt) # no of steps | |
| filename = 'sol.dat' | |
| u, t = solver_minmem(I=I, a=a, T=Nt*dt, dt=dt, theta=theta, | |
| filename=filename) | |
| # Test both methods of reading the file | |
| t, u = read_file(filename) | |
| t_, u_ = read_file_numpy(filename) | |
| file_reading = (t == t_).all() and (u == u_).all() | |
| # Compare numerical values | |
| u_de = np.array([exact_discrete_solution(n, I, a, theta, dt) | |
| for n in range(Nt+1)]) | |
| difference = abs(u_de - u).max() | |
| tol = 1E-15 # tolerance for comparing floats | |
| success = difference <= tol | |
| return success and file_reading | |
| def define_command_line_options(): | |
| import argparse | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument('--I', '--initial_condition', type=float, | |
| default=1.0, help='initial condition, u(0)', | |
| metavar='I') | |
| parser.add_argument('--a', type=float, | |
| default=1.0, help='coefficient in ODE', | |
| metavar='a') | |
| parser.add_argument('--T', '--stop_time', type=float, | |
| default=1.0, help='end time of simulation', | |
| metavar='T') | |
| parser.add_argument('--makeplot', action='store_true', | |
| help='display plot or not') | |
| parser.add_argument('--theta', type=float, | |
| default=0.5, help='parameter in scheme', | |
| metavar='theta') | |
| parser.add_argument('--dt', '--time_step', type=float, | |
| default=1.0, help='length of time step', | |
| metavar='dt') | |
| return parser | |
| def read_command_line(): | |
| parser = define_command_line_options() | |
| args = parser.parse_args() | |
| print 'I={}, a={}, T={}, makeplot={}, theta={}, dt={}'.format( | |
| args.I, args.a, args.T, args.makeplot, args.theta, args.dt) | |
| return args.I, args.a, args.T, args.makeplot, \ | |
| args.theta, args.dt | |
| def main(): | |
| I, a, T, makeplot, theta, dt = read_command_line() | |
| E = explore(I, a, T, dt, theta, makeplot) | |
| print 'theta=%.1f dt=%g Error=%.3E' % (theta, dt, E) | |
| if __name__ == '__main__': | |
| if verify(): | |
| main() | |
| else: | |
| print 'Bug in the implementation!' | |
Xet Storage Details
- Size:
- 4.8 kB
- Xet hash:
- 40aaeb76cc9d59c8aab21dfe0bdb9e2a29569e4203db1c4475d7803b5ebe80dd
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.