################################################################################
# Semi-Lagrangian Non-linear departure point method

print('\nSemi-Lagrangian Method')

# get heaviside function
MOL = SlepianMollifier(slepian_r)

# construct boundary and reparametrize
bdy = GSB(c=star(nb, x=0.0, y=0.0, a=0.0, f=3))
bdy = GSB(*arc_length_parameterize(bdy.x, bdy.y))
bh = bdy.dt * bdy.speed.min()
# construct embedded boundary
ebdy = EmbeddedBoundary(bdy, True, M, bh, pad_zone, MOL.step)
ebdyc = EmbeddedBoundaryCollection([
    ebdy,
])
# get a grid
grid = Grid([xmin, xmax],
            ngx, [ymin, ymax],
            ngy,
            x_endpoints=[True, False],
            y_endpoints=[True, False])
ebdyc.register_grid(grid)

original_ebdy = ebdy

# initial c field
c0 = EmbeddedFunction(ebdyc)
c0.define_via_function(c0_function)
Exemple #2
0
if reparametrize:
    bdy = GSB(*arc_length_parameterize(bdy.x, bdy.y))
# get h to use for radial solvers and grid
bh = bdy.dt * bdy.speed.min()
# construct embedded boundary
ebdy = EmbeddedBoundary(bdy,
                        True,
                        M,
                        bh / grid_upsample,
                        pad_zone=0,
                        heaviside=MOL.step,
                        qfs_tolerance=qfs_tolerance,
                        coordinate_tolerance=coordinate_tolerance,
                        coordinate_scheme=coordinate_scheme)
ebdyc = EmbeddedBoundaryCollection([
    ebdy,
])
grid = ebdyc.generate_grid(bh / grid_upsample)
ebdyc.register_grid(grid, verbose=verbose)
ebdyc.ready_bump(MOL.bump, (grid.x_bounds[1] - ebdy.radial_width,
                            grid.y_bounds[1] - ebdy.radial_width),
                 ebdyc[0].radial_width)
# register the grid
print('\nRegistering the grid')
ebdyc.register_grid(grid, verbose=verbose)

################################################################################
# Get solution, forces, BCs

if problem == 'easy':
    solution_func = lambda x, y: -np.cos(x) * np.exp(np.sin(x)) * np.sin(y)
