# Inversion of magnetization amplitude with different direction than external field

**URL:** <https://simpeg.discourse.group/t/inversion-of-magnetization-amplitude-with-different-direction-than-external-field/737>\
**Category:** Potential Fields\
**Created:** [October 20, 2025, 11:40am UTC](https://simpeg.discourse.group/t/inversion-of-magnetization-amplitude-with-different-direction-than-external-field/737 "2025-10-20T11:40:07Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![clairebouligand](https://avatars.discourse-cdn.com/v4/letter/c/9e8a1a/32.png) [@clairebouligand](https://simpeg.discourse.group/u/clairebouligand)\
**Post date:** [October 20, 2025, 11:40am UTC](https://simpeg.discourse.group/t/inversion-of-magnetization-amplitude-with-different-direction-than-external-field/737/1 "2025-10-20T11:40:07Z")

</div>

Hi,  
I would like to know if this is possible to do an inversion of magnetization or pseudo-susceptibility assuming the magnetization direction is different from the external field. I have tested the mvi inversion by imposing a starting and reference model with a fixed direction of magnetization different from the external field and i see the recovered magnetization remain close to the starting magnetization direction which is what i wanted but if possible i would like to keep the magnetization direction completely fixed, in order to limit the number of free parameters in the inversion. Is this possible with simpeg and if so how could I do that ?  
Thank you,  
Claire.

---

<div class="post-metadata">

**Author:** ![johnweis](https://avatars.discourse-cdn.com/v4/letter/j/4491bb/32.png) [@johnweis](https://simpeg.discourse.group/u/johnweis)\
**Post date:** [October 21, 2025, 7:03pm UTC](https://simpeg.discourse.group/t/inversion-of-magnetization-amplitude-with-different-direction-than-external-field/737/2 "2025-10-21T19:03:36Z")

</div>

Hi Claire,

This is not something built in but I wrote a mapping class that can do this. I attached a snippet here. You would use simulation\_scalar to run your inversion, and pass scalar\_map to your regularization. If you have any questions on it let me know.

Cheers,

John

```auto
from simpeg.maps import IdentityMap
from simpeg import utils
from simpeg.utils import mkvc,sdiag
import scipy.sparse as sp

class MagnetizationMap(IdentityMap):

    def __init__ (self, mesh=None, nP=None, inducing_field = None, **kwargs):
        super(MagnetizationMap, self). __init__ (mesh=mesh, nP=nP, **kwargs)
        self.inducing_field = inducing_field
        num = np.ones(nP)
        Mx = sp.diags(num*inducing_field[0])
        My = sp.diags(num*inducing_field[1])
        Mz = sp.diags(num*inducing_field[2])
        self.M = sp.vstack([Mx, My, Mz])

    @property
    def shape(self):

        return (self.nP * 3, self.nP)

    def _transform(self, m):

        return self.M * m

    def deriv(self, m, v=None):
        if v is not None:
            return self.M * v
        return self.M * sp.eye(self.nP)

actv = active_from_xyz(mesh, topo)
nC = int(actv.sum())

dip = 45.0
azm = 90.0

dip_model = dip*np.ones(nC)
azm_model = azm*np.ones(nC)

#model amp is the scalar amplitude throughout the mesh
model_vector = sdiag(model_amp) * utils.mat_utils.dip_azimuth2cartesian(
    dip_model, azm_model
)

# Map you use to invert for vector inversion
vectorMap = maps.IdentityMap(nP=nC * 3)

# Pass this map to your regularization for scalar inversion
scalarMap = maps.IdentityMap(nP=nC)

mag_map_indfield = 1 * utils.mat_utils.dip_azimuth2cartesian(
    dip, azm
)[0]

# pass this map to scalar forward simulation
mag_map = MagnetizationMap(nP=nC,inducing_field=mag_map_indfield)

#setup vector simulation
simulation_vector = magnetics.simulation.Simulation3DIntegral(
    survey=survey, mesh=mesh, chiMap=vectorMap, active_cells=actv, model_type="vector",
)

#setup scalar simulation
simulation_scalar = magnetics.simulation.Simulation3DIntegral(
    survey=survey, mesh=mesh, chiMap=mag_map, active_cells=actv, model_type="vector",
)

#check that they give the same result
d1 = simulation_vector.dpred(mkvc(model_vector))
d2 = simulation_scalar.dpred(model_amp)

assert(np.allclose(d1, d2))

```

---

<div class="post-metadata">

**Author:** ![clairebouligand](https://avatars.discourse-cdn.com/v4/letter/c/9e8a1a/32.png) [@clairebouligand](https://simpeg.discourse.group/u/clairebouligand)\
**Post date:** [October 23, 2025, 9:53am UTC](https://simpeg.discourse.group/t/inversion-of-magnetization-amplitude-with-different-direction-than-external-field/737/3 "2025-10-23T09:53:25Z")

</div>

Dear John,  
Thank you very much for your prompt answer.  
If we want to continue your script with the inversion step, can we then simply follow the instructions in the tutorial for susceptibility inversion at [3D Inversion of TMI Data to Recover a Susceptibility Model - SimPEG User Tutorials](https://simpeg.xyz/user-tutorials/inv-magnetics-induced-3d/) with the following definitions :

- dmis = data\_misfit.L2DataMisfit(data=data\_object, simulation=simulation\_scalar)
- reference\_tensor\_model and starting\_tensor\_model defined as magnetization amplitude 1D array similar to the model\_amp array

Is that all or are there additional changes that i am missing ?  
Thank you,  
Claire.

---

<div class="post-metadata">

**Author:** ![johnweis](https://avatars.discourse-cdn.com/v4/letter/j/4491bb/32.png) [@johnweis](https://simpeg.discourse.group/u/johnweis)\
**Post date:** [October 24, 2025, 3:23am UTC](https://simpeg.discourse.group/t/inversion-of-magnetization-amplitude-with-different-direction-than-external-field/737/4 "2025-10-24T03:23:22Z")

</div>

Hi Claire,

Yes that is right for all the other pieces you can just run a normal susceptibility style inversion. The only thing that changes is the simulation which uses that mapping.

John

---

<div class="post-metadata">

**Author:** ![rpzanon](https://avatars.discourse-cdn.com/v4/letter/r/58f4c7/32.png) [@rpzanon](https://simpeg.discourse.group/u/rpzanon)\
**Post date:** [March 26, 2026, 7:06pm UTC](https://simpeg.discourse.group/t/inversion-of-magnetization-amplitude-with-different-direction-than-external-field/737/5 "2026-03-26T19:06:21Z")

</div>

Hi,

I am running the magnetic amplitude inversion on 3D TreeMesh. it seems that the predicted data is based on the synthetic data, not in the model, so the inversion results are empty. which line I have to change to correct the data ?

```auto
# Assign magnetization value, inducing field strength will
# be applied in by the :class:`simpeg.PF.Magnetics` problem
model = np.zeros(mesh.nC)
model[ind] = chi_e

# Remove air cells
model = model[actv]

# Create reduced identity map
idenMap = maps.IdentityMap(nP=nC)

# Create the forward model operator
simulation = magnetics.simulation.Simulation3DIntegral(
    survey=survey,
    mesh=mesh,
    chiMap=idenMap,
    active_cells=actv,
    store_sensitivities="forward_only",
)
simulation.M = M_xyz

# Compute some data and add some random noise
synthetic_data = simulation.dpred(model)

# Split the data in components
nD = rxLoc.shape[0]

std = 5 # nT
synthetic_data += np.random.randn(nD) * std
wd = np.ones(nD) * std

# Assign data and uncertainties to the survey
data_object = data.Data(survey, dobs=synthetic_data, standard_deviation=wd)

```

kind regards,

roberto
