<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="bbPress/1.0.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>k-Wave User Forum &#187; Topic: Problem Simulation Transducer Beam Pattern</title>
		<link>http://www.k-wave.org/forum/topic/problem-simulation-transducer-beam-pattern</link>
		<description>Support for the k-Wave MATLAB toolbox</description>
		<language>en-US</language>
		<pubDate>Wed, 13 May 2026 16:24:26 +0000</pubDate>
		<generator>http://bbpress.org/?v=1.0.2</generator>
		<textInput>
			<title><![CDATA[Search]]></title>
			<description><![CDATA[Search all topics from these forums.]]></description>
			<name>q</name>
			<link>http://www.k-wave.org/forum/search.php</link>
		</textInput>
		<atom:link href="http://www.k-wave.org/forum/rss/topic/problem-simulation-transducer-beam-pattern" rel="self" type="application/rss+xml" />

		<item>
			<title>Bradley Treeby on "Problem Simulation Transducer Beam Pattern"</title>
			<link>http://www.k-wave.org/forum/topic/problem-simulation-transducer-beam-pattern#post-6156</link>
			<pubDate>Thu, 19 Oct 2017 09:25:44 +0000</pubDate>
			<dc:creator>Bradley Treeby</dc:creator>
			<guid isPermaLink="false">6156@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi Mason,&#60;/p&#62;
&#60;p&#62;Your simulation is unstable (there should be a warning printed to the command line about this). You can fix this by reducing the size of the time step, e.g., &#60;/p&#62;
&#60;pre&#62;&#60;code&#62;% create the time array
t_end = 7.5e-6; % [s]
CFL = 0.1;
kgrid.t_array = makeTime(kgrid, medium.sound_speed, CFL, t_end);&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Brad.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Mason Schellenberg on "Problem Simulation Transducer Beam Pattern"</title>
			<link>http://www.k-wave.org/forum/topic/problem-simulation-transducer-beam-pattern#post-6149</link>
			<pubDate>Thu, 12 Oct 2017 19:16:18 +0000</pubDate>
			<dc:creator>Mason Schellenberg</dc:creator>
			<guid isPermaLink="false">6149@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hey all,&#60;/p&#62;
&#60;p&#62;I am trying to simulate the beam pattern of a transducer but am getting some confusing results. The first time step results in the volume being saturated with acoustic pressure and then seems to go negative for the rest of the run. The resulting beam pattern looks like a checkerboard. Any help would be greatly appreciated. My code is based on the example provided when I downloaded it and is as follows: &#60;/p&#62;
&#60;p&#62;clear all;&#60;/p&#62;
&#60;p&#62;% simulation settings&#60;br /&#62;
DATA_CAST = 'single';       % set to 'single' or 'gpuArray-single' to speed up computations&#60;br /&#62;
MASK_PLANE = 'xy';          % set to 'xy' or 'xz' to generate the beam pattern in different planes&#60;br /&#62;
USE_STATISTICS = true;      % set to true to compute the rms or peak beam patterns, set to false to compute the harmonic beam patterns&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE K-WAVE GRID&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% set the size of the perfectly matched layer (PML)&#60;br /&#62;
PML_X_SIZE = 16;            % [grid points]&#60;br /&#62;
PML_Y_SIZE = 16;            % [grid points]&#60;br /&#62;
PML_Z_SIZE = 16;            % [grid points]&#60;/p&#62;
&#60;p&#62;% set total number of grid points not including the PML&#60;br /&#62;
Nx = 64 - 2*PML_X_SIZE;    % [grid points]&#60;br /&#62;
Ny = 256 - 2*PML_Y_SIZE;     % [grid points]&#60;br /&#62;
Nz = 256 - 2*PML_Z_SIZE;     % [grid points]&#60;/p&#62;
&#60;p&#62;% calculate the spacing between the grid points&#60;br /&#62;
dx = 50e-6;                  % [m]&#60;br /&#62;
dy = dx;                    % [m]&#60;br /&#62;
dz = dx;                    % [m]&#60;/p&#62;
&#60;p&#62;% create the k-space grid&#60;br /&#62;
kgrid = makeGrid(Nx, dx, Ny, dy, Nz, dz);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE MEDIUM PARAMETERS&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define the properties of the propagation medium&#60;br /&#62;
medium.sound_speed = 1595;      % [m/s]&#60;br /&#62;
medium.density = 1000;          % [kg/m^3]&#60;br /&#62;
medium.alpha_coeff = 1.08;      % [dB/(MHz^y cm)]&#60;br /&#62;
medium.alpha_power = 1.001;&#60;/p&#62;
&#60;p&#62;% create the time array&#60;br /&#62;
t_end = 7.5e-6;                  % [s]&#60;br /&#62;
kgrid.t_array = makeTime(kgrid, medium.sound_speed, [], t_end);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE INPUT SIGNAL&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define properties of the input signal&#60;br /&#62;
source_strength = 1e6;          % [Pa]&#60;br /&#62;
tone_burst_freq = 12.5e6;    	% [Hz]&#60;br /&#62;
tone_burst_cycles = 1;&#60;/p&#62;
&#60;p&#62;% create the input signal using toneBurst&#60;br /&#62;
input_signal = toneBurst(1/kgrid.dt, tone_burst_freq, tone_burst_cycles);&#60;/p&#62;
&#60;p&#62;% scale the source magnitude by the source_strength divided by the&#60;br /&#62;
% impedance (the source is assigned to the particle velocity)&#60;br /&#62;
input_signal = (source_strength./(medium.sound_speed*medium.density)).*input_signal;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE ULTRASOUND TRANSDUCER&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% physical properties of the transducer&#60;br /&#62;
transducer.number_elements = 32;    % total number of transducer elements&#60;br /&#62;
transducer.element_width = 3;       % width of each element [grid points]&#60;br /&#62;
transducer.element_length = 120;     % length of each element [grid points]&#60;br /&#62;
transducer.element_spacing = 1;     % spacing (kerf  width) between the elements [grid points]&#60;/p&#62;
&#60;p&#62;% calculate the width of the transducer in grid points&#60;br /&#62;
transducer_width = transducer.number_elements*transducer.element_width ...&#60;br /&#62;
    + (transducer.number_elements - 1)*transducer.element_spacing;&#60;/p&#62;
