Spin-orbit torque

Last changes: Documentation changelog

Physical problem

PrescribedSpinOrbitTorque adds a local damping-like (DL) and field-like (FL) source to the magnetization equation. It does not solve charge accumulation, spin accumulation, spin diffusion, or an HM/FM interface problem. The authored efficiencies already represent all conversion and transmission physics that the model omits.

Use the tabs below to choose the correct model before assigning parameters.

Use PrescribedSpinOrbitTorque when the signed current density, spin-polarization axis, and effective DL/FL efficiencies are known inputs. The heavy-metal layer does not need to be meshed. Runtime cost is that of a local LLG source.

This is the Fullmag counterpart of a MuMax-style EnableSOT model: J maps to the signed drive, Pol to sigma, ThetaSH to xi_dl, ThetaFL to xi_fl, and FreeLayerThickness to free_layer_thickness_m. The mapping is a parameter mapping, not a claim that xi_dl equals a bulk spin Hall angle in a real stack.

Use the transport model when the torque must follow from material conductivities, spin Hall angle, spin-relaxation lengths, boundary conditions, and HM/FM mixing conductance. Fullmag then resolves

CurrentTransport -> SpinDriftDiffusion -> interface absorption -> DriftDiffusionSpinTorque

That route produces a generally nonuniform torque and can include backflow and finite-transparency effects. It is documented separately in Spin Hall drift-diffusion transport. Do not add PrescribedSpinOrbitTorque on top of the solved transport torque unless the two sources intentionally represent different physics.

Question

Prescribed local SOT

Solved SHE transport

Primary input

signed current and effective xi_dl, xi_fl

material and interface transport parameters

Charge/spin PDE

none

solved

HM mesh

optional and not consumed by this torque

part of the transport domain

Spatial variation

target mask, material fields, and current-source projection

transport solution and interface absorption

Best use

calibrated reduced model, switching scans, MuMax comparison

stack design and spatial spin-transport studies

Prescribed SOT comparison: local SOT, M1, and M2

PrescribedSpinOrbitTorque, M1, and M2 can all add a spin torque to the same magnetization equation, but they do not represent the same physical problem. The distinction is the location at which the model starts:

Prescribed SOT: authored J, sigma, xi_DL, xi_FL, t_F -> local LLG source

M1: electrodes/materials -> charge solve -> spin solve -> interface absorption -> LLG source

M2: electrodes/materials <-> reciprocal charge-spin block
                              -> interface absorption -> LLG source

The prescribed model starts at the final, reduced torque law. M1 starts at charge transport and computes the spin distribution without feeding spin back into the charge solution. M2 solves a reciprocal charge-spin problem in which the spin state can modify the charge response. Therefore xi_dl=theta_sh does not, by itself, make a prescribed-SOT simulation equivalent to M1 or M2.

Meaning of M1 and M2 in Fullmag

These names describe coupling levels of the drift-diffusion model, not two formula variants of PrescribedSpinOrbitTorque.

M1: one-way solved transport. CurrentTransport(coupling="one_way") produces the charge-current field first. SpinDriftDiffusion then consumes that named current source, evaluates direct spin Hall injection, diffusion and active spin reactions, and supplies absorbed interface spin flux to DriftDiffusionSpinTorque. The spin solution does not alter the already solved charge field.

M2: reciprocal solved transport. CurrentTransport(coupling="bidirectional") selects the reciprocal constitutive contract. Charge and spin belong to one coupled steady problem; the charge block includes the authored magnetoresistive conductivities and the spin block can return an inverse-spin-Hall contribution. In the public Python contract, bidirectional current transport requires model="ohmic_poisson", complete anisotropic conductivity data, and a block_gmres charge policy. SpinDriftDiffusion.to_ir() records transport_constitutive.reciprocal.fullmag.v1 instead of the M1 transport_constitutive.one_way.fullmag.v1 contract.

Prescribed SOT: no transport solve. The module directly evaluates a local DL/FL source from a signed current, a polarization axis, two effective efficiencies and the physical FM thickness. It does not create charge potential, spin potential, spin current, interface backflow, or inverse-SHE observables.

Side-by-side physical comparison

Property

Prescribed SOT

M1: one-way transport

M2: reciprocal transport

Model entry point

effective local torque law

charge boundary-value problem

coupled charge-spin boundary-value problem

Charge potential and current

not solved by SignedScalarDrive; optional named current projection with VectorCurrentDrive

solved before spin

solved inside the reciprocal block

Spin accumulation

not a state variable

solved in the transport domain

solved and coupled back to charge

Direct SHE

absorbed into fitted xi_dl/xi_fl

generated from local theta_sh and charge current

generated from local theta_sh and coupled charge current

Inverse SHE

absent

absent from charge feedback

included by the reciprocal constitutive contract

AMR/PHE/AHE charge response

absent from the torque module

not part of one-way spin feedback

authored through parallel, perpendicular and AHE conductivities

Spin diffusion and relaxation

absent

resolved from sigma_s_Spm, lambda_sf_m, and enabled magnetic lengths

resolved in the reciprocal block

HM/FM interface

not required by the module

explicit transparent or mixing-conductance interface

