Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
ee3f46b
Create kspaceFirstOrder1D.py
djps Dec 4, 2025
2cbbfcf
Add 1D simulation example folder
djps Dec 4, 2025
00fa6c6
Add files via upload
djps Dec 4, 2025
e7265c5
Rename 1d-demo-simulation to ivp_1D_simulation
djps Dec 4, 2025
23d0d52
Created using Colab
djps Dec 4, 2025
9765aea
include extra file and tidy example
djps Dec 4, 2025
9b2d95c
add into init
djps Dec 4, 2025
e78dcaa
imports
djps Dec 4, 2025
05be993
formatting
djps Dec 4, 2025
5aaa346
update ipynb as test colab is working
djps Dec 4, 2025
b27d723
Created using Colab
djps Dec 4, 2025
8284566
Update pyproject.toml
djps Dec 4, 2025
3fd2e97
Bump version from 0.4.1 to 0.4.2
djps Dec 4, 2025
b71fbec
Created using Colab. Refactoring
djps Dec 5, 2025
1d42993
Add create_storage_variables and improve sensor data handling
djps Jan 7, 2026
f78fb00
To pass failing tests, repo path
djps Jan 8, 2026
5751533
update to ignore windowing with single length
djps Jan 8, 2026
78405e3
ruff fixes and import path for notebook
djps Jan 8, 2026
a85355f
revert version back to current one
djps Jan 8, 2026
e6f7569
clean up and add cupy import
djps Jan 8, 2026
1ede056
first pass at gpu implementation
djps Jan 9, 2026
cdff8f9
ruff fixes
djps Jan 9, 2026
924457a
minor optimizations and add readme to example.
djps Jan 9, 2026
c880435
Fix sensor data extraction and k-space method issues
djps Jan 11, 2026
ef39cb8
some fixes
djps Jan 12, 2026
c4fe6c2
Update kspaceFirstOrder1D.py
djps Jan 12, 2026
5617355
more fixes
djps Jan 12, 2026
a6e9bd7
suggested fixes
djps Jan 12, 2026
4c34d49
suggested fixes
djps Jan 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions examples/ivp_1D_simulation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Simulations In One Dimension Example

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/waltsims/k-wave-python/blob/HEAD/examples/ivp_1D_simulation/ivp_1D_simulation.ipynb)

This example provides a simple demonstration for the simulation and detection of the pressure field generated by an initial pressure distribution within a one-dimensional heterogeneous propagation medium.

To read more, visit the [original example page](http://www.k-wave.org/documentation/example_ivp_1D_simulation.php).
214 changes: 214 additions & 0 deletions examples/ivp_1D_simulation/ivp_1D_simulation.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "RQYRmOfG27FV"
},
"source": [
"First install the package using the latest version."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "5bq8_I2z29l6"
},
"outputs": [],
"source": [
"%%capture\n",
"!pip install k-wave-python"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7lktiAv5XtsS"
},
"source": [
"Now import dependencies, and parts of library which are required."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "VCcwZsQ2ASoj"
},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"from kwave.data import Vector\n",
"from kwave.kgrid import kWaveGrid\n",
"from kwave.kmedium import kWaveMedium\n",
"from kwave.ksensor import kSensor\n",
"from kwave.ksource import kSource\n",
"from kwave.kspaceFirstOrder1D import kspace_first_order_1D\n",
"from kwave.options.simulation_execution_options import SimulationExecutionOptions\n",
"from kwave.options.simulation_options import SimulationOptions"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xUqsDgayASoj"
},
"source": [
"Set parameters to build the grid"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "FwbGsg_gASok"
},
"outputs": [],
"source": [
"# create the computational grid\n",
"Nx: int = 512 # number of grid points in the x (row) direction\n",
"dx: float = 0.05e-3 # grid point spacing in the x direction [m]\n",
"\n",
"grid_size_points = Vector([Nx, ])\n",
"grid_spacing_meters = Vector([dx, ])\n",
"\n",
"# create the k-space grid\n",
"kgrid = kWaveGrid(grid_size_points, grid_spacing_meters)\n",
"\n",
"# define the properties of the propagation medium\n",
"sound_speed = 1500.0 * np.ones((Nx, 1)) # [m/s]\n",
"sound_speed[:np.round(Nx / 3).astype(int) - 1] = 2000.0\t # [m/s]\n",
"density = 1000.0 * np.ones((Nx, 1)) # [kg/m^3]\n",
"density[np.round(4 * Nx / 5).astype(int) - 1:] = 1500.0 # [kg/m^3]\n",
"medium = kWaveMedium(sound_speed=sound_speed, density=density)\n",
"\n",
"# set the simulation time to capture the reflections\n",
"c_max = np.max(medium.sound_speed.flatten()) # [m/s]\n",
"t_end = 2.5 * kgrid.x_size / c_max # [s]\n",
"\n",
"# define the time array\n",
"kgrid.makeTime(c_max, t_end=t_end)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "misFfiLaASok"
},
"source": [
"Build source and sensor"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "maEowzD6ASok"
},
"outputs": [],
"source": [
"# Create the source object\n",
"source = kSource()\n",
"\n",
"# create initial pressure distribution using a smoothly shaped sinusoid\n",
"x_pos: int = 280 # [grid points]\n",
"width: int = 100 # [grid points]\n",
"height: int = 1 # [au]\n",
"p0 = np.linspace(0.0, 2.0 * np.pi, width + 1)\n",
"\n",
"part1 = np.zeros(x_pos).astype(float)\n",
"part2 = (height / 2.0) * np.sin(p0 - np.pi / 2.0) + (height / 2.0)\n",
"part3 = np.zeros(Nx - x_pos - width - 1).astype(float)\n",
"source.p0 = np.concatenate([part1, part2, part3])\n",
"\n",
"# create a Cartesian sensor mask recording the pressure\n",
"sensor = kSensor()\n",
"sensor.record = [\"p\"]\n",
"\n",
"# this hack is needed to ensure that the sensor is in [1,2] dimensions\n",
"mask = np.array([-10e-3, 10e-3]) # [m]\n",
"mask = mask[:, np.newaxis].T\n",
"sensor.mask = mask"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ZSmPpm6X3fm5"
},
"source": [
"Set options and run simulation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "BiFT0YEE3fyE"
},
"outputs": [],
"source": [
"# define the simulation options\n",
"simulation_options = SimulationOptions(data_cast=\"off\", save_to_disk=False)\n",
"execution_options = SimulationExecutionOptions(is_gpu_simulation=True)\n",
"\n",
"# run the simulation\n",
"sensor_data = kspace_first_order_1D(kgrid, source, sensor, medium, simulation_options=simulation_options, execution_options=execution_options)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "a4WRzAZ_ASol"
},
"source": [
"Visualisations"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "s4ZO890kASol"
},
"outputs": [],
"source": [
"# plot the recorded time signals\n",
"_, ax1 = plt.subplots()\n",
"ax1.plot(sensor_data['p'][0, :], 'b-')\n",
"ax1.plot(sensor_data['p'][1, :], 'r-')\n",
"ax1.grid(True)\n",
"ax1.set_ylim(-0.1, 0.7)\n",
"ax1.set_ylabel('Pressure')\n",
"ax1.set_xlabel('Time Step')\n",
"ax1.legend(['Sensor Position 1', 'Sensor Position 2'])\n",
"plt.show()"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
94 changes: 94 additions & 0 deletions examples/ivp_1D_simulation/ivp_1D_simulation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
"""
Simulations In One Dimension Example

This example provides a simple demonstration of using k-Wave for the
simulation and detection of the pressure field generated by an initial
pressure distribution within a one-dimensional heterogeneous propagation
medium. It builds on the Homogeneous Propagation Medium and Heterogeneous
Propagation Medium examples.
"""

import matplotlib.pyplot as plt
import numpy as np

from kwave.data import Vector
from kwave.kgrid import kWaveGrid
from kwave.kmedium import kWaveMedium
from kwave.ksensor import kSensor
from kwave.ksource import kSource
from kwave.kspaceFirstOrder1D import kspace_first_order_1D
from kwave.options.simulation_execution_options import SimulationExecutionOptions
from kwave.options.simulation_options import SimulationOptions

# =========================================================================
# SIMULATION
# =========================================================================

# create the computational grid
Nx: int = 512 # number of grid points in the x (row) direction
dx: float = 0.05e-3 # grid point spacing in the x direction [m]

grid_size_points = Vector([Nx, ])
grid_spacing_meters = Vector([dx, ])

# create the k-space grid
kgrid = kWaveGrid(grid_size_points, grid_spacing_meters)

# define the properties of the propagation medium
sound_speed = 1500.0 * np.ones((Nx, 1)) # [m/s]
sound_speed[:np.round(Nx / 3).astype(int) - 1] = 2000.0 # [m/s]
density = 1000.0 * np.ones((Nx, 1)) # [kg/m^3]
density[np.round(4 * Nx / 5).astype(int) - 1:] = 1500.0 # [kg/m^3]
medium = kWaveMedium(sound_speed=sound_speed, density=density)

# Create the source object
source = kSource()

# create initial pressure distribution using a smoothly shaped sinusoid
x_pos: int = 280 # [grid points]
width: int = 100 # [grid points]
height: int = 1 # [au]
p0 = np.linspace(0.0, 2.0 * np.pi, width + 1)

part1 = np.zeros(x_pos).astype(float)
part2 = (height / 2.0) * np.sin(p0 - np.pi / 2.0) + (height / 2.0)
part3 = np.zeros(Nx - x_pos - width - 1).astype(float)
source.p0 = np.concatenate([part1, part2, part3])

# create a Cartesian sensor mask recording the pressure
sensor = kSensor()
sensor.record = ["p"]

# this hack is needed to ensure that the sensor is in [1,2] dimensions
mask = np.array([-10e-3, 10e-3]) # [m]
mask = mask[:, np.newaxis].T
sensor.mask = mask

# set the simulation time to capture the reflections
c_max = np.max(medium.sound_speed.flatten()) # [m/s]
t_end = 2.5 * kgrid.x_size / c_max # [s]

# define the time array
kgrid.makeTime(c_max, t_end=t_end)

# define the simulation options
simulation_options = SimulationOptions(data_cast="off", save_to_disk=False)
execution_options = SimulationExecutionOptions(is_gpu_simulation=True)

# run the simulation
sensor_data = kspace_first_order_1D(kgrid, source, sensor, medium, simulation_options=simulation_options, execution_options=execution_options)

# =========================================================================
# VISUALISATION
# =========================================================================

# plot the recorded time signals
_, ax1 = plt.subplots()
ax1.plot(sensor_data['p'][0, :], 'b-')
ax1.plot(sensor_data['p'][1, :], 'r-')
ax1.grid(True)
ax1.set_ylim(-0.1, 0.7)
ax1.set_ylabel('Pressure')
ax1.set_xlabel('Time Step')
ax1.legend(['Sensor Position 1', 'Sensor Position 2'])
plt.show()
Loading
Loading