def Simulated_Annealing(a_search_space, b_search_space, func, t): scale = np.sqrt(t) a_init = np.random.choice(a_search_space) b_init = np.random.choice(b_search_space) a = a_init b = b_init cur = func(a, b) a_history = [a] b_history = [b] iterations = 2000 for i in range(iterations): prop_a = int(a + np.random.normal() * scale) prop_b = int(b + np.random.normal() * scale) if (prop_a >= -60 and prop_a <= 60 and prop_b >= -30 and prop_b <= 70): new_out = func(prop_a, prop_b) diff = new_out - cur if diff < 0 or np.exp(-diff / (k * t)) > np.random.rand(): #time.sleep(1) a = prop_a b = prop_b cur = func(a, b) a_history.append(a) b_history.append(b) t = 0.9 * t return a, b, round(func(a, b), 4), len(a_history)
def Nesterov_3_qv(x, epoch=100, epoch_N_G=100, h_N_G=0.001): L = func(x) f_line = [] for i in range(epoch): f = func(x) F = function(x) jac = jacobian(function, x)[:, 0] # print('x : {}'.format(x)) # print('f : {}'.format(f)) # print('jac : {}'.format(jac)) # print('hes : {}'.format(hes)) x_k = torch.zeros_like(x) x_k.copy_(x) x_k = x_k.view(3, 1) func_Nes = lambda y: 1 / (2 * f) * (f**2 + ( (F + jac.mm(y - x_k))**2).sum()) + L / 2 * ((y - x_k)**2).sum() # print('1 : {} {}'.format(x_k, func_Nes(x_k))) # print('2 : {} {}'.format(x, func_Nes(x))) x, _ = Newton_for_Nesterov(x, func_Nes, epoch=epoch_N_G, h=h_N_G) # print('3 : {} {}'.format(x_k, func_Nes(x_k))) # print('4 : {} {}'.format(x, func_Nes(x))) print(x, end='\r') f_line.append(f) return x, f_line
def BruteForce(xmin, xmax, ymin, ymax): min = 1000000.0 count = 0 for x in range(xmin, xmax + 1): for y in range(ymin, ymax + 1): if func(x, y) < min: min = func(x, y) count = count + 1 return min, count
def Brute_force(): max = 10000 for a in range(int(x[0]), int(x[1])): for b in range(int(y[0]), int(y[1])): if (func(a, b) < max): max = func(a, b) ans_a = a ans_b = b return ans_a, ans_b, round(func(ans_a, ans_b), 4)
def mod_Newton(x, epoch=1000, epoch_N_G=100, h_N_G=0.001): L = func(x) n = x.shape[0] E = torch.eye(n, n, dtype=torch.float32) f_line = [func(x)] for i in range(epoch): F = function(x) F_T = F.transpose(0, 1) jac = jacobian(function, x)[:, 0] jac_T = jac.transpose(0, 1) # print(F) # print() # print(F_T) # print() # print(jac) # print() # print(jac_T) # print() l = torch.tensor(1, dtype=torch.float32) def func_Nes(l): A = (E * l + jac.mm(jac_T) / L).inverse() return l / 2 + (A.mm(F) * F).sum() / 2 l, line = Newton_for_Newton(l, func_Nes, epoch=epoch_N_G, h=h_N_G) # return line #print(l, end='\r') # lambda для двойственной задачи B = (E * l + jac.mm(jac_T) / L).inverse() h = -1 / L * jac_T.mm(B).mm(F)[:, 0] # print(B) # print() # print(jac_T) # print() # print(F) # print() # print(h, end='\r') # print() print(x, end='\r') x += h f_line.append(func(x)) return x, f_line
def BF(rX1, rX2, rY1, rY2): BFmin = func(rX1, rY1) runtimes = 0 for x in range(rX1, rX2+1): for y in range(rY1, rY2+1): runtimes+=1 if BFmin > func(x, y): BFmin = func(x, y) roundBF = round(BFmin,3) print("%.3f"%roundBF, " times: ", runtimes) exportOutput(roundBF) return
def getfunc(point): global xmin, xmax, ymin, ymax val = func(point[0], point[1]) if point[0] > xmax or point[1] > ymax or point[0] < xmin or point[1] < ymin: return 1000000.0 else: return val
def hill_climbing(x, y, t, step): # count execution of func() count_func = 0 z_min = func(x, y) count_func += 1 while True: now_z_min = z_min # for check whether break the loop # climb left if x-step >= t.x_min: z = func(x-step, y) count_func += 1 if z < z_min: x = x-step z_min = z # climb right if x+step <= t.x_max: z = func(x+step, y) count_func += 1 if z < z_min: x = x+step z_min = z # climb up if y+step <= t.y_max: z = func(x, y+step) count_func += 1 if z < z_min: y = y+step z_min = z # climb down if y-step >= t.y_min: z = func(x, y-step) count_func += 1 if z < z_min: y = y-step z_min = z if now_z_min == z_min: break return z_min, count_func
def ex0(a, b, c): ack = -1 if b >= a: x_ = np.arange(a, b, c) plt.figure(update_figure_number()) plt.title('Ex 1') plt.plot(x_, fn.func(x_)) ack = 0 return ack
def hillClimbing(rangeX, rangeY, point, stepSize): print("Hill Climbing with", str(point)) [x, y] = point [rangeXMin, rangeXMax] = sorted(rangeX) [rangeYMin, rangeYMax] = sorted(rangeY) min = func(x, y) callFuncCount = 0 # For Q2 in report while (x >= rangeXMin and x <= rangeXMax and y >= rangeYMin and y <= rangeYMax): nextStepList = [] # For storing up, down, left, right directions z value & next point, using this to find the smallest value # Up if (y + stepSize <= rangeYMax): z = func(x, y + stepSize) callFuncCount += 1 # For Q2 in report if(z < min): nextStepList.append([z, x, y + stepSize]) # Down if (y - stepSize >= rangeYMin): z = func(x, y - stepSize) callFuncCount += 1 # For Q2 in report if(z < min): nextStepList.append([z, x, y - stepSize]) # Left if (x - stepSize >= rangeXMin): z = func(x - stepSize, y) callFuncCount += 1 # For Q2 in report if(z < min): nextStepList.append([z, x - stepSize, y]) # Right if (x + stepSize <= rangeXMax): z = func(x + stepSize, y) callFuncCount += 1 # For Q2 in report if(z < min): nextStepList.append([z, x + stepSize, y]) # If there's no next point's z smaller than current point, break the while loop if(len(nextStepList) == 0): break # Sort list in ascend nextStepList = sorted(nextStepList, key=lambda list: list[0]) min = nextStepList[0][0] x = nextStepList[0][1] y = nextStepList[0][2] print("Count of calling func in hill climbing: ", callFuncCount,"/","{0:.3f}".format(round(min, 3))) return "{0:.3f}".format(round(min, 3)) + "\n"
def hill_climbing(x_range, y_range, initial_point): step_size = 1 # may change into different value to get other answer iteration = 0 [x, y] = initial_point z = func(x, y) while x in range(min(x_range), max(x_range) + 1) and y in range(min(y_range), max(y_range) + 1): next = [float('inf'), float('inf'), float('inf'), float('inf')] if (x + step_size) <= max(x_range): iteration += 1 next[0] = func(x + step_size, y) if (x - step_size) >= min(x_range): iteration += 1 next[1] = func(x - step_size, y) if (y + step_size) <= max(y_range): iteration += 1 next[2] = func(x, y + step_size) if (y - step_size) >= min(y_range): iteration += 1 next[3] = func(x, y - step_size) # if there is any step that makes z smaller, take that step if z > min(next): z = min(next) # find which direction is smaller if next.index(min(next)) is 0: x += step_size elif next.index(min(next)) is 1: x -= step_size elif next.index(min(next)) is 2: y += step_size elif next.index(min(next)) is 3: y -= step_size else: print('an error occured while taking steps') # if there is no step that go smaller, z is the minimum else: break print("hill climbing iteration: ", iteration) z = round(z, 3) return "{:.3f}".format(z)
def Brutal_Force(x1, x2, y1, y2): z = 0 for i in range(x1, x2): for j in range(y1, y2): result = func(i, j) if result < z: x = i y = j z = result print('---------- Brute_Force ----------') print(x) print(y) print('{:.3f}'.format(z))
def brutalFormula(rangeX, rangeY): print("Brutal with", str(rangeX), str(rangeY)) [rangeXMin, rangeXMax] = sorted(rangeX) [rangeYMin, rangeYMax] = sorted(rangeY) min = float('inf') callFuncCount = 0 # For Q2 in report for x in range(rangeXMin, rangeXMax+1): for y in range(rangeYMin, rangeXMax+1): z = func(x, y) callFuncCount += 1 # For Q2 in report if(z < min): min = z print("Count of calling func in brutal: ", callFuncCount) return "{0:.3f}".format(round(min, 3)) + "\n"
def force_solution(x_range, y_range): ans = float( 'inf') # as we want to find minimum, should start from positive inf iteration = 0 for i in range(min(x_range), max(x_range) + 1): for j in range(min(y_range), max(y_range) + 1): iteration += 1 z = func(i, j) # update answer if lesser than original value if z < ans: ans = z print("force solution iteration:", iteration) ans = round(ans, 3) return "{:.3f}".format(ans)
def HC(rX1, rX2, rY1, rY2, iX, iY): HCmin = func(iX, iY) stepSize = 1 runtimes = 1 while True: direction = 0 if iX+stepSize <= rX2 and iX+stepSize >= rX1: # X+1 runtimes+=1 if HCmin > func(iX+stepSize, iY): HCmin = func(iX+stepSize, iY) direction = 1 if iX-stepSize <= rX2 and iX-stepSize >= rX1: # X-1 runtimes+=1 if HCmin > func(iX-stepSize, iY): HCmin = func(iX-stepSize, iY) direction = 2 if iY+stepSize <= rY2 and iY+stepSize >= rY1: # Y+1 runtimes+=1 if HCmin > func(iX, iY+stepSize): HCmin = func(iX, iY+stepSize) direction = 3 if iY-stepSize <= rY2 and iY-stepSize >= rY1: # Y-1 runtimes+=1 if HCmin > func(iX, iY-stepSize): HCmin = func(iX, iY-stepSize) direction = 4 if direction == 0: roundHC = round(HCmin,3) print("%.3f"%roundHC, " times: ", runtimes) exportOutput(roundHC) break else: if direction == 1: iX = iX+stepSize elif direction == 2: iX = iX-stepSize elif direction == 3: iY = iY+stepSize elif direction == 4: iY = iY-stepSize return
def ex4_solver(): # fourth exercise print("Ex 4") if fn.check_mse() == 0: info = "Images " + str(figure_number + 1) x = np.arange(1, 201, 1) coefficient_a = 1.2 f_x = 0.1*fn.func(x) g_x = coefficient_a*x plt.figure(update_figure_number()) plot_graph_2_curves(x, f_x, "f(x)", x, g_x, "g(x)", "Ex 4 f(x) and g(x)") g_x = fn.find_better_linear_approximation(x, f_x) plt.figure(update_figure_number()) plot_graph_2_curves(x, f_x, "f(x)", x, g_x, "g(x)", "Ex 4 f(x) and g(x) after coefficent's computation") info += "-" + str(figure_number) print(info) return 0
def brute(t): """ input <MyRange> t output <Float> z_min """ z_min = 9999 # count execution of func() count_func = 0 for x in range(t.x_min, t.x_max): for y in range(t.y_min, t.y_max): z = func(x,y) count_func += 1 if z < z_min: z_min = z print("Brute: {0}".format(count_func)) return round(z_min,3)
def error_channel_flow_RK2_unsteady_inlet(steps=3, return_stability=False, name='heun', guess=None, project=[], theta=None): probDescription = sc.ProbDescription() f = func(probDescription) dt = probDescription.get_dt() μ = probDescription.get_mu() nx, ny = probDescription.get_gridPoints() dx, dy = probDescription.get_differential_elements() t = 0.0 tend = steps count = 0 print('dt=', dt) xcc, ycc = probDescription.get_cell_centered() xu, yu = probDescription.get_XVol() xv, yv = probDescription.get_YVol() # initialize velocities - we stagger everything in the negative direction. A scalar cell owns its minus face, only. # Then, for example, the u velocity field has a ghost cell at x0 - dx and the plus ghost cell at lx np.random.seed(123) u0 = np.random.rand(ny + 2, nx + 2) / 10000 # include ghost cells # u0 = np.ones([ny +2, nx+2])# include ghost cells # same thing for the y-velocity component v0 = np.random.rand(ny + 2, nx + 2) / 10000 # include ghost cells # v0 = np.ones([ny +2, nx+2]) # include ghost cells at = lambda t: (np.pi / 6) * np.sin(t / 2) u_bc_top_wall = lambda xv: 0 u_bc_bottom_wall = lambda xv: 0 u_bc_right_wall = lambda u: lambda yv: u u_bc_left_wall = lambda t: lambda yv: np.cos(at(t)) v_bc_top_wall = lambda xv: 0 v_bc_bottom_wall = lambda xv: 0 v_bc_right_wall = lambda yv: 0 v_bc_left_wall = lambda t: lambda yv: np.sin(at(t)) # pressure def pressure_right_wall(p): # pressure on the right wall p[1:-1, -1] = -p[1:-1, -2] p_bcs = lambda p: pressure_right_wall(p) # apply bcs f.top_wall(u0, v0, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u0, v0, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u0, v0, u_bc_right_wall(u0[1:-1, -1]), v_bc_right_wall) f.left_wall(u0, v0, u_bc_left_wall(t), v_bc_left_wall(t)) Coef = f.A_channel_flow() u0_free, v0_free, _, _ = f.ImQ_bcs(u0, v0, Coef, 0, p_bcs) f.top_wall(u0_free, v0_free, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u0_free, v0_free, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u0_free, v0_free, u_bc_right_wall(u0_free[1:-1, -1]), v_bc_right_wall) f.left_wall(u0_free, v0_free, u_bc_left_wall(t), v_bc_left_wall(t)) print('div_u0=', np.linalg.norm(f.div(u0_free, v0_free).ravel())) # initialize the pressure p0 = np.zeros([nx + 2, ny + 2]) # include ghost cells #declare unp1 unp1 = np.zeros_like(u0) vnp1 = np.zeros_like(v0) div_np1 = np.zeros_like(p0) # a bunch of lists for animation purposes usol = [] # usol.append(u0) usol.append(u0_free) vsol = [] # vsol.append(v0) vsol.append(v0_free) psol = [] psol.append(p0) iterations = [0] while count < tend: print('timestep:{}'.format(count + 1)) print('-----------') # rk coefficients RK2 = sc.RK2(name, theta) a21 = RK2.a21 b1 = RK2.b1 b2 = RK2.b2 u = usol[-1].copy() v = vsol[-1].copy() pn = np.zeros_like(u) pnm1 = np.zeros_like(u) # pnm2 = np.zeros_like(u) # only needed for high accurate pressure if count > 1: # change the count for 2 if high accurate pressure at time np1 is needed pn = psol[-1].copy() pnm1 = psol[-2].copy() # pnm2 = psol[-3].copy() # only needed for high accurate pressure f1x, f1y = f.Guess([pn, pnm1], order=guess, integ='RK2', type=name, theta=theta) d2, = project elif count <= 1: # compute pressures for 2 time steps # change the count for 2 if high accurate pressure at time np1 is needed d2 = 1 f1x, f1y = f.Guess([pn, pnm1], order=None, integ='RK2', type=name, theta=theta) ## stage 1 print(' Stage 1:') print(' --------') time_start = time.clock() u1 = u.copy() v1 = v.copy() # Au1 # apply boundary conditions before the computation of the rhs f.top_wall(u1, v1, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u1, v1, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u1, v1, u_bc_right_wall(u1[1:-1, -1]), v_bc_right_wall) # this won't change anything for u2 f.left_wall(u1, v1, u_bc_left_wall(t), v_bc_left_wall(t)) urhs1 = f.urhs_bcs(u1, v1) vrhs1 = f.vrhs_bcs(u1, v1) # divergence of u1 div_n = np.linalg.norm(f.div(u1, v1).ravel()) print(' divergence of u1 = ', div_n) ## stage 2 print(' Stage 2:') print(' --------') uh2 = u + a21 * dt * (urhs1 - f1x) vh2 = v + a21 * dt * (vrhs1 - f1y) f.top_wall(uh2, vh2, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(uh2, vh2, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(uh2, vh2, u_bc_right_wall(uh2[1:-1, -2]), v_bc_right_wall) # this won't change anything for u2 f.left_wall(uh2, vh2, u_bc_left_wall(t + a21 * dt), v_bc_left_wall(t + a21 * dt)) if d2 == 1: print(' pressure projection stage{} = True'.format(2)) u2, v2, _, iter1 = f.ImQ_bcs(uh2, vh2, Coef, pn, p_bcs) print(' iterations stage 2 = ', iter1) elif d2 == 0: u2 = uh2 v2 = vh2 # apply bcs f.top_wall(u2, v2, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u2, v2, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u2, v2, u_bc_right_wall(u2[1:-1, -1]), v_bc_right_wall) # this won't change anything for u2 f.left_wall(u2, v2, u_bc_left_wall(t + a21 * dt), v_bc_left_wall(t + a21 * dt)) div2 = np.linalg.norm(f.div(u2, v2).ravel()) print(' divergence of u2 = ', div2) urhs2 = f.urhs_bcs(u2, v2) vrhs2 = f.vrhs_bcs(u2, v2) uhnp1 = u + dt * b1 * (urhs1) + dt * b2 * (urhs2) vhnp1 = v + dt * b1 * (vrhs1) + dt * b2 * (vrhs2) f.top_wall(uhnp1, vhnp1, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(uhnp1, vhnp1, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(uhnp1, vhnp1, u_bc_right_wall(uhnp1[1:-1, -2]), v_bc_right_wall) # this won't change anything for u2 f.left_wall(uhnp1, vhnp1, u_bc_left_wall(t + dt), v_bc_left_wall(t + dt)) unp1, vnp1, press, iter2 = f.ImQ_bcs(uhnp1, vhnp1, Coef, pn, p_bcs) # apply bcs f.top_wall(unp1, vnp1, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(unp1, vnp1, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(unp1, vnp1, u_bc_right_wall(unp1[1:-1, -1]), v_bc_right_wall) # this won't change anything for unp1 f.left_wall(unp1, vnp1, u_bc_left_wall(t + dt), v_bc_left_wall(t + dt)) time_end = time.clock() psol.append(press) # new_press = 4 * pn - 9 * pnm1 / 2 + 3 * pnm2 / 2 # second order (working) cpu_time = time_end - time_start print(' cpu_time=', cpu_time) # Check mass residual div_np1 = np.linalg.norm(f.div(unp1, vnp1).ravel()) residual = div_np1 # if residual > 1e-12: print(' Mass residual:', residual) print('iterations:', iter) # save new solutions usol.append(unp1) vsol.append(vnp1) iterations.append(iter) Min = np.sum(unp1[1:ny + 1, 1]) Mout = np.sum(unp1[1:ny + 1, nx + 1]) print("Min=", Min) print("Mout=", Mout) t += dt # plot of the pressure gradient in order to make sure the solution is correct # # plt.contourf(usol[-1][1:-1,1:]) # if count % 10 ==0: # # divu = f.div(u0_free,v0_free) # # plt.imshow(divu[1:-1,1:-1], origin='bottom') # # plt.colorbar() # ucc = 0.5 * (u[1:-1, 2:] + u[1:-1, 1:-1]) # vcc = 0.5 * (v[2:, 1:-1] + v[1:-1, 1:-1]) # speed = np.sqrt(ucc * ucc + vcc * vcc) # # uexact = 4 * 1.5 * ycc * (1 - ycc) # # plt.plot(uexact, ycc, '-k', label='exact') # # plt.plot(ucc[:, int(8 / dx)], ycc, '--', label='x = {}'.format(8)) # plt.contourf(xcc, ycc, speed) # plt.colorbar() # # plt.streamplot(xcc, ycc, ucc, vcc, color='black', density=0.75, linewidth=1.5) # # plt.contourf(xcc, ycc, psol[-1][1:-1, 1:-1]) # # plt.colorbar() # plt.show() count += 1 if return_stability: return True else: return True, [div_np1], True, unp1[1:-1, 1:-1].ravel() # from singleton_classes import ProbDescription # # # Uinlet = 1 # ν = 0.01 # probDescription = ProbDescription(N=[4*32,32],L=[10,1],μ =ν,dt = 0.005) # dx,dy = probDescription.dx, probDescription.dy # dt = min(0.25*dx*dx/ν,0.25*dy*dy/ν, 4.0*ν/Uinlet/Uinlet) # probDescription.set_dt(dt) # error_channel_flow_RK2_unsteady_inlet (steps = 100,return_stability=False, name='midpoint', guess=None, project=[1],theta=None)
def add_layer(self, size, function='sigmoid'): function = fn.func(function) self.layers.append(np.zeros((size, 1))) self.functions.append(function)
from functions import func print(func(0, 0))
import torch from Nesterov_3qv import Nesterov_3_qv from mod_Newton import mod_Newton from functions import func epoch_N_G = 100 x1 = torch.randn(3, dtype=torch.float32) x2 = torch.zeros_like(x1) x2.copy_(x1) # x = torch.tensor([-1., 1., 1.], dtype=torch.float32) # x = torch.tensor([ 0.7876, -0.6326, 0.7936], dtype=torch.float32) x_N1, f_N1 = Nesterov_3_qv(x1, epoch=200, epoch_N_G=epoch_N_G) print('x = {} func = {}'.format((x_N1), func(x_N1))) x = torch.tensor([-1, 1, 1], dtype=torch.float32) x_N2, f_N2 = mod_Newton(x2, epoch=6000, epoch_N_G=epoch_N_G) print('x = {} func = {}'.format((x_N2), func(x_N2)))
def error_lid_driven_cavity_RK2(steps=3, return_stability=False, name='heun', guess=None, project=[], alpha=0.99): probDescription = sc.ProbDescription() f = func(probDescription) dt = probDescription.get_dt() μ = probDescription.get_mu() nx, ny = probDescription.get_gridPoints() dx, dy = probDescription.get_differential_elements() t = 0.0 tend = steps count = 0 print('dt=', dt) xcc, ycc = probDescription.get_cell_centered() xu, yu = probDescription.get_XVol() xv, yv = probDescription.get_YVol() # initialize velocities - we stagger everything in the negative direction. A scalar cell owns its minus face, only. # Then, for example, the u velocity field has a ghost cell at x0 - dx and the plus ghost cell at lx np.random.seed(123) u0 = np.random.rand(ny + 2, nx + 2) # include ghost cells # u0 = np.ones([ny +2, nx+2])# include ghost cells # same thing for the y-velocity component v0 = np.zeros([ny + 2, nx + 2]) # include ghost cells u_bc_top_wall = lambda xv: 1 u_bc_bottom_wall = lambda xv: 0 u_bc_right_wall = lambda yv: 0 u_bc_left_wall = lambda yv: 0 v_bc_top_wall = lambda xv: 0 v_bc_bottom_wall = lambda xv: 0 v_bc_right_wall = lambda yv: 0 v_bc_left_wall = lambda yv: 0 # pressure p_bcs = lambda p: p # apply bcs f.top_wall(u0, v0, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u0, v0, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u0, v0, u_bc_right_wall, v_bc_right_wall) f.left_wall(u0, v0, u_bc_left_wall, v_bc_left_wall) Coef = f.A_Lid_driven_cavity() # to make the initial condition divergence free. u0_free, v0_free, _, _ = f.ImQ_bcs(u0, v0, Coef, 0, p_bcs) f.top_wall(u0_free, v0_free, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u0_free, v0_free, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u0_free, v0_free, u_bc_right_wall, v_bc_right_wall) f.left_wall(u0_free, v0_free, u_bc_left_wall, v_bc_left_wall) print('div_u0=', np.linalg.norm(f.div(u0_free, v0_free).ravel())) # initialize the pressure p0 = np.zeros([nx + 2, ny + 2]) # include ghost cells #declare unp1 unp1 = np.zeros_like(u0) vnp1 = np.zeros_like(v0) div_np1 = np.zeros_like(p0) # a bunch of lists for animation purposes usol = [] usol.append(u0_free) vsol = [] vsol.append(v0_free) psol = [] psol.append(p0) iterations = [0] while count < tend: print('timestep:{}'.format(count + 1)) print('-----------') # rk coefficients RK2 = sc.RK2(name) a21 = RK2.a21 b1 = RK2.b1 b2 = RK2.b2 u = usol[-1].copy() v = vsol[-1].copy() pn = np.zeros_like(u) pnm1 = np.zeros_like(u) if count > 1: pn = psol[-1].copy() pnm1 = psol[-2].copy() f1x, f1y = f.Guess([pn, pnm1], order=guess, integ='RK2', type=name) d2, = project elif count <= 1: # compute pressures for 2 time steps d2 = 1 f1x, f1y = f.Guess([pn, pnm1], order=None, integ='RK2', type=name) ## stage 1 print(' Stage 1:') print(' --------') time_start = time.clock() u1 = u.copy() v1 = v.copy() # Au1 urhs1 = f.urhs_bcs(u1, v1) vrhs1 = f.vrhs_bcs(u1, v1) # divergence of u1 div_n = np.linalg.norm(f.div(u1, v1).ravel()) print(' divergence of u1 = ', div_n) ## stage 2 print(' Stage 2:') print(' --------') uh2 = u + a21 * dt * (urhs1 - f1x) vh2 = v + a21 * dt * (vrhs1 - f1y) if d2 == 1: print(' pressure projection stage{} = True'.format(2)) u2, v2, _, iter1 = f.ImQ_bcs(uh2, vh2, Coef, pn, p_bcs) print(' iterations stage 2 = ', iter1) elif d2 == 0: u2 = uh2 v2 = vh2 # apply bcs f.top_wall(u2, v2, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u2, v2, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u2, v2, u_bc_right_wall, v_bc_right_wall) f.left_wall(u2, v2, u_bc_left_wall, v_bc_left_wall) div2 = np.linalg.norm(f.div(u2, v2).ravel()) print(' divergence of u2 = ', div2) urhs2 = f.urhs_bcs(u2, v2) vrhs2 = f.vrhs_bcs(u2, v2) uhnp1 = u + dt * b1 * (urhs1) + dt * b2 * (urhs2) vhnp1 = v + dt * b1 * (vrhs1) + dt * b2 * (vrhs2) unp1, vnp1, press, iter2 = f.ImQ_bcs(uhnp1, vhnp1, Coef, pn, p_bcs) # apply bcs f.top_wall(unp1, vnp1, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(unp1, vnp1, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(unp1, vnp1, u_bc_right_wall, v_bc_right_wall) f.left_wall(unp1, vnp1, u_bc_left_wall, v_bc_left_wall) time_end = time.clock() psol.append(press) cpu_time = time_end - time_start print(' cpu_time=', cpu_time) # Check mass residual div_np1 = np.linalg.norm(f.div(unp1, vnp1).ravel()) residual = div_np1 # if residual > 1e-12: print(' Mass residual:', residual) print('iterations:', iter) # save new solutions usol.append(unp1) vsol.append(vnp1) iterations.append(iter) t += dt # plot of the pressure gradient in order to make sure the solution is correct # # plt.contourf(usol[-1][1:-1,1:]) # if count % 100 ==0: # divu = f.div(unp1,vnp1) # plt.imshow(divu[1:-1,1:-1], origin='bottom') # plt.colorbar() # # ucc = 0.5 * (u[1:-1, 2:] + u[1:-1, 1:-1]) # # vcc = 0.5 * (v[2:, 1:-1] + v[1:-1, 1:-1]) # # speed = np.sqrt(ucc * ucc + vcc * vcc) # # uexact = 4 * 1.5 * ycc * (1 - ycc) # # plt.plot(uexact, ycc, '-k', label='exact') # # plt.plot(ucc[:, int(8 / dx)], ycc, '--', label='x = {}'.format(8)) # # plt.contourf(xcc, ycc, speed) # # plt.colorbar() # # plt.streamplot(xcc, ycc, ucc, vcc, color='black', density=0.75, linewidth=1.5) # # plt.contourf(xcc, ycc, psol[-1][1:-1, 1:-1]) # # plt.colorbar() # plt.show() count += 1 if return_stability: return True else: return True, [div_np1], True, unp1[1:-1, 2:-1].ravel() # from singleton_classes import ProbDescription # # # Uinlet = 1 # ν = 0.01 # probDescription = ProbDescription(N=[32,32],L=[1,1],μ =ν,dt = 0.005) # dx,dy = probDescription.dx, probDescription.dy # dt = min(0.25*dx*dx/ν,0.25*dy*dy/ν, 4.0*ν/Uinlet/Uinlet) # probDescription.set_dt(dt) # error_lid_driven_cavity_RK2 (steps = 2000,return_stability=False, name='heun', guess=None, project=[1],alpha=0.99)
n = 8 #x = float(input('Type value of x: ')) #y = float(input('Type value of y: ')) #n = int(input('Type value of n: ')) fibo_sequence = fibonacci(n) i = [ y - x, ] i.append((fibo_sequence[-2] / fibo_sequence[-1]) * i[0]) u = x + i[1] v = y - i[1] a = func(u) b = func(v) k = 1 while (True): i.append((fibo_sequence[n - k - 1] * i[-1]) / fibo_sequence[n - k]) if (b >= a): x = v v = u u = x + i[-1] b = a a = func(u) else:
def error_DIRK2(steps=3, return_stability=False, name='midpoint', alpha=0.99, theta=0.25): # problem description probDescription = sc.ProbDescription() f = func(probDescription, 'periodic') dt = probDescription.get_dt() μ = probDescription.get_mu() nx, ny = probDescription.get_gridPoints() dx, dy = probDescription.get_differential_elements() # define exact solutions a = 2 * np.pi b = 2 * np.pi uf = 1 vf = 1 uexact = lambda a, b, x, y, t: uf - np.cos(a * (x - uf * t)) * np.sin(b * ( y - vf * t)) * np.exp(-(a**2 + b**2) * μ * t) vexact = lambda a, b, x, y, t: vf + np.sin(a * (x - uf * t)) * np.cos(b * ( y - vf * t)) * np.exp(-(a**2 + b**2) * μ * t) # # define some boiler plate t = 0.0 tend = steps count = 0 print('dt=', dt) xcc, ycc = probDescription.get_cell_centered() xu, yu = probDescription.get_XVol() xv, yv = probDescription.get_YVol() # initialize velocities - we stagger everything in the negative direction. A scalar cell owns its minus face, only. # Then, for example, the u velocity field has a ghost cell at x0 - dx and the plus ghost cell at lx u0 = np.zeros([ny + 2, nx + 2]) # include ghost cells u0[1:-1, 1:] = uexact(a, b, xu, yu, 0) # initialize the interior of u0 # same thing for the y-velocity component v0 = np.zeros([ny + 2, nx + 2]) # include ghost cells v0[1:, 1:-1] = vexact(a, b, xv, yv, 0) f.periodic_u(u0) f.periodic_v(v0) # initialize the pressure p0 = np.zeros([nx + 2, ny + 2]) # include ghost cells #declare unp1 unp1 = np.zeros_like(u0) vnp1 = np.zeros_like(v0) div_np1 = np.zeros_like(p0) # a bunch of lists for animation purposes usol = [] usol.append(u0) vsol = [] vsol.append(v0) psol = [] psol.append(p0) iterations = [] Coef = f.A() is_stable = True stability_counter = 0 total_iteration = 0 # # u and v num cell centered ucc = 0.5 * (u0[1:-1, 2:] + u0[1:-1, 1:-1]) vcc = 0.5 * (v0[2:, 1:-1] + v0[1:-1, 1:-1]) uexc = uexact(a, b, xu, yu, t) vexc = vexact(a, b, xv, yv, t) # u and v exact cell centered uexc_cc = 0.5 * (uexc[:, :-1] + uexc[:, 1:]) vexc_cc = 0.5 * (vexc[:-1, :] + vexc[1:, :]) # compute of kinetic energy ken_new = np.sum(ucc.ravel()**2 + vcc.ravel()**2) / 2 ken_exact = np.sum(uexc_cc.ravel()**2 + vexc_cc.ravel()**2) / 2 ken_old = ken_new final_KE = nx * ny alpha = 0.999 target_ke = ken_exact - alpha * (ken_exact - final_KE) print('time = ', t) print('ken_new = ', ken_new) print('ken_exc = ', ken_exact) while count < tend: print('timestep:{}'.format(count + 1)) DIRK2 = sc.DIRK2(name, theta) b1 = DIRK2.b1 b2 = DIRK2.b2 time_start = time.clock() un = usol[-1].copy() vn = vsol[-1].copy() pn = psol[-1].copy() # stage 1: #--------- u1, v1, p1, info = f.DIRK_S1(un, vn, pn, DIRK2) print(' number of function calls stage 1: ', info['nfev']) rhs_u1 = f.urhs(u1, v1) - f.Gpx(p1) rhs_v1 = f.vrhs(u1, v1) - f.Gpy(p1) # stage 2: # --------- u2, v2, p2, info = f.DIRK_S2(un, vn, pn, rhs_u1, rhs_v1, DIRK2) print(' number of function calls stage 2: ', info['nfev']) # time n+1 #---------- uhnp1 = un + b1 * dt * f.urhs(u1, v1) + b2 * dt * f.urhs(u2, v2) vhnp1 = vn + b1 * dt * f.vrhs(u1, v1) + b2 * dt * f.vrhs(u2, v2) unp1, vnp1, press, iter = f.ImQ(uhnp1, vhnp1, Coef, pn) time_end = time.clock() psol.append(press) cpu_time = time_end - time_start print(' cpu_time=', cpu_time) # Check mass residual div_np1 = np.linalg.norm(f.div(unp1, vnp1).ravel()) residual = div_np1 print(' Mass residual:', residual) # save new solutions usol.append(unp1) vsol.append(vnp1) print('len Usol:', len(usol)) print('Courant Number=', 1.42 * dt / dx) iterations.append(iter) # # u and v num cell centered ucc = 0.5 * (un[1:-1, 2:] + un[1:-1, 1:-1]) vcc = 0.5 * (vn[2:, 1:-1] + vn[1:-1, 1:-1]) # uexc = uexact(a, b, xu, yu, t) vexc = vexact(a, b, xv, yv, t) # u and v exact cell centered uexc_cc = 0.5 * (uexc[:, :-1] + uexc[:, 1:]) vexc_cc = 0.5 * (vexc[:-1, :] + vexc[1:, :]) t += dt # compute of kinetic energy ken_new = np.sum(ucc.ravel()**2 + vcc.ravel()**2) / 2 ken_exact = np.sum(uexc_cc.ravel()**2 + vexc_cc.ravel()**2) / 2 print('time = ', t) print('ken_new = ', ken_new) print('target_ken=', target_ke) print('ken_exc = ', ken_exact) print('(ken_new - ken_old)/ken_old = ', (ken_new - ken_old) / ken_old) if (((ken_new - ken_old) / ken_old) > 0 and count > 1) or np.isnan(ken_new): is_stable = False print('is_stable = ', is_stable) if stability_counter > 3: print('not stable !!!!!!!!') break else: stability_counter += 1 else: is_stable = True print('is_stable = ', is_stable) if ken_new < target_ke and count > 30: break ken_old = ken_new.copy() print('is_stable = ', is_stable) max = 4 min = -4 levels = np.linspace(min, max, 50, endpoint=True) # #plot of the pressure gradient in order to make sure the solution is correct # im = plt.contourf((psol[-1][1:-1,1:] - psol[-1][1:-1,:-1])/dx,cmap='viridis',levels=levels,vmin=-4,vmax=4) # v = np.linspace(-4, 4, 5, endpoint=True) # cbar = plt.colorbar(im) # plt.title("time={:0.4f}s".format(t)) # plt.tight_layout() # plt.savefig('Implicit-NSE/DIRK2_{}_capuano_form/animations/dpdx/timestep-{:0>2}.png'.format(name,count), dpi=300) # plt.close() count += 1 diff = np.linalg.norm( uexact(a, b, xu, yu, t).ravel() - unp1[1:-1, 1:].ravel(), np.inf) if return_stability: return is_stable else: return diff, [total_iteration], is_stable, unp1[1:-1, 1:].ravel()
def error_channel_flow_RK4_unsteady_inlet (steps = 3,return_stability=False, name='regular', guess=None, project=[],alpha=0.99): probDescription = sc.ProbDescription() f = func(probDescription) dt = probDescription.get_dt() μ = probDescription.get_mu() nx, ny = probDescription.get_gridPoints() dx, dy = probDescription.get_differential_elements() t = 0.0 tend = steps count = 0 print('dt=', dt) xcc, ycc = probDescription.get_cell_centered() xu, yu = probDescription.get_XVol() xv, yv = probDescription.get_YVol() # initialize velocities - we stagger everything in the negative direction. A scalar cell owns its minus face, only. # Then, for example, the u velocity field has a ghost cell at x0 - dx and the plus ghost cell at lx np.random.seed(123) # u0 = np.random.rand(ny + 2, nx + 2) / 1000000 # include ghost cells # u0 = np.ones([ny +2, nx+2])# include ghost cells u0 = np.zeros([ny + 2, nx + 2]) # same thing for the y-velocity component # v0 = np.random.rand(ny + 2, nx + 2) / 1000000 # include ghost cells # v0 = np.ones([ny +2, nx+2]) # include ghost cells v0 = np.zeros([ny + 2, nx + 2]) at = lambda t: (np.pi / 6) * np.sin(t / 2) u_bc_top_wall = lambda xv: 0 u_bc_bottom_wall = lambda xv: 0 u_bc_right_wall = lambda u: lambda yv: u u_bc_left_wall = lambda t: lambda yv: np.cos(at(t)) v_bc_top_wall = lambda xv: 0 v_bc_bottom_wall = lambda xv: 0 v_bc_right_wall = lambda yv: 0 v_bc_left_wall = lambda t: lambda yv: np.sin(at(t)) # pressure def pressure_right_wall(p): # pressure on the right wall p[1:-1, -1] = -p[1:-1, -2] p_bcs = lambda p: pressure_right_wall(p) # apply bcs f.top_wall(u0, v0, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u0, v0, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u0, v0, u_bc_right_wall(u0[1:-1, -1]), v_bc_right_wall) f.left_wall(u0, v0, u_bc_left_wall(t), v_bc_left_wall(t)) Coef = f.A_channel_flow() u0_free, v0_free, _, _ = f.ImQ_bcs(u0, v0, Coef, 0, p_bcs) f.top_wall(u0_free, v0_free, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u0_free, v0_free, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u0_free, v0_free, u_bc_right_wall(u0_free[1:-1, -1]), v_bc_right_wall) f.left_wall(u0_free, v0_free, u_bc_left_wall(t), v_bc_left_wall(t)) print('div_u0=', np.linalg.norm(f.div(u0_free, v0_free).ravel())) # initialize the pressure p0 = np.zeros([nx + 2, ny + 2]); # include ghost cells # declare unp1 unp1 = np.zeros_like(u0) vnp1 = np.zeros_like(v0) div_np1 = np.zeros_like(p0) # a bunch of lists for animation purposes usol = [] # usol.append(u0) usol.append(u0_free) vsol = [] # vsol.append(v0) vsol.append(v0_free) psol = [] psol.append(p0) iterations = [0] while count < tend: print('timestep:{}'.format(count + 1)) print('-----------') # rk coefficients RK4 = sc.RK4(name) a21 = RK4.a21 a31 = RK4.a31 a32 = RK4.a32 a41 = RK4.a41 a42 = RK4.a42 a43 = RK4.a43 b1 = RK4.b1 b2 = RK4.b2 b3 = RK4.b3 b4 = RK4.b4 u = usol[-1].copy() v = vsol[-1].copy() pn = np.zeros_like(u) pnm1 = np.zeros_like(u) pnm2 = np.zeros_like(u) pnm3 = np.zeros_like(u) if count > 4: pn = psol[-1].copy() pnm1 = psol[-2].copy() pnm2 = psol[-3].copy() pnm3 = psol[-4].copy() f1x, f1y, f2x, f2y, f3x, f3y = f.Guess([pn, pnm1,pnm2,pnm3], order=guess, integ='RK4', type=name) d2,d3, d4 = project elif count <= 4: # compute pressures for 3 time steps d2 = 1 d3 = 1 d4 = 1 f1x, f1y, f2x, f2y, f3x, f3y = f.Guess([pn, pnm1,pnm2,pnm3], order=None, integ='RK4', type=name) ## stage 1 print(' Stage 1:') print(' --------') time_start = time.clock() u1 = u.copy() v1 = v.copy() # Au1 urhs1 = f.urhs_bcs(u1, v1) vrhs1 = f.vrhs_bcs(u1, v1) # divergence of u1 div_n = np.linalg.norm(f.div(u1, v1).ravel()) print(' divergence of u1 = ', div_n) ## stage 2 print(' Stage 2:') print(' --------') uh2 = u + a21 * dt * (urhs1 - f1x) vh2 = v + a21 * dt * (vrhs1 - f1y) f.top_wall(uh2, vh2, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(uh2, vh2, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(uh2, vh2, u_bc_right_wall(uh2[1:-1, -2]), v_bc_right_wall) # this won't change anything for u2 f.left_wall(uh2, vh2, u_bc_left_wall(t+a21*dt), v_bc_left_wall(t+a21*dt)) if d2 == 1: print(' pressure projection stage{} = True'.format(2)) u2, v2, _, iter1 = f.ImQ_bcs(uh2, vh2, Coef, pn, p_bcs) print(' iterations stage 2 = ', iter1) elif d2 == 0: u2 = uh2 v2 = vh2 # apply bcs f.top_wall(u2, v2, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u2, v2, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u2, v2, u_bc_right_wall(u2[1:-1, -1]), v_bc_right_wall) # this won't change anything for u2 f.left_wall(u2, v2, u_bc_left_wall(t+a21*dt), v_bc_left_wall(t+a21*dt)) div2 = np.linalg.norm(f.div(u2, v2).ravel()) print(' divergence of u2 = ', div2) urhs2 = f.urhs_bcs(u2, v2) vrhs2 = f.vrhs_bcs(u2, v2) ## stage 3 print(' Stage 3:') print(' --------') uh3 = u + a31 * dt * (urhs1 - f1x) + a32 * dt * (urhs2 - f2x) vh3 = v + a31 * dt * (vrhs1 - f1y) + a32 * dt * (vrhs2 - f2y) f.top_wall(uh3, vh3, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(uh3, vh3, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(uh3, vh3, u_bc_right_wall(uh3[1:-1, -2]), v_bc_right_wall) # this won't change anything for u2 f.left_wall(uh3, vh3, u_bc_left_wall(t+(a31+a32)*dt), v_bc_left_wall(t+(a31+a32)*dt)) if d3 == 1: print(' pressure projection stage{} = True'.format(3)) u3, v3, _, iter1 = f.ImQ_bcs(uh3, vh3, Coef, pn, p_bcs) print(' iterations stage 3 = ', iter1) elif d3 == 0: u3 = uh3 v3 = vh3 # apply bcs f.top_wall(u3, v3, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u3, v3, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u3, v3, u_bc_right_wall(u3[1:-1, -1]), v_bc_right_wall) # this won't change anything for u2 f.left_wall(u3, v3, u_bc_left_wall(t+(a31+a32)*dt), v_bc_left_wall(t+(a31+a32)*dt)) div3 = np.linalg.norm(f.div(u3, v3).ravel()) print(' divergence of u3 = ', div3) urhs3 = f.urhs_bcs(u3, v3) vrhs3 = f.vrhs_bcs(u3, v3) ## stage 4 print(' Stage 4:') print(' --------') uh4 = u + a41 * dt * (urhs1 - f1x) + a42 * dt * (urhs2 - f2x) + a43 * dt * (urhs3 - f3x) vh4 = v + a41 * dt * (vrhs1 - f1y) + a42 * dt * (vrhs2 - f2y) + a43 * dt * (vrhs3 - f3y) f.top_wall(uh4, vh4, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(uh4, vh4, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(uh4, vh4, u_bc_right_wall(uh4[1:-1, -2]), v_bc_right_wall) # this won't change anything for u2 f.left_wall(uh4, vh4, u_bc_left_wall(t+(a41+a42+a43)*dt), v_bc_left_wall(t+(a41+a42+a43)*dt)) if d4 == 1: print(' pressure projection stage{} = True'.format(3)) u4, v4, _, iter1 = f.ImQ_bcs(uh4, vh4, Coef, pn, p_bcs) print(' iterations stage 4 = ', iter1) elif d4 == 0: u4 = uh4 v4 = vh4 # apply bcs f.top_wall(u4, v4, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u4, v4, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u4, v4, u_bc_right_wall(u4[1:-1, -1]), v_bc_right_wall) # this won't change anything for u2 f.left_wall(u4, v4, u_bc_left_wall(t+(a41+a42+a43)*dt), v_bc_left_wall(t+(a41+a42+a43)*dt)) div4 = np.linalg.norm(f.div(u4, v4).ravel()) print(' divergence of u4 = ', div3) urhs4 = f.urhs_bcs(u4, v4) vrhs4 = f.vrhs_bcs(u4, v4) uhnp1 = u + dt * b1 * (urhs1) + dt * b2 * (urhs2) + dt * b3 * (urhs3) + dt * b4 * (urhs4) vhnp1 = v + dt * b1 * (vrhs1) + dt * b2 * (vrhs2) + dt * b3 * (vrhs3) + dt * b4 * (vrhs4) f.top_wall(uhnp1, vhnp1, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(uhnp1, vhnp1, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(uhnp1, vhnp1, u_bc_right_wall(uhnp1[1:-1, -2]),v_bc_right_wall) # this won't change anything for unp1 f.left_wall(uhnp1, vhnp1, u_bc_left_wall(t+dt), v_bc_left_wall(t+dt)) unp1, vnp1, press, iter2 = f.ImQ_bcs(uhnp1, vhnp1, Coef, pn, p_bcs) # apply bcs f.top_wall(unp1, vnp1, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(unp1, vnp1, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(unp1, vnp1, u_bc_right_wall(unp1[1:-1, -1]), v_bc_right_wall) # this won't change anything for unp1 f.left_wall(unp1, vnp1, u_bc_left_wall(t+dt), v_bc_left_wall(t+dt)) # # post processing projection # unp1r =unp1+ dt * f.urhs_bcs(unp1, vnp1) # vnp1r =vnp1+ dt * f.vrhs_bcs(unp1, vnp1) # # f.top_wall(unp1r, vnp1r, u_bc_top_wall, v_bc_top_wall) # f.bottom_wall(unp1r, vnp1r, u_bc_bottom_wall, v_bc_bottom_wall) # f.right_wall(unp1r, vnp1r, u_bc_right_wall(unp1r[1:-1, -2]), # v_bc_right_wall) # this won't change anything for unp1 # f.left_wall(unp1r, vnp1r, u_bc_left_wall, v_bc_left_wall) # # _, _, press, _ = f.ImQ_bcs(unp1r, vnp1r, Coef, pn, p_bcs) time_end = time.clock() psol.append(press) cpu_time = time_end - time_start print(' cpu_time=', cpu_time) # Check mass residual div_np1 = np.linalg.norm(f.div(unp1, vnp1).ravel()) residual = div_np1 # if residual > 1e-12: print(' Mass residual:', residual) print('iterations:', iter) # save new solutions usol.append(unp1) vsol.append(vnp1) iterations.append(iter) t += dt # plot of the pressure gradient in order to make sure the solution is correct # # plt.contourf(usol[-1][1:-1,1:]) # if count % 10 ==0: # # divu = f.div(unp1,vnp1) # # plt.imshow(divu[1:-1,1:-1], origin='bottom') # # plt.colorbar() # ucc = 0.5 * (u[1:-1, 2:] + u[1:-1, 1:-1]) # vcc = 0.5 * (v[2:, 1:-1] + v[1:-1, 1:-1]) # speed = np.sqrt(ucc * ucc + vcc * vcc) # # uexact = 4 * 1.5 * ycc * (1 - ycc) # # plt.plot(uexact, ycc, '-k', label='exact') # # plt.plot(ucc[:, int(8 / dx)], ycc, '--', label='x = {}'.format(8)) # plt.contourf(xcc, ycc, speed) # plt.colorbar() # # plt.streamplot(xcc, ycc, ucc, vcc, color='black', density=0.75, linewidth=1.5) # # plt.contourf(xcc, ycc, psol[-1][1:-1, 1:-1]) # # plt.colorbar() # plt.show() count += 1 if return_stability: return True else: return True, [div_np1], True, unp1[1:-1, 1:-1].ravel() # return True, [div_np1], True, press[1:-1, 1:-1].ravel() # from singleton_classes import ProbDescription # # # Uinlet = 1 # ν = 0.01 # probDescription = ProbDescription(N=[4*32,32],L=[10,1],μ =ν,dt = 0.005) # dx,dy = probDescription.dx, probDescription.dy # dt = min(0.25*dx*dx/ν,0.25*dy*dy/ν, 4.0*ν/Uinlet/Uinlet) # probDescription.set_dt(dt) # error_channel_flow_RK4_unsteady_inlet (steps = 2000,return_stability=False, name='regular', guess=None, project=[1,1,1],alpha=0.99)
def error_FE(steps=3, return_stability=False, alpha=0.99): # problem description probDescription = sc.ProbDescription() f = func(probDescription, 'periodic') dt = probDescription.get_dt() μ = probDescription.get_mu() nx, ny = probDescription.get_gridPoints() dx, dy = probDescription.get_differential_elements() # define exact solutions a = 2 * np.pi b = 2 * np.pi uf = 1 vf = 1 uexact = lambda a, b, x, y, t: uf - np.cos(a * (x - uf * t)) * np.sin(b * ( y - vf * t)) * np.exp(-(a**2 + b**2) * μ * t) vexact = lambda a, b, x, y, t: vf + np.sin(a * (x - uf * t)) * np.cos(b * ( y - vf * t)) * np.exp(-(a**2 + b**2) * μ * t) # # define some boiler plate t = 0.0 tend = steps count = 0 print('dt=', dt) xcc, ycc = probDescription.get_cell_centered() xu, yu = probDescription.get_XVol() xv, yv = probDescription.get_YVol() # initialize velocities - we stagger everything in the negative direction. A scalar cell owns its minus face, only. # Then, for example, the u velocity field has a ghost cell at x0 - dx and the plus ghost cell at lx u0 = np.zeros([ny + 2, nx + 2]) # include ghost cells u0[1:-1, 1:] = uexact(a, b, xu, yu, 0) # initialize the interior of u0 # same thing for the y-velocity component v0 = np.zeros([ny + 2, nx + 2]) # include ghost cells v0[1:, 1:-1] = vexact(a, b, xv, yv, 0) f.periodic_u(u0) f.periodic_v(v0) # initialize the pressure p0 = np.zeros([nx + 2, ny + 2]) # include ghost cells #declare unp1 unp1 = np.zeros_like(u0) vnp1 = np.zeros_like(v0) div_np1 = np.zeros_like(p0) # a bunch of lists for animation purposes usol = [] usol.append(u0) vsol = [] vsol.append(v0) psol = [] psol.append(p0) iterations = [] Coef = scipy.sparse.csr_matrix.toarray(f.A()) is_stable = True stability_counter = 0 total_iteration = 0 # # u and v num cell centered ucc = 0.5 * (u0[1:-1, 2:] + u0[1:-1, 1:-1]) vcc = 0.5 * (v0[2:, 1:-1] + v0[1:-1, 1:-1]) uexc = uexact(a, b, xu, yu, t) vexc = vexact(a, b, xv, yv, t) # u and v exact cell centered uexc_cc = 0.5 * (uexc[:, :-1] + uexc[:, 1:]) vexc_cc = 0.5 * (vexc[:-1, :] + vexc[1:, :]) # compute of kinetic energy ken_new = np.sum(ucc.ravel()**2 + vcc.ravel()**2) / 2 ken_exact = np.sum(uexc_cc.ravel()**2 + vexc_cc.ravel()**2) / 2 ken_old = ken_new final_KE = nx * ny alpha = 0.999 target_ke = ken_exact - alpha * (ken_exact - final_KE) print('time = ', t) print('ken_new = ', ken_new) print('ken_exc = ', ken_exact) while count < tend: print('timestep:{}'.format(count + 1)) print('-----------') ## stage 1 pn = np.zeros_like(u0) if count > 1: pn = psol[-1].copy() print(' Stage 1:') print(' --------') time_start = time.clock() u = usol[-1].copy() v = vsol[-1].copy() # divergence of u1 div_n = np.linalg.norm(f.div(u, v).ravel()) print(' divergence of u1 = ', div_n) ## stage 2 print(' Stage 2:') print(' --------') uh = u + dt * f.urhs(u, v) vh = v + dt * f.vrhs(u, v) unp1, vnp1, press, iter = f.ImQ(uh, vh, Coef, pn) total_iteration += iter time_end = time.clock() psol.append(press) cpu_time = time_end - time_start print(' cpu_time=', cpu_time) # Check mass residual div_np1 = np.linalg.norm(f.div(unp1, vnp1).ravel()) residual = div_np1 # if residual > 1e-12: print(' Mass residual:', residual) print('iterations:', iter) # save new solutions usol.append(unp1) vsol.append(vnp1) iterations.append(iter) # # u and v num cell centered ucc = 0.5 * (u[1:-1, 2:] + u[1:-1, 1:-1]) vcc = 0.5 * (v[2:, 1:-1] + v[1:-1, 1:-1]) uexc = uexact(a, b, xu, yu, t) vexc = vexact(a, b, xv, yv, t) # u and v exact cell centered uexc_cc = 0.5 * (uexc[:, :-1] + uexc[:, 1:]) vexc_cc = 0.5 * (vexc[:-1, :] + vexc[1:, :]) t += dt # compute of kinetic energy ken_new = np.sum(ucc.ravel()**2 + vcc.ravel()**2) / 2 ken_exact = np.sum(uexc_cc.ravel()**2 + vexc_cc.ravel()**2) / 2 print('time = ', t) print('ken_new = ', ken_new) print('target_ken=', target_ke) print('ken_exc = ', ken_exact) print('(ken_new - ken_old)/ken_old = ', (ken_new - ken_old) / ken_old) if (((ken_new - ken_old) / ken_old) > 0 and count > 1) or np.isnan(ken_new): is_stable = False print('is_stable = ', is_stable) if stability_counter > 3: print('not stable !!!!!!!!') break else: stability_counter += 1 else: is_stable = True print('is_stable = ', is_stable) if ken_new < target_ke and count > 30: break ken_old = ken_new.copy() print('is_stable = ', is_stable) #plot of the pressure gradient in order to make sure the solution is correct # # plt.contourf(usol[-1][1:-1,1:]) # plt.contourf((psol[-1][1:-1,1:] - psol[-1][1:-1,:-1])/dx) # plt.colorbar() # plt.show() count += 1 diff = np.linalg.norm( uexact(a, b, xu, yu, t).ravel() - unp1[1:-1, 1:].ravel(), np.inf) print(' error={}'.format(diff)) if return_stability: return is_stable else: return diff, [total_iteration], is_stable, unp1[1:-1, 1:].ravel()
def error_tv_time_dependent_bcs_RK2(steps=3, return_stability=False, name='', guess=None, project=[], theta=None): probDescription = sc.ProbDescription() f = func(probDescription) dt = probDescription.get_dt() μ = probDescription.get_mu() nx, ny = probDescription.get_gridPoints() dx, dy = probDescription.get_differential_elements() a = 2 * np.pi b = 2 * np.pi uexact = lambda a, b, x, y, t: 1 - np.cos(a * (x - t)) * np.sin(b * ( y - t)) * np.exp(-(a**2 + b**2) * μ * t) vexact = lambda a, b, x, y, t: 1 + np.sin(a * (x - t)) * np.cos(b * ( y - t)) * np.exp(-(a**2 + b**2) * μ * t) pexact = lambda x, y, t: ( -8 * np.sin(np.pi * t)**4 * np.sin(np.pi * y)**4 - 2 * np .sin(np.pi * t)**4 - 2 * np.sin(np.pi * y)**4 - 5 * np.cos( 2 * np.pi * t) / 2 + 5 * np.cos(4 * np.pi * t) / 8 - 5 * np.cos( 2 * np.pi * y) / 2 + 5 * np.cos(4 * np.pi * y) / 8 - np.cos( np.pi * (2 * t - 4 * y)) / 4 + np.cos(np.pi * (2 * t - 2 * y)) + np .cos(np.pi * (2 * t + 2 * y)) - np.cos(np.pi * (2 * t + 4 * y)) / 4 - 3 * np.cos(np.pi * (4 * t - 4 * y)) / 16 - np.cos(np.pi * (4 * t - 2 * y)) / 4 - np.cos(np.pi * (4 * t + 2 * y)) / 4 + np.cos(np.pi * (4 * t + 4 * y)) / 16 + 27 / 8) * np.exp(-16 * np.pi**2 * μ * t) - np.exp( -16 * np.pi**2 * μ * t) * np.cos(np.pi * (-4 * t + 4 * x)) / 4 t = 0.0 tend = steps count = 0 print('dt=', dt) xcc, ycc = probDescription.get_cell_centered() xu, yu = probDescription.get_XVol() xv, yv = probDescription.get_YVol() # initialize velocities - we stagger everything in the negative direction. A scalar cell owns its minus face, only. # Then, for example, the u velocity field has a ghost cell at x0 - dx and the plus ghost cell at lx u0 = np.zeros([ny + 2, nx + 2]) # include ghost cells u0[1:-1, 1:] = uexact(a, b, xu, yu, t) # initialize the interior of u0 # same thing for the y-velocity component v0 = np.zeros([ny + 2, nx + 2]) # include ghost cells v0[1:, 1:-1] = vexact(a, b, xv, yv, t) print('div_before_bcs= {}'.format(np.linalg.norm(f.div(u0, v0)))) # print('right wall :, yv= {}'.format(yv[:,-1])) u_bc_top_wall = lambda t: lambda xv: uexact(a, b, xu[-1, :], np.ones_like(xu[-1, :]), t) u_bc_bottom_wall = lambda t: lambda xv: uexact(a, b, xu[0, :], np.zeros_like(xu[0, :]), t) u_bc_right_wall = lambda t: lambda yv: uexact(a, b, xu[:, -1], yu[:, -1], t ) u_bc_left_wall = lambda t: lambda yv: uexact(a, b, xu[:, 0], yu[:, 0], t) v_bc_top_wall = lambda t: lambda xv: vexact(a, b, xv[-1, :], yv[-1, :], t) v_bc_bottom_wall = lambda t: lambda xv: vexact(a, b, xv[0, :], yv[0, :], t) v_bc_right_wall = lambda t: lambda yv: vexact(a, b, np.ones_like( yv[:, -1]), yv[:, -1], t) v_bc_left_wall = lambda t: lambda yv: vexact(a, b, np.zeros_like(yv[:, 0]), yv[:, 0], t) # plt.imshow(u0,origin='bottom') # plt.show() # pressure def pressure_bcs(p, t): # # right wall # p[1:-1,-1] = 2*pexact(np.ones_like(ycc[:,-1]),ycc[:,-1],t)/ np.sum(pexact(np.ones_like(ycc[:,-2]),ycc[:,-2],t).ravel()) *np.sum(p[1:-1,-2].ravel()) -p[1:-1,-2] # # left wall # p[1:-1,0] = 2*pexact(np.zeros_like(ycc[:,0]),ycc[:,0],t)/np.sum(pexact(np.zeros_like(ycc[:,1]),ycc[:,1],t).ravel())*np.sum(p[1:-1,1].ravel()) -p[1:-1,1] # # top wall # p[-1,1:-1] = 2*pexact(np.ones_like(ycc[-1,:]),ycc[-1,:],t)/np.sum(pexact(np.ones_like(ycc[-2,:]),ycc[-2,:],t).ravel())*np.sum(p[-2,1:-1].ravel()) - p[-2,1:-1] # # bottom wall # p[0, 1:-1] = 2 * pexact(np.zeros_like(ycc[0,:]),ycc[0,:],t)/np.sum(pexact(np.zeros_like(ycc[1,:]),ycc[1,:],t).ravel())*np.sum(p[1, 1:-1].ravel()) - p[1, 1:-1] # # try extrapolation # right wall p[1:-1, -1] = (p[1:-1, -2] - p[1:-1, -3]) + p[1:-1, -2] # left wall p[1:-1, 0] = -(p[1:-1, 2] - p[1:-1, 1]) + p[1:-1, 1] # top wall p[-1, 1:-1] = (p[-2, 1:-1] - p[-3, 1:-1]) + p[-2, 1:-1] # bottom wall p[0, 1:-1] = -(p[2, 1:-1] - p[1, 1:-1]) + p[1, 1:-1] p_bcs = lambda t: lambda p: pressure_bcs(p, t) # apply bcs f.top_wall(u0, v0, u_bc_top_wall(t), v_bc_top_wall(t)) f.bottom_wall(u0, v0, u_bc_bottom_wall(t), v_bc_bottom_wall(t)) f.right_wall(u0, v0, u_bc_right_wall(t), v_bc_right_wall(t)) f.left_wall(u0, v0, u_bc_left_wall(t), v_bc_left_wall(t)) print('div_after_bcs= {}'.format(np.linalg.norm(f.div(u0, v0)))) # plt.imshow(u0, origin='bottom') # plt.show() # initialize the pressure p0 = np.zeros([nx + 2, ny + 2]) # include ghost cells #declare unp1 unp1 = np.zeros_like(u0) vnp1 = np.zeros_like(v0) div_np1 = np.zeros_like(p0) # a bunch of lists for animation purposes usol = [] usol.append(u0) vsol = [] vsol.append(v0) psol = [] psol.append(p0) iterations = [0] Coef = f.A_Lid_driven_cavity() while count < tend: print('timestep:{}'.format(count + 1)) print('-----------') # rk coefficients RK2 = sc.RK2(name, theta=theta) a21 = RK2.a21 b1 = RK2.b1 b2 = RK2.b2 u = usol[-1].copy() v = vsol[-1].copy() pn = np.zeros_like(u) pnm1 = np.zeros_like(u) if count > 1: pn = psol[-1].copy() pnm1 = psol[-2].copy() f1x, f1y = f.Guess([pn, pnm1], order=guess, integ='RK2', type=name) d2, = project elif count <= 1: # compute pressures for 2 time steps d2 = 1 f1x, f1y = f.Guess([pn, pnm1], order=None, integ='RK2', type=name) ## stage 1 print(' Stage 1:') print(' --------') time_start = time.clock() u1 = u.copy() v1 = v.copy() # Au1 urhs1 = f.urhs_bcs(u1, v1) vrhs1 = f.vrhs_bcs(u1, v1) # divergence of u1 div_n = np.linalg.norm(f.div(u1, v1).ravel()) print(' divergence of u1 = ', div_n) ## stage 2 print(' Stage 2:') print(' --------') uh2 = u + a21 * dt * (urhs1 - f1x) vh2 = v + a21 * dt * (vrhs1 - f1y) f.top_wall(uh2, vh2, u_bc_top_wall(t + a21 * dt), v_bc_top_wall(t + a21 * dt)) f.bottom_wall(uh2, vh2, u_bc_bottom_wall(t + a21 * dt), v_bc_bottom_wall(t + a21 * dt)) f.right_wall(uh2, vh2, u_bc_right_wall(t + a21 * dt), v_bc_right_wall(t + a21 * dt)) f.left_wall(uh2, vh2, u_bc_left_wall(t + a21 * dt), v_bc_left_wall(t + a21 * dt)) if d2 == 1: print(' pressure projection stage{} = True'.format(2)) u2, v2, _, iter1 = f.ImQ_bcs(uh2, vh2, Coef, pn, p_bcs((t + a21 * dt))) print(' iterations stage 2 = ', iter1) elif d2 == 0: u2 = uh2 v2 = vh2 # apply bcs f.top_wall(u2, v2, u_bc_top_wall(t + a21 * dt), v_bc_top_wall(t + a21 * dt)) f.bottom_wall(u2, v2, u_bc_bottom_wall(t + a21 * dt), v_bc_bottom_wall(t + a21 * dt)) f.right_wall(u2, v2, u_bc_right_wall(t + a21 * dt), v_bc_right_wall(t + a21 * dt)) f.left_wall(u2, v2, u_bc_left_wall(t + a21 * dt), v_bc_left_wall(t + a21 * dt)) div2 = np.linalg.norm(f.div(u2, v2).ravel()) print(' divergence of u2 = ', div2) urhs2 = f.urhs_bcs(u2, v2) vrhs2 = f.vrhs_bcs(u2, v2) uhnp1 = u + dt * b1 * (urhs1) + dt * b2 * (urhs2) vhnp1 = v + dt * b1 * (vrhs1) + dt * b2 * (vrhs2) f.top_wall(uhnp1, vhnp1, u_bc_top_wall(t + dt), v_bc_top_wall(t + dt)) f.bottom_wall(uhnp1, vhnp1, u_bc_bottom_wall(t + dt), v_bc_bottom_wall(t + dt)) f.right_wall(uhnp1, vhnp1, u_bc_right_wall(t + dt), v_bc_right_wall(t + dt)) f.left_wall(uhnp1, vhnp1, u_bc_left_wall(t + dt), v_bc_left_wall(t + dt)) unp1, vnp1, press, iter2 = f.ImQ_bcs(uhnp1, vhnp1, Coef, pn, p_bcs(t + dt)) # apply bcs f.top_wall(unp1, vnp1, u_bc_top_wall(t + dt), v_bc_top_wall(t + dt)) f.bottom_wall(unp1, vnp1, u_bc_bottom_wall(t + dt), v_bc_bottom_wall(t + dt)) f.right_wall(unp1, vnp1, u_bc_right_wall(t + dt), v_bc_right_wall(t + dt)) f.left_wall(unp1, vnp1, u_bc_left_wall(t + dt), v_bc_left_wall(t + dt)) time_end = time.clock() psol.append(press) cpu_time = time_end - time_start print(' cpu_time=', cpu_time) # Check mass residual div_np1 = np.linalg.norm(f.div(unp1, vnp1).ravel()) residual = div_np1 # if residual > 1e-12: print(' Mass residual:', residual) print('iterations:', iter) # save new solutions usol.append(unp1) vsol.append(vnp1) iterations.append(iter) t += dt # plot of the pressure gradient in order to make sure the solution is correct # # plt.contourf(usol[-1][1:-1,1:]) # if count % 1 ==0: # # plt.imshow(unp1[1:-1,1:]-uexact(a,b,xu,yu,t),origin='bottom') # plt.imshow(unp1[1:-1,1:],origin='bottom') # plt.colorbar() # # divu = f.div(unp1,vnp1) # # plt.imshow(divu[1:-1,1:-1], origin='bottom') # # plt.colorbar() # # ucc = 0.5 * (u[1:-1, 2:] + u[1:-1, 1:-1]) # # vcc = 0.5 * (v[2:, 1:-1] + v[1:-1, 1:-1]) # # speed = np.sqrt(ucc * ucc + vcc * vcc) # # uexact = 4 * 1.5 * ycc * (1 - ycc) # # plt.plot(uexact, ycc, '-k', label='exact') # # plt.plot(ucc[:, int(8 / dx)], ycc, '--', label='x = {}'.format(8)) # # plt.contourf(xcc, ycc, speed) # # plt.colorbar() # # plt.streamplot(xcc, ycc, ucc, vcc, color='black', density=0.75, linewidth=1.5) # # plt.contourf(xcc, ycc, psol[-1][1:-1, 1:-1]) # # plt.colorbar() # plt.show() count += 1 if return_stability: return True else: return True, [div_np1], True, unp1[1:-1, 1:-1].ravel() # from singleton_classes import ProbDescription # # # Uinlet = 1 # ν = 0.01 # probDescription = ProbDescription(N=[32,32],L=[1,1],μ =ν,dt = 0.005) # dx,dy = probDescription.dx, probDescription.dy # dt = min(0.25*dx*dx/ν,0.25*dy*dy/ν, 4.0*ν/Uinlet/Uinlet) # print('dt = ',dt) # probDescription.set_dt(0.001) # error_tv_time_dependent_bcs_RK2(steps = 200,return_stability=False, name='midpoint', guess=None, project=[1],theta=None)
def error_channel_flow_FE(steps=3, return_stability=False, name='', guess=None, project=[], alpha=0.99): probDescription = sc.ProbDescription() f = func(probDescription) dt = probDescription.get_dt() μ = probDescription.get_mu() nx, ny = probDescription.get_gridPoints() dx, dy = probDescription.get_differential_elements() t = 0.0 tend = steps count = 0 print('dt=', dt) xcc, ycc = probDescription.get_cell_centered() xu, yu = probDescription.get_XVol() xv, yv = probDescription.get_YVol() # initialize velocities - we stagger everything in the negative direction. A scalar cell owns its minus face, only. # Then, for example, the u velocity field has a ghost cell at x0 - dx and the plus ghost cell at lx u0 = np.zeros([ny + 2, nx + 2]) # include ghost cells # same thing for the y-velocity component v0 = np.zeros([ny + 2, nx + 2]) # include ghost cells u_bc_top_wall = lambda xv: 0 u_bc_bottom_wall = lambda xv: 0 u_bc_right_wall = lambda u: lambda yv: u u_bc_left_wall = lambda yv: 1 v_bc_top_wall = lambda xv: 0 v_bc_bottom_wall = lambda xv: 0 v_bc_right_wall = lambda yv: 0 v_bc_left_wall = lambda yv: 0 # pressure def pressure_right_wall(p): # pressure on the right wall p[1:-1, -1] = -p[1:-1, -2] p_bcs = lambda p: pressure_right_wall(p) # apply bcs f.top_wall(u0, v0, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(u0, v0, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(u0, v0, u_bc_right_wall(u0[1:-1, -1]), v_bc_right_wall) f.left_wall(u0, v0, u_bc_left_wall, v_bc_left_wall) # initialize the pressure p0 = np.zeros([nx + 2, ny + 2]) # include ghost cells #declare unp1 unp1 = np.zeros_like(u0) vnp1 = np.zeros_like(v0) div_np1 = np.zeros_like(p0) # a bunch of lists for animation purposes usol = [] usol.append(u0) vsol = [] vsol.append(v0) psol = [] psol.append(p0) iterations = [0] Coef = f.A_channel_flow() total_iters = 0 while count < tend: print('timestep:{}'.format(count + 1)) print('-----------') # rk coefficients u = usol[-1].copy() v = vsol[-1].copy() pn = np.zeros_like(u) pnm1 = np.zeros_like(u) time_start = time.clock() uhnp1 = u + dt * f.urhs_bcs(u, v) vhnp1 = v + dt * f.vrhs_bcs(u, v) f.left_wall(uhnp1, vhnp1, u_bc_left_wall, v_bc_left_wall) unp1, vnp1, press, iter = f.ImQ_bcs(uhnp1, vhnp1, Coef, pn, p_bcs) total_iters += iter # apply bcs f.top_wall(unp1, vnp1, u_bc_top_wall, v_bc_top_wall) f.bottom_wall(unp1, vnp1, u_bc_bottom_wall, v_bc_bottom_wall) f.right_wall(unp1, vnp1, u_bc_right_wall(unp1[1:-1, -1]), v_bc_right_wall) f.left_wall(unp1, vnp1, u_bc_left_wall, v_bc_left_wall) time_end = time.clock() psol.append(press) cpu_time = time_end - time_start print(' cpu_time=', cpu_time) # Check mass residual div_np1 = np.linalg.norm(f.div(unp1, vnp1).ravel()) residual = div_np1 # if residual > 1e-12: print(' Mass residual:', residual) print('iterations:', iter) # save new solutions usol.append(unp1) vsol.append(vnp1) iterations.append(iter) t += dt # plot of the pressure gradient in order to make sure the solution is correct # # plt.contourf(usol[-1][1:-1,1:]) # if count % 10 ==0: # divu = f.div(unp1,vnp1) # plt.imshow(divu[1:-1,1:-1], origin='bottom') # plt.colorbar() # # ucc = 0.5 * (u[1:-1, 2:] + u[1:-1, 1:-1]) # # vcc = 0.5 * (v[2:, 1:-1] + v[1:-1, 1:-1]) # # speed = np.sqrt(ucc * ucc + vcc * vcc) # # uexact = 4 * 1.5 * ycc * (1 - ycc) # # plt.plot(uexact, ycc, '-k', label='exact') # # plt.plot(ucc[:, int(8 / dx)], ycc, '--', label='x = {}'.format(8)) # # plt.contourf(xcc, ycc, speed) # # plt.colorbar() # # plt.streamplot(xcc, ycc, ucc, vcc, color='black', density=0.75, linewidth=1.5) # # plt.contourf(xcc, ycc, speed) # # plt.colorbar() # plt.show() count += 1 if return_stability: return True else: return True, [total_iters], True, unp1[1:-1, 1:-1].ravel() # from singleton_classes import ProbDescription # # # Uinlet = 1 # ν = 0.01 # probDescription = ProbDescription(N=[4*32,32],L=[10,1],μ =ν,dt = 0.005) # dx,dy = probDescription.dx, probDescription.dy # dt = min(0.25*dx*dx/ν,0.25*dy*dy/ν, 4.0*ν/Uinlet/Uinlet) # probDescription.set_dt(dt) # error_channel_flow_FE (steps = 2000)
def error_RK3_with_post_projection(steps=3, return_stability=False, name='regular', guess=None, project=[1, 1], alpha=0.999, post_projection=False): # problem description probDescription = sc.ProbDescription() f = func(probDescription, 'periodic') dt = probDescription.get_dt() μ = probDescription.get_mu() nx, ny = probDescription.get_gridPoints() dx, dy = probDescription.get_differential_elements() # define exact solutions a = 2 * np.pi b = 2 * np.pi uexact = lambda a, b, x, y, t: 1 - np.cos(a * (x - t)) * np.sin(b * ( y - t)) * np.exp(-(a**2 + b**2) * μ * t) vexact = lambda a, b, x, y, t: 1 + np.sin(a * (x - t)) * np.cos(b * ( y - t)) * np.exp(-(a**2 + b**2) * μ * t) t = 0.0 tend = steps count = 0 print('dt=', dt) xcc, ycc = probDescription.get_cell_centered() xu, yu = probDescription.get_XVol() xv, yv = probDescription.get_YVol() # initialize velocities - we stagger everything in the negative direction. A scalar cell owns its minus face, only. # Then, for example, the u velocity field has a ghost cell at x0 - dx and the plus ghost cell at lx u0 = np.zeros([ny + 2, nx + 2]) # include ghost cells u0[1:-1, 1:] = uexact(a, b, xu, yu, 0) # initialize the interior of u0 # same thing for the y-velocity component v0 = np.zeros([ny + 2, nx + 2]) # include ghost cells v0[1:, 1:-1] = vexact(a, b, xv, yv, 0) f.periodic_u(u0) f.periodic_v(v0) # initialize the pressure p0 = np.zeros([nx + 2, ny + 2]) # include ghost cells #declare unp1 unp1 = np.zeros_like(u0) vnp1 = np.zeros_like(v0) div_np1 = np.zeros_like(p0) # a bunch of lists for animation purposes usol = [] usol.append(u0) vsol = [] vsol.append(v0) psol = [] psol.append(p0) iterations = [] Coef = f.A() is_stable = True stability_counter = 0 # # u and v num cell centered ucc = 0.5 * (u0[1:-1, 2:] + u0[1:-1, 1:-1]) vcc = 0.5 * (v0[2:, 1:-1] + v0[1:-1, 1:-1]) uexc = uexact(a, b, xu, yu, t) vexc = vexact(a, b, xv, yv, t) # u and v exact cell centered uexc_cc = 0.5 * (uexc[:, :-1] + uexc[:, 1:]) vexc_cc = 0.5 * (vexc[:-1, :] + vexc[1:, :]) # compute of kinetic energy ken_new = np.sum(ucc.ravel()**2 + vcc.ravel()**2) / 2 ken_exact = np.sum(uexc_cc.ravel()**2 + vexc_cc.ravel()**2) / 2 ken_old = ken_new final_KE = nx * ny target_ke = ken_exact - alpha * (ken_exact - final_KE) print('time = ', t) print('ken_new = ', ken_new) print('ken_exc = ', ken_exact) while count < tend: RK3 = sc.RK3(name) a21 = RK3.a21 a31 = RK3.a31 a32 = RK3.a32 b1 = RK3.b1 b2 = RK3.b2 b3 = RK3.b3 print('timestep:{}'.format(count + 1)) print('-----------') iter0 = 0 iter1 = 0 iter2 = 0 u = usol[-1].copy() v = vsol[-1].copy() pn = np.zeros_like(u) pnm1 = np.zeros_like(u) pnm2 = np.zeros_like(u) if count > 2: pn = psol[-1].copy() pnm1 = psol[-2].copy() pnm2 = psol[-3].copy() d1 = 0 d2, d3 = project f1x, f1y, f2x, f2y = f.Guess([pn, pnm1, pnm2], order=guess, integ='RK3', type=name) elif count <= 2: # compute pressures for 2 time steps d1 = 1 d2 = 1 d3 = 1 f1x, f1y, f2x, f2y = f.Guess([pn, pnm1, pnm2], order=None, integ='RK3', type=name) time_start = time.clock() print(' Stage 1:') print(' --------') u1 = u.copy() v1 = v.copy() # Au1 urhs1 = f.urhs(u1, v1) vrhs1 = f.vrhs(u1, v1) # divergence of u1 div_n = np.linalg.norm(f.div(u1, v1).ravel()) print(' divergence of u1 = ', div_n) ## stage 2 print(' Stage 2:') print(' --------') uh2 = u + a21 * dt * (urhs1 - f1x) vh2 = v + a21 * dt * (vrhs1 - f1y) if d2 == 1: print(' pressure projection stage{} = True'.format(2)) u2, v2, _, iter1 = f.ImQ(uh2, vh2, Coef, pn) print(' iterations stage 2 = ', iter1) elif d2 == 0: u2 = uh2 v2 = vh2 div2 = np.linalg.norm(f.div(u2, v2).ravel()) print(' divergence of u2 = ', div2) ## stage 3 print(' Stage 3:') print(' --------') urhs2 = f.urhs(u2, v2) vrhs2 = f.vrhs(u2, v2) uh3 = u + dt * (a31 * (urhs1 - f1x) + a32 * (urhs2 - f2x)) vh3 = v + dt * (a31 * (vrhs1 - f1y) + a32 * (vrhs2 - f2y)) if d3 == 1: print(' pressure projection stage{} = True'.format(3)) u3, v3, _, iter2 = f.ImQ(uh3, vh3, Coef, pn) print(' iterations stage 3 = ', iter2) elif d3 == 0: u3 = uh3 v3 = vh3 div3 = np.linalg.norm(f.div(u3, v3).ravel()) print(' divergence of u3 = ', div3) uhnp1 = u + dt * b1 * (urhs1) + dt * b2 * (urhs2) + dt * b3 * (f.urhs( u3, v3)) vhnp1 = v + dt * b1 * (vrhs1) + dt * b2 * (vrhs2) + dt * b3 * (f.vrhs( u3, v3)) unp1, vnp1, press, iter3 = f.ImQ(uhnp1, vhnp1, Coef, pn) if post_projection: # post processing projection uhnp1_star = u + dt * (f.urhs(unp1, vnp1)) vhnp1_star = v + dt * (f.vrhs(unp1, vnp1)) _, _, press, _ = f.ImQ(uhnp1_star, vhnp1_star, Coef, pn) time_end = time.clock() psol.append(press) cpu_time = time_end - time_start print(' cpu_time=', cpu_time) # Check mass residual div_np1 = np.linalg.norm(f.div(unp1, vnp1).ravel()) residual = div_np1 # if residual > 1e-12: print(' Mass residual:', residual) print(' iterations last stage = ', iter3) # save new solutions usol.append(unp1) vsol.append(vnp1) iterations.append(iter1 + iter2 + iter3) # # u and v num cell centered ucc = 0.5 * (u[1:-1, 2:] + u[1:-1, 1:-1]) vcc = 0.5 * (v[2:, 1:-1] + v[1:-1, 1:-1]) uexc = uexact(a, b, xu, yu, t) vexc = vexact(a, b, xv, yv, t) # u and v exact cell centered uexc_cc = 0.5 * (uexc[:, :-1] + uexc[:, 1:]) vexc_cc = 0.5 * (vexc[:-1, :] + vexc[1:, :]) t += dt # compute of kinetic energy ken_new = np.sum(ucc.ravel()**2 + vcc.ravel()**2) / 2 ken_exact = np.sum(uexc_cc.ravel()**2 + vexc_cc.ravel()**2) / 2 print('time = ', t) print('ken_new = ', ken_new) print('target_ken=', target_ke) print('ken_exc = ', ken_exact) print('(ken_new - ken_old)/ken_old = ', (ken_new - ken_old) / ken_old) if (((ken_new - ken_old) / ken_old) > 0 and count > 1) or np.isnan(ken_new): is_stable = False print('is_stable = ', is_stable) if stability_counter > 5: print('not stable !!!!!!!!') break else: stability_counter += 1 else: is_stable = True print('is_stable = ', is_stable) if ken_new < target_ke and count > 30: break ken_old = ken_new.copy() #plot of the pressure gradient in order to make sure the solution is correct # if count %10 == 0: # # # plt.contourf(usol[-1][1:-1,1:]) # plt.contourf((psol[-1][1:-1,1:] - psol[-1][1:-1,:-1])/dx) # plt.colorbar() # plt.show() count += 1 diff = np.linalg.norm( uexact(a, b, xu, yu, t).ravel() - unp1[1:-1, 1:].ravel(), np.inf) print(' error={}'.format(diff)) if return_stability: return is_stable else: return diff, [div_n, div2, div3, div_np1], is_stable, unp1[1:-1, 1:].ravel()
def Simulated_Annealing(x1, x2, y1, y2): # Temperature definecurrent_cost T_Max = 100000 T_Min = 0.0001 T = T_Max cooling_rate = 0.99999 probability = 0 counter = 0 cost_list = [] step_list = [] prob_list = [] t_list = [] x_list = [] y_list = [] # Initial State current_state_x = randint(x1, x2) current_state_y = randint(y1, y2) current_cost = func(current_state_x, current_state_y) cost_list.append(abs(current_cost)) step_list.append(counter) t_list.append(T) x_list.append(current_state_x) y_list.append(current_state_y) prob_list.append(0) got_change_list = [] got_change_list.append(0) counter = counter + 1 while T > T_Min: # generate next state next_state_x, next_state_y = generate_NextState( x1, x2, y1, y2, current_state_x, current_state_y) # calculate next cost next_cost = func(next_state_x, next_state_y) # calculate delta energy cost between current state and next state delta = next_cost - current_cost # if next state cost is better than current if (delta < 0): current_state_x = next_state_x current_state_y = next_state_y current_cost = next_cost got_change_list.append(0) # next state is worse than current one else: probability = Acceptance(delta, T) threshold = uniform(0, 1) # randomly give a chance to replace if (threshold < probability): current_state_x = next_state_x current_state_y = next_state_y current_cost = next_cost got_change_list.append(1) else: got_change_list.append(0) # Update Temperature T = T * cooling_rate # plot graph - list t_list.append(T) step_list.append(counter) cost_list.append(abs(current_cost)) x_list.append(current_state_x) y_list.append(current_state_y) prob_list.append(probability) counter = counter + 1 # plt.plot(t_list[::200],got_change_list[::200],'b-') # plt.xlabel('Temperature Variation') # plt.ylabel('Second Chance is Accepted') # plt.show() print('------ Simulated_Annealing ------') print(current_state_x) print(current_state_y) print('{:.3f}'.format(current_cost))