explicit interface in the coupled transport graph

Interface transparency and backflow

folded into effective efficiencies

computed from interface and bulk transport data

computed while charge and spin are mutually coupled

Torque source

local DL/FL formula

absorbed transverse interface spin flux

absorbed transverse interface spin flux

Spatial nonuniformity

target mask, local magnetic fields, envelope, and optional current projection

charge crowding, diffusion, reactions, boundaries, geometry, and interface absorption

all M1 mechanisms plus reciprocal charge-spin redistribution

Required nonmagnetic mesh

none for the torque itself

yes, for every active transport region

yes, for every active transport region

Main fitted quantities

effective xi_dl, xi_fl

bulk and interface transport parameters

bulk, interface, magnetoresistive, and reciprocal transport parameters

Typical computational cost

local per magnetic degree of freedom

charge solve plus spin solve

coupled nonlinear/block solve; normally the most expensive of the three

Natural observables

magnetization and prescribed torque

potential, charge current, spin state, absorbed flux, and torque

M1 observables plus reciprocal charge response

Appropriate use

calibrated reduced switching/dynamics model

spatial SHE transport without feedback to charge

reciprocal device transport where spin modifies charge

The table compares physics only. Executable discretization, device, precision, solver, and interface support are lane-specific and fail closed. Consult the drift-diffusion transport page before selecting an M1 or M2 backend.

What prescribed SOT removes

The reduction replaces the solved transport chain with effective coefficients:

bulk charge conversion
+ spin diffusion and relaxation
+ interface transmission and backflow
+ unresolved stack losses
                         -> xi_DL and xi_FL

This replacement is useful only when those coefficients are known for the stack, temperature, thickness range and sign convention being simulated. It also changes what can be predicted. Prescribed SOT can answer how a magnetic body responds to an assumed torque efficiency. It cannot predict how changing HM conductivity, HM thickness, spin-diffusion length, interface mixing conductance or electrode geometry changes that efficiency. M1 or M2 is needed for those questions.

There is generally no unique parameter-by-parameter conversion from M1/M2 to prescribed SOT. An effective xi_dl may be extracted by matching an integrated or averaged damping-like torque for one operating point. An effective xi_fl may be fitted in the same way. The resulting pair need not reproduce local hotspots, edge accumulation, thickness dependence, current crowding, backflow, or a different magnetic state.

When the models may agree

Prescribed SOT can approximate M1 or M2 when all of the following are justified:

  • the FM is thin enough that a volume-averaged torque is meaningful;

  • the in-plane current and injected spin polarization are approximately uniform;

  • transport relaxes much faster than the magnetic dynamics of interest;

  • interface and bulk losses can be represented by fixed effective efficiencies;

  • reciprocal modification of the charge path is negligible, or already folded into a calibration performed at the same operating point;

  • the observable depends on the integrated torque rather than its local profile.

Agreement should be demonstrated against a declared observable, not assumed from similar-looking trajectories. Useful calibration targets include the volume-integrated DL/FL torque, initial angular acceleration, switching threshold, or a selected harmonic response. A coefficient fitted to one target is not automatically validated for the others.

When M1 or M2 is required

Choose M1 when spatial charge and spin transport matters but one-way charge-to-spin coupling is an acceptable approximation. Typical reasons are current crowding, finite spin-diffusion length, multilayer spin absorption, mixing-conductance interfaces, nonuniform torque, or a geometry in which a single authored sigma is insufficient.

Choose M2 when the reciprocal charge response is itself part of the physics or observable. Examples include inverse-SHE voltage/current, simultaneous AMR/PHE/AHE transport, or a device state in which magnetization-dependent charge redistribution materially changes spin injection. M2 is not automatically “more accurate”: it is a larger constitutive model requiring additional parameters, boundary data, solver policy, and validation.

Choose prescribed SOT when the scientific input is already an effective torque efficiency, when reproducing a MuMax-style local SOT experiment, or when large parameter scans would make a solved transport domain unnecessary. Do not use it merely to avoid supplying unknown transport data while still claiming predictions about that missing transport physics.

Python authoring: the decisive differences

The following fragments show the model-selection fields. They are deliberately short; complete M1 and M2 examples, including materials, interfaces, electrodes and solver restrictions, are maintained on the drift-diffusion page.

study.spin_torque(fm.PrescribedSpinOrbitTorque(
    name="local_sot",
    target=fm.RegionRef("fm"),
    drive=fm.SignedScalarDrive(
        current_density_Apm2=1.0e11,
        sigma=(0.0, 1.0, 0.0),
    ),
    xi_dl=0.12,
    xi_fl=0.01,
    free_layer_thickness_m=1.0e-9,
))

No CurrentTransport, SpinDriftDiffusion, transport material, interface, or spin boundary is consumed by this module.

charge = study.current_transport(
    name="charge",
    model="ohmic_poisson",
    coupling="one_way",
    # domain, materials, boundaries, gauge, solver
)
spin = study.spin_transport(fm.SpinDriftDiffusion(
    id="spin",
    current_source_id=charge.name,
    # domain, materials, interfaces, boundaries, solver
))
study.spin_torque(fm.DriftDiffusionSpinTorque(
    id="transport_torque",
    solve_id=spin.id,
    target=fm.RegionRef("fm"),
))

