Exemple #1
0
def show_L0_eigfuns(G, n=12, **kwargs):
	'''
	Show eigenfunctions of 0-Laplacian
	'''
	obs = gds.node_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)
	# 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]))):
		ev = np.round(ev, 5)
		obs = gds.node_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'L0-eigenfunctions', **kwargs)
Exemple #2
0
def heat_test():
    G = gds.grid_graph(10, 10)
    temp1 = gds.node_gds(G)
    x = (5, 5)
    i = temp1.X[x]
    B = temp1.incidence.copy().todense()
    B[i][B[i] < 0] = 0
    temp1.set_evolution(dydt=lambda t, y: -B @ B.T @ y)
    temp1.set_initial(y0=lambda n: 1.0 if n == x else 0.0)
    temp2 = gds.node_gds(G)
    temp2.set_evolution(dydt=lambda t, y: temp2.laplacian(y))
    temp2.set_constraints(dirichlet={x: 1.0})
    return temp1, temp2
Exemple #3
0
def schrodinger(G: nx.Graph, V: Callable, psi0: Callable, **kwargs):
	re, im = gds.node_gds(G), gds.node_gds(G)
	V_arr = np.array([V(x) for x in re.X])
	def f(t, y):
		psi = re.y + 1j*im.y
		return 1j * (re.laplacian(psi) - V_arr*psi)
	re.set_evolution(dydt=lambda t, y: np.real(f(t, y)))
	re.set_initial(y0=lambda x: np.real(psi0(x)))
	im.set_evolution(dydt=lambda t, y: np.imag(f(t, y)))
	im.set_initial(y0=lambda x: np.imag(psi0(x)))
	sys = gds.couple({
		'real': re,
		'imag': im,
	})
	gds.render(sys, dynamic_ranges=True, node_palette=cc.bmy, n_spring_iters=1000, **kwargs)
Exemple #4
0
def lagrangian_tracer(velocity: gds.edge_gds, alpha=1.0) -> gds.node_gds:
    ''' Passive tracer '''
    tracer = gds.node_gds(velocity.G)
    tracer.set_evolution(dydt=lambda t, y: -alpha * tracer.advect(velocity))
    start_x = random.choice(list(velocity.G.nodes()))
    tracer.set_initial(y0=lambda x: 1. if x == start_x else 0.)
    return tracer
Exemple #5
0
def wave(G: nx.Graph, c: float=5.0):
	n = 20
	G = gds.triangular_lattice(n, n*2, periodic=True)
	amplitude = gds.node_gds(G)
	amplitude.set_evolution(dydt=lambda t, y: (c**2)*amplitude.laplacian(), order=2)
	amplitude.set_initial(y0=lambda x: x[0]*x[1]*(n-x[0])*(n-x[1]) / (n**3))
	gds.render(amplitude, dynamic_ranges=True, node_palette=cc.bmy, n_spring_iters=1000, title='Waves on a simplicial torus')
Exemple #6
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
Exemple #7
0
def grid_tv_boundary():
    G = gds.square_lattice(10, 10)
    temperature = gds.node_gds(G)
    temperature.set_evolution(dydt=lambda t, y: temperature.laplacian())
    temperature.set_constraints(dirichlet=gds.combine_bcs(
        lambda x: 0 if x[0] == 9 else None,
        lambda t, x: np.sin(t + x[1] / 4)**2 if x[0] == 0 else None))
    gds.render(temperature, title='Heat equation with time-varying boundary')
Exemple #8
0
def SIR_model(
        G,
        dS=0.1,
        dI=0.5,
        dR=0.0,  # Diffusive terms
        muS=0.1,
        muI=0.3,
        muR=0.1,  # Death rates
        Lambda=0.5,  # Birth rate 
        beta=0.2,  # Rate of contact
        gamma=0.2,  # Rate of recovery
        initial_population=100,
        patient_zero=None,
        **kwargs):
    ''' 
	Reaction-Diffusion SIR model
	Based on Huang et al, https://www.researchgate.net/publication/281739911_The_reaction-diffusion_system_for_an_SIR_epidemic_model_with_a_free_boundary
	'''
    susceptible = gds.node_gds(G, **kwargs)
    infected = gds.node_gds(G, **kwargs)
    recovered = gds.node_gds(G, **kwargs)

    susceptible.set_evolution(dydt=lambda t, y: dS * susceptible.laplacian(
    ) - muS * susceptible.y - beta * susceptible.y * infected.y + Lambda)

    infected.set_evolution(
        dydt=lambda t, y: dI * infected.laplacian() + beta * susceptible.y *
        infected.y - muI * infected.y - gamma * infected.y)

    recovered.set_evolution(dydt=lambda t, y: dR * recovered.laplacian() +
                            gamma * infected.y - muR * recovered.y)

    if patient_zero is None:
        patient_zero = random.choice(list(G.nodes()))
    print(patient_zero)
    susceptible.set_initial(y0=lambda x: initial_population)
    infected.set_initial(y0=lambda x: 1 if x == patient_zero else 0.)

    sys = gds.couple({
        'Susceptible': susceptible,
        'Infected': infected,
        'Recovered': recovered
    })

    return sys
Exemple #9
0
def swift_hohenberg(G: nx.graph, a: float, b: float, c: float, gam0: float, gam2: float) -> gds.node_gds:
	assert c > 0, 'Unstable'
	amplitude = gds.node_gds(G)
	amplitude.set_evolution(
		dydt=lambda t, y: -a*y - b*(y**2) - c*(y**3) + gam0*amplitude.laplacian(y) - gam2*amplitude.bilaplacian(y)
	)
	# amplitude.set_initial(y0=lambda _: np.random.uniform())
	amplitude.set_initial(y0=lambda x: x[0]+x[1])
	return amplitude
Exemple #10
0
def heat_grid(n=10, steady_state=False) -> gds.node_gds:
    G = gds.square_lattice(n, n)
    temp = gds.node_gds(G)
    if steady_state:
        ''' Steady-state version (for comparison) '''
        temp.set_evolution(cost=lambda t, y: temp.laplacian(y))
    else:
        temp.set_evolution(dydt=lambda t, y: temp.laplacian(y))
    return temp
Exemple #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
Exemple #12
0
def test_orientation():
    G = gds.hexagonal_lattice(3, 4)
    # G = gds.random_planar_graph(100, 0.2)

    eq1 = gds.face_gds(G)
    eq1.set_evolution(nil=True)
    eq1.set_initial(y0=lambda x: 0.5)
    eq2 = gds.node_gds(G)
    eq2.set_evolution(nil=True)
    sys = gds.couple({
        'eq1': eq1,
        'eq2': eq2,
    })
    gds.render(sys, face_orientations=True)
Exemple #13
0
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