Hello,
I am currently simulating the acoustic field of a 1D linear probe using k-Wave.
I have modified the code based on example_us_beam_patterns.m, and my key simulation settings are as follows:
Frequency: 5 MHz
Grid spacing (dx): 0.025e-3 m
I confirmed that the initial ultrasound pulse propagates correctly. However, the pressure at the focal region is extremely low in the simulation results, making the beam pattern nearly invisible.
It appears as if the ultrasound wave propagates and then disappears.
Does anyone have any insights or suggestions on why this might be happening?
I would appreciate any insights or suggestions on how to resolve this issue.
Thank you!
Gwansuk
Below is the complete code:
clearvars;
% simulation settings
DATA_CAST = 'gpuArray-single'; % set to 'single' or 'gpuArray-single' to speed up computations
MASK_PLANE = 'xy'; % set to 'xy' or 'xz' to generate the beam pattern in different planes
USE_STATISTICS = true; % set to true to compute the rms or peak beam patterns, set to false to compute the harmonic beam patterns
% =========================================================================
% DEFINE THE K-WAVE GRID
% =========================================================================
% set the size of the perfectly matched layer (PML)
PML_X_SIZE = 20; % [grid points]
PML_Y_SIZE = 10; % [grid points]
PML_Z_SIZE = 10; % [grid points]
% set total number of grid points not including the PML
Nx = 84 - 2 * PML_X_SIZE; % [grid points]
Ny = 64 - 2 * PML_Y_SIZE; % [grid points]
Nz = 64 - 2 * PML_Z_SIZE; % [grid points]
Nx = Nx * 74; %Nx = Nx * 74;
Ny = Ny * 24;
Nz = Nz * 1;
% calculate the spacing between the grid points
dx = 0.025e-3; % [m]
dy = dx; % [m]
dz = dx; % [m]
% create the k-space grid
kgrid = kWaveGrid(Nx, dx, Ny, dy, Nz, dz);
% =========================================================================
% DEFINE THE MEDIUM PARAMETERS
% =========================================================================
% define the properties of the propagation medium
medium.sound_speed = 1540; % [m/s]
medium.density = 1000; % [kg/m^3]
medium.alpha_coeff = 0.75; % [dB/(MHz^y cm)]
medium.alpha_power = 1.5;
medium.BonA = 6;
% create the time array
fs = 300e6; % Sampling rate (Hz)
dt = 1/fs; % Time step (s)
t_end = 80e-6; % Total simulation time (s)
Nt = round(t_end / dt); % Number of time steps
% Set time axis
kgrid.t_array = 0:dt:(Nt-1)*dt;
% =========================================================================
% DEFINE THE INPUT SIGNAL
% =========================================================================
% define properties of the input signal
source_strength = 1e6; % [Pa]
tone_burst_freq = 5.0e6; % [Hz]
tone_burst_cycles = 3;
% create the input signal using toneBurst
input_signal = toneBurst(1/kgrid.dt, tone_burst_freq, tone_burst_cycles);
% scale the source magnitude by the source_strength divided by the
% impedance (the source is assigned to the particle velocity)
input_signal = (source_strength ./ (medium.sound_speed * medium.density)) .* input_signal;
% =========================================================================
% DEFINE THE ULTRASOUND TRANSDUCER
% =========================================================================
% physical properties of the transducer
transducer.number_elements = 96; % total number of transducer elements
transducer.element_width = 10; % width of each element [grid points]
transducer.element_length = 20; % length of each element [grid points]
transducer.element_spacing = 0; % spacing (kerf width) between the elements [grid points]
transducer.radius = inf; % radius of curvature of the transducer [m]
% calculate the width of the transducer in grid points
transducer_width = transducer.number_elements * transducer.element_width ...
+ (transducer.number_elements - 1) * transducer.element_spacing;
% use this to position the transducer in the middle of the computational grid
transducer.position = round([1, Ny/2 - transducer_width/2, Nz/2 - transducer.element_length/2]);
% properties used to derive the beamforming delays
transducer.sound_speed = 1540; % sound speed [m/s]
transducer.focus_distance = 55e-3; %55e-3; % focus distance [m]
transducer.elevation_focus_distance = 19e-3; % focus distance in the elevation plane [m]
transducer.elevation_focus_distance = 25e-3; % focus distance in the elevation plane [m]
transducer.steering_angle = 0; % steering angle [degrees]
% apodization
transducer.transmit_apodization = 'Rectangular';
transducer.receive_apodization = 'Rectangular';
% define the transducer elements that are currently active
transducer.active_elements = ones(transducer.number_elements, 1);
% append input signal used to drive the transducer
transducer.input_signal = input_signal;
% create the transducer using the defined settings
transducer = kWaveTransducer(kgrid, transducer);
% print out transducer properties
transducer.properties;
% =========================================================================
% DEFINE SENSOR MASK
% =========================================================================
% define a sensor mask through the central plane
sensor.mask = zeros(Nx, Ny, Nz);
switch MASK_PLANE
case 'xy'
% define mask
sensor.mask(:, :, Nz/2) = 1;
% store y axis properties
Nj = Ny;
j_vec = kgrid.y_vec;
j_label = 'y';
case 'xz'
% define mask
sensor.mask(:, Ny/2, :) = 1;
% store z axis properties
Nj = Nz;
j_vec = kgrid.z_vec;
j_label = 'z';
end
% set the record mode such that only the rms and peak values are stored
if USE_STATISTICS
sensor.record = {'p_rms', 'p_max'};
end
% =========================================================================
% RUN THE SIMULATION
% =========================================================================
% set the input settings
input_args = {'DisplayMask', transducer.all_elements_mask, ...
'PMLInside', false, 'PlotPML', false, 'PMLSize', [PML_X_SIZE, PML_Y_SIZE, PML_Z_SIZE], ...
'DataCast', DATA_CAST, 'DataRecast', true, 'PlotScale', [-1/2, 1/2] * source_strength};
% stream the data to disk in blocks of 100 if storing the complete time
% history
if ~USE_STATISTICS
input_args = [input_args {'StreamToDisk', 100}];
end
tic
% run the simulation
sensor_data = kspaceFirstOrder3D(kgrid, medium, transducer, sensor, input_args{:});
toc
% =========================================================================
% COMPUTE THE BEAM PATTERN USING SIMULATION STATISTICS
% =========================================================================
if USE_STATISTICS
% reshape the returned rms and max fields to their original position
sensor_data.p_rms = reshape(sensor_data.p_rms, [Nx, Nj]);
sensor_data.p_max = reshape(sensor_data.p_max, [Nx, Nj]);
% plot the beam pattern using the pressure maximum
figure;
imagesc(j_vec * 1e3, (kgrid.x_vec - min(kgrid.x_vec(:))) * 1e3, sensor_data.p_max * 1e-6);
xlabel([j_label '-position [mm]']);
ylabel('x-position [mm]');
title('Total Beam Pattern Using Maximum Of Recorded Pressure');
colormap(jet(256));
c = colorbar;
ylabel(c, 'Pressure [MPa]');
axis image;
% plot the beam pattern using the pressure rms
figure;
imagesc(j_vec * 1e3, (kgrid.x_vec - min(kgrid.x_vec(:))) * 1e3, sensor_data.p_rms * 1e-6);
xlabel([j_label '-position [mm]']);
ylabel('x-position [mm]');
title('Total Beam Pattern Using RMS Of Recorded Pressure');
colormap(jet(256));
c = colorbar;
ylabel(c, 'Pressure [MPa]');
axis image;
% end the example
return
end