The dependency direction is charge -> spin -> torque; no spin-to-charge edge is authored.

charge = study.current_transport(
    name="charge",
    model="ohmic_poisson",
    coupling="bidirectional",
    # complete anisotropic materials and block_gmres policy
)
spin = study.spin_transport(fm.SpinDriftDiffusion(
    id="spin",
    current_source_id=charge.name,
    mode="steady",
    # reciprocal operator and lane-specific solver policy
))
study.spin_torque(fm.DriftDiffusionSpinTorque(
    id="transport_torque",
    solve_id=spin.id,
    target=fm.RegionRef("fm"),
))

The problem validator binds charge and spin to the reciprocal constitutive contract. This is not obtained by adding PrescribedSpinOrbitTorque to M1.

Do not double count the torque

DriftDiffusionSpinTorque consumes the absorbed spin flux from a named M1/M2 solve. PrescribedSpinOrbitTorque creates an independent local source. Adding both to the same target sums both terms in the magnetization equation; Fullmag does not infer that one replaces the other. Such a combination is valid only when the user can identify two distinct physical sources, for example a solved HM torque plus a separately calibrated torque from another unmeshed layer.

For a comparison study, run separate problems or stages with one torque model active at a time, preserve the current and normal sign convention, and compare the same torque or magnetization observable.

Governing equations and sign convention

Let \(\mathbf m\) be the unit magnetization, \(\hat{\boldsymbol\sigma}\) the unit spin polarization, and \(J_{\mathrm{signed}}\) the conventional signed charge-current density. A thin-film reduction converts an effective spin angular-momentum flux \((\hbar/2e)\,\xi J_{\mathrm{signed}}\) into a volume source by dividing by the free-layer thickness \(t_F\).

The reduction is written below as separate equations. This is intentional: the base current-to-frequency conversion, the two efficiencies, and the two torque directions are different modelling choices and should not be read as one fitted constant.

Base current-to-frequency conversion

(1)\[\Omega_0 = \frac{\gamma_e\hbar J_{\mathrm{signed}}} {2eM_s t_F}.\]

This equation answers only: “how large is the torque frequency before DL/FL efficiencies are applied?” Its sign comes from \(J_{\mathrm{signed}}\). Increasing \(M_s\) or \(t_F\) reduces the same injected angular momentum per magnetic volume. The constants \(e\), \(\hbar\), and \(\gamma_e\) are supplied by the backend and are not Python inputs.

Damping-like rate

(2)\[\Omega_{\mathrm{DL}} = \xi_{\mathrm{DL}}\Omega_0.\]

xi_dl is an effective dimensionless damping-like efficiency. In a reduced model it absorbs bulk conversion, interface transmission, spin backflow, and other stack-specific losses. It is usually inferred from harmonic Hall, spin-torque ferromagnetic resonance, switching, or another calibrated torque measurement. It is not automatically equal to the bulk spin Hall angle.

Field-like rate

(3)\[\Omega_{\mathrm{FL}} = \xi_{\mathrm{FL}}\Omega_0.\]

xi_fl is the signed effective field-like efficiency. Its sign and magnitude can depend strongly on interfaces, stack order, annealing, and the convention used for current and interface normal. Do not infer it from xi_dl unless the chosen physical model or measurement explicitly supplies that relation.

Damping-like Gilbert torque

(4)\[\mathbf T_{\mathrm{DL}}^{G} = \Omega_{\mathrm{DL}} \mathbf m\times (\hat{\boldsymbol\sigma}\times\mathbf m).\]

The vector \(\mathbf m\times(\hat{\boldsymbol\sigma}\times\mathbf m)\) is the component of \(\hat{\boldsymbol\sigma}\) transverse to \(\mathbf m\). The DL term therefore pushes \(\mathbf m\) toward or away from that transverse polarization, depending on the total sign of \(J_{\mathrm{signed}}\xi_{\mathrm{DL}}\).

Field-like Gilbert torque

(5)\[\mathbf T_{\mathrm{FL}}^{G} = \Omega_{\mathrm{FL}} \mathbf m\times\hat{\boldsymbol\sigma}.\]

The vector \(\mathbf m\times\hat{\boldsymbol\sigma}\) has the same geometry as precession about a field parallel to \(\hat{\boldsymbol\sigma}\). This explains the name “field-like”; xi_fl remains a torque efficiency, not a magnetic-field input in tesla.

Total Gilbert source

(6)\[\mathbf T_{\mathrm{SOT}}^{G} = \mathbf T_{\mathrm{DL}}^{G} + \mathbf T_{\mathrm{FL}}^{G}.\]

The source has units \(\mathrm{s^{-1}}\) and is added to the magnetization time derivative. Reversing the signed current, reversing sigma, or reversing one efficiency reverses the corresponding term. Reversing both current and sigma leaves the torque unchanged.

Gilbert-to-explicit conversion

Backends add an explicit right-hand-side contribution after solving the Gilbert form once. Define the explicit damping-like coefficient separately:

