예제 #1
0
def show_L1_eigfuns(G, n=np.inf, **kwargs):
	'''
	Show eigenfunctions of 0-Laplacian
	'''
	obs = gds.edge_gds(G)
	# L = np.array(nx.laplacian_matrix(G).todense())
	L = -obs.laplacian(np.eye(obs.ndim))
	# vals, vecs = sp.sparse.linalg.eigs(-L, k=n, which='SM')
	vals, vecs = np.linalg.eigh(L)
	vals, vecs = np.real(vals), np.real(vecs)
	vals = np.round(vals, 6)
	# pdb.set_trace()
	sys = dict()
	sys['Surface'] = gds.face_gds(G)
	sys['Surface'].set_evolution(nil=True)
	canvas = dict()
	canvas['Surface'] = [[[sys['Surface']]]]
	for i, (ev, vec) in enumerate(sorted(zip(vals, vecs.T), key=lambda x: np.abs(x[0]))):
		obs = gds.edge_gds(G)
		obs.set_evolution(nil=True)
		obs.set_initial(y0=lambda x: vec[obs.X[x]])
		if ev in canvas:
			sys[f'eigval_{ev} eigfun_{len(canvas[ev])}'] = obs
			canvas[ev].append([[obs]])
		else:
			sys[f'eigval_{ev} eigfun_{0}'] = obs
			canvas[ev] = [[[obs]]]
		if i == n:
			break
	# canvas = sorted(list(canvas.values()), key=len)
	canvas = list(canvas.values())
	sys = gds.couple(sys)
	gds.render(sys, canvas=canvas, n_spring_iters=1200, title=f'L1-eigenfunctions', **kwargs)
예제 #2
0
파일: laplace.py 프로젝트: asrvsn/gds
def test_curl():
    G1 = nx.Graph()
    G1.add_nodes_from([1, 2, 3, 4])
    G1.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 1)])
    v1 = gds.edge_gds(G1)
    v1.set_evolution(nil=True)
    v1.set_initial(y0=lambda e: 1 if e == (1, 2) else 0)
    G2 = nx.Graph()
    G2.add_nodes_from([1, 2, 3, 4, 5, 6])
    G2.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 1), (1, 5), (5, 6), (6, 2)])
    v2 = gds.edge_gds(G2)
    v2.set_evolution(nil=True)
    v2.set_initial(y0=lambda e: 1 if e == (1, 2) else 0)
    sys = gds.couple({
        'velocity1':
        v1,
        'curl1':
        v1.project(gds.GraphDomain.faces, lambda v: v.curl()),
        'curl*curl1':
        v1.project(gds.GraphDomain.edges,
                   lambda v: v.curl_face.T @ v.curl_face @ v.y),
        'velocity2':
        v2,
        'curl2':
        v2.project(gds.GraphDomain.faces, lambda v: v.curl()),
        'curl*curl2':
        v2.project(gds.GraphDomain.edges,
                   lambda v: v.curl_face.T @ v.curl_face @ v.y)
    })
    gds.render(sys,
               edge_max=0.5,
               canvas=gds.grid_canvas(sys.observables.values(), 3),
               dynamic_ranges=True)
예제 #3
0
파일: fluid.py 프로젝트: asrvsn/gds
def initial_flow(G: nx.Graph,
                 KE: float = 1.,
                 scale_distribution: Callable = None):
    '''
	Construct divergence-free initial conditions with energies at specified length-scales.

	scale_distribution: probability measure on [0, 1] (default uniform)
	'''
    assert KE >= 0, 'Specify nonnegative kinetic energy'
    if scale_distribution is None:
        scale_distribution = lambda x: 1.

    N = len(G.edges())
    P = gds.edge_gds(
        G).leray_projector  # TODO: assumes determinism of construction
    freqs, spec_fun = edge_power_spectrum(G)
    dist = np.array(
        list(
            map(scale_distribution,
                (freqs - freqs.min()) / (freqs.max() - freqs.min()))))

    def f(x):
        return np.linalg.norm(spec_fun(P @ x) - dist)

    x0 = np.random.uniform(size=N)
    sol = minimize(f, x0)
    u = P @ sol.x
    u *= np.sqrt(KE / np.dot(u, u))
    return u
예제 #4
0
파일: fluid.py 프로젝트: asrvsn/gds
def edge_fourier_transform(G, method='hodge_faces'):
    '''
	Diagonalization of 1-form laplacian with varying 2-form definitions
	'''
    if method == 'hodge_faces':  # 2-forms defined on planar faces (default)
        pass
    elif method == 'hodge_cycles':  # 2-forms defined on cycle basis
        G.faces = [tuple(f) for f in nx.cycle_basis(G)]
    elif method == 'dual':
        raise NotImplementedError()
    else:
        raise ValueError(f'Method {method} undefined')

    v = gds.edge_gds(
        G)  # TODO: assumes determinism of edge index assignment -- fix!
    L1 = -v.laplacian(np.eye(v.ndim))
    eigvals, eigvecs = np.linalg.eigh(
        L1
    )  # Important to use eigh() rather than eig() -- otherwise non-unitary eigenvectors
    eigvecs = np.asarray(eigvecs)

    # Unitary check
    assert (np.round(eigvecs @ eigvecs.T,
                     6) == np.eye(v.ndim)).all(), 'VV^T != I'
    assert (np.round(eigvecs.T @ eigvecs,
                     6) == np.eye(v.ndim)).all(), 'V^TV != I'

    return eigvals, eigvecs
예제 #5
0
파일: laplace.py 프로젝트: asrvsn/gds
def square_edge_diffusion():
    m, n = 10, 10
    G, (l, r, t, b) = gds.square_lattice(n, m, with_boundaries=True)
    faces, outer_face = gds.embedded_faces(G)
    for j in range(m):
        G.add_edge((n - 1, j), (0, j))
    aux_faces = [((n - 1, j), (0, j), (0, j + 1), (n - 1, j + 1))
                 for j in range(m - 1)]
    G.faces = faces + aux_faces  # Hacky
    G.rendered_faces = np.array(range(len(faces)), dtype=np.intp)  # Hacky
    v = gds.edge_gds(G)
    v.set_evolution(dydt=lambda t, y: v.laplacian(y))
    velocity = 1.0

    def boundary(e):
        if e in b.edges:
            return velocity
        elif e == ((0, 0), (m - 1, 0)):
            return -velocity
        elif e in t.edges or e == ((0, n - 1), (m - 1, n - 1)):
            return 0.0
        return None

    v.set_constraints(dirichlet=boundary)
    return v
예제 #6
0
파일: laplace.py 프로젝트: asrvsn/gds
def edge_diffusion(m, n, constr, periodic=False):
    G, (l, r, t, b) = constr(m, n, with_boundaries=True)
    if periodic:
        for x in l.nodes:
            for y in r.nodes:
                if x[1] == y[1]:
                    G.add_edge(x, y)
    v = gds.edge_gds(G)
    v.set_evolution(dydt=lambda t, y: v.laplacian(y))
    velocity = -1.0

    def boundary(e):
        if e[0] in l.nodes and e[1] in r.nodes and e[0][1] == 0:
            return -velocity
        if e in b.edges:
            if e[1][1] > e[0][1] and e[0][0] % 2 == 0:
                # Hack to fix hexagonal bcs
                return -velocity
            return velocity
        elif e in t.edges:
            return 0.0
        return None

    v.set_constraints(dirichlet=boundary)
    return v
예제 #7
0
def euler_cycles(G: nx.Graph, density=1.0, integrator=Integrators.lsoda):
    velocity = gds.edge_gds(G)
    cycles = gds.cycle_basis(G)
    print(cycles)
    ops = dict()
    edge_set = set(G.edges())
    for i, cycle in enumerate(cycles):
        print(cycle)
        n = len(cycle)
        D = np.zeros((n, n))
        P = np.zeros((n, velocity.ndim))
        # edge_pairs = zip(zip(chain([cycle[-2], cycle[-1]], cycle[:-2]), chain([cycle[-1]], cycle[:-1])), zip(chain([cycle[-1]], cycle[:-1]), cycle))
        edges = zip(chain([cycle[-1]], cycle[:-1]), cycle)
        for idx, e_i in enumerate(edges):
            D[idx, idx] = -1
            D[idx, (idx + 1) % n] = 1
            i = velocity.X[e_i]
            P[idx, i] = 1 if e_i in edge_set else -1  # Re-orient
        Dm = relu(-D)
        Dp = relu(D)
        F = Dm.T @ Dp - Dp.T @ Dm
        ops[i] = {'c': cycle, 'D': D, 'P': P, 'F': F}

    def dvdt(t, v):
        ret = 0
        for i in ops:
            F, P = ops[i]['F'], ops[i]['P']
            pv = P @ v
            ret -= P.T @ (np.multiply(F.T, pv).T + np.multiply(F, pv)) @ pv
        return velocity.leray_project(ret)

    # dvdt(0, velocity.y)
    velocity.set_evolution(dydt=dvdt, integrator=integrator)
    return velocity
