.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "content/user-guide/examples/05-fdem/plot_inv_fdem_loop_loop_2Dinversion.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_content_user-guide_examples_05-fdem_plot_inv_fdem_loop_loop_2Dinversion.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_content_user-guide_examples_05-fdem_plot_inv_fdem_loop_loop_2Dinversion.py:


2D inversion of Loop-Loop EM Data
=================================

In this example, we consider a single line of loop-loop EM data
at 30kHz with 3 different coil separations [0.32m, 0.71m, 1.18m].
We will use only Horizontal co-planar orientations (vertical magnetic dipole),
and look at the real and imaginary parts of the secondary magnetic field.

We use the :class:`simpeg.maps.Surject2Dto3D` mapping to invert for a 2D model
and perform the forward modelling in 3D.

.. GENERATED FROM PYTHON SOURCE LINES 14-33

.. code-block:: Python


    import numpy as np
    import matplotlib.pyplot as plt
    import time


    import discretize
    from simpeg import (
        maps,
        optimization,
        data_misfit,
        regularization,
        inverse_problem,
        inversion,
        directives,
        Report,
    )
    from simpeg.electromagnetics import frequency_domain as FDEM








.. GENERATED FROM PYTHON SOURCE LINES 34-39

Setup
-----

Define the survey and model parameters


.. GENERATED FROM PYTHON SOURCE LINES 39-50

.. code-block:: Python


    sigma_surface = 10e-3
    sigma_deep = 40e-3
    sigma_air = 1e-8

    coil_separations = [0.32, 0.71, 1.18]
    freq = 30e3

    print("skin_depth: {:1.2f}m".format(500 / np.sqrt(sigma_deep * freq)))






.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    skin_depth: 14.43m




.. GENERATED FROM PYTHON SOURCE LINES 51-53

Define a dipping interface between the surface layer and the deeper layer


.. GENERATED FROM PYTHON SOURCE LINES 54-76

.. code-block:: Python


    z_interface_shallow = -0.25
    z_interface_deep = -1.5
    x_dip = np.r_[0.0, 8.0]


    def interface(x):
        interface = np.zeros_like(x)

        interface[x < x_dip[0]] = z_interface_shallow

        dipping_unit = (x >= x_dip[0]) & (x <= x_dip[1])
        x_dipping = (-(z_interface_shallow - z_interface_deep) / x_dip[1]) * (
            x[dipping_unit]
        ) + z_interface_shallow
        interface[dipping_unit] = x_dipping

        interface[x > x_dip[1]] = z_interface_deep

        return interface









.. GENERATED FROM PYTHON SOURCE LINES 77-87

Forward Modelling Mesh
----------------------

Here, we set up a 3D tensor mesh which we will perform the forward
simulations on.

.. note::

  In practice, a smaller horizontal discretization should be used to improve
  accuracy, particularly for the shortest offset (eg. you can try 0.25m).

.. GENERATED FROM PYTHON SOURCE LINES 87-119

.. code-block:: Python


    csx = 0.5  # cell size for the horizontal direction
    csz = 0.125  # cell size for the vertical direction
    pf = 1.3  # expansion factor for the padding cells

    npadx = 7  # number of padding cells in the x-direction
    npady = 7  # number of padding cells in the y-direction
    npadz = 11  # number of padding cells in the z-direction

    core_domain_x = np.r_[-11.5, 11.5]  # extent of uniform cells in the x-direction
    core_domain_z = np.r_[-2.0, 0.0]  # extent of uniform cells in the z-direction

    # number of cells in the core region
    ncx = int(np.diff(core_domain_x) / csx)
    ncz = int(np.diff(core_domain_z) / csz)

    # create a 3D tensor mesh
    mesh = discretize.TensorMesh(
        [
            [(csx, npadx, -pf), (csx, ncx), (csx, npadx, pf)],
            [(csx, npady, -pf), (csx, 1), (csx, npady, pf)],
            [(csz, npadz, -pf), (csz, ncz), (csz, npadz, pf)],
        ]
    )
    # set the origin
    mesh.x0 = np.r_[
        -mesh.h[0].sum() / 2.0, -mesh.h[1].sum() / 2.0, -mesh.h[2][: npadz + ncz].sum()
    ]

    print("the mesh has {} cells".format(mesh.nC))
    mesh.plot_grid()




.. image-sg:: /content/user-guide/examples/05-fdem/images/sphx_glr_plot_inv_fdem_loop_loop_2Dinversion_001.png
   :alt: plot inv fdem loop loop 2Dinversion
   :srcset: /content/user-guide/examples/05-fdem/images/sphx_glr_plot_inv_fdem_loop_loop_2Dinversion_001.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    /home/vsts/work/1/s/examples/05-fdem/plot_inv_fdem_loop_loop_2Dinversion.py:100: DeprecationWarning:

    Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)

    /home/vsts/work/1/s/examples/05-fdem/plot_inv_fdem_loop_loop_2Dinversion.py:101: DeprecationWarning:

    Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)

    the mesh has 34200 cells

    <Axes3D: xlabel='x1', ylabel='x2', zlabel='x3'>



.. GENERATED FROM PYTHON SOURCE LINES 120-125

Inversion Mesh
--------------

Here, we set up a 2D tensor mesh which we will represent the inversion model
on

.. GENERATED FROM PYTHON SOURCE LINES 125-130

.. code-block:: Python


    inversion_mesh = discretize.TensorMesh([mesh.h[0], mesh.h[2][mesh.cell_centers_z <= 0]])
    inversion_mesh.x0 = [-inversion_mesh.h[0].sum() / 2.0, -inversion_mesh.h[1].sum()]
    inversion_mesh.plot_grid()




.. image-sg:: /content/user-guide/examples/05-fdem/images/sphx_glr_plot_inv_fdem_loop_loop_2Dinversion_002.png
   :alt: plot inv fdem loop loop 2Dinversion
   :srcset: /content/user-guide/examples/05-fdem/images/sphx_glr_plot_inv_fdem_loop_loop_2Dinversion_002.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <Axes: xlabel='x1', ylabel='x2'>



.. GENERATED FROM PYTHON SOURCE LINES 131-137

Mappings
---------

Mappings are used to take the inversion model and represent it as electrical
conductivity on the inversion mesh. We will invert for log-conductivity below
the surface, fixing the conductivity of the air cells to 1e-8 S/m

.. GENERATED FROM PYTHON SOURCE LINES 137-153

.. code-block:: Python


    # create a 2D mesh that includes air cells
    mesh2D = discretize.TensorMesh([mesh.h[0], mesh.h[2]], x0=mesh.x0[[0, 2]])
    active_inds = mesh2D.gridCC[:, 1] < 0  # active indices are below the surface


    mapping = (
        maps.Surject2Dto3D(mesh)
        * maps.InjectActiveCells(  # populates 3D space from a 2D model
            mesh2D, active_inds, sigma_air
        )
        * maps.ExpMap(  # adds air cells
            nP=inversion_mesh.nC
        )  # takes the exponential (log(sigma) --> sigma)
    )








.. GENERATED FROM PYTHON SOURCE LINES 154-158

True Model
----------

Create our true model which we will use to generate synthetic data for

.. GENERATED FROM PYTHON SOURCE LINES 158-170

.. code-block:: Python


    m_true = np.log(sigma_deep) * np.ones(inversion_mesh.nC)
    interface_depth = interface(inversion_mesh.gridCC[:, 0])
    m_true[inversion_mesh.gridCC[:, 1] > interface_depth] = np.log(sigma_surface)

    fig, ax = plt.subplots(1, 1)
    cb = plt.colorbar(inversion_mesh.plot_image(m_true, ax=ax, grid=True)[0], ax=ax)
    cb.set_label(r"$\log(\sigma)$")
    ax.set_title("true model")
    ax.set_xlim([-10, 10])
    ax.set_ylim([-2, 0])




.. image-sg:: /content/user-guide/examples/05-fdem/images/sphx_glr_plot_inv_fdem_loop_loop_2Dinversion_003.png
   :alt: true model
   :srcset: /content/user-guide/examples/05-fdem/images/sphx_glr_plot_inv_fdem_loop_loop_2Dinversion_003.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    (-2.0, 0.0)



.. GENERATED FROM PYTHON SOURCE LINES 171-175

Survey
------

Create our true model which we will use to generate synthetic data for

.. GENERATED FROM PYTHON SOURCE LINES 175-209

.. code-block:: Python


    src_locations = np.arange(-11, 11, 0.5)
    src_z = 0.25  # src is 0.25m above the surface
    orientation = "z"  # z-oriented dipole for horizontal co-planar loops

    # reciever offset in 3D space
    rx_offsets = np.vstack([np.r_[sep, 0.0, 0.0] for sep in coil_separations])

    # create our source list - one source per location
    source_list = []
    for x in src_locations:
        src_loc = np.r_[x, 0.0, src_z]
        rx_locs = src_loc - rx_offsets

        rx_real = FDEM.Rx.PointMagneticFluxDensitySecondary(
            locations=rx_locs, orientation=orientation, component="real"
        )
        rx_imag = FDEM.Rx.PointMagneticFluxDensitySecondary(
            locations=rx_locs, orientation=orientation, component="imag"
        )

        src = FDEM.Src.MagDipole(
            receiver_list=[rx_real, rx_imag],
            location=src_loc,
            orientation=orientation,
            frequency=freq,
        )

        source_list.append(src)

    # create the survey and problem objects for running the forward simulation
    survey = FDEM.Survey(source_list)
    prob = FDEM.Simulation3DMagneticFluxDensity(mesh, survey=survey, sigmaMap=mapping)








.. GENERATED FROM PYTHON SOURCE LINES 210-215

Set up data for inversion
-------------------------

Generate clean, synthetic data. Later we will invert the clean data, and
assign a standard deviation of 0.05, and a floor of 1e-11.

.. GENERATED FROM PYTHON SOURCE LINES 215-263

.. code-block:: Python


    t = time.time()

    data = prob.make_synthetic_data(
        m_true, relative_error=0.05, noise_floor=1e-11, add_noise=False
    )

    dclean = data.dclean
    print("Done forward simulation. Elapsed time = {:1.2f} s".format(time.time() - t))


    def plot_data(data, ax=None, color="C0", label=""):
        if ax is None:
            fig, ax = plt.subplots(1, 3, figsize=(15, 5))

        # data is [re, im, re, im, ...]
        data_real = data[0::2]
        data_imag = data[1::2]

        for i, offset in enumerate(coil_separations):
            ax[i].plot(
                src_locations,
                data_real[i :: len(coil_separations)],
                color=color,
                label="{} real".format(label),
            )
            ax[i].plot(
                src_locations,
                data_imag[i :: len(coil_separations)],
                "--",
                color=color,
                label="{} imag".format(label),
            )

            ax[i].set_title("offset = {:1.2f}m".format(offset))
            ax[i].legend()
            ax[i].grid(which="both")
            ax[i].set_ylim(np.r_[data.min(), data.max()] + 1e-11 * np.r_[-1, 1])

            ax[i].set_xlabel("source location x (m)")
            ax[i].set_ylabel("Secondary B-Field (T)")

        plt.tight_layout()
        return ax


    ax = plot_data(dclean)




.. image-sg:: /content/user-guide/examples/05-fdem/images/sphx_glr_plot_inv_fdem_loop_loop_2Dinversion_004.png
   :alt: offset = 0.32m, offset = 0.71m, offset = 1.18m
   :srcset: /content/user-guide/examples/05-fdem/images/sphx_glr_plot_inv_fdem_loop_loop_2Dinversion_004.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    /home/vsts/work/1/s/simpeg/base/pde_simulation.py:490: DefaultSolverWarning:

    Using the default solver: Pardiso. 

    If you would like to suppress this notification, add 
    warnings.filterwarnings('ignore', simpeg.utils.solver_utils.DefaultSolverWarning)
     to your script.

    Done forward simulation. Elapsed time = 22.24 s