(7)\[C_{\mathrm{DL}} = \Omega_0 \frac{\xi_{\mathrm{DL}}-\alpha\xi_{\mathrm{FL}}} {1+\alpha^2}.\]

Define the explicit field-like coefficient independently:

(8)\[C_{\mathrm{FL}} = \Omega_0 \frac{\xi_{\mathrm{FL}}+\alpha\xi_{\mathrm{DL}}} {1+\alpha^2}.\]

The actual explicit source is then

(9)\[\mathbf T_{\mathrm{SOT}} = C_{\mathrm{DL}} \mathbf m\times (\hat{\boldsymbol\sigma}\times\mathbf m) + C_{\mathrm{FL}} \mathbf m\times\hat{\boldsymbol\sigma}.\]

The cross-coupling by \(\alpha\) is an algebraic consequence of converting the Gilbert equation to an explicit time derivative. It is why MuMax-style code may contain apparent DL/FL compensation. Author the physical xi_dl and xi_fl; do not pre-apply these formulas in Python.

Drive definitions

Signed scalar drive

SignedScalarDrive is the direct reduced-model input:

(10)\[J_{\mathrm{signed}}(t) = J_0 f(t).\]

J_0 is the signed current-density amplitude controlled by the script or experiment. \(f(t)\) is the dimensionless envelope evaluated at stage time.

(11)\[\hat{\boldsymbol\sigma}= \frac{\boldsymbol\sigma}{\lVert\boldsymbol\sigma\rVert}.\]

The authored vector \(\boldsymbol\sigma\) states the spin-polarization direction; only its direction is retained. J_0 may be positive, negative, or zero. sigma is normalized during authoring. The optional envelope must be one of the canonical Fullmag envelope objects: ConstantEnvelope, SinusoidalEnvelope, PulseEnvelope, PiecewiseLinearEnvelope, SincEnvelope, or TabulatedEnvelope.

Vector-current binding

VectorCurrentDrive binds the torque to a named vector-current source while making the geometric convention explicit:

(12)\[J_{\mathrm{signed}} = \mathbf J_c\cdot\hat{\mathbf t}.\]

Only the component of the named current source along drive_direction contributes to this reduced torque.

(13)\[\hat{\boldsymbol\sigma} = \frac{\hat{\mathbf n}_{NF}\times\hat{\mathbf t}} {\lVert\hat{\mathbf n}_{NF}\times\hat{\mathbf t}\rVert}.\]

drive_direction defines \(\hat{\mathbf t}\) and interface_normal defines the oriented normal \(\hat{\mathbf n}_{NF}\) from the nonmagnetic layer toward the ferromagnet. Both authored axes are normalized. They must be nonzero and must not be parallel within the canonical axis tolerance \(10^{-12}\). The projection preserves current reversal; the polarization axis does not flip when only the source current reverses.

Symbols and SI units

Symbol

Meaning

SI unit

\(m\)

unit magnetization

\(1\)

\(\hat{\boldsymbol\sigma}\)

unit spin-polarization axis

\(1\)

\(\boldsymbol\sigma\)

authored nonzero spin-polarization vector

\(1\)

\(J_{\mathrm{signed}}\)

signed conventional charge-current density driving the local source

\(\mathrm{A\,m^{-2}}\) (A/m^2)

\(J_0\)

prescribed signed current-density amplitude

\(\mathrm{A\,m^{-2}}\) (A/m^2)

\(\mathbf J_c\)

named vector charge-current density

\(\mathrm{A\,m^{-2}}\) (A/m^2)

\(\hat{\mathbf t}\)

normalized current-projection direction

\(1\)

\(\hat{\mathbf n}_{NF}\)

normalized oriented nonmagnet-to-ferromagnet interface normal

\(1\)

\(\xi_{\mathrm{DL}}\)

signed effective damping-like efficiency

\(1\)

\(\xi_{\mathrm{FL}}\)

signed effective field-like efficiency

\(1\)

\(t_F\)

physical free-layer thickness

\(\mathrm{m}\) (m)

\(M_s\)

local saturation magnetization

\(\mathrm{A\,m^{-1}}\) (A/m)

\(\gamma_e\)

positive magnitude of electron gyromagnetic ratio

\(\mathrm{s^{-1}\,T^{-1}}\) (1/(s T))

\(\hbar\)

reduced Planck constant

\(\mathrm{J\,s}\) (J s)

\(e\)

positive elementary charge

\(\mathrm{C}\) (C)

\(\alpha\)

Gilbert damping

\(1\)

\(\Omega_0\)

signed base torque frequency

\(\mathrm{s^{-1}}\) (1/s)

\(\Omega_{\mathrm{DL}}\)

signed damping-like Gilbert rate

\(\mathrm{s^{-1}}\) (1/s)

\(\Omega_{\mathrm{FL}}\)

signed field-like Gilbert rate

\(\mathrm{s^{-1}}\) (1/s)

\(C_{\mathrm{DL}}\)

damping-like coefficient after Gilbert-to-explicit conversion

\(\mathrm{s^{-1}}\) (1/s)

\(C_{\mathrm{FL}}\)

field-like coefficient after Gilbert-to-explicit conversion

\(\mathrm{s^{-1}}\) (1/s)