예제 #8
0
def navier_stokes(G: nx.Graph,
                  viscosity=1e-3,
                  density=1.0,
                  v_free=[],
                  body_force=None,
                  advect=None,
                  integrator=Integrators.lsoda,
                  **kwargs) -> (gds.node_gds, gds.edge_gds):
    if body_force is None:
        body_force = lambda t, y: 0
    if advect is None:
        advect = lambda v: v.advect()

    pressure = gds.node_gds(G, **kwargs)
    pressure.set_evolution(lhs=lambda t, p: pressure.laplacian(p) / density,
                           refresh_cvx=False)

    v_free = np.array([pressure.X[x] for x in set(v_free)], dtype=np.intp)
    velocity = gds.edge_gds(G, v_free=v_free, **kwargs)
    velocity.set_evolution(
        dydt=lambda t, u: velocity.
        leray_project(-advect(velocity) + body_force(t, u) +
                      (0 if viscosity == 0 else velocity.laplacian() *
                       viscosity / density)) - pressure.grad() / density,
        max_step=1e-3,
        integrator=integrator,
    )

    return velocity, pressure
예제 #9
0
def vector_advection_test(flows=[1,1,1,1,1], **kwargs):
	G = nx.Graph()
	G.add_nodes_from([0, 1, 2, 3, 4, 5])
	G.add_edges_from([(2, 0), (3, 0), (0, 1), (1, 5), (1, 4)])
	flow = gds.edge_gds(G)
	def field(e):
		ret = 1
		if e == (0, 2):
			ret = -1
		if e == (0, 3):
			ret = -1
		return flows[flow.edges[e]] * ret
	flow.set_evolution(dydt=lambda t, y: np.zeros_like(y))
	flow.set_initial(y0=field)
	obs = gds.edge_gds(G)
	obs.set_evolution(dydt=lambda t, y: -obs.advect(**kwargs))
	obs.set_initial(y0=field)
	return flow, obs
예제 #10
0
def vector_advection_circle_2():
	n = 10
	G = nx.Graph()
	G.add_nodes_from(list(range(n)))
	G.add_edges_from(list(zip(range(n), [n-1] + list(range(n-1)))))
	flow = gds.edge_gds(G)
	obs = gds.edge_gds(G)
	flow.set_evolution(dydt=lambda t, y: np.zeros_like(y))
	obs.set_evolution(dydt=lambda t, y: -obs.advect(flow, vectorized=False))
	def init_obs(e):
		if e == (2,3): return 1.5
		elif e == (0,n-1): return -1.0
		return 1.0
	obs.set_initial(y0=init_obs)
	def init_flow(e):
		if e == (0,n-1): return -1.0
		return 1.0
	flow.set_initial(y0=init_flow)
	# flow.set_constraints(dirichlet=dict_fun({(2,3): 1.0}))
	return flow, obs
예제 #11
0
def advection(G, v_field, kind=None):
	flow_diff = np.zeros(len(G.edges()))
	flow = gds.edge_gds(G)
	flow.set_evolution(dydt=lambda t, y: flow_diff)
	flow.set_initial(y0 = v_field)
	conc = gds.node_gds(G)
	if kind == None:
		conc.set_evolution(dydt=lambda t, y: -conc.advect(flow))
	elif kind == 'lie':
		conc.set_evolution(dydt=lambda t, y: -conc.lie_advect(flow))
	else:
		raise Exception('unrecognized kind')
	return conc, flow
예제 #12
0
def self_advection_2():
	G = nx.Graph()
	G.add_nodes_from(list(range(1,9)))
	v_field = {
		(1,2): 2, (2,3): 1, (3,4): 2, (1,4): -3,
		(5,6): 2, (6,7): 3, (7,8): 2, (5,8): -1,
		(1,5): 1, (2,6): 1, (3,7): -1, (4,8): -1,
	}
	G.add_edges_from(v_field.keys())
	u = gds.edge_gds(G)
	u.set_evolution(dydt=lambda t, y: -u.advect())
	u.set_initial(y0=lambda e: v_field[e])
	return u
