def angle(): x,z, N = trajectory() num = int(N/20) D, _ = cheb(N) yp = D.dot(z) r_ = r(x) theta1 = np.arctan(yp) # This is incorrect theta2 = (1-r_**2.)**(-1)*(-r_*yp + np.sqrt( (r_*yp)**2. + (1-r_**2)*(1. + yp**2.))) theta2 = np.arccos(1./theta2) # plt.plot(x,theta1,'-g',linewidth=2.) plt.plot(x,theta2,'-b',linewidth=2.) plt.xlabel('$x$',fontsize=18) plt.ylabel(r'$\theta$',fontsize=18) plt.yticks([0, np.pi/6, np.pi/3.,np.pi/2.], ['$0$', r'$\frac{\pi}{6}$', r'$\frac{\pi}{3}$', r'$\frac{\pi}{2}$']) # plt.savefig('trajectory_angle.pdf') plt.show() plt.clf() theta = theta1 # Checking that the angle is correct. print 0., np.min(theta), np.max(theta), np.pi/2. xdist, ydist = np.cos(theta), np.sin(theta) plt.quiver( x[::num], z[::num], xdist[::num], ydist[::num], pivot='tail', color='b', scale_units='xy',scale=3., angles='xy') # plt.plot(x,z,'-k',linewidth=2.) plt.axis([-1.1,1.1,0. -.5,z1 +1.]) plt.show()
def tridiagonal_approach(): epsilon, alpha, beta = .02, 2., 4. # N = number of subintervals or finite elements def AnalyticSolution(x,alpha, beta,epsilon): out = alpha+x+(beta-alpha-1.)*(np.exp(x/epsilon) -1.)/(np.exp(1./epsilon) -1.) return out def matrix_diagonals(N): x = np.linspace(0,1,N+1)**(1.) # N+1 = number of grid points h = np.diff(x) b, f = np.zeros(N+1), np.zeros(N+1) a, c= np.zeros(N), np.zeros(N) b[0], b[N] = 1., 1. f[0], f[N] = alpha, beta # i = 0 to N-2 b[1:N] = -epsilon*(1./h[0:N-1] + 1./h[1:N]) f[1:N] = -.5*(h[0:N-1] + h[1:N]) c[1:N] = epsilon/h[1:N] - .5 a[0:N-1] = epsilon/h[0:N-1] + .5 return a, b, c, f, x n = [2**i for i in range(4,22)] max_error_fe = [10]*(len(n)) h = [1./num for num in n] for j in range(len(n)): a, b, c, f, x = matrix_diagonals(n[j]) numerical_soln = tridiag(a,b,c,f) analytic_soln = AnalyticSolution(x, alpha, beta,epsilon) max_error_fe[j] = np.max(np.abs(numerical_soln - analytic_soln)) n2 = [2*i for i in range(4,50)] max_error_cheb = [10]*len(n2) for j in range(len(n2)): N = n2[j] D,x = cheb(N) M = 4*epsilon*D.dot(D) -2.*D M[0] = 0. M[-1] = 0. M[0,0] = 1. M[-1,-1] = 1. F = -np.ones(len(x)) F[0] = 4 # beta F[-1] = 2 # alpha cheb_sol = solve(M,F) analytic_soln = AnalyticSolution((x+1.)/2., alpha, beta,epsilon) max_error_cheb[j] = np.max(np.abs(cheb_sol - analytic_soln)) plt.loglog(n2,max_error_cheb,'-b',linewidth=2.,label='Chebychev Error') plt.loglog(n,max_error_fe,'-k',linewidth=2.) plt.xlabel('$n$',fontsize=16) plt.ylabel('$E(n)$',fontsize=16) # plt.savefig("FEM_error_2nd_order.pdf") plt.show() plt.clf()
def trajectory(): N = 200 D, x = cheb(N) eps = 0. def L_yp(x,yp_): a_ = a(x) return a_**3.*yp_*(1 + a_**2.*yp_**2.)**(-1./2) - a_**2.*r(x) def g(z): out = D.dot(L_yp( x,D.dot(z) )) out[0], out[-1] = z[0] - z1, z[-1] - 0 return out # Use the straight line trajectory as an initial guess. # Another option would be to use the shortest-time trajectory found # in heuristic_tractory() as an initial guess. eps, time = time_functional() sol = root(g,y(x,eps)) # sol = root(g,z1/2.*(x-(-1.))) # print sol.success z = sol.x poly = BarycentricInterpolator(x,D.dot(z)) num_func = lambda inpt: poly.__call__(inpt) def L(x): a_, yp_ = a(x), num_func(x) return a_*(1 + a_**2.*yp_**2.)**(1./2) - a_**2.*r(x)*yp_ print "The shortest time is approximately " print integrate.quad(L,-1,1,epsabs=1e-10,epsrel=1e-10)[0] # x0 = np.linspace(-1,1,200) # y0 = y(x0,eps) # plt.plot(x0,y0,'-g',linewidth=2.,label='Initial guess') # plt.plot(x,z,'-b',linewidth=2.,label="Numerical solution") # ax = np.linspace(0-.05,z1+.05,200) # plt.plot(-np.ones(ax.shape),ax,'-k',linewidth=2.5) # plt.plot(np.ones(ax.shape),ax,'-k',linewidth=2.5) # plt.plot(-1,0,'*b',markersize=10.) # plt.plot(1,z1,'*b',markersize=10.) # plt.xlabel('$x$',fontsize=18) # plt.ylabel('$y$',fontsize=18) # plt.legend(loc='best') # plt.axis([-1.1,1.1,0. -.05,z1 +.05]) # # plt.savefig("minimum_time_rivercrossing.pdf") # plt.show() # plt.clf() return x, z, N
def tridiagonal_approach(): epsilon, alpha, beta = .02, 2., 4. # N = number of subintervals or finite elements def AnalyticSolution(x, alpha, beta, epsilon): out = alpha + x + (beta - alpha - 1.) * (np.exp(x / epsilon) - 1.) / ( np.exp(1. / epsilon) - 1.) return out def matrix_diagonals(N): x = np.linspace(0, 1, N + 1)**(1.) # N+1 = number of grid points h = np.diff(x) b, f = np.zeros(N + 1), np.zeros(N + 1) a, c = np.zeros(N), np.zeros(N) b[0], b[N] = 1., 1. f[0], f[N] = alpha, beta # i = 0 to N-2 b[1:N] = -epsilon * (1. / h[0:N - 1] + 1. / h[1:N]) f[1:N] = -.5 * (h[0:N - 1] + h[1:N]) c[1:N] = epsilon / h[1:N] - .5 a[0:N - 1] = epsilon / h[0:N - 1] + .5 return a, b, c, f, x n = [2**i for i in range(4, 22)] max_error_fe = [10] * (len(n)) h = [1. / num for num in n] for j in range(len(n)): a, b, c, f, x = matrix_diagonals(n[j]) numerical_soln = tridiag(a, b, c, f) analytic_soln = AnalyticSolution(x, alpha, beta, epsilon) max_error_fe[j] = np.max(np.abs(numerical_soln - analytic_soln)) n2 = [2 * i for i in range(4, 50)] max_error_cheb = [10] * len(n2) for j in range(len(n2)): N = n2[j] D, x = cheb(N) M = 4 * epsilon * D.dot(D) - 2. * D M[0] = 0. M[-1] = 0. M[0, 0] = 1. M[-1, -1] = 1. F = -np.ones(len(x)) F[0] = 4 # beta F[-1] = 2 # alpha cheb_sol = solve(M, F) analytic_soln = AnalyticSolution((x + 1.) / 2., alpha, beta, epsilon) max_error_cheb[j] = np.max(np.abs(cheb_sol - analytic_soln)) plt.loglog(n2, max_error_cheb, '-b', linewidth=2., label='Chebychev Error') plt.loglog(n, max_error_fe, '-k', linewidth=2.) plt.xlabel('$n$', fontsize=16) plt.ylabel('$E(n)$', fontsize=16) # plt.savefig("FEM_error_2nd_order.pdf") plt.show() plt.clf()