Skip to content

Commit 6e41590

Browse files
authored
Merge pull request #91 from Timmmm/Timmmm-acoustic-wave-example
Add acoustic wave example
2 parents 82056d8 + 51d917b commit 6e41590

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,7 @@ path = "examples/snow.rs"
4646
[[example]]
4747
name = "histogram"
4848
path = "examples/histogram.rs"
49+
50+
[[example]]
51+
name = "acoustic_wave"
52+
path = "examples/acoustic_wave.rs"

examples/acoustic_wave.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
extern crate arrayfire as af;
2+
3+
use af::*;
4+
use std::f64::consts::*;
5+
6+
fn main() {
7+
set_device(0);
8+
info();
9+
10+
acoustic_wave_simulation();
11+
}
12+
13+
fn normalise(a: &Array) -> Array {
14+
(a/(max_all(&abs(a)).0 as f32 * 2.0f32)) + 0.5f32
15+
}
16+
fn acoustic_wave_simulation() {
17+
// Speed of sound
18+
let c = 0.1;
19+
// Distance step
20+
let dx = 0.5;
21+
// Time step
22+
let dt = 1.0;
23+
24+
// Grid size.
25+
let nx = 1500;
26+
let ny = 1500;
27+
28+
// Grid dimensions.
29+
let dims = Dim4::new(&[nx, ny, 1, 1]);
30+
31+
// Pressure field
32+
let mut p = constant::<f32>(0.0, dims);
33+
// d(pressure)/dt field
34+
let mut p_dot = p.clone();
35+
36+
// Laplacian (Del^2) convolution kernel.
37+
let laplacian_values = [0.0f32, 1.0, 0.0,
38+
1.0, -4.0, 1.0,
39+
0.0, 1.0, 0.0];
40+
let laplacian_kernel = Array::new(&laplacian_values, Dim4::new(&[3, 3, 1, 1])) / (dx * dx);
41+
42+
// Create a window to show the waves.
43+
let mut win = Window::new(1000, 1000, "Waves".to_string());
44+
45+
// Hann windowed pulse.
46+
let pulse_time = 100.0f64;
47+
let centre_freq = 0.05;
48+
49+
// Number of samples in pulse.
50+
let pulse_n = (pulse_time/dt).floor() as u64;
51+
52+
let i = range::<f32>(Dim4::new(&[pulse_n, 1, 1, 1]), 0);
53+
let t = i.clone() * dt;
54+
let hamming_window = cos(&(i * (2.0 * PI / pulse_n as f64))) * -0.46 + 0.54;
55+
let wave = sin(&(&t * centre_freq * 2.0 * PI));
56+
let pulse = wave * hamming_window;
57+
58+
// Iteration count.
59+
let mut it = 0;
60+
61+
while !win.is_closed() {
62+
// Convole with laplacian to get spacial second derivative.
63+
let lap_p = convolve2(&p, &laplacian_kernel, ConvMode::DEFAULT, ConvDomain::SPATIAL);
64+
// Calculate the updated pressure and d(pressure)/dt fields.
65+
p_dot += lap_p * (c * dt);
66+
p += &p_dot * dt;
67+
68+
if it < pulse_n {
69+
// Location of the source.
70+
let seqs = &[Seq::new(700.0, 800.0, 1.0), Seq::new(800.0, 800.0, 1.0)];
71+
// Set the pressure there.
72+
p = assign_seq(&p, seqs, &index(&pulse, &[Seq::new(it as f64, it as f64, 1.0)]));
73+
}
74+
75+
// Draw the image.
76+
win.set_colormap(af::ColorMap::BLUE);
77+
win.draw_image(&normalise(&p), None);
78+
79+
it += 1;
80+
}
81+
}

0 commit comments

Comments
 (0)