Пример #1
0
 def _set_derivative_method(self):
     if self.solver_type == 'spectral':
         self.dx = lambda x: fourier(x, self.ikx)
         self.dy = lambda x: fourier(x, self.iky)
     else:
         self.dx = lambda x: fd_x_4(x, self.ebdyc.grid.xh)
         self.dy = lambda x: fd_y_4(x, self.ebdyc.grid.yh)
Пример #2
0
 def laplacian(self, ff, derivative_type='spectral'):
     """
     Compute the laplacian of a function defined on the embedded boundary collection
     Inputs:
         ff, EmbeddedFunction: function to take the gradient of
         derivative_type: 'spectral' or 'fourth'
             in both cases, spectral differentation is used in the radial
             regions. On the grid, if 'spectral', then the function is cutoff
             and fourier based estimation of the derivative is used;
             if 'fourth', then the function is NOT cutoff and fourth-order
             centered differences are used.  This may provide better accuracy
             when the cutoff windows are thin.  However, if the cutoff windows
             are not at least 2h, then this can give catastrophically bad values
     Outputs:
         lapf: EmbeddedFunction giving the laplacian of f
     """
     f, _, fr_list = ff.get_components()
     if derivative_type == 'spectral':
         fc = f * self.grid_step
         fc[self.ext] = 0.0
         fch = np.fft.fft2(fc)
         lapfh = fch * self.lap
         lapf = np.fft.ifft2(lapfh).real
     else:
         fx = fd_x_4(f, self.grid.xh)
         fy = fd_y_4(f, self.grid.yh)
         fxx = fd_x_4(fx, self.grid.xh)
         fyy = fd_y_4(fy, self.grid.yh)
     # compute on the radial grid
     lapfrs = []
     for i in range(self.N):
         lapfr = self.ebdys[i].laplacian(lapf, fr_list[i])
         lapfrs.append(lapfr)
     # set to 0 on regular grid in the exterior region
     lapf *= self.phys
     # generate EmbeddedFunctions
     lapff = EmbeddedFunction(self)
     lapff.load_data(lapf, lapfrs)
     return lapff
Пример #3
0
 def gradient(self, ff, derivative_type='spectral'):
     """
     Compute the gradient of a function defined on the embedded boundary collection
     Inputs:
         ff, EmbeddedFunction: function to take the gradient of
         derivative_type: 'spectral' or 'fourth'
             in both cases, spectral differentation is used in the radial
             regions. On the grid, if 'spectral', then the function is cutoff
             and fourier based estimation of the derivative is used;
             if 'fourth', then the function is NOT cutoff and fourth-order
             centered differences are used.  This may provide better accuracy
             when the cutoff windows are thin.  However, if the cutoff windows
             are not at least 2h, then this can give catastrophically bad values
     Outputs:
         fx, fy: EmbeddedFunctions giving each required derivative
     """
     f, _, fr_list = ff.get_components()
     if derivative_type == 'spectral':
         fc = f * self.grid_step
         fc[self.ext] = 0.0
         fch = np.fft.fft2(fc)
         fxh = fch * self.ikx
         fyh = fch * self.iky
         fx = np.fft.ifft2(fxh).real
         fy = np.fft.ifft2(fyh).real
     else:
         fx = fd_x_4(f, self.grid.xh)
         fy = fd_y_4(f, self.grid.yh)
     # compute on the radial grid
     fxrs, fyrs = [], []
     for i in range(self.N):
         fxr, fyr = self[i].gradient(fx, fy, fr_list[i])
         fxrs.append(fxr)
         fyrs.append(fyr)
     # set to 0 on regular grid in the exterior region
     fx *= self.phys
     fy *= self.phys
     # generate EmbeddedFunctions
     ffx = EmbeddedFunction(self)
     ffy = EmbeddedFunction(self)
     ffx.load_data(fx, fxrs)
     ffy.load_data(fy, fyrs)
     return ffx, ffy
        by = ebdy.bdy.y + dt * vb

        bx, by, new_t = arc_length_parameterize(bx, by, return_t=True)
        bu_interp = interp1d(0, 2 * np.pi, bdy.dt, ub, p=True)
        bv_interp = interp1d(0, 2 * np.pi, bdy.dt, vb, p=True)
        # old boundary velocity values have to be in the correct place
        ubo_new_parm = bu_interp(new_t)
        vbo_new_parm = bv_interp(new_t)
        ubo = ub.copy()
        vbo = vb.copy()

        x_tracers.append(bx)
        y_tracers.append(by)

        # take gradients of the velocity fields
        dx = lambda f: fd_x_4(f, grid.xh, periodic_fix=True)
        dy = lambda f: fd_y_4(f, grid.yh, periodic_fix=True)
        if u_differentiation_type == 'spectral':
            ux, uy = ebdyc.gradient2(u, xder, yder, cutoff=True)
            vx, vy = ebdyc.gradient2(v, xder, yder, cutoff=True)
        elif u_differentiation_type == 'fourth':
            ux, uy = ebdyc.gradient2(u, dx, dy, cutoff=False)
            vx, vy = ebdyc.gradient2(v, dx, dy, cutoff=False)
        else:
            ux = EmbeddedFunction(ebdyc)
            uy = EmbeddedFunction(ebdyc)
            vx = EmbeddedFunction(ebdyc)
            vy = EmbeddedFunction(ebdyc)
            ux.define_via_function(lambda x, y: ux_function(x, y, t))
            uy.define_via_function(lambda x, y: uy_function(x, y, t))
            vx.define_via_function(lambda x, y: vx_function(x, y, t))
