GithubHelp home page GithubHelp logo

hpcsys-lab / simwave Goto Github PK

View Code? Open in Web Editor NEW
39.0 8.0 12.0 24.88 MB

Simulates the propagation of the acoustic wave using the finite difference method in 2D and 3D domains.

License: GNU General Public License v3.0

Python 43.28% C 20.75% Jupyter Notebook 14.79% Cuda 21.17%
scientific-computing stencil-codes performance finite-differences seismic-waves acoustic-wave

simwave's Introduction

PyPI version DOI

Simwave

Simwave is a Python package to simulate the propagation of the constant or variable density acoustic wave in an isotropic 2D/3D medium using the finite difference method. Finite difference kernels of aribtrary spatial order (up to 20th order) are written in C for performance and compiled at run time. These kernels are called via a user-friendly Python interface for easy integration with several scientific and engineering libraries to, for example perform full-waveform inversion.

For further information on the simwave design and implementation, please see the paper https://arxiv.org/abs/2201.05278

Installation:

For installation, simwave needs only scipy, numpy, and segyio. See requirements.txt. If you wish to plot, then matplotlib is additionally required. simwave compiles finite difference stencils at run time in C for performance and thus requires a working C compiler.

git clone https://github.com/HPCSys-Lab/simwave.git

cd simwave

pip3 install -e .

Contributing

All contributions are welcome.

To contribute to the software:

  1. Fork the repository.
  2. Clone the forked repository, add your contributions and push the changes to your fork.
  3. Create a Pull request

Before creating the pull request, make sure that the tests pass by running

pytest

Some things that will increase the chance that your pull request is accepted:

  • Write tests.
  • Add Python docstrings that follow the Sphinx.
  • Write good commit and pull request messages.

Problems?

If something isn't working as it should or you'd like to recommend a new addition/feature to the software, please let us know by starting an issue through the issues tab. I'll try to get to it as soon as possible.

Examples

Simulation with simwave is simple and can be accomplished in a dozen or so lines of Python! Jupyter notebooks with tutorials can be found here here.

Here we show how to simulate the constant density acoustic wave equation on a simple two layer velocity model.

from simwave import (
    SpaceModel, TimeModel, RickerWavelet, Solver, Compiler,
    Receiver, Source, plot_wavefield, plot_shotrecord, plot_velocity_model
)
import numpy as np


# set compiler options
# available language options: c (sequential) or  cpu_openmp (parallel CPU)
compiler = Compiler(
    cc='gcc',
    language='cpu_openmp',
    cflags='-O3 -fPIC -Wall -std=c99 -shared'
)

# Velocity model
vel = np.zeros(shape=(512, 512), dtype=np.float32)
vel[:] = 1500.0
vel[100:] = 2000.0

# create the space model
space_model = SpaceModel(
    bounding_box=(0, 5120, 0, 5120),
    grid_spacing=(10, 10),
    velocity_model=vel,
    space_order=4,
    dtype=np.float32
)

# config boundary conditions
# (none,  null_dirichlet or null_neumann)
space_model.config_boundary(
    damping_length=0,
    boundary_condition=(
        "null_neumann", "null_dirichlet",
        "none", "null_dirichlet"
    ),
    damping_polynomial_degree=3,
    damping_alpha=0.001
)

# create the time model
time_model = TimeModel(
    space_model=space_model,
    tf=1.0,
    saving_stride=0
)

# create the set of sources
source = Source(
    space_model,
    coordinates=[(2560, 2560)],
    window_radius=1
)

# crete the set of receivers
receiver = Receiver(
    space_model=space_model,
    coordinates=[(2560, i) for i in range(0, 5112, 10)],
    window_radius=1
)

# create a ricker wavelet with 10hz of peak frequency
ricker = RickerWavelet(10.0, time_model)

# create the solver
solver = Solver(
    space_model=space_model,
    time_model=time_model,
    sources=source,
    receivers=receiver,
    wavelet=ricker,    
    compiler=compiler
)

# run the forward
u_full, recv = solver.forward()

print("u_full shape:", u_full.shape)
plot_velocity_model(space_model.velocity_model)
plot_wavefield(u_full[-1])
plot_shotrecord(recv)

