SimPEG 0.24.0 Release Notes#

April 24th, 2025

Updates#

New features#

Speed up of dot products involved in PGI#

This release includes optimizations of some dot products carried out in the PGIsmallness. They significantly reduce the computation time of Petrophysically and Geologically Guided Inversions (PGI).

Specifically, these changes optimize the dot products involved when evaluating the regularization function itself and its derivatives. The optimization takes advantage of the numpy.einsum() function.

See simpeg/simpeg#1587 and simpeg/simpeg#1588 for more information.

Potential field sensitivity matrices as Linear Operators#

The gravity and magnetic field simulations are now capable of building the sensitivity matrix G as a SciPy LinearOperator object when the store_sensitivities argument is set to "forward_only". The LinearOperator objects can be used to compute the dot product with any vector (G @ v), or the dot product of their transpose (G.T @ v) as if they were arrays, although the dense matrix is never fully built nor allocated in memory. Instead, the forward computation is carried out whenever a dot product is requested.

This change allows to compute the simulation derivatives without requiring large amount of memory to store large sensitivity matrices, enabling users to run inversions of large models where the sensitivity matrix is larger than the available memory.

Using methods like Jvec(), Jtvec(), and getJtJdiag(), make use of G a linear operator when store_sensitivities="forward_only". Meanwhile, the getJ() method returns a composite LinearOperator object that can also be used to compute dot products with any vector.

See simpeg/simpeg#1622 and simpeg/simpeg#1634 for more information.

Move indexing of arrays from simpeg.data.Data to Surveys#

We moved the indexing capabilities of the Data objects to the different Survey objects. This is useful in case we have some data as a flat array that is related to a particular survey (or combination of sources and receivers), and we want to obtain the data values associated to a particular pair of source and receiver.

With this change, we don’t need to define a new Data object to slice an array, we can use the Survey itself. For example, let’s say we have a survey with two sources, and three receivers each:

receivers_a = [Recevier([[-2, 0]]), Recevier([[0, 0]]), Recevier([[2, 0]])]
source_a = Source(receiver_list=receivers_a)
receivers_b = [Recevier([[3, 1]]), Recevier([[4, 1]]), Recevier([[5, 1]])]
source_b = Source(receiver_list=receivers_b)
survey = Survey(source_list=[source_a, source_b])

And we have a dobs array that corresponds to this survey. We can obtain the values of the dobs array associated with the second receiver and the first source by using the get_slice method to obtain a slice object, and then use it to index the dobs array:

slice_obj = survey.get_slice(source_a, receivers_a[1])
dobs_slice = dobs[slice_obj]

See simpeg/simpeg#1616 and simpeg/simpeg#1632 for more information.

Documentation#

The documentation pages have been reorganized, merging the _Getting Started_ section into the User Guide. This change makes it easier to navigate through the different documentation pages, with the assistance of a table of contents on the side.

We updated the installation instructions, with Miniforge as the recommended Python distribution.

We have also improved the documentation of some classes and methods.

Bugfixes#

This release includes a list of bug fixes. We solved issues related to the getJ method of the DC, SIP, TDEM, and FDEM simulations. The EM1D simulations can now work with receivers objects with multiple locations. The BaseDataMisfit class and its children raise errors in case the simulation is retuning non-numeric values as output.

We have also improved some of the error messages that users get when things don’t work as expected, aiming to catch those mistakes earlier than late.

Contributors#

Contributors

Pull Requests#