Commit 74161976 by Lars Stietz

### cleaning up code and creating plots

parent 45ab9b6c
 ... ... @@ -4,14 +4,23 @@ from copy import deepcopy def woSubstitute(u_0, Q, F): sz = Q[1:, 1:].shape[1] """ Parameters: u_0 (numpy.ndarray) : vector of initial values Q (numpy.ndarray) : matrix with quadrature weights (node to node) F (numpy.ndarray) : matrix assembling the source term of ODE Returns: X (num """ I = np.eye(len(u_0)) sol = la.solve(I-Q@F, u_0) sol = la.solve(I - Q @ F, u_0) X, V = np.split(sol, 2) return X, V def wSubstitute(u_0, Q, k): def wSubstitute(u_0, Q, k, f): sz = Q[1:, 1:].shape[1] x_0, v_0 = np.split(u_0, 2) X = la.solve(np.eye(sz) + k * np.linalg.matrix_power(Q[1:, 1:], 2), x_0 + Q[1:, 1:] @ v_0) ... ... @@ -43,48 +52,42 @@ def leapFrogSweep(x_0, v_0, dt, f): return X[1:], V[1:] def secondOrderSDCsweep(x,v,dt,S,f): def secondOrderSDCsweep(x, v, dt, S, f): x_old = deepcopy(x) v_old = deepcopy(v) for m in range(1,len(dt)): x[m] = x[m-1] + dt[m]*(v[m-1]-v_old[m-1]) + 0.5*(dt[m]**2)*(f(x[m-1])-f(x_old[m-1])) + S[m+1,1:]@v_old v[m] = v[m-1] + 0.5*dt[m]*(f(x[m-1])+f(x[m])) - 0.5*dt[m]*((f(x_old[m-1])+f(x_old[m]))) + S[m+1,1:]@f(x_old) for m in range(1, len(dt)): x[m] = x[m - 1] + dt[m] * (v[m - 1] - v_old[m - 1]) + 0.5 * (dt[m] ** 2) * (f(x[m - 1]) - f(x_old[m - 1])) \ + S[m + 1, 1:] @ v_old v[m] = v[m - 1] + 0.5 * dt[m] * (f(x[m - 1]) + f(x[m])) - 0.5 * dt[m] * ((f(x_old[m - 1]) + f(x_old[m]))) \ + S[m + 1, 1:] @ f(x_old) return x,v return x, v def secondOrderSDCsweep_opt(x, v, U_0, Qdelta, Q, k): def secondOrderSDCsweep_opt(x, v, Qdelta, Q, k): x_old = deepcopy(x) v_old = deepcopy(v) sz = len(x_old) for m in range(1, sz): x[m] = x[0] + np.dot(Qdelta[m, :m], (v[:m]-v_old[:m])) - k*np.dot(Qdelta[m, sz:sz+m], (x[:m]-x_old[:m])) + np.dot(Q[m, :], v_old) v[m] = v[0] - k*np.dot(Qdelta[m+1, sz:], x) + k*np.dot(Qdelta[m, sz:], x_old)-k*np.dot(Q[m, :], x_old) x[m] = x[0] + np.dot(Qdelta[m, :m], (v[:m] - v_old[:m])) - k * np.dot(Qdelta[m, sz:sz + m], (x[:m] - x_old[:m])) \ + np.dot(Q[m, :], v_old) v[m] = v[0] - k * np.dot(Qdelta[m + 1, sz:], x) + k * np.dot(Qdelta[m, sz:], x_old) - k * np.dot(Q[m, :], x_old) return x, v def asmFmat(k,num_nodes): F = np.block([[np.zeros([num_nodes,num_nodes]),np.eye(num_nodes)],[-k*np.eye(num_nodes),np.zeros([num_nodes,num_nodes])]]) def asmFmat(k, num_nodes): F = np.block([[np.zeros([num_nodes, num_nodes]), np.eye(num_nodes)], [-k * np.eye(num_nodes), np.zeros([num_nodes, num_nodes])]]) return F def FU(U): fu = F@U return fu def secondOrderMat(X, V, U_0, Qdelta, Q, k): x_old = deepcopy(X) U = np.concatenate([X, V]) I = np.eye(len(U)) F = asmFmat(k, int(0.5*len(U))) Uout = np.linalg.solve(I-Qdelta@F, U_0) + U - np.linalg.solve(I-Qdelta@F, (I-Q@F)@U) X,V = np.split(Uout, 2) return X,V F = asmFmat(k, int(0.5 * len(U))) Uout = np.linalg.solve(I - Qdelta @ F, U_0) + U - np.linalg.solve(I - Qdelta @ F, (I - Q @ F) @ U) X, V = np.split(Uout, 2) return X, V
 import numpy as np import scipy.linalg as la import matplotlib.pyplot as plt #import matplotlib.gridspec as gridspec # import matplotlib.gridspec as gridspec from gauss_lobatto import CollGaussLobatto import SDCsecondOrder as SDC from MatrixSDC import MatrixSDC as mat ... ... @@ -10,40 +10,50 @@ import optimise_qdelta as opt '''Initialize Problem''' ################################################################################################################## k = 1 k = 1 # ODE parameter omega = np.sqrt(k) x_0 = 1 v_0 = 0 t_start = 0.0 t_end = 0.5 x_0 = 1 # start position v_0 = 0 # start velocity t_start = 0.0 # starting time t_end = 0.5 # end time # dx/dt = v # dv/dt = f(x) def f(x): return -k*x return -k * x # source term of ODE ################################################################################################################## '''Analytical solution''' ################################################################################################################## def x(t): return x_0*np.cos(omega*t)+v_0/omega*np.sin(omega*t) return x_0 * np.cos(omega * t) + v_0 / omega * np.sin(omega * t) def v(t): return -omega*x_0*np.sin(omega*t)+v_0*np.cos(omega*t) return -omega * x_0 * np.sin(omega * t) + v_0 * np.cos(omega * t) ################################################################################################################## '''SDC''' ################################################################################################################## num_tsteps = 2 num_nodes = 3 #optim only tested for three nodes num_nodes = 3 # optim only tested for three nodes iter = 10 aim = "norm" plot = 1 x_error = np.empty(0) v_error = np.empty(0) #delta_t = np.empty(0) # delta_t = np.empty(0) subinterval = np.linspace(t_start, t_end, num_tsteps) #delta_t = (t_end - t_start) / num_tsteps # delta_t = (t_end - t_start) / num_tsteps it_steps = np.zeros(num_tsteps, dtype=int) sol_x = np.empty(0) ... ... @@ -64,90 +74,90 @@ Q_delta = matrices.Qdelta opt_Qdelta, opt_val = opt.get_optimal_qdelta(Q, Q_delta, F, aim) for i in range(num_tsteps - 1): coll = CollGaussLobatto(num_nodes, subinterval[i], subinterval[i + 1]) nodes = np.concatenate([nodes, coll.nodes]) # eq sytem x'=v, v'=f(x)=-kx # initial values initial_val = np.block([x_0 * np.ones(num_nodes), v_0 * np.ones(num_nodes)]) X_0, V_0 = SDC.woSubstitute(initial_val, Q, F) U_0 = deepcopy(np.concatenate([X_0, V_0])) Xold = deepcopy(X_0) Vold = deepcopy(V_0) Xoldopt = deepcopy(X_0) Voldopt = deepcopy(V_0) res = 1 it = 0 while res > 1e-15 and it < 15: #X, V = SDC.secondOrderSDCsweep(Xold, Vold, coll.delta_m, coll.Smat, f) X, V = SDC.secondOrderSDCsweep_opt(Xold, Vold, Q_delta, coll.Qmat[1:,1:], k) #X, V = SDC.secondOrderMat(Xold, Vold, initial_val, matrices.Qdelta, matrices.Qmat, k) Xopt, Vopt = SDC.secondOrderSDCsweep_opt(Xoldopt, Voldopt, opt_Qdelta, coll.Qmat[1:, 1:], k) Xold = deepcopy(X) Vold = deepcopy(V) Xoldopt = deepcopy(Xopt) Voldopt = deepcopy(Vopt) res_x_inner = X_0 + coll.Qmat[1:, 1:] @ V - X res_norm_x = np.append(res_norm_x, la.norm(res_x_inner, np.inf)) res_x_opt = X_0 + coll.Qmat[1:, 1:] @ Vopt - Xopt res_norm_opt = np.append(res_norm_opt, la.norm(res_x_opt, np.inf)) res = la.norm(res_x_opt, np.inf) it = it + 1 it_steps[i + 1] = it sol_x = np.append(sol_x, X) sol_v = np.append(sol_v, V) sol_x_opt = np.append(sol_x_opt, Xopt) sol_v_opt = np.append(sol_v_opt, Vopt) res_x = X_0 + coll.Qmat[1:, 1:] @ V - X res_x_opt = V_0 + coll.Qmat[1:, 1:] @ f(X) - V res_it_x = np.append(res_it_x, res_x) res_it_x_opt = np.append(res_it_x_opt, res_x_opt) x_0 = sol_x[-1] v_0 = sol_v[-1] coll = CollGaussLobatto(num_nodes, subinterval[i], subinterval[i + 1]) nodes = np.concatenate([nodes, coll.nodes]) # eq sytem x'=v, v'=f(x)=-kx # initial values initial_val = np.block([x_0 * np.ones(num_nodes), v_0 * np.ones(num_nodes)]) X_0, V_0 = SDC.woSubstitute(initial_val, Q, F) U_0 = deepcopy(np.concatenate([X_0, V_0])) Xold = deepcopy(X_0) Vold = deepcopy(V_0) Xoldopt = deepcopy(X_0) Voldopt = deepcopy(V_0) res = 1 it = 0 while res > 1e-15 and it < 15: # X, V = SDC.secondOrderSDCsweep(Xold, Vold, coll.delta_m, coll.Smat, f) X, V = SDC.secondOrderSDCsweep_opt(Xold, Vold, Q_delta, coll.Qmat[1:, 1:], k) # X, V = SDC.secondOrderMat(Xold, Vold, initial_val, matrices.Qdelta, matrices.Qmat, k) Xopt, Vopt = SDC.secondOrderSDCsweep_opt(Xoldopt, Voldopt, opt_Qdelta, coll.Qmat[1:, 1:], k) Xold = deepcopy(X) Vold = deepcopy(V) Xoldopt = deepcopy(Xopt) Voldopt = deepcopy(Vopt) res_x_inner = X_0 + coll.Qmat[1:, 1:] @ V - X res_norm_x = np.append(res_norm_x, la.norm(res_x_inner, np.inf)) res_x_opt = X_0 + coll.Qmat[1:, 1:] @ Vopt - Xopt res_norm_opt = np.append(res_norm_opt, la.norm(res_x_opt, np.inf)) res = la.norm(res_x_opt, np.inf) it = it + 1 it_steps[i + 1] = it sol_x = np.append(sol_x, X) sol_v = np.append(sol_v, V) sol_x_opt = np.append(sol_x_opt, Xopt) sol_v_opt = np.append(sol_v_opt, Vopt) res_x = X_0 + coll.Qmat[1:, 1:] @ V - X res_x_opt = V_0 + coll.Qmat[1:, 1:] @ f(X) - V res_it_x = np.append(res_it_x, res_x) res_it_x_opt = np.append(res_it_x_opt, res_x_opt) x_0 = sol_x[-1] v_0 = sol_v[-1] kin_Energy = 0.5 * np.square(sol_v) + 0.5 * omega ** 2 * np.square(sol_x) x_error = np.append(x_error, la.norm(x(nodes) - sol_x) / la.norm(sol_x)) v_error = np.append(v_error,la.norm(v(nodes)-sol_v)/la.norm(sol_v)) v_error = np.append(v_error, la.norm(v(nodes) - sol_v) / la.norm(sol_v)) if plot: px = 1 / plt.rcParams['figure.dpi'] fig = plt.figure(figsize=(1.5 * 720 * px, 1.5 * 450 * px)) gs = fig.add_gridspec(3, 8) ax1 = fig.add_subplot(gs[:, :3], aspect=1) ax2 = fig.add_subplot(gs[0:1, 4:]) fax = fig.add_subplot(gs[2, 4:]) ax1.plot(sol_x_opt, sol_v_opt) ax1.set_title("SDC solution with optimisation wrt %s" % aim) ax1.set_ylabel("v(t)") ax1.set_xlabel("x(t)") ax2.semilogy(nodes, abs(res_it_x), label="Res of x(t)") ax2.semilogy(nodes, abs(res_it_x_opt), label="Res of x(t) optimised") ax2.set_title("Residual") ax2.set_xlabel("t") ax2.legend(loc="upper center") fax.semilogy(res_norm_opt, label="Optimised Residual") fax.semilogy(res_norm_x, label="Standard Residual") # fax.set_ylim(0.49, 0.51) fax.set_ylabel(r"$\|res\|$", usetex=True) fax.set_xlabel("#iter") fax.set_title("Residual norm after each iteration") fax.legend() plt.figure() plt.semilogy(res_norm_opt, label="Optimised Residual") plt.semilogy(res_norm_x, label="Standard Residual") # fax. set_ylim(0.49, 0.51) plt.ylabel(r"$\|res\|$", usetex=True) plt.xlabel("#iter") plt.title("Residual norm after each iteration for one timestep") plt.legend() plt.tight_layout() plt.show() \ No newline at end of file px = 1 / plt.rcParams['figure.dpi'] fig = plt.figure(figsize=(1.5 * 720 * px, 1.5 * 450 * px)) gs = fig.add_gridspec(3, 8) ax1 = fig.add_subplot(gs[:, :3], aspect=1) ax2 = fig.add_subplot(gs[0:1, 4:]) fax = fig.add_subplot(gs[2, 4:]) ax1.plot(sol_x_opt, sol_v_opt) ax1.set_title("SDC solution with optimisation wrt %s" % aim) ax1.set_ylabel("v(t)") ax1.set_xlabel("x(t)") ax2.semilogy(nodes, abs(res_it_x), label="Res of x(t)") ax2.semilogy(nodes, abs(res_it_x_opt), label="Res of x(t) optimised") ax2.set_title("Residual") ax2.set_xlabel("t") ax2.legend(loc="upper center") fax.semilogy(res_norm_opt, label="Optimised Residual") fax.semilogy(res_norm_x, label="Standard Residual") # fax.set_ylim(0.49, 0.51) fax.set_ylabel(r"$\|res\|$", usetex=True) fax.set_xlabel("#iter") fax.set_title("Residual norm after each iteration") fax.legend() plt.figure() plt.semilogy(res_norm_opt, label="Optimised Residual") plt.semilogy(res_norm_x, label="Standard Residual") # fax. set_ylim(0.49, 0.51) plt.ylabel(r"$\|res\|$", usetex=True) plt.xlabel("#iter") plt.title("Residual norm after each iteration for one timestep") plt.legend() plt.tight_layout() plt.show()
 ... ... @@ -18,8 +18,9 @@ matrices = mat(coll.delta_m, coll.Qmat[1:, 1:]) F = SDC.asmFmat(1, num_nodes) Q = matrices.Qmat Q_delta = matrices.Qdelta aim = "norm" opt_Qdelta,norm_val_opt = opt.get_optimal_qdelta(Q, Q_delta, F, "norm") opt_Qdelta, norm_val_opt = opt.get_optimal_qdelta(Q, Q_delta, F, "norm") norm_k = np.zeros(len(k)) norm_mat = np.zeros(len(k)) ... ... @@ -37,5 +38,6 @@ ax3.set_xlabel('k') ax3.set_ylabel('$\|.\|$') fig2.legend() ax3.set_title('Iteration Matrix Properties') plt.savefig("aim_{}.pdf".format(aim)) plt.show()
 ... ... @@ -34,12 +34,9 @@ def v(t): ################################################################################################################## num_tsteps = 10 num_nodes = 3 #optim only tested for three nodes iter = 10 aim = "norm" plot = 1 x_error = np.empty(0) v_error = np.empty(0) #delta_t = np.empty(0) subinterval = np.linspace(t_start, t_end, num_tsteps) ... ... @@ -72,8 +69,8 @@ spec_opt_Qdelta, spec_opt_val = opt.get_optimal_qdelta(Q, Q_delta, F, "spec") spec_opt_norm = la.norm(I-la.inv(I-spec_opt_Qdelta@F)@(I-Q@F),np.inf) norm_opt_Qdelta, norm_opt_val = opt.get_optimal_qdelta(Q, Q_delta, F, "norm") norm_opt_spec = max(abs(la.eigvals(I-la.inv(I-norm_opt_Qdelta@F)@(I-Q@F)))) rowname = [r"$\rho(E)$", r"$\| E \|$"] colname = ["Without optimisation", r"Optimised wrt $\rho(E)$", r"Optimised wrt $\| E \|$"] rowname = [r"$\rho(\mathbf{E})$", r"$\Vert \mathbf{E} \Vert$"] colname = ["Without optimization", r"Optimized with $C_\mathrm{spec}$", r"Optimized with $C_\mathrm{norm}$"] cell_data =[[spec_val, spec_opt_val, norm_opt_spec], [norm_val, spec_opt_norm, norm_opt_val]] X_0 = np.ones(num_nodes) * x_0 ... ... @@ -118,7 +115,6 @@ for i in range(num_tsteps - 1): res_norm_norm = np.append(res_norm_norm, la.norm(res_x_norm, np.inf)) res = la.norm(res_x_spec, np.inf) it = it + 1 print(it) it_steps[i + 1] = it sol_x = np.append(sol_x, X) ... ... @@ -129,8 +125,8 @@ for i in range(num_tsteps - 1): sol_v_norm = np.append(sol_v_norm, Vnorm) res_x = X_0 + coll.Qmat[1:, 1:] @ V - X res_x_spec = X_0 + coll.Qmat[1:, 1:] @ Vspec - Xspec res_x_norm = X_0 + coll.Qmat[1:, 1:] @ Vnorm - Xnorm res_x_spec = X_0_spec + coll.Qmat[1:, 1:] @ Vspec - Xspec res_x_norm = X_0_norm + coll.Qmat[1:, 1:] @ Vnorm - Xnorm res_it_x = np.append(res_it_x, res_x) res_it_x_spec = np.append(res_it_x_spec, res_x_spec) res_it_x_norm = np.append(res_it_x_norm, res_x_norm) ... ... @@ -173,50 +169,60 @@ if plot: fax = fig.add_subplot(gs[2, 4:]) ax1.plot(sol_x_spec, sol_v_spec) ax1.set_title(r"SDC solution with optimisation wrt $\rho(E)$", usetex = True) #ax1.set_title(r"SDC solution with optimisation wrt $\rho(E)$", usetex = True) ax1.set_ylabel("v(t)") ax1.set_xlabel("x(t)") #plt.savefig("solution_k-{}.pdf".format(k)) ax2.semilogy(nodes, abs(res_it_x), label="Res of x(t)") ax2.semilogy(nodes, abs(res_it_x_spec), label=r"Res of x(t) optimised wrt $\rho(E)$") ax2.semilogy(nodes, abs(res_it_x_norm), label=r"Res of x(t) optimised wrt $\|E\|$") ax2.set_title("Residual") ax2.semilogy(nodes, abs(res_it_x_spec), label=r"Res of x(t) optimized wrt $\rho(E)$") ax2.semilogy(nodes, abs(res_it_x_norm), label=r"Res of x(t) optimized wrt $\Vert E \Vert$") #ax2.set_title("Residual") ax2.set_xlabel("t") ax2.legend(loc="upper center") fax.semilogy(res_norm_x, label="Standard Residual") fax.semilogy(res_norm_spec, label=r"wrt $\rho(E)$ optimised") fax.semilogy(res_norm_norm, label=r"wrt $\|E\|$ optimised") fax.semilogy(res_norm_spec, label=r"wrt $\rho(E)$ optimized") fax.semilogy(res_norm_norm, label=r"wrt $\Vert E \Vert$ optimized") # fax.set_ylim(0.49, 0.51) fax.set_ylabel(r"$|\mathrm{res}|$", usetex=True) fax.set_xlabel("#iter") fax.set_title("Residual norm after each iteration") #fax.set_title("Residual norm after each iteration") fax.legend() #plt.savefig('k-{}_tsteps-{}.pdf'.format(k, num_tsteps)) plt.figure() plt.semilogy(res_norm_x[it_steps[0]:(it_steps[1] + it_steps[2])], label="Standard Residual") plt.semilogy(res_norm_spec[it_steps[0]:(it_steps[1] + it_steps[2])], label=r"Optimised Residual wrt $\rho(E)$") plt.semilogy(res_norm_norm[it_steps[0]:(it_steps[1] + it_steps[2])], label=r"Optimised Residual wrt $\| \mathrm{E} \|$") #plt.semilogy(np.power(spec_opt_val, np.tile(range(0,it_steps[1]),2)), label = "spec(E)^k") #plt.semilogy(np.power(norm_opt_val, np.tile(range(0, it_steps[1]), 2)), label="norm(E)^k") # fax. set_ylim(0.49, 0.51) plt.ylabel(r"$| \mathrm{res} |$", usetex=True) #plt.xlabel("#iter") plt.title("Residual norm after each iteration for two timesteps") plt.semilogy(res_norm_x[it_steps[0]:(it_steps[1] + it_steps[2])], label="no optimization") plt.semilogy(res_norm_spec[it_steps[0]:(it_steps[1] + it_steps[2])], label=r" $C_\mathrm{spec}$") plt.semilogy(res_norm_norm[it_steps[0]:(it_steps[1] + it_steps[2])], label=r"$C_\mathrm{norm}$") plt.ylabel(r"$\Vert \textbf{R}_{x} \Vert$", usetex=True) plt.xlabel("#iterations") #plt.title("Residual norm after each iteration for two timesteps") plt.legend() plt.xticks([]) the_table = plt.table(cellText=cell_data, rowLabels=rowname, colLabels=colname, loc='bottom') rowLabels=rowname, colLabels=colname, loc='top') plt.tight_layout() plt.savefig('res_k-{}_tsteps-{}.pdf'.format(k, num_tsteps)) plt.figure() plt.plot(nodes,kin_Energy, label = "standard") plt.plot(nodes, kin_Energy_spec, '--', label = "spec opt") plt.plot(nodes, kin_Energy_norm, label = "norm opt") plt.ylabel("total energy") plt.plot(nodes, kin_Energy, label="no optimization") plt.plot(nodes, kin_Energy_spec, '--', label =r" $C_\mathrm{spec}$") plt.plot(nodes, kin_Energy_norm, label =r"$C_\mathrm{norm}$") plt.ylabel(r"$E(t)$") plt.xlabel("time [t]") plt.title("Total energy calculated by different SDC optimized iterations") #plt.title("Total energy calculated by different SDC optimized iterations") plt.legend() plt.show() \ No newline at end of file plt.savefig('energy_k-{}_tsteps-{}.pdf'.format(k, num_tsteps)) plt.show() plt.axes().set_aspect('equal') plt.plot(sol_x_spec, sol_v_spec) # ax1.set_title(r"SDC solution with optimisation wrt $\rho(E)$", usetex = True) plt.ylabel("v(t)") plt.xlabel("x(t)") #plt.savefig("solution_k-{}.pdf".format(k)) \ No newline at end of file