\(\mathbf T_{\mathrm{DL}}^{G}\)

damping-like source in Gilbert form

\(\mathrm{s^{-1}}\) (1/s)

\(\mathbf T_{\mathrm{FL}}^{G}\)

field-like source in Gilbert form

\(\mathrm{s^{-1}}\) (1/s)

\(\mathbf T_{\mathrm{SOT}}^{G}\)

total prescribed source in Gilbert form

\(\mathrm{s^{-1}}\) (1/s)

\(\mathbf T_{\mathrm{SOT}}\)

prescribed spin-orbit torque contribution

\(\mathrm{s^{-1}}\) (1/s)

\(f(t)\)

canonical scalar time-envelope multiplier

\(1\)

Assumptions and validity

  • The ferromagnet is represented by a unit magnetization with positive local \(M_s\).

  • The HM/FM conversion is reduced to signed effective efficiencies; bulk spin Hall angle, interface transparency, spin backflow, and diffusion are not solved.

  • The free-layer thickness is an authored physical parameter and is not inferred from mesh cells.

  • VectorCurrentDrive uses fixed authored axes and one signed projection of a named current source.

  • The source is local to the resolved target mask; it does not generate an Oersted field.

Which values come from where?

The following classification is the practical minimum for preparing a script. “Literature” means a starting point for a comparable stack, not a universal material constant.

Script value

Category

Where to obtain it

Example used below

Required action

name

model identity

chosen by the author

"hm_sot"

choose a unique ID

target

geometry/model identity

Fullmag object and region names

RegionRef("film")

point to the magnetic free layer

body.Ms

measured material parameter

magnetometry or a validated material dataset

\(8.0\times10^5\,\mathrm{A\,m^{-1}}\)

replace with the sample value

body.Aex

material/model parameter

spin-wave, domain-wall, or literature calibration

\(13\,\mathrm{pJ\,m^{-1}}\)

replace or justify

body.alpha

measured effective material parameter

FMR linewidth or calibrated dynamics

\(0.02\)

replace with the stack value

free_layer_thickness_m

fabricated geometry

magnetic-layer thickness, not HM thickness

\(1.5\,\mathrm{nm}\)

enter the physical magnetic thickness

current_density_Apm2

controlled drive

applied current divided by the conducting cross-section, with declared sign

\(-4.0\times10^{11}\,\mathrm{A\,m^{-2}}\)

choose the sweep or pulse value

sigma

controlled geometry and sign convention

current direction, interface normal, and SHE convention

\((0,1,0)\)

verify using a current-reversal test

xi_dl

effective fitted SOT parameter

harmonic Hall, ST-FMR, switching fit, or literature seed

\(0.12\)

calibrate for the actual stack

xi_fl

effective fitted SOT parameter

harmonic Hall, ST-FMR, or dedicated fit

\(-0.03\)

calibrate independently

envelope

controlled waveform

experiment or numerical protocol

None, meaning constant

define pulse/ramp if needed

until

controlled simulation window

physical timescale and convergence study

\(1\,\mathrm{ps}\)

choose long enough for the observable

cell size

numerical parameter

convergence study and exchange length

\((2,2,2)\,\mathrm{nm}\)

demonstrate mesh convergence

engine/device/precision

numerical execution policy

desired qualified backend lane

FDM CPU double strict

choose explicitly

Fullmag supplies \(e\), \(\hbar\), and \(\gamma_e\). Fullmag derives \(\Omega_0\), \(\Omega_{\mathrm{DL}}\), \(\Omega_{\mathrm{FL}}\), \(C_{\mathrm{DL}}\), and \(C_{\mathrm{FL}}\). None of those constants or derived rates belongs in the Python constructor.

How to use literature values safely

Nguyen, Ralph, and Buhrman reported a peak damping-like efficiency per current density of \(\xi_{\mathrm{DL}}^j=0.12\) for their Pt/Co samples at Pt thickness \(2.8\)-\(3.9\,\mathrm{nm}\). This supports xi_dl=0.12 as a realistic literature seed for a related Pt/FM stack, but it does not determine the Co thickness, \(M_s\), \(\alpha\), xi_fl, or the sign convention of a different sample. Their measured efficiency also changes with Pt thickness and resistivity.

Garello and co-workers measured both DL-like and FL-like components and found strong dependence on stack composition, magnetization angle, and annealing. Consequently, the example xi_fl=-0.03 is explicitly illustrative; it is not presented as a transferable Pt/Co constant.

Use this order when building a real case:

  1. Enter measured geometry, \(M_s\), \(A_{\mathrm{ex}}\), and \(\alpha\) for the same sample.

  2. Fix and test the current, interface-normal, and spin-polarization sign convention.

  3. Use literature xi_dl and xi_fl only as initial estimates from a comparable stack.

  4. Fit or measure both effective efficiencies for the actual stack.

  5. Sweep their uncertainty separately from mesh, timestep, and current uncertainty.

Python authoring

Complete stage-first example

# %% Study and execution policy
import fullmag as fm

nm = 1.0e-9
study = fm.study("prescribed_sot_reference")
study.engine("fdm")
study.device("cpu", precision="double")
study.mode("strict")
study.objects.mesh.defaults(cell_size=(2 * nm, 2 * nm, 2 * nm))

