def random_walk_2D(np, ns, plot_step): xpositions = zeros(np) ypositions = zeros(np) # extent of the axis in the plot: ymin = -4 ymax = 8 * sqrt(ns) xmax = 3 * sqrt(ns) xmin = -xmax for step in range(ns): for i in range(np): r = random.randint(0, 10) if 0 <= r <= 5: ypositions[i] += 1 elif r == 6: ypositions[i] -= 1 elif 7 <= r <= 8: xpositions[i] += 1 elif 9 <= r <= 10: xpositions[i] -= 1 # plot just every plot_step steps: if (step + 1) % plot_step == 0: plot( xpositions, ypositions, "ko", axis=[xmin, xmax, ymin, ymax], title="%d researchers after %d months, with ownership of strategy" % (np, step + 1), hardcopy="tmp_%03d.eps" % (step + 1), ) return xpositions, ypositions
def random_walk_2D(np, ns, plot_step): xpositions = zeros(np) ypositions = zeros(np) # extent of the axis in the plot: ymin = -4 ymax = 8 * sqrt(ns) xmax = 3 * sqrt(ns) xmin = -xmax for step in range(ns): for i in range(np): r = random.randint(0, 10) if 0 <= r <= 5: ypositions[i] += 1 elif r == 6: ypositions[i] -= 1 elif 7 <= r <= 8: xpositions[i] += 1 elif 9 <= r <= 10: xpositions[i] -= 1 # plot just every plot_step steps: if (step + 1) % plot_step == 0: plot(xpositions, ypositions, 'ko', axis=[xmin, xmax, ymin, ymax], title='%d researchers after %d months, with ownership of strategy' % \ (np, step+1), hardcopy='tmp_%03d.eps' % (step+1)) return xpositions, ypositions
def d(n): from scitools.std import zeros, sqrt arr = zeros(n) cum_sum = 6 / sqrt(3) for i in range(n): k = i + 1 cum_sum += 6 / sqrt(3) * (-1)**k / (3**k * (2 * k + 1)) arr[i] = cum_sum return arr
def random_walk_2D(np, ns, plot_step): xpositions = zeros(np) ypositions = zeros(np) # extent of the axis in the plot: xymax = 3 * sqrt(ns) xymin = -xymax NORTH = 1 SOUTH = 2 WEST = 3 EAST = 4 # constants for step in range(ns): for i in range(np): direction = random_number.randint(1, 4) if direction == NORTH: ypositions[i] += 1 elif direction == SOUTH: ypositions[i] -= 1 elif direction == EAST: xpositions[i] += 1 elif direction == WEST: xpositions[i] -= 1 # plot just every plot_step steps: if (step + 1) % plot_step == 0: plot(xpositions, ypositions, 'ko', axis=[xymin, xymax, xymin, xymax], title='%d particles after %d steps' % \ (np, step+1), hardcopy='tmp_%03d.eps' % (step+1)) return xpositions, ypositions
def random_walk_2D(np, ns, plot_step): xpositions = zeros(np) ypositions = zeros(np) # extent of the axis in the plot: xymax = 3*sqrt(ns); xymin = -xymax NORTH = 1; SOUTH = 2; WEST = 3; EAST = 4 # constants for step in range(ns): for i in range(np): direction = random_number.randint(1, 4) if direction == NORTH: ypositions[i] += 1 elif direction == SOUTH: ypositions[i] -= 1 elif direction == EAST: xpositions[i] += 1 elif direction == WEST: xpositions[i] -= 1 # plot just every plot_step steps: if (step+1) % plot_step == 0: plot(xpositions, ypositions, 'ko', axis=[xymin, xymax, xymin, xymax], title='%d particles after %d steps' % \ (np, step+1), hardcopy='tmp_%03d.eps' % (step+1)) return xpositions, ypositions
def b(n): from scitools.std import sqrt, zeros arr = zeros(n) cum_sum = 0 for i in range(n): k = i + 1 cum_sum = sqrt(cum_sum**2 + 6 * k**(-2)) arr[i] = cum_sum return arr
def test_terminalVelocity(): """ Test for the terminal velocity with no source term. """ import nose.tools as nt T = 30.; dt = 0.1; g = 9.81; m = 50.; Cd = 1.2; rho = 1.0; A = 0.5; a = Cd*rho*A/(2.*m) v, t = solver(T, dt, -0.1, Cd, rho, A, m) nt.assert_almost_equal(v[-1], -sqrt(g/a), delta=1e-4)
def Temperature_and_Pressure(): meanT = 0 meanP = 0 mean_squareT = 0 mean_squareP = 0 # begin to sample after 200 timesteps: N = len(T) - 200 for j in range(N): i = j + 200 meanT += T[i] meanP += P[i] mean_squareT += T[i] * T[i] mean_squareP += P[i] * P[i] meanT = meanT / N meanP = meanP / N sT = sqrt(mean_squareT / N - meanT * meanT) sP = sqrt(mean_squareP / N - meanP * meanP) return meanT, meanP, sT, sP
def pathlength(x, y): ''' Computes the path length of the points (x0,y0), (x1,y1), ..., (xn,yn) x is a list of real numbers y is a list of real numbers len(x) and len(y) must be equal ''' from scitools.std import sqrt sum = 0 n = len(x) for i in range(1, n): sum += sqrt((x[i] - x[i - 1])**2 + (y[i] - y[i - 1])**2) return sum
def Temperature_and_Pressure(): meanT = 0 meanP = 0 mean_squareT = 0 mean_squareP = 0 # begin to sample after 200 timesteps: N = len(T) -200 for j in range(N): i = j+200 meanT += T[i] meanP += P[i] mean_squareT += T[i]*T[i] mean_squareP += P[i]*P[i] meanT = meanT/N meanP = meanP/N sT = sqrt(mean_squareT/N - meanT*meanT) sP = sqrt(mean_squareP/N - meanP*meanP) return meanT,meanP,sT,sP
def c(lambda_): ''' Computes the wave speed of water surface waves depending on the length lambda of the waves lambda_ must be in meters ''' g = 9.81 # m/s**2 s = 7.9*10**-2 # N/m, air-water surface tension rho = 1*10**6 # kg/m**3, density of water h = 50 # m, the water depth, which we have fixed from scitools.std import pi, tanh, sqrt return sqrt(g*lambda_/(2*pi)*(1 + s*4*pi**2/(rho*g*lambda_**2)) \ * tanh(2*pi*h/lambda_))
def c(lambda_): ''' Computes the wave speed of water surface waves depending on the length lambda of the waves lambda_ must be in meters ''' g = 9.81 # m/s**2 s = 7.9 * 10**-2 # N/m, air-water surface tension rho = 1 * 10**6 # kg/m**3, density of water h = 50 # m, the water depth, which we have fixed from scitools.std import pi, tanh, sqrt return sqrt(g*lambda_/(2*pi)*(1 + s*4*pi**2/(rho*g*lambda_**2)) \ * tanh(2*pi*h/lambda_))
def test_terminalVelocity(): """ Test for the terminal velocity with no source term. """ import nose.tools as nt T = 30. dt = 0.1 g = 9.81 m = 50. Cd = 1.2 rho = 1.0 A = 0.5 a = Cd * rho * A / (2. * m) v, t = solver(T, dt, -0.1, Cd, rho, A, m) nt.assert_almost_equal(v[-1], -sqrt(g / a), delta=1e-4)
def test_convergenceRates(): """ Test for the convergence rates of the solver. The expected result is that the variable r takes the value 2, because the Crank-Nicolson scheme and the geometric average have errors of order dt**2. The final error should then be O(dt**2) which gives r=2. """ dt_start = 1.0 num_dt = 10 E_values = zeros(num_dt) T = 10. g = 9.81 m = 50. Cd = 1.2 rho = 1.0 A = 0.5 a = Cd * rho * A / (2. * m) dt = zeros(num_dt) dt[0] = dt_start for i in range(1, len(dt)): dt[i] = dt[i - 1] / 2. D = -0.39 B = 0.76 C = -0.145 def exact(t): return D * t**3 + B * t + C def src(t): return m * g + m * a * abs( exact(t)) * exact(t) + m * (3 * D * t**2 + B) # Simulate for different timesteps, and store the error in E_values for i in range(num_dt): v, t = solver(T, dt[i], exact(0), Cd, rho, A, m, src) ve = exact(t) diff = v - ve E_values[i] = sqrt(dt[i] * sum(diff**2)) # Calculate r-values corresponding to the error with each different timestep r = zeros(len(E_values) - 1) for i in range(1, len(r)): r[i] = (log(E_values[i - 1] / E_values[i])) / (log(dt[i - 1] / dt[i])) import nose.tools as nt nt.assert_almost_equal(r[-1], 2, delta=0.1)
def finite_element_Picard(L, Nx, N, dt, C, P_L, P_R): # Define mesh mesh = Interval(Nx, 0, L) #Define function space and functions V = FunctionSpace(mesh, 'Lagrange', 1) v = TestFunction(V) q = TrialFunction(V) q_k = Function(V) q_1 = Function(V) # Define boundary conditions bcl = DirichletBC(V, Constant(P_L**2), LeftDiricletBoundary) bcr = DirichletBC(V, Constant(P_R**2), RightDiricletBoundary) bc = [bcl, bcr] # Initial condition I_q = Constant(P_R**2) q_1 = interpolate(I_q, V) q_k.assign(q_1) c = Constant(C) # Define variational problems a = q*v*dx + dt*c*q_k**1.5*inner(nabla_grad(q), nabla_grad(v))*dx L = q_1*v*dx # Time loop q = Function(V) # new unknown function tol = 1.0E-5 # tolerance maxiter = 25 # max no of iterations allowed t = dt for n in range(0, N): #print 'time =', t eps = 1.0 # error measure ||u-u_k|| iter = 0 # iteration counter b = assemble(L) while eps > tol and iter < maxiter: iter += 1 A = assemble(a) bcl.apply(A, b) bcr.apply(A, b) solve(A, q.vector(), b,'lu') diff = q.vector().array() - q_k.vector().array() eps = numpy.linalg.norm(diff, ord=numpy.Inf) q_k.assign(q) #print 'iter=%d: norm=%g' % (iter, eps) t += dt q_1.assign(q_k) # return last P return sqrt(q_k.vector().array())
def finite_difference(L, Nx, N, dt, C, P_L, P_R): x = linspace(0, L, Nx+1) dx = x[1] - x[0] C = 0.4*C*dt/(dx**2) print C Q = zeros(Nx+1) Q_1 = P_R**2*ones(Nx+1) for n in range(0, N): # Compute u at inner mesh points for i in range(1, Nx): Q[i] = Q_1[i] + C*(Q_1[i-1]**2.5 - 2*Q_1[i]**2.5 + Q_1[i+1]**2.5) # Insert boundary conditions Q[0]=P_L**2; Q[Nx]=P_R**2 # Update u_1 before next step Q_1[:]= Q return sqrt(Q), x
def test_convergenceRates(): """ Test for the convergence rates of the solver. The expected result is that the variable r takes the value 2, because the Crank-Nicolson scheme and the geometric average have errors of order dt**2. The final error should then be O(dt**2) which gives r=2. """ dt_start = 1.0; num_dt = 10 E_values = zeros(num_dt) T = 10.; g = 9.81; m = 50.; Cd = 1.2; rho = 1.0; A = 0.5; a = Cd*rho*A/(2.*m) dt = zeros(num_dt); dt[0] = dt_start for i in range(1,len(dt)): dt[i] = dt[i-1]/2. D = -0.39; B = 0.76; C = -0.145 def exact(t): return D*t**3 + B*t + C def src(t): return m*g + m*a*abs(exact(t))*exact(t) + m*(3*D*t**2 + B) # Simulate for different timesteps, and store the error in E_values for i in range(num_dt): v, t = solver(T, dt[i], exact(0), Cd, rho, A, m, src) ve = exact(t) diff = v - ve E_values[i] = sqrt(dt[i]*sum(diff**2)) # Calculate r-values corresponding to the error with each different timestep r=zeros(len(E_values)-1) for i in range(1, len(r)): r[i] = (log(E_values[i-1]/E_values[i]))/(log(dt[i-1]/dt[i])) import nose.tools as nt nt.assert_almost_equal(r[-1], 2, delta=0.1)
counter += 1 def T(z, t): # T0, A, k, and omega are global variables return T0 + A1 * exp(-a1 * z) * cos(omega1 * t - a1 * z) + \ A2 * exp(-a2 * z) * cos(omega2 * t - a2 * z) k = 1E-6 # thermal diffusivity (in m**2/s) A1 = 15 # amplitude of the daily temperature variations (in C) P1 = 24 * 60 * 60. # oscillation period of 24 h (in seconds) # angular frequency of daily temperature variations (in rad/s) omega1 = 2 * pi / P1 a1 = sqrt(omega1 / (2 * k)) A2 = 7 # amplitude of yearly temperature variations (in C) P2 = 24 * 60 * 60 * 365. # oscillation period of 1 yr (in seconds) # angular frequency of yearly temperature variations (in rad/s) omega2 = 2 * pi / P2 a2 = sqrt(omega2 / (2 * k)) dt = P2 / 30 # time lag: 0.1 yr tmax = 3 * P2 # 3 year simulation T0 = 10 # mean surface temperature in Celsius D = -(1 / a1) * log(0.001) # max depth n = 501 # no of points in the z direction z = linspace(0, D, n)
def test_undampedWaves(): #define constants given in exercise A = 1 mx=7. my=2. #define function that give q=lambda x,y: 1 #define some variables Lx = 3 Ly = 1.3 T = 1 C = 0.5 dt= 0.1 #define omega so equation holds w=pi*sqrt((mx/Lx)**2 +(my/Ly)**2) #help varabeles kx = pi*mx/Lx ky = pi*my/Ly #Exact solution ue = lambda x,y,t: A*cos(x*kx)*cos(y*ky)*cos(t*w) #initial condition so we get result we want. I = lambda x,y: A*cos(x*kx)*cos(y*ky) #factor dt decreeses per step step=0.5 #number of steps I want to do val=5 #array to store errors E=zeros(val) for i in range(val): v='vector' #solve eqation u,x,y,t,e=solver(I,None,None,q,0,Lx,Ly,dt*step**(i),T,C,1,mode=v,ue=ue) E[i]=e #find convergence rate between diffrent dt values r =zeros(val-1) r = log(E[1:]/E[:-1])/log(step) print "Test convergence for undamped waves:" for i in range(val): if i==0: print "dt: ",dt," Error: ",E[i] else: print "dt: ",dt*step**(i)," Error: ",E[i], "rate of con.: ", r[i-1] #requiere close to 2 in convergence rate for last r. assert abs(r[-1]-2)<0.01
def f(x, m, s): return (1.0/(sqrt(2*pi)*s))*exp(-0.5*((x-m)/s)**2)
a = 1 #set parameters for the orbit b = 1 w = 1 delta_t = (2 * pi) / (w * n) counter = 0 X = [] Y = [] for k in range(n + 1): tk = k * delta_t #each time through we need to add a new k value x = a * cos(w * tk) y = b * sin(w * tk) X.append(x) Y.append(y) XP = array(X) YP = array(Y) XF = array([x]) YF = array([y]) velo = w * sqrt(a**2 * sin(w * tk)**2 + b**2 * cos(w * tk)**2) plot(XP, YP, '-r', XF, YF, 'bo', axis=[-1.2, 1.2, -1.2, 1.2], title='Planetary orbit', legend=(['Instaneous velocity=%6f' % velo, 'present location']), savefig='pix/planet%4d.png' % counter) counter += 1 show()
# from __future__ import unicode_literals
def test_undampedWaves(): #define constants given in exercise A = 1 mx = 7. my = 2. #define function that give q = lambda x, y: 1 #define some variables Lx = 3 Ly = 1.3 T = 1 C = 0.5 dt = 0.1 #define omega so equation holds w = pi * sqrt((mx / Lx)**2 + (my / Ly)**2) #help varabeles kx = pi * mx / Lx ky = pi * my / Ly #Exact solution ue = lambda x, y, t: A * cos(x * kx) * cos(y * ky) * cos(t * w) #initial condition so we get result we want. I = lambda x, y: A * cos(x * kx) * cos(y * ky) #factor dt decreeses per step step = 0.5 #number of steps I want to do val = 5 #array to store errors E = zeros(val) for i in range(val): v = 'vector' #solve eqation u, x, y, t, e = solver(I, None, None, q, 0, Lx, Ly, dt * step**(i), T, C, 1, mode=v, ue=ue) E[i] = e #find convergence rate between diffrent dt values r = zeros(val - 1) r = log(E[1:] / E[:-1]) / log(step) print "Test convergence for undamped waves:" for i in range(val): if i == 0: print "dt: ", dt, " Error: ", E[i] else: print "dt: ", dt * step**( i), " Error: ", E[i], "rate of con.: ", r[i - 1] #requiere close to 2 in convergence rate for last r. assert abs(r[-1] - 2) < 0.01
def pathlength(x, y): L = 0 for i in xrange(1, len(x)): dL_squared = (x[i] - x[i - 1]) ** 2 + (y[i] - y[i - 1]) ** 2 L += sqrt(dL_squared) return L
show=False) t += dt counter += 1 def T(z, t): # T0, A, k, and omega are global variables return T0 + A1 * exp(-a1 * z) * cos(omega1 * t - a1 * z) + \ A2 * exp(-a2 * z) * cos(omega2 * t - a2 * z) k = 1E-6 # thermal diffusivity (in m**2/s) A1 = 15 # amplitude of the daily temperature variations (in C) P1 = 24 * 60 * 60. # oscillation period of 24 h (in seconds) omega1 = 2 * pi / P1 # angular freq of daily temp variations (in rad/s) a1 = sqrt(omega1 / (2 * k)) A2 = 7 # amplitude of yearly temperature variations (in C) P2 = 24 * 60 * 60 * 365. # oscillation period of 1 yr (in seconds) omega2 = 2 * pi / P2 # angular freq of yearly temp variations (in rad/s) a2 = sqrt(omega2 / (2 * k)) dt = P2 / 20 # time lag: 0.1 yr tmax = 3 * P2 # 3 year simulation T0 = 10 # mean surface temperature in Celsius D = -(1 / a1) * log(0.001) # max depth n = 501 # no of points in the z direction # set T0, A, k, omega, D, n, tmax, dt z = linspace(0, D, n) animate(tmax, dt, z, T, T0 - A2 - A1, T0 + A2 + A1, 0, 'z', 'T')
def advance_scalar(u, u_1, u_2, q, f, x, y, t, n, A, B, dt2, dtdx2,dtdy2, V=None, step1=False): t1 = time.clock() Ix = range(0, u.shape[0]); Iy = range(0, u.shape[1]) if step1: # Special formula for step 1 I = u_1; dt = sqrt(dt2) for i in Ix[1:-1]: for j in Iy[1:-1]: u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V(x[i],y[j]) + dt2*f(x[i], y[j], 0) \ + dtdx2*( (q[i,j] + q[i+1,j]) * (I[i+1,j] - I[i,j]) \ - (q[i,j] + q[i-1,j]) * (I[i,j] - I[i-1,j])) \ + dtdy2*( (q[i,j] + q[i,j+1]) * (I[i,j+1] - I[i,j]) \ - (q[i,j] + q[i,j-1]) * (I[i,j] - I[i,j-1]))) else: # Compute ALL interior points for i in Ix[1:-1]: for j in Iy[1:-1]: u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f(x[i], y[j], t[n]) \ + dtdx2*( (q[i,j] + q[i+1,j]) * (u_1[i+1,j] - u_1[i,j]) \ - (q[i,j] + q[i-1,j]) * (u_1[i,j] - u_1[i-1,j])) \ + dtdy2*( (q[i,j] + q[i,j+1]) * (u_1[i,j+1] - u_1[i,j]) \ - (q[i,j] + q[i,j-1]) * (u_1[i,j] - u_1[i,j-1]))) # Neumann boundary condition du/dx = 0 if step1: i = Ix[0] # 1) Boundary where x = 0 for j in Iy[1:-1]: u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V(x[i],y[j]) + dt2*f(x[i], y[j], 0) \ + dtdx2*2*(q[i,j] + q[i+1,j]) * (I[i+1,j] - I[i,j]) \ + dtdy2*( (q[i,j] + q[i,j+1]) * (I[i,j+1] - I[i,j]) \ - (q[i,j] + q[i,j-1]) * (I[i,j] - I[i,j-1]))) i = Ix[-1] # 1) Boundary where x = Nx for j in Iy[1:-1]: u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V(x[i],y[j]) + dt2*f(x[i], y[j], 0) \ + dtdx2*2*(q[i,j] + q[i-1,j]) * (I[i-1,j] - I[i,j]) \ + dtdy2*( (q[i,j] + q[i,j+1]) * (I[i,j+1] - I[i,j]) \ - (q[i,j] + q[i,j-1]) * (I[i,j] - I[i,j-1]))) j = Iy[0] # 1) Boundary where y = 0 for i in Ix[1:-1]: u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V(x[i],y[j]) + dt2*f(x[i], y[j], 0) \ + dtdx2*( (q[i,j] + q[i+1,j]) * (I[i+1,j] - I[i,j]) \ - (q[i,j] + q[i-1,j]) * (I[i,j] - I[i-1,j])) \ + dtdy2*2*(q[i,j] + q[i,j+1]) * (I[i,j+1] - I[i,j])) j = Iy[-1] # 1) Boundary where y = Ny for i in Ix[1:-1]: u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V(x[i],y[j]) + dt2*f(x[i], y[j], 0) \ + dtdx2*( (q[i,j] + q[i+1,j]) * (I[i+1,j] - I[i,j]) \ - (q[i,j] + q[i-1,j]) * (I[i,j] - I[i-1,j])) \ + dtdy2*2*(q[i,j] + q[i,j-1]) * (I[i,j-1] - I[i,j])) # Special formula for the four corner points i = Ix[0]; j = Iy[0] u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V(x[i],y[j]) + dt2*f(x[i], y[j], 0) \ + dtdx2*2*(q[i,j] + q[i+1,j]) * (I[i+1,j] - I[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j+1]) * (I[i,j+1] - I[i,j])) i = Ix[0]; j = Iy[-1] u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V(x[i],y[j]) + dt2*f(x[i], y[j], 0) \ + dtdx2*2*(q[i,j] + q[i+1,j]) * (I[i+1,j] - I[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j-1]) * (I[i,j-1] - I[i,j])) i = Ix[-1]; j = Iy[0] u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V(x[i],y[j]) + dt2*f(x[i], y[j], 0) \ + dtdx2*2*(q[i,j] + q[i-1,j]) * (I[i-1,j] - I[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j+1]) * (I[i,j+1] - I[i,j])) i = Ix[-1]; j = Iy[-1] u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V(x[i],y[j]) + dt2*f(x[i], y[j], 0) \ + dtdx2*2*(q[i,j] + q[i-1,j]) * (I[i-1,j] - I[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j-1]) * (I[i,j-1] - I[i,j])) else: # Any step NOT first i = Ix[0] # 1) Boundary where x = 0 for j in Iy[1:-1]: u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f(x[i], y[j], t[n]) \ + dtdx2*2*(q[i,j] + q[i+1,j]) * (u_1[i+1,j] - u_1[i,j]) \ + dtdy2*( (q[i,j] + q[i,j+1]) * (u_1[i,j+1] - u_1[i,j]) \ - (q[i,j] + q[i,j-1]) * (u_1[i,j] - u_1[i,j-1]))) i = Ix[-1] # 1) Boundary where x = Nx for j in Iy[1:-1]: u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f(x[i], y[j], t[n]) \ + dtdx2*2*(q[i,j] + q[i-1,j]) * (u_1[i-1,j] - u_1[i,j]) \ + dtdy2*( (q[i,j] + q[i,j+1]) * (u_1[i,j+1] - u_1[i,j]) \ - (q[i,j] + q[i,j-1]) * (u_1[i,j] - u_1[i,j-1]))) j = Iy[0] # 1) Boundary where y = 0 for i in Ix[1:-1]: u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f(x[i], y[j], t[n]) \ + dtdx2*( (q[i,j] + q[i+1,j]) * (u_1[i+1,j] - u_1[i,j]) \ - (q[i,j] + q[i-1,j]) * (u_1[i,j] - u_1[i-1,j])) \ + dtdy2*2*(q[i,j] + q[i,j+1]) * (u_1[i,j+1] - u_1[i,j]) ) j = Iy[-1] # 1) Boundary where y = Ny for i in Ix[1:-1]: u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f(x[i], y[j], t[n]) \ + dtdx2*( (q[i,j] + q[i+1,j]) * (u_1[i+1,j] - u_1[i,j]) \ - (q[i,j] + q[i-1,j]) * (u_1[i,j] - u_1[i-1,j])) \ + dtdy2*2*(q[i,j] + q[i,j-1]) * (u_1[i,j-1] - u_1[i,j]) ) # Special formula for the four corner points i = Ix[0]; j = Iy[0] u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f(x[i], y[j], t[n]) \ + dtdx2*2*(q[i,j] + q[i+1,j]) * (u_1[i+1,j] - u_1[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j+1]) * (u_1[i,j+1] - u_1[i,j])) i = Ix[0]; j = Iy[-1] u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f(x[i], y[j], t[n]) \ + dtdx2*2*(q[i,j] + q[i+1,j]) * (u_1[i+1,j] - u_1[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j-1]) * (u_1[i,j-1] - u_1[i,j])) i = Ix[-1]; j = Iy[0] u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f(x[i], y[j], t[n]) \ + dtdx2*2*(q[i,j] + q[i-1,j]) * (u_1[i-1,j] - u_1[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j+1]) * (u_1[i,j+1] - u_1[i,j])) i = Ix[-1]; j = Iy[-1] u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f(x[i], y[j], t[n]) \ + dtdx2*2*(q[i,j] + q[i-1,j]) * (u_1[i-1,j] - u_1[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j-1]) * (u_1[i,j-1] - u_1[i,j])) CPU_time = time.clock() - t1 return u, CPU_time
def f(x,m,s): return (1.0/(sqrt(2*pi)*s))*exp(-0.5*((x-m)/s)**2)
""" Exercise 5.3: Fill arrays; vectorized (plot) Author: Weiyun Lu """ from scitools.std import sqrt, pi, exp, linspace, plot h = lambda x : (1/(sqrt(2*pi))) * exp(-0.5*x**2) xlist = linspace(-4,4,41) hlist = h(xlist) pairs = zip(xlist,hlist) plot(xlist, hlist, axis=[xlist[0], xlist[-1], 0, 0.5], xlabel='x', \ ylabel='h(x)', title='Standard Gaussian')
N = 1600 h = 0.05 k = 0.2 P_L = 1 P_R = 0 dt = T/float(N); DX = L/float(Nx) C = k*h**2 c = C*dt/DX**2 # Solve by different methods start = time.clock() P_fd, x = finite_difference(L, Nx, N, dt, C, P_L, P_R) print 'FD forward Euler:', time.clock() - start P_ex = sqrt(1-x) start = time.clock() P_Pi = finite_element_Picard(L, Nx, N, dt, C, P_L, P_R) print 'FE backward Euler Picard:', time.clock() - start start = time.clock() P_Ne = finite_element_Newton(L, Nx, N, dt, C, P_L, P_R) print 'FE bacward Euler Newton:', time.clock() - start figure(1) pylab.plot(x, P_ex, x, P_fd, x, P_Pi, x, P_Ne)#, x, P_fe) pylab.legend(['Exact', 'FD forward Euler', 'FE backward Euler Picard', 'FE backward Euler Newton']) pylab.xlabel('x') pylab.ylabel('Pressure')
def solver(I, V_, f_, c, Lx, Ly, Nx, Ny, dt, T, b, user_action=None, version='scalar', skip_every_n_frame=10, show_cpu_time=False,display_warnings=True, plotting=False): order = 'C' # Store arrays in a column-major order (in memory) x = linspace(0, Lx, Nx+1) # mesh points in x dir y = linspace(0, Ly, Ny+1) # mesh points in y dir dx = x[1] - x[0] dy = y[1] - y[0] xv = x[:,newaxis] # for vectorized function evaluations yv = y[newaxis,:] # Assuming c is a function: c_ = zeros((Nx+1,Ny+1), order='c') for i,xx in enumerate(x): for j,yy in enumerate(y): c_[i,j] = c(xx,yy) # Loop through x and y with indices i,j at the same time c_max = c_.max() # Pick out the largest value from c(x,y) q = c_**2 stability_limit = (1/float(c_max))*(1/sqrt(1/dx**2 + 1/dy**2)) if dt <= 0: # shortcut for max time step is to use i.e. dt = -1 safety_factor = -dt # use negative dt as safety factor extra_factor = 1 # Easy way to make dt even smaller dt = safety_factor*stability_limit*extra_factor elif dt > stability_limit and display_warnings: print '\nWarning: (Unless you are testing the program), be aware that' print 'dt: %g is currently exceeding the stability limit: %g\n' %(dt, stability_limit) Nt = int(round(T/float(dt))) t = linspace(0, Nt*dt, Nt+1) # mesh points in time dt2 = dt**2 # Constants for simple calculation A = (1 + b*dt/2)**(-1) B = (b*dt/2 - 1) dtdx2 = dt**2/(2*dx**2) dtdy2 = dt**2/(2*dy**2) # Make f(x,y,t) and V(x,y) ready for computation with different schemes if f_ is None or f_ == 0: f = (lambda x, y, t: 0) if version == 'scalar' else \ lambda x, y, t: zeros((xv.shape[0], yv.shape[1])) else: if version == 'scalar': f = f_ if V_ is None or V_ == 0: V = (lambda x, y: 0) if version == 'scalar' else \ lambda x, y: zeros((xv.shape[0], yv.shape[1])) else: if version == 'scalar': V = V_ if version == 'vectorized': # Generate and fill matrices for first timestep f = zeros((Nx+1,Ny+1), order=order) V = zeros((Nx+1,Ny+1), order=order) f[:,:] = f_(xv,yv,0) V[:,:] = V_(xv,yv) u = zeros((Nx+1,Ny+1), order=order) # solution array u_1 = zeros((Nx+1,Ny+1), order=order) # solution at t-dt u_2 = zeros((Nx+1,Ny+1), order=order) # solution at t-2*dt Ix = range(0, u.shape[0]) # Index set notation Iy = range(0, u.shape[1]) It = range(0, t.shape[0]) import time; t0 = time.clock() # for measuring CPU time # Load initial condition into u_1 if version == 'scalar': for i in Ix: for j in Iy: u_1[i,j] = I(x[i], y[j]) else: # use vectorized version u_1[:,:] = I(xv, yv) if user_action is not None: if plotting: user_action(u_1, x, xv, y, yv, t, 0, skip_every_n_frame) else: user_action(u_1, x, xv, y, yv, t, 0) # Special formula for first time step n = 0 # First step requires a special formula, use either the scalar # or vectorized version (the impact of more efficient loops than # in advance_vectorized is small as this is only one step) if version == 'scalar': u,cpu_time = advance_scalar(u, u_1, u_2, q, f, x, y, t, n, A, B, dt2, dtdx2,dtdy2, V, step1=True) else: u,cpu_time = advance_vectorized(u, u_1, u_2, q, f, t, n, A, B, dt2, dtdx2,dtdy2, V, step1=True) if user_action is not None: if plotting: user_action(u, x, xv, y, yv, t, 1, skip_every_n_frame) else: user_action(u_1, x, xv, y, yv, t, 1) # Update data structures for next step u_2, u_1, u = u_1, u, u_2 # Time loop for all later steps for n in It[1:-1]: if version == 'scalar': # use f(x,y,t) function u,cpu_time = advance_scalar(u, u_1, u_2, q, f, x, y, t, n, A, B, dt2, dtdx2,dtdy2) if show_cpu_time: percent = (float(n)/It[-2])*100.0 sys.stdout.write("\rLast step took: %.3f sec with [scalar-code]. Computation is %d%% " %(cpu_time,percent)) sys.stdout.flush() else: # Use vectorized code f[:,:] = f_(xv, yv, t[n]) # must precompute the matrix f u,cpu_time = advance_vectorized(u, u_1, u_2, q, f, t, n, A, B, dt2, dtdx2,dtdy2) if show_cpu_time: percent = (float(n)/It[-2])*100.0 sys.stdout.write("\rLast step took: %.5f sec with [vec-code]. Computation is %d%% " %(cpu_time,percent)) sys.stdout.flush() if user_action is not None: if plotting: if user_action(u, x, xv, y, yv, t, n+1, skip_every_n_frame): break else: if user_action(u, x, xv, y, yv, t, n+1): break # Update data structures for next step #u_2[:] = u_1; u_1[:] = u # safe, but slower u_2, u_1, u = u_1, u, u_2 # Important to set u = u_1 if u is to be returned! t1 = time.clock() # dt might be computed in this function so return the value return dt, t1 - t0
def pathlength(x, y): L = 0 for i in xrange(1, len(x)): dL_squared = (x[i] - x[i - 1])**2 + (y[i] - y[i - 1])**2 L += sqrt(dL_squared) return L
def advance_vectorized(u, u_1, u_2, q, f, t, n, A, B, dt2, dtdx2,dtdy2, V=None, step1=False): """ Haakon (me) code """ t1 = time.clock() Ix = range(0, u.shape[0]); Iy = range(0, u.shape[1]) if step1: I = u_1; dt = sqrt(dt2) u[1:-1,1:-1] = 0.5*(2*I[1:-1,1:-1] - 2*B*dt*V[1:-1,1:-1] + dt2*f[1:-1,1:-1] \ + dtdx2*( (q[1:-1,1:-1] + q[2:,1:-1]) * (I[2:,1:-1] - I[1:-1,1:-1]) \ - (q[1:-1,1:-1] + q[:-2,1:-1]) * (I[1:-1,1:-1] - I[:-2,1:-1])) \ + dtdy2*( (q[1:-1,1:-1] + q[1:-1,2:]) * (I[1:-1,2:] - I[1:-1,1:-1]) \ - (q[1:-1,1:-1] + q[1:-1,:-2]) * (I[1:-1,1:-1] - I[1:-1,:-2]))) else: u[1:-1,1:-1] = A*( 2*u_1[1:-1,1:-1] + B*u_2[1:-1,1:-1] + dt2*f[1:-1,1:-1] \ + dtdx2*( (q[1:-1,1:-1] + q[2:,1:-1]) * (u_1[2:,1:-1] - u_1[1:-1,1:-1]) \ - (q[1:-1,1:-1] + q[:-2,1:-1]) * (u_1[1:-1,1:-1] - u_1[:-2,1:-1])) \ + dtdy2*( (q[1:-1,1:-1] + q[1:-1,2:]) * (u_1[1:-1,2:] - u_1[1:-1,1:-1]) \ - (q[1:-1,1:-1] + q[1:-1,:-2]) * (u_1[1:-1,1:-1] - u_1[1:-1,:-2]))) ###################################### # Neumann boundary condition du/dn=0 # ###################################### if step1: i = Ix[0] # 1) Boundary where x = 0 u[i,1:-1] = 0.5*(2*I[i,1:-1] - 2*B*dt*V[i,1:-1] + dt2*f[i,1:-1] \ + dtdx2*2*(q[i,1:-1] + q[i+1,1:-1]) * (I[i+1,1:-1] - I[i,1:-1]) \ + dtdy2*( (q[i,1:-1] + q[i,2:]) * (I[i,2:] - I[i,1:-1]) \ - (q[i,1:-1] + q[i,:-2]) * (I[i,1:-1] - I[i,:-2]))) i = Ix[-1] # 1) Boundary where x = Nx u[i,1:-1] = 0.5*(2*I[i,1:-1] - 2*B*dt*V[i,1:-1] + dt2*f[i,1:-1] \ + dtdx2*2*(q[i,1:-1] + q[i-1,1:-1]) * (I[i-1,1:-1] - I[i,1:-1]) \ + dtdy2*( (q[i,1:-1] + q[i,2:]) * (I[i,2:] - I[i,1:-1]) \ - (q[i,1:-1] + q[i,:-2]) * (I[i,1:-1] - I[i,:-2]))) j = Iy[0] # 1) Boundary where y = 0 u[1:-1,j] = 0.5*(2*I[1:-1,j] - 2*B*dt*V[1:-1,j] + dt2*f[1:-1,j] \ + dtdx2*( (q[1:-1,j] + q[2:,j]) * (I[2:,j] - I[1:-1,j]) \ - (q[1:-1,j] + q[:-2,j]) * (I[1:-1,j] - I[:-2,j])) \ + dtdy2*2*(q[1:-1,j] + q[1:-1:,j+1]) * (I[1:-1:,j+1] - I[1:-1,j])) j = Iy[-1] # 1) Boundary where y = Ny u[1:-1,j] = 0.5*(2*I[1:-1,j] - 2*B*dt*V[1:-1,j] + dt2*f[1:-1,j] \ + dtdx2*( (q[1:-1,j] + q[2:,j]) * (I[2:,j] - I[1:-1,j]) \ - (q[1:-1,j] + q[:-2,j]) * (I[1:-1,j] - I[:-2,j])) \ + dtdy2*2*(q[1:-1,j] + q[1:-1:,j-1]) * (I[1:-1:,j-1] - I[1:-1,j])) # Special formula for the four corner points i = Ix[0]; j = Iy[0] u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V[i,j] + dt2*f[i,j] \ + dtdx2*2*(q[i,j] + q[i+1,j]) * (I[i+1,j] - I[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j+1]) * (I[i,j+1] - I[i,j])) i = Ix[0]; j = Iy[-1] u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V[i,j] + dt2*f[i,j] \ + dtdx2*2*(q[i,j] + q[i+1,j]) * (I[i+1,j] - I[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j-1]) * (I[i,j-1] - I[i,j])) i = Ix[-1]; j = Iy[0] u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V[i,j] + dt2*f[i,j] \ + dtdx2*2*(q[i,j] + q[i-1,j]) * (I[i-1,j] - I[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j+1]) * (I[i,j+1] - I[i,j])) i = Ix[-1]; j = Iy[-1] u[i,j] = 0.5*(2*I[i,j] - 2*B*dt*V[i,j] + dt2*f[i,j] \ + dtdx2*2*(q[i,j] + q[i-1,j]) * (I[i-1,j] - I[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j-1]) * (I[i,j-1] - I[i,j])) else: # Any step NOT first i = Ix[0] # 1) Boundary where x = 0 u[i,1:-1] = A*( 2*u_1[i,1:-1] + B*u_2[i,1:-1] + dt2*f[i,1:-1] \ + dtdx2*2*(q[i,1:-1] + q[i+1,1:-1]) * (u_1[i+1,1:-1] - u_1[i,1:-1]) \ + dtdy2*( (q[i,1:-1] + q[i,2:]) * (u_1[i,2:] - u_1[i,1:-1]) \ - (q[i,1:-1] + q[i,:-2]) * (u_1[i,1:-1] - u_1[i,:-2]))) i = Ix[-1] # 1) Boundary where x = Nx u[i,1:-1] = A*( 2*u_1[i,1:-1] + B*u_2[i,1:-1] + dt2*f[i,1:-1] \ + dtdx2*2*(q[i,1:-1] + q[i-1,1:-1]) * (u_1[i-1,1:-1] - u_1[i,1:-1]) \ + dtdy2*( (q[i,1:-1] + q[i,2:]) * (u_1[i,2:] - u_1[i,1:-1]) \ - (q[i,1:-1] + q[i,:-2]) * (u_1[i,1:-1] - u_1[i,:-2]))) j = Iy[0] # 1) Boundary where y = 0 u[1:-1,j] = A*( 2*u_1[1:-1,j] + B*u_2[1:-1,j] + dt2*f[1:-1,j] \ + dtdx2*( (q[1:-1,j] + q[2:,j]) * (u_1[2:,j] - u_1[1:-1,j]) \ - (q[1:-1,j] + q[:-2,j]) * (u_1[1:-1,j] - u_1[:-2,j])) \ + dtdy2*2*(q[1:-1,j] + q[1:-1,j+1]) * (u_1[1:-1,j+1] - u_1[1:-1,j]) ) j = Iy[-1] # 1) Boundary where y = Ny u[1:-1,j] = A*( 2*u_1[1:-1,j] + B*u_2[1:-1,j] + dt2*f[1:-1,j] \ + dtdx2*( (q[1:-1,j] + q[2:,j]) * (u_1[2:,j] - u_1[1:-1,j]) \ - (q[1:-1,j] + q[:-2,j]) * (u_1[1:-1,j] - u_1[:-2,j])) \ + dtdy2*2*(q[1:-1,j] + q[1:-1,j-1]) * (u_1[1:-1,j-1] - u_1[1:-1,j]) ) # Special formula for the four corner points i = Ix[0]; j = Iy[0] u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f[i,j] \ + dtdx2*2*(q[i,j] + q[i+1,j]) * (u_1[i+1,j] - u_1[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j+1]) * (u_1[i,j+1] - u_1[i,j])) i = Ix[0]; j = Iy[-1] u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f[i,j] \ + dtdx2*2*(q[i,j] + q[i+1,j]) * (u_1[i+1,j] - u_1[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j-1]) * (u_1[i,j-1] - u_1[i,j])) i = Ix[-1]; j = Iy[0] u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f[i,j] \ + dtdx2*2*(q[i,j] + q[i-1,j]) * (u_1[i-1,j] - u_1[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j+1]) * (u_1[i,j+1] - u_1[i,j])) i = Ix[-1]; j = Iy[-1] u[i,j] = A*( 2*u_1[i,j] + B*u_2[i,j] + dt2*f[i,j] \ + dtdx2*2*(q[i,j] + q[i-1,j]) * (u_1[i-1,j] - u_1[i,j]) \ + dtdy2*2*(q[i,j] + q[i,j-1]) * (u_1[i,j-1] - u_1[i,j])) CPU_time = time.clock() - t1 return u,CPU_time