.. GENERATED FROM PYTHON SOURCE LINES 264-279

Set up the inversion
--------------------

We create the data misfit, simple regularization
(a least-squares-style regularization, :class:`simpeg.regularization.LeastSquareRegularization`)
The smoothness and smallness contributions can be set by including
`alpha_s, alpha_x, alpha_y` as input arguments when the regularization is
created. The default reference model in the regularization is the starting
model. To set something different, you can input an `mref` into the
regularization.

We estimate the trade-off parameter, beta, between the data
misfit and regularization by the largest eigenvalue of the data misfit and
the regularization. Here, we use a fixed beta, but could alternatively
employ a beta-cooling schedule using :class:`simpeg.directives.BetaSchedule`

.. GENERATED FROM PYTHON SOURCE LINES 279-293

.. code-block:: Python


    dmisfit = data_misfit.L2DataMisfit(simulation=prob, data=data)
    reg = regularization.WeightedLeastSquares(inversion_mesh)
    opt = optimization.InexactGaussNewton(maxIterCG=10, remember="xc")
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)

    betaest = directives.BetaEstimate_ByEig(beta0_ratio=0.05, n_pw_iter=1, random_seed=1)
    target = directives.TargetMisfit()

    directiveList = [betaest, target]
    inv = inversion.BaseInversion(invProb, directiveList=directiveList)

    print("The target misfit is {:1.2f}".format(target.target))





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    The target misfit is 264.00




.. GENERATED FROM PYTHON SOURCE LINES 294-298

Run the inversion
------------------

We start from a half-space equal to the deep conductivity.

.. GENERATED FROM PYTHON SOURCE LINES 298-305

.. code-block:: Python


    m0 = np.log(sigma_deep) * np.ones(inversion_mesh.nC)

    t = time.time()
    mrec = inv.run(m0)
    print("\n Inversion Complete. Elapsed Time = {:1.2f} s".format(time.time() - t))





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    Running inversion with SimPEG v0.23.1.dev27+g1148ef1e9
    simpeg.InvProblem will set Regularization.reference_model to m0.
    simpeg.InvProblem will set Regularization.reference_model to m0.
    simpeg.InvProblem will set Regularization.reference_model to m0.
    simpeg.InvProblem will set Regularization.reference_model to m0.
    simpeg.InvProblem will set Regularization.reference_model to m0.

                            simpeg.InvProblem is setting bfgsH0 to the inverse of the eval2Deriv.
                            ***Done using same Solver, and solver_opts as the Simulation3DMagneticFluxDensity problem***
                        
    model has any nan: 0
    ============================ Inexact Gauss Newton ============================
      #     beta     phi_d     phi_m       f      |proj(x-g)-x|  LS    Comment   
    -----------------------------------------------------------------------------
    x0 has any nan: 0
       0  3.20e+00  1.42e+04  0.00e+00  1.42e+04    3.21e+03      0              
       1  3.20e+00  1.48e+03  5.42e+00  1.50e+03    4.61e+02      0              
    ------------------------- STOP! -------------------------
    1 : |fc-fOld| = 0.0000e+00 <= tolF*(1+|f0|) = 1.4191e+03
    1 : |xc-x_last| = 6.2345e+00 <= tolX*(1+|x0|) = 1.3056e+01
    0 : |proj(x-g)-x|    = 4.6099e+02 <= tolG          = 1.0000e-01
    0 : |proj(x-g)-x|    = 4.6099e+02 <= 1e3*eps       = 1.0000e-02
    0 : maxIter   =      20    <= iter          =      2
    ------------------------- DONE! -------------------------

     Inversion Complete. Elapsed Time = 239.33 s




.. GENERATED FROM PYTHON SOURCE LINES 306-309

Plot the predicted and observed data
------------------------------------


.. GENERATED FROM PYTHON SOURCE LINES 309-314

.. code-block:: Python


    fig, ax = plt.subplots(1, 3, figsize=(15, 5))
    plot_data(dclean, ax=ax, color="C0", label="true")
    plot_data(invProb.dpred, ax=ax, color="C1", label="predicted")