# %% Geometry, material, and initial state
body = study.geometry(fm.Box(40 * nm, 20 * nm, 4 * nm), name="film")
body.Ms = 8.0e5
body.Aex = 13.0e-12
body.alpha = 0.02
body.m = fm.texture.uniform(1.0, 0.0, 0.0)

# %% Canonical prescribed SOT
sot = fm.PrescribedSpinOrbitTorque(
    name="hm_sot",
    target=fm.RegionRef("film"),
    drive=fm.SignedScalarDrive(
        current_density_Apm2=-4.0e11,
        sigma=(0.0, 1.0, 0.0),
    ),
    xi_dl=0.12,
    xi_fl=-0.03,
    free_layer_thickness_m=1.5 * nm,
)
study.spin_torque(sot)

# %% Ordered run stage
study.stages.add_run(stage_id="drive", until=1.0e-12)

The sign in current_density_Apm2 is retained in ProblemIR. The authored sigma=(0, 1, 0) is normalized and serialized as sigma_hat.

What the example numbers produce

Using the constants embedded by Fullmag, the example inputs produce the following signed rates. These values check units and sign propagation; they do not predict a switching time by themselves.

Derived quantity

Example value

Interpretation

\(\Omega_0\)

\(-1.932\times10^{10}\,\mathrm{s^{-1}}\)

base rate set by current, \(M_s\), and \(t_F\)

\(\Omega_{\mathrm{DL}}\)

\(-2.318\times10^9\,\mathrm{s^{-1}}\)

Gilbert DL rate before damping conversion

\(\Omega_{\mathrm{FL}}\)

\(+5.795\times10^8\,\mathrm{s^{-1}}\)

Gilbert FL rate; positive because both \(J\) and xi_fl are negative

\(C_{\mathrm{DL}}\)

\(-2.329\times10^9\,\mathrm{s^{-1}}\)

explicit DL coefficient for \(\alpha=0.02\)

\(C_{\mathrm{FL}}\)

\(+5.329\times10^8\,\mathrm{s^{-1}}\)

explicit FL coefficient after DL/FL mixing

The \(1\,\mathrm{ps}\) stage in the example is deliberately short. A switching, oscillation, or relaxation study must choose the stage duration from the actual field, anisotropy, damping, geometry, and observable, then demonstrate temporal and spatial convergence.

Binding to an existing vector-current source

If the study already contains a current module named charge, replace the drive object only:

# %% Alternative object-level vector-current binding
drive = fm.VectorCurrentDrive(
    current_source="charge",
    drive_direction=(1.0, 0.0, 0.0),
    interface_normal=(0.0, 0.0, 1.0),
)

sot = fm.PrescribedSpinOrbitTorque(
    name="hm_sot_from_charge",
    target=fm.RegionRef("film"),
    drive=drive,
    xi_dl=0.12,
    xi_fl=-0.03,
    free_layer_thickness_m=1.5e-9,
)
sot.to_ir_module()

For these axes, \(\hat{\boldsymbol\sigma}=\hat{\mathbf z}\times\hat{\mathbf x} =\hat{\mathbf y}\) and only the \(x\) projection of the named current contributes. VectorCurrentDrive has no independent envelope argument; timing belongs to the named current source.

Constructor reference

Python

Type

Default

SI unit

Validation

Meaning

Backend support

ProblemIR

PrescribedSpinOrbitTorque.name

str

required

\(1\)

non-empty

stable module ID

all prescribed-SOT lanes

spin_torque_modules[].id

PrescribedSpinOrbitTorque.target

RegionRef

required

\(1\)

exact RegionRef resolving to magnetic target

torque target

all prescribed-SOT lanes

spin_torque_modules[].target

PrescribedSpinOrbitTorque.drive

SignedScalarDrive or VectorCurrentDrive

required

\(1\)

exact canonical drive type

signed current and polarization definition

all prescribed-SOT lanes after planning

spin_torque_modules[].drive

PrescribedSpinOrbitTorque.xi_dl

float

required

\(1\)

finite

signed damping-like efficiency

all prescribed-SOT lanes

spin_torque_modules[].xi_dl

PrescribedSpinOrbitTorque.xi_fl

float

0.0

\(1\)

finite

signed field-like efficiency

all prescribed-SOT lanes

spin_torque_modules[].xi_fl

PrescribedSpinOrbitTorque.free_layer_thickness_m

float

required

\(\mathrm{m}\) (m)

finite and positive

physical free-layer thickness

all prescribed-SOT lanes

spin_torque_modules[].free_layer_thickness_m

SignedScalarDrive.current_density_Apm2

float

required

\(\mathrm{A\,m^{-2}}\) (A/m^2)

finite; sign retained

prescribed scalar current amplitude

all prescribed-SOT lanes

spin_torque_modules[].drive.current_density_Apm2

SignedScalarDrive.sigma

Sequence[float]

required

\(1\)

finite nonzero three-axis vector; normalized

authored spin-polarization direction

all prescribed-SOT lanes

spin_torque_modules[].drive.sigma_hat

SignedScalarDrive.envelope

