def norm_der(x, y): u_x = A * np.cos(A * x) * np.cos(B * y) u_y = -B * np.sin(A * x) * np.sin(B * y) n_x = alpha**2 * x / (hf.XYtoR(alpha * x, beta * y) + singular_null) n_y = beta**2 * y / (hf.XYtoR(alpha * x, beta * y) + singular_null) u_n = (u_x * n_x + u_y * n_y) / (hf.XYtoR(n_x, n_y) + singular_null) return u_n
def norm_der(x, y): u_x = -0.5 * (x - x0) u_y = -0.5 * (y - y0) n_x = x / (hf.XYtoR(x, y) + singular_null) n_y = y / (hf.XYtoR(x, y) + singular_null) u_n = (u_x * n_x + u_y * n_y) / (hf.XYtoR(n_x, n_y) + singular_null) return u_n
def norm_der(x, y): theta = hf.XYtoTheta(x, y) r = hf.XYtoR(x, y) u_x = A * np.cos(A * x) * np.cos(B * y) u_y = -B * np.sin(A * x) * np.sin(B * y) dphi_dr = 1. dphi_dtheta = -coef * theta_coef * np.cos(theta_coef * theta + theta_const) n_x = np.cos(theta) * dphi_dr - np.sin(theta) * dphi_dtheta / ( r + singular_null) n_y = np.sin(theta) * dphi_dr + np.cos(theta) * dphi_dtheta / ( r + singular_null) u_n = (u_x * n_x + u_y * n_y) / (hf.XYtoR(n_x, n_y) + singular_null) return u_n
def sigma(x,y): return -0.25 * (hf.XYtoR(x-x0, y-y0)+10**-17)
def level(x,y): return np.array(hf.XYtoR(x,y) - r0)
def poisson_jacobi_solver(u_init_, maxIterNum_, mesh_, beta_, rhs_func_, lvl_func_, jmp_func_): xmesh, ymesh = mesh_ beta_p, beta_m = beta_ #level grid phi = lvl_func_(xmesh,ymesh) h = xmesh[0,1]-xmesh[0,0] # u = u_init_ u=np.zeros_like(xmesh) # normal r_temp = hf.XYtoR(xmesh, ymesh) + 10**-17 n1, n2 = xmesh/r_temp, ymesh/r_temp # the source on the rhs #source = np.zeros_like(u) source = np.zeros_like(xmesh) isOut = np.array(np.greater(phi,0.0),dtype = int) source += (1.0 - isOut) * rhs_func_(xmesh, ymesh) a_mesh, b_mesh = jmp_func_(xmesh, ymesh, u_init_) def get_theta(u_cur,u_next): return np.abs(u_cur)/(np.abs(u_cur)+np.abs(u_next)) def get_effective_beta(beta_cur,beta_next,theta): ret = beta_cur * beta_next / (beta_next * theta + beta_cur * (1-theta)) return ret beta_x = np.zeros_like(xmesh[:,1:]) beta_y = np.zeros_like(ymesh[1:,:]) isOutx1 = np.array(np.greater(phi[:,1:],0.0),dtype = int) isOutx2 = np.array(np.greater(phi[:,:-1],0.0),dtype = int) isOuty1 = np.array(np.greater(phi[1:,:],0.0),dtype = int) isOuty2 = np.array(np.greater(phi[:-1,:],0.0),dtype = int) # step is 1 if k+1 is out and k is in # step is -1 if k is out and k+1 is in # step is 0 if both out or in xstep = isOutx1 - isOutx2 ystep = isOuty1 - isOuty2 xstep_p = np.array(np.greater( xstep,0.0),dtype = int) xstep_m = np.array(np.greater(-xstep,0.0),dtype = int) ystep_p = np.array(np.greater( ystep,0.0),dtype = int) ystep_m = np.array(np.greater(-ystep,0.0),dtype = int) theta_x = get_theta(phi[:,:-1],phi[:,1:]) theta_y = get_theta(phi[:-1,:],phi[1:,:]) beta_eff_x = np.zeros_like(beta_x) beta_eff_y = np.zeros_like(beta_y) beta_eff_x += xstep_p * get_effective_beta(beta_m,beta_p,theta_x) beta_eff_x += xstep_m * get_effective_beta(beta_p,beta_m,theta_x) beta_eff_y += ystep_p * get_effective_beta(beta_m,beta_p,theta_y) beta_eff_y += ystep_m * get_effective_beta(beta_p,beta_m,theta_y) a_jump_x = a_mesh[:,:-1] * (1-theta_x) + a_mesh[:,1:] * theta_x a_jump_y = a_mesh[:-1,:] * (1-theta_y) + a_mesh[1:,:] * theta_y b_jump_x = b_mesh[:,:-1]*(1-theta_x)*n1[:,:-1] + b_mesh[:,1:]*theta_x*n1[:,1:] b_jump_y = b_mesh[:-1,:]*(1-theta_y)*n2[:-1,:] + b_mesh[1:,:]*theta_y*n2[1:,:] # first additional term source[:,:-1] += a_jump_x * beta_eff_x*xstep/h**2 source[:, 1:] += -a_jump_x * beta_eff_x*xstep/h**2 source[:-1,:] += a_jump_y * beta_eff_y*ystep/h**2 source[ 1:,:] += -a_jump_y * beta_eff_y*ystep/h**2 beta_x_k = ((beta_p + beta_m) + (beta_p - beta_m)*xstep)/2 beta_x_kp1 = ((beta_p + beta_m) - (beta_p - beta_m)*xstep)/2 beta_y_k = ((beta_p + beta_m) + (beta_p - beta_m)*ystep)/2 beta_y_kp1 = ((beta_p + beta_m) - (beta_p - beta_m)*ystep)/2 # second additional term source[:,:-1] += (b_jump_x * beta_eff_x * xstep / h) * ((1-theta_x)/beta_x_k) source[:, 1:] += (b_jump_x * beta_eff_x * xstep / h) * (theta_x/beta_x_kp1) source[:-1,:] += (b_jump_y * beta_eff_y * ystep / h) * ((1-theta_y)/beta_y_k) source[ 1:,:] += (b_jump_y * beta_eff_y * ystep / h) * (theta_y/beta_y_kp1) isBoundary_x = np.abs(xstep) isBoundary_y = np.abs(ystep) beta_x += beta_eff_x * isBoundary_x beta_x += isOutx2 * (1-isBoundary_x) * beta_p beta_x += (1-isOutx2) * (1-isBoundary_x) * beta_m beta_y += beta_eff_y * isBoundary_y beta_y += isOuty2 * (1-isBoundary_y) * beta_p beta_y += (1-isOuty2) * (1-isBoundary_y) * beta_m beta_sum = beta_x[1:-1,:-1] + beta_x[1:-1,1:] + beta_y[:-1,1:-1] + beta_y[1:,1:-1] # source_bcc = np.copy(source) # # a_jump_x = a_mesh[:,:-1] * theta_x + a_mesh[:,1:] * (1 - theta_x) # a_jump_y = a_mesh[:-1,:] * theta_y + a_mesh[1:,:] * (1 - theta_y) # # b_jump_x = b_mesh[:,:-1]*theta_x*n1[:,:-1] + b_mesh[:,1:]*(1-theta_x)*n1[:,1:] # b_jump_y = b_mesh[:-1,:]*theta_y*n2[:-1,:] + b_mesh[1:,:]*(1-theta_y)*n2[1:,:] # # # first additional term # source_bcc[:,:-1] += a_jump_x * beta_eff_x*xstep/h**2 # source_bcc[:,1:] += -a_jump_x * beta_eff_x*xstep/h**2 # source_bcc[:-1,:] += a_jump_y * beta_eff_y*ystep/h**2 # source_bcc[1:,:] += -a_jump_y * beta_eff_y*ystep/h**2 # # second additional term # source_bcc[:,:-1] += (b_jump_x * beta_eff_x * xstep / h) * ((1-theta_x)/beta_x_k) # source_bcc[:,1:] += (b_jump_x * beta_eff_x * xstep / h) * (theta_x/beta_x_kp1) # source_bcc[:-1,:] += (b_jump_y * beta_eff_y * ystep / h) * ((1-theta_y)/beta_y_k) # source_bcc[1:,:] += (b_jump_y * beta_eff_y * ystep / h) * (theta_y/beta_y_kp1) # plt.pcolor(xmesh,ymesh,source) # plt.xlabel("x") # plt.ylabel("y") # plt.colorbar() #record data u_prev = u*(1-isOut) global iterNum_record iterNum_record = 0 for i in range(maxIterNum_): iterNum_record += 1 # enforce boundary condition # sol = solution1(xmesh, ymesh) u[ 0, :] = np.zeros_like(u[ 0, :]) u[-1, :] = np.zeros_like(u[-1, :]) u[ :, 0] = np.zeros_like(u[ :, 0]) u[ :,-1] = np.zeros_like(u[ :,-1]) u_new = np.copy(u) # update u according to Jacobi method formula # https://en.wikipedia.org/wiki/Jacobi_method del_u = u[1:-1,2:]*beta_x[1:-1,1:] + u[1:-1,0:-2]*beta_x[1:-1,0:-1] +\ u[2:,1:-1]*beta_y[1:,1:-1] + u[0:-2,1:-1]*beta_y[0:-1,1:-1] u_new[1:-1,1:-1] = -h**2/beta_sum * (source[1:-1,1:-1] - del_u/h**2) u = u_new # check convergence and print process check_convergence_rate = 10**-11 if(i % int(maxIterNum_/100) < 0.1): u_cur = u* (1-isOut) maxDif = np.max(np.abs(u_cur - u_prev)) / np.max(np.abs(u_cur)) L2Dif = hf.L_n_norm(np.abs(u_cur - u_prev)) / hf.L_n_norm(u_cur) if(L2Dif < check_convergence_rate): break; else: u_prev = u_cur sys.stdout.write("\rProgress: %4g%%" % (i *100.0/maxIterNum_)) sys.stdout.flush() print("") return u
def level(x, y): theta = np.arctan(y / (x + singular_null)) r = hf.XYtoR(x, y) return -(const + coef * np.sin(theta_coef * theta + theta_const) - r)
def level(x, y): return -0.9 + hf.XYtoR(alpha * x, beta * y)