<?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; User Favorites: liuying123</title>
		<link><a href='http://www.k-wave.org/forum/profile/liuying123'>liuying123</a></link>
		<description>Support for the k-Wave MATLAB toolbox</description>
		<language>en-US</language>
		<pubDate>Wed, 13 May 2026 01:06:45 +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/profile/" rel="self" type="application/rss+xml" />

		<item>
			<title>liuying123 on "Simulate echoes of balls or side-drilled holes (SDHs)"</title>
			<link>http://www.k-wave.org/forum/topic/simulate-echoes-of-balls-or-side-drilled-holes-sdhs#post-9198</link>
			<pubDate>Sun, 16 Mar 2025 06:00:17 +0000</pubDate>
			<dc:creator>liuying123</dc:creator>
			<guid isPermaLink="false">9198@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hello, your reply is very important to me. I would like to ask how you set up the materials for synthetic aperture imaging after scanning for internal defects in steel. Specifically, I have set up three layers: water, acrylic, and aluminum, with the phased array placed in the water layer for transmission and reception. Why are the echo signals very weak or even nonexistent? I have set the frequency to 7.5 MHz with a 36-element transducer array, scanning sequentially, but the A-scan data of the echoes does not seem correct. I would greatly appreciate your response. Below is my code. % 引导线性阵列示例&#60;br /&#62;
clearvars;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% 模拟&#60;br /&#62;
% ========================================================================&#60;br /&#62;
% 创建计算网格&#60;br /&#62;
Nx = 400;               % x 方向的网格点数&#60;br /&#62;
Ny = Nx;                % y 方向的网格点数&#60;br /&#62;
dx = 0.1e-3;           % x 方向的网格点间距 [m]&#60;br /&#62;
dy = dx;               % y 方向的网格点间距 [m]&#60;br /&#62;
kgrid = kWaveGrid(Nx, dx, Ny, dy);&#60;/p&#62;
&#60;p&#62;% 定义介质属性&#60;br /&#62;
sound_speed_water = 1500;  % 水声速 [m/s]&#60;br /&#62;
density_water = 1000;       % 水密度 [kg/m^3]&#60;br /&#62;
sound_speed_acrylic = 2700; % 亚克力声速 [m/s]&#60;br /&#62;
density_acrylic = 1190;      % 亚克力密度 [kg/m^3]&#60;br /&#62;
sound_speed_aluminum = 6300; % 铝声速 [m/s]&#60;br /&#62;
density_aluminum = 2690;      % 铝密度 [kg/m^3]&#60;/p&#62;
&#60;p&#62;% 创建时间数组&#60;br /&#62;
t_end = 45.5e-6; % [s]&#60;br /&#62;
kgrid.makeTime(sound_speed_acrylic, [], t_end); % acrylic&#60;/p&#62;
&#60;p&#62;% 定义线性换能器的参数&#60;br /&#62;
num_elements = 36;      % [阵元数量]&#60;br /&#62;
x_offset = 20;          % [网格点]&#60;br /&#62;
element_width = 1;      % 定义阵元宽度为1个网格点&#60;br /&#62;
source_focus = 0.13;    % 聚焦深度 [m]&#60;br /&#62;
element_pitch = 0.3e-3;  % 每个阵元的间距 [m]&#60;br /&#62;
source.p_mask = zeros(Nx, Ny);&#60;/p&#62;
&#60;p&#62;% 计算发射阵元的起始位置&#60;br /&#62;
transducer_width = num_elements * (element_width + 2); % 发射阵元总宽度，包含间隔&#60;br /&#62;
start_index = round(Ny/2 - transducer_width/2); % y方向的起始位置&#60;/p&#62;
&#60;p&#62;% 计算每个阵元的时间延迟&#60;br /&#62;
ids = (0:num_elements - 1); % 阵元索引&#60;br /&#62;
time_delays = -(sqrt((ids .* element_pitch).^2 + source_focus.^2) - source_focus) ./ sound_speed_water;&#60;br /&#62;
time_delays = time_delays - min(time_delays); % 归一化时间延迟&#60;/p&#62;
&#60;p&#62;% 定义用于驱动换能器的音调脉冲属性&#60;br /&#62;
sampling_freq = 75e6;     % [Hz]&#60;br /&#62;
tone_burst_freq = 7.5e6;  % [Hz]&#60;br /&#62;
tone_burst_cycles = 1;&#60;/p&#62;
&#60;p&#62;% 定义回波数据存储三维矩阵&#60;br /&#62;
num_scans = 128 - 36 + 1;              % 扫描次数&#60;br /&#62;
num_time_points = length(kgrid.t_array); % 修正时间点数为 kgrid.t_array 的长度&#60;br /&#62;
echo_data = zeros(num_scans, num_elements, num_time_points); % 初始化三维矩阵&#60;/p&#62;
&#60;p&#62;% 创建音调脉冲信号，为每个阵元生成时间序列&#60;br /&#62;
source.p = zeros(num_elements, length(kgrid.t_array)); % 初始化源信号矩阵&#60;br /&#62;
for i = 1:num_elements&#60;br /&#62;
    pulse = toneBurst(sampling_freq, tone_burst_freq, tone_burst_cycles, ...&#60;br /&#62;
        'SignalOffset', time_delays(i));&#60;br /&#62;
    source.p(i, 1:length(pulse)) = 20 * pulse; %加了20倍更明显&#60;br /&#62;
end&#60;/p&#62;
&#60;p&#62;% 分配输入选项&#60;br /&#62;
input_args = {'DisplayMask', source.p_mask};&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% 定义传感器&#60;br /&#62;
% =========================================================================&#60;br /&#62;
sensor.mask = zeros(Nx, Ny); % 初始化传感器蒙版&#60;br /&#62;
sensor.record = {'p'}; % 记录声压&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% 定义三层介质，包含孔缺陷&#60;br /&#62;
% =========================================================================&#60;br /&#62;
% 创建声速和密度的映射&#60;br /&#62;
sound_speed_map = zeros(Nx, Ny); % 初始化为零矩阵&#60;br /&#62;
density_map = zeros(Nx, Ny);      % 初始化为零矩阵&#60;/p&#62;
&#60;p&#62;% 设置水层的位置（上层）&#60;br /&#62;
water_height = round(10e-3 / dy); % 水层高度 10 mm&#60;br /&#62;
for i = 1:water_height&#60;br /&#62;
    sound_speed_map(i, :) = sound_speed_water;  % 水声速&#60;br /&#62;
    density_map(i, :) = density_water;          % 水密度&#60;br /&#62;
end&#60;/p&#62;
&#60;p&#62;% 设置亚克力层的位置（中层）&#60;br /&#62;
acrylic_height = round(10e-3 / dy); % 亚克力层高度 10 mm&#60;br /&#62;
for i = water_height + 1:water_height + acrylic_height&#60;br /&#62;
    sound_speed_map(i, :) = sound_speed_acrylic;  % 亚克力声速&#60;br /&#62;
    density_map(i, :) = density_acrylic;          % 亚克力密度&#60;br /&#62;
end&#60;/p&#62;
&#60;p&#62;% 设置铝层的位置（下层）&#60;br /&#62;
aluminum_height = round(20e-3 / dy); % 铝层高度 20 mm&#60;br /&#62;
for i = water_height + acrylic_height + 1:water_height + acrylic_height + aluminum_height&#60;br /&#62;
    sound_speed_map(i, :) = sound_speed_aluminum;  % 铝层声速&#60;br /&#62;
    density_map(i, :) = density_aluminum;          % 铝层密度&#60;br /&#62;
end&#60;/p&#62;
&#60;p&#62;% 定义缺陷位置（孔）&#60;br /&#62;
radius = 1e-3; % 孔的半径&#60;br /&#62;
x_center = 300; % 网格中心&#60;br /&#62;
y_center = 200; % 孔在亚克力层中间&#60;br /&#62;
defect_region = makeDisc(Nx, Ny, x_center, y_center, round(radius/dx), 2 * pi);&#60;br /&#62;
sound_speed_map(defect_region == 1) = sound_speed_water;  % 孔区域设置为水的声速&#60;br /&#62;
density_map(defect_region == 1) = density_water;          % 孔区域设置为水的密度&#60;/p&#62;
&#60;p&#62;% 更新介质属性&#60;br /&#62;
medium.sound_speed = sound_speed_map;  % 使用有效字段&#60;br /&#62;
medium.density = density_map;          % 使用有效字段&#60;/p&#62;
&#60;p&#62;% 从第128个网格点开始进行扫描&#60;br /&#62;
start_scan_index = 28; % 设置起始扫描位置&#60;br /&#62;
for scan_index = 0:2:(2 * (num_scans - 1)) % 每次跨越两个网格&#60;br /&#62;
    % 当前发射阵元的起始位置&#60;br /&#62;
    current_position = start_scan_index + scan_index; % 网格位置从 128 开始&#60;/p&#62;
&#60;p&#62;    % 更新发射阵元的掩码&#60;br /&#62;
    source.p_mask(:) = 0; % 清除之前的掩码&#60;br /&#62;
    start_index = current_position + round(num_elements/2) * (element_width + 2); % 计算当前起始索引&#60;br /&#62;
    for i = 0:num_elements - 1&#60;br /&#62;
        % 仅在阵元位置设置掩码&#60;br /&#62;
        source.p_mask(x_offset, start_index + i * (element_width + 2)) = 1;&#60;br /&#62;
    end&#60;/p&#62;
&#60;p&#62;    % 运行模拟&#60;br /&#62;
    sensor.mask = zeros(Nx, Ny); % 初始化传感器蒙版&#60;br /&#62;
    sensor.mask(x_offset, start_index:start_index + (num_elements - 1) * (element_width + 2)) = 0; % 清空传感器蒙版&#60;br /&#62;
    for i = 0:num_elements - 1&#60;br /&#62;
        % 仅在阵元位置设置传感器蒙版&#60;br /&#62;
        sensor.mask(x_offset, start_index + i * (element_width + 2)) = 1; %原来是x_offset，改成的100&#60;br /&#62;
    end&#60;br /&#62;
    sensor.record = {'p'}; % 记录声压&#60;/p&#62;
&#60;p&#62;    % 运行模拟&#60;br /&#62;
    sensor_data = kspaceFirstOrder2D(kgrid, medium, source, sensor, input_args{:});&#60;/p&#62;
&#60;p&#62;    % 存储回波数据，确保维度匹配&#60;br /&#62;
    echo_data(scan_index / 2 + 1, :, :) = sensor_data.p; % 存储回波数据&#60;br /&#62;
end&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% 可视化&#60;br /&#62;
% =========================================================================&#60;br /&#62;
figure;&#60;br /&#62;
plot(sensor_data.p(21,:));&#60;br /&#62;
xlabel('时间点');&#60;br /&#62;
ylabel('声压 [Pa]');&#60;br /&#62;
title('最后一次扫描的声压信号');&#60;/p&#62;
&#60;p&#62;% 绘制特定扫描的接收到的信号（例如第5次扫描）&#60;br /&#62;
figure;&#60;br /&#62;
plot(squeeze(echo_data(5, :, :))); % 选择特定扫描和阵元的信号&#60;br /&#62;
xlabel('时间点');&#60;br /&#62;
ylabel('声压 [Pa]');&#60;br /&#62;
title('特定扫描的接收到的信号');&#60;/p&#62;
&#60;p&#62;% 绘制所有回波数据的示例&#60;br /&#62;
figure;&#60;br /&#62;
stackedPlot(kgrid.t_array, squeeze(echo_data(5, :, :)));&#60;br /&#62;
xlabel('时间 [s]');&#60;br /&#62;
ylabel('回波信号');&#60;br /&#62;
title('所有数据的示例');
&#60;/p&#62;</description>
		</item>
		<item>
			<title>liuying123 on "Source-sensor interaction"</title>
			<link>http://www.k-wave.org/forum/topic/source-sensor-interaction#post-9191</link>
			<pubDate>Tue, 04 Mar 2025 07:21:07 +0000</pubDate>
			<dc:creator>liuying123</dc:creator>
			<guid isPermaLink="false">9191@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hello, I have encountered a similar problem as you. During the two-dimensional simulation, I used the same transmitting array elements as receiving array elements in the water. I set up three layers of media: water, acrylic, and aluminum, but the received signal is very weak. Do you have any solutions? I look forward to your reply.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>HD Y on "Using source.p to specify pressure distribution"</title>
			<link>http://www.k-wave.org/forum/topic/using-sourcep-to-specify-pressure-distribution#post-9188</link>
			<pubDate>Wed, 19 Feb 2025 23:21:34 +0000</pubDate>
			<dc:creator>HD Y</dc:creator>
			<guid isPermaLink="false">9188@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi, it seems I found some discussions on the implementation of Dirichlet boundary conditions in this post. But I still did not get how the scaling factor is set in general.&#60;/p&#62;
&#60;p&#62;On the other hand, I saw some good results in Figure 2 of the following publication:&#60;/p&#62;
&#60;p&#62;Modelling Nonlinear Ultrasound Propagation in Absorbing Media using the k-Wave Toolbox: Experimental Validation.&#60;/p&#62;
&#60;p&#62;May I ask in this reference, what exact scaling factor is used in order to get such good agreement between simulation results and experimental results.&#60;/p&#62;
&#60;p&#62;Thanks
&#60;/p&#62;</description>
		</item>
		<item>
			<title>‪Alon on "size of kWaveArray"</title>
			<link>http://www.k-wave.org/forum/topic/size-of-kwavearray#post-9163</link>
			<pubDate>Mon, 09 Dec 2024 19:53:37 +0000</pubDate>
			<dc:creator>‪Alon</dc:creator>
			<guid isPermaLink="false">9163@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hello,&#60;/p&#62;
&#60;p&#62;I've been experimenting with kWaveArray and noticed an issue when converting a karray to a binary mask. After conversion, the size of the elements seems to differ from the expected size, likely due to interpolation of off-grid points.&#60;/p&#62;
&#60;p&#62;For example, if I create a rectangular element with specific width and length, the binary mask generated by getArrayBinaryMask shows a size that is (much) larger than expected. Specifically, when I measure (in grid points) the length (say, along the x-axis), the result exceeds the intended size of Lx / dx (by more than 1-2 extra grid points).&#60;/p&#62;
&#60;p&#62;I understand that parameters like 'BLITolerance' can influence this behavior, but I'm wondering how I can ensure the size of the binary mask matches the intended dimensions exactly.&#60;/p&#62;
&#60;p&#62;Thanks for your help!
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mperezdiego on "Source-sensor interaction"</title>
			<link>http://www.k-wave.org/forum/topic/source-sensor-interaction#post-9158</link>
			<pubDate>Fri, 15 Nov 2024 09:28:14 +0000</pubDate>
			<dc:creator>mperezdiego</dc:creator>
			<guid isPermaLink="false">9158@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi, &#60;/p&#62;
&#60;p&#62;I am performing a 2D elastic simulation between two media where the incident medium is a solid and the imepedance mismatch is very high. I am exciting an application specific time varying pulse. The source I am using is a 1D horizontal line and I want to sense the received echo at the exact same grid points, so I defined the sensor mask equal to the source mask. What I observe after siulation is the original pulse and then the echo. The echo is equal to the excitation pulse (totally reflected back), but the sensed sent pulse, instead of being the inverted original pulse (what I observe when the sensor and the source are in different positions), I observe a more complex waveform that then offsets the received echo too. &#60;/p&#62;
&#60;p&#62;I would like to know how the sensor and source are coupled in this  case to give that curious waveform. I am particularly interested in that waveform because I observed it in other experimental conditions but in the echoes.&#60;/p&#62;
&#60;p&#62;Thank you,&#60;/p&#62;
&#60;p&#62;M.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Zakc on "Photoacoustic Image Reconstruction(Time reversal) in Elastic Model"</title>
			<link>http://www.k-wave.org/forum/topic/photoacoustic-image-reconstructiontime-reversal-in-elastic-model#post-9088</link>
			<pubDate>Thu, 02 May 2024 09:16:37 +0000</pubDate>
			<dc:creator>Zakc</dc:creator>
			<guid isPermaLink="false">9088@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi everyone,&#60;/p&#62;
&#60;p&#62;  I am doing well in photoacoustic image reconstruction by using time reversal and interpolating data in fluid model based on &#34;2D Time Reversal Reconstruction For A Circular Sensor Example&#34;. Hence, I am trying to do the same in the elastic model because the medium includes the skull. I encountered a problem in that the circular sensors emit waves in an axisymmetric manner and the reconstructed image is incorrect and axisymmetric. But everything went well by interpolating data and creating an equivalent continuous circle. The codes of sensor, source, time reversal are as follows.&#60;/p&#62;
&#60;p&#62;Yours,&#60;br /&#62;
Zak&#60;br /&#62;
------------------------------------------------------------&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;% assign the source
sampling_freq = 1/kgrid.dt;     % [Hz]
source.s_mask = makeDisc(Nx, Ny, disc_x_pos, disc_y_pos, disc_radius);
source.sxx = -disc_magnitude.* toneBurst(sampling_freq, tone_burst_freq, tone_burst_cycles,&#38;#39;Plot&#38;#39;,false);
source.syy = source.sxx;

% define sensor
sensor_radius = 12e-2;     % [m]
sensor_angle = 4*pi/2;      % [rad]
sensor_pos = [0, 0];        % [m]
num_sensor_points = 40;
sensor.mask = makeCartCircle(sensor_radius, num_sensor_points, sensor_pos, sensor_angle);
% sensor.mask = makeCircle(Nx, Ny, sensor_pos(1,1), sensor_pos(1,2), round(sensor_radius/dx), sensor_angle);

% set the input options
input_args = {&#38;#39;Smooth&#38;#39;, false, &#38;#39;PMLInside&#38;#39;, false, &#38;#39;PlotPML&#38;#39;, false,...
    &#38;#39;PlotSim&#38;#39;,true};

% run the elastic simulation
sensor_data_elastic = pstdElastic2D(kgrid, medium, source, sensor, input_args{:});

% =========================================================================
% ELASTIC RECONSTRUCTION
% =========================================================================

% redefine kgrid_recon
kgrid_recon = kWaveGrid(Nx, dx, Ny, dy);
kgrid_recon.makeTime(cp1,cfl);

% add noise to the recorded sensor data
signal_to_noise_ratio = 40;	% [dB]
sensor_data_elastic = addNoise(sensor_data_elastic, signal_to_noise_ratio, &#38;#39;peak&#38;#39;);

% reset the initial pressure
source.sxx = 0;
source.syy = source.sxx;

% assign the time reversal data(elastic)
sensor.time_reversal_boundary_data = sensor_data_elastic;

% run the time-reversal reconstruction
p0_recon_elastic = pstdElastic2D(kgrid_recon, medium, source, sensor, input_args{:});

% create a binary sensor mask of an equivalent continuous circle
sensor_radius_grid_points = round(sensor_radius / kgrid_recon.dx);
binary_sensor_mask = makeCircle(kgrid_recon.Nx, kgrid_recon.Ny, ...
kgrid_recon.Nx/2 + 1, kgrid_recon.Ny/2 + 1, sensor_radius_grid_points, sensor_angle);

% assign to sensor structure
sensor.mask = binary_sensor_mask;

cart_sensor_mask = makeCartCircle(sensor_radius, num_sensor_points, sensor_pos, sensor_angle);

% interpolate data to remove the gaps and assign to sensor structure
sensor.time_reversal_boundary_data = interpCartData(kgrid_recon, sensor_data_elastic, cart_sensor_mask, binary_sensor_mask);

% run the time-reversal reconstruction
p0_recon_interp_elastic = pstdElastic2D(kgrid_recon, medium, source, sensor, input_args{:});&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;------------------------------------------------------------------
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Bradley Treeby on "Artifacts in Plane Wave Simulations using kWaveArray"</title>
			<link>http://www.k-wave.org/forum/topic/artifacts-in-plane-wave-simulations-using-kwavearray#post-9011</link>
			<pubDate>Wed, 24 Jan 2024 11:17:15 +0000</pubDate>
			<dc:creator>Bradley Treeby</dc:creator>
			<guid isPermaLink="false">9011@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;I haven't run your simulation, but the effects you're describing is what I would expect to happen given the way sources are modelled in k-Wave. Depending on the transducer design, you also see this in experimental measurements. One simple way to remove the transmitted wave from the receive data would be to run two simulations, one in a homogeneous medium, and then one with the medium properties you are trying to image, and subtract the RF data of the first from the second.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>nikunj101 on "Artifacts in Plane Wave Simulations using kWaveArray"</title>
			<link>http://www.k-wave.org/forum/topic/artifacts-in-plane-wave-simulations-using-kwavearray#post-8987</link>
			<pubDate>Wed, 13 Dec 2023 19:10:16 +0000</pubDate>
			<dc:creator>nikunj101</dc:creator>
			<guid isPermaLink="false">8987@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi,&#60;/p&#62;
&#60;p&#62;I am currently working on simulating RFData generated by plane wave emissions from a linear array transducer. In this process, I am encountering several artifacts in my simulations, particularly when recombining sensor data using kWaveArray. The primary issue involves the inadequate cancellation of signals from adjacent elements, especially noticeable when the transmit angle deviates from zero. This results in unwanted signals appearing in the simulated RFData.&#60;/p&#62;
&#60;p&#62;Additionally, I observe an edge effect. The edges of my simulated array produce spherical wave patterns that propagate across the array, creating an X-like artifact in the RFData. While similar phenomena occur in practical scenarios with linear arrays, the inherent directionality of actual transducer elements usually reduces the intensity of this artifact. In my simulation using kWave, even though the spherical sources are non-directional, I expect the line elements implemented via kWaveArray to exhibit some directionality, so I'm surprised I'm seeing as strong an artifact as I am.&#60;/p&#62;
&#60;p&#62;I have tried applying a roll-off apodization along the array edges to mitigate this issue, but I am seeking alternative solutions. Could you suggest other methods to reduce the edge effect artifact? Additionally, how might I address the interference artifact arising from neighboring elements?&#60;/p&#62;
&#60;p&#62;Here is a minimal working example of my code using a homogenous medium. You can adjust the transmit angle by changing the TXangle parameter in the first section:&#60;/p&#62;
&#60;p&#62;&#60;code&#62;&#60;/code&#62;`&#60;br /&#62;
% Coherent Plane Wave Compounding Simulation Using K-Wave&#60;br /&#62;
%&#60;br /&#62;
% This script demonstrates how to setup a linear array transducer using the&#60;br /&#62;
% kWaveArray class for coherent plane wave compounding in ultrasound imaging.&#60;br /&#62;
% It involves creating a simulation grid, defining a medium with point targets,&#60;br /&#62;
% initializing a transducer array, generating a focused source, simulating wave&#60;br /&#62;
% propagation, and collecting sensor data.&#60;br /&#62;
%&#60;br /&#62;
% Author: Nikunj Khetan&#60;br /&#62;
% Last Update: 21st November 2023&#60;/p&#62;
&#60;p&#62;clearvars;&#60;br /&#62;
% close all&#60;/p&#62;
&#60;p&#62;%% DEFINE LITERALS - Setting up parameters for the simulation&#60;/p&#62;
&#60;p&#62;% Selection of K-Wave code execution model&#60;br /&#62;
model = 1;  % Options: 1 - MATLAB CPU, 2 - MATLAB GPU, 3 - C++ code, 4 - CUDA code&#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;% Medium parameters&#60;br /&#62;
c0 = 1540;        % Sound speed in the medium [m/s]&#60;br /&#62;
rho0 = 1020;      % Density of the medium [kg/m^3]&#60;/p&#62;
&#60;p&#62;% Source parameters&#60;br /&#62;
source_f0 = (250/48)*1e6;         % Frequency of the ultrasound source [Hz]&#60;br /&#62;
source_amp = 1e6;          % Amplitude of the ultrasound source [Pa]&#60;br /&#62;
source_cycles = 3;         % Number of cycles in the tone burst signal&#60;br /&#62;
numEl = 128;               % Number of elements in the transducer array&#60;br /&#62;
element_width = 2.3e-4;    % Width of each transducer element [m]&#60;br /&#62;
element_pitch = 2.3e-4;    % Pitch - distance between the centers of adjacent elements [m]&#60;br /&#62;
RF_fs = source_f0*4;       % Sampling Frequency of final RFData&#60;/p&#62;
&#60;p&#62;% Define transmission angles for plane wave compounding&#60;br /&#62;
na = 1;  % Number of angles for transmission&#60;br /&#62;
TXangle = 10*pi/180;&#60;/p&#62;
&#60;p&#62;% Grid parameters&#60;br /&#62;
grid_size_x = 40e-3;  % Grid size in x-direction [m]&#60;br /&#62;
grid_size_y = 10e-3;  % Grid size in y-direction [m]&#60;/p&#62;
&#60;p&#62;% Computational parameters&#60;br /&#62;
ppw = 4;             % Points per wavelength&#60;br /&#62;
t_end = round(grid_size_y/c0,6);        % Simulation duration [s]&#60;br /&#62;
cfl = 0.5;            % Courant-Friedrichs-Lewy (CFL) number for stability&#60;/p&#62;
&#60;p&#62;%% GRID - Creating the computational grid&#60;/p&#62;
&#60;p&#62;% Calculate grid spacing based on PPW and source frequency&#60;br /&#62;
dx = c0 / (ppw * source_f0);  % Grid spacing [m]&#60;br /&#62;
dy = dx;&#60;/p&#62;
&#60;p&#62;% Compute grid size&#60;br /&#62;
Nx = roundEven(grid_size_x / dx);  % Number of grid points in x-direction&#60;br /&#62;
Ny = roundEven(grid_size_y / dy);  % Number of grid points in y-direction&#60;/p&#62;
&#60;p&#62;% Create the computational grid&#60;br /&#62;
kgrid = kWaveGrid(Nx, dx, Ny, dy);&#60;/p&#62;
&#60;p&#62;% Create the time array&#60;br /&#62;
kgrid.makeTime(c0, cfl, t_end);&#60;br /&#62;
dsFactor = (1/kgrid.dt)/RF_fs;&#60;/p&#62;
&#60;p&#62;%% SOURCE - Initializing the transducer array and source signal&#60;/p&#62;
&#60;p&#62;[karray, ElemPos] = initArray(kgrid, numEl, element_pitch, element_width);&#60;/p&#62;
&#60;p&#62;% Create source signal using a tone burst&#60;br /&#62;
source_sig = source_amp .* toneBurst(1/kgrid.dt, source_f0, source_cycles);&#60;/p&#62;
&#60;p&#62;%% MEDIUM - Defining the medium properties &#60;/p&#62;
&#60;p&#62;medium.sound_speed = c0 * ones([Nx, Ny]);   % sound speed [m/s]&#60;br /&#62;
medium.density = rho0 * ones([Nx, Ny]);      % density [kg/m3]&#60;/p&#62;
&#60;p&#62;%% SENSOR - Setting up the sensor mask and properties&#60;/p&#62;
&#60;p&#62;% Assign binary mask from karray to the sensor mask&#60;br /&#62;
sensor.mask = karray.getArrayBinaryMask(kgrid);&#60;/p&#62;
&#60;p&#62;% set the record mode such that only the rms and peak values are stored&#60;br /&#62;
sensor.record = {'p'};&#60;/p&#62;
&#60;p&#62;% Define frequency response of the sensor&#60;br /&#62;
sensor.frequency_response = [source_f0, 100];&#60;/p&#62;
&#60;p&#62;%% SIMULATION - Running the simulation for different transmission angles&#60;/p&#62;
&#60;p&#62;% Preallocate arrays for time delays and RF data&#60;br /&#62;
time_delays = zeros(na, numEl);&#60;/p&#62;
&#60;p&#62;% Simulation input options&#60;br /&#62;
input_args = {'PMLSize', 'auto', 'PMLInside', false, 'PlotPML', false, 'DisplayMask', 'off'};&#60;br /&#62;
RFData = zeros(numEl, kgrid.Nt, na);&#60;/p&#62;
&#60;p&#62;% Loop over each angle for plane wave compounding&#60;br /&#62;
for i = 1:na&#60;br /&#62;
    [source, time_delays(i, :)] = genSource(kgrid, source_f0, source_cycles, source_amp, TXangle(i), karray, ElemPos, c0);&#60;/p&#62;
&#60;p&#62;    sensor_data = runSim(kgrid, medium, source, sensor, input_args, model,source_amp);&#60;/p&#62;
&#60;p&#62;    RFData(:, :, i) = karray.combineSensorData(kgrid, sensor_data.p);&#60;br /&#62;
end&#60;/p&#62;
&#60;p&#62;% Rearrange RF data dimensions for further processing&#60;br /&#62;
RFData = downsample(flip(permute(RFData, [2, 1, 3]),2),dsFactor);&#60;/p&#62;
&#60;p&#62;figure&#60;br /&#62;
colormap gray&#60;br /&#62;
imagesc(log10(abs(RFData(:,:,1))))&#60;/p&#62;
&#60;p&#62;%% HELPER FUNCTIONS&#60;br /&#62;
function [karray, ElemPos] = initArray(kgrid, element_num, element_pitch, element_width)&#60;br /&#62;
    % Initializes the transducer array.&#60;br /&#62;
    % Args:&#60;br /&#62;
    %   kgrid: The k-Wave grid object.&#60;br /&#62;
    %   element_num: Number of elements in the array.&#60;br /&#62;
    %   element_pitch: Distance between the centers of adjacent elements.&#60;br /&#62;
    %   element_width: Width of each element.&#60;br /&#62;
    % Returns:&#60;br /&#62;
    %   karray: The k-Wave array object.&#60;br /&#62;
    %   ElemPos: The positions of the elements in the array.&#60;/p&#62;
&#60;p&#62;    % Create empty kWaveArray object with specified BLI tolerance and upsampling rate&#60;br /&#62;
    karray = kWaveArray('BLITolerance', 0.05, 'UpsamplingRate', 10);&#60;/p&#62;
&#60;p&#62;    % Calculate the center position for the first element&#60;br /&#62;
    L = element_num * element_pitch / 2;&#60;br /&#62;
    ElemPos = -(L - element_pitch / 2) + (0:element_num - 1) * element_pitch;&#60;/p&#62;
&#60;p&#62;    % Add rectangular elements to the array&#60;br /&#62;
    for ind = 1:element_num&#60;br /&#62;
        % Set element position&#60;br /&#62;
        x_pos = ElemPos(ind);&#60;/p&#62;
&#60;p&#62;        % Define start and end points of the element&#60;br /&#62;
        start_point = [x_pos - element_width / 2, kgrid.y_vec(1)];&#60;br /&#62;
        end_point = [x_pos + element_width / 2, kgrid.y_vec(1)];&#60;/p&#62;
&#60;p&#62;        % Add line element to the array&#60;br /&#62;
        karray.addLineElement(start_point, end_point);&#60;br /&#62;
    end&#60;br /&#62;
end&#60;/p&#62;
&#60;p&#62;function [source, time_delays] = genSource(kgrid, source_f0, source_cycles, source_amp, theta, karray, ElemPos, c0)&#60;br /&#62;
    % Generates the source signal with time delays for each transducer element.&#60;br /&#62;
    % Args:&#60;br /&#62;
    %   kgrid: The k-Wave grid object.&#60;br /&#62;
    %   source_f0: Frequency of the source.&#60;br /&#62;
    %   source_cycles: Number of cycles in the tone burst signal.&#60;br /&#62;
    %   source_amp: Amplitude of the source.&#60;br /&#62;
    %   theta: Steering angle of the plane wave.&#60;br /&#62;
    %   karray: The k-Wave array object.&#60;br /&#62;
    %   ElemPos: The positions of the elements in the array.&#60;br /&#62;
    %   c0: Speed of sound.&#60;br /&#62;
    % Returns:&#60;br /&#62;
    %   source: The source object containing the mask and signals.&#60;br /&#62;
    %   time_delays: Time delays applied to each element for focusing.&#60;/p&#62;
&#60;p&#62;    % Calculate time delays for each element based on steering angle&#60;br /&#62;
    time_delays = ElemPos * sin(theta) / c0;&#60;br /&#62;
    time_delays = time_delays - min(time_delays);&#60;/p&#62;
&#60;p&#62;    % Create time-varying source signals for each physical element&#60;br /&#62;
    source_sig = source_amp .* toneBurst(1/kgrid.dt, source_f0, source_cycles, 'SignalOffset', round(time_delays / kgrid.dt));&#60;/p&#62;
&#60;p&#62;    % Assign binary mask for the source&#60;br /&#62;
    source.p_mask = karray.getArrayBinaryMask(kgrid);&#60;/p&#62;
&#60;p&#62;    % Assign source signals to the source object&#60;br /&#62;
    source.p = karray.getDistributedSourceSignal(kgrid, source_sig);&#60;br /&#62;
end&#60;/p&#62;
&#60;p&#62;function [sensor_data] = runSim(kgrid, medium, source, sensor, input_args, model, source_amp)&#60;br /&#62;
    % Runs the simulation based on the selected model (CPU or GPU).&#60;br /&#62;
    % Args:&#60;br /&#62;
    %   kgrid: The k-Wave grid object.&#60;br /&#62;
    %   medium: The medium in which waves propagate.&#60;br /&#62;
    %   source: The source object containing the ultrasound signal.&#60;br /&#62;
    %   sensor: The sensor object to record the pressure.&#60;br /&#62;
    %   input_args: Additional input arguments for the simulation.&#60;br /&#62;
    %   model: The selected model for running the simulation.&#60;br /&#62;
    % Returns:&#60;br /&#62;
    %   sensor_data: The recorded sensor data from the simulation.&#60;/p&#62;
&#60;p&#62;    % Run the simulation based on the chosen model&#60;br /&#62;
    switch model&#60;br /&#62;
        case 1&#60;br /&#62;
            % MATLAB CPU&#60;br /&#62;
            sensor_data = kspaceFirstOrder2D(kgrid, medium, source, sensor, ...&#60;br /&#62;
                input_args{:}, ...&#60;br /&#62;
                'DataCast', 'single', ...&#60;br /&#62;
                'PlotScale', [-1, 1] * source_amp);&#60;/p&#62;
&#60;p&#62;        case 2&#60;br /&#62;
            % MATLAB GPU&#60;br /&#62;
            sensor_data = kspaceFirstOrder2D(kgrid, medium, source, sensor, ...&#60;br /&#62;
                input_args{:}, ...&#60;br /&#62;
                'DataCast', 'gpuArray-single', ...&#60;br /&#62;
                'PlotScale', [-1, 1] * source_amp);&#60;/p&#62;
&#60;p&#62;        case 3&#60;br /&#62;
            % C++ code&#60;br /&#62;
            sensor_data = kspaceFirstOrder2DC(kgrid, medium, source, sensor, input_args{:});&#60;/p&#62;
&#60;p&#62;        case 4&#60;br /&#62;
            % C++/CUDA GPU&#60;br /&#62;
            sensor_data = kspaceFirstOrder2DG(kgrid, medium, source, sensor, input_args{:});&#60;br /&#62;
    end&#60;br /&#62;
end&#60;br /&#62;
&#60;code&#62;&#60;/code&#62;`
&#60;/p&#62;</description>
		</item>
		<item>
			<title>bencox on "Using source.p to specify pressure distribution"</title>
			<link>http://www.k-wave.org/forum/topic/using-sourcep-to-specify-pressure-distribution#post-8116</link>
			<pubDate>Sun, 11 Apr 2021 01:19:17 +0000</pubDate>
			<dc:creator>bencox</dc:creator>
			<guid isPermaLink="false">8116@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi Zahra,&#60;/p&#62;
&#60;p&#62;In 1D these sources should give the same result, but in higher dimensions they will differ as a pressure source is a monopole, which radiates omnidirectionally, but a velocity source is a dipole, which radiates with a figure-of-eight pattern.  Could that be the reason for the difference?&#60;/p&#62;
&#60;p&#62;As for comparison to measurements, I would recommend having a look at our colleague Elly Martin's recent paper on comparing experiments with k-Wave. &#60;a href=&#34;https://ieeexplore.ieee.org/document/8839830&#34;&#62;doi:10.1109/TUFFC.2019.2941795&#60;/a&#62;&#60;/p&#62;
&#60;p&#62;Best wishes&#60;br /&#62;
Ben
&#60;/p&#62;</description>
		</item>
		<item>
			<title>zahrat on "Using source.p to specify pressure distribution"</title>
			<link>http://www.k-wave.org/forum/topic/using-sourcep-to-specify-pressure-distribution#post-8083</link>
			<pubDate>Wed, 10 Mar 2021 17:25:34 +0000</pubDate>
			<dc:creator>zahrat</dc:creator>
			<guid isPermaLink="false">8083@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hey Ben&#60;/p&#62;
&#60;p&#62;Thanks for your reply and clarification.&#60;/p&#62;
&#60;p&#62;I have two more questions. I am trying to compare the pressure value from the simulation with the measurement and they are not quite agreeing. I am reading lower with the simulation than expected. I am not confident that I set the input pressure (p0) correctly in the code. I have tried to input pressure and velocity and compare the results as well. &#60;/p&#62;
&#60;p&#62;1) One method I set the p0 as follow (power is in watt)&#60;/p&#62;
&#60;p&#62;%-----------------input pressure est&#60;br /&#62;
pwr=2;Z0=1.5*1e6;area=1.35e-3*1.25e-3*6144;&#60;br /&#62;
p0=sqrt(pwr*Z0/area); %---estimate of p0&#60;br /&#62;
u0=p0/Z0; %----estimate of u0&#60;/p&#62;
&#60;p&#62; source.p_mask = tx_mask;&#60;br /&#62;
 ampc = (p0)*ones(size(phase));&#60;br /&#62;
 source.p_mode = 'dirichlet';&#60;/p&#62;
&#60;p&#62;source.p = createCWSignals(t, freq, ampc,focDistRad, 0);&#60;/p&#62;
&#60;p&#62;2) Using velocity approach as the source:&#60;/p&#62;
&#60;p&#62;source.u_mask = tx_mask;&#60;br /&#62;
ampc_u=u0*ones(size(phase));&#60;br /&#62;
source.u_mode = 'dirichlet';&#60;/p&#62;
&#60;p&#62;source.uz = createCWSignals(t, freq, ampc_u,focDistRad , 0);&#60;/p&#62;
&#60;p&#62;Two issues that I have is that 1) Max pressure from approach 1 &#38;amp; 2 are different 2) Max pressure from simulation seems to be lower than measurement.&#60;/p&#62;
&#60;p&#62;I appreciate if you let me know your thoughts on this.&#60;/p&#62;
&#60;p&#62;Thanks&#60;br /&#62;
Zahra
&#60;/p&#62;</description>
		</item>
		<item>
			<title>bencox on "Using source.p to specify pressure distribution"</title>
			<link>http://www.k-wave.org/forum/topic/using-sourcep-to-specify-pressure-distribution#post-7922</link>
			<pubDate>Fri, 13 Nov 2020 00:32:18 +0000</pubDate>
			<dc:creator>bencox</dc:creator>
			<guid isPermaLink="false">7922@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi Zahra, &#60;/p&#62;
&#60;p&#62;The scaling factor of &#60;code&#62;(2 * c0 * dt / dx)&#60;/code&#62; is exact for one-dimensional propagation, ie. a plane wave propagating in the x direction, but not for higher dimensions. In those cases it's a bit less straightforward. As we tried (!) to explain above, because of the numerical method that k-Wave is based on, when it takes an input 'source.p', it effectively multiplies each sample of that source with the band-limited interpolant, BLI - roughly &#60;code&#62;sinc(pi*x/dx)sinc(pi*y/dy)sinc(pi*z/dz)&#60;/code&#62; - centred at the source point. Unlike the source point, the BLI is distributed in space, so when it propagates - which is what happens when a timestep is taken - there is a non-zero value of the field at the source point. The next source sample then adds to that existing field, and so on, and the result is that the effective amplitude of the wave generated by &#60;code&#62;source.p&#60;/code&#62; is different from the input &#60;code&#62;source.p&#60;/code&#62;. Furthermore, because the BLI depends on the grid spacing the amplitude depends on the grid spacing. &#60;/p&#62;
&#60;p&#62;One way to avoid this is to set &#60;code&#62;source.p_mode = &#38;#39;dirichlet&#38;#39;&#60;/code&#62;, which enforces the values of &#60;code&#62;source.p&#60;/code&#62; at the source points, but in this case the source points also act as scatterers while they are transmitting a signal, which can be a nuisance in some circumstances. &#60;/p&#62;
&#60;p&#62;A pragmatic alternative that I have used is to note how the amplitude scales with the grid size and incorporate that factor, eg. dz, into the expression for the source amplitude, so that as you change grid resolution the source amplitude remains constant.&#60;/p&#62;
&#60;p&#62;Hope that helps a bit.&#60;/p&#62;
&#60;p&#62;Best wishes&#60;br /&#62;
Ben
&#60;/p&#62;</description>
		</item>
		<item>
			<title>zahrat on "Using source.p to specify pressure distribution"</title>
			<link>http://www.k-wave.org/forum/topic/using-sourcep-to-specify-pressure-distribution#post-7886</link>
			<pubDate>Tue, 20 Oct 2020 18:53:32 +0000</pubDate>
			<dc:creator>zahrat</dc:creator>
			<guid isPermaLink="false">7886@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hello,&#60;/p&#62;
&#60;p&#62;I am having scaling issue as well and  I am not sure if I understand your explanation correctly.&#60;br /&#62;
I am simulating an ultrasound phased array, propagating along the z axis.&#60;/p&#62;
&#60;p&#62;My source is generated at follow:&#60;/p&#62;
&#60;p&#62;ampc = (5)*ones(size(phase));&#60;br /&#62;
source.p = createCWSignals(t, freq, ampc,focDistRad, 0);%&#60;/p&#62;
&#60;p&#62;When I keep dx,dy=0.6 mm, sos=1485 fixed and just change dz for instance from .5mm to 0.25 mm, I am noticing the the output pressure max amp is reported double which I doubt it is due to the finer resolution.&#60;/p&#62;
&#60;p&#62;I get the dt from &#34;maketime&#34; fucntion (kgrid.makeTime(medium.sound_speed, 0.3)).&#60;/p&#62;
&#60;p&#62;You are mentioning that the scaling factor for the input (ie ampc) should be the inverse of (2 * c0 * dt / dz) while would nt it be the same number (ie .3) in my case (if I am using &#34;maketime&#34; function since dt= 0.3*sos/dz).&#60;/p&#62;
&#60;p&#62;Thanks for your help inadvance.&#60;br /&#62;
Zahra
&#60;/p&#62;</description>
		</item>
		<item>
			<title>RuiLiu on "reflection coefficient"</title>
			<link>http://www.k-wave.org/forum/topic/reflection-coefficient#post-7766</link>
			<pubDate>Mon, 24 Aug 2020 05:06:17 +0000</pubDate>
			<dc:creator>RuiLiu</dc:creator>
			<guid isPermaLink="false">7766@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi, we are doing the similar staff for kwave, I am also dealing the reflection issue. Please let me know if you want a discussion and you could leave wechat number below. Thanks.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Bradley Treeby on "reflection coefficient"</title>
			<link>http://www.k-wave.org/forum/topic/reflection-coefficient#post-7746</link>
			<pubDate>Wed, 19 Aug 2020 15:01:23 +0000</pubDate>
			<dc:creator>Bradley Treeby</dc:creator>
			<guid isPermaLink="false">7746@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi ljx199,&#60;/p&#62;
&#60;p&#62;As far as I can tell, the two sensor positions are at different distances from the scattering object, so the amplitudes will be difference due to geometric spreading.&#60;/p&#62;
&#60;p&#62;Also, keep in mind that the scattering profile when you have a density perturbation is not uniform with angle. The expression for the scattered wave as a function of angle is in quite a few text books dating all the way back to Rayleigh Theory of Sound (vol 2. Scattering from a small sphere).&#60;/p&#62;
&#60;p&#62;Hope that helps,&#60;/p&#62;
&#60;p&#62;Brad.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>ljx199 on "reflection coefficient"</title>
			<link>http://www.k-wave.org/forum/topic/reflection-coefficient#post-7731</link>
			<pubDate>Mon, 10 Aug 2020 14:28:22 +0000</pubDate>
			<dc:creator>ljx199</dc:creator>
			<guid isPermaLink="false">7731@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi,&#60;/p&#62;
&#60;p&#62;I am using k-wave fro NDT simulation. In order to simulate a defect, I set up a circular region inside the object under test, whose sound velocity and density are different from the material under test. But I found in the simulation that the reflection coefficients of different angles are different. Is there any way to make the reflection coefficient the same in all directions as the sound wave travels to the defect? The echo signal received at two sensor positions does not satisfy (1/sqrt(r1))/(1/sqrt(r2)). So I think it's due to different reflectivity in different directions. Below is my program. Looking for ward your reply. Thank you very much.&#60;/p&#62;
&#60;p&#62;%Echo data obtained by FMC(full matrix capture) &#60;/p&#62;
&#60;p&#62;% simulation settings&#60;br /&#62;
clearvars;&#60;br /&#62;
clc;&#60;br /&#62;
clear;&#60;/p&#62;
&#60;p&#62;% simulation settings&#60;br /&#62;
DATA_CAST = 'single';&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE K-WAVE GRID&#60;br /&#62;
% =========================================================================&#60;br /&#62;
% set the size of the perfectly matched layer (PML)&#60;br /&#62;
PML_X_SIZE = 20;            % [grid points]&#60;br /&#62;
PML_Y_SIZE = 20;            % [grid points]&#60;/p&#62;
&#60;p&#62;% set total number of grid points not including the PML&#60;br /&#62;
Nx = 512 - 2*PML_X_SIZE;    % [grid points]&#60;br /&#62;
Ny = 512 - 2*PML_Y_SIZE;    % [grid points]&#60;/p&#62;
&#60;p&#62;% calculate the spacing between the grid points&#60;br /&#62;
dx = 0.1e-3;                % [m]&#60;br /&#62;
dy = dx;                    % [m]&#60;/p&#62;
&#60;p&#62;% create the k-space grid&#60;br /&#62;
kgrid = kWaveGrid(Nx, dx, Ny, dy);&#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 = 6200;      % [m/s]&#60;br /&#62;
medium.density = 2700;          % [kg/m^3]&#60;/p&#62;
&#60;p&#62;% create the time array&#60;br /&#62;
t_end = 10e-6;                  % [s]&#60;br /&#62;
kgrid.makeTime(medium.sound_speed,[], t_end);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE INPUT SIGNAL Properities&#60;br /&#62;
% =========================================================================&#60;br /&#62;
% define properties of the input signal&#60;br /&#62;
source_strength = 1e6;          % [Pa]&#60;br /&#62;
tone_burst_freq = 5e6;        % [Hz]&#60;br /&#62;
tone_burst_cycles = 5;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE Excitation Source&#60;br /&#62;
% =========================================================================&#60;br /&#62;
N_element = 32;                  %定义阵元数目&#60;br /&#62;
element_width = 4;               %定义阵元宽度为4个网格点，即0.4mm&#60;br /&#62;
kerf = 1;                        %定义阵元间隙为1个网格点，即0.1mm&#60;br /&#62;
pitch = element_width + kerf;    %定义阵元间距&#60;br /&#62;
% calculate the width of the transducer in grid points&#60;br /&#62;
transducer_width = N_element * element_width ...&#60;br /&#62;
    + (N_element - 1) * kerf;&#60;br /&#62;
x_start = round(Ny/2 - transducer_width/2);   %x的起始网格点&#60;br /&#62;
y_start = 1;                           %y的起始网格点&#60;br /&#62;
source_mask = zeros(Nx, Ny, N_element);         %定义与阵元数目相同的蒙版&#60;br /&#62;
for i = 1 : N_element&#60;br /&#62;
    x_temp = x_start + pitch * (i-1);&#60;br /&#62;
    x_element = (x_temp :  x_temp + element_width -1);&#60;br /&#62;
    source_mask(y_start,x_element, i) = 1;&#60;br /&#62;
end&#60;br /&#62;
source.p_mask = source_mask(:, :, 16);   %仅一个阵元被激励，获取全矩阵捕获回波信号&#60;br /&#62;
input_signal = toneBurst(1/kgrid.dt, tone_burst_freq, tone_burst_cycles);&#60;br /&#62;
input_signal = (source_strength ./ (6200 * 2700)) .* input_signal;&#60;br /&#62;
source.p = source_strength * input_signal; &#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE Sensor&#60;br /&#62;
% =========================================================================&#60;br /&#62;
% define a single sensor point&#60;br /&#62;
% sensor.mask = zeros(Nx, Ny);&#60;br /&#62;
% sensor.mask(Nx/4, Ny/2) = 1;&#60;br /&#62;
% sensor.mask(2*Nx/4, Ny/2) = 1;&#60;br /&#62;
sensor.mask = source_mask(:, :, 1) + source_mask(:, :, 16);&#60;br /&#62;
% define the acoustic parameters to record&#60;br /&#62;
sensor.record = {'p'};&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINE THE Defect&#60;br /&#62;
% =========================================================================&#60;br /&#62;
%define a circle for the region of interesting&#60;br /&#62;
sound_speed_map = ones(Nx, Ny);&#60;br /&#62;
density_map = ones(Nx, Ny);&#60;br /&#62;
radius = 1.5e-3;      % [m]&#60;br /&#62;
arc_angle = 2*pi;&#60;br /&#62;
x = Nx * dx;&#60;br /&#62;
y = Ny * dy;&#60;br /&#62;
x_center = x/2;&#60;br /&#62;
y_center = y/2;&#60;br /&#62;
scattering_region1 = makeCircle(Nx, Ny, Nx/2, Ny/2, round(radius/dx), arc_angle);&#60;br /&#62;
sound_speed_map(scattering_region1 == 1) = 1540;&#60;br /&#62;
sound_speed_map(scattering_region1 == 0) = 6200;&#60;br /&#62;
density_map(scattering_region1 == 1) = 1000;&#60;br /&#62;
density_map(scattering_region1 == 0) = 2700;&#60;/p&#62;
&#60;p&#62;medium.sound_speed = sound_speed_map;&#60;br /&#62;
medium.density = density_map;&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% Calculator the pressure&#60;br /&#62;
% =========================================================================&#60;br /&#62;
% set the input settings&#60;br /&#62;
input_args = { 'PMLInside', false, 'PlotPML', false, 'PMLSize', [PML_X_SIZE, PML_Y_SIZE], ...&#60;br /&#62;
    'DataCast', DATA_CAST, 'PlotScale', [-1/20, 1/20] * source_strength};&#60;/p&#62;
&#60;p&#62;% run the simulation&#60;br /&#62;
sensor_data = kspaceFirstOrder2D(kgrid, medium, source, sensor, input_args{:});
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Bradley Treeby on "Simulation of Ultrasonic Testing (Borehole in Solid)"</title>
			<link>http://www.k-wave.org/forum/topic/simulation-of-ultrasonic-testing-borehole-in-solid#post-6735</link>
			<pubDate>Tue, 29 Jan 2019 22:36:57 +0000</pubDate>
			<dc:creator>Bradley Treeby</dc:creator>
			<guid isPermaLink="false">6735@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi Rola, &#60;/p&#62;
&#60;p&#62;No, keep the velocity the same. The sound speeds are much closer in magnitude than the density (factor of 5 vs 1000).&#60;/p&#62;
&#60;p&#62;Brad.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Rola on "Simulation of Ultrasonic Testing (Borehole in Solid)"</title>
			<link>http://www.k-wave.org/forum/topic/simulation-of-ultrasonic-testing-borehole-in-solid#post-6709</link>
			<pubDate>Tue, 15 Jan 2019 19:18:22 +0000</pubDate>
			<dc:creator>Rola</dc:creator>
			<guid isPermaLink="false">6709@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi Brad and Ben, &#60;/p&#62;
&#60;p&#62;If I inflate the air density artificially by a factor of 100, do I need to inflate the inflate the air velocity too?&#60;/p&#62;
&#60;p&#62;Best
&#60;/p&#62;</description>
		</item>
		<item>
			<title>bencox on "Simulation of Ultrasonic Testing (Borehole in Solid)"</title>
			<link>http://www.k-wave.org/forum/topic/simulation-of-ultrasonic-testing-borehole-in-solid#post-6687</link>
			<pubDate>Sun, 09 Dec 2018 23:28:27 +0000</pubDate>
			<dc:creator>bencox</dc:creator>
			<guid isPermaLink="false">6687@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;HI fabwo, &#60;/p&#62;
&#60;p&#62;You're putting in a toneburst at 40 MHz, so it's not surprising it's changing when you filter at 100 kHz or so. Perhaps use the &#60;code&#62;...&#38;#39;PlotSpectrums&#38;#39;, true)&#60;/code&#62; option in &#60;code&#62;filterTimeSeries&#60;/code&#62; to see the spectrum of your signal before and after filtering.&#60;/p&#62;
&#60;p&#62;If you are only interested in propagation in one direction, then could you use the 1D code? It would be much more computationally efficient.&#60;/p&#62;
&#60;p&#62;Best wishes,&#60;br /&#62;
Ben
&#60;/p&#62;</description>
		</item>
		<item>
			<title>fabwo on "Simulation of Ultrasonic Testing (Borehole in Solid)"</title>
			<link>http://www.k-wave.org/forum/topic/simulation-of-ultrasonic-testing-borehole-in-solid#post-6574</link>
			<pubDate>Fri, 31 Aug 2018 18:01:45 +0000</pubDate>
			<dc:creator>fabwo</dc:creator>
			<guid isPermaLink="false">6574@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi Ben,&#60;/p&#62;
&#60;p&#62;I adjusted my grid dimensions in x-direction (wave propagation is only in x-direction), shortened the time steps and tried different tone burst frequencies.&#60;br /&#62;
Unfortunately I didn't get better results. I also have some questions about the k-wave filter function.&#60;/p&#62;
&#60;p&#62;My grid dimension without the PML are Nx=1004, Ny=16, Nz=16 with dx=2.5e-5, dy=1e-3, dz=1e-3&#60;br /&#62;
My time steps are created using the function kgrid.makeTime with cfl=0.3, t_end=2e-5. This leads to 8002 time steps in the kgrid.t_array with 2.5e-9 seconds apart, but I have also tried shorter ones (e.g. dt=1e-9).&#60;br /&#62;
I modelled time varying stress at each of the source positions only in xx using the toneBurst function.&#60;br /&#62;
toneBurst(1/kgrid.dt, tone_burst_freq, tone_burst-cycles) with tone_burst_freq=4e7 (4Mhz), tone_burst-cycles=3&#60;/p&#62;
&#60;p&#62;The filterTimeSeries function uses by default 3 PPW of the largest grid point spacing to compute the cutoff frequency. Is there a way to consider only the grid spacing in x-direction (because it is the only direction the waves are propagating)?&#60;br /&#62;
At the moment my filter cutoff frequency is 114.3333 kHz (3PPW). But somehow this filter changes even a tone burst with a frequency of 100 kHz. The amplitude of the tone burst is reduces by a factor of 100. How is this possible?&#60;br /&#62;
When I simulated with a tone burst of 100 kHz the pressure in sensor_data still blows up. Do you know where my mistakes are?&#60;/p&#62;
&#60;p&#62;&#60;a href=&#34;https://ibb.co/iQfJee&#34; rel=&#34;nofollow&#34;&#62;https://ibb.co/iQfJee&#60;/a&#62;&#60;br /&#62;
&#60;a href=&#34;https://ibb.co/cOZdee&#34; rel=&#34;nofollow&#34;&#62;https://ibb.co/cOZdee&#60;/a&#62;&#60;br /&#62;
&#60;a href=&#34;https://ibb.co/cRx9kK&#34; rel=&#34;nofollow&#34;&#62;https://ibb.co/cRx9kK&#60;/a&#62;&#60;br /&#62;
&#60;a href=&#34;https://ibb.co/nD9dee&#34; rel=&#34;nofollow&#34;&#62;https://ibb.co/nD9dee&#60;/a&#62;&#60;/p&#62;
&#60;p&#62;Best wishes,&#60;br /&#62;
Fabian&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% 3D ULTRASONIC SIMULATION - BOREHOLE IN A FRP COMPONENT&#60;br /&#62;
% CIRCULAR TRANSDUCER&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% DEFINITION OF THE K-WAVE GRID&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% PML size (perfectly matched layer) on the outside of the k-wave grid&#60;br /&#62;
% Grid points == GP&#60;br /&#62;
PML_X_SIZE = 10;           % [GP]&#60;br /&#62;
PML_Y_SIZE = 8;            % [GP]&#60;br /&#62;
PML_Z_SIZE = 8;            % [GP]&#60;br /&#62;
PML_SIZE = [PML_X_SIZE, PML_Y_SIZE, PML_Z_SIZE];&#60;/p&#62;
&#60;p&#62;% Computational grid: number of GP without PML&#60;br /&#62;
% The number of GP (computational grid + PML) in each dimension should be&#60;br /&#62;
% given by a power of 2 or have a small primefactor because of&#60;br /&#62;
% computational advantages for later FFT use.&#60;br /&#62;
Nx = 1024 - 2*PML_X_SIZE;   % [GP]&#60;br /&#62;
Ny = 32 - 2*PML_Y_SIZE;     % [GP]&#60;br /&#62;
Nz = 32 - 2*PML_Z_SIZE;     % [GP]&#60;/p&#62;
&#60;p&#62;% Distance between GP&#60;br /&#62;
dx = 2.5e-5;                  % [m]&#60;br /&#62;
dy = 1e-3;                    % [m]&#60;br /&#62;
dz = 1e-3;                    % [m]&#60;/p&#62;
&#60;p&#62;% Creation of the k-space grid&#60;br /&#62;
kgrid = kWaveGrid(Nx, dx, Ny, dy, Nz, dz);&#60;/p&#62;
&#60;p&#62;%% ========================================================================&#60;br /&#62;
% TEST SET-UP &#38;amp; MEDIUM PARAMETER &#38;amp; TIME ARRAY&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% Test set-up&#60;br /&#62;
frp_thickness = 5.5e-3;        % [m] FRP plate thickness&#60;br /&#62;
hole_diameter = 4e-3;          % [m] borehole diameter&#60;br /&#62;
hole_depth = 2e-3;             % [m] borehole depth&#60;br /&#62;
wedge_diameter = 6e-3;         % [m] PMMA wedge diameter&#60;br /&#62;
wedge_length = 11e-3;          % [m] PMMA wedge length&#60;/p&#62;
&#60;p&#62;% Transformation [m] into [GP]&#60;br /&#62;
frp_thickness_GP = single(frp_thickness / dx);      % [GP] plate thickness&#60;br /&#62;
hole_radius_GP = single((hole_diameter/2) / dy);    % [GP] borehole radius&#60;br /&#62;
hole_depth_GP = single(hole_depth / dx);            % [GP] borehole depth&#60;br /&#62;
wedge_radius_GP = single((wedge_diameter/2) / dy);  % [GP] wedge radius&#60;br /&#62;
wedge_length_GP = single(wedge_length / dx);        % [GP] wedge lenth&#60;/p&#62;
&#60;p&#62;%% Medium properties&#60;br /&#62;
c_gel = 1500;       % [m/s] speed of sound gel&#60;br /&#62;
rho_gel = 1002;     % [kg/m^3] density gel&#60;br /&#62;
c_air = 343;        % [m/s] speed of sound air&#60;br /&#62;
% The simulation is unstable for the correct density of air (1.2 [kg/m^3])&#60;br /&#62;
% because of the very large impedance contrast. To fix this problem the air&#60;br /&#62;
% density is artificially inflated by factor 100. The reflection&#60;br /&#62;
% coefficient is still close to 1.&#60;br /&#62;
rho_air = 120;      % [kg/m^3] density air&#60;br /&#62;
cp_FRP = 3000;      % [m/s] speed of sound FRP Compression (longitudinal)&#60;br /&#62;
cs_FRP = 3000;      % [m/s] speed of sound FRP Shear (transversal)&#60;br /&#62;
rho_FRP = 1500;     % [kg/m^3] density FRP&#60;br /&#62;
cp_PMMA = 2700;     % [m/s] speed of sound PMMA Compression (longitudinal)&#60;br /&#62;
cs_PMMA = 1300;     % [m/s] speed of sound PMMA Shear (transversal)&#60;br /&#62;
rho_PMMA = 1180;    % [kg/m^3] density PMMA&#60;/p&#62;
&#60;p&#62;%% Medium model:&#60;br /&#62;
% Creating matrices with the dimension of the k-space grid for the density&#60;br /&#62;
% and the sound speed of longitudinal and transversal waves.&#60;/p&#62;
&#60;p&#62;% Initializing medium model matrices with air&#60;br /&#62;
medium.sound_speed_compression = c_air * ones(Nx, Ny, Nz); % [m/s]&#60;br /&#62;
medium.sound_speed_shear = c_air * ones(Nx, Ny, Nz);       % [m/s]&#60;br /&#62;
medium.density = rho_air * ones(Nx, Ny, Nz);               % [kg/m^3]&#60;/p&#62;
&#60;p&#62;% FRP plate&#60;br /&#62;
for m = (Nx - frp_thickness_GP) : Nx&#60;br /&#62;
    medium.sound_speed_compression(m,:,:) = cp_FRP;     % [m/s]&#60;br /&#62;
    medium.sound_speed_shear(m,:,:) = cs_FRP;           % [m/s]&#60;br /&#62;
    medium.density(m,:,:) = rho_FRP;                    % [kg/m^3]&#60;br /&#62;
end&#60;/p&#62;
&#60;p&#62;% Defects in the FRP plate (1 borehole)&#60;br /&#62;
disc2 = makeDisc(Ny, Nz, Ny/2, Nz/2, hole_radius_GP);	% position, radius&#60;br /&#62;
flaw1 = repmat(disc2, [1, 1, Nx]);      % 3D disc extrusion&#60;br /&#62;
flaw1 = permute (flaw1, [3,1,2]);       % rearranging dimensions&#60;br /&#62;
for n = 1 : (Nx - hole_depth_GP - 1)	% borehole model using 0 and 1&#60;br /&#62;
    flaw1(n,:,:) = 0;&#60;br /&#62;
end&#60;br /&#62;
% Filling the flaw model with air properties in the medium matrices&#60;br /&#62;
medium.sound_speed_compression(flaw1==1) = c_air;     % [m/s]&#60;br /&#62;
medium.sound_speed_shear(flaw1==1) = c_air;           % [m/s]&#60;br /&#62;
medium.density(flaw1==1) = rho_air;                   % [kg/m^3]&#60;/p&#62;
&#60;p&#62;% Gel layer between FRP plate and PMMA wedge&#60;br /&#62;
gel_layer1 = (Nx - frp_thickness_GP - 1);	% [GP] gel layer position&#60;br /&#62;
medium.sound_speed_compression(gel_layer1,:,:) = c_gel; % [m/s]&#60;br /&#62;
medium.sound_speed_shear(gel_layer1,:,:) = c_air;       % [m/s]&#60;br /&#62;
medium.density(gel_layer1,:,:) = rho_gel;               % [kg/m^3]&#60;/p&#62;
&#60;p&#62;% PMMA wedge&#60;br /&#62;
disc1 = makeDisc(Ny, Nz, Ny/2, Nz/2, wedge_radius_GP);	% position, radius&#60;br /&#62;
wedge = repmat(disc1, [1, 1, Nx]);              % 3D disc extrusion&#60;br /&#62;
wedge = permute (wedge, [3,1,2]);               % rearranging dimensions&#60;br /&#62;
for h = gel_layer1 : Nx       % PMMA model using 0 and 1&#60;br /&#62;
    wedge(h,:,:) = 0;&#60;br /&#62;
end&#60;br /&#62;
for k = 1 : (gel_layer1 - wedge_length_GP)&#60;br /&#62;
    wedge(k,:,:) = 0;&#60;br /&#62;
end&#60;br /&#62;
% Filling the wedge model with PMMA properties in the medium matrices&#60;br /&#62;
medium.sound_speed_compression(wedge==1) = cp_PMMA;   % [m/s]&#60;br /&#62;
medium.sound_speed_shear(wedge==1) = cs_PMMA;         % [m/s]&#60;br /&#62;
medium.density(wedge==1) = rho_PMMA;                  % [kg/m^3]&#60;/p&#62;
&#60;p&#62;% Gel layer above PMMA wedge (transducer position)&#60;br /&#62;
gel_layer2 = ((gel_layer1 - wedge_length_GP) - 1);	% [GP] gel layer position&#60;br /&#62;
medium.sound_speed_compression(gel_layer2,:,:) = c_gel; % [m/s]&#60;br /&#62;
medium.sound_speed_shear(gel_layer2,:,:) = c_air;       % [m/s]&#60;br /&#62;
medium.density(gel_layer2,:,:) = rho_gel;               % [kg/m^3]&#60;/p&#62;
&#60;p&#62;%% Time array&#60;br /&#62;
cfl = 0.3;                    % default = 0.3&#60;br /&#62;
t_end = 2e-5;                 % [s]&#60;br /&#62;
kgrid.makeTime(max(medium.sound_speed_compression,medium.sound_speed_shear), cfl, t_end);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% INPUT SIGNAL&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% Tone burst&#60;br /&#62;
tone_burst_freq = 4e7;    % [Hz]&#60;br /&#62;
tone_burst_cycles = 3;&#60;br /&#62;
% Time varying stress at each of the source positions&#60;br /&#62;
source_prefilter = toneBurst(1/kgrid.dt, tone_burst_freq, tone_burst_cycles);&#60;br /&#62;
source.syy = 0;&#60;br /&#62;
source.szz = 0;&#60;br /&#62;
source.sxy = 0;&#60;br /&#62;
source.sxz = 0;&#60;br /&#62;
source.syz = 0;&#60;/p&#62;
&#60;p&#62;%% Filter the source to remove high frequencies not supported by the grid&#60;br /&#62;
source.sxx = filterTimeSeries(kgrid, medium, source_prefilter);&#60;br /&#62;
source.syy = filterTimeSeries(kgrid, medium, source.syy);&#60;br /&#62;
source.szz = filterTimeSeries(kgrid, medium, source.szz);&#60;br /&#62;
source.sxy = filterTimeSeries(kgrid, medium, source.sxy);&#60;br /&#62;
source.sxz = filterTimeSeries(kgrid, medium, source.sxz);&#60;br /&#62;
source.syz = filterTimeSeries(kgrid, medium, source.syz);&#60;/p&#62;
&#60;p&#62;% =========================================================================&#60;br /&#62;
% TRANSDUCER DEFINITION [SOURCE AND SENSOR]&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% Transducer model using 0 and 1&#60;br /&#62;
% Source&#60;br /&#62;
source.s_mask = zeros(Nx, Ny, Nz);&#60;br /&#62;
source.s_mask(1,:,:) = disc1;       % same dimensions as the wedge&#60;br /&#62;
% Sensor&#60;br /&#62;
sensor.mask = source.s_mask;&#60;/p&#62;
&#60;p&#62;%% ========================================================================&#60;br /&#62;
% RUN THE SIMULATION&#60;br /&#62;
% =========================================================================&#60;/p&#62;
&#60;p&#62;% Assign additional input options&#60;br /&#62;
% place PML outside of the computational grid&#60;br /&#62;
input_args = { ...&#60;br /&#62;
    'PMLInside', false, 'DisplayMask', sensor.mask, 'PlotPML', false, ...&#60;br /&#62;
    'PMLSize', PML_SIZE};&#60;/p&#62;
&#60;p&#62;% Run the simulation&#60;br /&#62;
sensor_data = pstdElastic3D(kgrid, medium, source, sensor, input_args{:});&#60;br /&#62;
save('Workspace_SmallGrid.mat');
&#60;/p&#62;</description>
		</item>
		<item>
			<title>bencox on "Simulation of Ultrasonic Testing (Borehole in Solid)"</title>
			<link>http://www.k-wave.org/forum/topic/simulation-of-ultrasonic-testing-borehole-in-solid#post-6556</link>
			<pubDate>Thu, 16 Aug 2018 20:45:50 +0000</pubDate>
			<dc:creator>bencox</dc:creator>
			<guid isPermaLink="false">6556@http://www.k-wave.org/forum/</guid>
			<description>&#60;p&#62;Hi Fabian, &#60;/p&#62;
&#60;p&#62;It's not an instability problem, in that using too high a source frequency won't lead to the simulation blowing up. However, if you use a source with a frequency higher than the grid can support, then most of the energy will just not propagate anywhere. It's lost. Look at the amplitude of your source before and after you filter it to remove the frequencies not supported on the grid. It is almost set to zero. So I suspect you're just seeing an artifact rather than a real signal. Perhaps try a lower frequency source and see what happens. &#60;/p&#62;
&#60;p&#62;Best wishes,&#60;br /&#62;
Ben
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