.. image-sg:: /content/user-guide/examples/05-fdem/images/sphx_glr_plot_inv_fdem_loop_loop_2Dinversion_005.png
   :alt: offset = 0.32m, offset = 0.71m, offset = 1.18m
   :srcset: /content/user-guide/examples/05-fdem/images/sphx_glr_plot_inv_fdem_loop_loop_2Dinversion_005.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    array([<Axes: title={'center': 'offset = 0.32m'}, xlabel='source location x (m)', ylabel='Secondary B-Field (T)'>,
           <Axes: title={'center': 'offset = 0.71m'}, xlabel='source location x (m)', ylabel='Secondary B-Field (T)'>,
           <Axes: title={'center': 'offset = 1.18m'}, xlabel='source location x (m)', ylabel='Secondary B-Field (T)'>],
          dtype=object)



.. GENERATED FROM PYTHON SOURCE LINES 315-318

Plot the recovered model
------------------------


.. GENERATED FROM PYTHON SOURCE LINES 318-350

.. code-block:: Python


    fig, ax = plt.subplots(1, 2, figsize=(12, 5))

    # put both plots on the same colorbar
    clim = np.r_[np.log(sigma_surface), np.log(sigma_deep)]

    # recovered model
    cb = plt.colorbar(
        inversion_mesh.plot_image(mrec, ax=ax[0], clim=clim)[0],
        ax=ax[0],
    )
    ax[0].set_title("recovered model")
    cb.set_label(r"$\log(\sigma)$")

    # true model
    cb = plt.colorbar(
        inversion_mesh.plot_image(m_true, ax=ax[1], clim=clim)[0],
        ax=ax[1],
    )
    ax[1].set_title("true model")
    cb.set_label(r"$\log(\sigma)$")

    # # uncomment to plot the true interface
    # x = np.linspace(-10, 10, 50)
    # [a.plot(x, interface(x), 'k') for a in ax]

    [a.set_xlim([-10, 10]) for a in ax]
    [a.set_ylim([-2, 0]) for a in ax]

    plt.tight_layout()
    plt.show()




.. image-sg:: /content/user-guide/examples/05-fdem/images/sphx_glr_plot_inv_fdem_loop_loop_2Dinversion_006.png
   :alt: recovered model, true model
   :srcset: /content/user-guide/examples/05-fdem/images/sphx_glr_plot_inv_fdem_loop_loop_2Dinversion_006.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 351-354

Print the version of SimPEG and dependencies
--------------------------------------------


.. GENERATED FROM PYTHON SOURCE LINES 354-357

.. code-block:: Python


    Report()