Exemple #3
0
bh = min(bh1, bh2, bh3)
# get number of gridpoints to roughly match boundary spacing
ng = 2 * int(0.5 * 6.4 // bh)
# construct a grid
grid = Grid([-3.0, 3.4],
            ng, [-3.2, 3.2],
            ng,
            x_endpoints=[True, False],
            y_endpoints=[True, False])
# construct embedded boundary
bdys = [bdy1, bdy2, bdy3]
ebdys = [
    EmbeddedBoundary(bdy, bdy is bdy1, M, bh, pad_zone, MOL.step)
    for bdy in bdys
]
ebdyc = EmbeddedBoundaryCollection(ebdys)
# register the grid
print('\nRegistering the grid')
ebdyc.register_grid(grid, verbose=verbose)
# make some plots
if plot:
    fig, ax = plt.subplots()
    colors = ['black', 'blue', 'red', 'purple', 'purple']
    for ebdy in ebdys:
        q = ebdy.bdy_qfs
        q1 = q.interior_source_bdy if ebdy.interior else q.exterior_source_bdy
        q = ebdy.interface_qfs
        q2 = q.interior_source_bdy
        q3 = q.exterior_source_bdy
        bbs = [ebdy.bdy, ebdy.interface, q1, q2, q3]
        for bi, bb in enumerate(bbs):
bdy = GSB(*arc_length_parameterize(bdy.x, bdy.y))
bh = bdy.dt * bdy.speed.min()
# construct embedded boundary
tolerances = {
    'qfs': qfs_tolerance,
    'qfs_fsuf': qfs_fsuf,
}
ebdy = EmbeddedBoundary(bdy,
                        True,
                        M,
                        bh_ratio * bh,
                        pad_zone,
                        MOL.step,
                        tolerances=tolerances)
ebdyc = EmbeddedBoundaryCollection([
    ebdy,
])
# get a grid
grid = Grid([xmin, xmax],
            ngx, [ymin, ymax],
            ngy,
            x_endpoints=[True, False],
            y_endpoints=[True, False])
ebdyc.register_grid(grid)

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

# now timestep
c = c0.copy()
Exemple #5
0
    ax.scatter(bdy3.x, bdy3.y, color='red')
# get number of gridpoints to roughly match boundary spacing
ng = 2 * int(0.5 * 7 // bh)
# construct a grid
grid = Grid([-3.5, 3.5],
            ng, [-3.5, 3.5],
            ng,
            x_endpoints=[True, False],
            y_endpoints=[True, False])
# construct embedded boundary
bdys = [bdy1, bdy2, bdy3]
ebdys = [
    EmbeddedBoundary(bdy, bdy is bdy1, M, bh, pad_zone, MOL.step)
    for bdy in bdys
]
ebdyc = EmbeddedBoundaryCollection(ebdys)
# register the grid
print('\nRegistering the grid')
ebdyc.register_grid(grid, verbose=verbose)
# make some plots
if False:
    fig, ax = plt.subplots()
    colors = ['black', 'blue', 'red', 'purple', 'purple']
    for ebdy in ebdys:
        q = ebdy.bdy_qfs
        q1 = q.interior_source_bdy if ebdy.interior else q.exterior_source_bdy
        q = ebdy.interface_qfs
        q2 = q.interior_source_bdy
        q3 = q.exterior_source_bdy
        bbs = [ebdy.bdy, ebdy.interface, q1, q2, q3]
        for bi, bb in enumerate(bbs):
Exemple #6
0
GSB = pybie2d.boundaries.global_smooth_boundary.global_smooth_boundary.Global_Smooth_Boundary
Grid = pybie2d.grid.Grid

nb = 300
M = 12
slepian_r = 2*M

# get heaviside function
MOL = SlepianMollifier(slepian_r)
# construct boundary
bdy = GSB(c=star(nb, a=0.2, f=5))
bh = bdy.dt*bdy.speed.min()
# construct embedded boundary
ebdy = EmbeddedBoundary(bdy, True, M, bh*1, heaviside=MOL.step)
ebdys = [ebdy,]
ebdyc = EmbeddedBoundaryCollection([ebdy,])
# register the grid
print('\nRegistering the grid')
# ebdyc.register_grid(grid)
ebdyc.generate_grid(bh, bh)

# construct an embedded function
f = EmbeddedFunction(ebdyc)
f.define_via_function(lambda x, y: np.sin(x)*np.exp(y))

# try saving ebdy
ebdy_dict = ebdy.save()
ebdy2 = LoadEmbeddedBoundary(ebdy_dict)

# try saving ebdyc
ebdyc_dict = ebdyc.save()
tolerances = {
    'qfs': qfs_tolerance,
    'qfs_fsuf': qfs_fsuf,
}
ebdy = EmbeddedBoundary(bdy,
                        True,
                        M,
                        bh * 0.5,
                        pad_zone,
                        MOL.step,
                        tolerances=tolerances)
ebdys = [
    ebdy,
]
ebdyc = EmbeddedBoundaryCollection([
    ebdy,
])
# register the grid
print('\nRegistering the grid')
ebdyc.register_grid(grid, verbose=verbose)

################################################################################
# Get solution, forces, BCs

k = 8 * np.pi / 3

solution_func = lambda x, y: np.exp(np.sin(k * x)) * np.sin(k * y)
solution_func_dx = lambda x, y: k * np.cos(k * x) * np.exp(np.sin(k * x)
                                                           ) * np.sin(k * y)
solution_func_dy = lambda x, y: k * np.exp(np.sin(k * x)) * np.cos(k * y)
force_func = lambda x, y: helmholtz_k**2 * solution_func(x, y) - k**2 * np.exp(
Exemple #8
0
# construct boundary and reparametrize
bdy = GSB(c=star(nb, x=0.0, y=0.0, a=0.0, f=3))
bdy = GSB(*arc_length_parameterize(bdy.x, bdy.y))
bh = bdy.dt * bdy.speed.min()
# construct embedded boundary
ebdy = EmbeddedBoundary(bdy,
                        True,
                        M,
                        bh / radial_upsampling,
                        pad_zone=0,
                        heaviside=MOL.step,
                        qfs_fsuf=4,
                        coordinate_scheme='nufft',
                        coordinate_tolerance=1e-12)
ebdyc = EmbeddedBoundaryCollection([
    ebdy,
])
# get a grid
grid = Grid([-1.2, 1.7],
            ngx, [-1.5, 1.5],
            ngy,
            x_endpoints=[True, False],
            y_endpoints=[True, False])
ebdyc.register_grid(grid)

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

# now timestep
c = c0.copy()
Exemple #9
0
    def generate(self, dt, fixed_grid=False):
        """
        If fixed_grid = True, reuse same grid
        Otherwise, generate new grid
        """
        ebdyc = self.ebdyc
        u, v = self.u, self.v
        ux, uy, vx, vy = self.ux, self.uy, self.vx, self.vy
        # interpolate the velocity
        ubs = ebdyc.interpolate_radial_to_boundary(u)
        vbs = ebdyc.interpolate_radial_to_boundary(v)

        # move all boundarys; generate new embedded boundaries
        new_ebdys = []
        self.reparmed_ubs = []
        self.reparmed_vbs = []
        for ind, ebdy in enumerate(ebdyc):
            # interpolate the velocity
            ub = ubs[ind]
            vb = vbs[ind]
            # move the boundary with Forward Euler
            bx = ebdy.bdy.x + dt*ub
            by = ebdy.bdy.y + dt*vb
            # repararmetrize the boundary
            bx, by, new_t = arc_length_parameterize(bx, by, filter_fraction=self.filter_fraction, return_t=True)
            # bx, by, new_t = bx, by, np.linspace(0, 2*np.pi, bx.size, endpoint=False)
            # bx, by, new_t = arc_length_parameterize(bx, by, return_t=True, filter_function=self.filter_function)
            # move these boundary values to the new parametrization
            # This is not necessary for this timestepper, but is used by other
            # timesteppers which use this as a startup!
            # SHOULD I SWITCH THIS TO NUFFT WHEN THAT IS BEING USED?
            self.reparmed_ubs.append(nufft_interpolation1d(new_t, np.fft.fft(ub)))
            self.reparmed_vbs.append(nufft_interpolation1d(new_t, np.fft.fft(vb)))
            # bu_interp = interp1d(0, 2*np.pi, ebdy.bdy.dt, ub, p=True)
            # bv_interp = interp1d(0, 2*np.pi, ebdy.bdy.dt, vb, p=True)
            # self.reparmed_ubs.append(bu_interp(new_t))
            # self.reparmed_vbs.append(bv_interp(new_t))
            # generate the new embedded boundary
            new_ebdy = ebdy.regenerate(bx, by)
            new_ebdys.append(new_ebdy)
        new_ebdyc = EmbeddedBoundaryCollection(new_ebdys)
        # get dnager zone distance
        umax = np.sqrt(u*u + v*v).max()
        ddd = 2*umax*dt
        # raise an exception if danger zone thicker than radial width
        if ddd > new_ebdyc[0].radial_width:
            raise Exception('Velocity is so fast that one timestep oversteps safety zones; reduce timestep.')
        # register the grid...
        if fixed_grid:
            new_ebdyc.register_grid(ebdyc.grid, danger_zone_distance=ddd)
        else:
            new_ebdyc.generate_grid(danger_zone_distance=ddd)

        # let's get the points that need to be interpolated to
        aap = new_ebdyc.pnar
        AP_key  = ebdyc.register_points(aap.x, aap.y, dzl=new_ebdyc.danger_zone_list, gil=new_ebdyc.guess_ind_list)

        # now we need to interpolate onto things
        AEP = ebdyc.registered_partitions[AP_key]

        # get departure points
        xd_all = np.zeros(aap.N)
        yd_all = np.zeros(aap.N)

        c1n, c2n, c3n = AEP.get_Ns()
        # category 1 and 2
        c1_2n = c1n + c2n
        c1_2 = AEP.zone1_or_2
        uxh = ebdyc.interpolate_to_points(ux, aap.x, aap.y)
        uyh = ebdyc.interpolate_to_points(uy, aap.x, aap.y)
        vxh = ebdyc.interpolate_to_points(vx, aap.x, aap.y)
        vyh = ebdyc.interpolate_to_points(vy, aap.x, aap.y)
        uh = ebdyc.interpolate_to_points(u, aap.x, aap.y)
        vh = ebdyc.interpolate_to_points(v, aap.x, aap.y)
        SLM = np.zeros([c1_2n,] + [2,2], dtype=float)
        SLR = np.zeros([c1_2n,] + [2,], dtype=float)
        SLM[:,0,0] = 1 + dt*uxh[c1_2]
        SLM[:,0,1] = dt*uyh[c1_2]
        SLM[:,1,0] = dt*vxh[c1_2]
        SLM[:,1,1] = 1 + dt*vyh[c1_2]
        SLR[:,0] = dt*uh[c1_2]
        SLR[:,1] = dt*vh[c1_2]
        OUT = np.linalg.solve(SLM, SLR)
        xdt, ydt = OUT[:,0], OUT[:,1]
        xd, yd = aap.x[c1_2] - xdt, aap.y[c1_2] - ydt
        xd_all[c1_2] = xd
        yd_all[c1_2] = yd
        # categroy 3... this is the tricky one
        if c3n > 0:
            for ind, ebdy in enumerate(ebdyc):
                ub = ubs[ind]
                vb = vbs[ind]
                
                c3l = AEP.zone3l[ind]
                th = ebdy.bdy.dt
                # th = 2*np.pi/nb
                # tk = np.fft.fftfreq(nb, th/(2*np.pi))
                tk = ebdy.bdy.k
                def d1_der(f):
                    return np.fft.ifft(np.fft.fft(f)*tk*1j).real
                interp = lambda f: interp1d(0, 2*np.pi, th, f, k=3, p=True)
                bx_interp  = interp(ebdy.bdy.x)
                by_interp  = interp(ebdy.bdy.y)
                bxs_interp = interp(d1_der(ebdy.bdy.x))
                bys_interp = interp(d1_der(ebdy.bdy.y))
                nx_interp  = interp(ebdy.bdy.normal_x)
                ny_interp  = interp(ebdy.bdy.normal_y)
                nxs_interp = interp(d1_der(ebdy.bdy.normal_x))
                nys_interp = interp(d1_der(ebdy.bdy.normal_y))
                urb = ebdy.interpolate_radial_to_boundary_normal_derivative(u[ind])
                vrb = ebdy.interpolate_radial_to_boundary_normal_derivative(v[ind])
                ub_interp   = interp(ub)
                vb_interp   = interp(vb)
                urb_interp  = interp(urb)
                vrb_interp  = interp(vrb)
                ubs_interp  = interp(d1_der(ub))
                vbs_interp  = interp(d1_der(vb))
                urbs_interp = interp(d1_der(urb))
                vrbs_interp = interp(d1_der(vrb))
                xo = aap.x[c3l]
                yo = aap.y[c3l]
                def objective(s, r):
                    f = np.empty([s.size, 2])
                    f[:,0] = bx_interp(s) + r*nx_interp(s) + dt*ub_interp(s) + dt*r*urb_interp(s) - xo
                    f[:,1] = by_interp(s) + r*ny_interp(s) + dt*vb_interp(s) + dt*r*vrb_interp(s) - yo
                    return f
                def Jac(s, r):
                    J = np.empty([s.size, 2, 2])
                    J[:,0,0] = bxs_interp(s) + r*nxs_interp(s) + dt*ubs_interp(s) + dt*r*urbs_interp(s)
                    J[:,1,0] = bys_interp(s) + r*nys_interp(s) + dt*vbs_interp(s) + dt*r*vrbs_interp(s)
                    J[:,0,1] = nx_interp(s) + dt*urb_interp(s)
                    J[:,1,1] = ny_interp(s) + dt*vrb_interp(s)
                    return J
                # take as guess inds our s, r
                s = AEP.zone3t[ind]
                r = AEP.zone3r[ind]
                # now solve for sd, rd
                res = objective(s, r)
                mres = np.hypot(res[:,0], res[:,1]).max()
                tol = 1e-12
                while mres > tol:
                    J = Jac(s, r)
                    d = np.linalg.solve(J, res)
                    s -= d[:,0]
                    r -= d[:,1]
                    res = objective(s, r)
                    mres = np.hypot(res[:,0], res[:,1]).max()
                # get the departure points
                xd = bx_interp(s) + nx_interp(s)*r
                yd = by_interp(s) + ny_interp(s)*r
                xd_all[c3l] = xd
                yd_all[c3l] = yd

        self.new_ebdyc = new_ebdyc
        self.xd_all = xd_all
        self.yd_all = yd_all

        return self.new_ebdyc
Exemple #10
0
    def generate(self, dt, fixed_grid=False):
        ebdyc = self.ebdyc
        ebdyc_old = self.ebdyc_old
        u, v = self.u, self.v
        uo, vo = self.uo, self.vo
        ux, uy, vx, vy = self.ux, self.uy, self.vx, self.vy
        uxo, uyo, vxo, vyo = self.uxo, self.uyo, self.vxo, self.vyo

        # interpolate the velocity
        ubs = ebdyc.interpolate_radial_to_boundary(u)
        vbs = ebdyc.interpolate_radial_to_boundary(v)

        # move all boundarys; generate new embedded boundaries
        new_ebdys = []
        self.reparmed_ubs = []
        self.reparmed_vbs = []
        for ind, ebdy in enumerate(self.ebdyc):
            if False:  # this is the ABF way
                # interpolate the velocity
                ub = ubs.bdy_value_list[ind]
                vb = vbs.bdy_value_list[ind]
                ubo_new_parm = self.ubos[ind]
                vbo_new_parm = self.vbos[ind]
                # move the boundary with Forward Euler
                bx = ebdy.bdy.x + 0.5 * dt * (3 * ub - ubo_new_parm)
                by = ebdy.bdy.y + 0.5 * dt * (3 * vb - vbo_new_parm)
                # repararmetrize the boundary
                bx, by, new_t = arc_length_parameterize(
                    bx,
                    by,
                    filter_fraction=self.filter_fraction,
                    return_t=True)
                # move these boundary values for velocity to the new parametrization
                self.reparmed_ubs.append(
                    nufft_interpolation1d(new_t, np.fft.fft(ub)))
                self.reparmed_vbs.append(
                    nufft_interpolation1d(new_t, np.fft.fft(vb)))
                # generate the new embedded boundary
                new_ebdy = ebdy.regenerate(bx, by)
                new_ebdys.append(new_ebdy)
            else:  # this is the BDF way
                # interpolate the velocity
                ub = ubs.bdy_value_list[ind]
                vb = vbs.bdy_value_list[ind]
                ubo_new_parm = self.ubos[ind]
                vbo_new_parm = self.vbos[ind]
                # move the boundary with Forward Euler
                bx = ebdy.bdy.x + 0.5 * dt * (3 * ub - ubo_new_parm)
                by = ebdy.bdy.y + 0.5 * dt * (3 * vb - vbo_new_parm)
                # repararmetrize the boundary
                bx, by, new_t = arc_length_parameterize(
                    bx,
                    by,
                    filter_fraction=self.filter_fraction,
                    return_t=True)
                # move these boundary values for velocity to the new parametrization
                self.reparmed_ubs.append(
                    nufft_interpolation1d(new_t, np.fft.fft(ub)))
                self.reparmed_vbs.append(
                    nufft_interpolation1d(new_t, np.fft.fft(vb)))
                # generate the new embedded boundary
                new_ebdy = ebdy.regenerate(bx, by)
                new_ebdys.append(new_ebdy)

        new_ebdyc = EmbeddedBoundaryCollection(new_ebdys)
        # get dnager zone distance
        umax = np.sqrt(u * u + v * v).max()
        ddd = 2 * umax * dt
        # raise an exception if danger zone thicker than radial width
        if ddd > new_ebdyc[0].radial_width:
            raise Exception(
                'Velocity is so fast that one timestep oversteps safety zones; reduce timestep.'
            )
        # register the grid...
        if fixed_grid:
            new_ebdyc.register_grid(ebdyc.grid, danger_zone_distance=ddd)
        else:
            new_ebdyc.generate_grid(danger_zone_distance=ddd)

        # let's get the points that need to be interpolated to
        aap = new_ebdyc.pnar
        AP_key = ebdyc.register_points(aap.x,
                                       aap.y,
                                       dzl=new_ebdyc.danger_zone_list,
                                       gil=new_ebdyc.guess_ind_list)
        OAP_key = ebdyc_old.register_points(aap.x,
                                            aap.y,
                                            dzl=new_ebdyc.danger_zone_list,
                                            gil=new_ebdyc.guess_ind_list)

        # now we need to interpolate onto things
        AEP = ebdyc.registered_partitions[AP_key]
        OAEP = ebdyc_old.registered_partitions[OAP_key]

        # get departure points
        xd_all = np.zeros(aap.N)
        yd_all = np.zeros(aap.N)
        xD_all = np.zeros(aap.N)
        yD_all = np.zeros(aap.N)

        # advect those in the annulus
        c1n, c2n, c3n = AEP.get_Ns()
        oc1n, oc2n, oc3n = OAEP.get_Ns()
        # category 1 and 2
        c1_2 = AEP.zone1_or_2
        oc1_2 = OAEP.zone1_or_2
        fc12 = np.logical_and(c1_2, oc1_2)
        fc12n = np.sum(fc12)

        # category 1 and 2
        # NOTE:  THESE INTERPOLATIONS CAN BE MADE FASTER BY EXPLOITING SHARED
        #        GRIDPOINTS IF THAT IS ENFORCED IN GRID GENERATION
        #        THIS IS NOT EXPLOITED, FOR THE TIME BEING
        uxh = ebdyc.interpolate_to_points(ux, aap.x, aap.y)
        uyh = ebdyc.interpolate_to_points(uy, aap.x, aap.y)
        vxh = ebdyc.interpolate_to_points(vx, aap.x, aap.y)
        vyh = ebdyc.interpolate_to_points(vy, aap.x, aap.y)
        uh = ebdyc.interpolate_to_points(u, aap.x, aap.y)
        vh = ebdyc.interpolate_to_points(v, aap.x, aap.y)

        uxoh = ebdyc_old.interpolate_to_points(uxo, aap.x, aap.y)
        uyoh = ebdyc_old.interpolate_to_points(uyo, aap.x, aap.y)
        vxoh = ebdyc_old.interpolate_to_points(vxo, aap.x, aap.y)
        vyoh = ebdyc_old.interpolate_to_points(vyo, aap.x, aap.y)
        uoh = ebdyc_old.interpolate_to_points(uo, aap.x, aap.y)
        voh = ebdyc_old.interpolate_to_points(vo, aap.x, aap.y)

        SLM = np.zeros([
            fc12n,
        ] + [4, 4], dtype=float)
        SLR = np.zeros([
            fc12n,
        ] + [
            4,
        ], dtype=float)

        # solve for departure points
        SLM[:, 0, 0] = uxh[fc12]
        SLM[:, 0, 1] = uyh[fc12]
        SLM[:, 0, 2] = 0.5 / dt
        SLM[:, 0, 3] = 0.0
        SLM[:, 1, 0] = vxh[fc12]
        SLM[:, 1, 1] = vyh[fc12]
        SLM[:, 1, 2] = 0.0
        SLM[:, 1, 3] = 0.5 / dt
        SLM[:, 2, 0] = 2.0 / dt + 3 * uxh[fc12]
        SLM[:, 2, 1] = 3 * uyh[fc12]
        SLM[:, 2, 2] = -uxoh[fc12]
        SLM[:, 2, 3] = -uyoh[fc12]
        SLM[:, 3, 0] = 3 * vxh[fc12]
        SLM[:, 3, 1] = 2.0 / dt + 3 * vyh[fc12]
        SLM[:, 3, 2] = -vxoh[fc12]
        SLM[:, 3, 3] = -vyoh[fc12]
        SLR[:, 0] = uh[fc12]
        SLR[:, 1] = vh[fc12]
        SLR[:, 2] = 3 * uh[fc12] - uoh[fc12]
        SLR[:, 3] = 3 * vh[fc12] - voh[fc12]
        OUT = np.linalg.solve(SLM, SLR)
        dx, dy, Dx, Dy = OUT[:, 0], OUT[:, 1], OUT[:, 2], OUT[:, 3]
        xd, yd = aap.x[fc12] - dx, aap.y[fc12] - dy
        xD, yD = aap.x[fc12] - Dx, aap.y[fc12] - Dy
        xd_all[fc12] = xd
        yd_all[fc12] = yd
        xD_all[fc12] = xD
        yD_all[fc12] = yD

        # categroy 3... this is the tricky one
        fc3n = aap.N - fc12n
        # print('Number of points in category 3 is:', fc3n)
        if fc3n > 0:
            for ind, (ebdy, ebdy_old) in enumerate(zip(ebdyc, ebdyc_old)):
                ub = ubs.bdy_value_list[ind]
                vb = vbs.bdy_value_list[ind]

                c3l = AEP.zone3l[ind]
                oc3l = OAEP.zone3l[ind]
                fc3l = np.unique(np.concatenate([c3l, oc3l]))
                th = ebdy.bdy.dt
                tk = ebdy.bdy.k

                def d1_der(f):
                    return np.fft.ifft(np.fft.fft(f) * tk * 1j).real

                interp = lambda f: interp1d(0, 2 * np.pi, th, f, k=3, p=True)
                bx_interp = interp(ebdy.bdy.x)
                by_interp = interp(ebdy.bdy.y)
                bxs_interp = interp(d1_der(ebdy.bdy.x))
                bys_interp = interp(d1_der(ebdy.bdy.y))
                nx_interp = interp(ebdy.bdy.normal_x)
                ny_interp = interp(ebdy.bdy.normal_y)
                nxs_interp = interp(d1_der(ebdy.bdy.normal_x))
                nys_interp = interp(d1_der(ebdy.bdy.normal_y))
                urb = ebdy.interpolate_radial_to_boundary_normal_derivative(
                    u[0])
                vrb = ebdy.interpolate_radial_to_boundary_normal_derivative(
                    v[0])
                urrb = ebdy.interpolate_radial_to_boundary_normal_derivative2(
                    u[0])
                vrrb = ebdy.interpolate_radial_to_boundary_normal_derivative2(
                    v[0])
                ub_interp = interp(ub)
                vb_interp = interp(vb)
                urb_interp = interp(urb)
                vrb_interp = interp(vrb)
                urrb_interp = interp(urrb)
                vrrb_interp = interp(vrrb)
                ubs_interp = interp(d1_der(ub))
                vbs_interp = interp(d1_der(vb))
                urbs_interp = interp(d1_der(urb))
                vrbs_interp = interp(d1_der(vrb))
                urrbs_interp = interp(d1_der(urrb))
                vrrbs_interp = interp(d1_der(vrrb))

                old_bx_interp = interp(ebdy_old.bdy.x)
                old_by_interp = interp(ebdy_old.bdy.y)
                old_bxs_interp = interp(d1_der(ebdy_old.bdy.x))
                old_bys_interp = interp(d1_der(ebdy_old.bdy.y))
                old_nx_interp = interp(ebdy_old.bdy.normal_x)
                old_ny_interp = interp(ebdy_old.bdy.normal_y)
                old_nxs_interp = interp(d1_der(ebdy_old.bdy.normal_x))
                old_nys_interp = interp(d1_der(ebdy_old.bdy.normal_y))
                old_ub = ebdy_old.interpolate_radial_to_boundary(uo[0])
                old_vb = ebdy_old.interpolate_radial_to_boundary(vo[0])
                old_urb = ebdy_old.interpolate_radial_to_boundary_normal_derivative(
                    uo[0])
                old_vrb = ebdy_old.interpolate_radial_to_boundary_normal_derivative(
                    vo[0])
                old_urrb = ebdy_old.interpolate_radial_to_boundary_normal_derivative2(
                    uo[0])
                old_vrrb = ebdy_old.interpolate_radial_to_boundary_normal_derivative2(
                    vo[0])
                # i think the old parm is right, but should think about
                old_ub_interp = interp(old_ub)
                old_vb_interp = interp(old_vb)
                old_urb_interp = interp(old_urb)
                old_vrb_interp = interp(old_vrb)
                old_urrb_interp = interp(old_urrb)
                old_vrrb_interp = interp(old_vrrb)
                old_ubs_interp = interp(d1_der(old_ub))
                old_vbs_interp = interp(d1_der(old_vb))
                old_urbs_interp = interp(d1_der(old_urb))
                old_vrbs_interp = interp(d1_der(old_vrb))
                old_urrbs_interp = interp(d1_der(old_urrb))
                old_vrrbs_interp = interp(d1_der(old_vrrb))

                xx = aap.x[fc3l]
                yy = aap.y[fc3l]

                def objective(s, r, so, ro):
                    f = np.empty([s.size, 4])
                    f[:, 0] = old_bx_interp(so) + ro * old_nx_interp(
                        so) + 2 * dt * ub_interp(s) + 2 * dt * r * urb_interp(
                            s) + dt * r**2 * urrb_interp(s) - xx
                    f[:, 1] = old_by_interp(so) + ro * old_ny_interp(
                        so) + 2 * dt * vb_interp(s) + 2 * dt * r * vrb_interp(
                            s) + dt * r**2 * vrrb_interp(s) - yy
                    f[:, 2] = bx_interp(s) + r * nx_interp(
                        s
                    ) + 1.5 * dt * ub_interp(s) + 1.5 * dt * r * urb_interp(
                        s) + 0.75 * dt * r**2 * urrb_interp(
                            s) - 0.5 * dt * old_ub_interp(
                                so) - 0.5 * dt * ro * old_urb_interp(
                                    so) - 0.25 * dt * ro**2 * old_urrb_interp(
                                        so) - xx
                    f[:, 3] = by_interp(s) + r * ny_interp(
                        s
                    ) + 1.5 * dt * vb_interp(s) + 1.5 * dt * r * vrb_interp(
                        s) + 0.75 * dt * r**2 * vrrb_interp(
                            s) - 0.5 * dt * old_vb_interp(
                                so) - 0.5 * dt * ro * old_vrb_interp(
                                    so) - 0.25 * dt * ro**2 * old_vrrb_interp(
                                        so) - yy
                    return f

                def Jac(s, r, so, ro):
                    J = np.empty([s.size, 4, 4])
                    # derivative with respect to s
                    J[:, 0,
                      0] = 2 * dt * ubs_interp(s) + 2 * dt * r * urbs_interp(
                          s) + dt * r**2 * urrbs_interp(s)
                    J[:, 1,
                      0] = 2 * dt * vbs_interp(s) + 2 * dt * r * vrbs_interp(
                          s) + dt * r**2 * vrrbs_interp(s)
                    J[:, 2, 0] = bxs_interp(
                        s) + r * nxs_interp(s) + 1.5 * dt * ubs_interp(
                            s) + 1.5 * dt * r * urbs_interp(
                                s) + 0.75 * dt * r**2 * urrbs_interp(s)
                    J[:, 3, 0] = bys_interp(
                        s) + r * nys_interp(s) + 1.5 * dt * vbs_interp(
                            s) + 1.5 * dt * r * vrbs_interp(
                                s) + 0.75 * dt * r**2 * vrrbs_interp(s)
                    # derivative with respect to r
                    J[:, 0,
                      1] = 2 * dt * urb_interp(s) + 2 * dt * r * urrb_interp(s)
                    J[:, 1,
                      1] = 2 * dt * vrb_interp(s) + 2 * dt * r * vrrb_interp(s)
                    J[:, 2, 1] = nx_interp(s) + 1.5 * dt * urb_interp(
                        s) + 1.5 * dt * r * urrb_interp(s)
                    J[:, 3, 1] = ny_interp(s) + 1.5 * dt * vrb_interp(
                        s) + 1.5 * dt * r * vrrb_interp(s)
                    # derivative with respect to so
                    J[:, 0, 2] = old_bxs_interp(so) + ro * old_nxs_interp(so)
                    J[:, 1, 2] = old_bys_interp(so) + ro * old_nys_interp(so)
                    J[:, 2, 2] = -0.5 * dt * old_ubs_interp(
                        so) - 0.5 * dt * ro * old_urbs_interp(
                            so) - 0.25 * dt * ro**2 * old_urrbs_interp(so)
                    J[:, 3, 2] = -0.5 * dt * old_vbs_interp(
                        so) - 0.5 * dt * ro * old_vrbs_interp(
                            so) - 0.25 * dt * ro**2 * old_vrrbs_interp(so)
                    # derivative with respect to ro
                    J[:, 0, 3] = old_nx_interp(so)
                    J[:, 1, 3] = old_ny_interp(so)
                    J[:, 2, 3] = -0.5 * dt * old_urb_interp(
                        so) - 0.5 * dt * ro * old_urrb_interp(so)
                    J[:, 3, 3] = -0.5 * dt * old_vrb_interp(
                        so) - 0.5 * dt * ro * old_vrrb_interp(so)
                    return J

                # take as guess inds our s, r
                s = AEP.full_t[fc3l]
                r = AEP.full_r[fc3l]
                so = OAEP.full_t[fc3l]
                ro = OAEP.full_r[fc3l]
                # now solve for sd, rd
                res = objective(s, r, so, ro)
                mres1 = np.hypot(res[:, 0], res[:, 1]).max()
                mres2 = np.hypot(res[:, 2], res[:, 3]).max()
                mres = max(mres1, mres2)
                tol = 1e-12
                while mres > tol:
                    J = Jac(s, r, so, ro)
                    d = np.linalg.solve(J, res)
                    s -= d[:, 0]
                    r -= d[:, 1]
                    so -= d[:, 2]
                    ro -= d[:, 3]
                    res = objective(s, r, so, ro)
                    mres1 = np.hypot(res[:, 0], res[:, 1]).max()
                    mres2 = np.hypot(res[:, 2], res[:, 3]).max()
                    mres = max(mres1, mres2)
                r_fail_1 = r.max() > 0.0
                r_fail_2 = r.min() < -ebdy.radial_width
                ro_fail_1 = ro.max() > 0.0
                ro_fail_2 = ro.min() < -ebdy_old.radial_width
                r_fail = r_fail_1 or r_fail_2
                ro_fail = ro_fail_1 or ro_fail_2
                fail = r_fail or ro_fail
                fail_amount = 0.0
                if fail:
                    if r_fail_1:
                        fail_amount = max(fail_amount, r.max())
                        r[r > 0.0] = 0.0
                    if r_fail_2:
                        fail_amount = max(fail_amount,
                                          (-r - ebdy.radial_width).max())
                        r[r < -ebdy.radial_width] = -ebdy.radial_width
                    if ro_fail_1:
                        fail_amount = max(fail_amount, ro.max())
                        ro[ro > 0.0] = 0.0
                    if ro_fail_2:
                        fail_amount = max(fail_amount,
                                          (-ro - ebdy_old.radial_width).max())
                        ro[ro <
                           -ebdy_old.radial_width] = -ebdy_old.radial_width

                # get the departure points
                xd = bx_interp(s) + nx_interp(s) * r
                yd = by_interp(s) + ny_interp(s) * r
                xD = old_bx_interp(so) + old_nx_interp(so) * ro
                yD = old_by_interp(so) + old_ny_interp(so) * ro
                xd_all[fc3l] = xd
                yd_all[fc3l] = yd
                xD_all[fc3l] = xD
                yD_all[fc3l] = yD

        self.new_ebdyc = new_ebdyc
        self.xd_all = xd_all
        self.yd_all = yd_all
        self.xD_all = xD_all
        self.yD_all = yD_all

        return self.new_ebdyc
grid = Grid([-2.6, 2.6],
            ng, [-2.6, 2.6],
            ng,
            x_endpoints=[True, False],
            y_endpoints=[True, False])
# construct embedded boundary
bdys = [bdy1, bdy2, bdy3]
ebdys = [
    EmbeddedBoundary(bdy,
                     bdy is bdy1,
                     M,
                     bh,
                     pad_zone=pad_zone,
                     heaviside=MOL.step) for bdy in bdys
]
ebdyc = EmbeddedBoundaryCollection(ebdys)
# register the grid
print('\nRegistering the grid')
ebdyc.register_grid(grid, verbose=verbose)
# give ebdyc a bumpy function
ebdyc.ready_bump(MOL.bump,
                 (2.6 - ebdys[0].radial_width, 2.6 - ebdys[0].radial_width),
                 ebdys[0].radial_width)

################################################################################
# Extract radial information from ebdy and construct annular solver

# Testing the radial Stokes solver
print('   Testing Radial Stokes Solver')
a = 8.0
b = 7.0
kvy = np.fft.fftfreq(ngy, h/(2*np.pi))
kvx[int(ngx/2)] = 0.0
kvy[int(ngy/2)] = 0.0
kx, ky = np.meshgrid(kvx, kvy, indexing='ij')
ikx, iky = 1j*kx, 1j*ky

# get heaviside function
MOL = SlepianMollifier(slepian_r)

# construct boundary and reparametrize
bdy = GSB(c=star(nb, x=0.0, y=0.0, a=0.0, f=3))
bdy = GSB(*arc_length_parameterize(bdy.x, bdy.y))
bh = bdy.dt*bdy.speed.min()
# construct embedded boundary
ebdy = EmbeddedBoundary(bdy, True, M, bh*0.5, pad_zone, MOL.step, tolerances = tolerances)
ebdyc = EmbeddedBoundaryCollection([ebdy,])
# get a grid
grid = Grid([xmin, xmax], ngx, [ymin, ymax], ngy, x_endpoints=[True, False], y_endpoints=[True, False])
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

# now timestep
c = c0.copy()
Exemple #13
0
            x_endpoints=[True, False],
            y_endpoints=[True, False])
# construct embedded boundary
ebdy = EmbeddedBoundary(bdy,
                        True,
                        M,
                        grid.xh * 0.75,
                        pad_zone=pad_zone,
                        heaviside=MOL.step,
                        qfs_tolerance=1e-14,
                        qfs_fsuf=2)
ebdys = [
    ebdy,
]
ebdyc = EmbeddedBoundaryCollection([
    ebdy,
])
# register the grid
print('\nRegistering the grid')
ebdyc.register_grid(grid)
# give ebdyc a bumpy function
ebdyc.ready_bump(
    MOL.bump, (np.pi / 2 - ebdy.radial_width, np.pi / 2 - ebdy.radial_width),
    ebdyc[0].radial_width)

################################################################################
# Extract radial information from ebdy and construct annular solver

# Testing the radial Stokes solver
print('   Testing Radial Stokes Solver')
a = 3.0
bdy = GSB(c=star(nb, a=0.2, f=5))
if reparametrize:
    bdy = GSB(*arc_length_parameterize(bdy.x, bdy.y))
bh = bdy.dt * bdy.speed.min()
# get number of gridpoints to roughly match boundary spacing
ng = 2 * int(0.5 * 2.4 // bh)
# construct a grid
grid = Grid([-1.2, 1.2],
            ng, [-1.2, 1.2],
            ng,
            x_endpoints=[True, False],
            y_endpoints=[True, False])
# construct embedded boundary
ebdy = EmbeddedBoundary(bdy, True, M, bh * 1.0, pad_zone, MOL.step)
ebdyc = EmbeddedBoundaryCollection([
    ebdy,
])
# register the grid
print('\nRegistering the grid')
ebdyc.register_grid(grid, verbose=verbose)
# give ebdyc a bumpy function
ebdyc.ready_bump(MOL.bump, (1.2 - ebdy.radial_width, 1.2 - ebdy.radial_width),
                 ebdy.radial_width)

################################################################################
# Get solution, forces, BCs

k = 8 * np.pi / 3

solution_func = lambda x, y: np.exp(np.sin(k * x)) * np.sin(k * y)
force_func = lambda x, y: k**2 * np.exp(np.sin(k * x)) * np.sin(k * y) * (
Exemple #15
0
################################################################################
# Semi-Lagrangian Non-linear departure point method

print('Testing Linear Departure Method')

# get heaviside function
MOL = SlepianMollifier(slepian_r)

# construct boundary and reparametrize
bdy = GSB(c=star(nb, x=0.0, y=0.0, a=0.1, f=3))
bdy = GSB(*arc_length_parameterize(bdy.x, bdy.y))
bh = bdy.dt * bdy.speed.min()
# construct embedded boundary
ebdy = EmbeddedBoundary(bdy, True, M, bh, pad_zone, MOL.step)
ebdyc = EmbeddedBoundaryCollection([
    ebdy,
])
# get a grid
grid = Grid([-1.5, 1.5],
            ng, [-1.5, 1.5],
            ng,
            x_endpoints=[True, False],
            y_endpoints=[True, False])
# register the grid
print('\nRegistering the grid')
ebdyc.register_grid(grid)

original_ebdy = ebdy

# initial c field
c0 = EmbeddedFunction(ebdyc)
Exemple #16
0
            ng, [-1.2, 1.2],
            ng,
            x_endpoints=[True, False],
            y_endpoints=[True, False])
# construct embedded boundary
ebdy = EmbeddedBoundary(bdy,
                        True,
                        M,
                        bh * 1,
                        pad_zone=pad_zone,
                        heaviside=MOL.step,
                        qfs_tolerance=qfs_tolerance,
                        coordinate_tolerance=coordinate_tolerance,
                        coordinate_scheme=coordinate_scheme)
ebdyc = EmbeddedBoundaryCollection([
    ebdy,
])
# register the grid
print('\nRegistering the grid')
ebdyc.register_grid(grid, verbose=verbose)
# give ebdyc a bumpy function
ebdyc.ready_bump(MOL.bump, (1.2 - ebdy.radial_width, 1.2 - ebdy.radial_width),
                 ebdyc[0].radial_width)

################################################################################
# Get solution, forces, BCs

k = 8 * np.pi / 3

solution_func = lambda x, y: -np.cos(x) * np.exp(np.sin(x)) * np.sin(y)
force_func = lambda x, y: (2.0 * np.cos(x) + 3.0 * np.cos(x) * np.sin(x) - np.
Exemple #17
0
# get heaviside function
MOL = SlepianMollifier(slepian_r)
# construct boundary
bdy = GSB(c=star(nb, a=0.0, f=5))
if reparametrize:
	bdy = GSB(*arc_length_parameterize(bdy.x, bdy.y))
bh = bdy.dt*bdy.speed.min()
# get number of gridpoints to roughly match boundary spacing
ng = 2*int(0.5*2.4//bh)
# construct a grid
grid = Grid([-1.2, 1.2], ng, [-1.2, 1.2], ng, x_endpoints=[True, False], y_endpoints=[True, False])
# construct embedded boundary
ebdy = EmbeddedBoundary(bdy, True, M, bh*1, pad_zone, MOL.step)
ebdys = [ebdy,]
ebdyc = EmbeddedBoundaryCollection([ebdy,])
# register the grid
print('\nRegistering the grid')
ebdyc.register_grid(grid, verbose=verbose)
# give ebdyc a bumpy function
ebdyc.ready_bump(MOL.bump, (1.2-ebdy.radial_width, 1.2-ebdy.radial_width), ebdys[0].radial_width)

################################################################################
# Get solution, forces, BCs

k = 8*np.pi/3

solution_func = lambda x, y: np.exp(np.sin(k*x))*np.sin(k*y)
force_func = lambda x, y: k**2*np.exp(np.sin(k*x))*np.sin(k*y)*(np.cos(k*x)**2-np.sin(k*x)-1.0)
f = force_func(ebdy.grid.xg, ebdy.grid.yg)*ebdy.phys
frs = [force_func(ebdy.radial_x, ebdy.radial_y) for ebdy in ebdys]