k-Wave Toolbox |
![]() ![]() |
On this page… |
---|
The time-varying pressure signals recorded from a photoacoustic source look different depending on the number of dimensions used in the simulation. This difference occurs because a point source in 1D corresponds to a plane wave in 3D, and a point source in 2D corresponds to an infinite line source in 3D. This examples shows the difference between the signals recorded in each dimension. It builds on the Simulations in One Dimension, Homogeneous Propagation Medium, and Simulations in Three Dimensions examples.
The fact that the characteristics of plane (1D), cylindrical (2D) and spherical (3D) wave propagation are different in some fundamental ways is often overlooked. This can lead to incorrect insight into the results from photoacoustic simulations. In particular, three key differences between 1D, 2D and 3D propagation are these:
Note that 1D, 2D and 3D are used here to refer to the Cartesian coordinate systems in which the variables are (z), (z, x), and (z, x, y). Other cases that could be described as 1D (such as spherically-symmetric with just a radial coordinate) or 2D (such as cylindrically-symmetric with (r, theta) as the coordinates) are not considered.
First the common settings for all three examples are set, including the grid size, properties of the medium, size of the initial pressure distribution, source-receiver separation, time step and length of time to run the simulation.
% size of the computational grid Nx = 64; % number of pixels in the x direction x = 1e-3; % size of the domain in the x direction [m] dx = x/Nx; % pixel width [m] % define the properties of the propagation medium medium.sound_speed = 1500; % [m/s] % size of the initial pressure distribution source_radius = 2; % distance between the centre of the source and the sensor source_sensor_distance = 10; % time array dt = 2e-9; t_end = 300e-9; % computation settings input_args = {'DataCast', 'single'};
The final line above sets up the input argument to the propagation code that tells MATLAB to run the simulations in single precision arithmetic, which is faster than double precision and usually adequate for practical purposes. The next set of commands create the k-space grid and the array of time points
% create the computational grid kgrid = makeGrid(Nx, dx); % create the time array kgrid.t_array = 0:dt:t_end;
and then the initial pressure distribution (source) and sensor position.
% create initial pressure distribution source.p0 = zeros(Nx, 1); source.p0(Nx/2 - source_radius:Nx/2 + source_radius) = 1; % define a single sensor point sensor.mask = zeros(Nx, 1); sensor.mask(Nx/2 + source_sensor_distance) = 1;
Finally, the 1D example is run
% run the simulation sensor_data_1D = kspaceFirstOrder1D(kgrid, medium, source, sensor, input_args{:});
Running the simulation in 2D is very similar, except the initial
pressure distribution is defined as a disc (filled circle) using makeDisc
, and the sensor mask is defined as a single pixel
in two-dimensions:
% create the computational grid kgrid = makeGrid(Nx, dx, Nx, dx); % create initial pressure distribution source.p0 = makeDisc(Nx, Nx, Nx/2, Nx/2, source_radius); % define a single sensor point sensor.mask = zeros(Nx, Nx); sensor.mask(Nx/2 - source_sensor_distance, Nx/2) = 1; % run the simulation sensor_data_2D = kspaceFirstOrder2D(kgrid, medium, source, sensor, input_args{:});
The 3D example follows the same pattern, except now the source is defined as a ball (filled
sphere) using makeBall
:
% create the computational grid kgrid = makeGrid(Nx, dx, Nx, dx, Nx, dx); % create initial pressure distribution source.p0 = makeBall(Nx, Nx, Nx, Nx/2, Nx/2, Nx/2, source_radius); % define a single sensor point sensor.mask = zeros(Nx, Nx, Nx); sensor.mask(Nx/2 - source_sensor_distance, Nx/2, Nx/2) = 1; % run the simulation sensor_data_3D = kspaceFirstOrder3D(kgrid, medium, source, sensor, input_args{:});
The three recorded time series, for 1D, 2D and 3D are normalised and plotted on the same plot. A legend indicating which is which is also added:
figure; [t_sc, t_scale, t_prefix] = scaleSI(t_end); plot(kgrid.t_array*t_scale, sensor_data_1D./max(abs(sensor_data_1D)), 'b-'); hold on; plot(kgrid.t_array*t_scale, sensor_data_2D./max(abs(sensor_data_2D)), 'r-'); plot(kgrid.t_array*t_scale, sensor_data_3D./max(abs(sensor_data_3D)), 'k-'); xlabel(['Time [' t_prefix 's]']); ylabel('Recorded Pressure [au]'); legend('1D', '2D', '3D');
![]() |
Simulations In Three Dimensions | Time Varying Source Problems | ![]() |
© 2009, 2010, 2011 Bradley Treeby and Ben Cox.