import IPython
Ray Tracing
Ray Paths, Refraction and Snell’s Law
Wavefronts are points that are reached by the pressure perturbation at the same time.
At each point of the wavefront we can associate a vector: the gradient \(\nabla\tau\) of the time of arrival \(\tau\). Its direction is towards points that are reached with increasing time.
The gradient, w.r.t to the wavefront, is perpendicular to the local tangent of the wavefront.
Acoustic propagation is continuous: wavefronts are continuous (even though we are drawing them discretely)
We can build a continuous curve that connects the directions of the gradients of the wavefronts: we call this ray.
When wavefronts are circumferences (or spheres), rays are straight lines that start at the source
- Medium must be isotrope (same properties in all directions) to have spherical wavefronts
- For each ray we can define the angle \(\theta\) with the tangent to the ray
- We can do this for every point of the ray, and for every ray
Snell’s Law
- For each ray, \(\theta\) must locally satisfy:
\[ \frac{\cos\theta}{c} = const \]
where \(c\) is the local speed of sounds (right on the point under analysis - for ex. when the ray starts at the source location)
- If the medium is isotrope, \(c=constant\) everywhere
\[ \frac{\cos\theta}{c_{const}} = const \Rightarrow \theta = const \]
Consider now:
- At the source \(c=c_0\), and we have initial \(\theta=\theta_0\)
- \(\Rightarrow const = \frac{\cos\theta_0}{c_0}\)
what is \(\theta\) in another point?
- if \(c>c_0\) (speed of sound is increasing): \[ \frac{\cos\theta}{c}= \frac{\cos\theta_0}{c_0} \Rightarrow \cos\theta > \cos\theta_0 \Rightarrow \theta < \theta_0 \]
This means that the ray must bend towards the surface \(\theta < \theta_0\).
- if \(c<c_0\) (speed of sound is decreasing): \[ \frac{\cos\theta}{c}= \frac{\cos\theta_0}{c_0} \Rightarrow \cos\theta < \cos\theta_0 \Rightarrow \theta > \theta_0 \]
This means that the ray must bend downwards \(\theta > \theta_0\).
Ray paths and wave-guide effects
- The discussion before means that reading the sound speed profile
- Assuming sound speed profile only varies with depth (generaly true for range < \(20\) km
- Several rays pattern can appear depending on the source depth
- SSP is measured: note the change in SSP at the surface (higher at 30m than at 0m)
Let’s zoom in:
Source is at the surface
- Rays will bend upwards until they hit the surface and will be reflected down, etc.
- Not all rays will bend upwards so much that they hit the surface. It depends on the initial ray angle.
</tr></table>
An approximation is shown in the picture below.
This is called surface sound channel.
</tr></table>
Source at the minimum of the sound speed: internal sound channel
- Ray pointing downwards propagates within regions where sound speed increases: angle decreases, and bend upwards.
- Depending on the initial angles some rays will graze or hit the sea bottom.
- Ray pointing upwards propagates within regions where sound speed increases: angle decreases, and bend downwards
- Depending on the initial angle, some rays might get inside the surface channel
- Intuitively, rays tend to go to the minimum of the sound speed.
</tr></table>
Bottom limited sound channel
- Upwards rays will bend downwards and have total reflections (reflections generated by refraction)
- Downwards rays do not have total reflections and they all hit the seabed.
</tr></table>
Let’s go back to our experimental picture:
- Ray bending is possible only if the medium is not isotrope (speed changes along some directions, i.e. depth)
- Along each of the rays travels our harmonic wave.
- Some rays will go through the same point in space and they all interfere.
- We saw this already with the Lloys’ mirror case. But in that case we only had two rays and was easier to describe.
- Unisotropic propagation contributes to propogation loss.
- When we have multiple paths that the sound can take (see for instance, internal sound channel, km 5) is called multi-path structure.
- Multi-path can causes interference patterns (constructive or destructive) - i.e. an additinal loss factor.
- Convergent zones are areas where interference patterns is in-phase (i.e. constructive)
Intruitively, if we start with uniformely spaced rays: - Denser rays (at least in some areas) should correspond to maxima (constructive interference) - Sparser rays corresponds to minima - The density of the rays corresponds to the acoustic intensity
SOFAR (SOund Fixing And Ranging) Channel
- Generalises the internal sound channel
- Corresponds to the global minimum of the SSP
- In deep water (>600m), the global minimum always exists
- Sound can travel thousands of km without significant loss. In some cases even half way around the world (Australia to Bermuda)
- To compare, similar sound level would only travel kms in air
History of the SOFAR Channel
Adapted from History of the SOFAR channel and Sound travel in the SOFAR channel.
In the spring of 1944, ocean scientists, Maurice Ewing and J. Worzel, departed Woods Hole, Massachusetts, aboard the research vessel R/V Saluda to test a theory that predicted that low-frequency sound should be able to travel long distances in the deep ocean.
A deep receiving hydrophone was hung from R/V Saluda. A second ship dropped 4-pound explosive charges set to explode deep in the ocean at distances up to 900 miles from the R/V Saluda’s hydrophone. Ewing and Worzel heard, for the first time, the characteristic sound of a SOFAR (SOund Fixing And Ranging) transmission, consisting of a series of pulses building up to its climax.
"./mp3/SOFAR1.mp3") IPython.display.Audio(
Although sound travels away from a sound source in all directions, only sound traveling away from a source on paths that leave the source at specific angles will reach a receiver at a specific location. The sound waves traveling on these different paths have slightly different travel times. A single explosive source will therefore be heard as a number of separate arrivals, leading to the characteristic signature of a SOFAR transmission building up to its climax. The final pulse of sound is typically the loudest and comes from the sound wave that travels nearly on the sound channel axis. Although this sound wave travels the shortest distance, it travels in the region near the sound speed minimum where the sound speed is lowest.
Surface duct and shadow zones
What happens to those rays that get out of the surface duct?
- It depends..if there is a SOFAR channel below.
- Note the presence of an area where there are NO acoustic rays: shadow zone.
Wrap up
This is a qualitative analysis: Given a SSP profile, intuitively understand how sound propagates.
Transmission Loss affects the Signal-to-Noise Ratio:
- Higher Loss, Lower SNR
- Lowe Loss, Higher SNR
Multi-path structure generates Symbolic Interference
- When signals overlap at the receiver, they sum up and the symbols that the signal is carring interfere with each other.
A Very Simple Ray Tracer
SoundParticle
SoundParticle (r0, d0, theta0, ssp)
Models the movement of a sound particle along a ray.
Example usage:
sp = SoundParticle(r0=0, d0=50, theta0=np.deg2rad(-1), ssp=ssp)
print('Initial conditions:', sp)
# initial state
r_t, d_t, q_t, c_t = sp.get_state()
r, d, q, c = [], [], [], []
# simulation times
t0 = 0
tf = 4
dt = 0.01
for t in np.arange(t0, tf, dt):
r.append(r_t)
d.append(d_t)
q.append(q_t)
c.append(c_t)
sp.move(dt)
r_t, d_t, q_t, c_t = sp.get_state()
SSP
SSP (depths, speeds)
Defines one sound speed profile (depth (m) and speed (m/s) at each depth)
Let’s try it out.
Below there are three different sound speed profiles, similar to those experimentally collected before. Each one gives rise to a different type of propogation.
Try them all out.
# increasing sound speed (surface duct)
# ssp = SSP(np.linspace(0, 15, 9),
# [1501, 1501.5, 1502, 1502.5, 1503, 1504.5, 1508, 1509, 1510])
# internal sound channel
# ssp = SSP(np.linspace(0, 15, 9),
# [1505, 1504.5, 1503, 1502.5, 1503, 1504.5, 1508, 1509, 1510])
# bottom limited sound channel
= SSP([0, 10, 25, 50, 100, 150, 250],
ssp 1501, 1502, 1505, 1490, 1480, 1480, 1485])
[
ssp.plot()10) ssp.plot_speed_at_depth(
And now we can try what happens when we change the depth of the source using the \(d0\) variable: - d0=8m - d0=50m - d0=100m
# theta0: negative angles: downwards
# theta0: positive angles: upwards
= SoundParticle(r0=0, d0=50, theta0=np.deg2rad(-1), ssp=ssp)
sp print('Initial conditions:', sp)
# initial state
= sp.get_state()
r_t, d_t, q_t, c_t = [], [], [], []
r, d, q, c
# simulation times
= 0
t0 = 4
tf = 0.01
dt for t in np.arange(t0, tf, dt):
r.append(r_t)
d.append(d_t)
q.append(q_t)
c.append(c_t)
sp.move(dt) # print(sp)
= sp.get_state()
r_t, d_t, q_t, c_t
##
## Plot
0], d[0], color='r', linewidth=3)
plt.scatter(r[='k')
plt.plot(r, np.array(d), colormin(ssp._depths), max(ssp._depths)))
plt.ylim((
plt.gca().invert_yaxis()'Range (m)')
plt.xlabel('Depth (m)'); plt.ylabel(
Initial conditions: range (m): 0.00, depth (m): 50.00, angle (deg): -1.00, speed (m/s): 1490.00
And we can plot more rays:
= 50
source_depth_m
for theta0 in range(5, -5, -1):
# theta0: negative angles: downwards
# theta0: positive angles: upwards
= SoundParticle(r0=0, d0=source_depth_m, theta0=np.deg2rad(theta0), ssp=ssp)
sp print('Initial conditions:', sp)
# initial state
= sp.get_state()
r_t, d_t, q_t, c_t = [], [], [], []
r, d, q, c
# simulation times
= 0
t0 = 4
tf = 0.01
dt for t in np.arange(t0, tf, dt):
r.append(r_t)
d.append(d_t)
q.append(q_t)
c.append(c_t)
sp.move(dt) # print(sp)
= sp.get_state()
r_t, d_t, q_t, c_t
##
## Plot
0], d[0], color='r', linewidth=3)
plt.scatter(r[='k')
plt.plot(r, np.array(d), colormin(ssp._depths), max(ssp._depths)))
plt.ylim((
plt.gca().invert_yaxis()'Range (m)')
plt.xlabel('Depth (m)'); plt.ylabel(
Initial conditions: range (m): 0.00, depth (m): 50.00, angle (deg): 5.00, speed (m/s): 1490.00
Initial conditions: range (m): 0.00, depth (m): 50.00, angle (deg): 4.00, speed (m/s): 1490.00
Initial conditions: range (m): 0.00, depth (m): 50.00, angle (deg): 3.00, speed (m/s): 1490.00
Initial conditions: range (m): 0.00, depth (m): 50.00, angle (deg): 2.00, speed (m/s): 1490.00
Initial conditions: range (m): 0.00, depth (m): 50.00, angle (deg): 1.00, speed (m/s): 1490.00
Initial conditions: range (m): 0.00, depth (m): 50.00, angle (deg): 0.00, speed (m/s): 1490.00
Initial conditions: range (m): 0.00, depth (m): 50.00, angle (deg): -1.00, speed (m/s): 1490.00
Initial conditions: range (m): 0.00, depth (m): 50.00, angle (deg): -2.00, speed (m/s): 1490.00
Initial conditions: range (m): 0.00, depth (m): 50.00, angle (deg): -3.00, speed (m/s): 1490.00
Initial conditions: range (m): 0.00, depth (m): 50.00, angle (deg): -4.00, speed (m/s): 1490.00
Let’s make it a class to use it later
RayTracer
RayTracer (time, source_depth, min_range, thetas, ssp)
time : simulation time as [t0, tf, dt] source_depth: depth of the source in m min_range: min_range from source in m thetas: range of tx angles (deg). E.g. thetas=range(5, -5, -1) ssp: sound speed profile (defined using class SSP)
# bottom limited sound channel
= SSP([0, 10, 25, 50, 100, 150, 250],
ssp 1501, 1502, 1505, 1490, 1480, 1480, 1485])
[
= 50
source_depth_m # simulation times
= 0
t0 = 4
tf = 0.01
dt = RayTracer(time=[t0, tf, dt],
rt =source_depth_m,
source_depth=0,
min_range=range(5, -5, -1),
thetas=ssp) ssp
rt.run()