diff --git a/notebooks/03-gravity/fwd_gravity_anomaly_3d.ipynb b/notebooks/03-gravity/fwd_gravity_anomaly_3d.ipynb index 10937e3b..8c5e7430 100644 --- a/notebooks/03-gravity/fwd_gravity_anomaly_3d.ipynb +++ b/notebooks/03-gravity/fwd_gravity_anomaly_3d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** Here we use the module [simpeg.potential_fields.gravity](myst:simpeg#simpeg.potential_fields.gravity) to simulate gravity anomaly data for a synthetic density contrast model. We use the [3D integral formulation](myst:simpeg#simpeg.potential_fields.gravity.Simulation3DIntegral) and carry out the forward simulation on a tensor mesh.\n", + "**Summary:** Here we use the module [simpeg.potential_fields.gravity](xref:simpeg#simpeg.potential_fields.gravity) to simulate gravity anomaly data for a synthetic density contrast model. We use the [3D integral formulation](xref:simpeg#simpeg.potential_fields.gravity.Simulation3DIntegral) and carry out the forward simulation on a tensor mesh.\n", "\n", "
\n", "\n", @@ -59,7 +59,7 @@ "source": [ "## Import Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to simulating gravity data are imported from [simpeg.potential_fields.gravity](myst:simpeg#simpeg.potential_fields.gravity). We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To simulate gravity data, we need to define our problem geometry on a numerical grid (or mesh).\n", + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to simulating gravity data are imported from [simpeg.potential_fields.gravity](xref:simpeg#simpeg.potential_fields.gravity). We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To simulate gravity data, we need to define our problem geometry on a numerical grid (or mesh).\n", "To generate the mesh, we used the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, @@ -103,7 +103,7 @@ "source": [ "## Define the Topography\n", "\n", - "Surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) for 3D simulations.\n", + "Surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) for 3D simulations.\n", "Here, we create basic topography for the forward simulation.\n", "For user-specific simulations, you may load topography from an XYZ file." ] @@ -192,12 +192,12 @@ "\n", "Surveys within SimPEG generally require the user to create and connect three types of objects:\n", "\n", - "- [receivers](myst:simpeg#simpeg.potential_fields.gravity.receivers.Point): which define the locations of field measurements and type of data being measured.\n", - "- [sources](myst:simpeg#simpeg.potential_fields.gravity.sources.SourceField): the passive or active sources responsible for generating geophysical responses, and their associated receivers.\n", - "- [survey](myst:simpeg#simpeg.potential_fields.gravity.survey.Survey): the object which stores and organizes all of the sources and receivers.\n", + "- [receivers](xref:simpeg#simpeg.potential_fields.gravity.receivers.Point): which define the locations of field measurements and type of data being measured.\n", + "- [sources](xref:simpeg#simpeg.potential_fields.gravity.sources.SourceField): the passive or active sources responsible for generating geophysical responses, and their associated receivers.\n", + "- [survey](xref:simpeg#simpeg.potential_fields.gravity.survey.Survey): the object which stores and organizes all of the sources and receivers.\n", "\n", "Here, we define the survey that will be used for the forward simulation. Gravity\n", - "surveys are simple to create. The user only needs an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) to define\n", + "surveys are simple to create. The user only needs an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) to define\n", "the xyz locations of the observation locations, and a list of field components\n", "which are to be measured. For the tutorial simulation, the receivers are located 5 m\n", "above the surface topography and spaced 10 m apart." @@ -304,7 +304,7 @@ "## Design a (Tensor) Mesh\n", "\n", "Meshes are designed using the [discretize](https://discretize.simpeg.xyz/en/main) package. See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating meshes.\n", - "Here, the forward simulation is computed for a [tensor mesh](myst:discretize#discretize.TensorMesh). If you wanted to generate a [tree mesh](myst:discretize#discretize.TreeMesh) instead, you can use the code snippet from the [3D Forward Simulation of Gravity Gradiometry Data](fwd_gravity_gradiometry_3d.ipynb) tutorial.\n", + "Here, the forward simulation is computed for a [tensor mesh](xref:discretize#discretize.TensorMesh). If you wanted to generate a [tree mesh](xref:discretize#discretize.TreeMesh) instead, you can use the code snippet from the [3D Forward Simulation of Gravity Gradiometry Data](fwd_gravity_gradiometry_3d.ipynb) tutorial.\n", "\n", "The integral formulation for gravity essentially sums the independent gravity anomaly contribution for every voxel cell in the mesh. Since the kernel function that computes the contribution for a single cell is an analytic solution, small cells are not required to accurately compute the contributions from coarse structures with constant density (e.g. a rectangular prism). For complex structures however, or to define surface topography more accurately, finer cells may be needed. Furthermore, cells do not need to be cubic.\n", "\n", @@ -385,7 +385,7 @@ "## Define the Active Cells\n", "\n", "Whereas cells below the Earth's surface contribute towards the simulated gravity anomaly, air cells do not.\n", - "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -411,7 +411,7 @@ "source": [ "## Mapping from the Model to Active Cells\n", "\n", - "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be parameters defining a layered Earth. When simulating gravity anomaly data using the integral formulation, we must define a mapping from the set of model parameters to the active cells in the mesh. Mappings are created using the [simpeg.maps](myst:simpeg#simpeg.maps.IdentityMap) module. For the tutorial exercise, the model is the density contrast values for all active cells. As such, our mapping is an identity mapping, whose dimensions are equal to the number of active cells." + "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be parameters defining a layered Earth. When simulating gravity anomaly data using the integral formulation, we must define a mapping from the set of model parameters to the active cells in the mesh. Mappings are created using the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module. For the tutorial exercise, the model is the density contrast values for all active cells. As such, our mapping is an identity mapping, whose dimensions are equal to the number of active cells." ] }, { @@ -441,11 +441,11 @@ "\n", "Here, we create the model that will be used to predict gravity anomaly data.\n", "Recall that our model is the density constrast values for all active mesh cells.\n", - "So the model is a 1D [numpy.ndarray](myst:numpy#numpy.ndarray) whose length is\n", + "So the model is a 1D [numpy.ndarray](xref:numpy#numpy.ndarray) whose length is\n", "equal to the number of model parameters.\n", "**In SimPEG, density contrast values are defined in units of g/cc**.\n", "Here, the model consists of a less dense block and a more dense sphere.\n", - "We plot the model using the [plot_slice](myst:discretize#discretize.TensorMesh.plot_slice) method." + "We plot the model using the [plot_slice](xref:discretize#discretize.TensorMesh.plot_slice) method." ] }, { @@ -578,7 +578,7 @@ "## Define the Forward Simulation\n", "\n", "In SimPEG, the physics of the forward simulation is defined by creating an instance of an appropriate simulation class.\n", - "In this case, we use the simulation class for the [3D integral formulation](myst:simpeg#simpeg.potential_fields.gravity.Simulation3DIntegral). To fully define the forward simulation, we need to connect the simulation object to:\n", + "In this case, we use the simulation class for the [3D integral formulation](xref:simpeg#simpeg.potential_fields.gravity.Simulation3DIntegral). To fully define the forward simulation, we need to connect the simulation object to:\n", "\n", "- the survey\n", "- the mesh\n", @@ -628,7 +628,7 @@ "source": [ "## Simulate Gravity Anomaly Data\n", "\n", - "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](myst:simpeg#simpeg.simulation.BaseSimulation.dpred) method. **SimPEG uses a right-handed coordinate system to simulate gravity anomaly data where Z is positive upward!!!** Please be aware of this when using gravity anomaly data to infer the locations of more and less dense structures. E.g. above a more dense block, a negative gravity anomaly is observed because gravity is stronger in the -ve Z direction. In SimPEG, gravity anomaly values are in **units mGal.**" + "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](xref:simpeg#simpeg.simulation.BaseSimulation.dpred) method. **SimPEG uses a right-handed coordinate system to simulate gravity anomaly data where Z is positive upward!!!** Please be aware of this when using gravity anomaly data to infer the locations of more and less dense structures. E.g. above a more dense block, a negative gravity anomaly is observed because gravity is stronger in the -ve Z direction. In SimPEG, gravity anomaly values are in **units mGal.**" ] }, { diff --git a/notebooks/03-gravity/fwd_gravity_gradiometry_3d.ipynb b/notebooks/03-gravity/fwd_gravity_gradiometry_3d.ipynb index c10c7893..c72289c9 100644 --- a/notebooks/03-gravity/fwd_gravity_gradiometry_3d.ipynb +++ b/notebooks/03-gravity/fwd_gravity_gradiometry_3d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** Here we use the module [simpeg.potential_fields.gravity](myst:simpeg#simpeg.potential_fields.gravity) to simulate gravity gradiometry data for a synthetic density contrast model. We use the [3D integral formulation](myst:simpeg#simpeg.potential_fields.gravity.Simulation3DIntegral) and carry out the forward simulation on a tree mesh.\n", + "**Summary:** Here we use the module [simpeg.potential_fields.gravity](xref:simpeg#simpeg.potential_fields.gravity) to simulate gravity gradiometry data for a synthetic density contrast model. We use the [3D integral formulation](xref:simpeg#simpeg.potential_fields.gravity.Simulation3DIntegral) and carry out the forward simulation on a tree mesh.\n", "\n", "
\n", "\n", @@ -60,7 +60,7 @@ "## Import Modules\n", "\n", "Here, we import all of the functionality required to run the notebook for the tutorial exercise.\n", - "All of the functionality specific to simulating gravity data are imported from [simpeg.potential_fields.gravity](myst:simpeg#simpeg.potential_fields.gravity).\n", + "All of the functionality specific to simulating gravity data are imported from [simpeg.potential_fields.gravity](xref:simpeg#simpeg.potential_fields.gravity).\n", "We also import some useful utility functions from SimPEG. To simulate gravity data,\n", "we need to define our problem geometry on a numerical grid (or mesh).\n", "To generate the mesh, we used the [discretize](https://discretize.simpeg.xyz/en/main) package." @@ -106,7 +106,7 @@ "source": [ "## Define the Topography\n", "\n", - "Surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) for 3D simulations.\n", + "Surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) for 3D simulations.\n", "Here, we create basic topography for the forward simulation.\n", "For user-specific simulations, you may load topography from an XYZ file." ] @@ -193,12 +193,12 @@ "\n", "Surveys within SimPEG generally require the user to create and connect three types of objects:\n", "\n", - "- [receivers](myst:simpeg#simpeg.potential_fields.gravity.receivers.Point): which define the locations of field measurements and type of data being measured.\n", - "- [sources](myst:simpeg#simpeg.potential_fields.gravity.sources.SourceField): the passive or active sources responsible for generating geophysical responses, and their associated receivers.\n", - "- [survey](myst:simpeg#simpeg.potential_fields.gravity.survey.Survey): the object which stores and organizes all of the sources and receivers.\n", + "- [receivers](xref:simpeg#simpeg.potential_fields.gravity.receivers.Point): which define the locations of field measurements and type of data being measured.\n", + "- [sources](xref:simpeg#simpeg.potential_fields.gravity.sources.SourceField): the passive or active sources responsible for generating geophysical responses, and their associated receivers.\n", + "- [survey](xref:simpeg#simpeg.potential_fields.gravity.survey.Survey): the object which stores and organizes all of the sources and receivers.\n", "\n", "Here, we define the survey that will be used for the forward simulation. Gravity\n", - "surveys are simple to create. The user only needs an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) to define\n", + "surveys are simple to create. The user only needs an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) to define\n", "the xyz locations of the observation locations, and a list of field components\n", "which are to be measured. For the tutorial simulation, the receivers are located 5 m\n", "above the surface topography and spaced 10 m apart." @@ -308,7 +308,7 @@ "## Design a (Tree) Mesh\n", "\n", "Meshes are designed using the [discretize](https://discretize.simpeg.xyz/en/main) package. See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating meshes.\n", - "Here, the forward simulation is computed for a [tree mesh](myst:discretize#discretize.TreeMesh). If you wanted to generate a [tensor mesh](myst:discretize#discretize.TensorMesh) instead, you can use the code snippet from the [3D Forward Simulation of Gravity Anomaly Data](fwd_gravity_anomaly_3d.ipynb) tutorial.\n", + "Here, the forward simulation is computed for a [tree mesh](xref:discretize#discretize.TreeMesh). If you wanted to generate a [tensor mesh](xref:discretize#discretize.TensorMesh) instead, you can use the code snippet from the [3D Forward Simulation of Gravity Anomaly Data](fwd_gravity_anomaly_3d.ipynb) tutorial.\n", "\n", "The integral formulation for gravity essentially sums the independent contribution for every voxel cell in the mesh. Since the kernel function that computes the contribution for a single cell is an analytic solution, small cells are not required to accurately compute the contributions from coarse structures with constant density (e.g. a rectangular prism). For complex structures however, or to define surface topography more accurately, finer cells may be needed. Furthermore, cells do not need to be cubic.\n", "\n", @@ -412,7 +412,7 @@ "## Define the Active Cells\n", "\n", "Whereas cells below the Earth's surface contribute towards the simulated gravity anomaly, air cells do not.\n", - "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -438,7 +438,7 @@ "source": [ "## Mapping from the Model to Active Cells\n", "\n", - "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be parameters defining a layered Earth. When simulating gravity anomaly data using the integral formulation, we must define a mapping from the set of model parameters to the active cells in the mesh. Mappings are created using the [simpeg.maps](myst:simpeg#simpeg.maps.IdentityMap) module. For the tutorial exercise, the model is the density contrast values for all active cells. As such, our mapping is an identity mapping, whose dimensions are equal to the number of active cells." + "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be parameters defining a layered Earth. When simulating gravity anomaly data using the integral formulation, we must define a mapping from the set of model parameters to the active cells in the mesh. Mappings are created using the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module. For the tutorial exercise, the model is the density contrast values for all active cells. As such, our mapping is an identity mapping, whose dimensions are equal to the number of active cells." ] }, { @@ -468,11 +468,11 @@ "\n", "Here, we create the model that will be used to predict gravity anomaly data.\n", "Recall that our model is the density constrast values for all active mesh cells.\n", - "So the model is a 1D [numpy.ndarray](myst:numpy#numpy.ndarray) whose length is\n", + "So the model is a 1D [numpy.ndarray](xref:numpy#numpy.ndarray) whose length is\n", "equal to the number of model parameters.\n", "**In SimPEG, density contrast values are defined in units of g/cc**.\n", "Here, the model consists of a less dense block and a more dense sphere.\n", - "We plot the model using the [plot_slice](myst:discretize#discretize.TreeMesh.plot_slice) method." + "We plot the model using the [plot_slice](xref:discretize#discretize.TreeMesh.plot_slice) method." ] }, { @@ -606,7 +606,7 @@ "## Define the Forward Simulation\n", "\n", "In SimPEG, the physics of the forward simulation is defined by creating an instance of an appropriate simulation class.\n", - "In this case, the simulation class corresponds to a [3D integral formulation](myst:simpeg#simpeg.potential_fields.gravity.Simulation3DIntegral). To fully define the forward simulation, we need to connect the simulation object to:\n", + "In this case, the simulation class corresponds to a [3D integral formulation](xref:simpeg#simpeg.potential_fields.gravity.Simulation3DIntegral). To fully define the forward simulation, we need to connect the simulation object to:\n", "\n", "- the survey\n", "- the mesh\n", @@ -656,7 +656,7 @@ "source": [ "## Simulate Gravity Gradiometry Data\n", "\n", - "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](myst:simpeg#simpeg.simulation.BaseSimulation.dpred) method. **SimPEG uses a right-handed coordinate system to simulate gravity gradiometry data where Z is positive upward!!!** Please be aware of this when using gravity gradiometry data to infer the locations of more and less dense structures. In SimPEG, gravity gradiometry values are in **units Eotvos,** where 1 E = $10^{-9} \\; s^{-2}$ = $10^{-4}$ mGal/m." + "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](xref:simpeg#simpeg.simulation.BaseSimulation.dpred) method. **SimPEG uses a right-handed coordinate system to simulate gravity gradiometry data where Z is positive upward!!!** Please be aware of this when using gravity gradiometry data to infer the locations of more and less dense structures. In SimPEG, gravity gradiometry values are in **units Eotvos,** where 1 E = $10^{-9} \\; s^{-2}$ = $10^{-4}$ mGal/m." ] }, { diff --git a/notebooks/03-gravity/inv_gravity_anomaly_3d.ipynb b/notebooks/03-gravity/inv_gravity_anomaly_3d.ipynb index a8fc07cf..ccc58908 100644 --- a/notebooks/03-gravity/inv_gravity_anomaly_3d.ipynb +++ b/notebooks/03-gravity/inv_gravity_anomaly_3d.ipynb @@ -70,7 +70,7 @@ "## Import Modules\n", "\n", "Here, we import all of the functionality required to run the notebook for the tutorial exercise.\n", - "All of the functionality specific to the forward simulation of gravity data are imported from the [simpeg.potential_fields.gravity](myst:simpeg#simpeg.potential_fields.gravity) module. Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." + "All of the functionality specific to the forward simulation of gravity data are imported from the [simpeg.potential_fields.gravity](xref:simpeg#simpeg.potential_fields.gravity) module. Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, { @@ -176,7 +176,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "For this tutorial, the data are organized within basic XYZ files. However, SimPEG does allow the user to import UBC-GIF formatted gravity data files; see [read_grav3d_ubc](myst:simpeg#simpeg.utils.io_utils.read_grav3d_ubc)." + "For this tutorial, the data are organized within basic XYZ files. However, SimPEG does allow the user to import UBC-GIF formatted gravity data files; see [read_grav3d_ubc](xref:simpeg#simpeg.utils.io_utils.read_grav3d_ubc)." ] }, { @@ -373,7 +373,7 @@ "source": [ "## Define the Data\n", "\n", - "The SimPEG [Data](myst:simpeg#simpeg.data.Data) class is required for inversion and connects the observed data, uncertainties and survey geometry." + "The SimPEG [Data](xref:simpeg#simpeg.data.Data) class is required for inversion and connects the observed data, uncertainties and survey geometry." ] }, { @@ -407,7 +407,7 @@ "source": [ "### Design a (Tensor) Mesh\n", "\n", - "Meshes are designed using the [discretize package](https://discretize.simpeg.xyz). Here, we design a [tensor mesh](myst:discretize#discretize.TensorMesh). See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating meshes. When designing a mesh for gravity inversion, we must consider the spatial wavelengths of the signals contained within the data. If the data spacing is large and/or the signals present in the data are smooth, larger cells can be used to construct the mesh. If the data spacing is smaller and compact anomalies are observed, smaller cells are needed to characterize the structures responsible. And smaller cells are required when the effects of surface topography are significant.\n", + "Meshes are designed using the [discretize package](https://discretize.simpeg.xyz). Here, we design a [tensor mesh](xref:discretize#discretize.TensorMesh). See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating meshes. When designing a mesh for gravity inversion, we must consider the spatial wavelengths of the signals contained within the data. If the data spacing is large and/or the signals present in the data are smooth, larger cells can be used to construct the mesh. If the data spacing is smaller and compact anomalies are observed, smaller cells are needed to characterize the structures responsible. And smaller cells are required when the effects of surface topography are significant.\n", "\n", "**General rule of thumb:** The minimum cell size in each direction is at most 0.5 - 1 times the station spacing. And the thickness of the padding is at least 1 - 2 times the width of the survey region." ] @@ -443,7 +443,7 @@ "### Define the Active Cells\n", "\n", "Whereas cells below the Earth's surface contribute towards the simulated gravity anomaly, air cells do not.\n", - "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -469,7 +469,7 @@ "source": [ "### Mapping from the Model to Active Cells\n", "\n", - "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For whatever model we choose, we must define a mapping from the set of model parameters (a [1D numpy.ndarray](myst:numpy#numpy.ndarray)) to the active cells in the mesh. Mappings are created using the [simpeg.maps](myst:simpeg#simpeg.maps.IdentityMap) module. For the tutorial exercise, the model is the density contrast values for all active cells. As such, our mapping is an identity mapping, whose dimensions are equal to the number of active cells." + "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For whatever model we choose, we must define a mapping from the set of model parameters (a [1D numpy.ndarray](xref:numpy#numpy.ndarray)) to the active cells in the mesh. Mappings are created using the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module. For the tutorial exercise, the model is the density contrast values for all active cells. As such, our mapping is an identity mapping, whose dimensions are equal to the number of active cells." ] }, { @@ -588,7 +588,7 @@ "source": [ "### Define the Forward Simulation\n", "\n", - "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for gravity anomaly data was discussed in the [3D Forward Simulation of Gravity Anomaly Data](fwd_gravity_anomaly_3d.ipynb) tutorial. Here, we use the [3D integral formulation](myst:simpeg#simpeg.potential_fields.gravity.simulation.Simulation3DIntegral)." + "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for gravity anomaly data was discussed in the [3D Forward Simulation of Gravity Anomaly Data](fwd_gravity_anomaly_3d.ipynb) tutorial. Here, we use the [3D integral formulation](xref:simpeg#simpeg.potential_fields.gravity.simulation.Simulation3DIntegral)." ] }, { @@ -629,7 +629,7 @@ "### Define the Data Misfit\n", "\n", "To understand the role of the data misfit in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/Uncertainties.html).\n", - "Here, we use the [L2DataMisfit](myst:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." + "Here, we use the [L2DataMisfit](xref:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." ] }, { @@ -654,7 +654,7 @@ "source": [ "### Define the Regularization\n", "\n", - "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). Here, we use the [WeightedLeastSquares](myst:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Here, length scales along x, y and z are used to balance the smallness and smoothness terms. And the reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros." + "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). Here, we use the [WeightedLeastSquares](xref:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Here, length scales along x, y and z are used to balance the smallness and smoothness terms. And the reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros." ] }, { @@ -687,7 +687,7 @@ "source": [ "### Define the Optimization Algorithm\n", "\n", - "Here, we use the [InexactGaussNewton](myst:simpeg#simpeg.optimization.InexactGaussNewton) class to solve the optimization problem using inexact Gauss-Newton. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches." + "Here, we use the [InexactGaussNewton](xref:simpeg#simpeg.optimization.InexactGaussNewton) class to solve the optimization problem using inexact Gauss-Newton. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches." ] }, { @@ -714,7 +714,7 @@ "source": [ "### Define the Inverse Problem\n", "\n", - "We use the [BaseInvProblem](myst:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." + "We use the [BaseInvProblem](xref:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." ] }, { @@ -741,15 +741,15 @@ "\n", "Directives represent operations that are carried out during the inversion. Here, we apply common directives for weighted least-squares inversion of gravity data and describe their roles. These are:\n", "\n", - "- [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights): Apply sensitivity weighting to counteract the natural tendancy of potential field inversion to cluster recovered structures near the receivers. Because the 3D integral formulation is linear, the sensitivity weighting is independent of the model and does not need to be updated throughout the inversion, so we set `every_iteration=False`.\n", + "- [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights): Apply sensitivity weighting to counteract the natural tendancy of potential field inversion to cluster recovered structures near the receivers. Because the 3D integral formulation is linear, the sensitivity weighting is independent of the model and does not need to be updated throughout the inversion, so we set `every_iteration=False`.\n", "\n", - "- [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem.\n", + "- [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem.\n", "\n", - "- [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", + "- [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", "\n", - "- [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta.\n", + "- [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta.\n", "\n", - "- [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", + "- [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", "\n", "\n", "The directive objects are organized in a ``list``. Upon starting the inversion or updating the recovered model at each iteration, the inversion will call each directive within the list **in order**. The order of the directives matters, and SimPEG will throw an error if directives are organized into an improper order. Some directives, like the ``BetaEstimate_ByEig`` are only used when starting the inversion. Other directives, like ``UpdatePreconditionner``, are used whenever the model is updated." @@ -789,7 +789,7 @@ "source": [ "### Define and Run the Inversion\n", "\n", - "We define the inversion using the [BaseInversion](myst:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" + "We define the inversion using the [BaseInversion](xref:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" ] }, { @@ -1153,7 +1153,7 @@ "source": [ "### Design a (Tree) Mesh\n", "\n", - "Here, we design a [tree mesh](myst:discretize#discretize.TreeMesh). See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating tree meshes. The same approach used to construct the tensor mesh used in the weighted least-squares inversion example applies to tree meshes." + "Here, we design a [tree mesh](xref:discretize#discretize.TreeMesh). See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating tree meshes. The same approach used to construct the tensor mesh used in the weighted least-squares inversion example applies to tree meshes." ] }, { @@ -1328,7 +1328,7 @@ "source": [ "### Define the Regularization\n", "\n", - "Here, we use the [Sparse](myst:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Here, the scaling constants that balance the smallness and smoothness terms are set directly. Equal emphasis on smallness and smoothness is generally applied by using the inverse square of the smallest cell dimension. The reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros. Here, we apply a 0-norm to the smallness term and a 1-norm to first-order smoothness along the x, y and z directions." + "Here, we use the [Sparse](xref:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Here, the scaling constants that balance the smallness and smoothness terms are set directly. Equal emphasis on smallness and smoothness is generally applied by using the inverse square of the smallest cell dimension. The reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros. Here, we apply a 0-norm to the smallness term and a 1-norm to first-order smoothness along the x, y and z directions." ] }, { @@ -1363,7 +1363,7 @@ "source": [ "### Define the Optimization Algorithm\n", "\n", - "Here, we use the [ProjectedGNCG](myst:simpeg#simpeg.optimization.ProjectedGNCG) class to solve the optimization problem using projected Gauss-Newton conjugate gradient. This opimization class allows the user to set upper and lower bounds for the recovered model using the `upper` and `lower` properties." + "Here, we use the [ProjectedGNCG](xref:simpeg#simpeg.optimization.ProjectedGNCG) class to solve the optimization problem using projected Gauss-Newton conjugate gradient. This opimization class allows the user to set upper and lower bounds for the recovered model using the `upper` and `lower` properties." ] }, { @@ -1413,9 +1413,9 @@ "source": [ "### Provide Inversion Directives\n", "\n", - "Here, we create common directives for IRLS inversion of gravity data and describe their roles. In additon to the [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig) (described before), inversion with sparse-norms requires the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive.\n", + "Here, we create common directives for IRLS inversion of gravity data and describe their roles. In additon to the [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig) (described before), inversion with sparse-norms requires the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive.\n", "\n", - "You will notice that we don't use the [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property. " + "You will notice that we don't use the [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property. " ] }, { diff --git a/notebooks/04-magnetics/fwd_magnetics_induced_3d.ipynb b/notebooks/04-magnetics/fwd_magnetics_induced_3d.ipynb index cd6d674c..8a19e7ab 100644 --- a/notebooks/04-magnetics/fwd_magnetics_induced_3d.ipynb +++ b/notebooks/04-magnetics/fwd_magnetics_induced_3d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** Here we use the module [simpeg.potential_fields.magnetics](myst:simpeg#simpeg.potential_fields.magnetics) to simulate total magnetic intensity data for a synthetic susceptibility model. We use the [3D integral formulation](myst:simpeg#simpeg.potential_fields.magnetics.Simulation3DIntegral) and carry out the forward simulation on a tensor mesh. The integral formulation works well when magnetic susceptibilities are less than 0.1 SI. However when susceptibilities are sufficiently large, self-demagnetization becomes significant and the integral formulation is no longer accurate.\n", + "**Summary:** Here we use the module [simpeg.potential_fields.magnetics](xref:simpeg#simpeg.potential_fields.magnetics) to simulate total magnetic intensity data for a synthetic susceptibility model. We use the [3D integral formulation](xref:simpeg#simpeg.potential_fields.magnetics.Simulation3DIntegral) and carry out the forward simulation on a tensor mesh. The integral formulation works well when magnetic susceptibilities are less than 0.1 SI. However when susceptibilities are sufficiently large, self-demagnetization becomes significant and the integral formulation is no longer accurate.\n", "\n", "
\n", "\n", @@ -59,8 +59,8 @@ "source": [ "## Import Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to simulating magnetic data are imported from [simpeg.potential_fields.magnetics](myst:simpeg#simpeg.potential_fields.magnetics).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To simulate magnetic data, we need to define our problem geometry on a numerical grid (or mesh).\n", + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to simulating magnetic data are imported from [simpeg.potential_fields.magnetics](xref:simpeg#simpeg.potential_fields.magnetics).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To simulate magnetic data, we need to define our problem geometry on a numerical grid (or mesh).\n", "To generate the mesh, we used the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, @@ -104,7 +104,7 @@ "source": [ "## Define the Topography\n", "\n", - "Surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) for 3D simulations.\n", + "Surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) for 3D simulations.\n", "Here, we create basic topography for the forward simulation.\n", "For user-specific simulations, you may load topography from an XYZ file." ] @@ -191,11 +191,11 @@ "\n", "Surveys within SimPEG generally require the user to create and connect three types of objects:\n", "\n", - "- [receivers](myst:simpeg#simpeg.potential_fields.magnetics.receivers.Point): which define the locations of field measurements and type of data being measured.\n", - "- [sources](myst:simpeg#simpeg.potential_fields.magnetics.sources.UniformBackgroundField): the passive or active sources responsible for generating geophysical responses, and their associated receivers.\n", - "- [survey](myst:simpeg#simpeg.potential_fields.magnetics.Survey): the object which stores and organizes all of the sources and receivers.\n", + "- [receivers](xref:simpeg#simpeg.potential_fields.magnetics.receivers.Point): which define the locations of field measurements and type of data being measured.\n", + "- [sources](xref:simpeg#simpeg.potential_fields.magnetics.sources.UniformBackgroundField): the passive or active sources responsible for generating geophysical responses, and their associated receivers.\n", + "- [survey](xref:simpeg#simpeg.potential_fields.magnetics.Survey): the object which stores and organizes all of the sources and receivers.\n", "\n", - "Here, we define the survey that will be used for the forward simulation. Magnetic surveys are simple to create. The user only needs an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) to define the xyz locations of the observation locations, the field components being measured, and the Earth's inducing field. For the tutorial simulation, the receivers are located 10 m above the surface topography and spaced 10 m apart." + "Here, we define the survey that will be used for the forward simulation. Magnetic surveys are simple to create. The user only needs an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) to define the xyz locations of the observation locations, the field components being measured, and the Earth's inducing field. For the tutorial simulation, the receivers are located 10 m above the surface topography and spaced 10 m apart." ] }, { @@ -307,7 +307,7 @@ "## Design a (Tensor) Mesh\n", "\n", "Meshes are designed using the [discretize](https://discretize.simpeg.xyz/en/main) package. See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating meshes.\n", - "Here, the forward simulation is computed for a [tensor mesh](myst:discretize#discretize.TensorMesh). If you wanted to generate a [tree mesh](myst:discretize#discretize.TreeMesh) instead, you can use the code snippet from the [Forward simulation of magnetic gradiometry data](fwd_magnetics_gradiometry_3d.ipynb) tutorial.\n", + "Here, the forward simulation is computed for a [tensor mesh](xref:discretize#discretize.TensorMesh). If you wanted to generate a [tree mesh](xref:discretize#discretize.TreeMesh) instead, you can use the code snippet from the [Forward simulation of magnetic gradiometry data](fwd_magnetics_gradiometry_3d.ipynb) tutorial.\n", "\n", "The integral formulation for magnetics essentially sums the independent contribution for every magnetized voxel cell in the mesh. Since the kernel function that computes the contribution for a single cell is an analytic solution, small cells are not required to accurately compute the contributions from coarse structures with constant magnetization (e.g. a rectangular prism). For complex structures however, or to define surface topography more accurately, finer cells may be needed. Furthermore, cells do not need to be cubic. **Since the analytic solution is only valid outside the magnetized region, please do no place receivers within the Earth.**\n", "\n", @@ -388,7 +388,7 @@ "## Define the Active Cells\n", "\n", "Whereas cells below the Earth's surface contribute towards the simulated magnetic anomaly, air cells do not. \n", - "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -414,7 +414,7 @@ "source": [ "## Mapping from the Model to Active Cells\n", "\n", - "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be parameters defining a layered Earth. When simulating total magnetic intensity data using the integral formulation, we must define a mapping from the set of model parameters to the active cells in the mesh. Mappings are created using the [simpeg.maps](myst:simpeg#simpeg.maps.IdentityMap) module. For the tutorial exercise, the model is the susceptibility values for all active cells. As such, our mapping is an identity mapping, whose dimensions are equal to the number of active cells." + "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be parameters defining a layered Earth. When simulating total magnetic intensity data using the integral formulation, we must define a mapping from the set of model parameters to the active cells in the mesh. Mappings are created using the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module. For the tutorial exercise, the model is the susceptibility values for all active cells. As such, our mapping is an identity mapping, whose dimensions are equal to the number of active cells." ] }, { @@ -444,11 +444,11 @@ "\n", "Here, we create the model that will be used to predict total magnetic intensity data.\n", "Recall that our model is the susceptibility values for all active mesh cells.\n", - "So the model is a 1D [numpy.ndarray](myst:numpy#numpy.ndarray) whose length is\n", + "So the model is a 1D [numpy.ndarray](xref:numpy#numpy.ndarray) whose length is\n", "equal to the number of model parameters.\n", "**In SimPEG, susceptibility values are in SI units**.\n", "Here, the model consists of a susceptible sphere within a negligibly susceptible host.\n", - "We plot the model using the [plot_slice](myst:discretize#discretize.TensorMesh.plot_slice) method." + "We plot the model using the [plot_slice](xref:discretize#discretize.TensorMesh.plot_slice) method." ] }, { @@ -568,7 +568,7 @@ "## Define the Forward Simulation\n", "\n", "In SimPEG, the physics of the forward simulation is defined by creating an instance of an appropriate simulation class.\n", - "In this case, we use the simulation class for the [3D integral formulation](myst:simpeg#simpeg.potential_fields.magnetics.Simulation3DIntegral). To fully define the forward simulation, we need to connect the simulation object to:\n", + "In this case, we use the simulation class for the [3D integral formulation](xref:simpeg#simpeg.potential_fields.magnetics.Simulation3DIntegral). To fully define the forward simulation, we need to connect the simulation object to:\n", "\n", "- the survey\n", "- the mesh\n", @@ -611,7 +611,7 @@ "source": [ "## Simulate Total Magnetic Intensity Data\n", "\n", - "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](myst:simpeg#simpeg.simulation.BaseSimulation.dpred) method. In SimPEG, total magnetic data values are in **units nT.**" + "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](xref:simpeg#simpeg.simulation.BaseSimulation.dpred) method. In SimPEG, total magnetic data values are in **units nT.**" ] }, { diff --git a/notebooks/04-magnetics/fwd_magnetics_mvi_3d.ipynb b/notebooks/04-magnetics/fwd_magnetics_mvi_3d.ipynb index cd5fa608..9db5a768 100644 --- a/notebooks/04-magnetics/fwd_magnetics_mvi_3d.ipynb +++ b/notebooks/04-magnetics/fwd_magnetics_mvi_3d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** Here we use the module [SimPEG.potential_fields.magnetics](myst:SimPEG#SimPEG.potential_fields.magnetics) to simulate magnetic gradiometry data for a magnetic vector model. We use the [3D integral formulation](myst:SimPEG#SimPEG.potential_fields.magnetics.Simulation3DIntegral) and carry out the forward simulation on a tree mesh.\n", + "**Summary:** Here we use the module [simpeg.potential_fields.magnetics](xref:simpeg#simpeg.potential_fields.magnetics) to simulate magnetic gradiometry data for a magnetic vector model. We use the [3D integral formulation](xref:simpeg#simpeg.potential_fields.magnetics.Simulation3DIntegral) and carry out the forward simulation on a tree mesh.\n", "\n", "
\n", "\n", @@ -60,8 +60,8 @@ "source": [ "## Import Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to simulating magnetic data are imported from [SimPEG.potential_fields.magnetics](myst:SimPEG#SimPEG.potential_fields.magnetics).\n", - "We also import some useful utility functions from [SimPEG.utils](myst:SimPEG#SimPEG.utils). To simulate magnetic data, we need to define our problem geometry on a numerical grid (or mesh).\n", + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to simulating magnetic data are imported from [simpeg.potential_fields.magnetics](xref:simpeg#simpeg.potential_fields.magnetics).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To simulate magnetic data, we need to define our problem geometry on a numerical grid (or mesh).\n", "To generate the mesh, we used the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, @@ -88,9 +88,9 @@ ], "source": [ "# SimPEG functionality\n", - "from SimPEG.potential_fields import magnetics\n", - "from SimPEG.utils import plot2Ddata, model_builder, mat_utils\n", - "from SimPEG import maps\n", + "from simpeg.potential_fields import magnetics\n", + "from simpeg.utils import plot2Ddata, model_builder, mat_utils\n", + "from simpeg import maps\n", "\n", "# discretize functionality\n", "from discretize import TreeMesh\n", @@ -115,7 +115,7 @@ "source": [ "## Define the Topography\n", "\n", - "Surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) for 3D simulations.\n", + "Surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) for 3D simulations.\n", "Here, we create basic topography for the forward simulation.\n", "For user-specific simulations, you may load topography from an XYZ file." ] @@ -202,11 +202,11 @@ "\n", "Surveys within SimPEG generally require the user to create and connect three types of objects:\n", "\n", - "- [receivers](myst:SimPEG#SimPEG.potential_fields.magnetics.receivers.Point): which define the locations of field measurements and type of data being measured.\n", - "- [sources](myst:SimPEG#SimPEG.potential_fields.magnetics.sources.UniformBackgroundField): the passive or active sources responsible for generating geophysical responses, and their associated receivers.\n", - "- [survey](myst:SimPEG#SimPEG.potential_fields.magnetics.Survey): the object which stores and organizes all of the sources and receivers.\n", + "- [receivers](xref:simpeg#simpeg.potential_fields.magnetics.receivers.Point): which define the locations of field measurements and type of data being measured.\n", + "- [sources](xref:simpeg#simpeg.potential_fields.magnetics.sources.UniformBackgroundField): the passive or active sources responsible for generating geophysical responses, and their associated receivers.\n", + "- [survey](xref:simpeg#simpeg.potential_fields.magnetics.Survey): the object which stores and organizes all of the sources and receivers.\n", "\n", - "Here, we define the survey that will be used for the forward simulation. Magnetic surveys are simple to create. The user only needs an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) to define the xyz locations of the observation locations, the field components being measured, and the Earth's inducing field. For the tutorial simulation, the receivers are located 10 m above the surface topography and spaced 10 m apart." + "Here, we define the survey that will be used for the forward simulation. Magnetic surveys are simple to create. The user only needs an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) to define the xyz locations of the observation locations, the field components being measured, and the Earth's inducing field. For the tutorial simulation, the receivers are located 10 m above the surface topography and spaced 10 m apart." ] }, { @@ -321,7 +321,7 @@ "## Design a (Tree) Mesh\n", "\n", "Meshes are designed using the [discretize](https://discretize.simpeg.xyz/en/main) package. See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating meshes.\n", - "Here, the forward simulation is computed for a [tree mesh](myst:discretize#discretize.TreeMesh). If you wanted to generate a [tensor mesh](myst:discretize#discretize.TensorMesh) instead, you can use the code snippet from the [3D Forward Simulation of Total Magnetic Intensity Data](fwd_gravity_anomaly_3d.ipynb) tutorial.\n", + "Here, the forward simulation is computed for a [tree mesh](xref:discretize#discretize.TreeMesh). If you wanted to generate a [tensor mesh](xref:discretize#discretize.TensorMesh) instead, you can use the code snippet from the [3D Forward Simulation of Total Magnetic Intensity Data](fwd_gravity_anomaly_3d.ipynb) tutorial.\n", "\n", "The integral formulation for magnetics essentially sums the independent contribution for every magnetized voxel cell in the mesh. Since the kernel function that computes the contribution for a single cell is an analytic solution, small cells are not required to accurately compute the contributions from coarse structures with constant magnetization (e.g. a rectangular prism). For complex structures however, or to define surface topography more accurately, finer cells may be needed. Furthermore, cells do not need to be cubic. **Since the analytic solution is only valid outside the magnetized region, please do no place receivers within the Earth.**\n", "\n", @@ -425,7 +425,7 @@ "## Define the Active Cells\n", "\n", "Whereas cells below the Earth's surface contribute towards the simulated magnetic anomaly, air cells do not. \n", - "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -451,7 +451,7 @@ "source": [ "## Mapping from the Model to Active Cells\n", "\n", - "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be parameters defining a layered Earth. When simulating magnetic data using the integral formulation, we must define a mapping from the set of model parameters to the active cells in the mesh. Mappings are created using the [SimPEG.maps](myst:SimPEG#SimPEG.maps.IdentityMap) module. For the tutorial exercise, the model is the density contrast values for all active cells. As such, our mapping is an identity mapping, whose dimensions are equal to the number of active cells." + "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be parameters defining a layered Earth. When simulating magnetic data using the integral formulation, we must define a mapping from the set of model parameters to the active cells in the mesh. Mappings are created using the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module. For the tutorial exercise, the model is the density contrast values for all active cells. As such, our mapping is an identity mapping, whose dimensions are equal to the number of active cells." ] }, { @@ -492,9 +492,9 @@ "2) Define the remanent magnetization vector for each cell, once again in A/m.\n", "3) Sum the induced and remanent contributions.\n", "4) Normalize by the amplitude of inducing magnetic field intensity; i.e. $\\left | \\vec{H}_0 \\right |$ in units A/m. The resulting quantity is unitless (SI).\n", - "5) Re-organize the quantity as a 1D [numpy.ndarray](myst:numpy#numpy.ndarray) organized by vector component; i.e. np.r_[chi_1, chi_2, chi_3]\n", + "5) Re-organize the quantity as a 1D [numpy.ndarray](xref:numpy#numpy.ndarray) organized by vector component; i.e. np.r_[chi_1, chi_2, chi_3]\n", "\n", - "Here, the model consists of a susceptible and remanently magnetized sphere within a negligibly susceptible host. The horizontal components of the induced and remanent magnetization has been balance so that they cancel out, and the net magnetization is downward. We plot the magnetic vector models using the [plot_slice](myst:discretize#discretize.TreeMesh.plot_slice) method." + "Here, the model consists of a susceptible and remanently magnetized sphere within a negligibly susceptible host. The horizontal components of the induced and remanent magnetization has been balance so that they cancel out, and the net magnetization is downward. We plot the magnetic vector models using the [plot_slice](xref:discretize#discretize.TreeMesh.plot_slice) method." ] }, { @@ -699,7 +699,7 @@ "## Define the Forward Simulation\n", "\n", "In SimPEG, the physics of the forward simulation is defined by creating an instance of an appropriate simulation class.\n", - "In this case, we use the simulation class for the [3D integral formulation](myst:SimPEG#SimPEG.potential_fields.magnetics.Simulation3DIntegral). To fully define the forward simulation, we need to connect the simulation object to:\n", + "In this case, we use the simulation class for the [3D integral formulation](xref:simpeg#simpeg.potential_fields.magnetics.Simulation3DIntegral). To fully define the forward simulation, we need to connect the simulation object to:\n", "\n", "- the survey\n", "- the mesh\n", @@ -739,7 +739,7 @@ "source": [ "## Simulate Magnetic Gradiometry Data\n", "\n", - "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](myst:SimPEG#SimPEG.simulation.BaseSimulation.dpred) method. In SimPEG, magnetic gradiometry data values are in **nT/m.**" + "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](xref:simpeg#simpeg.simulation.BaseSimulation.dpred) method. In SimPEG, magnetic gradiometry data values are in **nT/m.**" ] }, { diff --git a/notebooks/04-magnetics/inv_magnetics_induced_3d.ipynb b/notebooks/04-magnetics/inv_magnetics_induced_3d.ipynb index 345e0e36..04a25660 100644 --- a/notebooks/04-magnetics/inv_magnetics_induced_3d.ipynb +++ b/notebooks/04-magnetics/inv_magnetics_induced_3d.ipynb @@ -70,7 +70,7 @@ "## Import Modules\n", "\n", "Here, we import all of the functionality required to run the notebook for the tutorial exercise.\n", - "All of the functionality specific to the forward simulation of magnetic data are imported from the [simpeg.potential_fields.magnetics](myst:simpeg#simpeg.potential_fields.magnetics) module. Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." + "All of the functionality specific to the forward simulation of magnetic data are imported from the [simpeg.potential_fields.magnetics](xref:simpeg#simpeg.potential_fields.magnetics) module. Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, { @@ -175,7 +175,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "For this tutorial, the data are organized within basic XYZ files. However, SimPEG does allow the user to import UBC-GIF formatted magnetic data files; see [read_mag3d_ubc](myst:simpeg#simpeg.utils.io_utils.read_mag3d_ubc)." + "For this tutorial, the data are organized within basic XYZ files. However, SimPEG does allow the user to import UBC-GIF formatted magnetic data files; see [read_mag3d_ubc](xref:simpeg#simpeg.utils.io_utils.read_mag3d_ubc)." ] }, { @@ -387,7 +387,7 @@ "source": [ "## Define the Data\n", "\n", - "The SimPEG [Data](myst:simpeg#simpeg.data.Data) class is required for inversion and connects the observed data, uncertainties and survey geometry." + "The SimPEG [Data](xref:simpeg#simpeg.data.Data) class is required for inversion and connects the observed data, uncertainties and survey geometry." ] }, { @@ -419,7 +419,7 @@ "source": [ "### Design a (Tensor) Mesh\n", "\n", - "Meshes are designed using the [discretize package](https://discretize.simpeg.xyz). Here, we design a [tensor mesh](myst:discretize#discretize.TensorMesh). See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating meshes. When designing a mesh for magnetic inversion, we must consider the spatial wavelengths of the signals contained within the data. If the data spacing is large and/or the signals present in the data are smooth, larger cells can be used to construct the mesh. If the data spacing is smaller and compact anomalies are observed, smaller cells are needed to characterize the structures responsible. And smaller cells are required when the effects of surface topography are significant.\n", + "Meshes are designed using the [discretize package](https://discretize.simpeg.xyz). Here, we design a [tensor mesh](xref:discretize#discretize.TensorMesh). See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating meshes. When designing a mesh for magnetic inversion, we must consider the spatial wavelengths of the signals contained within the data. If the data spacing is large and/or the signals present in the data are smooth, larger cells can be used to construct the mesh. If the data spacing is smaller and compact anomalies are observed, smaller cells are needed to characterize the structures responsible. And smaller cells are required when the effects of surface topography are significant.\n", "\n", "**General rule of thumb:** The minimum cell size in each direction is at most 0.5 - 1 times the station spacing. And the thickness of the padding is at least 1 - 2 times the width of the survey region." ] @@ -455,7 +455,7 @@ "### Define the Active Cells\n", "\n", "Whereas cells below the Earth's surface contribute towards simulated magnetic anomalies, air cells do not.\n", - "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -481,7 +481,7 @@ "source": [ "### Mapping from the Model to Active Cells\n", "\n", - "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For whatever model we choose, we must define a mapping from the set of model parameters (a [1D numpy.ndarray](myst:numpy#numpy.ndarray)) to the active cells in the mesh. Mappings are created using the [simpeg.maps](myst:simpeg#simpeg.maps.IdentityMap) module. For the tutorial exercise, the model is the susceptibility values for all active cells. As such, our mapping is an identity mapping, whose dimensions are equal to the number of active cells." + "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For whatever model we choose, we must define a mapping from the set of model parameters (a [1D numpy.ndarray](xref:numpy#numpy.ndarray)) to the active cells in the mesh. Mappings are created using the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module. For the tutorial exercise, the model is the susceptibility values for all active cells. As such, our mapping is an identity mapping, whose dimensions are equal to the number of active cells." ] }, { @@ -600,7 +600,7 @@ "source": [ "### Define the Forward Simulation\n", "\n", - "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for total magnetic intensity data was discussed in the [3D Forward Simulation of Total Magnetic Intensity Data](fwd_magnetics_anomaly_3d.ipynb) tutorial. Here, we use the [3D integral formulation](myst:simpeg#simpeg.potential_fields.magnetics.simulation.Simulation3DIntegral)." + "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for total magnetic intensity data was discussed in the [3D Forward Simulation of Total Magnetic Intensity Data](fwd_magnetics_anomaly_3d.ipynb) tutorial. Here, we use the [3D integral formulation](xref:simpeg#simpeg.potential_fields.magnetics.simulation.Simulation3DIntegral)." ] }, { @@ -642,7 +642,7 @@ "### Define the Data Misfit\n", "\n", "To understand the role of the data misfit in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/Uncertainties.html).\n", - "Here, we use the [L2DataMisfit](myst:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." + "Here, we use the [L2DataMisfit](xref:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." ] }, { @@ -667,7 +667,7 @@ "source": [ "### Define the Regularization\n", "\n", - "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). Here, we use the [WeightedLeastSquares](myst:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Here, length scales along x, y and z are used to balance the smallness and smoothness terms. And the reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros." + "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). Here, we use the [WeightedLeastSquares](xref:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Here, length scales along x, y and z are used to balance the smallness and smoothness terms. And the reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros." ] }, { @@ -700,7 +700,7 @@ "source": [ "### Define the Optimization Algorithm\n", "\n", - "Here, we use the [ProjectedGNCG](myst:simpeg#simpeg.optimization.ProjectedGNCG) class to solve the optimization problem using projected Gauss-Newton with conjugate gradietn solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches. Here, the `lower` property is set to 0 to ensure recovered susceptibility values are positive." + "Here, we use the [ProjectedGNCG](xref:simpeg#simpeg.optimization.ProjectedGNCG) class to solve the optimization problem using projected Gauss-Newton with conjugate gradietn solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches. Here, the `lower` property is set to 0 to ensure recovered susceptibility values are positive." ] }, { @@ -727,7 +727,7 @@ "source": [ "### Define the Inverse Problem\n", "\n", - "We use the [BaseInvProblem](myst:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." + "We use the [BaseInvProblem](xref:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." ] }, { @@ -754,15 +754,15 @@ "\n", "Directives represent operations that are carried out during the inversion. Here, we apply common directives for weighted least-squares inversion of magnetic data and describe their roles. These are:\n", "\n", - "- [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights): Apply sensitivity weighting to counteract the natural tendancy of potential field inversion to cluster recovered structures near the receivers. Because the 3D integral formulation is linear, the sensitivity weighting is independent of the model and does not need to be updated throughout the inversion, so we set `every_iteration=False`.\n", + "- [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights): Apply sensitivity weighting to counteract the natural tendancy of potential field inversion to cluster recovered structures near the receivers. Because the 3D integral formulation is linear, the sensitivity weighting is independent of the model and does not need to be updated throughout the inversion, so we set `every_iteration=False`.\n", "\n", - "- [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem.\n", + "- [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem.\n", "\n", - "- [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", + "- [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", "\n", - "- [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta.\n", + "- [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta.\n", "\n", - "- [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", + "- [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", "\n", "\n", "The directive objects are organized in a ``list``. Upon starting the inversion or updating the recovered model at each iteration, the inversion will call each directive within the list **in order**. The order of the directives matters, and SimPEG will throw an error if directives are organized into an improper order. Some directives, like the ``BetaEstimate_ByEig`` are only used when starting the inversion. Other directives, like ``UpdatePreconditionner``, are used whenever the model is updated." @@ -802,7 +802,7 @@ "source": [ "### Define and Run the Inversion\n", "\n", - "We define the inversion using the [BaseInversion](myst:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" + "We define the inversion using the [BaseInversion](xref:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" ] }, { @@ -1134,7 +1134,7 @@ "source": [ "### Design a (Tree) Mesh\n", "\n", - "Here, we design a [tree mesh](myst:discretize#discretize.TreeMesh). See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating tree meshes. The same approach used to construct the tensor mesh used in the weighted least-squares inversion example applies to tree meshes." + "Here, we design a [tree mesh](xref:discretize#discretize.TreeMesh). See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating tree meshes. The same approach used to construct the tensor mesh used in the weighted least-squares inversion example applies to tree meshes." ] }, { @@ -1313,7 +1313,7 @@ "source": [ "### Define the Regularization\n", "\n", - "Here, we use the [Sparse](myst:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Here, the scaling constants that balance the smallness and smoothness terms are set directly. Equal emphasis on smallness and smoothness is generally applied by using the inverse square of the smallest cell dimension. The reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros. Here, we apply a 0-norm to the smallness term and a 1-norm to first-order smoothness along the x, y and z directions." + "Here, we use the [Sparse](xref:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Here, the scaling constants that balance the smallness and smoothness terms are set directly. Equal emphasis on smallness and smoothness is generally applied by using the inverse square of the smallest cell dimension. The reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros. Here, we apply a 0-norm to the smallness term and a 1-norm to first-order smoothness along the x, y and z directions." ] }, { @@ -1396,9 +1396,9 @@ "source": [ "### Provide Inversion Directives\n", "\n", - "Here, we create common directives for IRLS inversion of total magnetic intensity data and describe their roles. In additon to the [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig) (described before), inversion with sparse-norms requires the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive.\n", + "Here, we create common directives for IRLS inversion of total magnetic intensity data and describe their roles. In additon to the [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig) (described before), inversion with sparse-norms requires the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive.\n", "\n", - "You will notice that we don't use the [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property. " + "You will notice that we don't use the [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property. " ] }, { diff --git a/notebooks/05-dcr/fwd_dcr_1d.ipynb b/notebooks/05-dcr/fwd_dcr_1d.ipynb index aed5d848..1e9691a3 100644 --- a/notebooks/05-dcr/fwd_dcr_1d.ipynb +++ b/notebooks/05-dcr/fwd_dcr_1d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** Here we use the module [simpeg.electromagnetics.static.resistivity](myst:simpeg#simpeg.electromagnetics.static.resistivity) to simulate 1D apparent resistivity data for a 1D Wenner array. The [Simulation1DLayers](myst:simpeg#simpeg.electromagnetics.static.resistivity.simulation_1d.Simulation1DLayers) class is used to solve the problem via a semi-analytic Hankel transform solution.\n", + "**Summary:** Here we use the module [simpeg.electromagnetics.static.resistivity](xref:simpeg#simpeg.electromagnetics.static.resistivity) to simulate 1D apparent resistivity data for a 1D Wenner array. The [Simulation1DLayers](xref:simpeg#simpeg.electromagnetics.static.resistivity.simulation_1d.Simulation1DLayers) class is used to solve the problem via a semi-analytic Hankel transform solution.\n", "\n", "
\n", "\n", @@ -58,8 +58,8 @@ "source": [ "## Import Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to DC resistivity is imported from [simpeg.electromagnetics.static.resistivity](myst:simpeg#simpeg.electromagnetics.static.resistivity).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils)." + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to DC resistivity is imported from [simpeg.electromagnetics.static.resistivity](xref:simpeg#simpeg.electromagnetics.static.resistivity).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils)." ] }, { @@ -99,9 +99,9 @@ "\n", "DC resistivity surveys within SimPEG require the user to create and connect three types of objects:\n", "\n", - "- [receivers](myst:simpeg#simpeg.electromagnetics.static.resistivity.receivers.BaseRx): which defines the locations of the potential (or MN) electrodes and the type of data; e.g. 'volt' for normalized voltage in V/A or 'apparent_resistivity' for apparent resistivity in $\\Omega m$. *Note only M electrode locations are needed to define pole receivers*.\n", - "- [sources](myst:simpeg#simpeg.electromagnetics.static.resistivity.sources.BaseSrc): which defines the locations of the current (or AB) electrodes, and their associated receivers. *Note only A electrode locations are needed to define pole sources*.\n", - "- [survey](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey): the object which stores and organizes all of the sources and receivers.\n", + "- [receivers](xref:simpeg#simpeg.electromagnetics.static.resistivity.receivers.BaseRx): which defines the locations of the potential (or MN) electrodes and the type of data; e.g. 'volt' for normalized voltage in V/A or 'apparent_resistivity' for apparent resistivity in $\\Omega m$. *Note only M electrode locations are needed to define pole receivers*.\n", + "- [sources](xref:simpeg#simpeg.electromagnetics.static.resistivity.sources.BaseSrc): which defines the locations of the current (or AB) electrodes, and their associated receivers. *Note only A electrode locations are needed to define pole sources*.\n", + "- [survey](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey): the object which stores and organizes all of the sources and receivers.\n", "\n", "Each datum corresponds to a unique pair of current and potential electrodes. When running the 1D forward simulation, the horizontal position is taken into account and we assume the electrodes are placed at the Earth's surface. Therefore electrode locations can be defined by an xyz location, but the vertical position is ignored." ] @@ -253,13 +253,13 @@ "source": [ "## Define a Model and Mapping\n", "\n", - "In SimPEG, the term 'model' is not necessarily synonymous with a set of physical property values. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](myst:numpy#numpy.ndarray) whose lengths are equal to the number of model parameters.\n", + "In SimPEG, the term 'model' is not necessarily synonymous with a set of physical property values. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](xref:numpy#numpy.ndarray) whose lengths are equal to the number of model parameters.\n", "\n", "Classes within the ``simpeg.maps`` module are used to define the mapping that connects the model to the parameters required to run the DC resistivity simulation; i.e. layer thicknesses and layer conductivities/resistivities. Here, we demonstrate two types of mappings and models that may be used for 1D DC resistivity simulation.\n", "\n", - "**1. Resistivity model:** For forward simulation, the easiest approach is to define the model as the layer resistivities and hard-code the layer thicknesses into simulation. In this case, the mapping from the model to the resistivities is defined using the [simpeg.maps.IdentityMap](myst:simpeg#simpeg.maps.IdentityMap) class.\n", + "**1. Resistivity model:** For forward simulation, the easiest approach is to define the model as the layer resistivities and hard-code the layer thicknesses into simulation. In this case, the mapping from the model to the resistivities is defined using the [simpeg.maps.IdentityMap](xref:simpeg#simpeg.maps.IdentityMap) class.\n", "\n", - "**2. Parametric layered Earth model:** In this case, the model defines the layer thicknesses and log-conductivities. We therefore need a mapping that extracts layer thicknesses from the model, and a mapping that extracts log-conductivities from the model and converts them into conductivities. For this, we require the [simpeg.maps.Wires](myst:simpeg#simpeg.maps.Wires) mapping and [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) mapping classes. Note that successive mappings can be chained together using the $*$ operator." + "**2. Parametric layered Earth model:** In this case, the model defines the layer thicknesses and log-conductivities. We therefore need a mapping that extracts layer thicknesses from the model, and a mapping that extracts log-conductivities from the model and converts them into conductivities. For this, we require the [simpeg.maps.Wires](xref:simpeg#simpeg.maps.Wires) mapping and [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) mapping classes. Note that successive mappings can be chained together using the $*$ operator." ] }, { @@ -295,7 +295,7 @@ "source": [ "## Define the Forward Simulation\n", "\n", - "In SimPEG, the physics of the forward simulation is defined by creating an instance of an appropriate simulation class. Here, we use the [Simulation1DLayers](myst:simpeg#simpeg.electromagnetics.static.resistivity.Simulation1DLayers) which simulates the data according to a 1D Hankel transform solution. To fully define the forward simulation, we need to connect the simulation object to:\n", + "In SimPEG, the physics of the forward simulation is defined by creating an instance of an appropriate simulation class. Here, we use the [Simulation1DLayers](xref:simpeg#simpeg.electromagnetics.static.resistivity.Simulation1DLayers) which simulates the data according to a 1D Hankel transform solution. To fully define the forward simulation, we need to connect the simulation object to:\n", "\n", "- the survey\n", "- the layer thicknesses\n", @@ -354,7 +354,7 @@ "source": [ "## Predict DC Resistivity Data\n", "\n", - "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](myst:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the model, the data predicted by both simulations is equivalent because data are being modeled for the same 1D layered Earth." + "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](xref:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the model, the data predicted by both simulations is equivalent because data are being modeled for the same 1D layered Earth." ] }, { diff --git a/notebooks/05-dcr/fwd_dcr_2d.ipynb b/notebooks/05-dcr/fwd_dcr_2d.ipynb index 225ad963..fb7c8ad8 100644 --- a/notebooks/05-dcr/fwd_dcr_2d.ipynb +++ b/notebooks/05-dcr/fwd_dcr_2d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** Here we use the module [simpeg.electromagnetics.static.resistivity](myst:simpeg#simpeg.electromagnetics.static.resistivity) to simulate DC resistivity data when the local geology doesn't change along the strike direction. Here, we use a 2.5D simulation approach to leverage the symmetry of the problem and avoid the higher computational cost associated with full 3D simulations.\n", + "**Summary:** Here we use the module [simpeg.electromagnetics.static.resistivity](xref:simpeg#simpeg.electromagnetics.static.resistivity) to simulate DC resistivity data when the local geology doesn't change along the strike direction. Here, we use a 2.5D simulation approach to leverage the symmetry of the problem and avoid the higher computational cost associated with full 3D simulations.\n", "\n", "
\n", "\n", @@ -58,8 +58,8 @@ "source": [ "## Import Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to DC resistivity is imported from [simpeg.electromagnetics.static.resistivity](myst:simpeg#simpeg.electromagnetics.static.resistivity).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To simulate DC resistivity data, we need to define our problem geometry on a numerical grid (or mesh).\n", + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to DC resistivity is imported from [simpeg.electromagnetics.static.resistivity](xref:simpeg#simpeg.electromagnetics.static.resistivity).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To simulate DC resistivity data, we need to define our problem geometry on a numerical grid (or mesh).\n", "To generate the mesh, we used the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, @@ -111,8 +111,8 @@ "source": [ "## Define the Topography\n", "\n", - "True surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray).\n", - "For use in a 2.5D simulation however, topography is defined as an (N, 2) [numpy.ndarray](myst:numpy#numpy.ndarray), where the first coordinate represent along-line position and the second coordinate represents the vertical position. Here, we define the 2D topography used for the 2.5D simulation." + "True surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray).\n", + "For use in a 2.5D simulation however, topography is defined as an (N, 2) [numpy.ndarray](xref:numpy#numpy.ndarray), where the first coordinate represent along-line position and the second coordinate represents the vertical position. Here, we define the 2D topography used for the 2.5D simulation." ] }, { @@ -186,9 +186,9 @@ "\n", "DC (and IP) surveys within SimPEG require the user to create and connect three types of objects:\n", "\n", - "- [receivers](myst:simpeg#simpeg.electromagnetics.static.resistivity.receivers.BaseRx): which defines the locations of the potential (or MN) electrodes and the type of data; e.g. 'volt' for normalized voltage (V/A), 'apparent_resistivity' for apparent resistivity ($\\Omega m$) or 'apparent_chargeability' for apparent chargeability (unitless). *Note only M electrode locations are needed to define pole receivers*.\n", - "- [sources](myst:simpeg#simpeg.electromagnetics.static.resistivity.sources.BaseSrc): which defines the locations of the current (or AB) electrodes, and their associated receivers. *Note only A electrode locations are needed to define pole sources*.\n", - "- [survey](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey): the object which stores and organizes all of the sources and receivers.\n", + "- [receivers](xref:simpeg#simpeg.electromagnetics.static.resistivity.receivers.BaseRx): which defines the locations of the potential (or MN) electrodes and the type of data; e.g. 'volt' for normalized voltage (V/A), 'apparent_resistivity' for apparent resistivity ($\\Omega m$) or 'apparent_chargeability' for apparent chargeability (unitless). *Note only M electrode locations are needed to define pole receivers*.\n", + "- [sources](xref:simpeg#simpeg.electromagnetics.static.resistivity.sources.BaseSrc): which defines the locations of the current (or AB) electrodes, and their associated receivers. *Note only A electrode locations are needed to define pole sources*.\n", + "- [survey](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey): the object which stores and organizes all of the sources and receivers.\n", "\n", "Each DC/IP datum corresponds to a unique pair of current and potential electrode locations. Within the SimPEG framework, there is a standard way in which the electrodes are organized. Because each current source (pole or dipole) is discretized to form a separate right-hand side for the DC resistivity PDE, each source object defines the electrodes for a single source. But for each source object, we can instantiate a single receiver object to store the electrode locations of all potential electrodes.\n", "\n", @@ -201,7 +201,7 @@ "source": [ "**Option A: Define each source and its associated receivers directly**\n", "\n", - "For a 2.5D simulation, current electrode locations are defined as (2,) [numpy.array](myst:numpy#numpy.array) and the associated set of potential electrode locations are defined as (N, 2) [numpy.ndarray](myst:numpy#numpy.ndarray). We can define [Pole](myst:simpeg#simpeg.electromagnetics.static.resistivity.sources.Pole) or [Dipole](myst:simpeg#simpeg.electromagnetics.static.resistivity.sources.Dipole) sources. And we can define [Pole](myst:simpeg#simpeg.electromagnetics.static.resistivity.receivers.Pole) or [Dipole](myst:simpeg#simpeg.electromagnetics.static.resistivity.receivers.Dipole) receivers.\n", + "For a 2.5D simulation, current electrode locations are defined as (2,) [numpy.array](xref:numpy#numpy.array) and the associated set of potential electrode locations are defined as (N, 2) [numpy.ndarray](xref:numpy#numpy.ndarray). We can define [Pole](xref:simpeg#simpeg.electromagnetics.static.resistivity.sources.Pole) or [Dipole](xref:simpeg#simpeg.electromagnetics.static.resistivity.sources.Dipole) sources. And we can define [Pole](xref:simpeg#simpeg.electromagnetics.static.resistivity.receivers.Pole) or [Dipole](xref:simpeg#simpeg.electromagnetics.static.resistivity.receivers.Dipole) receivers.\n", "\n", "Here, the survey consists of an 800 m long EW dipole-dipole line with an electrode spacing of 40 m. There is a maximum of 10 potential electrodes per current electrode. And the data defined by the receivers are current-normalized voltages in **V/A**." ] @@ -320,7 +320,7 @@ "source": [ "**Option B: Survey from ABMN electrode locations**\n", "\n", - "If we have (N, 2) [numpy.ndarray](myst:numpy#numpy.ndarray) for A, B, M and N electrode locations for each datum (loaded or created), we can use the [generate_survey_from_abmn_locations](myst:simpeg#simpeg.electromagnetics.static.utils.generate_survey_from_abmn_locations) to generate the survey automatically." + "If we have (N, 2) [numpy.ndarray](xref:numpy#numpy.ndarray) for A, B, M and N electrode locations for each datum (loaded or created), we can use the [generate_survey_from_abmn_locations](xref:simpeg#simpeg.electromagnetics.static.utils.generate_survey_from_abmn_locations) to generate the survey automatically." ] }, { @@ -329,7 +329,7 @@ "source": [ "**Option C: Survey from a set of survey lines**\n", "\n", - "If the survey is comprised of a single DC resistivity line, we can use the [generate_dcip_sources_line](myst:simpeg#simpeg.electromagnetics.static.utils.generate_dcip_sources_line) utility function to define the source list. I.e.:\n", + "If the survey is comprised of a single DC resistivity line, we can use the [generate_dcip_sources_line](xref:simpeg#simpeg.electromagnetics.static.utils.generate_dcip_sources_line) utility function to define the source list. I.e.:\n", "\n", "```\n", "# Generate source list for DC survey line\n", @@ -395,7 +395,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we plot the electrode locations. We use the [pseudo_locations](myst:simpeg#simpeg.electromagnetics.static.utils.pseudo_locations) utility to extract the pseudo-locations." + "Here we plot the electrode locations. We use the [pseudo_locations](xref:simpeg#simpeg.electromagnetics.static.utils.pseudo_locations) utility to extract the pseudo-locations." ] }, { @@ -439,7 +439,7 @@ "## Design a (Tree) Mesh\n", "\n", "Meshes are designed using the [discretize](https://discretize.simpeg.xyz/en/main) package. See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating meshes.\n", - "Here, the forward simulation is computed for a [tree mesh](myst:discretize#discretize.TreeMesh). Because of the modular nature of SimPEG, you could define a [tensor mesh](myst:discretize#discretize.TensorMesh) instead.\n", + "Here, the forward simulation is computed for a [tree mesh](xref:discretize#discretize.TreeMesh). Because of the modular nature of SimPEG, you could define a [tensor mesh](xref:discretize#discretize.TensorMesh) instead.\n", "\n", "**Standard approach for DC/IP:** The electric potential produced by a current electrode falls off as $r^{-3}$. So smaller cells are needed near the current electrodes to model the fields accurately, and larger cells can be used away from the current electrodes where the fields are smooth. Tree meshes are well-suited for DC (and IP) simulation because the cell size can be increased at specified distances from the current electrodes. For DC resistivity meshing, we advise the following considerations and rules of thumb:\n", "\n", @@ -449,7 +449,7 @@ "4. The increase in cell size at increasing distances from the current electrodes should not happen too abruptly. At each cell size, you should have a layer at least 4 cells thick before increasing the cell size.\n", "5. Finer discretization is required when topography is significant.\n", "\n", - "**Tutorial mesh:** Here, a minimum cell width of 4 m (or 1/10 the minimum electrode spacing) is used within our survey region. The largest electrode spacing was 400 m, so a the padding was extended at least 1200 m from the survey region. Using the [refine_surface](myst:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](myst:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](myst:discretize#discretize.TreeMesh) API to see additional refinement methods." + "**Tutorial mesh:** Here, a minimum cell width of 4 m (or 1/10 the minimum electrode spacing) is used within our survey region. The largest electrode spacing was 400 m, so a the padding was extended at least 1200 m from the survey region. Using the [refine_surface](xref:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](xref:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](xref:discretize#discretize.TreeMesh) API to see additional refinement methods." ] }, { @@ -591,7 +591,7 @@ "source": [ "## Define the Active Cells\n", "\n", - "Simulated geophysical data are dependent on the subsurface distribution of physical property values. As a result, the cells lying below the surface topography are commonly referred to as 'active cells'. And air cells, whose physical property values are fixed, are commonly referred to as 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "Simulated geophysical data are dependent on the subsurface distribution of physical property values. As a result, the cells lying below the surface topography are commonly referred to as 'active cells'. And air cells, whose physical property values are fixed, are commonly referred to as 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -620,10 +620,10 @@ "source": [ "## Models and Mappings\n", "\n", - "In SimPEG, the term 'model' is not necessarily synonymous with the set of physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](myst:numpy#numpy.ndarray) whose lengths are\n", + "In SimPEG, the term 'model' is not necessarily synonymous with the set of physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](xref:numpy#numpy.ndarray) whose lengths are\n", "equal to the number of model parameters.\n", "\n", - "Classes within the [simpeg.maps](myst:simpeg#simpeg.maps.IdentityMap) module are used to define the mapping that connects the model to the physical property values used in the DC resistivity simulation. Sophisticated mappings can be defined by combining multiple mapping objects. But in the simplest case, the mapping is an identity map and the model consists of the conductivity/resistivity values for all mesh cells (including air).\n", + "Classes within the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module are used to define the mapping that connects the model to the physical property values used in the DC resistivity simulation. Sophisticated mappings can be defined by combining multiple mapping objects. But in the simplest case, the mapping is an identity map and the model consists of the conductivity/resistivity values for all mesh cells (including air).\n", "\n", "When simulating DC resistivity data, we have the choice of using resistivity or conductivity to define the Earth's electrical properties. Here, we define the model and its associate mapping for two cases:\n", "1. The model consists of the conductivity values for all active cells\n", @@ -694,9 +694,9 @@ "source": [ "### Mapping from the Model to the Mesh\n", "\n", - "For our first case, we use the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) mapping. This mapping projects quantities defined on the active cells to the entire mesh, and sets a constant value for all inactive cells. **Important:** we set all inactive (air) cells to 1e-8 S/m instead of 0. This is done to ensure that the linear system constructed to solve the PDE for the DC resistivity problem is well-conditioned.\n", + "For our first case, we use the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) mapping. This mapping projects quantities defined on the active cells to the entire mesh, and sets a constant value for all inactive cells. **Important:** we set all inactive (air) cells to 1e-8 S/m instead of 0. This is done to ensure that the linear system constructed to solve the PDE for the DC resistivity problem is well-conditioned.\n", "\n", - "For the second case, we both the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) and [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) mappings; the latter of which takes the natural exponential. **Important:** we set all inactive (air) cells to 1e8 $\\Omega m$ instead of $\\infty$. Once again, this is done to ensure that the linear system constructed to solve the PDE for the DC resistivity problem is well-conditioned." + "For the second case, we both the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) and [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) mappings; the latter of which takes the natural exponential. **Important:** we set all inactive (air) cells to 1e8 $\\Omega m$ instead of $\\infty$. Once again, this is done to ensure that the linear system constructed to solve the PDE for the DC resistivity problem is well-conditioned." ] }, { @@ -727,7 +727,7 @@ "source": [ "### Plot the Model\n", "\n", - "To show the geometry of the problem, we plot the conductivity model using the [plot_slice](myst:discretize#discretize.TreeMesh.plot_slice) method." + "To show the geometry of the problem, we plot the conductivity model using the [plot_slice](xref:discretize#discretize.TreeMesh.plot_slice) method." ] }, { @@ -803,7 +803,7 @@ "source": [ "## Project Electrodes to Discretized Topography\n", "\n", - "Surface DC resistivity data will not be modeled accurately if the electrodes are modeled as living above or below the surface. It is especially problematic when electrodes are modeled as living in the air. Prior to simulating surface DC resistivity data, we must project the electrodes from their true elevation to the surface of the *discretized* topography. This is done using the [drape_electrodes_on_topography](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method." + "Surface DC resistivity data will not be modeled accurately if the electrodes are modeled as living above or below the surface. It is especially problematic when electrodes are modeled as living in the air. Prior to simulating surface DC resistivity data, we must project the electrodes from their true elevation to the surface of the *discretized* topography. This is done using the [drape_electrodes_on_topography](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method." ] }, { @@ -830,8 +830,8 @@ "\n", "In SimPEG, the physics of the forward simulation is defined by creating an instance of an appropriate simulation class. There are two simulation classes which may be used to simulate 2.5D DC resistivity data:\n", "\n", - "- [Simulation2DNodel](myst:simpeg#simpeg.electromagnetics.static.resistivity.Simulation2DNodal), which defines the discrete electric potentials on mesh nodes.\n", - "- [Simulation2DCellCentered](myst:simpeg#simpeg.electromagnetics.static.resistivity.Simulation2DCellCentered), which defines the discrete electric potentials at cell centers.\n", + "- [Simulation2DNodel](xref:simpeg#simpeg.electromagnetics.static.resistivity.Simulation2DNodal), which defines the discrete electric potentials on mesh nodes.\n", + "- [Simulation2DCellCentered](xref:simpeg#simpeg.electromagnetics.static.resistivity.Simulation2DCellCentered), which defines the discrete electric potentials at cell centers.\n", "\n", "For surface DC resistivity data, the nodal formulation is more well-suited and will be used here. The cell-centered formulation works well for simulating borehole DC resistivity data. To fully define the forward simulation, we need to connect the simulation object to:\n", "\n", @@ -872,7 +872,7 @@ "source": [ "## Predict DC Resistivity Data\n", "\n", - "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](myst:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the models representing the Earth's electrical properties, the data predicted by both simulations is equivalent." + "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](xref:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the models representing the Earth's electrical properties, the data predicted by both simulations is equivalent." ] }, { diff --git a/notebooks/05-dcr/fwd_dcr_3d.ipynb b/notebooks/05-dcr/fwd_dcr_3d.ipynb index 1e59afe6..ec7dc9cc 100644 --- a/notebooks/05-dcr/fwd_dcr_3d.ipynb +++ b/notebooks/05-dcr/fwd_dcr_3d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** Here we use the module [simpeg.electromagnetics.static.resistivity](myst:simpeg#simpeg.electromagnetics.static.resistivity) to simulate 3D DC resistivity data on a tree mesh. Most of the functionality required for this tutorial was presented in the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial. We strongly urge the reader to work through the 2.5D tutorial prior to working through this one, as we will avoid verbose repitition of content.\n", + "**Summary:** Here we use the module [simpeg.electromagnetics.static.resistivity](xref:simpeg#simpeg.electromagnetics.static.resistivity) to simulate 3D DC resistivity data on a tree mesh. Most of the functionality required for this tutorial was presented in the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial. We strongly urge the reader to work through the 2.5D tutorial prior to working through this one, as we will avoid verbose repitition of content.\n", "\n", "
\n", "\n", @@ -58,8 +58,8 @@ "source": [ "## Import Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to DC resistivity is imported from [simpeg.electromagnetics.static.resistivity](myst:simpeg#simpeg.electromagnetics.static.resistivity).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To simulate DC resistivity data, we need to define our problem geometry on a numerical grid (or mesh).\n", + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to DC resistivity is imported from [simpeg.electromagnetics.static.resistivity](xref:simpeg#simpeg.electromagnetics.static.resistivity).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To simulate DC resistivity data, we need to define our problem geometry on a numerical grid (or mesh).\n", "To generate the mesh, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, @@ -122,7 +122,7 @@ "source": [ "## Define the Topography\n", "\n", - "Surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) for 3D simulations.\n", + "Surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) for 3D simulations.\n", "Here, we create basic topography for the forward simulation.\n", "For user-specific simulations, you may load topography from an XYZ file." ] @@ -221,7 +221,7 @@ "source": [ "**Option A: Define each source and its associated receivers directly**\n", "\n", - "We used this approach in our [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial. For a 3D simulation however, current electrode locations are defined as (3,) [numpy.array](myst:numpy#numpy.array) and the associated set of potential electrode locations are defined as (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray). This approach is somewhat cumbersome for generating synthetic 3D examples, so we will use a survey generation utility instead (Option C)." + "We used this approach in our [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial. For a 3D simulation however, current electrode locations are defined as (3,) [numpy.array](xref:numpy#numpy.array) and the associated set of potential electrode locations are defined as (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray). This approach is somewhat cumbersome for generating synthetic 3D examples, so we will use a survey generation utility instead (Option C)." ] }, { @@ -230,7 +230,7 @@ "source": [ "**Option B: Survey from ABMN electrode locations**\n", "\n", - "If we have (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) containing the A, B, M and N electrode locations for each datum (loaded or created), we can use the [generate_survey_from_abmn_locations](myst:simpeg#simpeg.electromagnetics.static.utils.generate_survey_from_abmn_locations) to generate the survey automatically." + "If we have (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) containing the A, B, M and N electrode locations for each datum (loaded or created), we can use the [generate_survey_from_abmn_locations](xref:simpeg#simpeg.electromagnetics.static.utils.generate_survey_from_abmn_locations) to generate the survey automatically." ] }, { @@ -239,7 +239,7 @@ "source": [ "**Option C: Survey from a set of survey lines**\n", "\n", - "If the survey is comprised of a set of DC resistivity lines, we can use the [generate_dcip_sources_line](myst:simpeg#simpeg.electromagnetics.static.utils.generate_dcip_sources_line) utility function to define the survey. Here we define the DC resistivity survey that is used simulate the tutorial data. The survey consists of 3 DC resistivity lines that use a dipole-dipole electrode configuration; 1 line along the East-West direction and 2 lines along the North-South direction. Each line is 2000 m in length and has an electrode spacing of 100 m." + "If the survey is comprised of a set of DC resistivity lines, we can use the [generate_dcip_sources_line](xref:simpeg#simpeg.electromagnetics.static.utils.generate_dcip_sources_line) utility function to define the survey. Here we define the DC resistivity survey that is used simulate the tutorial data. The survey consists of 3 DC resistivity lines that use a dipole-dipole electrode configuration; 1 line along the East-West direction and 2 lines along the North-South direction. Each line is 2000 m in length and has an electrode spacing of 100 m." ] }, { @@ -292,7 +292,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here we plot the electrode locations. We use the [unique_electrode_locations](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey.unique_electrode_locations) method to extract the unique electrode locations from the survey and the [pseudo_locations](myst:simpeg#simpeg.electromagnetics.static.utils.pseudo_locations) utility to extract the pseudo-location." + "Here we plot the electrode locations. We use the [unique_electrode_locations](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey.unique_electrode_locations) method to extract the unique electrode locations from the survey and the [pseudo_locations](xref:simpeg#simpeg.electromagnetics.static.utils.pseudo_locations) utility to extract the pseudo-location." ] }, { @@ -345,7 +345,7 @@ "\n", "**Standard approach for DC/IP:** The standard approach presented in the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial also applies to forward simulations in 3D. And the same methods are used to refine the tree mesh around electrodes, topography, etc... For 3D simulations however, we may need to consider limitations in computational resources which are not encountered in 2.5D simulations. Because 3D simulations require discretization along a third direction, the number of cells in the mesh is proportional $h^{-3}$; where $h$ is the minimum cell edge length. Therefore the minimum cell size used for 3D simulations is generally coarser than the minimum cell size used for 2.5D simulations.\n", "\n", - "**Tutorial mesh:** Here, a minimum cell width of 25 m (or 1/4 the minimum electrode spacing) is used within our survey region. The largest electrode spacing was 1000 m, so a the padding was extended at least 3000 m from the survey region. Using the [refine_surface](myst:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](myst:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](myst:discretize#discretize.TreeMesh) API to see additional refinement methods." + "**Tutorial mesh:** Here, a minimum cell width of 25 m (or 1/4 the minimum electrode spacing) is used within our survey region. The largest electrode spacing was 1000 m, so a the padding was extended at least 3000 m from the survey region. Using the [refine_surface](xref:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](xref:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](xref:discretize#discretize.TreeMesh) API to see additional refinement methods." ] }, { @@ -398,7 +398,7 @@ "source": [ "## Define the Active Cells\n", "\n", - "Simulated geophysical data are dependent on the subsurface distribution of physical property values. As a result, the cells lying below the surface topography are commonly referred to as 'active cells'. And air cells, whose physical property values are fixed, are commonly referred to as 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "Simulated geophysical data are dependent on the subsurface distribution of physical property values. As a result, the cells lying below the surface topography are commonly referred to as 'active cells'. And air cells, whose physical property values are fixed, are commonly referred to as 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -427,10 +427,10 @@ "source": [ "## Models and Mappings\n", "\n", - "In SimPEG, the term 'model' is not necessarily synonymous with the set of physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](myst:numpy#numpy.ndarray) whose lengths are\n", + "In SimPEG, the term 'model' is not necessarily synonymous with the set of physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](xref:numpy#numpy.ndarray) whose lengths are\n", "equal to the number of model parameters.\n", "\n", - "Classes within the [simpeg.maps](myst:simpeg#simpeg.maps.IdentityMap) module are used to define the mapping that connects the model to the physical property values used in the DC resistivity simulation. Sophisticated mappings can be defined by combining multiple mapping objects. But in the simplest case, the mapping is an identity map and the model consists of the conductivity/resistivity values for all mesh cells (including air).\n", + "Classes within the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module are used to define the mapping that connects the model to the physical property values used in the DC resistivity simulation. Sophisticated mappings can be defined by combining multiple mapping objects. But in the simplest case, the mapping is an identity map and the model consists of the conductivity/resistivity values for all mesh cells (including air).\n", "\n", "When simulating DC resistivity data, we have the choice of using resistivity or conductivity to define the Earth's electrical properties. Here, we define the model and its associate mapping for two cases:\n", "1. The model consists of the conductivity values for all active cells\n", @@ -502,9 +502,9 @@ "source": [ "### Mapping from the Model to the Mesh\n", "\n", - "For our first case, we use the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) mapping. This mapping projects quantities defined on the active cells to the entire mesh, and sets a constant value for all inactive cells. **Important:** we set all inactive (air) cells to 1e-8 S/m instead of 0. This is done to ensure that the linear system constructed to solve the PDE for the DC resistivity problem is well-conditioned.\n", + "For our first case, we use the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) mapping. This mapping projects quantities defined on the active cells to the entire mesh, and sets a constant value for all inactive cells. **Important:** we set all inactive (air) cells to 1e-8 S/m instead of 0. This is done to ensure that the linear system constructed to solve the PDE for the DC resistivity problem is well-conditioned.\n", "\n", - "For the second case, we use both the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) and [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) mappings; the latter of which takes the natural exponential. **Important:** we set all inactive (air) cells to 1e8 $\\Omega m$ instead of $\\infty$. Once again, this is done to ensure that the linear system constructed to solve the PDE for the DC resistivity problem is well-conditioned." + "For the second case, we use both the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) and [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) mappings; the latter of which takes the natural exponential. **Important:** we set all inactive (air) cells to 1e8 $\\Omega m$ instead of $\\infty$. Once again, this is done to ensure that the linear system constructed to solve the PDE for the DC resistivity problem is well-conditioned." ] }, { @@ -535,7 +535,7 @@ "source": [ "### Plot the Model\n", "\n", - "To show the geometry of the problem, we plot the conductivity model using the [plot_slice](myst:discretize#discretize.TreeMesh.plot_slice) method." + "To show the geometry of the problem, we plot the conductivity model using the [plot_slice](xref:discretize#discretize.TreeMesh.plot_slice) method." ] }, { @@ -611,7 +611,7 @@ "source": [ "## Project Electrodes to Discretized Topography\n", "\n", - "Surface DC resistivity data will not be modeled accurately if the electrodes are modeled as living above or below the surface. It is especially problematic when electrodes are modeled as living in the air. Prior to simulating surface DC resistivity data, we must project the electrodes from their true elevation to the surface of the *discretized* topography. This is done using the [drape_electrodes_on_topography](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method." + "Surface DC resistivity data will not be modeled accurately if the electrodes are modeled as living above or below the surface. It is especially problematic when electrodes are modeled as living in the air. Prior to simulating surface DC resistivity data, we must project the electrodes from their true elevation to the surface of the *discretized* topography. This is done using the [drape_electrodes_on_topography](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method." ] }, { @@ -638,8 +638,8 @@ "\n", "In SimPEG, the physics of the forward simulation is defined by creating an instance of an appropriate simulation class. There are two simulation classes which may be used to simulate 3D DC resistivity data:\n", "\n", - "- [Simulation3DNodel](myst:simpeg#simpeg.electromagnetics.static.resistivity.Simulation3DNodal), which defines the discrete electric potentials on mesh nodes.\n", - "- [Simulation3DCellCentered](myst:simpeg#simpeg.electromagnetics.static.resistivity.Simulation3DCellCentered), which defines the discrete electric potentials at cell centers.\n", + "- [Simulation3DNodel](xref:simpeg#simpeg.electromagnetics.static.resistivity.Simulation3DNodal), which defines the discrete electric potentials on mesh nodes.\n", + "- [Simulation3DCellCentered](xref:simpeg#simpeg.electromagnetics.static.resistivity.Simulation3DCellCentered), which defines the discrete electric potentials at cell centers.\n", "\n", "For surface DC resistivity data, the nodal formulation is more well-suited and will be used here. The cell-centered formulation works well for simulating borehole DC resistivity data. Here, we define two simulation objects, one where the model defines the subsurface conductivities, and one where the model defines subsurface log-resistivities. When our model is used to define subsurface electric conductivity, the mapping is set using the ``sigmaMap`` keyword argument. However when our model is used to define subsurface electric resistivity, the mapping must be set using the ``rhoMap`` keyword argument" ] @@ -674,7 +674,7 @@ "source": [ "## Predict DC Resistivity Data\n", "\n", - "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](myst:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the models representing the Earth's electrical properties, the data predicted by both simulations is equivalent." + "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](xref:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the models representing the Earth's electrical properties, the data predicted by both simulations is equivalent." ] }, { diff --git a/notebooks/05-dcr/inv_dcr_1d.ipynb b/notebooks/05-dcr/inv_dcr_1d.ipynb index 32e0b2b6..ef109d5c 100644 --- a/notebooks/05-dcr/inv_dcr_1d.ipynb +++ b/notebooks/05-dcr/inv_dcr_1d.ipynb @@ -66,7 +66,7 @@ "## Import Modules\n", "\n", "Here, we import all of the functionality required to run the notebook for the tutorial exercise.\n", - "All of the functionality specific to the forward simulation of 1D DC resistivity data are imported from the [simpeg.electromagnetics.static.resistivity](myst:simpeg#simpeg.electromagnetics.static.resistivity) module. Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." + "All of the functionality specific to the forward simulation of 1D DC resistivity data are imported from the [simpeg.electromagnetics.static.resistivity](xref:simpeg#simpeg.electromagnetics.static.resistivity) module. Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, { @@ -370,7 +370,7 @@ "source": [ "## Define the Data\n", "\n", - "The SimPEG [Data](myst:simpeg#simpeg.data.Data) class is required for inversion and connects the observed data, uncertainties and survey geometry." + "The SimPEG [Data](xref:simpeg#simpeg.data.Data) class is required for inversion and connects the observed data, uncertainties and survey geometry." ] }, { @@ -483,7 +483,7 @@ "\n", "Recall from the [Forward Simulation of 1D Sounding DC Resistivity Data](fwd_dcr_1d.ipynb) tutorial that the 'model' is not necessarily synonymous with physical property values. And that we need to define a mapping from the model to the set of input parameters required by the forward simulation. When inverting to recover electrical resistivities (or conductivities), it is best to use the log-value, as electrical resistivities (or conductivities) of rocks span many order of magnitude.\n", "\n", - "Here, the model defines the log-resistivity values for a defined set of subsurface layers. And we use the [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) to map from the model parameters to the resistivity values required by the forward simulation." + "Here, the model defines the log-resistivity values for a defined set of subsurface layers. And we use the [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) to map from the model parameters to the resistivity values required by the forward simulation." ] }, { @@ -541,7 +541,7 @@ "source": [ "### Define the Forward Simulation\n", "\n", - "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 1D DC resistivity was discussed in the [1D Forward Simulation of DC Resistivity Data for a Single Sounding](fwd_dcr_1d.ipynb) tutorial. Here, we use the [Simulation1DLayers](myst:simpeg#simpeg.electromagnetics.static.resistivity.Simulation1DLayers) which simulates the data according to a 1D Hankel transform solution.\n", + "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 1D DC resistivity was discussed in the [1D Forward Simulation of DC Resistivity Data for a Single Sounding](fwd_dcr_1d.ipynb) tutorial. Here, we use the [Simulation1DLayers](xref:simpeg#simpeg.electromagnetics.static.resistivity.Simulation1DLayers) which simulates the data according to a 1D Hankel transform solution.\n", "\n", "The layer thicknesses are a static property of the simulation, and we set them using the ``thicknessess`` keyword argument. Since our model consists of log-resistivities, we use ``rhoMap`` to set the mapping from the model to the layer resistivities." ] @@ -559,7 +559,7 @@ }, "outputs": [], "source": [ - "simulation_L2 = dc.simulation_1d.Simulation1DLayers(\n", + "simulation_L2 = dc.simulation_1d.Simulation1DLayered(\n", " survey=survey,\n", " rhoMap=log_resistivity_map,\n", " thicknesses=layer_thicknesses,\n", @@ -573,7 +573,7 @@ "### Define the Data Misfit\n", "\n", "To understand the role of the data misfit in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/Uncertainties.html).\n", - "Here, we use the [L2DataMisfit](myst:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." + "Here, we use the [L2DataMisfit](xref:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." ] }, { @@ -600,7 +600,7 @@ "\n", "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). \n", "\n", - "To define the regularization within SimPEG, we must define a 1D [tensor mesh](myst:discretize#discretize.TensorMesh). Meshes are designed using the [discretize package](https://discretize.simpeg.xyz). Whereas layer *thicknesses* and our *model* are defined from our top-layer down, tensor meshes are defined from the bottom up. So to define a 1D tensor mesh for the regularization, we:\n", + "To define the regularization within SimPEG, we must define a 1D [tensor mesh](xref:discretize#discretize.TensorMesh). Meshes are designed using the [discretize package](https://discretize.simpeg.xyz). Whereas layer *thicknesses* and our *model* are defined from our top-layer down, tensor meshes are defined from the bottom up. So to define a 1D tensor mesh for the regularization, we:\n", "\n", "- add an extra layer to the end of our thicknesses so that the number of cells in the 1D mesh equals the number of model parameters\n", "- reverse the order so that the model parameters in the regularization match up with the appropriate cell\n", @@ -649,7 +649,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "By default, the regularization acts on the model parameters. In this case, the model parameters are the log-resistivities, not the electric resistivities!!! Here, we use the [WeightedLeastSquares](myst:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Here, length scale along x are used to balance the smallness and smoothness terms; yes, x is smoothness along the vertical direction. And the reference model is only applied to the smallness term. If we wanted to apply the regularization to a function of the model parameters, we would need to set an approprate mapping object using the ``mapping`` keyword argument." + "By default, the regularization acts on the model parameters. In this case, the model parameters are the log-resistivities, not the electric resistivities!!! Here, we use the [WeightedLeastSquares](xref:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Here, length scale along x are used to balance the smallness and smoothness terms; yes, x is smoothness along the vertical direction. And the reference model is only applied to the smallness term. If we wanted to apply the regularization to a function of the model parameters, we would need to set an approprate mapping object using the ``mapping`` keyword argument." ] }, { @@ -679,7 +679,7 @@ "source": [ "### Define the Optimization Algorithm\n", "\n", - "Here, we use the [InexactGaussNewton](myst:simpeg#simpeg.optimization.InexactGaussNewton) class to solve the optimization problem using the inexact Gauss Newton with conjugate gradient solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches." + "Here, we use the [InexactGaussNewton](xref:simpeg#simpeg.optimization.InexactGaussNewton) class to solve the optimization problem using the inexact Gauss Newton with conjugate gradient solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches." ] }, { @@ -706,7 +706,7 @@ "source": [ "### Define the Inverse Problem\n", "\n", - "We use the [BaseInvProblem](myst:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." + "We use the [BaseInvProblem](xref:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." ] }, { @@ -733,15 +733,15 @@ "\n", "Directives represent operations that are carried out during the inversion. Here, we apply common directives for weighted least-squares inversion of DC resistivity data and describe their roles. These are:\n", "\n", - "- [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights): Apply sensitivity weighting to counteract the natural tendency of DC resistivity inversion to place materials near the electrodes. Since the problem is non-linear and the sensitivities are updated with every model, we set `every_iteration=True`.\n", + "- [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights): Apply sensitivity weighting to counteract the natural tendency of DC resistivity inversion to place materials near the electrodes. Since the problem is non-linear and the sensitivities are updated with every model, we set `every_iteration=True`.\n", "\n", - "- [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=True` because the ideal preconditioner is model-dependent.\n", + "- [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=True` because the ideal preconditioner is model-dependent.\n", "\n", - "- [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", + "- [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", "\n", - "- [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 2 or 3 works well for DC resistivity inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", + "- [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 2 or 3 works well for DC resistivity inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", "\n", - "- [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", + "- [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", "\n", "\n", "The directive objects are organized in a ``list``. Upon starting the inversion or updating the recovered model at each iteration, the inversion will call each directive within the list **in order**. The order of the directives matters, and SimPEG will throw an error if directives are organized into an improper order. Some directives, like the ``BetaEstimate_ByEig`` are only used when starting the inversion. Other directives, like ``UpdatePreconditionner``, are used whenever the model is updated." @@ -781,7 +781,7 @@ "source": [ "### Define and Run the Inversion\n", "\n", - "We define the inversion using the [BaseInversion](myst:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" + "We define the inversion using the [BaseInversion](xref:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" ] }, { @@ -804,7 +804,7 @@ "Running inversion with SimPEG v0.22.1\n", "\n", " simpeg.InvProblem is setting bfgsH0 to the inverse of the eval2Deriv.\n", - " ***Done using same Solver, and solver_opts as the Simulation1DLayers problem***\n", + " ***Done using same Solver, and solver_opts as the Simulation1DLayered problem***\n", " \n" ] }, @@ -1091,7 +1091,7 @@ }, "outputs": [], "source": [ - "simulation_irls = dc.simulation_1d.Simulation1DLayers(\n", + "simulation_irls = dc.simulation_1d.Simulation1DLayered(\n", " survey=survey,\n", " rhoMap=log_resistivity_map,\n", " thicknesses=layer_thicknesses,\n", @@ -1127,7 +1127,7 @@ "source": [ "### Define the Regularization\n", "\n", - "Here, we use the [Sparse](myst:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Here, the scaling constants that balance the smallness and smoothness terms are set directly. Equal emphasis on smallness and smoothness is generally applied by using the inverse square of the smallest cell dimension. The reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros. Here, we apply a 1-norm to the smallness term and a 1-norm to first-order smoothness along the x (vertical direction)." + "Here, we use the [Sparse](xref:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Here, the scaling constants that balance the smallness and smoothness terms are set directly. Equal emphasis on smallness and smoothness is generally applied by using the inverse square of the smallest cell dimension. The reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros. Here, we apply a 1-norm to the smallness term and a 1-norm to first-order smoothness along the x (vertical direction)." ] }, { @@ -1206,9 +1206,9 @@ "source": [ "### Provide Inversion Directives\n", "\n", - "Here, we create common directives for IRLS inversion of DC resistivity data and describe their roles. In additon to the [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig) directives (described before), inversion with sparse-norms requires the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive.\n", + "Here, we create common directives for IRLS inversion of DC resistivity data and describe their roles. In additon to the [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig) directives (described before), inversion with sparse-norms requires the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive.\n", "\n", - "You will notice that we don't use the [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property. " + "You will notice that we don't use the [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property. " ] }, { @@ -1272,7 +1272,7 @@ "simpeg.InvProblem will set Regularization.reference_model to m0.\n", "\n", " simpeg.InvProblem is setting bfgsH0 to the inverse of the eval2Deriv.\n", - " ***Done using same Solver, and solver_opts as the Simulation1DLayers problem***\n", + " ***Done using same Solver, and solver_opts as the Simulation1DLayered problem***\n", " \n", "model has any nan: 0\n", "============================ Inexact Gauss Newton ============================\n", @@ -1624,7 +1624,7 @@ "source": [ "### Models and Mappings\n", "\n", - "For a 3-layered Earth model, the model consists of 2 log-thicknesses and 3 log-conductivities. Similar to the [1D Forward Simulation of DC Resistivity Data](fwd_dcr_1d.ipynb) tutorial, need a mapping that extract log-thicknesses and log-conductivities from the model, and mappings that convert log-values to property values. For this, we require the [simpeg.maps.Wires](myst:simpeg#simpeg.maps.Wires) mapping and [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) mapping classes. Note that successive mappings can be chained together using the $*$ operator." + "For a 3-layered Earth model, the model consists of 2 log-thicknesses and 3 log-conductivities. Similar to the [1D Forward Simulation of DC Resistivity Data](fwd_dcr_1d.ipynb) tutorial, need a mapping that extract log-thicknesses and log-conductivities from the model, and mappings that convert log-values to property values. For this, we require the [simpeg.maps.Wires](xref:simpeg#simpeg.maps.Wires) mapping and [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) mapping classes. Note that successive mappings can be chained together using the $*$ operator." ] }, { @@ -1699,7 +1699,7 @@ }, "outputs": [], "source": [ - "simulation_parametric = dc.simulation_1d.Simulation1DLayers(\n", + "simulation_parametric = dc.simulation_1d.Simulation1DLayered(\n", " survey=survey,\n", " sigmaMap=log_conductivity_map,\n", " thicknessesMap=log_thicknesses_map,\n", @@ -1737,9 +1737,9 @@ "source": [ "### Define a (Combo) Regularization\n", "\n", - "We need to define a regularization for each model parameter type. In this case, we have log-thicknesses and log-conductivities. For each model parameter type, we create a 1D [tensor mesh](myst:discretize#discretize.TensorMesh) with length equal to the number of parameters. In the ``mapping`` keyword argument, we used the wire map that extracts the specific model parameters from the model.\n", + "We need to define a regularization for each model parameter type. In this case, we have log-thicknesses and log-conductivities. For each model parameter type, we create a 1D [tensor mesh](xref:discretize#discretize.TensorMesh) with length equal to the number of parameters. In the ``mapping`` keyword argument, we used the wire map that extracts the specific model parameters from the model.\n", "\n", - "Using the $*$ operator, separate regularizations can be summed to form a regularization that is also a [ComboObjectiveFunction](myst:simpeg#simpeg.objective_function.ComboObjectiveFunction). By setting the ``multipliers`` property, we can emphasis the relative contributions of the log-thicknesses and log-conductivities regularizations." + "Using the $*$ operator, separate regularizations can be summed to form a regularization that is also a [ComboObjectiveFunction](xref:simpeg#simpeg.objective_function.ComboObjectiveFunction). By setting the ``multipliers`` property, we can emphasis the relative contributions of the log-thicknesses and log-conductivities regularizations." ] }, { @@ -1883,7 +1883,7 @@ "Running inversion with SimPEG v0.22.1\n", "\n", " simpeg.InvProblem is setting bfgsH0 to the inverse of the eval2Deriv.\n", - " ***Done using same Solver, and solver_opts as the Simulation1DLayers problem***\n", + " ***Done using same Solver, and solver_opts as the Simulation1DLayered problem***\n", " \n", "model has any nan: 0\n", "============================ Inexact Gauss Newton ============================\n", diff --git a/notebooks/05-dcr/inv_dcr_2d.ipynb b/notebooks/05-dcr/inv_dcr_2d.ipynb index 1a0f28cc..c3600012 100644 --- a/notebooks/05-dcr/inv_dcr_2d.ipynb +++ b/notebooks/05-dcr/inv_dcr_2d.ipynb @@ -68,8 +68,8 @@ "## Import Modules\n", "\n", "Here, we import all of the functionality required to run the notebook for the tutorial exercise.\n", - "All of the functionality specific to DC resistivity is imported from [simpeg.electromagnetics.static.resistivity](myst:simpeg#simpeg.electromagnetics.static.resistivity).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." + "All of the functionality specific to DC resistivity is imported from [simpeg.electromagnetics.static.resistivity](xref:simpeg#simpeg.electromagnetics.static.resistivity).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, { @@ -186,8 +186,8 @@ "source": [ "### Load the Topography\n", "\n", - "True surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray).\n", - "For the 2.5D problem geometry however, topography is an (N, 2) [numpy.ndarray](myst:numpy#numpy.ndarray), where the first coordinate represent along-line position and the second coordinate represents the vertical position. In this tutorial, we assume the topography and electrode locations are defined according to the 2.5D geometry." + "True surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray).\n", + "For the 2.5D problem geometry however, topography is an (N, 2) [numpy.ndarray](xref:numpy#numpy.ndarray), where the first coordinate represent along-line position and the second coordinate represents the vertical position. In this tutorial, we assume the topography and electrode locations are defined according to the 2.5D geometry." ] }, { @@ -257,7 +257,7 @@ "source": [ "**Option A: DCIP2D formatted data**\n", "\n", - "For this tutorial, the observed data are organized with a UBC-GIF DCIP2D formatted data file. We can use the [read_dcip2d_ubc](myst:simpeg#simpeg.utils.io_utils.read_dcip2d_ubc) utility function to load data in this format. This function outputs a SimPEG [Data](myst:simpeg#simpeg.data.Data) object. The data are normalized voltages in units V/A." + "For this tutorial, the observed data are organized with a UBC-GIF DCIP2D formatted data file. We can use the [read_dcip2d_ubc](xref:simpeg#simpeg.utils.io_utils.read_dcip2d_ubc) utility function to load data in this format. This function outputs a SimPEG [Data](xref:simpeg#simpeg.data.Data) object. The data are normalized voltages in units V/A." ] }, { @@ -284,11 +284,11 @@ "\n", "If you have CSV-formatted data containing the ABMN electrode locations, you will need to:\n", "\n", - "* load the file into a [numpy.ndarray](myst:numpy#numpy.ndarray)\n", + "* load the file into a [numpy.ndarray](xref:numpy#numpy.ndarray)\n", "* extract the data column and the A, B, M and N electrode locations\n", - "* transform the electrode locations to the 2.5D geometry if necessary; i.e. (N, 2) [numpy.ndarray](myst:numpy#numpy.ndarray)\n", - "* use the [generate_survey_from_abmn_locations](myst:simpeg#simpeg.electromagnetics.static.utils.generate_survey_from_abmn_locations) to generate a [survey](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey) object automatically.\n", - "* Define a [Data](myst:simpeg#simpeg.data.Data) object attached to the survey and observed data.\n", + "* transform the electrode locations to the 2.5D geometry if necessary; i.e. (N, 2) [numpy.ndarray](xref:numpy#numpy.ndarray)\n", + "* use the [generate_survey_from_abmn_locations](xref:simpeg#simpeg.electromagnetics.static.utils.generate_survey_from_abmn_locations) to generate a [survey](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey) object automatically.\n", + "* Define a [Data](xref:simpeg#simpeg.data.Data) object attached to the survey and observed data.\n", "\n", "E.g. for a file containing electrode locations already formatted for a 2.5D geometry:\n", "```\n", @@ -429,7 +429,7 @@ "\n", "The same rules for defining appropriate meshes for forward simulation of DC resistivity apply to inversion. Please visit the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial to see the best practices for mesh design.\n", "\n", - "**Tutorial mesh:** Here, a minimum cell width of 4 m (or 1/10 the minimum electrode spacing) is used within our survey region. The largest electrode spacing was 400 m, so a the padding was extended at least 1200 m from the survey region. Using the [refine_surface](myst:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](myst:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](myst:discretize#discretize.TreeMesh) API to see additional refinement methods." + "**Tutorial mesh:** Here, a minimum cell width of 4 m (or 1/10 the minimum electrode spacing) is used within our survey region. The largest electrode spacing was 400 m, so a the padding was extended at least 1200 m from the survey region. Using the [refine_surface](xref:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](xref:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](xref:discretize#discretize.TreeMesh) API to see additional refinement methods." ] }, { @@ -483,7 +483,7 @@ "source": [ "## Define the Active Cells\n", "\n", - "Simulated geophysical data are dependent on the subsurface distribution of physical property values. As a result, the cells lying below the surface topography are commonly referred to as 'active cells'. And air cells, whose physical property values are fixed, are commonly referred to as 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "Simulated geophysical data are dependent on the subsurface distribution of physical property values. As a result, the cells lying below the surface topography are commonly referred to as 'active cells'. And air cells, whose physical property values are fixed, are commonly referred to as 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -512,7 +512,7 @@ "source": [ "## Project Electrodes to Discretized Topography\n", "\n", - "Surface DC resistivity data will not be modeled accurately if the electrodes are modeled as living above or below the surface. It is especially problematic when electrodes are modeled as living in the air. Prior to inverting DC resistivity data, we must project the electrodes from their true elevation to the surface of the *discretized* topography. This is done using the [drape_electrodes_on_topography](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method." + "Surface DC resistivity data will not be modeled accurately if the electrodes are modeled as living above or below the surface. It is especially problematic when electrodes are modeled as living in the air. Prior to inverting DC resistivity data, we must project the electrodes from their true elevation to the surface of the *discretized* topography. This is done using the [drape_electrodes_on_topography](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method." ] }, { @@ -549,9 +549,9 @@ "source": [ "### Mapping from the Model to the Mesh\n", "\n", - "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For whatever model we choose, we must define a mapping from the set of model parameters (a [1D numpy.ndarray](myst:numpy#numpy.ndarray)) to the physical property values of all cells in the mesh. Mappings are created using the [simpeg.maps](myst:simpeg#simpeg.maps.IdentityMap) module.\n", + "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For whatever model we choose, we must define a mapping from the set of model parameters (a [1D numpy.ndarray](xref:numpy#numpy.ndarray)) to the physical property values of all cells in the mesh. Mappings are created using the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module.\n", "\n", - "For DC resistivity, the model parameters define the subsurface electrical conductivity, and the electrical conductivities of the cells in the air are given a fixed value. Here, the model defines the log-conductivity values for all active cells. We use the [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) to map from the model parameters to the conductivity values for all active cells. Then we use the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) map to project the active cell conductivities to the entire mesh. As explained in the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial, air cells are given a fixed value of 1e-8 S/m to ensure the forward problem is well-conditionned. And the $*$ operator is used to combine the separate mapping objects into a single mapping." + "For DC resistivity, the model parameters define the subsurface electrical conductivity, and the electrical conductivities of the cells in the air are given a fixed value. Here, the model defines the log-conductivity values for all active cells. We use the [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) to map from the model parameters to the conductivity values for all active cells. Then we use the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) map to project the active cell conductivities to the entire mesh. As explained in the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial, air cells are given a fixed value of 1e-8 S/m to ensure the forward problem is well-conditionned. And the $*$ operator is used to combine the separate mapping objects into a single mapping." ] }, { @@ -615,7 +615,7 @@ "source": [ "### Define the Forward Simulation\n", "\n", - "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 2.5D DC resistivity was discussed in the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial. Here, we use the [Simulation2DNodal](myst:simpeg#simpeg.electromagnetics.static.resistivity.Simulation2DNodal) simulation which solves for the electric potential on mesh nodes.\n", + "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 2.5D DC resistivity was discussed in the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial. Here, we use the [Simulation2DNodal](xref:simpeg#simpeg.electromagnetics.static.resistivity.Simulation2DNodal) simulation which solves for the electric potential on mesh nodes.\n", "\n", "Since our model consists of log-conductivities, we use ``sigmaMap`` to set the mapping from the model to the mesh cells. Except for in extreme cases, we can compute and store the Jacobian explicitly for 2.5D problems. By doing so, we drastically reduce the run-time of the inversion." ] @@ -645,7 +645,7 @@ "### Define the Data Misfit\n", "\n", "To understand the role of the data misfit in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/Uncertainties.html).\n", - "Here, we use the [L2DataMisfit](myst:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." + "Here, we use the [L2DataMisfit](xref:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." ] }, { @@ -670,7 +670,7 @@ "source": [ "### Define the Regularization\n", "\n", - "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). Here, we use the [WeightedLeastSquares](myst:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Here, the scaling constants that balance the smallness and smoothness terms are set directly. We use the inverse square of the smallest cell size to balance the smallness and smoothness terms. Setting ``alpha_s`` to a very small value will recover the smoothest model. And the reference model is only applied to the smallness term.\n", + "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). Here, we use the [WeightedLeastSquares](xref:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Here, the scaling constants that balance the smallness and smoothness terms are set directly. We use the inverse square of the smallest cell size to balance the smallness and smoothness terms. Setting ``alpha_s`` to a very small value will recover the smoothest model. And the reference model is only applied to the smallness term.\n", "\n", "By default, the regularization acts on the model parameters; which in the case are the log-conductivities of the active cells. So we need to specify which cells are active in the regularization. And if we wanted to apply the regularization to a function of the model parameters, we would need to set an approprate mapping object using the ``mapping`` keyword argument." ] @@ -705,7 +705,7 @@ "source": [ "### Define the Optimization Algorithm\n", "\n", - "Here, we use the [InexactGaussNewton](myst:simpeg#simpeg.optimization.InexactGaussNewton) class to solve the optimization problem using the inexact Gauss Newton with conjugate gradient solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches." + "Here, we use the [InexactGaussNewton](xref:simpeg#simpeg.optimization.InexactGaussNewton) class to solve the optimization problem using the inexact Gauss Newton with conjugate gradient solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches." ] }, { @@ -732,7 +732,7 @@ "source": [ "### Define the Inverse Problem\n", "\n", - "We use the [BaseInvProblem](myst:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." + "We use the [BaseInvProblem](xref:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." ] }, { @@ -759,15 +759,15 @@ "\n", "Directives represent operations that are carried out during the inversion. Here, we apply common directives for weighted least-squares inversion of DC resistivity data and describe their roles. These are:\n", "\n", - "- [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights): Apply sensitivity weighting to counteract the natural tendency of DC resistivity inversion to place materials near the electrodes. Since the problem is non-linear and the sensitivities are updated with every model, we set `every_iteration=True`. For DC resistivity inversion, we do not want to use the entire dynamic range of the sensitivities to generate our weighting. So we generally set `threshold_value` to a value betwewen 1e-5 and 1e-3.\n", + "- [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights): Apply sensitivity weighting to counteract the natural tendency of DC resistivity inversion to place materials near the electrodes. Since the problem is non-linear and the sensitivities are updated with every model, we set `every_iteration=True`. For DC resistivity inversion, we do not want to use the entire dynamic range of the sensitivities to generate our weighting. So we generally set `threshold_value` to a value betwewen 1e-5 and 1e-3.\n", "\n", - "- [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=True` because the ideal preconditioner is model-dependent.\n", + "- [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=True` because the ideal preconditioner is model-dependent.\n", "\n", - "- [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", + "- [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", "\n", - "- [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 2 or 3 works well for DC resistivity inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", + "- [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 2 or 3 works well for DC resistivity inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", "\n", - "- [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", + "- [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", "\n", "\n", "The directive objects are organized in a ``list``. Upon starting the inversion or updating the recovered model at each iteration, the inversion will call each directive within the list **in order**. The order of the directives matters, and SimPEG will throw an error if directives are organized into an improper order. Some directives, like the ``BetaEstimate_ByEig`` are only used when starting the inversion. Other directives, like ``UpdatePreconditionner``, are used whenever the model is updated." @@ -809,7 +809,7 @@ "source": [ "### Define and Run the Inversion\n", "\n", - "We define the inversion using the [BaseInversion](myst:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" + "We define the inversion using the [BaseInversion](xref:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" ] }, { @@ -1118,7 +1118,7 @@ "source": [ "### Define An Apparent Resistivity Survey\n", "\n", - "We cannot reuse a survey that was used to simulate a different data type. So we must define a new survey object for inverting apparent resistivity data. This can be done by extracting the ABMN electrode locations from the previous survey object and using the [generate_survey_from_abmn_locations](myst:simpeg#simpeg.electromagnetics.static.utils.generate_survey_from_abmn_locations) utility function." + "We cannot reuse a survey that was used to simulate a different data type. So we must define a new survey object for inverting apparent resistivity data. This can be done by extracting the ABMN electrode locations from the previous survey object and using the [generate_survey_from_abmn_locations](xref:simpeg#simpeg.electromagnetics.static.utils.generate_survey_from_abmn_locations) utility function." ] }, { @@ -1218,7 +1218,7 @@ "source": [ "### Mapping from the Model to the Mesh\n", "\n", - "Here, the model defines the log-resistivity values for all active cells. We use the [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) to map from the model parameters to the resistivity values for all active cells. Then we use the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) map to project the active cell resisitivities to the entire mesh. As explained in the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial, air cells are given a fixed value of 1e8 $\\Omega m$ to ensure the forward problem is well-conditionned. And the $*$ operator is used to combine the separate mapping objects into a single mapping." + "Here, the model defines the log-resistivity values for all active cells. We use the [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) to map from the model parameters to the resistivity values for all active cells. Then we use the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) map to project the active cell resisitivities to the entire mesh. As explained in the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial, air cells are given a fixed value of 1e8 $\\Omega m$ to ensure the forward problem is well-conditionned. And the $*$ operator is used to combine the separate mapping objects into a single mapping." ] }, { @@ -1324,7 +1324,7 @@ "source": [ "### Define the Regularization\n", "\n", - "Here, we use the [Sparse](myst:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Length scales along x and y are used to balance the smallness and smoothness terms. Here, length scales of 100 are used to more strongly emphasize smoothness in the recovered model. The reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros. Here, we apply a 0-norm to the smallness and 2-norm to first-order smoothness along the x and y directions." + "Here, we use the [Sparse](xref:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Length scales along x and y are used to balance the smallness and smoothness terms. Here, length scales of 100 are used to more strongly emphasize smoothness in the recovered model. The reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros. Here, we apply a 0-norm to the smallness and 2-norm to first-order smoothness along the x and y directions." ] }, { @@ -1404,9 +1404,9 @@ "source": [ "### Provide Inversion Directives\n", "\n", - "Here, we create common directives for IRLS inversion of total magnetic intensity data and describe their roles. In additon to the [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig) (described before), inversion with sparse-norms requires the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive.\n", + "Here, we create common directives for IRLS inversion of total magnetic intensity data and describe their roles. In additon to the [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig) (described before), inversion with sparse-norms requires the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive.\n", "\n", - "You will notice that we don't use the [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property. " + "You will notice that we don't use the [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property. " ] }, { diff --git a/notebooks/05-dcr/inv_dcr_3d.ipynb b/notebooks/05-dcr/inv_dcr_3d.ipynb index 19496125..e05534fa 100644 --- a/notebooks/05-dcr/inv_dcr_3d.ipynb +++ b/notebooks/05-dcr/inv_dcr_3d.ipynb @@ -57,8 +57,8 @@ "## Import Modules\n", "\n", "Here, we import all of the functionality required to run the notebook for the tutorial exercise.\n", - "All of the functionality specific to DC resistivity is imported from [simpeg.electromagnetics.static.resistivity](myst:simpeg#simpeg.electromagnetics.static.resistivity).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." + "All of the functionality specific to DC resistivity is imported from [simpeg.electromagnetics.static.resistivity](xref:simpeg#simpeg.electromagnetics.static.resistivity).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, { @@ -183,7 +183,7 @@ "source": [ "### Load the Topography\n", "\n", - "Surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray)." + "Surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray)." ] }, { @@ -246,7 +246,7 @@ "\n", "**Option A: DCIP3D formatted data**\n", "\n", - "The [read_dcip3d_ubc](myst:simpeg#simpeg.utils.io_utils.read_dcip3d_ubc) utility function can be used to load DC/IP data stored in a UBC-GIF formatted file. This function outputs a SimPEG [Data](myst:simpeg#simpeg.data.Data) object." + "The [read_dcip3d_ubc](xref:simpeg#simpeg.utils.io_utils.read_dcip3d_ubc) utility function can be used to load DC/IP data stored in a UBC-GIF formatted file. This function outputs a SimPEG [Data](xref:simpeg#simpeg.data.Data) object." ] }, { @@ -255,7 +255,7 @@ "source": [ "**Option B: Load XYZ formatted data**\n", "\n", - "For this tutorial, the observed data are organized within an XYZ formatted file. We can use the [read_dcip_xyz](myst:simpeg#simpeg.utils.io_utils.read_dcip_xyz) utility function to load data in this format. This function outputs a SimPEG [Data](myst:simpeg#simpeg.data.Data) object. The data are normalized voltages in units V/A.\n", + "For this tutorial, the observed data are organized within an XYZ formatted file. We can use the [read_dcip_xyz](xref:simpeg#simpeg.utils.io_utils.read_dcip_xyz) utility function to load data in this format. This function outputs a SimPEG [Data](xref:simpeg#simpeg.data.Data) object. The data are normalized voltages in units V/A.\n", "\n", "The `dict_headers` input argument can be used to import other data columns that are not required to define the SimPEG data object. In this case, we import a column that defines the survey line associated with each datum. We will use this to plot pseudosections for individual survey lines." ] @@ -499,7 +499,7 @@ "\n", "Please visit the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial to see the best practices for mesh design. The same rules for defining appropriate meshes for 2.5D simulations and inversion apply to 3D simulations and inversion.\n", "\n", - "**Tutorial mesh:** Here, a minimum cell width of 25 m (or 1/4 the minimum electrode spacing) is used within our survey region. The largest electrode spacing was 1000 m, so a the padding was extended at least 3000 m from the survey region. Using the [refine_surface](myst:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](myst:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](myst:discretize#discretize.TreeMesh) API to see additional refinement methods." + "**Tutorial mesh:** Here, a minimum cell width of 25 m (or 1/4 the minimum electrode spacing) is used within our survey region. The largest electrode spacing was 1000 m, so a the padding was extended at least 3000 m from the survey region. Using the [refine_surface](xref:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](xref:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](xref:discretize#discretize.TreeMesh) API to see additional refinement methods." ] }, { @@ -555,7 +555,7 @@ "source": [ "## Define the Active Cells\n", "\n", - "Simulated geophysical data are dependent on the subsurface distribution of physical property values. As a result, the cells lying below the surface topography are commonly referred to as 'active cells'. And air cells, whose physical property values are fixed, are commonly referred to as 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "Simulated geophysical data are dependent on the subsurface distribution of physical property values. As a result, the cells lying below the surface topography are commonly referred to as 'active cells'. And air cells, whose physical property values are fixed, are commonly referred to as 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -584,7 +584,7 @@ "source": [ "## Project Electrodes to Discretized Topography\n", "\n", - "Surface DC resistivity data will not be modeled accurately if the electrodes are modeled as living above or below the surface. It is especially problematic when electrodes are modeled as living in the air. Prior to inverting surface DC resistivity data, we must project the electrodes from their true elevation to the surface of the *discretized* topography. This is done using the [drape_electrodes_on_topography](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method." + "Surface DC resistivity data will not be modeled accurately if the electrodes are modeled as living above or below the surface. It is especially problematic when electrodes are modeled as living in the air. Prior to inverting surface DC resistivity data, we must project the electrodes from their true elevation to the surface of the *discretized* topography. This is done using the [drape_electrodes_on_topography](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method." ] }, { @@ -609,7 +609,7 @@ "source": [ "## Mapping from the Model to the Mesh\n", "\n", - "Here, the model defines the log-conductivity values for all active cells. We use the [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) to map from the model parameters to the conductivity values for all active cells. Then we use the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) map to project the active cell resisitivities to the entire mesh. As explained in the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial, air cells are given a fixed value of 1e-8 $S/m$ to ensure the forward problem is well-conditionned. And the $*$ operator is used to combine the separate mapping objects into a single mapping." + "Here, the model defines the log-conductivity values for all active cells. We use the [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) to map from the model parameters to the conductivity values for all active cells. Then we use the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) map to project the active cell resisitivities to the entire mesh. As explained in the [2.5D Forward Simulation](fwd_dcr_2d.ipynb) tutorial, air cells are given a fixed value of 1e-8 $S/m$ to ensure the forward problem is well-conditionned. And the $*$ operator is used to combine the separate mapping objects into a single mapping." ] }, { @@ -673,7 +673,7 @@ "source": [ "## Define the Forward Simulation\n", "\n", - "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 3D DC resistivity was discussed in the [3D Forward Simulation](fwd_dcr_2d.ipynb) tutorial. Here, we use the [Simulation3DNodal](myst:simpeg#simpeg.electromagnetics.static.resistivity.Simulation3DNodal) simulation which solves for the electric potential on mesh nodes.\n", + "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 3D DC resistivity was discussed in the [3D Forward Simulation](fwd_dcr_2d.ipynb) tutorial. Here, we use the [Simulation3DNodal](xref:simpeg#simpeg.electromagnetics.static.resistivity.Simulation3DNodal) simulation which solves for the electric potential on mesh nodes.\n", "\n", "Since our model consists of log-conductivities, we use ``sigmaMap`` to set the mapping from the model to the mesh cells. For reasonable cases, we can compute and store the Jacobian explicitly for 3D problems by setting ``storeJ`` to ``True``. By doing this, we drastically reduce the run-time of the inversion. For larger problems being run on computers with insufficient RAM, you may need to set ``storeJ`` to ``False`` and invert the data without storing the sensitivities explicitly." ] @@ -703,7 +703,7 @@ "## Define the Data Misfit\n", "\n", "To understand the role of the data misfit in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/Uncertainties.html).\n", - "Here, we use the [L2DataMisfit](myst:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." + "Here, we use the [L2DataMisfit](xref:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." ] }, { @@ -728,7 +728,7 @@ "source": [ "## Define the Regularization\n", "\n", - "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). Here, we use the [WeightedLeastSquares](myst:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Length scales along x, y and z are used to balance the smallness and smoothness terms. And the reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros.\n", + "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). Here, we use the [WeightedLeastSquares](xref:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Length scales along x, y and z are used to balance the smallness and smoothness terms. And the reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros.\n", "\n", "By default, the regularization acts on the model parameters; which in the case are the log-conductivities of the active cells. So we need to specify which cells are active in the regularization. And if we wanted to apply the regularization to a function of the model parameters, we would need to set an approprate mapping object using the ``mapping`` keyword argument." ] @@ -762,7 +762,7 @@ "source": [ "## Define the Optimization Algorithm\n", "\n", - "Here, we use the [InexactGaussNewton](myst:simpeg#simpeg.optimization.InexactGaussNewton) class to solve the optimization problem using the inexact Gauss Newton with conjugate gradient solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches." + "Here, we use the [InexactGaussNewton](xref:simpeg#simpeg.optimization.InexactGaussNewton) class to solve the optimization problem using the inexact Gauss Newton with conjugate gradient solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches." ] }, { @@ -789,7 +789,7 @@ "source": [ "## Define the Inverse Problem\n", "\n", - "We use the [BaseInvProblem](myst:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." + "We use the [BaseInvProblem](xref:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." ] }, { @@ -816,15 +816,15 @@ "\n", "Directives represent operations that are carried out during the inversion. Here, we apply common directives for weighted least-squares inversion of DC resistivity data and describe their roles. These are:\n", "\n", - "- [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights): apply sensitivity weighting to counteract the natural tendency of DC resistivity inversion to place materials near the electrodes. Since the problem is non-linear and the sensitivities are updated with every model, we set `every_iteration=True`. For DC resistivity inversion, we do not want to use the entire dynamic range of the sensitivities to generate our weighting. So we generally set `threshold_value` to a value betwewen 1e-4 and 1e-1. **Warning: should not be used if storeJ set to False in the simulation class**.\n", + "- [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights): apply sensitivity weighting to counteract the natural tendency of DC resistivity inversion to place materials near the electrodes. Since the problem is non-linear and the sensitivities are updated with every model, we set `every_iteration=True`. For DC resistivity inversion, we do not want to use the entire dynamic range of the sensitivities to generate our weighting. So we generally set `threshold_value` to a value betwewen 1e-4 and 1e-1. **Warning: should not be used if storeJ set to False in the simulation class**.\n", "\n", - "- [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=True` because the ideal preconditioner is model-dependent. **Warning: should not be used if storeJ set to False in the simulation class**.\n", + "- [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=True` because the ideal preconditioner is model-dependent. **Warning: should not be used if storeJ set to False in the simulation class**.\n", "\n", - "- [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", + "- [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", "\n", - "- [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 2 or 3 works well for DC resistivity inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", + "- [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 2 or 3 works well for DC resistivity inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", "\n", - "- [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", + "- [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", "\n", "\n", "The directive objects are organized in a ``list``. Upon starting the inversion or updating the recovered model at each iteration, the inversion will call each directive within the list **in order**. The order of the directives matters, and SimPEG will throw an error if directives are organized into an improper order. Some directives, like the ``BetaEstimate_ByEig`` are only used when starting the inversion. Other directives, like ``UpdatePreconditionner``, are used whenever the model is updated." @@ -868,7 +868,7 @@ "source": [ "## Define and Run the Inversion\n", "\n", - "We define the inversion using the [BaseInversion](myst:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" + "We define the inversion using the [BaseInversion](xref:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" ] }, { diff --git a/notebooks/06-ip/fwd_ip_2d.ipynb b/notebooks/06-ip/fwd_ip_2d.ipynb index e21da23b..f1a60e8c 100644 --- a/notebooks/06-ip/fwd_ip_2d.ipynb +++ b/notebooks/06-ip/fwd_ip_2d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** Here, we use the [simpeg.electromagnetics.static.induced_polarization](myst:simpeg#simpeg.electromagnetics.static.induced_polarization) module to simulate 2.5D DC induced polarization (IP) data on a tree mesh. This approach is ideal when the local geology doesn't change along the strike direction, as we can leverage the symmetry of the problem to reduce computational cost.\n", + "**Summary:** Here, we use the [simpeg.electromagnetics.static.induced_polarization](xref:simpeg#simpeg.electromagnetics.static.induced_polarization) module to simulate 2.5D DC induced polarization (IP) data on a tree mesh. This approach is ideal when the local geology doesn't change along the strike direction, as we can leverage the symmetry of the problem to reduce computational cost.\n", "\n", "Because the same survey geometry, mesh and topography that are used to simulate DC resistivity data are used simulate IP data, almost all of the fundamental functionality used in this tutorial is described in detail in the [2.5D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_2d.ipynb) tutorial. In this tutorial, we focus primarily on functionality related to the simulation of IP data. More specifically, we discuss:\n", "\n", @@ -54,8 +54,8 @@ "source": [ "## Import Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to IP is imported from [simpeg.electromagnetics.static.induced_polarization](myst:simpeg#simpeg.electromagnetics.static.induced_polarization).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To simulate DC and IP data, we need to define our problem geometry on a numerical grid (or mesh).\n", + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to IP is imported from [simpeg.electromagnetics.static.induced_polarization](xref:simpeg#simpeg.electromagnetics.static.induced_polarization).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To simulate DC and IP data, we need to define our problem geometry on a numerical grid (or mesh).\n", "To generate the mesh, we used the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, @@ -106,8 +106,8 @@ "source": [ "## Define the Topography\n", "\n", - "True surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray).\n", - "For use in a 2.5D simulation however, topography is defined as an (N, 2) [numpy.ndarray](myst:numpy#numpy.ndarray), where the first coordinate represent along-line position and the second coordinate represents the vertical position. Here, we define the 2D topography used for the 2.5D simulation." + "True surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray).\n", + "For use in a 2.5D simulation however, topography is defined as an (N, 2) [numpy.ndarray](xref:numpy#numpy.ndarray), where the first coordinate represent along-line position and the second coordinate represents the vertical position. Here, we define the 2D topography used for the 2.5D simulation." ] }, { @@ -179,7 +179,7 @@ "source": [ "## Define the IP Survey\n", "\n", - "A full description of elements required to define DC and IP surveys was presented in the [2.5D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_2d.ipynb) tutorial. Here, we take the same approach. The only difference is that our receivers are defined to measure apparent chargeabilities. Because SimPEG uses a linearized formulation for simulating IP data; see [Simulation2DCellCentered](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DCellCentered) or [Simulation2DNodal](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal), the units of the apparent chargeability data are the same as the units chosen to represent the subsurface chargeabilities.\n", + "A full description of elements required to define DC and IP surveys was presented in the [2.5D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_2d.ipynb) tutorial. Here, we take the same approach. The only difference is that our receivers are defined to measure apparent chargeabilities. Because SimPEG uses a linearized formulation for simulating IP data; see [Simulation2DCellCentered](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DCellCentered) or [Simulation2DNodal](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal), the units of the apparent chargeability data are the same as the units chosen to represent the subsurface chargeabilities.\n", "\n", "The survey line is an 800 m long EW dipole-dipole line with an electrode spacing of 40 m. There is a maximum of 10 potential electrodes per current electrode." ] @@ -326,7 +326,7 @@ "source": [ "## Define the Active Cells\n", "\n", - "Use the [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function to obtain the indices of the active mesh cells from topography (e.g. cells below surface)." + "Use the [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function to obtain the indices of the active mesh cells from topography (e.g. cells below surface)." ] }, { @@ -357,7 +357,7 @@ "\n", "In order to simulate IP data, we require the background conductivity/resistivity defined on the entire mesh. You can generate this directly, or apply the appropriate mapping to a different parameterization of the conductivity/resistivity. \n", "\n", - "For the tutorial, we generate the conductivity model that was used for the [2.5D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_2d.ipynb) tutorial; i.e. the electrical conductivities of all active cells. And so we must use the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) mapping to map from the model space to the conductivities on the entire mesh." + "For the tutorial, we generate the conductivity model that was used for the [2.5D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_2d.ipynb) tutorial; i.e. the electrical conductivities of all active cells. And so we must use the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) mapping to map from the model space to the conductivities on the entire mesh." ] }, { @@ -498,7 +498,7 @@ "\n", "The model does not need to be synonymous with the physical property values. But it is common to define chargeability models as the chargeabilities for all subsurface (active) cells. So, what are the units?\n", "\n", - "SimPEG uses a linearized formulation for simulating IP data; see [Simulation2DCellCentered](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DCellCentered) or [Simulation2DNodal](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal). In this formulation, any standard definition of the chargeability can be used. And the resulting apparent chargeability data will be in terms of the same units; e.g. intrinsic chargeability (V/V or mV/V) or integrated chargeability (ms). If you are simulating secondary voltages, the chargeability model must represent intrinsic chargeabilities ($0 \\leq \\eta \\leq 1$) in V/V.\n", + "SimPEG uses a linearized formulation for simulating IP data; see [Simulation2DCellCentered](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DCellCentered) or [Simulation2DNodal](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal). In this formulation, any standard definition of the chargeability can be used. And the resulting apparent chargeability data will be in terms of the same units; e.g. intrinsic chargeability (V/V or mV/V) or integrated chargeability (ms). If you are simulating secondary voltages, the chargeability model must represent intrinsic chargeabilities ($0 \\leq \\eta \\leq 1$) in V/V.\n", "\n", "For this tutorial, we use the intrinsic chargeability in units V/V. Here, the conductive sphere is chargeable, but the resistive sphere and the host are not. Note that unlike DC resistivity, the physical property value defining air cells for IP simulation can be set to zero." ] @@ -618,7 +618,7 @@ "source": [ "## Project Electrodes to Discretized Topography\n", "\n", - "As explained in the [2.5D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_2d.ipynb) tutorial, we use the [drape_electrodes_on_topography](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method to project the electrodes to the discrete surface topography." + "As explained in the [2.5D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_2d.ipynb) tutorial, we use the [drape_electrodes_on_topography](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method to project the electrodes to the discrete surface topography." ] }, { @@ -645,8 +645,8 @@ "\n", "There are two simulation classes which may be used to simulate 2.5D IP data:\n", "\n", - "- [Simulation2DNodel](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal), which defines the discrete electric potentials on mesh nodes.\n", - "- [Simulation2DCellCentered](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DCellCentered), which defines the discrete electric potentials at cell centers.\n", + "- [Simulation2DNodel](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal), which defines the discrete electric potentials on mesh nodes.\n", + "- [Simulation2DCellCentered](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DCellCentered), which defines the discrete electric potentials at cell centers.\n", "\n", "For surface DC and IP data, the nodal formulation is more well-suited and will be used here. The cell-centered formulation works well for simulating borehole DC and IP data. To fully define the forward simulation, we need to connect the simulation object to:\n", "\n", diff --git a/notebooks/06-ip/fwd_ip_3d.ipynb b/notebooks/06-ip/fwd_ip_3d.ipynb index fed3bebb..8fe94c9f 100644 --- a/notebooks/06-ip/fwd_ip_3d.ipynb +++ b/notebooks/06-ip/fwd_ip_3d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** Here, we use the [simpeg.electromagnetics.static.induced_polarization](myst:simpeg#simpeg.electromagnetics.static.induced_polarization) module to simulate 3D DC induced polarization (IP) data on a tree mesh. This approach is ideal when the local geology doesn't change along the strike direction, as we can leverage the symmetry of the problem to reduce computational cost.\n", + "**Summary:** Here, we use the [simpeg.electromagnetics.static.induced_polarization](xref:simpeg#simpeg.electromagnetics.static.induced_polarization) module to simulate 3D DC induced polarization (IP) data on a tree mesh. This approach is ideal when the local geology doesn't change along the strike direction, as we can leverage the symmetry of the problem to reduce computational cost.\n", "\n", "Because the same survey geometry, mesh and topography that are used to simulate DC resistivity data are used simulate IP data, almost all of the fundamental functionality used in this tutorial is described in detail in the [3D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_3d.ipynb) tutorial. In this tutorial, we focus primarily on functionality related to the simulation of IP data. More specifically, we discuss:\n", "\n", @@ -54,8 +54,8 @@ "source": [ "## Import Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to IP is imported from [simpeg.electromagnetics.static.induced_polarization](myst:simpeg#simpeg.electromagnetics.static.induced_polarization).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To simulate DC and IP data, we need to define our problem geometry on a numerical grid (or mesh).\n", + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to IP is imported from [simpeg.electromagnetics.static.induced_polarization](xref:simpeg#simpeg.electromagnetics.static.induced_polarization).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To simulate DC and IP data, we need to define our problem geometry on a numerical grid (or mesh).\n", "To generate the mesh, we used the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, @@ -116,7 +116,7 @@ "source": [ "## Define the Topography\n", "\n", - "Surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) for 3D simulations.\n", + "Surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) for 3D simulations.\n", "Here, we create basic topography for the forward simulation.\n", "For user-specific simulations, you may load topography from an XYZ file." ] @@ -205,7 +205,7 @@ "source": [ "## Define the IP Survey\n", "\n", - "A full description of elements required to define DC and IP surveys was presented in the [3D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_3d.ipynb) tutorial. Here, we take the same approach. The only difference is that our receivers are defined to measure apparent chargeabilities. Because SimPEG uses a linearized formulation for simulating IP data; see [Simulation3DCellCentered](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation3DCellCentered) or [Simulation3DNodal](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation3DNodal), the units of the apparent chargeability data are the same as the units chosen to represent the subsurface chargeabilities..\n", + "A full description of elements required to define DC and IP surveys was presented in the [3D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_3d.ipynb) tutorial. Here, we take the same approach. The only difference is that our receivers are defined to measure apparent chargeabilities. Because SimPEG uses a linearized formulation for simulating IP data; see [Simulation3DCellCentered](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation3DCellCentered) or [Simulation3DNodal](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation3DNodal), the units of the apparent chargeability data are the same as the units chosen to represent the subsurface chargeabilities..\n", "\n", "Here, the survey consists of 5 IP lines that use a dipole-dipole electrode configuration; 1 line along the East-West direction and 2 lines along the North-South direction. Each line is 2000 m in length and has an electrode spacing of 100 m." ] @@ -369,7 +369,7 @@ "source": [ "## Define the Active Cells\n", "\n", - "Use the [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function to obtain the indices of the active mesh cells from topography (e.g. cells below surface)." + "Use the [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function to obtain the indices of the active mesh cells from topography (e.g. cells below surface)." ] }, { @@ -540,7 +540,7 @@ "\n", "The model does not need to be synonymous with the physical property values. But it is common to define chargeability models as the chargeabilities for all subsurface (active) cells. So, what are the units?\n", "\n", - "SimPEG uses a linearized formulation for simulating IP data; see [Simulation2DCellCentered](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DCellCentered) or [Simulation2DNodal](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal). In this formulation, any standard definition of the chargeability can be used. And the resulting apparent chargeability data will be in terms of the same units; e.g. intrinsic chargeability (V/V or mV/V) or integrated chargeability (ms). If you are simulating secondary voltages, the chargeability model must represent intrinsic chargeabilities ($0 \\leq \\eta \\leq 1$) in V/V.\n", + "SimPEG uses a linearized formulation for simulating IP data; see [Simulation2DCellCentered](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DCellCentered) or [Simulation2DNodal](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal). In this formulation, any standard definition of the chargeability can be used. And the resulting apparent chargeability data will be in terms of the same units; e.g. intrinsic chargeability (V/V or mV/V) or integrated chargeability (ms). If you are simulating secondary voltages, the chargeability model must represent intrinsic chargeabilities ($0 \\leq \\eta \\leq 1$) in V/V.\n", "\n", "For this tutorial, we use the intrinsic chargeability in units V/V. Here, the conductive sphere is chargeable, but the resistive sphere and the host are not. Note that unlike DC resistivity, the physical property value defining air cells for IP simulation can be set to zero." ] @@ -661,7 +661,7 @@ "source": [ "## Project Electrodes to Discretized Topography\n", "\n", - "As explained in the [3D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_3d.ipynb) tutorial, we use the [drape_electrodes_on_topography](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method to project the electrodes to the discrete surface topography." + "As explained in the [3D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_3d.ipynb) tutorial, we use the [drape_electrodes_on_topography](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method to project the electrodes to the discrete surface topography." ] }, { @@ -688,8 +688,8 @@ "\n", "There are two simulation classes which may be used to simulate 2.5D IP data:\n", "\n", - "- [Simulation3DNodel](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation3DNodal), which defines the discrete electric potentials on mesh nodes.\n", - "- [Simulation3DCellCentered](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation3DCellCentered), which defines the discrete electric potentials at cell centers.\n", + "- [Simulation3DNodel](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation3DNodal), which defines the discrete electric potentials on mesh nodes.\n", + "- [Simulation3DCellCentered](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation3DCellCentered), which defines the discrete electric potentials at cell centers.\n", "\n", "For surface DC and IP data, the nodal formulation is more well-suited and will be used here. The cell-centered formulation works well for simulating borehole DC and IP data. To fully define the forward simulation, we need to connect the simulation object to:\n", "\n", diff --git a/notebooks/06-ip/inv_ip_2d.ipynb b/notebooks/06-ip/inv_ip_2d.ipynb index f5ba8ba2..7d1e420b 100644 --- a/notebooks/06-ip/inv_ip_2d.ipynb +++ b/notebooks/06-ip/inv_ip_2d.ipynb @@ -63,8 +63,8 @@ "## Import Modules\n", "\n", "Here, we import all of the functionality required to run the notebook for the tutorial exercise.\n", - "All of the functionality specific to IP is imported from [simpeg.electromagnetics.static.induced_polarization](myst:simpeg#simpeg.electromagnetics.static.induced_polarization).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." + "All of the functionality specific to IP is imported from [simpeg.electromagnetics.static.induced_polarization](xref:simpeg#simpeg.electromagnetics.static.induced_polarization).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, { @@ -181,8 +181,8 @@ "source": [ "### Load the Topography\n", "\n", - "True surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray).\n", - "For the 2.5D problem geometry however, topography is an (N, 2) [numpy.ndarray](myst:numpy#numpy.ndarray), where the first coordinate represent along-line position and the second coordinate represents the vertical position. In this tutorial, we assume the topography and electrode locations are defined according to the 2.5D geometry." + "True surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray).\n", + "For the 2.5D problem geometry however, topography is an (N, 2) [numpy.ndarray](xref:numpy#numpy.ndarray), where the first coordinate represent along-line position and the second coordinate represents the vertical position. In this tutorial, we assume the topography and electrode locations are defined according to the 2.5D geometry." ] }, { @@ -251,7 +251,7 @@ "source": [ "**Option A: DCIP2D formatted data**\n", "\n", - "For this tutorial, the observed data are organized with a UBC-GIF DCIP2D formatted data file. We can use the [read_dcip2d_ubc](myst:simpeg#simpeg.utils.io_utils.read_dcip2d_ubc) utility function to load data in this format. This function outputs a SimPEG [Data](myst:simpeg#simpeg.data.Data) object. The data are apparent chargeabilities in V/V." + "For this tutorial, the observed data are organized with a UBC-GIF DCIP2D formatted data file. We can use the [read_dcip2d_ubc](xref:simpeg#simpeg.utils.io_utils.read_dcip2d_ubc) utility function to load data in this format. This function outputs a SimPEG [Data](xref:simpeg#simpeg.data.Data) object. The data are apparent chargeabilities in V/V." ] }, { @@ -278,11 +278,11 @@ "\n", "If you have CSV-formatted data containing the ABMN electrode locations, you will need to:\n", "\n", - "* load the file into a [numpy.ndarray](myst:numpy#numpy.ndarray)\n", + "* load the file into a [numpy.ndarray](xref:numpy#numpy.ndarray)\n", "* extract the data column and the A, B, M and N electrode locations\n", - "* transform the electrode locations to the 2.5D geometry if necessary; i.e. (N, 2) [numpy.ndarray](myst:numpy#numpy.ndarray)\n", - "* use the [generate_survey_from_abmn_locations](myst:simpeg#simpeg.electromagnetics.static.utils.generate_survey_from_abmn_locations) to generate a [survey](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey) object automatically.\n", - "* Define a [Data](myst:simpeg#simpeg.data.Data) object attached to the survey and observed data.\n", + "* transform the electrode locations to the 2.5D geometry if necessary; i.e. (N, 2) [numpy.ndarray](xref:numpy#numpy.ndarray)\n", + "* use the [generate_survey_from_abmn_locations](xref:simpeg#simpeg.electromagnetics.static.utils.generate_survey_from_abmn_locations) to generate a [survey](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey) object automatically.\n", + "* Define a [Data](xref:simpeg#simpeg.data.Data) object attached to the survey and observed data.\n", "\n", "E.g. for a file containing electrode locations already formatted for a 2.5D geometry:\n", "```\n", @@ -399,7 +399,7 @@ "\n", "IP inversion is carried out on the same mesh that is used for DC resistivity inversion. Here, we reproduce the survey-based meshing approach that was used in the [2.5D Inversion of DC Resistivity Data](../05-dcr/inv_dcr_2d.ipynb) tutorial. The best-practices for meshes design for DC/IP problems is provided in the [2.5D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_2d.ipynb) tutorial.\n", "\n", - "**Tutorial mesh:** Here, a minimum cell width of 4 m (or 1/10 the minimum electrode spacing) is used within our survey region. The largest electrode spacing was 400 m, so a the padding was extended at least 1200 m from the survey region. Using the [refine_surface](myst:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](myst:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](myst:discretize#discretize.TreeMesh) API to see additional refinement methods." + "**Tutorial mesh:** Here, a minimum cell width of 4 m (or 1/10 the minimum electrode spacing) is used within our survey region. The largest electrode spacing was 400 m, so a the padding was extended at least 1200 m from the survey region. Using the [refine_surface](xref:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](xref:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](xref:discretize#discretize.TreeMesh) API to see additional refinement methods." ] }, { @@ -453,7 +453,7 @@ "source": [ "## Define the Active Cells\n", "\n", - "Use the [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function to obtain the indices of the active mesh cells from topography (e.g. cells below surface)." + "Use the [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function to obtain the indices of the active mesh cells from topography (e.g. cells below surface)." ] }, { @@ -482,7 +482,7 @@ "source": [ "## Project Electrodes to Discretized Topography\n", "\n", - "Surface IP data will not be modeled accurately if the electrodes are modeled as living above or below the surface. It is especially problematic when electrodes are modeled as living in the air. Prior to inverting surface IP data, we must project the electrodes from their true elevation to the surface of the *discretized* topography. This is done using the [drape_electrodes_on_topography](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method." + "Surface IP data will not be modeled accurately if the electrodes are modeled as living above or below the surface. It is especially problematic when electrodes are modeled as living in the air. Prior to inverting surface IP data, we must project the electrodes from their true elevation to the surface of the *discretized* topography. This is done using the [drape_electrodes_on_topography](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method." ] }, { @@ -509,7 +509,7 @@ "\n", "In order to invert IP data, we require the background conductivity/resistivity model. **In practice,** a conductivity/resistivity model is recovered by inverting DC resistivity data; see the [2.5D Inversion of DC Resistivity Data](../05-dcr/inv_dcr_2d.ipynb) tutorial. Since the conductivity/resistivity model greatly impacts the sensitivities for the IP problem, IP inversion is most successful when the recovered conductivity/resistivity model accurately characterizes the true subsurface distribution of electrical properties.\n", "\n", - "**For the tutorial,** we will demonstrate the importance of using an appropriate background conductivity model for IP inversion. For our weighted least-squares inversion approach, we use a halfspace as the background conductivity model. For the iteratively re-weighted least-squares inversion approach, we use the true subsurface conductivity model. In both cases, the model is defined on the active mesh cells, and we must use the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) mapping to map from the model space to the conductivities on the entire mesh." + "**For the tutorial,** we will demonstrate the importance of using an appropriate background conductivity model for IP inversion. For our weighted least-squares inversion approach, we use a halfspace as the background conductivity model. For the iteratively re-weighted least-squares inversion approach, we use the true subsurface conductivity model. In both cases, the model is defined on the active mesh cells, and we must use the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) mapping to map from the model space to the conductivities on the entire mesh." ] }, { @@ -661,11 +661,11 @@ "source": [ "### Mapping from the Model to the Mesh\n", "\n", - "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For whatever model we choose, we must define a mapping from the set of model parameters (a [1D numpy.ndarray](myst:numpy#numpy.ndarray)) to the physical property values of all cells in the mesh. Mappings are created using the [simpeg.maps](myst:simpeg#simpeg.maps.IdentityMap) module.\n", + "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For whatever model we choose, we must define a mapping from the set of model parameters (a [1D numpy.ndarray](xref:numpy#numpy.ndarray)) to the physical property values of all cells in the mesh. Mappings are created using the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module.\n", "\n", - "SimPEG uses a linearized formulation for simulating IP data; see [Simulation2DCellCentered](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DCellCentered) or [Simulation2DNodal](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal). In this formulation, any standard definition of the chargeability can be inverted. And the units of the recovered chargeability values is the same as the data units; e.g. intrinsic chargeability (V/V or mV/V) or integrated chargeability (ms). If you are inverting secondary voltages however, the chargeability model must represent intrinsic chargeabilities ($0 \\leq \\eta \\leq 1$) in V/V.\n", + "SimPEG uses a linearized formulation for simulating IP data; see [Simulation2DCellCentered](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DCellCentered) or [Simulation2DNodal](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal). In this formulation, any standard definition of the chargeability can be inverted. And the units of the recovered chargeability values is the same as the data units; e.g. intrinsic chargeability (V/V or mV/V) or integrated chargeability (ms). If you are inverting secondary voltages however, the chargeability model must represent intrinsic chargeabilities ($0 \\leq \\eta \\leq 1$) in V/V.\n", "\n", - "**In this tutorial,** the model parameters are the subsurface chargeabilities ($0 \\leq \\eta \\leq 1$) in V/V. We use the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) map to project the active cell chargeabilities to the entire mesh. " + "**In this tutorial,** the model parameters are the subsurface chargeabilities ($0 \\leq \\eta \\leq 1$) in V/V. We use the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) map to project the active cell chargeabilities to the entire mesh. " ] }, { @@ -719,7 +719,7 @@ "source": [ "### Define the Forward Simulation\n", "\n", - "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 2.5D IP was discussed in the [2.5D IP Forward Simulation](fwd_dcip_2d.ipynb) tutorial. Here, we use the [Simulation2DNodal](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal) simulation which solves for the electric potential on mesh nodes.\n", + "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 2.5D IP was discussed in the [2.5D IP Forward Simulation](fwd_dcip_2d.ipynb) tutorial. Here, we use the [Simulation2DNodal](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal) simulation which solves for the electric potential on mesh nodes.\n", "\n", "Since we are using a background *conductivity* model, we use ``sigma`` to define the background conductivity on the entire mesh. Because the IP problem has been linearized, we store the sensitivities for the inversion using ``storeJ``." ] @@ -753,7 +753,7 @@ "### Define the Data Misfit\n", "\n", "To understand the role of the data misfit in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/Uncertainties.html).\n", - "Here, we use the [L2DataMisfit](myst:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." + "Here, we use the [L2DataMisfit](xref:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." ] }, { @@ -778,7 +778,7 @@ "source": [ "### Define the Regularization\n", "\n", - "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). Here, we use the [WeightedLeastSquares](myst:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Length scales along x and y are used to balance the smallness and smoothness terms. Here, length scales of 5 are used to emphasize more smoothness in the recovered model. The reference model is only applied to the smallness term.\n", + "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). Here, we use the [WeightedLeastSquares](xref:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Length scales along x and y are used to balance the smallness and smoothness terms. Here, length scales of 5 are used to emphasize more smoothness in the recovered model. The reference model is only applied to the smallness term.\n", "\n", "By default, the regularization acts on the model parameters; which in the case are the chargeabilities of the active cells. So we need to specify which cells are active in the regularization. And if we wanted to apply the regularization to a function of the model parameters, we would need to set an approprate mapping object using the ``mapping`` keyword argument." ] @@ -812,7 +812,7 @@ "source": [ "### Define the Optimization Algorithm\n", "\n", - "Here, we use the [ProjectedGNCG](myst:simpeg#simpeg.optimization.ProjectedGNCG) class to solve the optimization problem using projected Gauss-Newton with conjugate gradietn solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches. Here, the `lower` property is set to 0 to ensure recovered chargeability values are positive." + "Here, we use the [ProjectedGNCG](xref:simpeg#simpeg.optimization.ProjectedGNCG) class to solve the optimization problem using projected Gauss-Newton with conjugate gradietn solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches. Here, the `lower` property is set to 0 to ensure recovered chargeability values are positive." ] }, { @@ -839,7 +839,7 @@ "source": [ "### Define the Inverse Problem\n", "\n", - "We use the [BaseInvProblem](myst:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." + "We use the [BaseInvProblem](xref:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." ] }, { @@ -866,15 +866,15 @@ "\n", "Directives represent operations that are applied while the inversion is running. Here, we apply common directives for weighted least-squares inversion of IP data and describe their roles. These are:\n", "\n", - "- [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights): Apply sensitivity weighting to counteract the natural tendency of IP inversion to place materials near the electrodes. Since the IP problem has been linearized, we do not need to update the sensitivities and we set `every_iteration=False`. For IP inversion, we do not want to use the entire dynamic range of the sensitivities to generate our weighting. So we generally set `threshold_value` to a value betwewen 1e-4 and 1e-1.\n", + "- [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights): Apply sensitivity weighting to counteract the natural tendency of IP inversion to place materials near the electrodes. Since the IP problem has been linearized, we do not need to update the sensitivities and we set `every_iteration=False`. For IP inversion, we do not want to use the entire dynamic range of the sensitivities to generate our weighting. So we generally set `threshold_value` to a value betwewen 1e-4 and 1e-1.\n", "\n", - "- [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=False` because the ideal preconditioner because the forward problem and regularization are not model-dependent.\n", + "- [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=False` because the ideal preconditioner because the forward problem and regularization are not model-dependent.\n", "\n", - "- [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", + "- [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", "\n", - "- [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 2 or 3 works well for DC resistivity inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", + "- [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 2 or 3 works well for DC resistivity inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", "\n", - "- [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", + "- [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", "\n", "\n", "The directive objects are organized in a ``list``. Upon starting the inversion or updating the recovered model at each iteration, the inversion will call each directive within the list **in order**. The order of the directives matters, and SimPEG will throw an error if directives are organized into an improper order. Some directives, like the ``BetaEstimate_ByEig`` are only used when starting the inversion. Other directives, like ``UpdatePreconditionner``, are used whenever the model is updated." @@ -916,7 +916,7 @@ "source": [ "### Define and Run the Inversion\n", "\n", - "We define the inversion using the [BaseInversion](myst:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" + "We define the inversion using the [BaseInversion](xref:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" ] }, { @@ -1250,7 +1250,7 @@ "source": [ "### Define the Regularization\n", "\n", - "Here, we use the [Sparse](myst:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Length scales along x and y are used to balance the smallness and smoothness terms. We use the same length scales that were used in the weighted least-squares inversion. Here, we apply a 0-norm on the smallness and a 2-norm on the smoothness." + "Here, we use the [Sparse](xref:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Length scales along x and y are used to balance the smallness and smoothness terms. We use the same length scales that were used in the weighted least-squares inversion. Here, we apply a 0-norm on the smallness and a 2-norm on the smoothness." ] }, { @@ -1331,9 +1331,9 @@ "source": [ "### Provide Inversion Directives\n", "\n", - "Here, we create common directives for IRLS inversion of IP data and describe their roles. In additon to the [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig) (described before), inversion with sparse-norms requires the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive. Note that `every_iteration` has been set to ``True`` for the Jacobi preconditioner. This is because the IRLS regularization is model-dependent.\n", + "Here, we create common directives for IRLS inversion of IP data and describe their roles. In additon to the [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig) (described before), inversion with sparse-norms requires the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive. Note that `every_iteration` has been set to ``True`` for the Jacobi preconditioner. This is because the IRLS regularization is model-dependent.\n", "\n", - "You will notice that we don't use the [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property. " + "You will notice that we don't use the [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property. " ] }, { diff --git a/notebooks/06-ip/inv_ip_3d.ipynb b/notebooks/06-ip/inv_ip_3d.ipynb index 2e77766d..856c2418 100644 --- a/notebooks/06-ip/inv_ip_3d.ipynb +++ b/notebooks/06-ip/inv_ip_3d.ipynb @@ -63,8 +63,8 @@ "## Import Modules\n", "\n", "Here, we import all of the functionality required to run the notebook for the tutorial exercise.\n", - "All of the functionality specific to IP is imported from [simpeg.electromagnetics.static.induced_polarization](myst:simpeg#simpeg.electromagnetics.static.induced_polarization).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." + "All of the functionality specific to IP is imported from [simpeg.electromagnetics.static.induced_polarization](xref:simpeg#simpeg.electromagnetics.static.induced_polarization).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, { @@ -251,7 +251,7 @@ "\n", "**Option A: DCIP3D formatted data**\n", "\n", - "The [read_dcip3d_ubc](myst:simpeg#simpeg.utils.io_utils.read_dcip3d_ubc) utility function can be used to load DC/IP data stored in a UBC-GIF formatted file. This function outputs a SimPEG [Data](myst:simpeg#simpeg.data.Data) object." + "The [read_dcip3d_ubc](xref:simpeg#simpeg.utils.io_utils.read_dcip3d_ubc) utility function can be used to load DC/IP data stored in a UBC-GIF formatted file. This function outputs a SimPEG [Data](xref:simpeg#simpeg.data.Data) object." ] }, { @@ -260,7 +260,7 @@ "source": [ "**Option B: Load XYZ formatted data**\n", "\n", - "For this tutorial, the observed data are organized within an XYZ formatted file. We can use the [read_dcip_xyz](myst:simpeg#simpeg.utils.io_utils.read_dcip_xyz) utility function to load data in this format. This function outputs a SimPEG [Data](myst:simpeg#simpeg.data.Data) object. The data are apparent chargeabilities in V/V.\n", + "For this tutorial, the observed data are organized within an XYZ formatted file. We can use the [read_dcip_xyz](xref:simpeg#simpeg.utils.io_utils.read_dcip_xyz) utility function to load data in this format. This function outputs a SimPEG [Data](xref:simpeg#simpeg.data.Data) object. The data are apparent chargeabilities in V/V.\n", "\n", "The `dict_headers` input argument can be used to import other data columns that are not required to define the SimPEG data object. In this case, we import a column that defines the survey line associated with each datum. We will use this to plot pseudosections for individual survey lines." ] @@ -493,7 +493,7 @@ "\n", "IP inversion is carried out on the same mesh that is used for DC resistivity inversion. Here, we reproduce the survey-based meshing approach that was used in the [3D Inversion of DC Resistivity Data](../05-dcr/inv_dcr_3d.ipynb) tutorial. The best-practices for meshes design for DC/IP problems is provided in the [2.5D Forward Simulation of DC Resistivity Data](../05-dcr/fwd_dcr_2d.ipynb) tutorial. The same rules for defining appropriate meshes for 2.5D simulations and inversion apply to 3D simulations and inversion.\n", "\n", - "**Tutorial mesh:** Here, a minimum cell width of 25 m (or 1/4 the minimum electrode spacing) is used within our survey region. The largest electrode spacing was 1000 m, so a the padding was extended at least 3000 m from the survey region. Using the [refine_surface](myst:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](myst:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](myst:discretize#discretize.TreeMesh) API to see additional refinement methods." + "**Tutorial mesh:** Here, a minimum cell width of 25 m (or 1/4 the minimum electrode spacing) is used within our survey region. The largest electrode spacing was 1000 m, so a the padding was extended at least 3000 m from the survey region. Using the [refine_surface](xref:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](xref:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](xref:discretize#discretize.TreeMesh) API to see additional refinement methods." ] }, { @@ -549,7 +549,7 @@ "source": [ "## Define the Active Cells\n", "\n", - "Use the [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function to obtain the indices of the active mesh cells from topography (e.g. cells below surface)." + "Use the [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function to obtain the indices of the active mesh cells from topography (e.g. cells below surface)." ] }, { @@ -578,7 +578,7 @@ "source": [ "## Project Electrodes to Discretized Topography\n", "\n", - "Surface IP data will not be modeled accurately if the electrodes are modeled as living above or below the surface. It is especially problematic when electrodes are modeled as living in the air. Prior to inverting surface IP data, we must project the electrodes from their true elevation to the surface of the *discretized* topography. This is done using the [drape_electrodes_on_topography](myst:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method." + "Surface IP data will not be modeled accurately if the electrodes are modeled as living above or below the surface. It is especially problematic when electrodes are modeled as living in the air. Prior to inverting surface IP data, we must project the electrodes from their true elevation to the surface of the *discretized* topography. This is done using the [drape_electrodes_on_topography](xref:simpeg#simpeg.electromagnetics.static.resistivity.Survey.drape_electrodes_on_topography) method." ] }, { @@ -743,11 +743,11 @@ "source": [ "## Mapping from the Model to the Mesh\n", "\n", - "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For whatever model we choose, we must define a mapping from the set of model parameters (a [1D numpy.ndarray](myst:numpy#numpy.ndarray)) to the physical property values of all cells in the mesh. Mappings are created using the [simpeg.maps](myst:simpeg#simpeg.maps.IdentityMap) module.\n", + "In SimPEG, the term 'model' is not synonymous with the physical property values defined on the mesh. For whatever model we choose, we must define a mapping from the set of model parameters (a [1D numpy.ndarray](xref:numpy#numpy.ndarray)) to the physical property values of all cells in the mesh. Mappings are created using the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module.\n", "\n", - "SimPEG uses a linearized formulation for simulating IP data; see [Simulation2DCellCentered](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DCellCentered) or [Simulation2DNodal](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal). In this formulation, any standard definition of the chargeability can be inverted. And the units of the recovered chargeability values is the same as the data units; e.g. intrinsic chargeability (V/V or mV/V) or integrated chargeability (ms). If you are inverting secondary voltages however, the chargeability model must represent intrinsic chargeabilities ($0 \\leq \\eta \\leq 1$) in V/V.\n", + "SimPEG uses a linearized formulation for simulating IP data; see [Simulation2DCellCentered](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DCellCentered) or [Simulation2DNodal](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation2DNodal). In this formulation, any standard definition of the chargeability can be inverted. And the units of the recovered chargeability values is the same as the data units; e.g. intrinsic chargeability (V/V or mV/V) or integrated chargeability (ms). If you are inverting secondary voltages however, the chargeability model must represent intrinsic chargeabilities ($0 \\leq \\eta \\leq 1$) in V/V.\n", "\n", - "**In this tutorial,** the model parameters are the subsurface chargeabilities ($0 \\leq \\eta \\leq 1$) in V/V. We use the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) map to project the active cell chargeabilities to the entire mesh. " + "**In this tutorial,** the model parameters are the subsurface chargeabilities ($0 \\leq \\eta \\leq 1$) in V/V. We use the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) map to project the active cell chargeabilities to the entire mesh. " ] }, { @@ -802,7 +802,7 @@ "source": [ "## Define the Forward Simulation\n", "\n", - "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 3D IP was discussed in the [3D IP Forward Simulation](fwd_dcip_3d.ipynb) tutorial. Here, we use the [Simulation3DNodal](myst:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation3DNodal) simulation which solves for the electric potential on mesh nodes.\n", + "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 3D IP was discussed in the [3D IP Forward Simulation](fwd_dcip_3d.ipynb) tutorial. Here, we use the [Simulation3DNodal](xref:simpeg#simpeg.electromagnetics.static.induced_polarization.Simulation3DNodal) simulation which solves for the electric potential on mesh nodes.\n", "\n", "Since we are using a background *conductivity* model, we use ``sigma`` to define the background conductivity on the entire mesh. Because the IP problem has been linearized, we store the sensitivities for the inversion using ``storeJ``." ] @@ -836,7 +836,7 @@ "## Define the Data Misfit\n", "\n", "To understand the role of the data misfit in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/Uncertainties.html).\n", - "Here, we use the [L2DataMisfit](myst:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." + "Here, we use the [L2DataMisfit](xref:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." ] }, { @@ -861,7 +861,7 @@ "source": [ "## Define the Regularization\n", "\n", - "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). Here, we use the [WeightedLeastSquares](myst:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Length scales along x, y and z are used to balance the smallness and smoothness terms. And the reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros.\n", + "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). Here, we use the [WeightedLeastSquares](xref:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Length scales along x, y and z are used to balance the smallness and smoothness terms. And the reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros.\n", "\n", "By default, the regularization acts on the model parameters; which in the case are the log-conductivities of the active cells. So we need to specify which cells are active in the regularization. And if we wanted to apply the regularization to a function of the model parameters, we would need to set an approprate mapping object using the ``mapping`` keyword argument." ] @@ -896,7 +896,7 @@ "source": [ "## Define the Optimization Algorithm\n", "\n", - "Here, we use the [ProjectedGNCG](myst:simpeg#simpeg.optimization.ProjectedGNCG) class to solve the optimization problem using projected Gauss-Newton with conjugate gradietn solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches. Here, the `lower` property is set to 0 to ensure recovered chargeability values are positive." + "Here, we use the [ProjectedGNCG](xref:simpeg#simpeg.optimization.ProjectedGNCG) class to solve the optimization problem using projected Gauss-Newton with conjugate gradietn solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches. Here, the `lower` property is set to 0 to ensure recovered chargeability values are positive." ] }, { @@ -923,7 +923,7 @@ "source": [ "## Define the Inverse Problem\n", "\n", - "We use the [BaseInvProblem](myst:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." + "We use the [BaseInvProblem](xref:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." ] }, { @@ -950,15 +950,15 @@ "\n", "Directives represent operations that are applied while the inversion is running. Here, we apply common directives for weighted least-squares inversion of IP data and describe their roles. These are:\n", "\n", - "- [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights): Apply sensitivity weighting to counteract the natural tendency of IP inversion to place materials near the electrodes. Since the IP problem has been linearized, we do not need to update the sensitivities and we set `every_iteration=False`. For IP inversion, we do not want to use the entire dynamic range of the sensitivities to generate our weighting. So we generally set `threshold_value` to a value betwewen 1e-4 and 1e-1.\n", + "- [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights): Apply sensitivity weighting to counteract the natural tendency of IP inversion to place materials near the electrodes. Since the IP problem has been linearized, we do not need to update the sensitivities and we set `every_iteration=False`. For IP inversion, we do not want to use the entire dynamic range of the sensitivities to generate our weighting. So we generally set `threshold_value` to a value betwewen 1e-4 and 1e-1.\n", "\n", - "- [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=False` because the ideal preconditioner because the forward problem and regularization are not model-dependent.\n", + "- [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=False` because the ideal preconditioner because the forward problem and regularization are not model-dependent.\n", "\n", - "- [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", + "- [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", "\n", - "- [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 2 or 3 works well for DC resistivity inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", + "- [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 2 or 3 works well for DC resistivity inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", "\n", - "- [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", + "- [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", "\n", "\n", "The directive objects are organized in a ``list``. Upon starting the inversion or updating the recovered model at each iteration, the inversion will call each directive within the list **in order**. The order of the directives matters, and SimPEG will throw an error if directives are organized into an improper order. Some directives, like the ``BetaEstimate_ByEig`` are only used when starting the inversion. Other directives, like ``UpdatePreconditionner``, are used whenever the model is updated." @@ -1000,7 +1000,7 @@ "source": [ "## Define and Run the Inversion\n", "\n", - "We define the inversion using the [BaseInversion](myst:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" + "We define the inversion using the [BaseInversion](xref:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" ] }, { diff --git a/notebooks/07-fdem/fwd_fdem_1d.ipynb b/notebooks/07-fdem/fwd_fdem_1d.ipynb index 169c4db8..f75d3720 100644 --- a/notebooks/07-fdem/fwd_fdem_1d.ipynb +++ b/notebooks/07-fdem/fwd_fdem_1d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** In this tutorial, we present the fundamentals of simulating FDEM data in SimPEG. We use the module [simpeg.electromagnetics.static.frequency_domain](myst:simpeg#simpeg.electromagnetics.frequency_domain) to simulate FDEM data for a 1D sounding. The [Simulation1DLayered](myst:simpeg#simpeg.electromagnetics.frequency_domain.simulation_1d.Simulation1DLayered) class is used to solve the problem via a semi-analytic Hankel transform solution. Note that almost all of what is learned here can be applied to simulating 3D FDEM data.\n", + "**Summary:** In this tutorial, we present the fundamentals of simulating FDEM data in SimPEG. We use the module [simpeg.electromagnetics.static.frequency_domain](xref:simpeg#simpeg.electromagnetics.frequency_domain) to simulate FDEM data for a 1D sounding. The [Simulation1DLayered](xref:simpeg#simpeg.electromagnetics.frequency_domain.simulation_1d.Simulation1DLayered) class is used to solve the problem via a semi-analytic Hankel transform solution. Note that almost all of what is learned here can be applied to simulating 3D FDEM data.\n", "\n", "**Learning Objectives:**\n", "\n", @@ -59,8 +59,8 @@ "source": [ "## Importing Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to FDEM is imported from [simpeg.electromagnetics.frequency_domain](myst:simpeg#simpeg.electromagnetics.frequency_domain).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils)." + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to FDEM is imported from [simpeg.electromagnetics.frequency_domain](xref:simpeg#simpeg.electromagnetics.frequency_domain).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils)." ] }, { @@ -101,11 +101,11 @@ "\n", "FDEM surveys within SimPEG require the user to create and connect three types of objects:\n", "\n", - "- **receivers:** There are a multitude of FDEM receiver classes within SimPEG, each of which is used to simulate data corresponding to a different field measurement; e.g. [PointMagneticField](myst:simpeg#simpeg.electromagnetics.frequency_domain.receivers.PointMagneticField) and [PointElectricField](myst:simpeg#simpeg.electromagnetics.frequency_domain.receivers.PointElectricField). The properties for each FDEM receiver object generally include: the orientation of the field being measured (x, y, z, other), the component (real or imaginary), the data type (field or ppm), and one or more associated observation locations.\n", - "- **sources:** There are a multitude of FDEM source classes within SimPEG, each of which corresponds to a different geometry; e.g. [MagDipole](myst:simpeg#simpeg.electromagnetics.frequency_domain.sources.MagDipole), [CircularLoop](myst:simpeg#simpeg.electromagnetics.frequency_domain.sources.CircularLoop) and [LineCurrent](myst:simpeg#simpeg.electromagnetics.frequency_domain.sources.LineCurrent). Source classes generally require the user to define the operating frequency (in Hz), its location and its geometry.\n", + "- **receivers:** There are a multitude of FDEM receiver classes within SimPEG, each of which is used to simulate data corresponding to a different field measurement; e.g. [PointMagneticField](xref:simpeg#simpeg.electromagnetics.frequency_domain.receivers.PointMagneticField) and [PointElectricField](xref:simpeg#simpeg.electromagnetics.frequency_domain.receivers.PointElectricField). The properties for each FDEM receiver object generally include: the orientation of the field being measured (x, y, z, other), the component (real or imaginary), the data type (field or ppm), and one or more associated observation locations.\n", + "- **sources:** There are a multitude of FDEM source classes within SimPEG, each of which corresponds to a different geometry; e.g. [MagDipole](xref:simpeg#simpeg.electromagnetics.frequency_domain.sources.MagDipole), [CircularLoop](xref:simpeg#simpeg.electromagnetics.frequency_domain.sources.CircularLoop) and [LineCurrent](xref:simpeg#simpeg.electromagnetics.frequency_domain.sources.LineCurrent). Source classes generally require the user to define the operating frequency (in Hz), its location and its geometry.\n", "- **survey:** the object which stores and organizes all of the sources and receivers.\n", "\n", - "For a full description of all source and receiver classes, please visit API documentation for [simpeg.electromagnetics.frequency_domain](myst:simpeg#simpeg.electromagnetics.frequency_domain).\n", + "For a full description of all source and receiver classes, please visit API documentation for [simpeg.electromagnetics.frequency_domain](xref:simpeg#simpeg.electromagnetics.frequency_domain).\n", "\n", "**Topography:** When generating the survey for a 1D forward simulation, sources and receivers **must** be located **above** the Earth's surface. By default, the Earth's surface is at z = 0 m when defining the 1D simulation. So for 1D FDEM problems, it is easiest to define the z-locations of all sources and receivers as flight heights.\n", "\n", @@ -277,15 +277,15 @@ "source": [ "## Models and Mappings for 1D Simulations\n", "\n", - "In SimPEG, the term 'model' is not necessarily synonymous with a set of physical property values. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](myst:numpy#numpy.ndarray) whose lengths are equal to the number of model parameters. For 1D FDEM simulations, we can characterize the Earth's electric properties according to electrical conductivity or electrical resistivity.\n", + "In SimPEG, the term 'model' is not necessarily synonymous with a set of physical property values. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](xref:numpy#numpy.ndarray) whose lengths are equal to the number of model parameters. For 1D FDEM simulations, we can characterize the Earth's electric properties according to electrical conductivity or electrical resistivity.\n", "\n", "Classes within the ``simpeg.maps`` module are used to define the mapping that connects the model to the parameters required to run the 1D FDEM simulation; i.e. layer conductivities/resistivities, magnetic permeabilities and/or layer thicknesses. In this tutorial, we demonstrate several types of mappings and models that may be used for 1D FDEM simulation.\n", "\n", - "**CASE 1: Conductivity model.** The easiest case is when the layer thicknesses are fixed in the simulation, and by default we assume the Earth is non-permeable. Here, we define the model as the layer conductivities. And the mapping from the model to the conductivities is defined using the [simpeg.maps.IdentityMap](myst:simpeg#simpeg.maps.IdentityMap) class.\n", + "**CASE 1: Conductivity model.** The easiest case is when the layer thicknesses are fixed in the simulation, and by default we assume the Earth is non-permeable. Here, we define the model as the layer conductivities. And the mapping from the model to the conductivities is defined using the [simpeg.maps.IdentityMap](xref:simpeg#simpeg.maps.IdentityMap) class.\n", "\n", - "**CASE 2: Log-resistivity model with fixed magnetic permeability.** Here, the model parameters are the log-resistivity values for the layers. In addition to fixing the layer thicknesses in the simulation, we need to fix the magnetic permeabilities. In this case, we need a mapping that converts log-resistivities to resistivities. To do this, we use the [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) class.\n", + "**CASE 2: Log-resistivity model with fixed magnetic permeability.** Here, the model parameters are the log-resistivity values for the layers. In addition to fixing the layer thicknesses in the simulation, we need to fix the magnetic permeabilities. In this case, we need a mapping that converts log-resistivities to resistivities. To do this, we use the [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) class.\n", "\n", - "**CASE 3: Log-conductivity, magnetic permeability and layer thicknesses.** In this case, the model defines log-conductivities, magnetic permeabilities and layer thicknesses. We therefore need mappings that extract each parameter type from the model, and a converts to the appropriate quantity. For this, we require the [simpeg.maps.Wires](myst:simpeg#simpeg.maps.Wires) mapping and [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) mapping classes. Note that successive mappings can be chained together using the $*$ operator." + "**CASE 3: Log-conductivity, magnetic permeability and layer thicknesses.** In this case, the model defines log-conductivities, magnetic permeabilities and layer thicknesses. We therefore need mappings that extract each parameter type from the model, and a converts to the appropriate quantity. For this, we require the [simpeg.maps.Wires](xref:simpeg#simpeg.maps.Wires) mapping and [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) mapping classes. Note that successive mappings can be chained together using the $*$ operator." ] }, { @@ -367,7 +367,7 @@ "source": [ "## Defining the Forward Simulation\n", "\n", - "In SimPEG, the physics of the forward simulation is defined by creating an instance of an appropriate simulation class. Here, we use the [Simulation1DLayered](myst:simpeg#simpeg.electromagnetics.frequency_domain.Simulation1DLayered) which simulates the data according to a 1D Hankel transform solution. To fully define the forward simulation, we need to connect the simulation object to:\n", + "In SimPEG, the physics of the forward simulation is defined by creating an instance of an appropriate simulation class. Here, we use the [Simulation1DLayered](xref:simpeg#simpeg.electromagnetics.frequency_domain.Simulation1DLayered) which simulates the data according to a 1D Hankel transform solution. To fully define the forward simulation, we need to connect the simulation object to:\n", "\n", "- the survey\n", "- the layer thicknesses\n", @@ -465,7 +465,7 @@ "source": [ "## Predict 1D FDEM Data\n", "\n", - "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](myst:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the model, the data predicted for CASE 1 and CASE 2 should be the same. And for CASE 3, we expect to see differences given the layer is now significantly permeable.\n", + "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](xref:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the model, the data predicted for CASE 1 and CASE 2 should be the same. And for CASE 3, we expect to see differences given the layer is now significantly permeable.\n", "\n", "For surveys consisting of multiple sources, multiple receivers per source and multiple observation locations per receiver, the predicted data vector is organized:\n", "\n", diff --git a/notebooks/07-fdem/fwd_fdem_3d.ipynb b/notebooks/07-fdem/fwd_fdem_3d.ipynb index a6baa305..345400fe 100644 --- a/notebooks/07-fdem/fwd_fdem_3d.ipynb +++ b/notebooks/07-fdem/fwd_fdem_3d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** In this tutorial, we present the fundamentals of simulating 3D FDEM data in SimPEG. We use the module [simpeg.electromagnetics.static.frequency_domain](myst:simpeg#simpeg.electromagnetics.frequency_domain) to simulate airborne FDEM data on a tree mesh. We assume the reader is already familiar with the fundamental aspects of simulating FDEM data in SimPEG, which were covered in the [Forward Simulation of Frequency Domain EM Data for a 1D Sounding](fwd_fdem_1d.ipynb) tutorial. This tutorial focusses on the following:\n", + "**Summary:** In this tutorial, we present the fundamentals of simulating 3D FDEM data in SimPEG. We use the module [simpeg.electromagnetics.static.frequency_domain](xref:simpeg#simpeg.electromagnetics.frequency_domain) to simulate airborne FDEM data on a tree mesh. We assume the reader is already familiar with the fundamental aspects of simulating FDEM data in SimPEG, which were covered in the [Forward Simulation of Frequency Domain EM Data for a 1D Sounding](fwd_fdem_1d.ipynb) tutorial. This tutorial focusses on the following:\n", "\n", "- Defining FDEM surveys for 3D simulations\n", "- How to define an appropriate tree mesh based on problem geometry\n", @@ -55,8 +55,8 @@ "source": [ "## Importing Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to FDEM is imported from [simpeg.electromagnetics.frequency_domain](myst:simpeg#simpeg.electromagnetics.frequency_domain). \n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). And to generate the mesh, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to FDEM is imported from [simpeg.electromagnetics.frequency_domain](xref:simpeg#simpeg.electromagnetics.frequency_domain). \n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). And to generate the mesh, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, { @@ -98,7 +98,7 @@ "source": [ "## Defining Topography\n", "\n", - "Surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) for 3D simulations.\n", + "Surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) for 3D simulations.\n", "To keep things simple, we create flat topography for the forward simulation.\n", "For user-specific simulations, you may generate less trivial topography or load topography from an XYZ file." ] @@ -182,7 +182,7 @@ "source": [ "## Defining the Survey\n", "\n", - "The fundamentals of constructing FDEM surveys was presented in the [Forward Simulation of Frequency Domain EM Data for a 1D Sounding](fwd_fdem_1d.ipynb) tutorial. We advise the reader to already be familiar with this material. For a full description of all source and receiver classes, please visit API documentation for [simpeg.electromagnetics.frequency_domain](myst:simpeg#simpeg.electromagnetics.frequency_domain).\n", + "The fundamentals of constructing FDEM surveys was presented in the [Forward Simulation of Frequency Domain EM Data for a 1D Sounding](fwd_fdem_1d.ipynb) tutorial. We advise the reader to already be familiar with this material. For a full description of all source and receiver classes, please visit API documentation for [simpeg.electromagnetics.frequency_domain](xref:simpeg#simpeg.electromagnetics.frequency_domain).\n", "\n", "**For this tutorial**, we simulate data for a [DIGHEM survey geometry](https://em.geosci.xyz/content/geophysical_surveys/airborne_fdem/dighem.html). This surveys is ideal for demonstrating the general construction of FDEM survey within SimPEG because there are a multitude of data locations and source-receiver geometries; i.e. vertical coplanar and horizontal coaxial. Here, the airborne survey consists of an 9x9 grid with a spacing of 50 m. The transmitter-receiver separation is in the x-direction and the flight height is 20 m. And the location of the datum is defined at the source location." ] @@ -294,7 +294,7 @@ "## Designing a (Tree) Mesh for FDEM\n", "\n", "Meshes are designed using the [discretize](https://discretize.simpeg.xyz/en/main) package. See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating meshes.\n", - "Here, the forward simulation is computed for a [tree mesh](myst:discretize#discretize.TreeMesh). Because of the modular nature of SimPEG, you could define a [tensor mesh](myst:discretize#discretize.TensorMesh) instead.\n", + "Here, the forward simulation is computed for a [tree mesh](xref:discretize#discretize.TreeMesh). Because of the modular nature of SimPEG, you could define a [tensor mesh](xref:discretize#discretize.TensorMesh) instead.\n", "\n", "### General Approach:\n", "\n", @@ -339,7 +339,7 @@ "- A minimum cells size of 10 m was used to discretize the Earth. We expect the inductive response from the host to be accurate at all frequencies. However, the inductive response from the conductive target may not be particularly accurate at the highest frequency.\n", "- The width of the domain in the x, y and z direction was chosen to be 4000 m. As a result, the padding (~2000 m) is roughly 2-3 times the largest skin depth.\n", "\n", - "Using the [refine_surface](myst:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](myst:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](myst:discretize#discretize.TreeMesh) API to see additional refinement methods." + "Using the [refine_surface](xref:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. And using the [refine_points](xref:discretize#discretize.TreeMesh.refine_points) methods, we refine based on electrodes locations. Visit the [tree mesh](xref:discretize#discretize.TreeMesh) API to see additional refinement methods." ] }, { @@ -428,7 +428,7 @@ "source": [ "## Active Cells\n", "\n", - "Simulated geophysical data are dependent on the subsurface distribution of physical property values. As a result, the cells lying below the surface topography are commonly referred to as 'active cells'. And air cells, whose physical property values are fixed, are commonly referred to as 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "Simulated geophysical data are dependent on the subsurface distribution of physical property values. As a result, the cells lying below the surface topography are commonly referred to as 'active cells'. And air cells, whose physical property values are fixed, are commonly referred to as 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -455,10 +455,10 @@ "source": [ "## Models and Mapping from the Model to the Mesh\n", "\n", - "In SimPEG, the term 'model' is not necessarily synonymous with the set of physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](myst:numpy#numpy.ndarray) whose lengths are\n", + "In SimPEG, the term 'model' is not necessarily synonymous with the set of physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](xref:numpy#numpy.ndarray) whose lengths are\n", "equal to the number of model parameters.\n", "\n", - "Classes within the [simpeg.maps](myst:simpeg#simpeg.maps.IdentityMap) module are used to define the mapping that connects the model to the physical property values used in the 3D FDEM simulation. Sophisticated mappings can be defined by combining multiple mapping objects. But in the simplest case, the mapping is an identity map and the model consists of the conductivity/resistivity values for all mesh cells (including air). Here, the model consists of the log-conductivity values for all active mesh cells.\n", + "Classes within the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module are used to define the mapping that connects the model to the physical property values used in the 3D FDEM simulation. Sophisticated mappings can be defined by combining multiple mapping objects. But in the simplest case, the mapping is an identity map and the model consists of the conductivity/resistivity values for all mesh cells (including air). Here, the model consists of the log-conductivity values for all active mesh cells.\n", "\n", "When simulating 3D FDEM data, we have the choice of using resistivity or conductivity to define the Earth's electrical properties. However, one option may be implemented more naturally depending on the formulation used." ] @@ -538,7 +538,7 @@ "source": [ "### Defining the Mapping\n", "\n", - "Here, we use the [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) mapping to convert our model values from log-conductivities to conductivities, and the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) mapping to project active cells to the entire mesh. As we will demonstrate, a single mapping can be constructed from multiple mapping classes using the $*$ operator. **Important:** When defining the active cells mapping, we set all inactive (air) cells to 1e-8 $S/m$ instead of $0$. This is done to ensure that the linear system constructed to solve the PDE for the DC resistivity problem is well-conditioned." + "Here, we use the [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) mapping to convert our model values from log-conductivities to conductivities, and the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) mapping to project active cells to the entire mesh. As we will demonstrate, a single mapping can be constructed from multiple mapping classes using the $*$ operator. **Important:** When defining the active cells mapping, we set all inactive (air) cells to 1e-8 $S/m$ instead of $0$. This is done to ensure that the linear system constructed to solve the PDE for the DC resistivity problem is well-conditioned." ] }, { @@ -565,7 +565,7 @@ "source": [ "### Plotting the discretization and active conductivities\n", "\n", - "To show the geometry of the problem, we plot the discretization near several sources and the active cell conductivities using the [plot_slice](myst:discretize#discretize.TreeMesh.plot_slice) method." + "To show the geometry of the problem, we plot the discretization near several sources and the active cell conductivities using the [plot_slice](xref:discretize#discretize.TreeMesh.plot_slice) method." ] }, { @@ -655,10 +655,10 @@ "\n", "There are a multitude of simulation classes, each of which solves Maxwell's equations in terms of a different field:\n", "\n", - "- [Simulation3DElectricField](myst:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DElectricField), which solves for the electric fields on mesh edges.\n", - "- [Simulation3DMagneticFluxDensity](myst:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DMagneticFluxDensity), which solves for the magnetic flux density on mesh faces.\n", - "- [Simulation3DMagneticField](myst:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DMagneticField), which solves for the magnetic fields on mesh edges.\n", - "- [Simulation3DCurrentDensity](myst:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DCurrentDensity), which solves for the current density on mesh faces.\n", + "- [Simulation3DElectricField](xref:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DElectricField), which solves for the electric fields on mesh edges.\n", + "- [Simulation3DMagneticFluxDensity](xref:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DMagneticFluxDensity), which solves for the magnetic flux density on mesh faces.\n", + "- [Simulation3DMagneticField](xref:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DMagneticField), which solves for the magnetic fields on mesh edges.\n", + "- [Simulation3DCurrentDensity](xref:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DCurrentDensity), which solves for the current density on mesh faces.\n", "\n", "The optimum choice in simulation class depends on the fields being measured and the class used to define FDEM sources. For example, it may be best to use the electric field formulation when the source is a line-current and electric fields are being measured. And it may be best to use the magnetic field formulation for a magnetic dipole source and magnetic field measurements.\n", "\n", @@ -699,7 +699,7 @@ "source": [ "## Simulating Total Field and Secondary Field Data\n", "\n", - "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](myst:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the models representing the Earth's electrical properties, the data predicted by both simulations is equivalent." + "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](xref:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the models representing the Earth's electrical properties, the data predicted by both simulations is equivalent." ] }, { diff --git a/notebooks/07-fdem/inv_fdem_1d.ipynb b/notebooks/07-fdem/inv_fdem_1d.ipynb index 17e9658b..eb308da6 100644 --- a/notebooks/07-fdem/inv_fdem_1d.ipynb +++ b/notebooks/07-fdem/inv_fdem_1d.ipynb @@ -64,7 +64,7 @@ "## Importing Modules\n", "\n", "Here, we import all of the functionality required to run the notebook for the tutorial exercise.\n", - "All of the functionality specific to the forward simulation of 1D frequency domain EM data are imported from the [simpeg.electromagnetics.frequency_domain](myst:simpeg#simpeg.electromagnetics.frequency_domain) module. Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." + "All of the functionality specific to the forward simulation of 1D frequency domain EM data are imported from the [simpeg.electromagnetics.frequency_domain](xref:simpeg#simpeg.electromagnetics.frequency_domain) module. Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, { @@ -348,7 +348,7 @@ "source": [ "## Defining the Data\n", "\n", - "The SimPEG [Data](myst:simpeg#simpeg.data.Data) class is required for inversion and connects the observed data, uncertainties and survey geometry." + "The SimPEG [Data](xref:simpeg#simpeg.data.Data) class is required for inversion and connects the observed data, uncertainties and survey geometry." ] }, { @@ -479,7 +479,7 @@ "\n", "Recall from the [1D Forward Simulation of Frequency-Domain EM Data for a Single Sounding](fwd_fdem_1d.ipynb) tutorial that the 'model' is not necessarily synonymous with physical property values. And that we need to define a mapping from the model to the set of input parameters required by the forward simulation. When inverting to recover electrical conductivities (or resistivities), it is best to use the log-value, as electrical conductivities of rocks span many order of magnitude.\n", "\n", - "Here, the model defines the log-conductivity values for a defined set of subsurface layers. And we use the [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) to map from the model parameters to the conductivity values required by the forward simulation." + "Here, the model defines the log-conductivity values for a defined set of subsurface layers. And we use the [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) to map from the model parameters to the conductivity values required by the forward simulation." ] }, { @@ -537,7 +537,7 @@ "source": [ "### Define the Forward Simulation\n", "\n", - "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 1D DC resistivity was discussed in the [1D Forward Simulation of Frequency-Domain EM Data for a Single Sounding](fwd_fdem_1d.ipynb) tutorial. Here, we use the [Simulation1DLayers](myst:simpeg#simpeg.electromagnetics.frequency_domain.Simulation1DLayers) which simulates the data according to a 1D Hankel transform solution.\n", + "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 1D DC resistivity was discussed in the [1D Forward Simulation of Frequency-Domain EM Data for a Single Sounding](fwd_fdem_1d.ipynb) tutorial. Here, we use the [Simulation1DLayered](xref:simpeg#simpeg.electromagnetics.frequency_domain.Simulation1DLayered) which simulates the data according to a 1D Hankel transform solution.\n", "\n", "The layer thicknesses are a static property of the simulation, and we set them using the ``thicknessess`` keyword argument. Since our model consists of log-conductivities, we use ``sigmaMap`` to set the mapping from the model to the layer conductivities." ] @@ -567,7 +567,7 @@ "### Data Misfit\n", "\n", "To understand the role of the data misfit in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/Uncertainties.html).\n", - "Here, we use the [L2DataMisfit](myst:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." + "Here, we use the [L2DataMisfit](xref:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." ] }, { @@ -594,7 +594,7 @@ "\n", "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). \n", "\n", - "To define the regularization within SimPEG, we must define a 1D [tensor mesh](myst:discretize#discretize.TensorMesh). Meshes are designed using the [discretize package](https://discretize.simpeg.xyz). Whereas layer *thicknesses* and our *model* are defined from our top-layer down, tensor meshes are defined from the bottom up. So to define a 1D tensor mesh for the regularization, we:\n", + "To define the regularization within SimPEG, we must define a 1D [tensor mesh](xref:discretize#discretize.TensorMesh). Meshes are designed using the [discretize package](https://discretize.simpeg.xyz). Whereas layer *thicknesses* and our *model* are defined from our top-layer down, tensor meshes are defined from the bottom up. So to define a 1D tensor mesh for the regularization, we:\n", "\n", "- add an extra layer to the end of our thicknesses so that the number of cells in the 1D mesh equals the number of model parameters\n", "- reverse the order so that the model parameters in the regularization match up with the appropriate cell\n", @@ -643,7 +643,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "By default, the regularization acts on the model parameters. In this case, the model parameters are the log-resistivities, not the electric resistivities!!! Here, we use the [WeightedLeastSquares](myst:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Here, length scale along x are used to balance the smallness and smoothness terms; yes, x is smoothness along the vertical direction. And the reference model is only applied to the smallness term. If we wanted to apply the regularization to a function of the model parameters, we would need to set an approprate mapping object using the ``mapping`` keyword argument." + "By default, the regularization acts on the model parameters. In this case, the model parameters are the log-resistivities, not the electric resistivities!!! Here, we use the [WeightedLeastSquares](xref:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Here, length scale along x are used to balance the smallness and smoothness terms; yes, x is smoothness along the vertical direction. And the reference model is only applied to the smallness term. If we wanted to apply the regularization to a function of the model parameters, we would need to set an approprate mapping object using the ``mapping`` keyword argument." ] }, { @@ -673,7 +673,7 @@ "source": [ "### Optimization\n", "\n", - "Here, we use the [InexactGaussNewton](myst:simpeg#simpeg.optimization.InexactGaussNewton) class to solve the optimization problem using the inexact Gauss Newton with conjugate gradient solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches." + "Here, we use the [InexactGaussNewton](xref:simpeg#simpeg.optimization.InexactGaussNewton) class to solve the optimization problem using the inexact Gauss Newton with conjugate gradient solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches." ] }, { @@ -700,7 +700,7 @@ "source": [ "### Inverse Problem\n", "\n", - "We use the [BaseInvProblem](myst:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." + "We use the [BaseInvProblem](xref:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." ] }, { @@ -727,13 +727,13 @@ "\n", "To understand the role of directives in the inversion, please visit this online resource. Here, we apply common directives for weighted least-squares inversion of gravity data and describe their roles. These are:\n", "\n", - "- [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=True` because the ideal preconditioner is model-dependent.\n", + "- [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=True` because the ideal preconditioner is model-dependent.\n", "\n", - "- [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", + "- [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", "\n", - "- [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 3 works well for FDEM inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", + "- [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 3 works well for FDEM inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", "\n", - "- [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", + "- [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", "\n", "\n", "The directive objects are organized in a ``list``. Upon starting the inversion or updating the recovered model at each iteration, the inversion will call each directive within the list **in order**. The order of the directives matters, and SimPEG will throw an error if directives are organized into an improper order. Some directives, like the ``BetaEstimate_ByEig`` are only used when starting the inversion. Other directives, like ``UpdatePreconditionner``, are used whenever the model is updated." @@ -766,7 +766,7 @@ "source": [ "### Define and Run the Inversion\n", "\n", - "We define the inversion using the [BaseInversion](myst:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" + "We define the inversion using the [BaseInversion](xref:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" ] }, { @@ -1086,7 +1086,7 @@ "source": [ "### Regularization\n", "\n", - "Here, we use the [Sparse](myst:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Here, the scaling constants that balance the smallness and smoothness terms are set directly. Equal emphasis on smallness and smoothness is generally applied by using the inverse square of the smallest cell dimension. The reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros. Here, we apply a 1-norm to the smallness term and a 1-norm to first-order smoothness along the x (vertical direction)." + "Here, we use the [Sparse](xref:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Here, the scaling constants that balance the smallness and smoothness terms are set directly. Equal emphasis on smallness and smoothness is generally applied by using the inverse square of the smallest cell dimension. The reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros. Here, we apply a 1-norm to the smallness term and a 1-norm to first-order smoothness along the x (vertical direction)." ] }, { @@ -1165,9 +1165,9 @@ "source": [ "### Directives\n", "\n", - "Here, we create common directives for IRLS inversion of total magnetic intensity data and describe their roles. In additon to the [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig) (described before), inversion with sparse-norms requires the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive.\n", + "Here, we create common directives for IRLS inversion of total magnetic intensity data and describe their roles. In additon to the [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig) (described before), inversion with sparse-norms requires the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive.\n", "\n", - "You will notice that we don't use the [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property. " + "You will notice that we don't use the [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property. " ] }, { @@ -1528,7 +1528,7 @@ "source": [ "### Model and Mapping\n", "\n", - "For a 3-layered Earth model, the model consists of 2 log-thicknesses and 3 log-conductivities. Similar to the [1D Forward Simulation of Frequency Domain EM Data for a Single Sounding](fwd_fdem_1d.ipynb) tutorial, need a mapping that extract log-thicknesses and log-resistivities from the model, and mappings that convert log-values to property values. For this, we require the [simpeg.maps.Wires](myst:simpeg#simpeg.maps.Wires) mapping and [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) mapping classes. Note that successive mappings can be chained together using the $*$ operator." + "For a 3-layered Earth model, the model consists of 2 log-thicknesses and 3 log-conductivities. Similar to the [1D Forward Simulation of Frequency Domain EM Data for a Single Sounding](fwd_fdem_1d.ipynb) tutorial, need a mapping that extract log-thicknesses and log-resistivities from the model, and mappings that convert log-values to property values. For this, we require the [simpeg.maps.Wires](xref:simpeg#simpeg.maps.Wires) mapping and [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) mapping classes. Note that successive mappings can be chained together using the $*$ operator." ] }, { @@ -1641,9 +1641,9 @@ "source": [ "### (Combo) Regularization\n", "\n", - "We need to define a regularization for each model parameter type. In this case, we have log-thicknesses and log-conductivities. For each model parameter type, we create a 1D [tensor mesh](myst:discretize#discretize.TensorMesh) with length equal to the number of parameters. In the ``mapping`` keyword argument, we used the wire map that extracts the specific model parameters from the model.\n", + "We need to define a regularization for each model parameter type. In this case, we have log-thicknesses and log-conductivities. For each model parameter type, we create a 1D [tensor mesh](xref:discretize#discretize.TensorMesh) with length equal to the number of parameters. In the ``mapping`` keyword argument, we used the wire map that extracts the specific model parameters from the model.\n", "\n", - "Using the $*$ operator, separate regularizations can be summed to form a regularization that is also a [ComboObjectiveFunction](myst:simpeg#simpeg.objective_function.ComboObjectiveFunction). By setting the ``multipliers`` property, we can emphasize the relative contributions of the log-thicknesses and log-conductivities regularizations." + "Using the $*$ operator, separate regularizations can be summed to form a regularization that is also a [ComboObjectiveFunction](xref:simpeg#simpeg.objective_function.ComboObjectiveFunction). By setting the ``multipliers`` property, we can emphasize the relative contributions of the log-thicknesses and log-conductivities regularizations." ] }, { diff --git a/notebooks/08-tdem/fwd_tdem_1d.ipynb b/notebooks/08-tdem/fwd_tdem_1d.ipynb index 6c6d98c0..80ec65f1 100644 --- a/notebooks/08-tdem/fwd_tdem_1d.ipynb +++ b/notebooks/08-tdem/fwd_tdem_1d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** In this tutorial, we present the fundamentals of simulating TDEM data in SimPEG. We use the module [simpeg.electromagnetics.time_domain](myst:simpeg#simpeg.electromagnetics.time_domain) to simulate TDEM data for a 1D sounding. The [Simulation1DLayered](myst:simpeg#simpeg.electromagnetics.time_domain.simulation_1d.Simulation1DLayered) class is used to solve the problem via a semi-analytic Hankel transform solution. Note that most of what is learned here can be applied to simulating 3D TDEM data.\n", + "**Summary:** In this tutorial, we present the fundamentals of simulating TDEM data in SimPEG. We use the module [simpeg.electromagnetics.time_domain](xref:simpeg#simpeg.electromagnetics.time_domain) to simulate TDEM data for a 1D sounding. The [Simulation1DLayered](xref:simpeg#simpeg.electromagnetics.time_domain.simulation_1d.Simulation1DLayered) class is used to solve the problem via a semi-analytic Hankel transform solution. Note that most of what is learned here can be applied to simulating 3D TDEM data.\n", "\n", "The tutorial is organized into 3 parts. In **part 1,** we focus on the most fundamental aspects of simulating TDEM data. For a step-off waveform, we simulate TDEM data for a conductive and non-permeable layered Earth. In **part 2,** we demonstrate how to include dispersive electromagnetic properties in the 1D TDEM simulation. And in **part 3,** we demonstrate how data can be simulated for user-specified transmitter waveforms.\n", "\n", @@ -64,8 +64,8 @@ "source": [ "## Importing Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to TDEM is imported from [simpeg.electromagnetics.time_domain](myst:simpeg#simpeg.electromagnetics.time_domain).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils)." + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to TDEM is imported from [simpeg.electromagnetics.time_domain](xref:simpeg#simpeg.electromagnetics.time_domain).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils)." ] }, { @@ -115,12 +115,12 @@ "\n", "TDEM surveys within SimPEG require the user to create and connect four types of objects:\n", "\n", - "- **receivers:** There are a multitude of TDEM receiver classes within SimPEG, each of which is used to simulate data corresponding to a different field measurement; e.g. [PointMagneticField](myst:simpeg#simpeg.electromagnetics.time_domain.receivers.PointMagneticField), [PointMagneticFluxTimeDerivative](myst:simpeg#simpeg.electromagnetics.time_domain.receivers.PointMagneticFluxTimeDerivative) and [PointElectricField](myst:simpeg#simpeg.electromagnetics.time_domain.receivers.PointElectricField). The properties for each TDEM receiver object generally include: the orientation of the field being measured (x, y, z, other), the time channels, the data type, and one or more associated observation locations.\n", - "- **sources:** There are a multitude of TDEM source classes within SimPEG, each of which corresponds to a different geometry; e.g. [MagDipole](myst:simpeg#simpeg.electromagnetics.time_domain.sources.MagDipole) and [LineCurrent](myst:simpeg#simpeg.electromagnetics.time_domain.sources.LineCurrent). Source classes generally require the user to define the current waveform, location and geometry.\n", - "- **waveforms:** The waveform defining the time-dependent current in the source is defined by an object in SimPEG. Some waveform classes include [StepOffWaveform](myst:simpeg#simpeg.electromagnetics.time_domain.sources.StepOffWaveform), [VTEMWaveform](myst:simpeg#simpeg.electromagnetics.time_domain.sources.VTEMWaveform) and [RawWaveform](myst:simpeg#simpeg.electromagnetics.time_domain.sources.RawWaveform)\n", + "- **receivers:** There are a multitude of TDEM receiver classes within SimPEG, each of which is used to simulate data corresponding to a different field measurement; e.g. [PointMagneticField](xref:simpeg#simpeg.electromagnetics.time_domain.receivers.PointMagneticField), [PointMagneticFluxTimeDerivative](xref:simpeg#simpeg.electromagnetics.time_domain.receivers.PointMagneticFluxTimeDerivative) and [PointElectricField](xref:simpeg#simpeg.electromagnetics.time_domain.receivers.PointElectricField). The properties for each TDEM receiver object generally include: the orientation of the field being measured (x, y, z, other), the time channels, the data type, and one or more associated observation locations.\n", + "- **sources:** There are a multitude of TDEM source classes within SimPEG, each of which corresponds to a different geometry; e.g. [MagDipole](xref:simpeg#simpeg.electromagnetics.time_domain.sources.MagDipole) and [LineCurrent](xref:simpeg#simpeg.electromagnetics.time_domain.sources.LineCurrent). Source classes generally require the user to define the current waveform, location and geometry.\n", + "- **waveforms:** The waveform defining the time-dependent current in the source is defined by an object in SimPEG. Some waveform classes include [StepOffWaveform](xref:simpeg#simpeg.electromagnetics.time_domain.sources.StepOffWaveform), [VTEMWaveform](xref:simpeg#simpeg.electromagnetics.time_domain.sources.VTEMWaveform) and [RawWaveform](xref:simpeg#simpeg.electromagnetics.time_domain.sources.RawWaveform)\n", "- **survey:** The object which stores and organizes all of the sources and receivers.\n", "\n", - "For a full list of *source types*, *waveform types* and *receiver types*, please visit API documentation for [simpeg.electromagnetics.time_domain](myst:simpeg#simpeg.electromagnetics.time_domain).\n", + "For a full list of *source types*, *waveform types* and *receiver types*, please visit API documentation for [simpeg.electromagnetics.time_domain](xref:simpeg#simpeg.electromagnetics.time_domain).\n", "\n", "**Topography:** When generating the survey for a 1D forward simulation, sources and receivers **must** be located **above** the Earth's surface. By default, the Earth's surface is at z = 0 m when defining the 1D simulation. So for 1D FDEM problems, it is easiest to define the z-locations of all sources and receivers as flight heights.\n", "\n", @@ -292,13 +292,13 @@ "source": [ "### Models and Mappings for 1D Simulations\n", "\n", - "In SimPEG, the term 'model' is not necessarily synonymous with a set of physical property values. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](myst:numpy#numpy.ndarray) whose lengths are equal to the number of model parameters. For 1D TDEM simulations, we can characterize the Earth's electric properties according to electrical conductivity or electrical resistivity.\n", + "In SimPEG, the term 'model' is not necessarily synonymous with a set of physical property values. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](xref:numpy#numpy.ndarray) whose lengths are equal to the number of model parameters. For 1D TDEM simulations, we can characterize the Earth's electric properties according to electrical conductivity or electrical resistivity.\n", "\n", "Classes within the ``simpeg.maps`` module are used to define the mapping that connects the model to the parameters required to run the 1D TDEM simulation; e.g. layer conductivities/resistivities, magnetic permeabilities and/or layer thicknesses. In this part of the tutorial, we demonstrate 2 types of mappings and models that may be used for 1D TDEM simulation.\n", "\n", - "**1. Conductivity model:** For forward simulation, the easiest approach is to define the model as the layer conductivities and set the layer thicknesses as a static property of the 1D simulation. In this case, the mapping from the model to the conductivities is defined using the [simpeg.maps.IdentityMap](myst:simpeg#simpeg.maps.IdentityMap) class.\n", + "**1. Conductivity model:** For forward simulation, the easiest approach is to define the model as the layer conductivities and set the layer thicknesses as a static property of the 1D simulation. In this case, the mapping from the model to the conductivities is defined using the [simpeg.maps.IdentityMap](xref:simpeg#simpeg.maps.IdentityMap) class.\n", "\n", - "**2. Parametric layered Earth model:** In this case, the model parameters are log-resistivities and layer thicknesses. We therefore need a mapping that extracts log-resistivities from the model and converts them into resistivities, and a mapping that extracts layer thicknesses from the model. For this, we require the [simpeg.maps.Wires](myst:simpeg#simpeg.maps.Wires) mapping and [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) mapping classes. Note that successive mappings can be chained together using the $*$ operator." + "**2. Parametric layered Earth model:** In this case, the model parameters are log-resistivities and layer thicknesses. We therefore need a mapping that extracts log-resistivities from the model and converts them into resistivities, and a mapping that extracts layer thicknesses from the model. For this, we require the [simpeg.maps.Wires](xref:simpeg#simpeg.maps.Wires) mapping and [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) mapping classes. Note that successive mappings can be chained together using the $*$ operator." ] }, { @@ -333,7 +333,7 @@ "source": [ "### Defining the Forward Simulation\n", "\n", - "In SimPEG, the physics of the forward simulation is defined by creating an instance of an appropriate simulation class. Here, we use the [Simulation1DLayered](myst:simpeg#simpeg.electromagnetics.time_domain.Simulation1DLayered) which simulates the data according to a 1D Hankel transform solution. To fully define the forward simulation, we need to connect the simulation object to:\n", + "In SimPEG, the physics of the forward simulation is defined by creating an instance of an appropriate simulation class. Here, we use the [Simulation1DLayered](xref:simpeg#simpeg.electromagnetics.time_domain.Simulation1DLayered) which simulates the data according to a 1D Hankel transform solution. To fully define the forward simulation, we need to connect the simulation object to:\n", "\n", "- the survey\n", "- the layer thicknesses\n", @@ -392,7 +392,7 @@ "source": [ "### Predict 1D TDEM Data\n", "\n", - "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](myst:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the model, the data predicted for the conductivity and parametric models is the same.\n", + "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](xref:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the model, the data predicted for the conductivity and parametric models is the same.\n", "\n", "For surveys consisting of multiple sources, multiple receivers per source and multiple observation locations and time channels per receiver, the predicted data vector is organized:\n", "\n", @@ -765,7 +765,7 @@ "source": [ "## Part 3: Simulation for Different Waveforms\n", "\n", - "In this part of the tutorial, we simulate TDEM data for various transmitter waveforms using a single survey object. As we learned in part 1, each waveform will require the construction of a different source object. For any waveform object, the [eval](myst:simpeg#simpeg.electromagnetics.time_domain.sources.BaseWaveform.eval) method can be used to evaluate the waveform at the time provided." + "In this part of the tutorial, we simulate TDEM data for various transmitter waveforms using a single survey object. As we learned in part 1, each waveform will require the construction of a different source object. For any waveform object, the [eval](xref:simpeg#simpeg.electromagnetics.time_domain.sources.BaseWaveform.eval) method can be used to evaluate the waveform at the time provided." ] }, { diff --git a/notebooks/08-tdem/fwd_tdem_3d.ipynb b/notebooks/08-tdem/fwd_tdem_3d.ipynb index 6d32c1e6..8e53c643 100644 --- a/notebooks/08-tdem/fwd_tdem_3d.ipynb +++ b/notebooks/08-tdem/fwd_tdem_3d.ipynb @@ -39,7 +39,7 @@ "\n", "
\n", "\n", - "**Summary:** In this tutorial, we present the fundamentals of simulating 3D TDEM data in SimPEG. We use the module [simpeg.electromagnetics.time_domain](myst:simpeg#simpeg.electromagnetics.time_domain) to simulate airborne TDEM data on a tree mesh. We assume the reader is already familiar with the fundamental aspects of simulating TDEM data in SimPEG, which were covered in the [Forward Simulation of Time Domain EM Data for a 1D Sounding](fwd_tdem_1d.ipynb) tutorial. This tutorial focusses on the following:\n", + "**Summary:** In this tutorial, we present the fundamentals of simulating 3D TDEM data in SimPEG. We use the module [simpeg.electromagnetics.time_domain](xref:simpeg#simpeg.electromagnetics.time_domain) to simulate airborne TDEM data on a tree mesh. We assume the reader is already familiar with the fundamental aspects of simulating TDEM data in SimPEG, which were covered in the [Forward Simulation of Time Domain EM Data for a 1D Sounding](fwd_tdem_1d.ipynb) tutorial. This tutorial focusses on the following:\n", "\n", "- Defining TDEM surveys for 3D simulations\n", "- How to define an appropriate tree mesh based on problem geometry\n", @@ -55,8 +55,8 @@ "source": [ "## Importing Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to TDEM is imported from [simpeg.electromagnetics.time_domain](myst:simpeg#simpeg.electromagnetics.time_domain). \n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). And to generate the mesh, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to TDEM is imported from [simpeg.electromagnetics.time_domain](xref:simpeg#simpeg.electromagnetics.time_domain). \n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). And to generate the mesh, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, { @@ -98,7 +98,7 @@ "source": [ "## Defining Topography\n", "\n", - "Surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) for 3D simulations.\n", + "Surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) for 3D simulations.\n", "To keep things simple, we create flat topography for the forward simulation.\n", "For user-specific simulations, you may generate less trivial topography or load topography from an XYZ file." ] @@ -182,7 +182,7 @@ "source": [ "## Defining the Survey\n", "\n", - "The fundamentals of constructing TDEM surveys was presented in the [Forward Simulation of Time Domain EM Data for a 1D Sounding](fwd_tdem_1d.ipynb) tutorial. We advise the reader to already be familiar with this material. For a full description of all source and receiver classes, please visit API documentation for [simpeg.electromagnetics.time_domain](myst:simpeg#simpeg.electromagnetics.time_domain)." + "The fundamentals of constructing TDEM surveys was presented in the [Forward Simulation of Time Domain EM Data for a 1D Sounding](fwd_tdem_1d.ipynb) tutorial. We advise the reader to already be familiar with this material. For a full description of all source and receiver classes, please visit API documentation for [simpeg.electromagnetics.time_domain](xref:simpeg#simpeg.electromagnetics.time_domain)." ] }, { @@ -364,7 +364,7 @@ "## Designing a (Tree) Mesh for TDEM\n", "\n", "Meshes are designed using the [discretize](https://discretize.simpeg.xyz/en/main) package. See the [discretize user tutorials](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/index.html) to learn more about creating meshes.\n", - "Here, the forward simulation is computed for a [tree mesh](myst:discretize#discretize.TreeMesh). Because of the modular nature of SimPEG, you could define a [tensor mesh](myst:discretize#discretize.TensorMesh) instead.\n", + "Here, the forward simulation is computed for a [tree mesh](xref:discretize#discretize.TreeMesh). Because of the modular nature of SimPEG, you could define a [tensor mesh](xref:discretize#discretize.TensorMesh) instead.\n", "\n", "### General Approach:\n", "\n", @@ -465,7 +465,7 @@ "source": [ "## Active Cells\n", "\n", - "Simulated geophysical data are dependent on the subsurface distribution of physical property values. As a result, the cells lying below the surface topography are commonly referred to as 'active cells'. And air cells, whose physical property values are fixed, are commonly referred to as 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "Simulated geophysical data are dependent on the subsurface distribution of physical property values. As a result, the cells lying below the surface topography are commonly referred to as 'active cells'. And air cells, whose physical property values are fixed, are commonly referred to as 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -492,10 +492,10 @@ "source": [ "## Models and Mapping from the Model to the Mesh\n", "\n", - "In SimPEG, the term 'model' is not necessarily synonymous with the set of physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](myst:numpy#numpy.ndarray) whose lengths are\n", + "In SimPEG, the term 'model' is not necessarily synonymous with the set of physical property values defined on the mesh. For example, the model may be defined as the logarithms of the physical property values, or be the parameters defining a layered Earth geometry. Models in SimPEG are 1D [numpy.ndarray](xref:numpy#numpy.ndarray) whose lengths are\n", "equal to the number of model parameters.\n", "\n", - "Classes within the [simpeg.maps](myst:simpeg#simpeg.maps.IdentityMap) module are used to define the mapping that connects the model to the physical property values used in the 3D FDEM simulation. Sophisticated mappings can be defined by combining multiple mapping objects. But in the simplest case, the mapping is an identity map and the model consists of the conductivity/resistivity values for all mesh cells (including air). Here, the model consists of the log-conductivity values for all active mesh cells.\n", + "Classes within the [simpeg.maps](xref:simpeg#simpeg.maps.IdentityMap) module are used to define the mapping that connects the model to the physical property values used in the 3D FDEM simulation. Sophisticated mappings can be defined by combining multiple mapping objects. But in the simplest case, the mapping is an identity map and the model consists of the conductivity/resistivity values for all mesh cells (including air). Here, the model consists of the log-conductivity values for all active mesh cells.\n", "\n", "When simulating 3D FDEM data, we have the choice of using resistivity or conductivity to define the Earth's electrical properties. However, one option may be implemented more naturally depending on the formulation used." ] @@ -575,7 +575,7 @@ "source": [ "### Defining the Mapping\n", "\n", - "Here, we use the [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) mapping to convert our model values from log-conductivities to conductivities, and the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) mapping to project active cells to the entire mesh. As we will demonstrate, a single mapping can be constructed from multiple mapping classes using the $*$ operator. **Important:** When defining the active cells mapping, we set all inactive (air) cells to 1e-8 $S/m$ instead of $0$. This is done to ensure that the linear system constructed to solve the PDE for the DC resistivity problem is well-conditioned." + "Here, we use the [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) mapping to convert our model values from log-conductivities to conductivities, and the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) mapping to project active cells to the entire mesh. As we will demonstrate, a single mapping can be constructed from multiple mapping classes using the $*$ operator. **Important:** When defining the active cells mapping, we set all inactive (air) cells to 1e-8 $S/m$ instead of $0$. This is done to ensure that the linear system constructed to solve the PDE for the DC resistivity problem is well-conditioned." ] }, { @@ -602,7 +602,7 @@ "source": [ "### Plotting the discretization and active conductivities\n", "\n", - "To show the geometry of the problem, we plot the discretization near several sources and the active cell conductivities using the [plot_slice](myst:discretize#discretize.TreeMesh.plot_slice) method." + "To show the geometry of the problem, we plot the discretization near several sources and the active cell conductivities using the [plot_slice](xref:discretize#discretize.TreeMesh.plot_slice) method." ] }, { @@ -715,10 +715,10 @@ "\n", "There are a multitude of simulation classes, each of which solves Maxwell's equations in terms of a different field:\n", "\n", - "- [Simulation3DElectricField](myst:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DElectricField), which solves for the electric fields on mesh edges.\n", - "- [Simulation3DMagneticFluxDensity](myst:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DMagneticFluxDensity), which solves for the magnetic flux density on mesh faces.\n", - "- [Simulation3DMagneticField](myst:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DMagneticField), which solves for the magnetic fields on mesh edges.\n", - "- [Simulation3DCurrentDensity](myst:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DCurrentDensity), which solves for the current density on mesh faces.\n", + "- [Simulation3DElectricField](xref:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DElectricField), which solves for the electric fields on mesh edges.\n", + "- [Simulation3DMagneticFluxDensity](xref:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DMagneticFluxDensity), which solves for the magnetic flux density on mesh faces.\n", + "- [Simulation3DMagneticField](xref:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DMagneticField), which solves for the magnetic fields on mesh edges.\n", + "- [Simulation3DCurrentDensity](xref:simpeg#simpeg.electromagnetics.frequency_domain.Simulation3DCurrentDensity), which solves for the current density on mesh faces.\n", "\n", "The optimum choice in simulation class depends on the fields being measured and the class used to define FDEM sources. For example, it may be best to use the electric field formulation when the source is a line-current and electric fields are being measured. And it may be best to use the magnetic field formulation for a magnetic dipole source and magnetic field measurements.\n", "\n", @@ -801,7 +801,7 @@ "source": [ "## Simulating Total Field and Secondary Field Data\n", "\n", - "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](myst:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the models representing the Earth's electrical properties, the data predicted by both simulations is equivalent." + "Once any simulation within SimPEG has been properly constructed, simulated data for a given model vector can be computed using the [dpred](xref:simpeg#simpeg.simulation.BaseSimulation.dpred) method. Note that despite the difference in how we defined the models representing the Earth's electrical properties, the data predicted by both simulations is equivalent." ] }, { diff --git a/notebooks/08-tdem/fwd_tdem_fundamentals.ipynb b/notebooks/08-tdem/fwd_tdem_fundamentals.ipynb index f41e02e3..fb1d86af 100644 --- a/notebooks/08-tdem/fwd_tdem_fundamentals.ipynb +++ b/notebooks/08-tdem/fwd_tdem_fundamentals.ipynb @@ -56,7 +56,7 @@ "\n", "This tutorial does not focus on the syntax for generating and using the SimPEG objects required for TDEM forward simulations. We assume the user has worked through the [1D Forward Simulation for a Single Sounding](fwd_tdem_1d.ipynb) tutorial and is already familiar with generating waveform, source, receiver, survey and simulation objects. Since designing the survey and choosing an appropriate simulation class are problem-dependent, we will cover this in separate tutorials. \n", "\n", - "Here, we introduce guidelines for discretizing TDEM problems in space and in time that can be applied in most cases. We then demonstrate how our choices with regards to discretization impact TDEM forward simulations. To limit the computation time required to run the tutorial, all simulations are performed on a [Cylindrical Mesh](myst:discretize#discretize.CylindricalMesh). However, the knowledge gained here can be applied regardless of the mesh type (e.g. [Tensor Mesh](myst:discretize#discretize.TensorMesh), [Tree Mesh](myst:discretize#discretize.TreeMesh)).\n", + "Here, we introduce guidelines for discretizing TDEM problems in space and in time that can be applied in most cases. We then demonstrate how our choices with regards to discretization impact TDEM forward simulations. To limit the computation time required to run the tutorial, all simulations are performed on a [Cylindrical Mesh](xref:discretize#discretize.CylindricalMesh). However, the knowledge gained here can be applied regardless of the mesh type (e.g. [Tensor Mesh](xref:discretize#discretize.TensorMesh), [Tree Mesh](xref:discretize#discretize.TreeMesh)).\n", "\n", "
\n", "\n", @@ -73,7 +73,7 @@ "source": [ "## Importing Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to TDEM is imported from [simpeg.electromagnetics.time_domain](myst:simpeg#simpeg.electromagnetics.time_domain). We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils)." + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to TDEM is imported from [simpeg.electromagnetics.time_domain](xref:simpeg#simpeg.electromagnetics.time_domain). We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils)." ] }, { @@ -156,7 +156,7 @@ "source": [ "### Generate the Survey\n", "\n", - "For the [waveform object](myst:simpeg#simpeg.electromagnetics.time_domain.sources.BaseWaveform) and field type provided, this function generates the [TDEM survey object](myst:simpeg#simpeg.electromagnetics.time_domain.survey.Survey) for our problem geometry when called." + "For the [waveform object](xref:simpeg#simpeg.electromagnetics.time_domain.sources.BaseWaveform) and field type provided, this function generates the [TDEM survey object](xref:simpeg#simpeg.electromagnetics.time_domain.survey.Survey) for our problem geometry when called." ] }, { @@ -200,7 +200,7 @@ "source": [ "### Generate the Mesh, Model and Mapping\n", "\n", - "For the minimum cell size *dh*, minimum diffusion distance *d_min* and maximum diffusion distance *d_max*, this function generates a [Cylindrical Mesh](myst:discretize#discretize.CylindricalMesh). The extent of the core region is 8 times the smallest diffusion distance. The padding thickness is 2 times the largest diffusion distance and a padding factor of 1.25 is used. For more, visit the [discretize tutorial on cylindrical meshes](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/3_cylindrical_mesh.html)." + "For the minimum cell size *dh*, minimum diffusion distance *d_min* and maximum diffusion distance *d_max*, this function generates a [Cylindrical Mesh](xref:discretize#discretize.CylindricalMesh). The extent of the core region is 8 times the smallest diffusion distance. The padding thickness is 2 times the largest diffusion distance and a padding factor of 1.25 is used. For more, visit the [discretize tutorial on cylindrical meshes](https://discretize.simpeg.xyz/en/main/tutorials/mesh_generation/3_cylindrical_mesh.html)." ] }, { @@ -285,8 +285,8 @@ "\n", "*2) Discretization within the core region:* The core region describes the region containing structures whose responses you wish to simulate. Further away from any controlled source, the fields are smoother and we can use a coarser discretization. But what is the rate at which we can increase the cell widths?\n", "\n", - " * [Cylindrical Meshes](myst:discretize#discretize.CylindricalMesh) and [Tensor Meshes](myst:discretize#discretize.TensorMesh): In this case, the minimum cell size is used throughout the entire core mesh region. Based on the size of the problem, the thickness of this region is some multiple of the minimum diffusion distance for the simulation.\n", - " * [Tree Meshes](myst:discretize#discretize.TreeMesh): In this case, cell size can increase linearly with respect to distance from any controlled source. However it is important not to increase the cell size too quickly. You should have a layer at least 4 cells thick before increasing the cell size again within the core mesh region.\n", + " * [Cylindrical Meshes](xref:discretize#discretize.CylindricalMesh) and [Tensor Meshes](xref:discretize#discretize.TensorMesh): In this case, the minimum cell size is used throughout the entire core mesh region. Based on the size of the problem, the thickness of this region is some multiple of the minimum diffusion distance for the simulation.\n", + " * [Tree Meshes](xref:discretize#discretize.TreeMesh): In this case, cell size can increase linearly with respect to distance from any controlled source. However it is important not to increase the cell size too quickly. You should have a layer at least 4 cells thick before increasing the cell size again within the core mesh region.\n", "\n", "As an additional note, the dimensions of the cells within the core mesh region should **never** exceed an aspect ratio of 2:1. \n", "\n", @@ -298,8 +298,8 @@ "\n", "The padding region between the survey and the edge of the mesh **must** be 2-3 times the largest diffusion distance. Because the fields within this padding region are smooth, we can used a very coarse discretization.\n", "\n", - " * [Cylindrical Meshes](myst:discretize#discretize.CylindricalMesh) and [Tensor Meshes](myst:discretize#discretize.TensorMesh): In this case, the widths of the cells along each direction are increased successively by a constant factor. We advise using a factor that is $\\leq 1.5$.\n", - " * [Tree Meshes](myst:discretize#discretize.TreeMesh): Tree meshes will pad out naturally. So long as the core mesh region extends sufficiently far, you can expect reasonable accuracy at late times." + " * [Cylindrical Meshes](xref:discretize#discretize.CylindricalMesh) and [Tensor Meshes](xref:discretize#discretize.TensorMesh): In this case, the widths of the cells along each direction are increased successively by a constant factor. We advise using a factor that is $\\leq 1.5$.\n", + " * [Tree Meshes](xref:discretize#discretize.TreeMesh): Tree meshes will pad out naturally. So long as the core mesh region extends sufficiently far, you can expect reasonable accuracy at late times." ] }, { @@ -377,7 +377,7 @@ "source": [ "### Define the Waveform\n", "\n", - "Here, we define the [stepoff waveform object](myst:simpeg#simpeg.electromagnetics.time_domain.sources.StepOffWaveform) that is used in the forward simulations. This waveform assumes a constant current of 1 A at time $t \\leq 0$." + "Here, we define the [stepoff waveform object](xref:simpeg#simpeg.electromagnetics.time_domain.sources.StepOffWaveform) that is used in the forward simulations. This waveform assumes a constant current of 1 A at time $t \\leq 0$." ] }, { @@ -486,7 +486,7 @@ "source": [ "### Semi-Analytic 1D Solution\n", "\n", - "Here, the [Simulation1DLayered](myst:simpeg#simpeg.electromagnetics.time_domain.Simulation1DLayered) simulation class is used to simulate the semi-analytic solution for our problem." + "Here, the [Simulation1DLayered](xref:simpeg#simpeg.electromagnetics.time_domain.Simulation1DLayered) simulation class is used to simulate the semi-analytic solution for our problem." ] }, { @@ -851,8 +851,8 @@ "\n", "Here, we define the waveforms that will be used to simulate data in this part of the tutorial. They are a:\n", "\n", - "* [triangular waveform](myst:simpeg#simpeg.electromagnetics.time_domain.sources.TriangularWaveform) with a peak current amplitude at -0.0005 s.\n", - "* [trapezoidal waveform](myst:simpeg#simpeg.electromagnetics.time_domain.sources.TrapezoidalWaveform) with a linear ramp-on and a linear ramp-off that each lasts 2.5e-5 s." + "* [triangular waveform](xref:simpeg#simpeg.electromagnetics.time_domain.sources.TriangularWaveform) with a peak current amplitude at -0.0005 s.\n", + "* [trapezoidal waveform](xref:simpeg#simpeg.electromagnetics.time_domain.sources.TrapezoidWaveform) with a linear ramp-on and a linear ramp-off that each lasts 2.5e-5 s." ] }, { diff --git a/notebooks/08-tdem/fwd_utem_3d.ipynb b/notebooks/08-tdem/fwd_utem_3d.ipynb index aceaae7a..06ea741b 100644 --- a/notebooks/08-tdem/fwd_utem_3d.ipynb +++ b/notebooks/08-tdem/fwd_utem_3d.ipynb @@ -50,7 +50,7 @@ "\n", "
\n", "\n", - "**Summary:** In this tutorial, we present the fundamentals of simulating on-time large-loop TDEM data in 3D for a user-defined waveform. In this case, the data are simulated for a UTEM system. Please work through any prerequisite tutorials before working through this one. Functionality used to simulate the data is imported from the [simpeg.electromagnetics.time_domain](myst:simpeg#simpeg.electromagnetics.time_domain) module.\n", + "**Summary:** In this tutorial, we present the fundamentals of simulating on-time large-loop TDEM data in 3D for a user-defined waveform. In this case, the data are simulated for a UTEM system. Please work through any prerequisite tutorials before working through this one. Functionality used to simulate the data is imported from the [simpeg.electromagnetics.time_domain](xref:simpeg#simpeg.electromagnetics.time_domain) module.\n", "\n", "
\n", "\n", @@ -68,8 +68,8 @@ "source": [ "## Importing Modules\n", "\n", - "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to TDEM is imported from [simpeg.electromagnetics.time_domain](myst:simpeg#simpeg.electromagnetics.time_domain).\n", - "We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils)." + "Here, we import all of the functionality required to run the notebook for the tutorial exercise. All of the functionality specific to TDEM is imported from [simpeg.electromagnetics.time_domain](xref:simpeg#simpeg.electromagnetics.time_domain).\n", + "We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils)." ] }, { @@ -115,7 +115,7 @@ "source": [ "## Define the Topography\n", "\n", - "Surface topography is defined as an (N, 3) [numpy.ndarray](myst:numpy#numpy.ndarray) for 3D simulations.\n", + "Surface topography is defined as an (N, 3) [numpy.ndarray](xref:numpy#numpy.ndarray) for 3D simulations.\n", "Here, we create basic topography for the forward simulation. For user-specific simulations, you may load topography from an XYZ file." ] }, @@ -209,7 +209,7 @@ "* waveforms\n", "* sources\n", "\n", - "to a survey object. Unlike in the 1D simulation, sources and receivers can be located either above or below the Earth's surface. For a full list of *source types*, *waveform types* and *receiver types*, please visit API documentation for [simpeg.electromagnetics.time_domain](myst:simpeg#simpeg.electromagnetics.time_domain).\n", + "to a survey object. Unlike in the 1D simulation, sources and receivers can be located either above or below the Earth's surface. For a full list of *source types*, *waveform types* and *receiver types*, please visit API documentation for [simpeg.electromagnetics.time_domain](xref:simpeg#simpeg.electromagnetics.time_domain).\n", "\n", "**For this tutorial**, we simulate University of Toronto electromagnetic (UTEM) data for a single transmitter loop. Some basic information regarding UTEM survey geometry and its data can be found [here](https://giftoolscookbook.readthedocs.io/en/latest/content/comprehensive_workflow/utem/1_basic_anomalies.html). The transmitter loop is square with a side length of 1400 m. And the period of the waveform is 1 s. db/dt sensors located within the loop are used to measure 3-component data for a highly-regulated triangular waveform with a 100% duty cycle." ] @@ -250,9 +250,9 @@ "source": [ "### Defining the Waveform\n", "\n", - "A waveform object must the must be assigned to every TDEM source object in the survey. The waveform object defines time-dependent current in the source. The same waveform object can be assigned to multiple source objects if they all use the same waveform. However in practice, surveys that collect data for multiple loops simultaneously will use waveforms with different operating frequencies. Scroll down to the *Waveforms* section of the [simpeg.electromagnetics.static.time_domain](myst:simpeg#simpeg.electromagnetics.time_domain) module to see the different waveforms that can be defined within SimPEG. \n", + "A waveform object must the must be assigned to every TDEM source object in the survey. The waveform object defines time-dependent current in the source. The same waveform object can be assigned to multiple source objects if they all use the same waveform. However in practice, surveys that collect data for multiple loops simultaneously will use waveforms with different operating frequencies. Scroll down to the *Waveforms* section of the [simpeg.electromagnetics.static.time_domain](xref:simpeg#simpeg.electromagnetics.time_domain) module to see the different waveforms that can be defined within SimPEG. \n", "\n", - "Here, we use the [BaseWaveform](myst:simpeg#simpeg.electromagnetics.time_domain.sources.RawWaveform) class to define a custom waveform. Instatiation of this class requires we define a function handle that returns the current at any time between the initial time for the simulation $t_0$ and the latest time channel $t_{max}$. Because the waveform uses a 100\\% duty cycle, the off-time for the waveform is set after the latest time channel." + "Here, we use the [BaseWaveform](xref:simpeg#simpeg.electromagnetics.time_domain.sources.RawWaveform) class to define a custom waveform. Instatiation of this class requires we define a function handle that returns the current at any time between the initial time for the simulation $t_0$ and the latest time channel $t_{max}$. Because the waveform uses a 100\\% duty cycle, the off-time for the waveform is set after the latest time channel." ] }, { @@ -426,7 +426,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "For each source, we define the associated receivers list. Separate receivers must be defined for each orientation, however multiple times and locations can be defined within a single receiver object. Both the receivers and waveform are assigned to the source object. The list of sources is then used to define the survey object. We use the [MagneticFluxTimeDerivative](myst:simpeg#simpeg.electromagnetics.time_domain.receivers.MagneticFluxTimeDerivative) class to measure 3-component dB/dt data for a triangular waveform. And we use the [LineCurrent](myst:simpeg#simpeg.electromagnetics.time_domain.sources.LineCurrent) to define our wire path." + "For each source, we define the associated receivers list. Separate receivers must be defined for each orientation, however multiple times and locations can be defined within a single receiver object. Both the receivers and waveform are assigned to the source object. The list of sources is then used to define the survey object. We use the [PointMagneticFluxTimeDerivative](xref:simpeg#simpeg.electromagnetics.time_domain.receivers.PointMagneticFluxTimeDerivative) class to measure 3-component dB/dt data for a triangular waveform. And we use the [LineCurrent](xref:simpeg#simpeg.electromagnetics.time_domain.sources.LineCurrent) to define our wire path." ] }, { @@ -601,7 +601,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here, we use the [refine_points](myst:discretize#discretize.TreeMesh.refine_points) method to discretize along the wire path. In our case, the source loop's path has been sufficiently sampled. **However** if the lengths of individual wire segments are too long relative to the minimum cell size and level of discretization, we may not discrete sufficient along certain portions of the wire.\n", + "Here, we use the [refine_points](xref:discretize#discretize.TreeMesh.refine_points) method to discretize along the wire path. In our case, the source loop's path has been sufficiently sampled. **However** if the lengths of individual wire segments are too long relative to the minimum cell size and level of discretization, we may not discrete sufficient along certain portions of the wire.\n", "\n", "In cases where the host is more conductive, we may want to pad out from the loop more gradually, as we would expect significant EM induction near the wire at our observation times. In this case, the host is quite resistive and the induced currents in the host are far away from the wire by our first time channel." ] @@ -643,7 +643,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here, we use the [refine_bounding_box](myst:discretize#discretize.TreeMesh.refine_bounding_box) method to define the discretization in the region our slab lives." + "Here, we use the [refine_bounding_box](xref:discretize#discretize.TreeMesh.refine_bounding_box) method to define the discretization in the region our slab lives." ] }, { @@ -670,7 +670,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Using the [refine_surface](myst:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. We do this to a sufficient distance from the survey in order to avoid a large number of unnecessary fine cells in the padding." + "Using the [refine_surface](xref:discretize#discretize.TreeMesh.refine_surface) method, we refine the tree mesh where there is significant topography. We do this to a sufficient distance from the survey in order to avoid a large number of unnecessary fine cells in the padding." ] }, { @@ -716,7 +716,7 @@ "## Define the Active Cells\n", "\n", "Whereas cells below the Earth's surface contribute towards the simulated magnetic anomaly, air cells do not. \n", - "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](myst:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." + "The set of mesh cells used in the forward simulation are referred to as 'active cells'. Unused cells (air cells) are 'inactive cells'. Here, the discretize [active_from_xyz](xref:discretize#discretize.utils.active_from_xyz) utility function is used to find the indices of the active cells using the mesh and surface topography. The output quantity is a ``bool`` array." ] }, { @@ -936,7 +936,7 @@ "source": [ "### Mapping from the Model to the Mesh\n", "\n", - "Here, we use the [simpeg.maps.InjectActiveCells](myst:simpeg#simpeg.maps.InjectActiveCells) mapping. This mapping projects quantities defined on the active cells to the entire mesh, and sets a constant value for all inactive cells. **Important:** we set all inactive (air) cells to 1e-8 S/m instead of 0. This is done to ensure that the linear system constructed to solve the PDE for the TDEM problem is well-conditioned. If working with resistivity, we would set all inactive (air) cells to 1e8 $\\Omega m$ instead of $\\infty$." + "Here, we use the [simpeg.maps.InjectActiveCells](xref:simpeg#simpeg.maps.InjectActiveCells) mapping. This mapping projects quantities defined on the active cells to the entire mesh, and sets a constant value for all inactive cells. **Important:** we set all inactive (air) cells to 1e-8 S/m instead of 0. This is done to ensure that the linear system constructed to solve the PDE for the TDEM problem is well-conditioned. If working with resistivity, we would set all inactive (air) cells to 1e8 $\\Omega m$ instead of $\\infty$." ] }, { @@ -1070,7 +1070,7 @@ "* our source is a line current, and\n", "* our receivers are measuring the time-derivative of the magnetic flux density\n", "\n", - "As a result, the [Simulation3DElectricField](myst:simpeg#simpeg.electromagnetics.time_domain.simulation.Simulation3DElectricField) class is best-suited for the forward simulation. This is because line current sources are naturally discretized to mesh edges, and db/dt can be easily obtained from the electric field solution. For different source and receiver types, another simulation class may be better suited." + "As a result, the [Simulation3DElectricField](xref:simpeg#simpeg.electromagnetics.time_domain.simulation.Simulation3DElectricField) class is best-suited for the forward simulation. This is because line current sources are naturally discretized to mesh edges, and db/dt can be easily obtained from the electric field solution. For different source and receiver types, another simulation class may be better suited." ] }, { @@ -1116,7 +1116,7 @@ "source": [ "## Predict Data\n", "\n", - "Like any other simulation object within SimPEG, we use the [dpred](myst:simpeg#simpeg.simulation.BaseSimulation.dpred) method to predict data for the model provided." + "Like any other simulation object within SimPEG, we use the [dpred](xref:simpeg#simpeg.simulation.BaseSimulation.dpred) method to predict data for the model provided." ] }, { diff --git a/notebooks/08-tdem/inv_tdem_1d.ipynb b/notebooks/08-tdem/inv_tdem_1d.ipynb index 29505c2f..511eb0dd 100644 --- a/notebooks/08-tdem/inv_tdem_1d.ipynb +++ b/notebooks/08-tdem/inv_tdem_1d.ipynb @@ -63,7 +63,7 @@ "## Importing Modules\n", "\n", "Here, we import all of the functionality required to run the notebook for the tutorial exercise.\n", - "All of the functionality specific to the forward simulation of 1D time domain EM data are imported from the [simpeg.electromagnetics.time_domain](myst:simpeg#simpeg.electromagnetics.time_domain) module. Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](myst:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." + "All of the functionality specific to the forward simulation of 1D time domain EM data are imported from the [simpeg.electromagnetics.time_domain](xref:simpeg#simpeg.electromagnetics.time_domain) module. Classes required to define the data misfit, regularization, optimization, etc... are imported from elsewhere within SimPEG. We also import some useful utility functions from [simpeg.utils](xref:simpeg#simpeg.utils). To generate the mesh used for the inversion, we use the [discretize](https://discretize.simpeg.xyz/en/main) package." ] }, { @@ -333,7 +333,7 @@ "source": [ "## Defining the Data\n", "\n", - "The SimPEG [Data](myst:simpeg#simpeg.data.Data) class is required for inversion and connects the observed data, uncertainties and survey geometry." + "The SimPEG [Data](xref:simpeg#simpeg.data.Data) class is required for inversion and connects the observed data, uncertainties and survey geometry." ] }, { @@ -464,7 +464,7 @@ "\n", "Recall from the [1D Forward Simulation of Time-Domain EM Data for a Single Sounding](fwd_tdem_1d.ipynb) tutorial that the 'model' is not necessarily synonymous with physical property values. And that we need to define a mapping from the model to the set of input parameters required by the forward simulation. When inverting to recover electrical conductivities (or resistivities), it is best to use the log-value, as electrical conductivities of rocks span many order of magnitude.\n", "\n", - "Here, the model defines the log-conductivity values for a defined set of subsurface layers. And we use the [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) to map from the model parameters to the conductivity values required by the forward simulation." + "Here, the model defines the log-conductivity values for a defined set of subsurface layers. And we use the [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) to map from the model parameters to the conductivity values required by the forward simulation." ] }, { @@ -522,7 +522,7 @@ "source": [ "### Define the Forward Simulation\n", "\n", - "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 1D DC resistivity was discussed in the [1D Forward Simulation of Time-Domain EM Data for a Single Sounding](fwd_tdem_1d.ipynb) tutorial. Here, we use the [Simulation1DLayers](myst:simpeg#simpeg.electromagnetics.time_domain.Simulation1DLayers) which simulates the data according to a 1D Hankel transform solution.\n", + "A simulation object defining the forward problem is required in order to predict data and calculate misfits for recovered models. A comprehensive description of the simulation object for 1D DC resistivity was discussed in the [1D Forward Simulation of Time-Domain EM Data for a Single Sounding](fwd_tdem_1d.ipynb) tutorial. Here, we use the [Simulation1DLayered](xref:simpeg#simpeg.electromagnetics.time_domain.Simulation1DLayered) which simulates the data according to a 1D Hankel transform solution.\n", "\n", "The layer thicknesses are a static property of the simulation, and we set them using the ``thicknessess`` keyword argument. Since our model consists of log-conductivities, we use ``sigmaMap`` to set the mapping from the model to the layer conductivities." ] @@ -552,7 +552,7 @@ "### Data Misfit\n", "\n", "To understand the role of the data misfit in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/Uncertainties.html).\n", - "Here, we use the [L2DataMisfit](myst:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." + "Here, we use the [L2DataMisfit](xref:simpeg#simpeg.data_misfit.L2DataMisfit) class to define the data misfit. In this case, the data misfit is the L2 norm of the weighted residual between the observed data and the data predicted for a given model. When instantiating the data misfit object within SimPEG, we must assign an appropriate *data object* and *simulation object* as properties." ] }, { @@ -579,7 +579,7 @@ "\n", "To understand the role of the regularization in the inversion, please visit [this online resource](https://giftoolscookbook.readthedocs.io/en/latest/content/fundamentals/ObjectiveFunction.html). \n", "\n", - "To define the regularization within SimPEG, we must define a 1D [tensor mesh](myst:discretize#discretize.TensorMesh). Meshes are designed using the [discretize package](https://discretize.simpeg.xyz). Whereas layer *thicknesses* and our *model* are defined from our top-layer down, tensor meshes are defined from the bottom up. So to define a 1D tensor mesh for the regularization, we:\n", + "To define the regularization within SimPEG, we must define a 1D [tensor mesh](xref:discretize#discretize.TensorMesh). Meshes are designed using the [discretize package](https://discretize.simpeg.xyz). Whereas layer *thicknesses* and our *model* are defined from our top-layer down, tensor meshes are defined from the bottom up. So to define a 1D tensor mesh for the regularization, we:\n", "\n", "- add an extra layer to the end of our thicknesses so that the number of cells in the 1D mesh equals the number of model parameters\n", "- reverse the order so that the model parameters in the regularization match up with the appropriate cell\n", @@ -628,7 +628,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "By default, the regularization acts on the model parameters. In this case, the model parameters are the log-resistivities, not the electric resistivities!!! Here, we use the [WeightedLeastSquares](myst:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Here, length scale along x are used to balance the smallness and smoothness terms; yes, x is smoothness along the vertical direction. And the reference model is only applied to the smallness term. If we wanted to apply the regularization to a function of the model parameters, we would need to set an approprate mapping object using the ``mapping`` keyword argument." + "By default, the regularization acts on the model parameters. In this case, the model parameters are the log-resistivities, not the electric resistivities!!! Here, we use the [WeightedLeastSquares](xref:simpeg#simpeg.regularization.WeightedLeastSquares) regularization class to constrain the inversion result. Here, length scale along x are used to balance the smallness and smoothness terms; yes, x is smoothness along the vertical direction. And the reference model is only applied to the smallness term. If we wanted to apply the regularization to a function of the model parameters, we would need to set an approprate mapping object using the ``mapping`` keyword argument." ] }, { @@ -658,7 +658,7 @@ "source": [ "### Optimization\n", "\n", - "Here, we use the [InexactGaussNewton](myst:simpeg#simpeg.optimization.InexactGaussNewton) class to solve the optimization problem using the inexact Gauss Newton with conjugate gradient solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches." + "Here, we use the [InexactGaussNewton](xref:simpeg#simpeg.optimization.InexactGaussNewton) class to solve the optimization problem using the inexact Gauss Newton with conjugate gradient solver. Reasonable default values have generally been set for the properties of each optimization class. However, the user may choose to set custom values; e.g. the accuracy tolerance for the conjugate gradient solver or the number of line searches." ] }, { @@ -685,7 +685,7 @@ "source": [ "### Inverse Problem\n", "\n", - "We use the [BaseInvProblem](myst:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." + "We use the [BaseInvProblem](xref:simpeg#simpeg.inverse_problem.BaseInvProblem) class to fully define the inverse problem that is solved at each beta (trade-off parameter) iteration. The inverse problem requires appropriate *data misfit*, *regularization* and *optimization* objects." ] }, { @@ -712,13 +712,13 @@ "\n", "To understand the role of directives in the inversion, please visit this online resource. Here, we apply common directives for weighted least-squares inversion of gravity data and describe their roles. These are:\n", "\n", - "- [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=True` because the ideal preconditioner is model-dependent.\n", + "- [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner): Apply Jacobi preconditioner when solving optimization problem to reduce the number of conjugate gradient iterations. We set `update_every_iteration=True` because the ideal preconditioner is model-dependent.\n", "\n", - "- [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", + "- [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig): Compute and set starting trade-off parameter (beta) based on largest eigenvalues.\n", "\n", - "- [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 3 works well for TDEM inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", + "- [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule): Size reduction of the trade-off parameter at every beta iteration, and the number of Gauss-Newton iterations for each beta. In general, a `coolingFactor` between 1.5 and 2.5, and `coolingRate` of 3 works well for TDEM inversion. Cooling beta too quickly will result in portions of the model getting trapped in local minima. And we will not be finding the solution that minimizes the optimization problem if the cooling rate is too small.\n", "\n", - "- [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", + "- [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit): Terminates the inversion when the data misfit equals the target misfit. A `chifact=1` terminates the inversion when the data misfit equals the number of data.\n", "\n", "\n", "The directive objects are organized in a ``list``. Upon starting the inversion or updating the recovered model at each iteration, the inversion will call each directive within the list **in order**. The order of the directives matters, and SimPEG will throw an error if directives are organized into an improper order. Some directives, like the ``BetaEstimate_ByEig`` are only used when starting the inversion. Other directives, like ``UpdatePreconditionner``, are used whenever the model is updated." @@ -751,7 +751,7 @@ "source": [ "### Define and Run the Inversion\n", "\n", - "We define the inversion using the [BaseInversion](myst:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" + "We define the inversion using the [BaseInversion](xref:simpeg#simpeg.inversion.BaseInversion) class. The inversion class must be instantiated with an appropriate *inverse problem* object and *directives list*. The ``run`` method, along with a starting model, is respondible for running the inversion. The output is a 1D numpy.ndarray containing the recovered model parameters" ] }, { @@ -1102,7 +1102,7 @@ "source": [ "### Regularization\n", "\n", - "Here, we use the [Sparse](myst:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Here, the scaling constants that balance the smallness and smoothness terms are set directly. Equal emphasis on smallness and smoothness is generally applied by using the inverse square of the smallest cell dimension. The reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros. Here, we apply a 1-norm to the smallness term and a 1-norm to first-order smoothness along the x (vertical direction)." + "Here, we use the [Sparse](xref:simpeg#simpeg.regularization.Sparse) regularization class to constrain the inversion result using an IRLS approach. Here, the scaling constants that balance the smallness and smoothness terms are set directly. Equal emphasis on smallness and smoothness is generally applied by using the inverse square of the smallest cell dimension. The reference model is only applied to the smallness term; which is redundant for the tutorial example since we have set the reference model to an array of zeros. Here, we apply a 1-norm to the smallness term and a 1-norm to first-order smoothness along the x (vertical direction)." ] }, { @@ -1181,9 +1181,9 @@ "source": [ "### Directives\n", "\n", - "Here, we create common directives for IRLS inversion of total magnetic intensity data and describe their roles. In additon to the [UpdateSensitivityWeights](myst:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](myst:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](myst:simpeg#simpeg.directives.BetaEstimate_ByEig) (described before), inversion with sparse-norms requires the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive.\n", + "Here, we create common directives for IRLS inversion of total magnetic intensity data and describe their roles. In additon to the [UpdateSensitivityWeights](xref:simpeg#simpeg.directives.UpdateSensitivityWeights), [UpdatePreconditioner](xref:simpeg#simpeg.directives.UpdatePreconditioner) and [BetaEstimate_ByEig](xref:simpeg#simpeg.directives.BetaEstimate_ByEig) (described before), inversion with sparse-norms requires the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive.\n", "\n", - "You will notice that we don't use the [BetaSchedule](myst:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](myst:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](myst:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property." + "You will notice that we don't use the [BetaSchedule](xref:simpeg#simpeg.directives.BetaSchedule) and [TargetMisfit](xref:simpeg#simpeg.directives.TargetMisfit) directives. Here, the beta cooling schedule is set in the [Update_IRLS](xref:simpeg#simpeg.directives.Update_IRLS) directive using the `coolingFactor` and `coolingRate` properties. The target misfit for the L2 portion of the IRLS approach is set with the `chifact_start` property." ] }, { @@ -1722,7 +1722,7 @@ "source": [ "### Model and Mapping\n", "\n", - "For a 3-layered Earth model, the model consists of 2 log-thicknesses and 3 log-conductivities. Similar to the [1D Forward Simulation of Time Domain EM Data for a Single Sounding](fwd_tdem_1d.ipynb) tutorial, need a mapping that extract log-thicknesses and log-resistivities from the model, and mappings that convert log-values to property values. For this, we require the [simpeg.maps.Wires](myst:simpeg#simpeg.maps.Wires) mapping and [simpeg.maps.ExpMap](myst:simpeg#simpeg.maps.ExpMap) mapping classes. Note that successive mappings can be chained together using the $*$ operator." + "For a 3-layered Earth model, the model consists of 2 log-thicknesses and 3 log-conductivities. Similar to the [1D Forward Simulation of Time Domain EM Data for a Single Sounding](fwd_tdem_1d.ipynb) tutorial, need a mapping that extract log-thicknesses and log-resistivities from the model, and mappings that convert log-values to property values. For this, we require the [simpeg.maps.Wires](xref:simpeg#simpeg.maps.Wires) mapping and [simpeg.maps.ExpMap](xref:simpeg#simpeg.maps.ExpMap) mapping classes. Note that successive mappings can be chained together using the $*$ operator." ] }, { @@ -1835,9 +1835,9 @@ "source": [ "### (Combo) Regularization\n", "\n", - "We need to define a regularization for each model parameter type. In this case, we have log-thicknesses and log-conductivities. For each model parameter type, we create a 1D [tensor mesh](myst:discretize#discretize.TensorMesh) with length equal to the number of parameters. In the ``mapping`` keyword argument, we used the wire map that extracts the specific model parameters from the model.\n", + "We need to define a regularization for each model parameter type. In this case, we have log-thicknesses and log-conductivities. For each model parameter type, we create a 1D [tensor mesh](xref:discretize#discretize.TensorMesh) with length equal to the number of parameters. In the ``mapping`` keyword argument, we used the wire map that extracts the specific model parameters from the model.\n", "\n", - "Using the $*$ operator, separate regularizations can be summed to form a regularization that is also a [ComboObjectiveFunction](myst:simpeg#simpeg.objective_function.ComboObjectiveFunction). By setting the ``multipliers`` property, we can emphasize the relative contributions of the log-thicknesses and log-conductivities regularizations." + "Using the $*$ operator, separate regularizations can be summed to form a regularization that is also a [ComboObjectiveFunction](xref:simpeg#simpeg.objective_function.ComboObjectiveFunction). By setting the ``multipliers`` property, we can emphasize the relative contributions of the log-thicknesses and log-conductivities regularizations." ] }, {