def _get_qfs(self): # construct qfs evaluators for the interface sign = 1 if self.interior else -1 # singular construction; not in use right now # until I make a version of QFS that is compatible with # pressure fixes and the singular operators if False: self.Singular_SLP = lambda src, _: Stokes_Layer_Singular_Form( src, ifforce=True) self.Singular_DLP_G = lambda src, _: Stokes_Layer_Singular_Form( src, ifdipole=True) - sign * 0.5 * np.eye(2 * self.ebdy.bdy.N) self.Singular_DLP_R = lambda src, _: Stokes_Layer_Singular_Form( src, ifdipole=True) + sign * 0.5 * np.eye(2 * self.ebdy.bdy.N) self.Naive_SLP = lambda src, trg: Fixed_SLP(src, trg) self.interface_qfs_g = QFS_Evaluator( self.ebdy.interface_qfs, self.interior, [self.Singular_SLP, self.Singular_DLP_G], self.Naive_SLP, on_surface=True, form_b2c=False, vector=True) self.interface_qfs_r = QFS_Evaluator( self.ebdy.interface_qfs, not self.interior, [self.Singular_SLP, self.Singular_DLP_R], self.Naive_SLP, on_surface=True, form_b2c=False, vector=True) else: # the non-singular construction self.interface_qfs_g = Stokes_Converter(self.ebdy, self.interior) self.interface_qfs_r = Stokes_Converter(self.ebdy, not self.interior)
def _get_qfs(self): # construct qfs evaluators for the interface self.interface_qfs_1 = QFS_Evaluator(self.ebdy.interface_qfs, self.interior, [Singular_SLP,], Naive_SLP, on_surface=True, form_b2c=False) self.interface_qfs_2 = QFS_Evaluator(self.ebdy.interface_qfs, not self.interior, [Singular_SLP,], Naive_SLP, on_surface=True, form_b2c=False) # construct qfs evaluator for the boundary self.boundary_qfs = QFS_Evaluator(self.ebdy.interface_qfs, self.interior, [Singular_SLP, self.Singular_DLP], Naive_SLP, on_surface=True, form_b2c=False)
def _get_qfs(self): # construct qfs evaluators for the interface self.interface_qfs_1 = QFS_Evaluator( self.ebdy.interface_qfs, self.interior, [self.Singular_SLP, self.Singular_DLP_I], self.Fixed_SLP, on_surface=True, form_b2c=False, vector=True) self.interface_qfs_2 = QFS_Evaluator( self.ebdy.interface_qfs, not self.interior, [self.Singular_SLP, self.Singular_DLP_E], self.Fixed_SLP, on_surface=True, form_b2c=False, vector=True)
def __init__(self, ebdy, interior=True, interior_point=None): qfs = ebdy.interface_qfs bdy = ebdy.interface h = bdy.speed[0] * bdy.dt self.bdy = bdy self.interior = interior if self.interior: self.src = qfs.interior_source_bdy sign = -1 else: self.src = qfs.exterior_source_bdy sign = 1 if interior_point is None: self.pressure_targ_x = bdy.x[0] + sign * 6 * bdy.normal_x[0] * h self.pressure_targ_y = bdy.y[0] + sign * 6 * bdy.normal_y[0] * h else: self.pressure_targ_x = interior_point[0] self.pressure_targ_y = interior_point[1] self.sh = [2, self.src.N] Singular_SLP = lambda src, _: Stokes_Layer_Singular_Form(src, ifforce=True) Singular_DLP = lambda src, _: Stokes_Layer_Singular_Form( src, ifdipole=True) + sign * 0.5 * np.eye(2 * src.N) Naive_SLP = lambda src, trg: Stokes_Layer_Form(src, trg, ifforce=True) def Stokes_Pressure_Fix(src, trg): Nxx = trg.normal_x[:, None] * src.normal_x Nxy = trg.normal_x[:, None] * src.normal_y Nyx = trg.normal_y[:, None] * src.normal_x Nyy = trg.normal_y[:, None] * src.normal_y NN = np.array(np.bmat([[Nxx, Nxy], [Nyx, Nyy]])) return NN def Fixed_SLP(src, trg): return Naive_SLP(src, trg) + Stokes_Pressure_Fix(src, trg) self.qfs = QFS_Evaluator(qfs, self.interior, b2c_funcs=[Singular_SLP, Singular_DLP], s2c_func=Fixed_SLP, form_b2c=True, on_surface=True, vector=True)
mue = np.ma.array(ue, mask=ebdyc.ext) if plot: fig, ax = plt.subplots() ax.pcolormesh(grid.xg, grid.yg, mue) ax.plot(ebdy.bdy.x, ebdy.bdy.y, color='black', linewidth=3) ax.plot(ebdy.interface.x, ebdy.interface.y, color='white', linewidth=3) # this isn't correct yet because we haven't applied boundary conditions A = Laplace_Layer_Singular_Form(bdy, ifdipole=True) - 0.5 * np.eye(bdy.N) bv = solver.get_boundary_values(uers) tau = np.linalg.solve(A, bcs2v - bv) qfs = QFS_Evaluator(ebdy.bdy_qfs, True, [ Singular_DLP, ], Naive_SLP, on_surface=True, form_b2c=False) sigma = qfs([ tau, ]) out = Laplace_Layer_Apply(ebdyc.bdy_inward_sources, ebdyc.grid_and_radial_pts, charge=sigma) gslp, rslpl = ebdyc.divide_grid_and_radial(out) rslp = rslpl[0] uer += rslp.reshape(uer.shape) ue[ebdyc.phys] += gslp if plot:
c0.define_via_function(c0_function) # now timestep c = c0.copy() t = 0.0 x_tracers = [] y_tracers = [] ts = [] new_ebdyc = ebdyc qfs1 = QFS_Evaluator(new_ebdyc.ebdys[0].bdy_qfs, True, [ Singular_SLP1, ], Naive_SLP1, on_surface=True, form_b2c=False) qfs2 = QFS_Evaluator(new_ebdyc.ebdys[0].bdy_qfs, True, [ Singular_SLP2, ], Naive_SLP2, on_surface=True, form_b2c=False) qfs3 = QFS_Evaluator(new_ebdyc.ebdys[0].bdy_qfs, True, [ Singular_SLP3, ], Naive_SLP3,
def Stokes_Pressure_Fix(src, trg): Nxx = trg.normal_x[:,None]*src.normal_x*src.weights Nxy = trg.normal_x[:,None]*src.normal_y*src.weights Nyx = trg.normal_y[:,None]*src.normal_x*src.weights Nyy = trg.normal_y[:,None]*src.normal_y*src.weights NN = np.array(np.bmat([[Nxx, Nxy], [Nyx, Nyy]]))/np.sum(src.speed*src.weights) return NN def Fixed_SLP(src, trg): return Naive_SLP(src, trg) + Stokes_Pressure_Fix(src, trg) A = Stokes_Layer_Singular_Form(bdy, ifdipole=True) - 0.5*np.eye(2*bdy.N) + Stokes_Pressure_Fix(bdy, bdy) bu, bv = solver.get_bv(ur, vr) buc = np.concatenate([bu, bv]) bc = np.concatenate([upper_u, upper_v]) tau = np.linalg.solve(A, bc-buc) qfs = QFS_Evaluator(ebdy.bdy_qfs, True, [Singular_DLP,], Fixed_SLP, on_surface=True, form_b2c=False, vector=True) sigma = qfs([tau,]) rslp = Stokes_Layer_Apply(ebdy.bdy_qfs.interior_source_bdy, solver.radp, forces=sigma, out_type='stacked') gslp = Stokes_Layer_Apply(ebdy.bdy_qfs.interior_source_bdy, solver.gridpa, forces=sigma, out_type='stacked') ur += rslp[0].reshape(ur.shape) vr += rslp[1].reshape(ur.shape) uc[ebdy.phys] += gslp[0] vc[ebdy.phys] += gslp[1] if plot: mue = np.ma.array(uc, mask=ebdy.ext) fig, ax = plt.subplots() ax.pcolormesh(grid.xg, grid.yg, mue) ax.plot(ebdy.bdy.x, ebdy.bdy.y, color='black', linewidth=3) ax.plot(ebdy.interface.x, ebdy.interface.y, color='white', linewidth=3, alpha=0.2)
# separate this into pieces taul = ebdyc.v2l(tau) # get effective sources qfs_list = [] Naive_SLP = lambda src, trg: MH_Layer_Form( src, trg, ifcharge=True, k=helmholtz_k) for ebdy in ebdys: def Kernel_Function(src, trg): return src.Modified_Helmholtz_SLP_Self_Form(k=helmholtz_k) qfs = QFS_Evaluator(ebdy.bdy_qfs, ebdy.interior, [ Kernel_Function, ], Naive_SLP, on_surface=True, form_b2c=False) qfs_list.append(qfs) # compute sigmas sigmal = [qfs([tau]) for qfs, tau in zip(qfs_list, taul)] sigmav = np.concatenate(sigmal) print('Evaluating homogeneous solution') # evaluate this onto all gridpoints and radial points out = MH_Layer_Apply(ebdyc.bdy_inward_sources, ebdyc.grid_and_radial_pts, charge=sigmav, k=helmholtz_k)
if ebdy.interior: def Kernel_Function(src, trg): return Stokes_Layer_Singular_Form( src, ifdipole=True) - 0.5 * np.eye(2 * src.N) else: def Kernel_Function(src, trg): return Stokes_Layer_Singular_Form( src, ifdipole=True, ifforce=True) + 0.5 * np.eye(2 * src.N) print(ebdy.interior) qfs = QFS_Evaluator(ebdy.bdy_qfs, ebdy.interior, [ Kernel_Function, ], Fixed_SLP, on_surface=True, form_b2c=False, vector=True) qfs_list.append(qfs) sigmal = [qfs([ tau, ]) for qfs, tau in zip(qfs_list, taul)] sigmav = np.column_stack([v2f(sigma) for sigma in sigmal]) out = Stokes_Layer_Apply(ebdyc.bdy_inward_sources, ebdyc.grid_and_radial_pts, forces=sigmav) outu, outv = v2f(out) gslpu, rslplu = ebdyc.divide_grid_and_radial(outu)
_ = new_ebdyc.interpolate_radial_to_grid(c_new.radial_value_list, c_new.grid_value) # now solve diffusion equation solver = ModifiedHelmholtzSolver(new_ebdyc, solver_type='spectral', k=helmholtz_k) c_new_update = solver(c_new / zeta, tol=1e-12, verbose=False) A = s_singular(new_ebdyc.ebdys[0].bdy) - half_eye(new_ebdyc.ebdys[0].bdy) bvn = solver.get_boundary_normal_derivatives( c_new_update.radial_value_list) tau = np.linalg.solve(A, bvn) qfs = QFS_Evaluator(new_ebdyc.ebdys[0].bdy_qfs, True, [ Singular_SLP, ], Naive_SLP, on_surface=True, form_b2c=False) sigma = qfs([ tau, ]) out = MH_Layer_Apply(new_ebdyc.bdy_inward_sources, new_ebdyc.grid_and_radial_pts, charge=sigma, k=helmholtz_k) gslp, rslpl = new_ebdyc.divide_grid_and_radial(out) rslp = rslpl[0] c_new_update.radial_value_list[0] += rslp.reshape(M, nb) c_new_update.grid_value[new_ebdyc.phys] += gslp c_new = c_new_update