simpeg/simpeg: Simulation
SimPEG contributors, Lindsey J. Heagy, Seogi Kang, Fournier, Dominique, Guðni Karl Rosenkjær, Capriotti, Joseph, Thibaut Astic, Devin C. Cowan, David R. Marchant, Michael E. Mitchell, Johnathan Kuttai, Dieter Werthmüller, Luz Angélica Caudillo Mata, Zheng-Kai Ye, Franklin Koch, Brendan Smithyman, Kalen Martens, Craig Miller, Christoph Gohlke, Sarah G. R. Devriese · Zenodo (CERN European Organization for Nuclear Research) · 2020
SimPEG 0.14.0 Release Notes This release marks a major change in the structure of SimPEG, and it all started with this, #562: What's the problem with Problem? We hope to answer that question with this release! This release will break backward compatibility as many modules and classes have been renamed. Check out the Examples and Tutorials (which have also been improved) to see how it's done. We are also only supporting Python versions >=3.6 at this time. We have dropped all testing and development on Python versions previous to this (especially 2.7). Highlights No more Problem-s, only Simulation-s Data is important PEP 8 renaming Dask parallelism Resistivity Simulation improvements Simulation We will refer to this update as the simulation update, and there are a few large changes that we will attempt to describe here. We (the developers) believed that there were some significant challenges with the overall structure of the SimPEG framework, which all revolved around constructing a forward simulation by pair-ing a Survey and a Problem. The Survey handled things like sources, receivers, and the Problem handled the physics engine of the forward simulation. These two items had to be created separately, then pair-ed afterwards for both the Problem to be able to use sources, and for the Survey to predict data. We found that this structure made it difficult to interface with other packages and was also generally difficult to explain. Also, field data was then attached to the Survey class. These changes within this section are also the ones which will require the most changes to code (which are still hopefully small). The Simulation class Problem has been renamed to Simulation We decided to refactor this code into something a little more understandable. The Simulation class is now the workhorse of the SimPEG forward simulations. It handles things like modeling fields and projecting those fields to the data locations defined by its survey. The Survey class is much lighter weight, now only handling the sources and receivers. Also a single survey can now be attached to many Simulation-s. Previously we had something like, survey = DC.Survey(srcList) prob = DC.Problem3D_CC(mesh, rhoMap=mapping) prob.pair(survey) # Compute the fields from `prob` fields = prob.fields(model) # And predict data using the `survey` dpred = survey.dpred(model, f=fields) Now, survey = resistivity.Survey([source_list]) sim = resistivity.Simulation3DCellCentered( mesh, survey=survey, rhoMap=mapping ) # Compute the fields from `sim` fields = sim.fields(model) # Predict data also using `sim` dpred = sim.dpred(model, f=fields) See? The Simulation handles predicting data. This change will also make it easier to interface with external codes for inversion purposes, as all that is needed to be defined to use a Simulation for an InvProblem, is sim.dpred, sim.Jvec and sim.Jtvec. Please see the documentation for the SimPEG.simulation.BaseSimulation class as well as the individual methods' Simulation-s, for a detailed description of arguments, but largely it accepts the same arguments as the Problem class, but now also requires a Survey to be set. The Data class Previously, field data would also live within the Survey class. Which was not only confusing, but placed the importance on the wrong component. When inverting geophysical data, we are concerned with the data. Thus we would like to enforce this importance by making data live in a dedicated Data class. This Data class can act like a smart dictionary to grab data associated with a specific source, receiver combination. More importantly, this Data class is where we store information related to observed data and its errors. This class started in the SimPEG.Survey module, but has now been moved into its own new module SimPEG.data. See the documentation for the SimPEG.data.Data for all of the details. Previously, # Add data to the survey survey.dobs = dobs survey.std = 0.05 # a 5% relative error survey.eps = 1.0E-6 # a noise floor Now, # Create a data object data = data.Data(dobs=dobs, relative_error=0.05, noise_floor=1e-6) You might also notice that we changed the name of the terms used to construct the standard deviation. See issue #846. Previously survey.std represented an error that was relative to the absolute value of the data. The name of this term is misleading, as it is not actually the classic statistical standard deviation. Previously the uncertainty was constructed as: uncertainty = survey.std * np.abs(survey.dobs) + survey.eps We now have updated the names to be clearer and more in line with what we would naturally expect, which is accessed from data.standard_deviation. The value that is returned from this is now defined as: data.standard_deviation = ( data.relative_error * np.abs(data.dobs) + data.noise_floor ) You can also directly set the value of data.standard_deviation if you prefer to work with that quantity. data.standard_deviation = 0.01 This Data class is now also the object that is returned from: data = sim.make_synthetic_data( m, relative_error=0.05, noise_floor=0.0, f=None, add_noise=True ) The DataMisfit class Previously, because the Survey class handled predicting data at the receivers, and it also had knowledge of the observed data and its noise, we constructed the data misfit measure using only the survey. Now we have specifically broken this piece up into a forward Simulation object, and a Data object. This mimics the definition of the classic data misfit measure. The Simulation class handles the forward operation, , and the Data class handles the noise, , and the observed data, . See the documentation for the SimPEG.data_misfit.L2DataMisfit for all of the details. Previously, # Survey knows how to predict data, knows the observed data, # and its standard deviation dmis = DataMisfit.l2_DataMisfit(survey) Now, # Create a data misfit # The data class now knows the observed data and its standard deviation. # The simulation knows how to create data from a model. dmis = data_misfit.L2DataMisfit(simulation=sim, data=data) Dask We have begun a concerted effort to incorporate dask as a means to allow SimPEG to scale to larger computers (and take advantage of parallelism). Checkout the dask docs at https://docs.dask.org/en/latest/. This feature is experimental at the moment and can be toggled on like so, import SimPEG.dask which will then enable parallel operations for a few modules. It will specifically replace these functions with dask versions, SimPEG.potential_fields.BasePFSimulation.linear_operator SimPEG.potential_fields.magnetics.Simulation3DIntegral.getJtJdiag SimPEG.potential_fields.gravity.Simulation3DIntegral.getJtJdiag SimPEG.electromagnetics.static.resistivity.simulation.BaseDCSimulation.getJ SimPEG.electromagnetics.static.resistivity.simulation.BaseDCSimulation.getJtJdiag SimPEG.electromagnetics.static.induced_polarization.simulation.BaseDCSimulation.getJ SimPEG.electromagnetics.static.induced_polarization.simulation.BaseDCSimulation.getJtJdiag Changelog As can be expected, there are many changes in this release, and we hope to identify most of them here (or at least point you in the right direction). Renamed Modules We have taken steps to rename the modules of SimPEG to a more PEP 8 friendly system. The previous locations do not exist. EM → electromagnetics EM.FDEM → electromagnetics.frequency_domain EM.TDEM → electromagnetics.time_domain EM.NSEM → electromagnetics.natural_source EM.Static → electromagnetics.static EM.Static.DC → electromagnetics.static.resistivity EM.Static.DC.Utils → electromagnetics.static.resistivity.utils EM.Static.IP → electromagnetics.static.induced_polarization EM.Static.SIP → electromagnetics.static.spectral_induced_polarization EM.Static.Utils → electromagnetics.static.utils EM.Utils → electromagnetics.utils VRM → electromagnetics.viscous_remanent_magnetization FLOW → flow SEIS → seismic PF → potential_fields PF.Gravity → potential_fields.gravity