Dominik Demuth 5acbaaa5f8 Comments
2026-03-08 15:33:56 +01:00
2026-03-08 15:33:56 +01:00
2024-11-28 14:50:26 +01:00
2024-12-15 18:34:05 +01:00
2024-11-28 14:50:26 +01:00
2024-11-30 16:15:38 +01:00
2024-11-04 19:39:53 +01:00
2024-12-15 18:34:05 +01:00
2024-12-15 18:34:05 +01:00
2024-12-15 18:34:05 +01:00

NMR Random Walk Simulation

Simulate solid-state NMR spectra and stimulated echo (STE) decays using random walk models.

Build

Requires CMake 3.18+, a C++17 compiler, and OpenMP.

cmake -B build
cmake --build build

The executable is build/src/rwsim.

Running

./build/src/rwsim /path/to/config.txt MotionModel DistributionModel --ste --spectrum -ARG1 1 -ARG2 2

Three positional arguments are required: the path to a configuration file, the motion model name, and the distribution model name. Set --ste and/or --spectrum to run stimulated echo or spectrum simulations. Any parameter from the configuration file can be overridden on the command line, e.g. -tau 1e-3.

Use -seed 42 for reproducible results. Without a seed, a random one is used.

Output files are overwritten if a simulation with the same parameters is run again.

Configuration file

Change delta, eta, mixing times, echo times, etc. in this file. If a parameter appears multiple times, only the last value is used.

General parameters

Parameter Description
num_walker Number of trajectories
delta Anisotropy parameter in Hz
eta Asymmetry parameter

Distribution of correlation times

Model CLI name Parameters
Delta distribution (same tau for all walkers) Delta tau (jump time in s)
Log-normal distribution LogNormal tau (peak time in s), sigma (width)

Motion models

Model CLI name Parameters
Isotropic random jump RandomJump
Isotropic jump by fixed angle IsotropicAngle angle (degrees)
Bimodal angle distribution BimodalAngle angle1, angle2 (degrees), probability1 (01)
Tetrahedral 4-site jump FourSiteTetrahedral
Octahedral 6-site jump (C3) SixSiteOctahedralC3
N-site jump on cone NSiteConeJump num_sites, chi (cone angle, degrees)
Random jump on cone RandomJumpOnCone angle (cone angle)
Wobbling in cone ConeWobble angle (cone angle)

Spectrum parameters

Parameter Description
dwell_time Acquisition dwell time in s
num_acq Number of acquisition points
techo_start First echo time in s
techo_stop Last echo time in s
techo_steps Number of echo times

STE parameters

Parameter Description
tevo_start First evolution time in s
tevo_stop Last evolution time in s
tevo_steps Number of evolution times
tmix_start First mixing time in s
tmix_stop Last mixing time in s
tmix_steps Number of mixing times (log-spaced)
tpulse4 Delay of 4th pulse in s

Architecture

The simulation is built around three abstractions:

Dynamics

Dynamics (src/dynamics/base.h) produces trajectory steps — pairs of {dt, omega} representing a waiting time and the NMR frequency after a jump. This is the core interface for defining physical models.

DecoupledDynamics wraps a separate motion model and time distribution, calling them independently. This covers all existing models.

To implement a coupled model where motion and time are interdependent (e.g. jump angle affects waiting time, or position-dependent dynamics), implement the Dynamics interface directly:

class MyModel : public Dynamics {
    void initialize(std::mt19937_64& rng) override { /* set initial state */ }
    Step next(std::mt19937_64& rng) override {
        // draw angle, compute rate from angle, draw wait time from rate
        return {dt, omega};
    }
    // ... clone(), setParameters(), etc.
};

Experiment

Experiment (src/experiments/base.h) defines how trajectory data is turned into observables:

  • setup(params) — configure time axes, allocate accumulators
  • accumulate(trajectory) — process one walker's trajectory
  • save(directory) — write results to files
  • clone() / merge() — for thread-parallel accumulation

Existing experiments: SpectrumExperiment, STEExperiment.

Simulation runner

run_simulation() (src/sims.h) connects a Dynamics and an Experiment:

  1. Sets parameters on both
  2. Generates trajectories in parallel (OpenMP, one clone per thread)
  3. Each thread accumulates into its own experiment clone
  4. Merges thread-local results
  5. Saves output

The walker loop is parallelized with OpenMP using static scheduling for deterministic reproducibility with a given seed and thread count.

Description
No description provided
Readme GPL-3.0 Cite this repository 472 KiB
Languages
C++ 82.1%
Python 15.9%
CMake 1.9%
Shell 0.1%