&#60;p&#62;% use this to position the transducer in the middle of the computational grid&#60;br /&#62;
transducer.position = round([1, Ny/2 - transducer_width/2, Nz/2 - transducer.element_length/2]);&#60;/p&#62;
&#60;p&#62;% properties used to derive the beamforming delays&#60;br /&#62;
transducer.sound_speed = 1595;              % sound speed [m/s]&#60;/p&#62;
&#60;p&#62;% apodization&#60;br /&#62;
transducer.transmit_apodization = 'Rectangular';&#60;br /&#62;
transducer.receive_apodization = 'Rectangular';&#60;/p&#62;
&#60;p&#62;% define the transducer elements that are currently active&#60;br /&#62;
transducer.active_elements = ones(transducer.number_elements, 1);&#60;/p&#62;
&#60;p&#62;% append input signal used to drive the transducer&#60;br /&#62;
transducer.input_signal = input_signal;&#60;/p&#62;
&#60;p&#62;% create the transducer using the defined settings&#60;br /&#62;
transducer = makeTransducer(kgrid, transducer);&#60;/p&#62;
&#60;p&#62;% print out transducer properties&#60;br /&#62;
transducer.properties;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE SENSOR MASK&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% define a sensor mask through the central plane&#60;br /&#62;
sensor.mask = zeros(Nx, Ny, Nz);&#60;br /&#62;
switch MASK_PLANE&#60;br /&#62;
    case 'xy'&#60;br /&#62;
        % define mask&#60;br /&#62;
        sensor.mask(:, :, Nz/2) = 1;&#60;/p&#62;
&#60;p&#62;        % store y axis properties&#60;br /&#62;
        Nj = Ny;&#60;br /&#62;
        j_vec = kgrid.y_vec;&#60;br /&#62;
        j_label = 'y';&#60;/p&#62;
&#60;p&#62;    case 'xz'&#60;br /&#62;
        % define mask&#60;br /&#62;
        sensor.mask(:, Ny/2, :) = 1;&#60;/p&#62;
&#60;p&#62;        % store z axis properties&#60;br /&#62;
        Nj = Nz;&#60;br /&#62;
        j_vec = kgrid.z_vec;&#60;br /&#62;
        j_label = 'z';&#60;/p&#62;
