Wave equation

import functools as ft
import multiprocessing as mp
import logging

import numpy as np
from scipy.signal import gaussian

import pylab as pl

from triflow import Model, Simulation, schemes, displays

%matplotlib inline

We initialize the model with the wave equation written as a system of first order differential equations.

\[\partial_{t,\,t}u = c^2 \partial_{x,\,x} u\]

which lead to

with \(c\) the velocity of the wave.

model = Model(["c**2 * dxxu", "v"],
               ["v", "u"], "c")

We discretize our spatial domain. retstep=True ask to return the spatial step.

x, dx = np.linspace(0, 100, 500, retstep=True)

We initialize with three gaussian pulses for the initial condition

u = (np.roll(gaussian(x.size, 10), x.size // 5) +
     np.roll(gaussian(x.size, 10), -x.size // 5) -
     gaussian(x.size, 30) * 1.5)
v = np.zeros_like(u)

fields = model.fields_template(x=x, u=u, v=v)

pl.figure(figsize=(15, 4))
pl.plot(fields.x, fields.u)
pl.xlim(0, fields.x.max())
pl.show()
../_images/wave_equation_7_0.png

We precise our parameters. The default scheme provide an automatic time_stepping. We want dirichlet boundary condition, so we set the periodic flag to False.

parameters = dict(c=5, periodic=False)

This function will set the boundary condition. We will have a fixed rope at each edge.

def dirichlet(t, fields, pars):
    # fields.u[:] = np.sin(t * 2 * np.pi * 2) * gaussian(x.size, 10) - fields.u[:]
    fields.u[0] = 0
    fields.u[-1] = 0
    fields.v[0] = 0
    fields.v[-1] = 0
    return fields, pars

We initialize the simulation, and we set a bokeh display in order to have real-time plotting.

t = 0
simulation = Simulation(model, t, fields, parameters,
                        dt=.1, tmax=15,
                        hook=dirichlet)

We iterate on the simulation until the end.

pl.figure(figsize=(15, 10))
for i, (t, fields) in enumerate(simulation):
    if i % 2 == 0:
        pl.fill_between(fields.x, fields.u + .1 * (i + 1),
                        fields.u.min() - 1,
                        color='darkred', zorder=-2 * i, alpha=.7)
        pl.plot(fields.x, fields.u + .1 * (i + 1),
                color='white',
                zorder=-(2 * i - 1))
    print(f"t: {t:g}".ljust(80), end='\r')
pl.xlim(0, fields.x.max())
pl.show()
t: 15
../_images/wave_equation_15_1.png