TimeEnvelope or None

None

\(1\)

canonical supported envelope type

scalar time multiplier

bounded prescribed-SOT lanes

spin_torque_modules[].drive.envelope

VectorCurrentDrive.current_source

str

required

\(1\)

non-empty and resolvable named current source

vector-current producer

planner-resolved prescribed-SOT lanes

spin_torque_modules[].drive.current_source_id

VectorCurrentDrive.drive_direction

Sequence[float]

required

\(1\)

finite nonzero axis; normalized; not parallel to interface normal

signed current projection axis

planner-resolved prescribed-SOT lanes

spin_torque_modules[].drive.drive_direction

VectorCurrentDrive.interface_normal

Sequence[float]

required

\(1\)

finite nonzero axis; normalized; not parallel to drive direction

oriented nonmagnet-to-ferromagnet normal

planner-resolved prescribed-SOT lanes

spin_torque_modules[].drive.interface_normal

SpinOrbitTorque is a deprecated compatibility constructor. New scripts and canonical exports must use PrescribedSpinOrbitTorque.

ProblemIR contract

The scalar example lowers to the following module record:

{
  "kind": "prescribed_sot",
  "schema_version": "prescribed_sot.v1",
  "id": "hm_sot",
  "target": {"object_id": "film", "region_id": null},
  "formula_version": "prescribed_sot.fullmag.v1",
  "drive": {
    "kind": "signed_scalar",
    "current_density_Apm2": -400000000000.0,
    "sigma_hat": [0.0, 1.0, 0.0]
  },
  "xi_dl": 0.12,
  "xi_fl": -0.03,
  "free_layer_thickness_m": 1.5e-9
}

Validation fails closed for duplicate IDs, non-finite coefficients, non-positive thickness, unresolved targets or current sources, invalid axes, parallel vector axes, and incompatible envelope artifacts. The legacy wire formula prescribed_sot.legacy_fullmag.v0 is retained only for migration and is not the authoring contract documented here.

Round trip and failure semantics

The requested intent preserves the authored target, drive variant, signed values, axes, envelope, efficiencies, thickness, execution mode, device, and precision. The planner records resolved execution separately, including the selected lane and the projected signed current. Python and ProblemIR validation errors reject malformed or unresolved inputs before runtime. Strict unsupported combinations fail closed; they are not silently rebound to another solver or device. Provenance therefore keeps both the canonical authored module and the planner/runtime resolution.

Discrete realization

Solver

Device

Status

Evidence boundary

FDM

CPU

Partial

executable double-precision reference path, signed current, target mask, and envelope contracts; broad scientific qualification is not claimed

FDM

GPU

Partial

native CUDA implementation with fixed-trajectory CPU parity and bounded current-scaling tests when CUDA is available; no implicit CPU fallback

FEM

CPU

Partial

executable MFEM reference source with SI-prefactor, damping conversion, mask, and time-envelope checks

FEM

GPU

Partial

native CUDA RHS kernel with independent SI oracle and CPU comparison; device availability and wider production qualification remain separate gates

Partial means the interaction is executable in the bounded lanes above, not that every mesh, precision, integrator, or deployment route is production qualified.

FDM CPU

The reference evaluator consumes a per-cell active mask, local \(M_s\) and \(\alpha\), the signed scalar amplitude, normalized polarization, and the stage-time envelope.

FDM GPU

The native CUDA path selects prescribed_sot.fullmag.v1 explicitly and is bounded by fixed-trajectory CPU parity and current-scaling tests when a CUDA device is present.

FEM CPU

The MFEM local-interaction path evaluates the same SI prefactor at magnetic nodes, applies the active mask, and performs the Gilbert-to-explicit conversion once.

FEM GPU

The CUDA RK source adds the canonical local RHS on device. Its bounded contract checks the independent SI oracle, active-mask exclusion, and CPU parity; this does not by itself qualify every runtime or mesh configuration.

Validation requirements

A trustworthy SOT result should demonstrate all of the following for the chosen backend and device:

  • exact SI prefactor for a single cell or node;

  • odd scaling under current reversal;

  • independent DL-only and FL-only basis-vector cases;

  • the \(\alpha\)-dependent Gilbert-to-explicit coefficient mixing;

  • target-mask exclusion and zero contribution outside the magnetic target;

  • envelope value at stage time, including retry or rollback behavior;

  • CPU/GPU parity on the same trajectory when GPU execution is claimed;

  • no silent CPU fallback for a strict GPU request.

Limitations

  • xi_dl and xi_fl are effective reduced-model inputs, not independently solved bulk and interface observables.

  • The model cannot predict spin accumulation, spin backflow, diffusion-length effects, interface hot spots, or a self-consistent inverse spin Hall response.

  • A spatially resolved SHE stack must use the separate drift-diffusion transport model.

  • Published backend statuses are bounded evidence statements, not universal production qualification for every precision, integrator, device, and deployment route.

Implementation mapping

Layer

File and stable symbol

Responsibility

Python API

packages/fullmag-py/src/fullmag/model/spin_torque.py, class PrescribedSpinOrbitTorque

validates module arguments and emits canonical v1 ProblemIR

Scalar drive