&#60;p&#62;end &#60;/p&#62;
&#60;p&#62;% set the record mode such that only the rms and peak values are stored&#60;br /&#62;
if USE_STATISTICS&#60;br /&#62;
    sensor.record = {'p_rms', 'p_max'};&#60;br /&#62;
end&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% RUN THE SIMULATION&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% set the input settings&#60;br /&#62;
input_args = {'DisplayMask', transducer.all_elements_mask, ...&#60;br /&#62;
    'PMLInside', false, 'PlotPML', false, 'PMLSize', [PML_X_SIZE, PML_Y_SIZE, PML_Z_SIZE], ...&#60;br /&#62;
    'DataCast', DATA_CAST, 'DataRecast', true, 'PlotScale', [-source_strength/2, source_strength/2]};&#60;/p&#62;
&#60;p&#62;% stream the data to disk in blocks of 100 if storing the complete time&#60;br /&#62;
% history&#60;br /&#62;
if ~USE_STATISTICS&#60;br /&#62;
    input_args = [input_args {'StreamToDisk', 100}];&#60;br /&#62;
end&#60;/p&#62;
&#60;p&#62;% run the simulation&#60;br /&#62;
sensor_data = kspaceFirstOrder3D(kgrid, medium, transducer, sensor, input_args{:});&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% COMPUTE THE BEAM PATTERN USING SIMULATION STATISTICS&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;if USE_STATISTICS&#60;/p&#62;
&#60;p&#62;    % reshape the returned rms and max fields to their original position&#60;br /&#62;
    sensor_data.p_rms = reshape(sensor_data.p_rms, [Nx, Nj]);&#60;br /&#62;
    sensor_data.p_max = reshape(sensor_data.p_max, [Nx, Nj]);&#60;/p&#62;
&#60;p&#62;    % plot the beam pattern using the pressure maximum&#60;br /&#62;
    figure;&#60;br /&#62;
    imagesc(j_vec*1e3, (kgrid.x_vec - min(kgrid.x_vec(:)))*1e3, sensor_data.p_max/1e6);&#60;br /&#62;
    xlabel([j_label '-position [mm]']);&#60;br /&#62;
    ylabel('x-position [mm]');&#60;br /&#62;
    title('Total Beam Pattern Using Maximum Of Recorded Pressure');&#60;br /&#62;
    colormap(jet(256));&#60;br /&#62;
    c = colorbar;&#60;br /&#62;
    ylabel(c, 'Pressure [MPa]');&#60;br /&#62;
    axis image;&#60;/p&#62;
&#60;p&#62;    % plot the beam pattern using the pressure rms&#60;br /&#62;
    figure;&#60;br /&#62;
    imagesc(j_vec*1e3, (kgrid.x_vec - min(kgrid.x_vec(:)))*1e3, sensor_data.p_rms/1e6);&#60;br /&#62;
    xlabel([j_label '-position [mm]']);&#60;br /&#62;
    ylabel('x-position [mm]');&#60;br /&#62;
    title('Total Beam Pattern Using RMS Of Recorded Pressure');&#60;br /&#62;
    colormap(jet(256));&#60;br /&#62;
    c = colorbar;&#60;br /&#62;
    ylabel(c, 'Pressure [MPa]');&#60;br /&#62;
    axis image;&#60;/p&#62;
&#60;p&#62;    % end the example&#60;br /&#62;
    return&#60;/p&#62;