.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <table style='border: 1.5px solid;'>
      <tr>
         <td style='text-align: center; font-weight: bold; font-size: 1.2em; border: 1px solid;' colspan='6'>Fri Mar 21 09:07:54 2025 UTC</td>
      </tr>
      <tr>
        <td style='text-align: right; border: 1px solid;'>OS</td>
        <td style='text-align: left; border: 1px solid;'>Linux (Ubuntu 22.04)</td>
        <td style='text-align: right; border: 1px solid;'>CPU(s)</td>
        <td style='text-align: left; border: 1px solid;'>2</td>
        <td style='text-align: right; border: 1px solid;'>Machine</td>
        <td style='text-align: left; border: 1px solid;'>x86_64</td>
      </tr>
      <tr>
        <td style='text-align: right; border: 1px solid;'>Architecture</td>
        <td style='text-align: left; border: 1px solid;'>64bit</td>
        <td style='text-align: right; border: 1px solid;'>RAM</td>
        <td style='text-align: left; border: 1px solid;'>6.8 GiB</td>
        <td style='text-align: right; border: 1px solid;'>Environment</td>
        <td style='text-align: left; border: 1px solid;'>Python</td>
      </tr>
      <tr>
        <td style='text-align: right; border: 1px solid;'>File system</td>
        <td style='text-align: left; border: 1px solid;'>ext4</td>
      </tr>
      <tr>
         <td style='text-align: center; border: 1px solid;' colspan='6'>Python 3.10.16 | packaged by conda-forge | (main, Dec  5 2024, 14:16:10) [GCC 13.3.0]</td>
      </tr>
      <tr>
        <td style='text-align: right; border: 1px solid;'>simpeg</td>
        <td style='text-align: left; border: 1px solid;'>0.23.1.dev27+g1148ef1e9</td>
        <td style='text-align: right; border: 1px solid;'>discretize</td>
        <td style='text-align: left; border: 1px solid;'>0.11.2</td>
        <td style='text-align: right; border: 1px solid;'>pymatsolver</td>
        <td style='text-align: left; border: 1px solid;'>0.3.1</td>
      </tr>
      <tr>
        <td style='text-align: right; border: 1px solid;'>numpy</td>
        <td style='text-align: left; border: 1px solid;'>2.1.3</td>
        <td style='text-align: right; border: 1px solid;'>scipy</td>
        <td style='text-align: left; border: 1px solid;'>1.15.2</td>
        <td style='text-align: right; border: 1px solid;'>matplotlib</td>
        <td style='text-align: left; border: 1px solid;'>3.10.1</td>
      </tr>
      <tr>
        <td style='text-align: right; border: 1px solid;'>geoana</td>
        <td style='text-align: left; border: 1px solid;'>0.7.2</td>
        <td style='text-align: right; border: 1px solid;'>libdlf</td>
        <td style='text-align: left; border: 1px solid;'>0.3.0</td>
        <td style='text-align: right; border: 1px solid;'>pydiso</td>
        <td style='text-align: left; border: 1px solid;'>0.1.2</td>
      </tr>
      <tr>
        <td style='text-align: right; border: 1px solid;'>numba</td>
        <td style='text-align: left; border: 1px solid;'>0.61.0</td>
        <td style='text-align: right; border: 1px solid;'>dask</td>
        <td style='text-align: left; border: 1px solid;'>2025.2.0</td>
        <td style='text-align: right; border: 1px solid;'>sklearn</td>
        <td style='text-align: left; border: 1px solid;'>1.6.1</td>
      </tr>
      <tr>
        <td style='text-align: right; border: 1px solid;'>pandas</td>
        <td style='text-align: left; border: 1px solid;'>2.2.3</td>
        <td style='text-align: right; border: 1px solid;'>sympy</td>
        <td style='text-align: left; border: 1px solid;'>1.13.3</td>
        <td style='text-align: right; border: 1px solid;'>plotly</td>
        <td style='text-align: left; border: 1px solid;'>6.0.1</td>
      </tr>
      <tr>
        <td style='text-align: right; border: 1px solid;'>memory_profiler</td>
        <td style='text-align: left; border: 1px solid;'>0.61.0</td>
        <td style='text-align: right; border: 1px solid;'>choclo</td>
        <td style='text-align: left; border: 1px solid;'>0.3.2</td>
        <td style= border: 1px solid;'></td>
        <td style= border: 1px solid;'></td>
      </tr>
    </table>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 358-369

Moving Forward
--------------

If you have suggestions for improving this example, please create a `pull request on the example in SimPEG <https://github.com/simpeg/simpeg/blob/main/examples/07-fdem/plot_loop_loop_2Dinversion.py>`_

You might try:
   - improving the discretization
   - changing beta
   - changing the noise model
   - playing with the regulariztion parameters
   - ...


.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (4 minutes 30.693 seconds)

**Estimated memory usage:**  3161 MB


.. _sphx_glr_download_content_user-guide_examples_05-fdem_plot_inv_fdem_loop_loop_2Dinversion.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_inv_fdem_loop_loop_2Dinversion.ipynb <plot_inv_fdem_loop_loop_2Dinversion.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_inv_fdem_loop_loop_2Dinversion.py <plot_inv_fdem_loop_loop_2Dinversion.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: plot_inv_fdem_loop_loop_2Dinversion.zip <plot_inv_fdem_loop_loop_2Dinversion.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_