Core Module¶
The core module provides fundamental constants and operators for NV center simulation.
Physical Constants¶
Physical constants and unit conversions for NV center simulation.
Unit Convention¶
- This library uses practical laboratory units for the API:
Frequencies: GHz, MHz, kHz (not Hz)
Magnetic fields: mT (not Tesla)
Lengths: µm, nm (not meters)
Internally, all values are converted to rad/s for the Hamiltonian.
Why rad/s?¶
The Hamiltonian H has units of energy. In quantum mechanics we work with ℏ=1, so that energy = frequency × 2π.
E = ℏω = ω (for ℏ=1)
Therefore, the Hamiltonian matrix elements are in rad/s.
Example
>>> from sim.core.constants import GHZ, MHZ, MT
>>> D = 2.87 * GHZ # ZFS in rad/s
>>> B = 10 * MT # 10 mT in Tesla
- sim.core.constants.GHZ = 6283185307.179586¶
D = 2.87 * GHZ
- Type:
1 GHz in rad/s. Usage
- sim.core.constants.MHZ = 6283185.307179586¶
A = 2.14 * MHZ
- Type:
1 MHz in rad/s. Usage
- sim.core.constants.KHZ = 6283.185307179586¶
1 kHz in rad/s.
- sim.core.constants.HZ = 6.283185307179586¶
1 Hz in rad/s.
- sim.core.constants.MT = 0.001¶
B = 10 * MT
- Type:
1 millitesla in Tesla. Usage
- sim.core.constants.UT = 1e-06¶
1 microtesla in Tesla.
- sim.core.constants.GAUSS = 0.0001¶
1 Gauss in Tesla (CGS unit, sometimes still used).
- sim.core.constants.UM = 1e-06¶
1 micrometer in meters.
- sim.core.constants.NM = 1e-09¶
1 nanometer in meters.
- sim.core.constants.ANGSTROM = 1e-10¶
1 Ångström in meters.
- sim.core.constants.HBAR = 1.054571817e-34¶
Reduced Planck constant ℏ = h/(2π) in J·s.
- sim.core.constants.H_PLANCK = 6.62607015e-34¶
Planck constant h in J·s.
- sim.core.constants.MU_B = 9.274010078e-24¶
Bohr magneton μ_B = eℏ/(2m_e) in J/T.
- sim.core.constants.MU_N = 5.050783746e-27¶
Nuclear magneton μ_N = eℏ/(2m_p) in J/T.
- sim.core.constants.KB = 1.380649e-23¶
Boltzmann constant k_B in J/K.
- sim.core.constants.E_CHARGE = 1.602176634e-19¶
Elementary charge e in Coulomb.
- sim.core.constants.G_E = 2.0028¶
Electron g-factor for NV center (close to free electron g≈2.002).
- sim.core.constants.G_N14 = 0.4038¶
N14 nuclear g-factor.
- sim.core.constants.G_C13 = 1.4048¶
C13 nuclear g-factor.
- sim.core.constants.GAMMA_E = 176128235979.76355¶
Electron gyromagnetic ratio γ_e in rad/(s·T).
- For a magnetic field B, the Larmor frequency is:
ω_L = γ_e * B
- At B = 1 mT:
ω_L = 1.761e11 * 1e-3 = 1.761e8 rad/s ≈ 28 MHz
- sim.core.constants.GAMMA_N14 = 19339664.153330963¶
N14 nuclear gyromagnetic ratio in rad/(s·T).
- sim.core.constants.GAMMA_C13 = 67281724.1272891¶
C13 nuclear gyromagnetic ratio in rad/(s·T).
- sim.core.constants.D_GS = 18032741831.605415¶
2.87 GHz (in rad/s).
This is the energy difference between ms=0 and ms=±1.
- Type:
ZFS D-parameter in ground state
- sim.core.constants.D_ES = 8922123136.195013¶
1.42 GHz (in rad/s).
- Type:
ZFS D-parameter in excited state
- sim.core.constants.A_PARALLEL_N14 = -13446016.557364315¶
-2.14 MHz (in rad/s).
- Type:
Parallel hyperfine coupling for N14
- sim.core.constants.A_PERP_N14 = -16964600.329384882¶
-2.70 MHz (in rad/s).
- Type:
Perpendicular hyperfine coupling for N14
- sim.core.constants.P_N14 = -31415926.53589793¶
-5.0 MHz (in rad/s).
- Type:
N14 quadrupole parameter
- sim.core.constants.ghz_to_rads(freq_ghz)[source]¶
Convert frequency from GHz to rad/s.
Examples
>>> ghz_to_rads(2.87) # ZFS 18032327871.53...
- sim.core.constants.zeeman_splitting_mhz(B_mt, g=2.0028)[source]¶
Calculate the Zeeman splitting in MHz for a given B-field.
- The splitting between ms=+1 and ms=-1 is:
Δf = 2 * γ * B / (2π) = 2 * g * μ_B * B / h
- Parameters:
- Returns:
Splitting in MHz
- Return type:
Examples
>>> zeeman_splitting_mhz(10) # 10 mT 560.6... # approximately 56 MHz/mT * 10 mT
Unit Conversions¶
The library uses practical laboratory units for the API:
Frequencies: GHz, MHz, kHz
Magnetic fields: mT
Lengths: μm, nm
Internally, all values are converted to rad/s (with ℏ=1).
from sim.core.constants import GHZ, MHZ, MT
D = 2.87 * GHZ # ZFS in rad/s
B = 10 * MT # 10 mT in Tesla
A = 2.14 * MHZ # Hyperfine in rad/s
Available Constants¶
Unit Conversions:
GHZ: 1 GHz in rad/s (≈ 6.28×10⁹)MHZ: 1 MHz in rad/s (≈ 6.28×10⁶)KHZ: 1 kHz in rad/sMT: 1 mT in Tesla (10⁻³)
Fundamental Constants:
HBAR: Reduced Planck constant (1.055×10⁻³⁴ J·s)MU_B: Bohr magneton (9.274×10⁻²⁴ J/T)KB: Boltzmann constant (1.381×10⁻²³ J/K)
NV-Specific:
D_GS: Ground state ZFS (2.87 GHz)D_ES: Excited state ZFS (1.42 GHz)GAMMA_E: Electron gyromagnetic ratioA_PARALLEL_N14,A_PERP_N14: N14 hyperfine couplingsP_N14: N14 quadrupole parameter
Spin Operators¶
Spin-1 operators for NV center simulation.
This module provides the spin-1 matrices required for describing the electron spin (S=1) and N14 nuclear spin (I=1) in the NV center.
Physical Background¶
The NV center ground state is a spin triplet (S=1) with states |ms=+1>, |ms=0>, |ms=-1>. The spin operators satisfy the standard commutation relations:
[Sx, Sy] = i*Sz (and cyclic permutations) S² = S(S+1) = 2 for S=1
Basis Convention¶
All matrices are represented in the {|+1>, |0>, |-1>} basis, where Sz is diagonal with eigenvalues +1, 0, -1 on the diagonal.
18-Dimensional Hilbert Space¶
The full NV center Hilbert space is the tensor product:
- class sim.core.operators.Spin1Ops(Sx, Sy, Sz, Sp, Sm, I)[source]¶
Bases:
objectContainer for spin-1 operators.
- Sx¶
Spin-x operator (3×3 complex)
- Type:
np.ndarray
- Sy¶
Spin-y operator (3×3 complex)
- Type:
np.ndarray
- Sz¶
Spin-z operator (3×3 complex, diagonal)
- Type:
np.ndarray
- Sp¶
Raising operator S+ = Sx + i*Sy
- Type:
np.ndarray
- Sm¶
Lowering operator S- = Sx - i*Sy
- Type:
np.ndarray
- I¶
Identity matrix (3×3)
- Type:
np.ndarray
- sim.core.operators.spin1_operators()[source]¶
Create spin-1 operators in the {|+1>, |0>, |-1>} basis.
- The matrices satisfy:
[Sx, Sy] = i*Sz (and cyclic permutations)
S² = Sx² + Sy² + Sz² = 2*I (for S=1)
Sz|m> = m|m> for m ∈ {+1, 0, -1}
- Returns:
Dataclass containing Sx, Sy, Sz, S+, S-, and identity matrix
- Return type:
Examples
>>> ops = spin1_operators() >>> np.allclose(ops.Sx @ ops.Sy - ops.Sy @ ops.Sx, 1j * ops.Sz) True >>> np.linalg.eigvalsh(ops.Sz) array([-1., 0., 1.])
- sim.core.operators.extend_to_18x18(H_3x3)[source]¶
Extend a 3×3 electron spin Hamiltonian to the full 18×18 space.
The operator acts on the electron spin in BOTH manifolds (ground and excited) and leaves the nuclear spin unchanged.
- Mathematically:
H_18 = I_2 ⊗ H_3 ⊗ I_3
- where:
- Parameters:
H_3x3 (np.ndarray) – 3×3 Hamiltonian in the electron spin subspace
- Returns:
18×18 Hamiltonian in the full Hilbert space
- Return type:
np.ndarray
Notes
This extension is correct for terms like ZFS and Zeeman that act only on the electron spin and are identical in both electronic states (g and e).
Examples
>>> from sim.hamiltonian.terms import ZFS >>> zfs = ZFS(D=2.87) >>> H_3 = zfs._build_3x3() >>> H_18 = extend_to_18x18(H_3) >>> H_18.shape (18, 18)
- sim.core.operators.extend_electron_only(H_3x3, manifold='ground')[source]¶
Extend 3×3 to 18×18, acting only on ONE electronic manifold.
Unlike extend_to_18x18(), this operator acts ONLY on the ground state (|g>) OR the excited state (|e>), not both.
This is needed for terms that differ between g and e, e.g., different ZFS parameters in the excited state.
- Parameters:
- Returns:
18×18 Hamiltonian acting only on the chosen manifold
- Return type:
np.ndarray
Examples
>>> # ZFS only in ground state >>> H_gs = extend_electron_only(H_zfs_3x3, manifold="ground") >>> # Different ZFS in excited state >>> H_es = extend_electron_only(H_zfs_excited_3x3, manifold="excited") >>> H_total = H_gs + H_es
Spin-1 Operators¶
The spin1_operators() function returns a container with all standard spin-1 operators:
from sim.core.operators import spin1_operators
ops = spin1_operators()
Sx = ops.Sx # 3×3 spin-x matrix
Sy = ops.Sy # 3×3 spin-y matrix
Sz = ops.Sz # 3×3 spin-z matrix
Sp = ops.Sp # Raising operator S+
Sm = ops.Sm # Lowering operator S-
Properties:
Extending to 18×18¶
Operators can be extended to the full 18-dimensional Hilbert space:
from sim.core.operators import extend_to_18x18, extend_electron_only
# Acts on both g and e manifolds
H_18 = extend_to_18x18(H_3x3)
# Acts only on ground state
H_g = extend_electron_only(H_3x3, manifold="ground")
# Acts only on excited state
H_e = extend_electron_only(H_3x3, manifold="excited")
Nuclear Operators¶
Nuclear spin operators for NV center simulation.
This module provides spin-1/2 operators for C13 nuclear spins and utility functions for building tensor products in the extended Hilbert space.
Hilbert Space Structure¶
The full NV center Hilbert space is:
When including a C13 nuclear spin (I=1/2), this extends to:
However, for computational efficiency, C13 coupling is often treated in a block-diagonal approximation within the 18D space.
Spin-1/2 Operators¶
The Pauli matrices σ are related to spin operators by:
Ix = σx/2, Iy = σy/2, Iz = σz/2
The operators satisfy [Ii, Ij] = iε_ijk Ik.
- class sim.core.nuclear_operators.SpinHalfOps(Ix, Iy, Iz, Ip, Im, I)[source]¶
Bases:
objectContainer for spin-1/2 operators.
- Ix¶
Spin-x operator (2×2 complex)
- Type:
np.ndarray
- Iy¶
Spin-y operator (2×2 complex)
- Type:
np.ndarray
- Iz¶
Spin-z operator (2×2 complex, diagonal)
- Type:
np.ndarray
- Ip¶
Raising operator I+ = Ix + i*Iy
- Type:
np.ndarray
- Im¶
Lowering operator I- = Ix - i*Iy
- Type:
np.ndarray
- I¶
Identity matrix (2×2)
- Type:
np.ndarray
Examples
>>> ops = spin_half_operators() >>> np.allclose(ops.Ix @ ops.Iy - ops.Iy @ ops.Ix, 0.5j * ops.Iz) True >>> np.linalg.eigvalsh(ops.Iz) array([-0.5, 0.5])
- sim.core.nuclear_operators.spin_half_operators()[source]¶
Create spin-1/2 operators in the {|+1/2⟩, |-1/2⟩} basis.
- The matrices are:
Ix = (1/2) * σx = (1/2) * [[0, 1], [1, 0]] Iy = (1/2) * σy = (1/2) * [[0, -i], [i, 0]] Iz = (1/2) * σz = (1/2) * [[1, 0], [0, -1]]
- Returns:
Dataclass containing Ix, Iy, Iz, I+, I-, and identity
- Return type:
Examples
>>> ops = spin_half_operators() >>> # Check commutation relation [Ix, Iy] = i*Iz/2 >>> comm = ops.Ix @ ops.Iy - ops.Iy @ ops.Ix >>> np.allclose(comm, 0.5j * ops.Iz) True
>>> # Check I² = I(I+1) = 3/4 for I=1/2 >>> I_squared = ops.Ix @ ops.Ix + ops.Iy @ ops.Iy + ops.Iz @ ops.Iz >>> np.allclose(I_squared, 0.75 * ops.I) True
- sim.core.nuclear_operators.extend_9x9_to_18x18(H_9x9)[source]¶
Extend 9×9 matrix (electron ⊗ N14) to 18×18 full space.
The 9×9 operator acts on |ms⟩ ⊗ |mI_N14⟩ and is embedded in the full space as acting identically on both g and e manifolds.
- Mathematically:
H_18 = I_2 ⊗ H_9
where I_2 is the identity on |g/e⟩.
- Parameters:
H_9x9 (np.ndarray) – 9×9 matrix in electron spin ⊗ N14 nuclear spin space
- Returns:
18×18 matrix in full Hilbert space
- Return type:
np.ndarray
Notes
This is the correct extension for terms like hyperfine coupling that are identical in ground and excited states.
Examples
>>> H_9 = np.eye(9, dtype=complex) >>> H_18 = extend_9x9_to_18x18(H_9) >>> H_18.shape (18, 18) >>> np.allclose(H_18[:9, :9], H_9) True >>> np.allclose(H_18[9:, 9:], H_9) True
- sim.core.nuclear_operators.extend_9x9_to_18x18_manifold(H_9x9, manifold='ground')[source]¶
Extend 9×9 matrix to 18×18, acting only on one manifold.
Unlike extend_9x9_to_18x18(), this operator acts ONLY on the ground state OR excited state, not both.
- Parameters:
H_9x9 (np.ndarray) – 9×9 matrix in electron spin ⊗ N14 space
manifold (str) – “ground” for g manifold (indices 0-8) “excited” for e manifold (indices 9-17)
- Returns:
18×18 matrix acting only on chosen manifold
- Return type:
np.ndarray
Examples
>>> H_9 = np.eye(9, dtype=complex) >>> H_g = extend_9x9_to_18x18_manifold(H_9, "ground") >>> np.allclose(H_g[:9, :9], H_9) True >>> np.allclose(H_g[9:, 9:], 0) True
- sim.core.nuclear_operators.build_spin_spin_coupling(S_ops, I_ops, A_tensor)[source]¶
Build spin-spin coupling Hamiltonian H = S·A·I.
- Computes the tensor product:
H = Σ_ij A_ij (S_i ⊗ I_j)
- Parameters:
- Returns:
Coupling Hamiltonian of dimension (3*dim_I) × (3*dim_I)
- Return type:
np.ndarray
Notes
The tensor product S_i ⊗ I_j creates a matrix of size (3 × dim_I) × (3 × dim_I).
Examples
>>> from sim.core.operators import spin1_operators >>> S = spin1_operators() >>> I = spin_half_operators() >>> A = np.diag([1e6, 1e6, 2e6]) # Axial tensor >>> H = build_spin_spin_coupling( ... (S.Sx, S.Sy, S.Sz), ... (I.Ix, I.Iy, I.Iz), ... A ... ) >>> H.shape (6, 6)
- sim.core.nuclear_operators.dipolar_tensor(r_vec, gamma_1, gamma_2)[source]¶
Compute dipolar coupling tensor between two spins.
The dipolar interaction tensor is:
A_dip = (μ₀/4π) × (γ₁γ₂ℏ²/r³) × (I - 3r̂r̂ᵀ)
In frequency units (rad/s):
A_dip = (μ₀γ₁γ₂ℏ)/(4πr³) × (I - 3r̂r̂ᵀ)
- Parameters:
- Returns:
3×3 dipolar tensor in rad/s
- Return type:
np.ndarray
Notes
The tensor is traceless and symmetric.
Examples
>>> from sim.core.constants import GAMMA_E, GAMMA_C13, NM >>> r = np.array([0.154, 0, 0]) * NM # C-C bond length >>> A = dipolar_tensor(r, GAMMA_E, GAMMA_C13) >>> np.isclose(np.trace(A), 0) # Traceless True >>> np.allclose(A, A.T) # Symmetric True
The nuclear operators module provides spin-1/2 operators for C13 and utilities for calculating dipolar hyperfine tensors.