예제 #13
0
def ns_cycle_test():
    n = 30
    G = gds.directed_cycle_graph(n)
    velocity = gds.edge_gds(G)
    mu = 0  # viscosity
    print(velocity.X.keys())
    D = np.zeros((velocity.ndim, velocity.ndim))
    L = -D.T @ D
    IV = np.zeros((velocity.ndim, velocity.ndim))
    edge_pairs = zip(
        zip(chain([n - 2, n - 1], range(n - 2)), chain([n - 1], range(n - 1))),
        zip(chain([n - 1], range(n - 1)), range(n)))
    for idx, (e_i, e_j) in enumerate(edge_pairs):
        print(e_i, e_j)
        i, j = velocity.X[e_i], velocity.X[e_j]
        D[i, i] = -1
        D[i, j] = 1
        IV[j, idx] = 1
    # print(D)
    # D = -velocity.incidence # Either incidence or dual derivative seems to work
    Dm = relu(-D)
    Dp = relu(D)
    F = Dm.T @ Dp - Dp.T @ Dm

    # pdb.set_trace()
    def dvdt(t, v):
        A = np.multiply(F.T, v).T + np.multiply(F, v)
        return -A @ v + mu * L @ v

    velocity.set_evolution(dydt=dvdt)
    bump = 2 * stats.norm().pdf(np.linspace(-4, 4, n))
    # v0 = -IV @ bump
    # v0 = IV @ rotate(bump, 10)
    v0 = IV @ (bump - rotate(bump, n // 2))
    velocity.set_initial(y0=lambda e: v0[velocity.X[e]])

    sys = gds.couple({
        'velocity': velocity,
        # 'gradient': velocity.project(gds.GraphDomain.edges, lambda v: D @ v.y),
        # 'laplacian': velocity.project(gds.GraphDomain.edges, lambda v: -D.T @ D @ v.y),
        # 'dual': velocity.project(gds.GraphDomain.nodes, lambda v: v.y),
        # 'L1': velocity.project(PointObservable, lambda v: np.abs(v.y).sum()),
        # 'L2': velocity.project(PointObservable, lambda v: np.linalg.norm(v.y)),
        # 'min': velocity.project(PointObservable, lambda v: v.y.min()),
    })
    gds.render(sys,
               canvas=gds.grid_canvas(sys.observables.values(), 3),
               edge_max=3,
               dynamic_ranges=False)
예제 #14
0
def self_advection_test_2(flows=[1,1,1,1,1], interactions=[1,0,1,0]):
	G = nx.Graph()
	G.add_nodes_from([0, 1, 2, 3, 4, 5])
	G.add_edges_from([(2, 0), (3, 0), (0, 1), (1, 5), (1, 4)])
	flow = gds.edge_gds(G)
	def field(e):
		ret = 1
		if e == (0, 2):
			ret = -1
		if e == (0, 3):
			ret = -1
		return flows[flow.edges[e]] * ret
	flow.set_evolution(dydt=lambda t, y: -flow.advect2(vectorized=False, interactions=interactions))
	flow.set_initial(y0=field)
	return flow
예제 #15
0
def solve_beltrami(G: nx.Graph):
    flow = gds.edge_gds(G)

    def f(x):
        return np.linalg.norm(
            flow.leray_project(flow.advect(flow.leray_project(x))))

    x0 = np.random.uniform(low=-10, high=10, size=flow.ndim)
    sol = basinhopping(f, x0)
    if sol.fun >= 1e-6:
        print('Unsuccessful solve')
        pdb.set_trace()
    u = flow.leray_project(sol.x)
    flow.set_evolution(nil=True)
    flow.set_initial(y0=lambda x: u[flow.X[x]])
    return flow
예제 #16
0
def self_advection_1():
	G = nx.Graph()
	G.add_nodes_from(list(range(1,7)))
	G.add_edges_from([
		(1,2),(2,3),(3,4),(4,1),
		(4,5),(5,6),(6,3),
	])
	negated = set([(1,4),(3,6),])
	def v_field(e):
		ret = 1.0
		if e in negated:
			ret *= -1
		if e == (3,4):
			ret *= 2
		return ret
	u = gds.edge_gds(G)
	u.set_evolution(dydt=lambda t, y: -u.advect())
	u.set_initial(y0=v_field)
	return u
예제 #17
0
def show_leray(G, v: Callable = None, **kwargs):
    '''
	Show Leray decomposition of a vector field.
	'''
    if v is None:
        v = lambda x: np.random.uniform(1, 2)
    orig = gds.edge_gds(G)
    orig.set_evolution(nil=True)
    orig.set_initial(y0=v)

    div_free = orig.project(GraphDomain.edges, lambda u: u.leray_project())
    curl_free = orig.project(GraphDomain.edges,
                             lambda u: u.y - u.leray_project())

    sys = gds.couple({
        'original':
        orig,
        'original (div)':
        orig.project(GraphDomain.nodes, lambda u: u.div()),
        'original (curl)':
        orig.project(GraphDomain.faces, lambda u: u.curl()),
        'div-free':
        div_free,
        'div-free (div)':
        div_free.project(
            GraphDomain.nodes,
            lambda u: orig.div(u.y)),  # TODO: chaining projections?
        'div-free (curl)':
        div_free.project(GraphDomain.faces, lambda u: orig.curl(u.y)),
        'curl-free':
        curl_free,
        'curl-free (div)':
        curl_free.project(GraphDomain.nodes, lambda u: orig.div(u.y)),
        'curl-free (curl)':
        curl_free.project(GraphDomain.faces, lambda u: orig.curl(u.y)),
    })

    gds.render(sys,
               n_spring_iters=1000,
               canvas=gds.grid_canvas(sys.observables.values(), 3),
               title='Leray decomposition',
               min_rng_size=1e-3,
               **kwargs)
예제 #18
0
def self_advection_circle():
	n = 10
	G = nx.Graph()
	G.add_nodes_from(list(range(n)))
	G.add_edges_from(list(zip(range(n), [n-1] + list(range(n-1)))))
	flow = gds.edge_gds(G)
	flow.set_evolution(dydt=lambda t, y: -flow.advect())
	# flow.set_initial(y0=dict_fun({(2,3): 1.0, (3,4): 1.0}, def_val=0.))
	def init_flow(e):
		if e == (2,3): return 1.5
		elif e == (0,n-1): return -1.0
		return 1.0
	flow.set_initial(y0=init_flow)
	flow.advect()
	sys = gds.couple({
		'flow': flow,
		'advective': flow.project(gds.GraphDomain.edges, lambda y: -y.advect()),
	})
	gds.render(sys, edge_max=0.5)
예제 #19
0
파일: fluid.py 프로젝트: asrvsn/gds
def navier_stokes(G: nx.Graph,
                  viscosity=1e-3,
                  density=1.0,
                  v_free=[],
                  e_free=[],
                  e_normal=[],
                  advect=None,
                  integrator=Integrators.lsoda,
                  **kwargs) -> (gds.node_gds, gds.edge_gds):
    if advect is None:
        advect = lambda v: v.advect()

    pressure = gds.node_gds(G, **kwargs)
    velocity = gds.edge_gds(G, **kwargs)
    v_free = np.array(
        [pressure.X[x] for x in set(v_free)],
        dtype=np.intp)  # Inlet/outlet nodes (typically, pressure boundaries)
    e_free = np.array([velocity.X[x] for x in set(e_free)],
                      dtype=np.intp)  # Free-slip surface
    e_normal = np.array([velocity.X[x] for x in set(e_normal)],
                        dtype=np.intp)  # Inlets/outlet edges normal to surface
    min_step = 1e-3

    def pressure_f(t, y):
        dt = max(min_step, velocity.dt)
        lhs = velocity.div(velocity.y / dt - advect(velocity) +
                           velocity.laplacian(free=e_free, normal=e_normal) *
                           viscosity / density)
        lhs[v_free] = 0.
        lhs -= pressure.laplacian(y) / density
        return lhs

    def velocity_f(t, y):
        return -advect(
            velocity) - pressure.grad() / density + velocity.laplacian(
                free=e_free, normal=e_normal) * viscosity / density

    pressure.set_evolution(lhs=pressure_f)
    velocity.set_evolution(dydt=velocity_f, integrator=integrator)

    return velocity, pressure
예제 #20
0
def plot_beltrami():
    if not os.path.exists(save_path):
        raise Exception('no data')

    sys = dict()
    fig_N, fig_M = 0, 0
    with open(save_path, 'rb') as f:
        data = cloudpickle.load(f)
        fig_N, fig_M = len(data), len(data[next(iter(data))])
        for N, subdata in sorted(data.items(), key=lambda x: x[0]):
            for i in subdata:
                print((N, i))
                u = subdata[i]
                G = gds.triangular_lattice(m=1, n=N)
                flow = gds.edge_gds(G)
                flow.set_evolution(nil=True)
                flow.set_initial(y0=lambda x: u[flow.X[x]])
                sys[f'{N}_{i}'] = flow
    sys = gds.couple(sys)
    canvas = gds.grid_canvas(sys.observables.values(), fig_M)
    gds.render(sys, canvas=canvas, edge_max=0.6, dynamic_ranges=True)
예제 #21
0
파일: laplace.py 프로젝트: asrvsn/gds
def hex_edge_diffusion():
    m, n = 10, 20
    G, (l, r, t, b) = gds.hexagonal_lattice(m, n, with_boundaries=True)
    faces, outer_face = gds.embedded_faces(G)
    contractions = {}
    for j in range(1, 2 * m + 1):
        G = nx.algorithms.minors.contracted_nodes(G, (0, j), (n, j))
        contractions[(n, j)] = (0, j)
    nx.set_node_attributes(G, None, 'contraction')
    rendered_faces = set()
    for i, face in enumerate(faces):
        face = list(face)
        modified = False
        for j, node in enumerate(face):
            if node in contractions:
                n_l = contractions[node]  # identified
                face[j] = n_l
                faces[i] = tuple(face)
                modified = True
        if not modified:
            rendered_faces.add(i)
    G.faces = faces
    G.rendered_faces = np.array(sorted(list(rendered_faces)),
                                dtype=np.intp)  # Hacky
    # pdb.set_trace()
    v = gds.edge_gds(G)
    v.set_evolution(dydt=lambda t, y: v.laplacian(y))
    velocity = 1.0

    def boundary(e):
        if (e[0][1] == e[1][1] == 0) and (e[0][0] == e[1][0] - 1):
            return velocity
        elif e in t.edges or e == ((0, 2 * m), (n, 2 * m + 1)):
            return 0.0
        return None

    v.set_constraints(dirichlet=boundary)
    return v
예제 #22
0
 def foreach(G, data, N, KE):
     v = gds.edge_gds(G)
     P = v.leray_projector
     data = torch.from_numpy(data).float()
     spectra = 0
     du_t = ortho_group.rvs(
         data.shape[1])  # Initial orthonormal perturbation matrix
     for i in range(window):
         u_t = data[transient + i]
         J_t = P @ v.advect_jac(u_t).numpy()
         du_t += dt * J_t @ du_t
         if i % interval == 0:
             Q, R = np.linalg.qr(du_t, mode='complete')
             spectra += np.log(np.abs(np.diag(R)))
             du_t = Q
     spectra /= (window / interval)
     spectra = spectra[spectra >= floor]
     if not (N in plot_data):
         plot_data[N] = {'x': [], 'y': [], 'e_x': [], 'e_y': []}
     plot_data[N]['x'].extend([KE] * spectra.size)
     plot_data[N]['y'].extend(spectra.tolist())
     plot_data[N]['e_x'].append(KE)
     plot_data[N]['e_y'].append(spectra.max())
예제 #23
0
파일: laplace.py 프로젝트: asrvsn/gds
def tri_edge_diffusion():
    m, n = 10, 20
    G, (l, r, t, b) = gds.triangular_lattice(m, n, with_boundaries=True)
    faces, outer_face = gds.embedded_faces(G)
    for j in range(m + 1):
        G = nx.algorithms.minors.contracted_nodes(G, (0, j), ((n + 1) // 2, j))
    rendered_faces = set()
    r_nodes = set(r.nodes())
    for i, face in enumerate(faces):
        face = list(face)
        modified = False
        for j, node in enumerate(face):
            if node in r_nodes:
                n_l = (0, node[1])  # identified
                face[j] = n_l
                faces[i] = tuple(face)
                modified = True
        if not modified:
            rendered_faces.add(i)
    G.faces = faces
    G.rendered_faces = np.array(sorted(list(rendered_faces)),
                                dtype=np.intp)  # Hacky
    v = gds.edge_gds(G)
    v.set_evolution(dydt=lambda t, y: v.laplacian(y))
    velocity = 1.0

    def boundary(e):
        if e in b.edges:
            return velocity
        elif e == ((0, 0), (n // 2 - 1, 0)):
            return -velocity
        elif e in t.edges or e == ((0, m), (n // 2 - 1, m)):
            return 0.0
        return None

    v.set_constraints(dirichlet=boundary)
    return v
예제 #24
0
 def foreach(G, data, ax):
     v = gds.edge_gds(G)
     values = []
     for row in data:
         values.append(np.dot(row, v.leray_project(-v.advect(row))))
     ax.plot(values)