def build_grid(self): config = self.config Lx = config.grid.Lx self.Lx = Lx La = config.uc.a self.La = La Ms = config.grid.Ms MsA = config.grid.vMs[0] MsB = config.grid.vMs[1] if os.path.exists(config.grid.field_data): mat = loadmat(config.grid.field_data) self.wA = mat['wA'] self.wB = mat['wB'] else: self.wA = np.random.rand(Lx) self.wB = np.random.rand(Lx) self.qA = np.zeros((MsA, Lx)) self.qA[0, :] = 1. self.qAc = np.zeros((MsA, Lx)) self.qB = np.zeros((MsB, Lx)) self.qBc = np.zeros((MsB, Lx)) self.qBc[0, :] = 1. ds = 1. / (Ms - 1) self.ds = ds lbcA = BC(self.lbc, self.lbc_vc) rbcA = BC(self.rbc, self.rbc_vc) self.kaA = lbcA.beta self.kbA = rbcA.beta fA = self.fA fB = self.fB lbcB = copy.deepcopy(lbcA) lbcB.beta = -lbcA.beta * fA / fB # See Fredrickson Book p.194 rbcB = copy.deepcopy(rbcA) rbcB.beta = -rbcA.beta * fA / fB #print 'lbcA=', lbcA.__dict__ #print 'rbcA=', rbcA.__dict__ #print 'lbcB=', lbcB.__dict__ #print 'rbcB=', rbcB.__dict__ self.qA_solver = ETDRK4(La, Lx - 1, MsA, h=ds, lbc=lbcA, rbc=rbcA) self.qAc_solver = ETDRK4(La, Lx - 1, MsA, h=ds, lbc=lbcA, rbc=rbcA) self.qB_solver = ETDRK4(La, Lx - 1, MsB, h=ds, lbc=lbcB, rbc=rbcB) self.qBc_solver = ETDRK4(La, Lx - 1, MsB, h=ds, lbc=lbcB, rbc=rbcB) self.lamA = config.grid.lam[0] self.lamB = config.grid.lam[1] self.lamY = config.grid.lam[2] #self.yita = self.lamY # for compressible model self.yita = np.zeros(Lx) # for incompressible model
def build_grid(self): config = self.config Lx = config.grid.Lx self.Lx = Lx La = config.uc.a self.La = La Ms = config.grid.Ms if os.path.exists(config.grid.field_data): print "Reading from ", config.grid.field_data mat = loadmat(config.grid.field_data) self.w = np.zeros(Lx, dtype=np.complex128) self.w = mat['w'].reshape(Lx) else: self.w = np.zeros(Lx, dtype=np.complex128) self.w.real = np.random.rand(Lx) self.w.imag = np.random.rand(Lx) self.phi = np.zeros(Lx, dtype=np.complex128) self.q = np.zeros((Ms, Lx), dtype=np.complex128) self.q[0].real = 1. ds = 1. / (Ms - 1) self.ds = ds lbc = BC(self.lbc, self.lbc_vc) rbc = BC(self.rbc, self.rbc_vc) self.q_solver = ETDRK4(La, Lx - 1, Ms, h=ds, lbc=lbc, rbc=rbc) self.lam = config.grid.lam[0]
def test_exact_neumann_dirichlet(): L = 10 N = 128 Ns = 200 + 1 #20000 + 1 algo = 1 scheme = 1 W, u0, x = init_chebyshev_fredrikson(N, L) u0[0] = 0. print 'ETDRK4 N = ', N, ' Ns = ', Ns-1 #q3, x3 = cheb_mde_neumann_dirichlet_etdrk4(W, u0, L, Ns, algo, scheme) lbc = BC('Neumann') rbc = BC('Dirichlet') etdrk4_solver = ETDRK4(L, N, Ns, h=None, lbc=lbc, rbc=rbc) q3, x3 = etdrk4_solver.solve(W, u0) Q3 = 0.5 * L * cheb_quadrature_clencurt(q3) if scheme == 0: #data_name = 'benchmark/NBC-DBC/exact/ETDRK4_Cox_N' data_name = 'ETDRK4_Cox_N' data_name = data_name + str(N) + '_Ns' + str(Ns-1) else: #data_name = 'benchmark/NBC-DBC/exact/ETDRK4_Krogstad_N' data_name = 'ETDRK4_Krogstad_N' data_name = data_name + str(N) + '_Ns' + str(Ns-1) savemat(data_name,{ 'N':N, 'Ns':Ns-1, 'W':W, 'u0':u0, 'Lz':L, 'x':x, 'q':q3, 'Q':Q3}) plt.plot(x3, q3, 'r') plt.axis([0, 10, 0, 1.15]) plt.xlabel('$z$') plt.ylabel('$q(z)$') plt.savefig(data_name, bbox_inches='tight') plt.show()
def build_grid(self): config = self.config Lx = config.grid.Lx self.Lx = Lx La = config.uc.a self.La = La Ms = config.grid.Ms if os.path.exists(config.grid.field_data): mat = loadmat(config.grid.field_data) self.w = mat['w'] else: #self.w = np.zeros([Lx]) self.w = np.random.rand(Lx) self.q = np.zeros((Ms, Lx)) self.q[0, :] = 1. ds = 1. / (Ms - 1) self.ds = ds lbc = BC(self.lbc, self.lbc_vc) rbc = BC(self.rbc, self.rbc_vc) self.q_solver = ETDRK4(La, Lx - 1, Ms, h=ds, lbc=lbc, rbc=rbc) self.lam = config.grid.lam[0]
def build_grid(self): config = self.config Lx = config.grid.Lx self.Lx = Lx L = config.uc.a # in unit of Rg self.L = L / self.z_hat # in unit of \hat{z} N = Lx - 1 self.N = N Ms = config.grid.Ms if os.path.exists(config.grid.field_data): mat = loadmat(config.grid.field_data) self.w = mat['w'] self.w.shape = (self.w.size, ) else: self.w = np.random.rand(Lx) self.q = np.zeros((Ms, Lx)) self.q[0, :] = 1. self.qc = np.zeros((Ms, Lx)) lbc = BC(self.lbc, self.lbc_vc) rbc = BC(self.rbc, self.rbc_vc) h = 1. / (Ms - 1) c = 0.25 / self.beta self.q_solver = ETDRK4(L, N, Ms, h=h, c=c, lbc=lbc, rbc=rbc, algo=1, scheme=1) #self.qc_solver = ETDRK4(L, N, Ms, h=h, c=c, lbc=lbc, rbc=rbc, # algo=1, scheme=1) self.qc_solver = ETDRK4(L, N, Ms - 1, h=h, c=c, lbc=lbc, rbc=rbc, algo=1, scheme=1) # CKE
def test_etdrk4_complex(): ''' The test case is according to R. C. Daileda Lecture notes. du/dt = (1/25) u_xx , x@(0,3) with boundary conditions: u(0,t) = 0 u_x(3,t) = -(1/2) u(3,t) u(x,0) = 100*(1-x/3) Conclusion: We find that the numerical solution is much more accurate than the five term approximation of the exact analytical solution. ''' Nx = 64 Lx = 3 t = 1. Ns = 101 ds = t / (Ns - 1) ii = np.arange(Nx + 1) x = np.cos(np.pi * ii / Nx) # yy [-1, 1] x = 0.5 * (x + 1) * Lx # mapping to [0, Ly] w = np.zeros(Nx + 1, dtype=np.complex128) q = np.zeros([Ns, Nx + 1], dtype=np.complex128) q[0] = 100 * (1 - x / 3) # The approximation of exact solution by first 5 terms q_exact = 47.0449*np.exp(-0.0210*t)*np.sin(0.7249*x) + \ 45.1413*np.exp(-0.1113*t)*np.sin(1.6679*x) + \ 21.3586*np.exp(-0.2872*t)*np.sin(2.6795*x) + \ 19.3403*np.exp(-0.5505*t)*np.sin(3.7098*x) + \ 12.9674*np.exp(-0.9015*t)*np.sin(4.7474*x) lbc = BC(DIRICHLET, [0, 1, 0]) rbc = BC(ROBIN, [1., 0.5, 0]) q_solver = ETDRK4(Lx, Nx, Ns, h=ds, c=1. / 25, lbc=lbc, rbc=rbc) q1, x = q_solver.solve(w, q[0], q) plt.plot(x, q[0].real, label='q_0') plt.plot(x, q1.real, label='q_solution1') plt.plot(x, q[-1].real, label='q_solution2') plt.plot(x, q_exact, label='q_exact') plt.legend(loc='best') plt.show()
def build_grid(self): config = self.config Lx = config.grid.Lx self.Lx = Lx La = config.uc.a self.La = La Ms = config.grid.Ms if os.path.exists(config.grid.field_data): print "Reading from ", config.grid.field_data mat = loadmat(config.grid.field_data) self.w = np.zeros(Lx, dtype=np.complex128) #try: # self.w = mat['iw_avg'][0,:] #except: # self.w.real = mat['w'].reshape(Lx) #y = np.arange(-1, 1, 2.0/Lx) #self.w.real = cheb_interpolation_1d(y, w.real) #self.w.imag = cheb_interpolation_1d(y, w.imag) self.phi = np.zeros(Lx, dtype=np.complex128) try: self.phi.real = mat['phi_avg'][0, :].real except: self.phi.real = mat['phi'][0, :] #self.phi.real = cheb_interpolation_1d(y, phi.real) else: print "Abort: you must provide a density field." exit(1) self.q = np.zeros((Ms, Lx), dtype=np.complex128) self.q[0].real = 1. ds = 1. / (Ms - 1) self.ds = ds lbc = BC(self.lbc, self.lbc_vc) rbc = BC(self.rbc, self.rbc_vc) self.q_solver = ETDRK4(La, Lx - 1, Ms, h=ds, lbc=lbc, rbc=rbc) self.lam = config.grid.lam[0]
def test_speed_space_etdrk4(): ''' The expect complexity for ETDRK4 is O(N^2). However, due to the calculation of matrix exponential, it exceeds O(N^2) for large N. ''' # Construct reference solution oscheb_ref = '../benchmark/exact/OSCHEB_N' oscheb_ref = oscheb_ref + '8192_Ns200000.mat' mat = loadmat(oscheb_ref) q_ref = mat['q'] Q_ref = mat['Q'][0,0] N_ref = mat['N'] Ns_ref = mat['Ns'] L = 10.0 n = 10 # Nmax = 2^n Ns = 200+1 # highest accuracy for reference. h = 1e-4 M_array = np.ones(n-1) # number of same run M_array[0:5] = 1000 # 4, 8, 16, 32, 64 M_array[5] = 500 # 128 M_array[6] = 100 # 256 M_array[7] = 20 # 512 M_array[8] = 5 # 1024 N_array = [] t_full_array = [] t_array = [] err_array = [] i = 0 for N in 2**np.arange(2, n+1): M = int(M_array[i]) W, u0, x = init_chebyshev_fredrikson(N, L) solver = ETDRK4(L, N, Ns) t = clock() for m in xrange(M): q, x = solver.solve(W, u0) t = (clock() - t) / M t_array.append(t) t_full = clock() for m in xrange(M): solver = ETDRK4(L, N, Ns) q, x = solver.solve(W, u0) t_full = (clock() - t_full) / M t_full_array.append(t_full) N_array.append(N) q.shape = (q.size,) Q = 0.5 * L * cheb_quadrature_clencurt(q) err = np.abs(Q - Q_ref) / np.abs(Q_ref) err_array.append(err) print N, '\t', t_full_array[-1], '\t', print t_array[-1], '\t', err_array[-1] i += 1 is_save = 1 is_display = 1 if is_save: savemat('speed_ETDRK4_N',{ 'N':N_array, 'Ns':Ns-1, 'N_ref':N_ref, 'Ns_ref':Ns_ref, 't_full':t_full_array, 't':t_array, 'err':err_array}) if is_display: plt.figure() ax = plt.subplot(111) ax.plot(N_array, t_full_array, '.-', label='Full') ax.plot(N_array, t_array, '.-', label='Core') plt.xscale('log') plt.yscale('log') plt.xlabel('$N$') plt.ylabel('Computer time') plt.grid('on') ax.legend(loc='upper left') if is_save: plt.savefig('speed_ETDRK4_N', bbox_inches='tight') plt.show() plt.figure() ax = plt.subplot(111) ax.plot(err_array, t_array, 'o-') plt.xscale('log') plt.yscale('log') plt.xlabel('Relative error in $Q$') plt.ylabel('Computer time') plt.grid('on') if is_save: plt.savefig('speed_error_ETDRK4_N', bbox_inches='tight') plt.show()
def test_exact_neumann(osc=0,oscheb=0,etdrk4=0): L = 10.0 if osc: N = 128 Ns = 1000 + 1 #20000 + 1 W, u0, x = init_fourier(N, L) print 'OSC N = ', N, ' Ns = ', Ns-1 #q1, x1 = cheb_mde_osc(W, u0, L, Ns) osc_solver = OSC(L, N, Ns) q1, x1 = osc_solver.solve(W, u0) Q1 = L * simps(q1, dx=1./N) #data_name = 'benchmark/NBC-NBC/exact/OSS_N' data_name = 'OSS_N' data_name = data_name + str(N) + '_Ns' + str(Ns-1) savemat(data_name,{ 'N':N, 'Ns':Ns-1, 'W':W, 'u0':u0, 'Lz':L, 'x':x, 'q':q1, 'Q':Q1}) plt.plot(x1, q1, 'b') plt.axis([0, 10, 0, 1.15]) plt.xlabel('$z$') plt.ylabel('$q(z)$') plt.savefig(data_name, bbox_inches='tight') #plt.show() if oscheb: N = 128 Ns = 200 + 1 #20000 + 1 W, u0, x = init_chebyshev_fredrikson(N, L) print 'OSCHEB N = ', N, ' Ns = ', Ns-1 #q2 = cheb_mde_neumann_oscheb(W, u0, L, Ns) oscheb_sovler = OSCHEB(L, N, Ns, bc=BC('Neumann')) q2, x2 = oscheb_sovler.solve(W, u0) Q2 = 0.5 * L * cheb_quadrature_clencurt(q2) #data_name = 'benchmark/NBC-NBC/exact/OSCHEB_N' data_name = 'OSCHEB_N' data_name = data_name + str(N) + '_Ns' + str(Ns-1) savemat(data_name,{ 'N':N, 'Ns':Ns-1, 'W':W, 'u0':u0, 'Lz':L, 'x':x2, 'q':q2, 'Q':Q2}) plt.plot(x2, q2, 'g') plt.axis([0, 10, 0, 1.15]) plt.xlabel('$z$') plt.ylabel('$q(z)$') plt.savefig(data_name, bbox_inches='tight') #plt.show() if etdrk4: N = 128 Ns = 200 + 1 algo = 1 scheme = 1 W, u0, x = init_chebyshev_fredrikson(N, L) print 'ETDRK4 N = ', N, ' Ns = ', Ns-1 #q3, x3 = cheb_mde_neumann_etdrk4(W, u0, L, Ns, None, algo, scheme) lbc = BC('Neumann') rbc = BC('Neumann') etdrk4_solver = ETDRK4(L, N, Ns, h=None, lbc=lbc, rbc=rbc) q3, x3 = etdrk4_solver.solve(W, u0) Q3 = 0.5 * L * cheb_quadrature_clencurt(q3) #if scheme == 0: # data_name = 'benchmark/NBC-NBC/exact/ETDRK4_Cox_N' # data_name = data_name + str(N) + '_Ns' + str(Ns-1) #else: # data_name = 'benchmark/NBC-NBC/exact/ETDRK4_Krogstad_N' # data_name = data_name + str(N) + '_Ns' + str(Ns-1) #savemat(data_name,{ # 'N':N, 'Ns':Ns-1, 'W':W, 'u0':u0, 'Lz':L, # 'x':x, 'q':q3, 'Q':Q3}) plt.plot(x3, q3, 'r') plt.axis([0, 10, 0, 1.15]) plt.xlabel('$z$') plt.ylabel('$q(z)$') #plt.savefig(data_name, bbox_inches='tight') plt.show()
def test_exact_dirichlet(oss=0,oscheb=0,etdrk4=0): L = 10.0 if oss: N = 1024 #4096 Ns = 1000 + 1 #100000 + 1 W, u0, x = init_fourier(N, L) u0[0] = 0.; u0[N] = 0.; print 'OSS N = ', N, ' Ns = ', Ns-1 #q1, x1 = cheb_mde_oss(W, u0, L, Ns) oss_solver = OSS(L, N, Ns) q1, x1 = oss_solver.solve(W, u0) Q1 = L * oss_integral_weights(q1) #data_name = 'benchmark/exact/OSS_N' + str(N) + '_Ns' + str(Ns-1) data_name = 'OSS_N' + str(N) + '_Ns' + str(Ns-1) savemat(data_name,{ 'N':N, 'Ns':Ns-1, 'W':W, 'u0':u0, 'Lz':L, 'x':x, 'q':q1, 'Q':Q1}) plt.plot(x1, q1, 'b') plt.axis([0, 10, 0, 1.15]) #plt.show() if oscheb: N = 128 #16384 Ns = 200 + 1 #1000000 + 1 W, u0, x = init_chebyshev_fredrikson(N, L) u0[0] = 0; u0[N] = 0; print 'OSCHEB N = ', N, ' Ns = ', Ns-1 #q2 = cheb_mde_dirichlet_oscheb(W, u0, L, Ns) oscheb_sovler = OSCHEB(L, N, Ns) q2, x2 = oscheb_sovler.solve(W, u0) Q2 = 0.5 * L * cheb_quadrature_clencurt(q2) #data_name = 'benchmark/exact/OSCHEB_N' + str(N) + '_Ns' + str(Ns-1) data_name = 'OSCHEB_N' + str(N) + '_Ns' + str(Ns-1) savemat(data_name,{ 'N':N, 'Ns':Ns-1, 'W':W, 'u0':u0, 'Lz':L, 'x':x2, 'q':q2, 'Q':Q2}) plt.plot(x2, q2, 'g') plt.axis([0, 10, 0, 1.15]) plt.xlabel('$z$') plt.ylabel('$q(z)$') plt.savefig(data_name, bbox_inches='tight') #plt.show() if etdrk4: N = 128 Ns = 200 + 1 #20000 + 1 algo = 1 scheme = 1 W, u0, x = init_chebyshev_fredrikson(N, L) u0[0] = 0; u0[N] = 0; print 'ETDRK4 N = ', N, ' Ns = ', Ns-1 #q3, x3 = cheb_mde_dirichlet_etdrk4(W, u0, L, Ns, algo, scheme) etdrk4_solver = ETDRK4(L, N, Ns) q3, x3 = etdrk4_solver.solve(W, u0) Q3 = 0.5 * L * cheb_quadrature_clencurt(q3) #data_name = 'benchmark/exact/ETDRK4_N' + str(N) + '_Ns' + str(Ns-1) data_name = 'ETDRK4_N' + str(N) + '_Ns' + str(Ns-1) savemat(data_name,{ 'N':N, 'Ns':Ns-1, 'W':W, 'u0':u0, 'Lz':L, 'x':x, 'q':q3, 'Q':Q3}) plt.plot(x3, q3, 'r') plt.axis([0, 10, 0, 1.15]) plt.xlabel('$z$') plt.ylabel('$q(z)$') plt.savefig(data_name, bbox_inches='tight') plt.show()
def test_etdrk4fxcy(): ''' The test function is u = e^[f(x,y) - t] where f(x,y) = h(x) + g(y) Assume it is the solution of following PDE du/dt = (d^2/dx^2 + d^2/dy^2) u - w(x,y)u in the domain [0,Lx]x[0,Ly] for time t=0 to t=1, with boundary conditions u(x+Lx,y,t) = u(x,y,t) # periodic in x direction d/dy[u(x,y=0,t)] = ka u(y=0) d/dy[u(x,y=Ly,t)] = kb u(y=Ly) To generate a suitable solution, we assume h(x) = sin(x) h_x = dh/dx = cos(x) h_xx = d^2h/dx^2 = -sin(x) since it is periodic in x direction. The corresponding w(x,y) is w(x,y) = h_xx + g_yy + (h_x)^2 + (g_y)^2 + 1 1. For homogeneous NBC (ka=kb=0), a suitable g(y) is g(y) = Ay^2(2y-3)/6 g_y = A(y^2-y) # g_y(y=0)=0, g_y(y=1)=0 g_yy = A(2*y-1) where A is a positive constant. Lx = 2*pi, Ly = 1.0, Nx = 64, Ny =32, Ns = 21 is a good parameter set. Note the time step ds = 1/(Ns-1) = 0.05 is very large. 2. For homogeneous DBC, an approximate g(y) is g(y) = -A(y-1)^2 g_y = -2A(y-1) g_yy = -2A where A is a positive and large constant. Lx = 2*pi, Ly = 2.0, Nx = 64, Ny =32, Ns = 101 is a good parameter set. 3. For RBC, g(y) is given by g(y) = -Ay g_y = -A # ka=kb=-A g_yy = 0 A is a positive constant. Numerical result is different than the analytical one. ''' Lx = 2 * np.pi # x [0, Lx] Nx = 64 Ly = 1.0 # y [0, Ly] Ny = 127 Ns = 101 ds = 1. / (Ns - 1) # Periodic in x direction, Fourier xx = np.arange(Nx) * Lx / Nx # Non-periodic in y direction, Chebyshev ii = np.arange(Ny + 1) yy = np.cos(np.pi * ii / Ny) # yy [-1, 1] yy = 0.5 * (yy + 1) * Ly # mapping to [0, Ly] w = np.zeros([Nx, Ny + 1]) A = 1.0 q = np.zeros([Ns, Nx, Ny + 1]) q_exact = np.zeros([Nx, Ny + 1]) #q[0] = 1. for i in xrange(Nx): for j in xrange(Ny + 1): x = xx[i] y = yy[j] # RBC #q_exact[i,j] = np.exp(-A*y + np.sin(x) - 1) #q[0,i,j] = np.exp(-A*y + np.sin(x)) #w[i,j] = np.cos(x)**2 - np.sin(x) + A**2 + 1 # homogeneous NBC q_exact[i, j] = np.exp(A * y**2 * (2 * y - 3) / 6 + np.sin(x) - 1) q[0, i, j] = np.exp(A * y**2 * (2 * y - 3) / 6 + np.sin(x)) w[i, j] = ( A * y * (y - 1))**2 + np.cos(x)**2 - np.sin(x) + A * (2 * y - 1) + 1 # homogeneous DBC #q[0,i,j] = np.exp(-A*(y-1)**2 + np.sin(x)) #q_exact[i,j] = np.exp(-A*(y-1)**2 + np.sin(x) + 1) #w[i, j] = np.cos(x)**2 - np.sin(x) + 4*A**2 + (2*A*(y-1))**2 + 1 # Fredrickson #sech = 1. / np.cosh(0.25*(6*y[j]-3*Ly)) #w[i,j] = (1 - 2*sech**2)*(np.sin(2*np.pi*x[i]/Lx)+1) #w[i,j] = (1 - 2*sech**2) x = xx y = yy plt.imshow(w) plt.xlabel('w') plt.show() plt.plot(x, w[:, Ny / 2]) plt.xlabel('w(x)') plt.show() plt.plot(y, w[Nx / 4, :]) plt.xlabel('w(y)') plt.show() # DBC #lbc = BC(DIRICHLET, [0.0, 1.0, 0.0]) #rbc = BC(DIRICHLET, [0.0, 1.0, 0.0]) # RBC #lbc = BC(ROBIN, [1.0, A, 0.0]) #rbc = BC(ROBIN, [1.0, A, 0.0]) # NBC lbc = BC(ROBIN, [1.0, 0, 0.0]) rbc = BC(ROBIN, [1.0, 0, 0.0]) #q_solver = ETDRK4FxCy(Lx, Ly, Nx, Ny, Ns, h=ds, lbc=lbc, rbc=rbc) q_solver = ETDRK4FxCy2(Lx, Ly, Nx, Ny, Ns, h=ds, lbc=lbc, rbc=rbc) M = 100 # Took 1117.6 x 4 seconds for cpu one core with Timer() as t: for m in xrange(M): q1 = q_solver.solve(w, q[0], q) print "100 runs took ", t.secs, " seconds." print 'Error =', np.max(np.abs(q1 - q_exact)) plt.imshow(q[0]) plt.xlabel('q_0') plt.show() plt.imshow(q1) plt.xlabel('q_solution') plt.show() plt.imshow(q_exact) plt.xlabel('q_exact') plt.show() plt.plot(x, q[0, :, Ny / 2], label='q0') plt.plot(x, q1[:, Ny / 2], label='q_solution') plt.plot(x, q_exact[:, Ny / 2], label='q_exact') plt.legend(loc='best') plt.xlabel('q[:,Ny/2]') plt.show() plt.plot(y, q[0, Nx / 4, :], label='q0') plt.plot(y, q1[Nx / 4, :], label='q_solution') plt.plot(y, q_exact[Nx / 4, :], label='q_exact') plt.legend(loc='best') plt.xlabel('q[Nx/4,:]') plt.show() plt.plot(y, q[0, Nx * 3 / 4, :], label='q0') plt.plot(y, q1[Nx * 3 / 4, :], label='q_solution') plt.plot(y, q_exact[Nx * 3 / 4, :], label='q_exact') plt.legend(loc='best') plt.xlabel('q[Nx*3/4,:]') plt.show() exit() # Check with ETDRK4 sech = 1. / np.cosh(0.25 * (6 * y - 3 * Ly)) w1 = 1 - 2 * sech**2 plt.plot(y, w1) plt.show() q = np.zeros([Ns, Ny + 1]) q[0] = 1. q_solver = ETDRK4(Ly, Ny, Ns, h=ds, lbc=lbc, rbc=rbc) q1, y = q_solver.solve(w1, q[0], q) plt.plot(y, q1) plt.show()
def test_Ns_dirichlet(): ''' 1 OSS 2 OSCHEB 3 ETDRK4 ''' L = 10 N = 128 Ns1 = 200000 + 1 Ns2 = 200000 + 1 Ns3 = 200000 + 1 method = 2 # 0: OSS, 1: OSCHEB, 2: ETDRK4 algo3 = 1 # 0: circular, 1: hyperbolic, 2: scaling and squaring scheme = 1 data_name = 'benchmark/Ns_convergence/' if method == 0: data_name = data_name + 'OSS/Ns_DBC_N' + str(N) elif method == 1: data_name = data_name + 'OSCHEB/Ns_DBC_N' + str(N) elif method == 2: if scheme == 0: data_name = data_name + 'Cox_Matthews/Ns_DBC_N' + str(N) else: data_name = data_name + 'Krogstad/Ns_DBC_N' + str(N) else: raise ValueError('No such method!') print data_name oscheb_ref = '../benchmark/exact/OSCHEB_N' oscheb_ref = oscheb_ref + '8192_Ns200000.mat' mat = loadmat(oscheb_ref) q2_ref = mat['q'] Q2_ref = mat['Q'][0, 0] N2_ref = mat['N'] Ns2_ref = mat['Ns'] #oss_ref = 'benchmark/exact/OSS_N' #oss_ref = oss_ref + str(N) + '_Ns20000.mat' oss_ref = oscheb_ref mat = loadmat(oss_ref) q1_ref = mat['q'] Q1_ref = mat['Q'][0, 0] N1_ref = mat['N'] Ns1_ref = mat['Ns'] #if scheme == 0: # etdrk4_ref = 'benchmark/exact/CoxMatthews/ETDRK4_N' #elif scheme == 1: # etdrk4_ref = 'benchmark/exact/Krogstad/ETDRK4_N' #else: # raise ValueError('No such scheme!') #etdrk4_ref = etdrk4_ref + str(N) + '_Ns20000.mat' etdrk4_ref = oscheb_ref mat = loadmat(etdrk4_ref) q3_ref = mat['q'] Q3_ref = mat['Q'][0, 0] print Q3_ref.shape N3_ref = mat['N'] Ns3_ref = mat['Ns'] mode = 0 # error mode 0: Q only, 1: q and Q if N1_ref == N and N2_ref.size == N and N3_ref.size == N: mode = 1 print 'OSS' if method == 0: iters = 10 else: iters = 0 errs0_1 = [] errs1_1 = [] Qs1 = [] Nss1 = [] W1, u0, x = init_fourier(N, L) u0[0] = 0. u0[-1] = 0. ns_max = int(np.log10((Ns1 - 1) / 2)) # Ns_max = 10^{ns_max} for Ns in np.power(10, np.linspace(0, ns_max, iters)).astype(int) + 1: q1, x1 = cheb_mde_oss(W1, u0, L, Ns) Q1 = L * oss_integral_weights(q1) Qs1.append(Q1) if mode: err1 = np.max(np.abs(q1 - q1_ref)) / np.max(q1_ref) errs0_1.append(err1) err1 = np.abs(Q1 - Q1_ref) / np.abs(Q1_ref) errs1_1.append(err1) Nss1.append(1. / (Ns - 1)) print Ns - 1, '\t', err1 print 'OSCHEB' if method == 1: iters = 10 else: iters = 0 errs0_2 = [] errs1_2 = [] Qs2 = [] Nss2 = [] W2, u0, x = init_chebyshev_fredrikson(N, L) u0[0] = 0. u0[-1] = 0. ns_max = int(np.log10((Ns2 - 1) / 2)) # Ns_max = 10^{ns_max} for Ns in np.power(10, np.linspace(0, ns_max, iters)).astype(int) + 1: q2 = cheb_mde_dirichlet_oscheb(W2, u0, L, Ns) Q2 = 0.5 * L * cheb_quadrature_clencurt(q2) Qs2.append(Q2) if mode: err2 = np.max(np.abs(q2 - q2_ref)) / np.max(q2_ref) errs0_2.append(err2) err2 = np.abs(Q2 - Q2_ref) / np.abs(Q2_ref) errs1_2.append(err2) Nss2.append(1. / (Ns - 1)) print Ns - 1, '\t', err2 if scheme == 0: print 'ETDRK4-Cox-Matthews' else: print 'ETDRK4-Krogstad', 'N =', N if method == 2: iters = 10 else: iters = 0 errs0_3 = [] errs1_3 = [] Qs3 = [] Nss3 = [] W3, u0, x = init_chebyshev_fredrikson(N, L) u0[0] = 0. u0[-1] = 0. ns_max = int(np.log10((Ns3 - 1) / 2)) # Ns_max = 10^{ns_max} for Ns in np.power(10, np.linspace(0, ns_max, iters)).astype(int) + 1: #q3, x3 = cheb_mde_dirichlet_etdrk4(W3, u0, L, Ns, # None, None, algo3, scheme) solver = ETDRK4(L, N, Ns) q3, x3 = solver.solve(W3, u0) q3.shape = (q3.size, ) Q3 = 0.5 * L * cheb_quadrature_clencurt(q3) Qs3.append(Q3) if mode: err3 = np.max(np.abs(q3 - q3_ref)) / np.max(q3_ref) errs0_3.append(err3) err3 = np.abs(Q3 - Q3_ref) / np.abs(Q3_ref) errs1_3.append(err3) Nss3.append(1. / (Ns - 1)) print Ns - 1, '\t', err3, '\t', Q3_ref savemat( data_name, { 'N_ref1': N1_ref, 'N_ref2': N2_ref, 'N_ref3': N3_ref, 'N': N, 'Ns1_ref': Ns1_ref, 'Ns2_ref': Ns2_ref, 'Ns3_ref': Ns3_ref, 'Algorithm1': 'OSS', 'Algorithm2': 'OSCHEB', 'Algorithm3': 'ETDRK4', 'Q1_ref': Q1_ref, 'Q2_ref': Q2_ref, 'Q3_ref': Q3_ref, 'Q1': Qs1, 'Q2': Qs2, 'Q3': Qs3, 'Ns0_1': Nss1, 'err0_1': errs0_1, 'Ns1_1': Nss1, 'err1_1': errs1_1, 'Ns0_2': Nss2, 'err0_2': errs0_2, 'Ns1_2': Nss2, 'err1_2': errs1_2, 'Ns0_3': Nss3, 'err0_3': errs0_3, 'Ns1_3': Nss3, 'err1_3': errs1_3 }) if mode: plt.plot(Nss1, errs0_1, 'bo-', label='OSS') plt.plot(Nss2, errs0_2, 'go-', label='OSCHEB') plt.plot(Nss3, errs0_3, 'ro-', label='ETDRK4') plt.xscale('log') plt.yscale('log') plt.xlabel('$\Delta s$') plt.ylabel('Relative Error at s=1') handles, labels = plt.gca().get_legend_handles_labels() plt.legend(handles, labels, loc='lower right') plt.grid('on') plt.show() plt.plot(Nss1, errs1_1, 'bo-', label='OSS') plt.plot(Nss2, errs1_2, 'go-', label='OSCHEB') plt.plot(Nss3, errs1_3, 'ro-', label='ETDRK4') plt.xscale('log') plt.yscale('log') plt.xlabel('$\Delta s$') plt.ylabel('Relative Error at s=1') handles, labels = plt.gca().get_legend_handles_labels() plt.legend(handles, labels, loc='lower right') plt.grid('on') plt.savefig(data_name, bbox_inches='tight') plt.show()