&#60;p&#62;end&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% COMPUTE THE BEAM PATTERN FROM THE AMPLITUDE SPECTRUM&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% reshape the sensor data to its original position so that it can be&#60;br /&#62;
% indexed as sensor_data(x, j, t)&#60;br /&#62;
sensor_data = reshape(sensor_data, [Nx, Nj, kgrid.Nt]);&#60;/p&#62;
&#60;p&#62;% compute the amplitude spectrum&#60;br /&#62;
[freq, amp_spect] = spect(sensor_data, 1/kgrid.dt, 'Dim', 3);&#60;/p&#62;
&#60;p&#62;% compute the index at which the source frequency and its harmonics occur&#60;br /&#62;
[f1_value, f1_index] = findClosest(freq, tone_burst_freq);&#60;br /&#62;
[f2_value, f2_index] = findClosest(freq, tone_burst_freq*2);&#60;/p&#62;
&#60;p&#62;% extract the amplitude at the source frequency and store&#60;br /&#62;
beam_pattern_f1 = amp_spect(:, :, f1_index);&#60;/p&#62;
&#60;p&#62;% extract the amplitude at the second harmonic and store&#60;br /&#62;
beam_pattern_f2 = amp_spect(:, :, f2_index);       &#60;/p&#62;
&#60;p&#62;% extract the integral of the total amplitude spectrum&#60;br /&#62;
beam_pattern_total = sum(amp_spect, 3);&#60;/p&#62;
&#60;p&#62;% plot the beam patterns&#60;br /&#62;
figure;&#60;br /&#62;
imagesc(j_vec*1e3, (kgrid.x_vec - min(kgrid.x_vec(:)))*1e3, beam_pattern_f1/1e6);&#60;br /&#62;
xlabel([j_label '-position [mm]']);&#60;br /&#62;
ylabel('x-position [mm]');&#60;br /&#62;
title('Beam Pattern At Source Fundamental');&#60;br /&#62;
colormap(jet(256));&#60;br /&#62;
c = colorbar;&#60;br /&#62;
ylabel(c, 'Pressure [MPa]');&#60;br /&#62;
axis image;&#60;/p&#62;
&#60;p&#62;figure;&#60;br /&#62;
imagesc(j_vec*1e3, (kgrid.x_vec - min(kgrid.x_vec(:)))*1e3, beam_pattern_f2/1e3);&#60;br /&#62;
xlabel([j_label '-position [mm]']);&#60;br /&#62;
ylabel('x-position [mm]');&#60;br /&#62;
title('Beam Pattern At Second Harmonic');&#60;br /&#62;
colormap(jet(256));&#60;br /&#62;
c = colorbar;&#60;br /&#62;
ylabel(c, 'Pressure [kPa]');&#60;br /&#62;
axis image;&#60;/p&#62;
&#60;p&#62;figure;&#60;br /&#62;
imagesc(j_vec*1e3, (kgrid.x_vec - min(kgrid.x_vec(:)))*1e3, beam_pattern_total/1e6);&#60;br /&#62;
xlabel([j_label '-position [mm]']);&#60;br /&#62;
ylabel('x-position [mm]');&#60;br /&#62;
title('Total Beam Pattern Using Integral Of Recorded Pressure');&#60;br /&#62;
colormap(jet(256));&#60;br /&#62;
c = colorbar;&#60;br /&#62;
ylabel(c, 'Pressure [MPa]');&#60;br /&#62;
axis image;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% PLOT DIRECTIVITY PATTERN AT FOCUS&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% compute the directivity at each of the harmonics&#60;br /&#62;
directivity_f1 = squeeze(beam_pattern_f1(round(transducer.focus_distance/dx), :));&#60;br /&#62;
directivity_f2 = squeeze(beam_pattern_f2(round(transducer.focus_distance/dx), :));&#60;/p&#62;
&#60;p&#62;% normalise&#60;br /&#62;
directivity_f1 = directivity_f1./max(directivity_f1(:));&#60;br /&#62;
directivity_f2 = directivity_f2./max(directivity_f2(:));&#60;/p&#62;
&#60;p&#62;% compute relative angles from transducer&#60;br /&#62;
if strcmp(MASK_PLANE, 'xy')&#60;br /&#62;
    horz_axis = ((1:Ny) - Ny/2)*dy;&#60;br /&#62;
else&#60;br /&#62;
    horz_axis = ((1:Nz) - Nz/2)*dz;&#60;br /&#62;
end&#60;br /&#62;
angles = 180*atan2(horz_axis, transducer.focus_distance)/pi;&#60;/p&#62;
&#60;p&#62;% plot the directivity&#60;br /&#62;
figure;&#60;br /&#62;
plot(angles, directivity_f1, 'k-', angles, directivity_f2, 'k--');&#60;br /&#62;
axis tight;&#60;br /&#62;
set(gca, 'FontSize', 12);&#60;br /&#62;
xlabel('Angle [deg]');&#60;br /&#62;
ylabel('Normalised Amplitude');&#60;br /&#62;
legend('Fundamental', 'Second Harmonic', 'Location', 'NorthWest');
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
