Basic example

In this notebook we show how to perform a basic simulation.


In [1]:
import numpy as np
from pstd import PSTD, PML, Medium, PointSource
from acoustics import Signal
import seaborn as sns
%matplotlib inline

Configuration

The following are the parameters for our simulation


In [2]:
x = 30.0
y = 20.0
z = 0.0

soundspeed = 343.2
density = 1.296
maximum_frequency_target = 200.0

Create model

We now create a model. Waves propagate in a medium which we define first.


In [3]:
medium = Medium(soundspeed=soundspeed, density=density)

The model is only finite and to prevent aliasing we need a Perfectly Matched Layer.


In [4]:
pml = PML(absorption_coefficient=(1000.0, 1000.0), depth=10.0)

Now we create the actual model.


In [5]:
model = PSTD(maximum_frequency=maximum_frequency_target, pml=pml, medium=medium, cfl=0.05, size=[x, y])

In this example our source excites a pulse.


In [6]:
source_position = (x/4.0, y/2.0)

source = model.add_object('source', 'PointSource', position=source_position, 
                          excitation='pulse', quantity='pressure', amplitude=0.1)

We also add a receiver on the other side of the domain


In [7]:
receiver_position = (x*3.0/4.0, y/2.0)

receiver = model.add_object('receiver', 'Receiver', position=receiver_position, quantity='pressure')

Check model

To get a quick overview of all parameters, for example to check them, we can print one


In [8]:
print(model.overview())


Model timestep: 0.000125 
Maximum frequency: 200.0
Sample frequency temporal: 8000.0
Sample frequency spatial: 400.0
Grid spacing: 0.858
Grid shape: (59, 48)
Grid shape without PML: (35, 24)
Grid shape with PML: (59, 48)
PML nodes: 12
PML depth target: 10.00
PML depth actual: 10.30
Grid size: (50.622, 41.183999999999997)
Grid size without PML: (30.030000000000001, 20.591999999999999)
Grid size with PML: (50.622, 41.183999999999997)
Amount of sources: 1
Amount of receivers: 1

To check whether the geometry is as we want it to be, we can simply draw it.


In [9]:
_ = model.plot_scene()


Running the simulation

Now that we've defined and checked our model we can run it.

With model.run() you can specify the amount of time steps or amount of seconds it should run.


In [10]:
model.run(seconds=0.002)


Out[10]:
<pstd.pstd.PSTD at 0x7f3631e2f828>

Let's see how the sound pressure field looks like now.


In [11]:
_ = model.plot_field()


It might happen that you realize that you actually need to calculate a bit further. This can easily be done, since the state is remembered. Simply use model.run() again and the simulation continues.


In [12]:
model.run(seconds=0.060)


Out[12]:
<pstd.pstd.PSTD at 0x7f3631e2f828>

as you can see.


In [13]:
_ = model.plot_field()


Recordings

The receivers can record a quantity at a specific location. In this case, we're measuring an impulse response. The method receiver.recording() returns an instance of acoustics.Signal.


In [14]:
_ = receiver.recording().plot()


If however, you want to restart the simulation you can do so with model.restart().


In [15]:
model.restart()


Out[15]:
<pstd.pstd.PSTD at 0x7f3631e2f828>

Show log

Some simulations can take a very long time. To check how far the simulation is, you can check the log.


In [16]:
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)

When we now run the simulation, you will see which step it is at.


In [17]:
model.run(steps=10)


INFO:root:Will run for 10 steps.
INFO:root:Progress: Continuing simulation
INFO:root:Step 0 is done and took 0.03338339600304607 seconds.
INFO:root:Step 1 is done and took 0.02857455800040043 seconds.
INFO:root:Step 2 is done and took 0.019433445999311516 seconds.
INFO:root:Step 3 is done and took 0.019864893998601474 seconds.
INFO:root:Step 4 is done and took 0.03289434700127458 seconds.
INFO:root:Step 5 is done and took 0.021083128998725442 seconds.
INFO:root:Step 6 is done and took 0.05002360800062888 seconds.
INFO:root:Step 7 is done and took 0.012684220000664936 seconds.
INFO:root:Step 8 is done and took 0.015025019998574862 seconds.
INFO:root:Step 9 is done and took 0.023157126001024153 seconds.
INFO:root:Progress: Done
Out[17]:
<pstd.pstd.PSTD at 0x7f3631e2f828>

In [18]:
_ = model.plot_field()