Пример #5
0
err = max(errs)
print('Error in grid --> interface interpolation: {:0.2e}'.format(err))

# Interpolation of a function from radial to grid
frs = [test_func(ebdy.radial_x, ebdy.radial_y) for ebdy in ebdys]
fts = ebdyc.interpolate_radial_to_grid(frs)
fes = [test_func(ebdy.grid_ia_x, ebdy.grid_ia_y) for ebdy in ebdys]
errs = [np.abs(fe - ft).max() for fe, ft in zip(fes, fts)]
err = max(errs)
print('Error in radial --> grid interpolation:    {:0.2e}'.format(err))

################################################################################
# Test derivatives

# fourth order accurate gradient on whole domain
dx = lambda x: fd_x_4(x, grid.xh, periodic_fix=True)
dy = lambda x: fd_y_4(x, grid.yh, periodic_fix=True)
fxe, fye, fxres, fyres = ebdyc.gradient(f, frs, dx, dy, cutoff=False)
fxt = test_func_x(grid.xg, grid.yg)
fyt = test_func_y(grid.xg, grid.yg)
err_x = np.abs(fxt - fxe)[ebdyc.phys].max()
err_y = np.abs(fyt - fye)[ebdyc.phys].max()
err = max(err_x, err_y)
print('Error in gradient, 4th order FD:           {:0.2e}'.format(err))

# spectrally accurate gradient on whole domain
kxv = np.fft.fftfreq(grid.Nx, grid.xh / (2 * np.pi))
kyv = np.fft.fftfreq(grid.Ny, grid.yh / (2 * np.pi))
kx, ky = np.meshgrid(kxv, kyv, indexing='ij')
ikx, iky = 1j * kx, 1j * ky
dx = lambda x: fourier(x, ikx)
Пример #6
0
print('Error in radial --> grid interpolation:    {:0.2e}'.format(err))

################################################################################
# Test derivatives

# radial gradient
frxe, frye = ebdy.radial_grid_derivatives(fr)
frxt = test_func_x(ebdy.radial_x, ebdy.radial_y)
fryt = test_func_y(ebdy.radial_x, ebdy.radial_y)
err_x = np.abs(frxt-frxe).max()
err_y = np.abs(fryt-frye).max()
err = max(err_x, err_y)
print('Error in radial grid differentiation:      {:0.2e}'.format(err))

# fourth order accurate gradient on whole domain
dx = lambda x: fd_x_4(x, grid.xh, periodic_fix=not interior)
dy = lambda x: fd_y_4(x, grid.yh, periodic_fix=not interior)
fxe, fye, fxre, fyre = ebdy.gradient(f, fr, dx, dy)
fxt = test_func_x(grid.xg, grid.yg)
fyt = test_func_y(grid.xg, grid.yg)
err_x = np.abs(fxt-fxe)[ebdy.phys].max()
err_y = np.abs(fyt-fye)[ebdy.phys].max()
err = max(err_x, err_y)
print('Error in gradient, 4th order FD:           {:0.2e}'.format(err))

# spectrally accurate gradient on whole domain
kxv = np.fft.fftfreq(grid.Nx, grid.xh/(2*np.pi))
kyv = np.fft.fftfreq(grid.Ny, grid.yh/(2*np.pi))
kx, ky = np.meshgrid(kxv, kyv, indexing='ij')
ikx, iky = 1j*kx, 1j*ky
dx = lambda x: fourier(x, ikx)
Пример #7
0
ebdyc.register_grid(grid)

# initial c field
c0 = EmbeddedFunction(ebdyc)
c0.define_via_function(c0_function)


def xder(f):
    return np.fft.ifft2(np.fft.fft2(f) * ikx).real


def yder(f):
    return np.fft.ifft2(np.fft.fft2(f) * iky).real


xder = lambda f: fd_x_4(f, grid.xh)
yder = lambda f: fd_y_4(f, grid.yh)

# now timestep
c = c0.copy()
t = 0.0

x_tracers = []
y_tracers = []
ts = []

new_ebdyc = ebdyc

qfs0 = QFS_Evaluator(new_ebdyc.ebdys[0].bdy_qfs,
                     True, [
                         Singular_SLP0,