same file, class SignedScalarDrive

preserves signed current, normalizes sigma, validates envelope

Vector drive

same file, class VectorCurrentDrive

validates axes and emits named-current binding

ProblemIR

crates/fullmag-ir/src/study.rs, PrescribedSotV1DriveIR

owns tagged drive variants and formula fields

Planner

crates/fullmag-plan/src/spin_torque.rs, resolve_sot_fields

resolves current projection, polarization, target, and lane eligibility

FDM CPU

crates/fullmag-runner/src/fdm/cpu/reference/interactions.rs, build_sot

maps the plan into the CPU evaluator configuration

FDM GPU

crates/fullmag-runner/src/fdm/gpu/cuda/native.rs, ffi_prescribed_sot_formula

selects canonical versus legacy native CUDA formula

FEM CPU

backends/fem/cpu/mfem/interactions/sot.cpp, add_sot_rhs_aos

evaluates the canonical SI torque and damping conversion

FEM GPU

backends/fem/gpu/cuda/integrators/rk/rk_sot_torque.cu, fullmag_cuda_add_prescribed_sot_rhs

adds the canonical source to the device RHS

UI

apps/control-room/src/modules/inspector/panels/SpinAuthoringInspector.tsx, SpinAuthoringInspector

exposes prescribed SOT and its DL/FL efficiencies

Scientific bibliography

  • L. Liu et al., “Current-Induced Switching of Perpendicularly Magnetized Magnetic Layers Using Spin Torque from the Spin Hall Effect,” Physical Review Letters 109, 096602 (2012), doi:10.1103/PhysRevLett.109.096602.

  • K. Garello et al., “Symmetry and magnitude of spin-orbit torques in ferromagnetic heterostructures,” Nature Nanotechnology 8, 587-593 (2013), doi:10.1038/nnano.2013.145. Experimental basis for treating DL-like and FL-like torques as separately measured, stack-dependent quantities.

  • P. M. Haney et al., “Current induced torques and interfacial spin-orbit coupling: Semiclassical modeling,” Physical Review B 87, 174411 (2013), doi:10.1103/PhysRevB.87.174411. Theoretical context for bulk, interfacial, Boltzmann, and drift-diffusion interpretations.

  • M.-H. Nguyen, D. C. Ralph, and R. A. Buhrman, “Spin Torque Study of the Spin Hall Conductivity and Spin Diffusion Length in Platinum Thin Films with Varying Resistivity,” Physical Review Letters 116, 126601 (2016), doi:10.1103/PhysRevLett.116.126601. Reports \(\xi_{\mathrm{DL}}^j=0.12\) at the stated Pt thickness range and demonstrates thickness/resistivity dependence.

  • A. Manchon et al., “Current-induced spin-orbit torques in ferromagnetic and antiferromagnetic systems,” Reviews of Modern Physics 91, 035004 (2019), doi:10.1103/RevModPhys.91.035004.

Source-code index

Claim

Path

Symbol

Responsibility and evidence

Python torque API

packages/fullmag-py/src/fullmag/model/spin_torque.py

class PrescribedSpinOrbitTorque

canonical validation and ProblemIR lowering

Scalar drive

packages/fullmag-py/src/fullmag/model/spin_torque.py

class SignedScalarDrive

signed current, normalized polarization, envelope validation

Vector drive

packages/fullmag-py/src/fullmag/model/spin_torque.py

class VectorCurrentDrive

axes and named-current binding

ProblemIR

crates/fullmag-ir/src/study.rs

PrescribedSotV1DriveIR

canonical tagged drive variants

Planner

crates/fullmag-plan/src/spin_torque.rs

resolve_sot_fields

projection, target, envelope, and executable fields

FDM CPU

crates/fullmag-runner/src/fdm/cpu/reference/interactions.rs

build_sot

CPU evaluator configuration

FDM GPU

crates/fullmag-runner/src/fdm/gpu/cuda/native.rs

ffi_prescribed_sot_formula

canonical native formula selection

FEM CPU

backends/fem/cpu/mfem/interactions/sot.cpp

add_sot_rhs_aos

SI torque and damping conversion

FEM GPU

backends/fem/gpu/cuda/integrators/rk/rk_sot_torque.cu

fullmag_cuda_add_prescribed_sot_rhs

device RHS source

Python tests

packages/fullmag-py/tests/test_prescribed_sot.py

class TestPrescribedSpinOrbitTorque

exact JSON and fail-closed authoring tests

Planner test

crates/fullmag-plan/src/spin_torque.rs

canonical_prescribed_sot_vector_binding_preserves_axes_and_reverses_signed_projection

signed vector projection contract

FDM GPU test

crates/fullmag-runner/src/fdm/gpu/cuda/native.rs

native_fdm_prescribed_sot_matches_cpu_reference_for_fixed_trajectory_when_cuda_is_available

bounded CUDA/CPU trajectory parity

FEM GPU test

backends/fem/tests/cuda_sot_contract.cpp

main

independent oracle and CPU/CUDA contract runner

Control Room

apps/control-room/src/modules/inspector/panels/SpinAuthoringInspector.tsx

SpinAuthoringInspector

prescribed-SOT authoring fields