simwave's People

Contributors

gdelazzari avatar hermes-senger avatar jaimesouza avatar joao-bapdm avatar krober10nd avatar roussian avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simwave's Issues

example on how to use parallelism

  • It would be nice to have an example with code showing how to utilize OpenMP.
  • Pinning might be an issue too, not sure how that is dealt with.

Private?

  • Is there a reason why pywave remains currently private?
  • I ask because I could setup a Github workflows system to perform unit testing however if the repository is private, then we will have to pay for the full capabilities of this CI system.

Minor suggestions for `compiler` class

  1. Even though I specified the language=c compilation fails because the code tries to import omp.h header despite it not being used. Perhaps this could be avoided by putting this include in a pragma?
  2. In the case that the compilation failed, you can catch this error and write a helpful error message to the screen informing the user what compiler language's are supported.

Generalized source

It would be helpful to have a "generalized source" that instead of acting at a single coordinate, is a field depending on the coordinate position. so instead of s = f(t), the source would be s = f(t) * g(x).

I've tried creating one source for each grid point, but the code get's very slow.

The application would be to test the convergence for the variable density case.

More snapshots.

Hello.

The package is great but I have some difficulties to use it.
The example given on the readme.md generate a solution with only one snapshot. How do I increase the number of snapshots ?
I would like to create a video of the evolution of the wave.

Thanks.

utility of pywave as a sandbox for exploration in computer science?

  • One of the core points of pywave is that is that it can be used to explore code optimizations at a low-level--potentially more easily than say than using Devito as the compiler.
  • I think this aspect needs to be quantified somehow and shown through some examples.
  • I suspect many reviewers would bring this up: "Why did you not just use Devito?"
  • Perhaps when you think of pywave less as a specific wave propagator and more of a sandbox development environment to explore the performance of wave propagators, the question can be more easily answered.

variable order density acoustic wave equation

  • we should implement the same spatial orders (i.e., up to P=16) for the variable density acoustic wave equation.
  • Stopping at order 2 is not sufficient for the article in my opinion.

Waves in elastic media

Hello,

I am wondering if you have some plans to develop FDTD solver for 2D and 3D full linear elastic equations (isotropic, or maybe VTI/full anisotropic case)? It will be a great help to have a verified open-source solved with a good PML realization.

Performance with Marmousi2 simulation

  • As I attempt to write the variable density acoustic wave tutorial with Marmousi, I am running into some performance issues with first the constant density wave equation (I will later go to the variable density once I get this working)
  • Note: I downloaded the Marmousi model and then unzipped it: https://wiki.seg.org/wiki/AGL_Elastic_Marmousi

The following code takes far longer than what I would expect (given my experience with FEM codes) to run 265 timesteps on my laptop takes about 183 seconds. It also produces a fairly strange shot record. Given a similar configuration with spyro, it takes about 10-20 seconds.

  • I'll keep experimenting
 from pywave import *
 
 # number of grid points (z,x)
 shape = (2801, 13601)
 
 spacing = (50.0, 50.0)
 
 # propagation time (miliseconds)
 time = 2000
 
 velModel = Model(file="elastic-marmousi-model/model/MODEL_P-WAVE_VELOCITY_1.25m.segy")
 
 # plot_velocity_model(velModel, show=True)
 
 compiler = Compiler(cc="gcc", cflags="-O3 -shared")
 
 
 extension = BoundaryProcedures(
     nbl=(
         (0, 50),
         (50, 50),
     ),
     boundary_condition=(
         ("NN", "ND"),
         ("ND", "ND"),
     ),  # dirichlet on the left, right and bottom, neumann on the top
     damping_polynomial_degree=3,
     alpha=0.0001,
 )
 
 wavelet = Wavelet(frequency=5.0)
 
 source = Source(kws_half_width=1, wavelet=wavelet)
 source.add(position=(30, 6500))
 
 receivers = Receiver(kws_half_width=1)
 
 for i in range(1, 13601, 20):
     receivers.add(position=(45, i))
 
 
 setup = Setup(
     velocity_model=velModel,
     sources=source,
     receivers=receivers,
     boundary_config=extension,
     spacing=spacing,
     propagation_time=time,
     jumps=1,
     compiler=compiler,
     space_order=2,
 )
 
 solver = AcousticSolver(setup=setup)
 
 wavefields, rec, exec_time = solver.forward()
 
 print(exec_time, flush=True)
 
 plot_shotrecord(rec, show=True)

acoustic solver returns only one full snap

  • MWE
 import numpy as np
 from pywave import *
 
 shape = (512, 512)
 spacing = (15.0, 15.0)
 time = 10000
 vel = Data(shape=shape)
 compiler = Compiler(program_version="sequential")
 grid = Grid(shape=vel.shape())
 
 src_points, src_values = get_source_points(
     grid_shape=shape, source_location=(30, 255.5), half_width=4
 )
 
 rec_points = np.array([], dtype=np.uint)
 rec_values = np.array([], dtype=np.float32)
 for i in range(512):
     points, values = get_source_points(
         grid_shape=shape, source_location=(30, i), half_width=4
     )
     rec_points = np.append(rec_points, points)
     rec_values = np.append(rec_values, values)
 
 setup = Setup(
     grid=grid,
     velocity=vel,
     origin=(255, 255.5),
     spacing=spacing,
     progatation_time=time,
     frequency=5.0,
     nbl=150,
     compiler=compiler,
     src_points_interval=src_points,
     src_points_values=src_values,
     rec_points_interval=rec_points,
     rec_points_values=rec_values,
     num_receivers=511,
 )
 
 solver = AcousticSolver(setup=setup)
 
 wavefields, rec, exec_time = solver.forward()

print(wavefields.shape)

wavefields.shape has the size of only one snap? Shouldn't this save all timesnaps?

Errors trying to execute multiple examples

Hi everyone:

I'm trying to run the examples files on my Windows PC. First of all the acoustic 2D and gets an error at 53 line

----> 53 space_model = SpaceModel(
simwave\kernel\frontend\model.py:57
---> 57 self._velocity_model = self.interpolate(velocity_model)
simwave\kernel\frontend\model.py:242
--> 242     return self.dtype(interpolant((Z, X)))
File _rgi_cython.pyx:19, in scipy.interpolate._rgi_cython.__pyx_fused_cpdef()
TypeError: No matching signature found

Then I tried to run this on Google Colab and get an error a this point

u_full, recv = solver.forward()
Exception: Compilation failed

I'm really interested on using this library for solving problems of seismic acquisition.

Let me know what am I doing wrong, I'll appreciate it.

Application of domain extension

  • Domain extension application should be able to extend to all four sides of domain and not assume only the left, right, and bottom.

timestep specification

  • the delta t should be specified in the TimeModel
  • The delta t is related to the temporal discretization not directly the spatial model. It's a bit non-inutitive to specify the timestep through SpaceModel IMO.

Convergence test

At a minimum we need to demonstrate and have a unit test which verifies all implemented numerical methods are converging at the correct spatial order

for very high order methods, the cfl condition will need to be much more conservative than the stability criteria in order to satisfy the asymptotic regime criteria.

We may also think about higher order timestepping methods

Wave propogation in presence of obstacles

Hello,

Thank you for the interesting project!

I have a question: is it possible to take into account the variable-shaped obstacles during the simulation of wave propagation with simwave?

E.g. as the figure from your paper presents:

image

?

Consider using code formatter

  • I use the code formatter called black which automatically formats and syntax checks the code every time I save in my vim editor.
  • This can be run automatically (known as lint checking).
  • Standards are good.

Ultrasound wave propagation

Dear @jaimesouza ,
Thanks for your contribution. I would like to know if I can use it in ultrasound wave propagation such as 2.5MHz frequency. If yes, do you have experience in the space model or the computational time. Thanks a lot!

same sources + different order = different results

Doing a simulation with the same sources leads to different results depending on the order sources are added.

Using the 2d example from the example/ directory:

from pywave import *
import numpy as np

# shape of the grid
shape = (512, 512)

# spacing
spacing = (15.0, 15.0)

# propagation time
time = 1500

# Velocity model
vel = np.zeros(shape, dtype=np.float32)
vel[:] = 1500.0
vel[200:] = 2000.0
velModel = Model(ndarray=vel)

# Compiler
compiler = Compiler(cc="gcc", cflags="-O3 -shared")

# domain extension (damping + spatial order halo)
extension = BoundaryProcedures(
    nbl=50,
    boundary_condition=(("NN", "NN"), ("NN", "NN")),
    damping_polynomial_degree=3,
    alpha=0.0001,
)

# Wavelet
wavelet = Wavelet(frequency=5.0)

# Source
source = Source(kws_half_width=1, wavelet=wavelet)
source.add(position=(270, 240))
source.add(position=(255.5, 255.5))

# receivers
receivers = Receiver(kws_half_width=1)
for i in range(512):
    receivers.add(position=(255.5, i))

setup = Setup(
    velocity_model=velModel,
    sources=source,
    receivers=receivers,
    boundary_config=extension,
    spacing=spacing,
    propagation_time=time,
    jumps=0,
    compiler=compiler,
    space_order=2,
)

solver = AcousticSolver(setup=setup)

wavefields, rec, exec_time = solver.forward()

print(wavefields.shape)

if len(wavefields.shape) > 2:
    count = 0
    for wavefield in wavefields:
        plot_wavefield(wavefield, file_name="arq-" + str(count))
        count += 1
else:
    plot_wavefield(wavefields)

print("Forward execution time: %f seconds" % exec_time)

plot_shotrecord(rec)

swapping lines 34 and 35 leads to different shot records:

Adding first (255.5, 255.5), then (270, 240):

wavefield
shotrecord

Adding first (270, 240), then (255.5, 255.5):

wavefield
shotrecord

Unfortunately the bug does not come from my latest pull request, as I generated these images in commit 0b1b157.

2D execution failing with scipy==1.10.0

$ python3 gradient_2D.py 

Traceback (most recent call last):
  File "gradient_2D.py", line 199, in <module>
    recv_true = calculate_true_seimogram(velocity_model=tru_vel)
  File "gradient_2D.py", line 130, in calculate_true_seimogram
    solver = create_solver(saving_stride=0, velocity_model=velocity_model)
  File "gradient_2D.py", line 64, in create_solver
    space_model = SpaceModel(
  File "/home/jaime/simwave-research/simwave/kernel/frontend/model.py", line 57, in __init__
    self._velocity_model = self.interpolate(velocity_model)
  File "/home/jaime/simwave-research/simwave/kernel/frontend/model.py", line 242, in interpolate
    return self.dtype(interpolant((Z, X)))
  File "/usr/local/lib/python3.8/dist-packages/scipy/interpolate/_rgi.py", line 336, in __call__
    result = evaluate_linear_2d(self.values,
  File "_rgi_cython.pyx", line 19, in scipy.interpolate._rgi_cython.__pyx_fused_cpdef
TypeError: No matching signature found

It works with scipy==1.9.2

grid_spacing doesn't accept integers

Only floats. Otherwise nothing is actually evaluated, as can be seen by running this MWE:

from pywave import *
import numpy as np

# Set reference (numerical) model
c = 2000 * np.ones(shape=(512, 512), dtype=np.float32)
space_model = SpaceModel(
    bbox=(0, 5110, 0, 5110), grid_spacing=(10, 10), velocity_model=c
)
time_model = TimeModel(space_model=space_model, tf=1)
source = Source(space_model, coordinates=[(2560, 2560)])
receiver = Receiver(space_model, coordinates=[(3500, 3500)])
ricker = RickerWavelet(10.0, time_model)
solver = Solver(space_model,
                time_model=time_model,
                sources=source,
                receivers=receiver,
                wavelet=ricker,
                saving_jump=1)
# run the forward
u, rec = solver.forward()

Marmousi II tutorial

  • A short Jupyter notebook about simulating with the variable density formulation using pywave from the SEGY file format.
  • I can work on this.

Custom compiler options

  • For example, using gcc I normally add
-O3 -march=znver2 -mtune=znver2 -ffast-math -funroll-loops -ftree-loop-distribution

which is not always safe but is muito rapido nonetheless.

how could these be passed?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.