<?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: Scalloping in piston transducer simulation (large grid)</title>
		<link>http://www.k-wave.org/forum/topic/scalloping-in-piston-transducer-simulation-large-grid</link>
		<description>Support for the k-Wave MATLAB toolbox</description>
		<language>en-US</language>
		<pubDate>Wed, 13 May 2026 18:27:33 +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/scalloping-in-piston-transducer-simulation-large-grid" rel="self" type="application/rss+xml" />

		<item>
			<title>Bradley Treeby on "Scalloping in piston transducer simulation (large grid)"</title>
			<link>http://www.k-wave.org/forum/topic/scalloping-in-piston-transducer-simulation-large-grid#post-6438</link>
			<pubDate>Thu, 26 Apr 2018 09:13:45 +0000</pubDate>
			<dc:creator>Bradley Treeby</dc:creator>
			<guid isPermaLink="false">6438@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi apigula,&#60;/p&#62;
&#60;p&#62;The problem is related to the sampling of the time domain waveform. Although it might be sufficiently sampled (its Fourier spectrum decays), a time sample might not lie exactly on the maximum. A better way is to use exactly an integer number of points per period, and then extract the amplitude using the (e.g., &#60;code&#62;extractAmpPhase&#60;/code&#62;). An alternative is to upsample the time domain waveforms (e.g., using &#60;code&#62;interpft&#60;/code&#62;) before taking the maximum.&#60;/p&#62;
&#60;p&#62;Hope that helps,&#60;/p&#62;
&#60;p&#62;Brad.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>apigula on "Scalloping in piston transducer simulation (large grid)"</title>
			<link>http://www.k-wave.org/forum/topic/scalloping-in-piston-transducer-simulation-large-grid#post-6351</link>
			<pubDate>Mon, 19 Mar 2018 15:27:32 +0000</pubDate>
			<dc:creator>apigula</dc:creator>
			<guid isPermaLink="false">6351@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Yes, I increased it to allow a wave to propagate across the longest diagonal at speed C0, plus a little extra.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Bradley Treeby on "Scalloping in piston transducer simulation (large grid)"</title>
			<link>http://www.k-wave.org/forum/topic/scalloping-in-piston-transducer-simulation-large-grid#post-6324</link>
			<pubDate>Wed, 07 Mar 2018 22:37:44 +0000</pubDate>
			<dc:creator>Bradley Treeby</dc:creator>
			<guid isPermaLink="false">6324@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;I haven't run your code, but a quick question, did you also increase &#60;code&#62;T_END&#60;/code&#62; when increasing the grid size?&#60;/p&#62;
&#60;p&#62;Brad.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>apigula on "Scalloping in piston transducer simulation (large grid)"</title>
			<link>http://www.k-wave.org/forum/topic/scalloping-in-piston-transducer-simulation-large-grid#post-6312</link>
			<pubDate>Mon, 05 Mar 2018 20:00:41 +0000</pubDate>
			<dc:creator>apigula</dc:creator>
			<guid isPermaLink="false">6312@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hello, I have two questions about large-grid simulations, based on a modified version of your circular piston example.&#60;/p&#62;
&#60;p&#62;(1) At large grid sizes (say, 256x256x3456), I was getting terrible agreement between the theory and simulated axial pressures in the farfield.  I was able to improve the simulation's accuracy significantly by using PML = 30.  This is nonintuitive to me - Why would a large grid size require a larger PML?&#60;/p&#62;
&#60;p&#62;(2) Even after increasing the PML, I get funny oscillations in the simulated axial pressure when using a large grid size.  In particular, there's a scallop-like pattern near the farfield peak, and the pressure still doesn't quite match the prediction.  Any idea why this is?&#60;/p&#62;
&#60;p&#62;I'd appreciate any advice!&#60;/p&#62;
&#60;p&#62;Here's the code I was running:&#60;/p&#62;
&#60;p&#62;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&#60;/p&#62;
&#60;p&#62;clear all;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE LITERALS&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% select which code to run&#60;br /&#62;
%   1: MATLAB CPU code&#60;br /&#62;
%   2: MATLAB GPU code&#60;br /&#62;
%   3: C++ code&#60;br /&#62;
MODEL           = 3;&#60;/p&#62;
&#60;p&#62;% scale parameter (changes the resolution of the simulation)&#60;br /&#62;
SC              = 1;&#60;/p&#62;
&#60;p&#62;% grid parameters&#60;br /&#62;
PML_SIZE        = 30;                    % size of the perfectly matched layer [grid points]&#60;br /&#62;
Nx              = 3456*SC - 2*PML_SIZE;   % number of grid points in the x direction&#60;br /&#62;
Ny              = 256*SC - 2*PML_SIZE;   % number of grid points in the y direction&#60;br /&#62;
Nz              = 256*SC - 2*PML_SIZE;   % number of grid points in the z direction&#60;/p&#62;
&#60;p&#62;% sampling parameters&#60;br /&#62;
PPW             = 5*SC;    % points per wavelength (this defines the grid size)&#60;br /&#62;
PPP             = 80*SC/2;    % points per period (this defines the CFL)&#60;br /&#62;
T_END           = 1.3e-4;    % total compute time [s] (this must be long enough to reach steady state)&#60;br /&#62;
RECORD_PERIODS  = 2;        % number of periods to record&#60;/p&#62;
&#60;p&#62;% medium parameters&#60;br /&#62;
C0              = 1580;     % sound speed [m/s]&#60;br /&#62;
RHO0            = 1000;     % density [kg/m^3]&#60;/p&#62;
&#60;p&#62;% source parameters&#60;br /&#62;
F0              = 6e6;      % source frequency [Hz]&#60;br /&#62;
SOURCE_RADIUS   = 90*SC;    % piston radius [grid points]&#60;br /&#62;
SOURCE_MAG      = 0.5e6;    % source pressure [Pa]&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% CREATE GRID&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% calculate the grid spacing based on the PPW and F0&#60;br /&#62;
dx = C0 / (PPW * F0);   % [m]&#60;br /&#62;
dt = 1 / (PPP*F0);      % [s]&#60;/p&#62;
&#60;p&#62;% calculate the CFL&#60;br /&#62;
disp(['CFL = ' num2str(C0*dt/dx)]);&#60;/p&#62;
&#60;p&#62;% create the computational grid&#60;br /&#62;
kgrid = kWaveGrid(Nx, dx, Ny, dx, Nz, dx);&#60;/p&#62;
&#60;p&#62;% create the time array&#60;br /&#62;
kgrid.t_array = 0:dt:T_END;&#60;/p&#62;
&#60;p&#62;% assign medium properties&#60;br /&#62;
medium.sound_speed = C0;&#60;br /&#62;
medium.density = RHO0;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% CREATE SOURCE&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% create piston source mask&#60;br /&#62;
piston = makeDisc(Ny, Nz, Ny/2, Nz/2, SOURCE_RADIUS);&#60;/p&#62;
&#60;p&#62;source.p_mask = zeros(Nx, Ny, Nz);&#60;br /&#62;
source.p_mask(1, :, :) = piston;&#60;/p&#62;
&#60;p&#62;% create time varying source&#60;br /&#62;
source.p = SOURCE_MAG * sin(2*pi*F0*kgrid.t_array);&#60;/p&#62;
&#60;p&#62;% filter source with up-ramp&#60;br /&#62;
ramp_length = round((2*pi/F0)/dt);&#60;br /&#62;
ramp = (-cos( (0:(ramp_length-1))*pi/ramp_length ) + 1)/2;&#60;br /&#62;
source.p(1:ramp_length) = ramp .* source.p(1:ramp_length);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% CREATE SENSOR MASK&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% set sensor mask to record central axis, not including the source point&#60;br /&#62;
sensor.mask = zeros(Nx, Ny, Nz);&#60;br /&#62;
sensor.mask(2:end, Ny/2, Nz/2) = 1;&#60;/p&#62;
&#60;p&#62;% record the maximum pressure&#60;br /&#62;
sensor.record = {'p_max'};&#60;/p&#62;
&#60;p&#62;% average only the final few periods when the field is in steady state&#60;br /&#62;
sensor.record_start_index = kgrid.Nt - RECORD_PERIODS*PPP + 1;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% RUN k-WAVE SIMULATION&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% run code&#60;br /&#62;
switch MODEL&#60;br /&#62;
    case 1&#60;br /&#62;
        % MATLAB CPU&#60;br /&#62;
        sensor_data = kspaceFirstOrder3D(kgrid, medium, source, sensor, ...&#60;br /&#62;
            'DataCast', 'single', 'PMLInside', false, ...&#60;br /&#62;
            'DisplayMask', source.p_mask, 'PlotScale', [-1, 1]*SOURCE_MAG);&#60;br /&#62;
    case 2&#60;br /&#62;
        % MATLAB GPU&#60;br /&#62;
        sensor_data = kspaceFirstOrder3D(kgrid, medium, source, sensor, ...&#60;br /&#62;
            'DataCast', 'gpuArray-single', 'PMLInside', false, ...&#60;br /&#62;
            'DisplayMask', source.p_mask, 'PlotScale', [-1, 1]*SOURCE_MAG);&#60;br /&#62;
    case 3&#60;br /&#62;
        % C++&#60;br /&#62;
        sensor_data = kspaceFirstOrder3DC(kgrid, medium, source, sensor, 'PMLInside', false, 'PMLSize', PML_SIZE);&#60;br /&#62;
end&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% ANALYTICAL SOLUTION&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% calculate the wavenumber&#60;br /&#62;
k = 2*pi*F0./C0;&#60;/p&#62;
&#60;p&#62;% define radius and axis&#60;br /&#62;
a = SOURCE_RADIUS*dx;&#60;br /&#62;
x = (kgrid.x_vec(2:end, :) - min(kgrid.x_vec(:)));&#60;/p&#62;
&#60;p&#62;% calculate the analytical solution for a piston in an infinite baffle&#60;br /&#62;
% for comparison (Eq 5-7.3 in Pierce)&#60;br /&#62;
r_a = sqrt(x.^2 + a^2);&#60;br /&#62;
p_ref = SOURCE_MAG*abs(-2i*exp(1i*k*(x+r_a)/2).*sin((k*r_a - k*x)/2));&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% VISUALISATION&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% plot the pressure along the focal axis of the piston&#60;br /&#62;
figure;&#60;br /&#62;
plot(1000*x, p_ref, 'k-');&#60;br /&#62;
hold on;&#60;br /&#62;
plot(1000*x, sensor_data.p_max, 'bx')&#60;br /&#62;
xlabel('Distance (cm)');&#60;br /&#62;
legend('Exact', 'k-Wave');&#60;/p&#62;
&#60;p&#62;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
