This page was generated from doc/examples/animations-pulsating-sphere.ipynb.
Interactive online version:
Animations of a Pulsating Sphere
[1]:
import sfs
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import HTML
In this example, the sound field of a pulsating sphere is visualized. Different acoustic variables, such as sound pressure, particle velocity, and particle displacement, are simulated. The first two quantities are computed with
while the last one can be obtained by using
which converts the particle velocity into displacement.
A couple of additional functions are implemented in
in order to help creating animating pictures, which is fun!
[2]:
import animations_pulsating_sphere as animation
[3]:
# Pulsating sphere
center = [0, 0, 0]
radius = 0.25
amplitude = 0.05
f = 1000 # frequency
omega = 2 * np.pi * f # angular frequency
# Axis limits
figsize = (6, 6)
xmin, xmax = -1, 1
ymin, ymax = -1, 1
# Animations
frames = 20 # frames per period
Particle Displacement
[4]:
grid = sfs.util.xyz_grid([xmin, xmax], [ymin, ymax], 0, spacing=0.025)
ani = animation.particle_displacement(
omega, center, radius, amplitude, grid, frames, figsize, c='Gray')
plt.close()
HTML(ani.to_jshtml())
[4]:
Click the arrow button to start the animation. to_jshtml() allows you to play with the animation, e.g. speed up/down the animation (+/- button). Try to reverse the playback by clicking the left arrow. You’ll see a sound sink.
You can also show the animation by using to_html5_video(). See the documentation for more detail.
Of course, different types of grid can be chosen. Below is the particle animation using the same parameters but with a hexagonal grid.
[5]:
def hex_grid(xlim, ylim, hex_edge, align='horizontal'):
if align is 'vertical':
umin, umax = ylim
vmin, vmax = xlim
else:
umin, umax = xlim
vmin, vmax = ylim
du = np.sqrt(3) * hex_edge
dv = 1.5 * hex_edge
num_u = int((umax - umin) / du)
num_v = int((vmax - vmin) / dv)
u, v = np.meshgrid(np.linspace(umin, umax, num_u),
np.linspace(vmin, vmax, num_v))
u[::2] += 0.5 * du
if align is 'vertical':
grid = v, u, 0
elif align is 'horizontal':
grid = u, v, 0
return grid
<>:2: SyntaxWarning: "is" with 'str' literal. Did you mean "=="?
<>:16: SyntaxWarning: "is" with 'str' literal. Did you mean "=="?
<>:18: SyntaxWarning: "is" with 'str' literal. Did you mean "=="?
<>:2: SyntaxWarning: "is" with 'str' literal. Did you mean "=="?
<>:16: SyntaxWarning: "is" with 'str' literal. Did you mean "=="?
<>:18: SyntaxWarning: "is" with 'str' literal. Did you mean "=="?
/tmp/ipykernel_1294/2319301824.py:2: SyntaxWarning: "is" with 'str' literal. Did you mean "=="?
if align is 'vertical':
/tmp/ipykernel_1294/2319301824.py:16: SyntaxWarning: "is" with 'str' literal. Did you mean "=="?
if align is 'vertical':
/tmp/ipykernel_1294/2319301824.py:18: SyntaxWarning: "is" with 'str' literal. Did you mean "=="?
elif align is 'horizontal':
[6]:
grid = sfs.util.as_xyz_components(hex_grid([xmin, xmax],
[ymin, ymax],
0.0125,
'vertical'))
ani = animation.particle_displacement(
omega, center, radius, amplitude, grid, frames, figsize, c='Gray')
plt.close()
HTML(ani.to_jshtml())
[6]:
Another one using a random grid.
[7]:
grid = sfs.util.as_xyz_components([np.random.uniform(xmin, xmax, 4000),
np.random.uniform(ymin, ymax, 4000),
0])
ani = animation.particle_displacement(
omega, center, radius, amplitude, grid, frames, figsize, c='Gray')
plt.close()
HTML(ani.to_jshtml())
[7]: