Skip to content

Running kspaceFirstOrder3D alters it's input source and sensor parameters #600

Open
@precicely

Description

@precicely

Describe the bug
kspaceFirstOrder3D changes the contents and the formats of 2 of it's input parameters, namely source and sensor.
As a consequence, one cannot run kspaceFirstOrder3D twice with the same input as it bugs out.
This is apparent when trying to run kspaceFirstOrder3D with checkpointing enabled.

To Reproduce

from copy import copy
from pathlib import Path
from tempfile import TemporaryDirectory

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.kspaceFirstOrder3D import kspaceFirstOrder3D
from kwave.options.simulation_execution_options import SimulationExecutionOptions
from kwave.options.simulation_options import SimulationOptions
from kwave.utils.filters import smooth
from kwave.utils.mapgen import make_ball


def make_simulation_parameters(directory: Path):
    """
    See the 3D FFT Reconstruction For A Planar Sensor example for context.
    """
    scale = 2

    # create the computational grid
    PML_size = 10  # size of the PML in grid points
    N = Vector([32, 64, 64]) * scale - 2 * PML_size  # number of grid points
    d = Vector([0.2e-3, 0.2e-3, 0.2e-3]) / scale  # grid point spacing [m]
    kgrid = kWaveGrid(N, d)

    # define the properties of the propagation medium
    medium = kWaveMedium(sound_speed=1500)  # [m/s]

    # create initial pressure distribution using makeBall
    ball_magnitude = 10  # [Pa]
    ball_radius = 3 * scale  # [grid points]
    p0 = ball_magnitude * make_ball(N, N / 2, ball_radius)
    p0 = smooth(p0, restore_max=True)

    source = kSource()
    source.p0 = p0

    # define a binary planar sensor
    sensor = kSensor()
    sensor_mask = np.zeros(N)
    sensor_mask[0] = 1
    sensor.mask = sensor_mask

    input_filename = directory / "kwave_input.h5"
    output_filename = directory / "kwave_output.h5"
    checkpoint_filename = directory / "kwave_checkpoint.h5"

    # set the input arguments
    simulation_options = SimulationOptions(
        save_to_disk=True,
        pml_size=PML_size,
        pml_inside=False,
        smooth_p0=False,
        data_cast="single",
        input_filename=input_filename,
        output_filename=output_filename,
    )

    checkpoint_timesteps = 300  # approximately half way through the simulation

    execution_options = SimulationExecutionOptions(
        is_gpu_simulation=False,
        checkpoint_file=checkpoint_filename,
        checkpoint_timesteps=checkpoint_timesteps,
        verbose_level=2
    )
    return kgrid, medium, source, sensor, simulation_options, execution_options



def main():

    with TemporaryDirectory() as tmpdir:
        tmpdir = Path(tmpdir)
        # create the simulation parameters
        kgrid, medium, source, sensor, simulation_options, execution_options = make_simulation_parameters(tmpdir)

        # copy sourrce and sensor
        source2 = copy(source)
        sensor2 = copy(sensor)

        sensor_data = kspaceFirstOrder3D(kgrid, source, sensor, medium, simulation_options, execution_options)
        
        # the line below will fail (commented out for now)
        # sensor_data = kspaceFirstOrder3D(kgrid, source, sensor, medium, simulation_options, execution_options)
       
        # This works but needs to use copies of source and sensor
        sensor_data = kspaceFirstOrder3D(kgrid, source2, sensor2, medium, simulation_options, execution_options)


if __name__ == "__main__":
    main()

Expected behavior
kspaceFirstOrder3D should not (silently) alter it's inputs.

Context
Came across this issue as I was developing the checkpointing code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions