DevitoPRO
Compatibility notes
DevitoPRO requires Devito main.
DevitoPRO sets up Devito as a submodule locked onto the latest main commit which is compatible with DevitoPRO (i.e. passes all DevitoPRO tests). The branch of the submodule can be manually changed as desired, although it should be noted that this is discouraged. There is CI workflow which automatically updates the submodule every time a PR is merged into Devito, if the new update passes all the DevitoPRO tests. If necessary, the status of the submodule can also be updated by hand (typically for changes spanning both Devito and DevitoPRO).
Note: DevitoPRO now checks the commit tag of the installed Devito at both installation and runtime.
- At installation, DevitoPRO will force re-install Devito if the tag is not the compatible one.
- At runtime, DevitoPRO will raise an error if the tag is not the compatible one.
You can disable the runtime error by setting DEVITO_BYPASS_VERSION_CHECK=1 in your environment. This will only raise a warning instead of an error. This is useful for development purposes but not recommended for production.
Install from Docker
Virtually identical to Devito. The only difference is that the main Dockerfile here is called Dockerfile.devitopro (instead of Dockerfile.devito).
Install with pip
First install
Installing devitopro as a Python package is also supported. This setup is designed to handle all dependencies for the user, including installing devito at the required version. To install devitopro:
- First, clone your mirror repository:
git clone --recurse-submodules --depth 1 your-devitopro-mirrorThis will clone the repository and all the necessary submodules, currently devito and CvxCompress (CPU compression).
- Then, install
devitopro:
./install-devitopro.shDevitoPRO can be installed in editable mode with the ./install-devitopro.sh -e commmand.
Additionally MPI installation can be skipped with the --no-mpi option. This is useful if DevitoPRO is to be installed on a machine without MPI support or in a virtual environment.
./install-devitopro.sh --no-mpiFinally, if a Python installation other than the default system python3 is to be used, the --python option can be supplied with the path to the desired Python executable. This is useful when installing DevitoPRO in a virtual environment or using different Python versions.
./install-devitopro.sh --python /path/to/pythonNote: DevitoPRO is installed in a minimal configuration by default, skipping some dependencies to reduce the install size for production. Additional dependencies only used for testing, plotting, and demos are installed with the ./install-devitopro.sh --extras option.
Updating DevitoPRO
We are continuously improving DevitoPRO and updating the submodule to keep it synchronised with the latest Devito version. To update DevitoPRO, simply pull the latest changes from the repository and reinstall DevitoPRO by calling the install-devitopro.sh script with the same options as the original installation:
./install-devitopro.shIt is extremely important that you include the git submodule update --init --recursive so that devito is updated to the latest version as well. The pip install path/to/devitopro command will then automatically reinstall devito at the correct version if the required version has changed.
Note: By default, install-devitopro.sh automatically calls git submodule update --init --recursive at pip install. However we recommend doing it on the user side to avoid issues with for example git credentials.
Getting started
- For learning how to use Devito, a range of tutorials and examples can be found here. We recommend beginning with the README, before progressing to the
userapinotebooks which detail aspects of the DSL and, subsequently, theseismic/tutorialsnotebooks. - Tutorials for DevitoPRO-specific features are available at
/demos/tutorialsin your DevitoPRO repository. - API reference
- Devito FAQs
- DevitoPRO FAQs: devitopro/FAQ.md
Recipes
Curated solvers for DevitoPRO
Various physics examples available in this repository include:
- Isotropic Acoustic: Standard acoustic wave propagation. Supports SLS viscosity as well.
- Isotropic Elastic: Elastic wave propagation using isotropic models.
- Anisotropic Acoustic: Various variations of the acoustic TTI equation (Fletcher Du Fowler, Zhang, Bube’s self-adjoint)
- Anisotropic Elastic: Elastic wave propagation using anisotropic models such as TTI (Tilted Transverse Isotropy) and VTI (Vertical Transverse Isotropy).
Usage
To run the examples, navigate to the examples directory and execute the scripts or notebooks as needed. Ensure all dependencies are installed.
CLI
To run the solvers from the command line, use the following command:
python devitopro/recipes/run.py -physics <physics_name> -so <space_order> -d nx ny nz -nt <time_steps> ...You can get all the available options by running:
python devitopro/recipes/run.py -hWhen running on accelerators (GPUs) and/or with the DevitoPRO decoupler (DEVITO_DECOUPLER=1), all model initializations (e.g., vp, vs, etc.) are performed serially on the host to avoid unnecessary data transfers and communication overhead. A utility function, host_config, is available and can be imported with from recipes.utils import host_config for use in external codebases. Note that this function will be moved directly into DevitoPRO in the future.
Additional examples
Elastic Accuracy
This example demonstrates the accuracy of elastic solvers.
- Script: elastic-accuracy.py
- Description: The script compares different elastic solvers, including isotropic and anisotropic models, and visualizes their results.
- Sections:
- Elas vs Acou: Comparison between elastic and acoustic solvers.
- AnisoElas vs Elas: Comparison between anisotropic elastic and isotropic elastic solvers.
- VTI vs TTI: Comparison between vertical transverse isotropy (VTI) and tilted transverse isotropy (TTI) solvers.
- SSG vs RSG: Stability comparison with respect to theta and vs parameters.
Immersed Boundary for Acoustic Solvers
This notebook demonstrates the use of immersed boundary support for implementing a topographic free surface.
- Notebook: immersed_boundary.ipynb
- Description: It showcases how to read the Signed Distance Function (SDF) and implement immersed boundary conditions using the Schism library.
- Sections:
- Read the SDF: Explanation of the boundary geometry and material properties continuation through the surface.
Installation
The recipes should not be installed by themselves but should be automatically installed as part of the devitopro installation.
Customizing the imaging condition
The recipes/solver.py module defines the solvers base class and the public interface. All the recipes are subclasses of this class and, regardless of whether you have access to the open or the obfuscated version of the repository, you can always subclass the solver class and define your own imaging condition.
The tests/test_gradient.py::TestCustomization::test_dummy test shows how to subclass the solver class and define a dummy imaging condition. Below, we show a slightly modified fragment of said test:
class AcousticIsotropicDummy(AcousticIsotropic):
def sensitivity(self, params='m'):
"""
Define a custom imaging condition for our solver.
"""
# `m`, `vp`, ...
params = as_tuple(params)
assert len(params) == 1
param = params[0]
u = self.saved_state['u_save']
v = self.state['u']
b, damp = self.model.b, self.model.damp # noqa
dm = self.perturbation(param=param)
eqns = [Eq(dm, u.dx*v.dx)]
return eqnsIn short, to customize the imaging condition, you need to:
- Subclass a solver class (full list available in
recipes/__init__.py). - Override the
sensitivitymethod to define your imaging condition.- Inside this method you can access the wavefield at the current time step (via
self.state) as well as the wavefield snapshots saved during the forward run (viaself.saved_state). You may also access the overarching model object (viaself.model) as well as the inverted objects (via theparamsvariable). - Write the
Eq’s defining the imaging condition. For this part, you need to be familiar with the Devito API. - Return the list of
Eq’s defining the imaging condition.
- Inside this method you can access the wavefield at the current time step (via
That’s about it. The only remaining step is to ensure that your custom solver is accessible by the runtime. You can do it either programmatically (as in the test above) or by adding your new class to the recipes_registry dictionary in recipes/__init__.py. If you choose the latter, you can then run your custom solver directly from the CLI, e.g.:
python devitopro/recipes/run.py -physics iso-acoustic-dummy ...Where iso-acoustic-dummy is the name of your custom solver that you used as a key in the recipes_registry dictionary.
While here we only showed how to customize the imaging condition, you can customize any part of the solver by subclassing the solver class and overriding the relevant methods. The base solver class was designed to be easily extensible and customizable.