A fully open-source kinetic Monte Carlo (kMC) simulator for materials deposition, annealing, and memristive device modeling
Warning
Kinetix aims to bridge materials science and device physics by providing a transparent, modular, and accessible platform for multiscale simulation of emerging electronic devices, ideal for research in neuromorphic computing, memristors, and thin-film processing.
Kinetix is a Python-based, open-source simulation framework (MIT License) that enables atomic-scale modeling of:
- Material Deposition: Nucleation and growth of thin films of fcc metals (e.g., Ni, Pd, Ag, Pt, Au, Cu) from a kinetic gas-phase source, including substrateβmetal interaction effects on growth morphology.
- Vacuum Annealing: Thermal evolution, defect passivation, and surface morphology relaxation of deposited films.
- Resistive Switching: Formation and dissolution of conductive filaments in valence-change (VCM) and electrochemical (ECM) memristors, with electrode scavenging of mobile ions.
- Grain Boundary (GB) Engineering: Spatially resolved modification of activation energies at grain boundaries β vertical planar, cylindrical, and triple-junction geometries β including direction-dependent migration barriers that distinguish entry into, exit from, and within-GB hops.
- Multiphysics Coupling: Real-time feedback between electrostatics (Poisson), Joule heating (heat equation), and stochastic defect kinetics, with field-assisted migration barriers for charged species.
- Superbasin Acceleration: Local-superbasin event grouping to escape rare-event bottlenecks in deposition, annealing, and device simulations.
Caution
Simulation-type maintenance status: the electronic device path (simulation_type: "electronic_device", used by the resistive-switching presets) is the actively maintained code path and the one exercised by the test suite. Deposition and annealing remain available but are legacy paths that are not covered by the automated tests β they may require restoration before production use (they still pass configuration as plain containers rather than typed config objects).
Each simulation is driven by the command-line interface in kinetix/cli.py, which calls System_state.step_kmc() (kinetix/lattice/crystal.py) in the following loop:
- Lattice Generation: Constructs the 3D atomic grid (lattice, interfaces, and grain boundaries) with
pymatgen, generates interstitial sites using a Voronoi method, and builds the finite-element mesh withgmsh. - FEM Solvers: Computes the electric potential (Poisson) and, when enabled, the temperature field (heat equation) for the current defect configuration and electrode potentials using DOLFINx/FEniCS.
- Energy Landscape Update: Calculates site-resolved activation energies for all possible defect events (migration, generation, recombination), applying GB barrier modifications (linear or direction-dependent) and electric-field corrections for charged species, and lazily recomputes only the affected rates.
- kMC Step: Selects an event with the rejection-free BKL (Bortz-Kalos-Lebowitz) algorithm implemented on a balanced binary tree of transition rates, advances the simulation time, and updates the lattice.
- Loop: Repeats steps 2β4 β re-solving the fields at every voltage update for device simulations β until the deposition/annealing target or the applied voltage protocol is completed.
Note
The Poisson/heat solvers only run on Linux (guarded by platform.system() == 'Linux' in kinetix/cli.py). On other platforms there is no FEM field feedback, while pure deposition/annealing simulations continue to run.
Kinetix couples three layers of physics in every device simulation: the electrostatic potential, the temperature field, and the stochastic defect kinetics.
The electric potential
Charges are spread onto the FEM mesh as Gaussians (epsilon_gaussian_charge). When a conductive filament bridges the electrodes, the solver instead enforces current continuity,
The steady-state temperature field
with Joule-heating source
Each elementary event
with attempt frequency data/parameters/activation_energies/. Charged-species barriers may be reduced by the local electric field (
Kinetix is driven by modular YAML and JSON configuration files under data/parameters/. This separation allows you to swap materials, defect chemistries, and device geometries without modifying the Python core. Every simulation is assembled by a preset file in data/parameters/presets/.
data/parameters/
βββ defects/ # Mobile species, charges, and enabled events (YAML)
βββ reactions/ # Redox, recombination, and passivation reactions (YAML)
βββ electrical/ # Voltage protocols and current models (YAML)
βββ grain_boundaries/ # GB geometry and barrier modifications (YAML)
βββ activation_energies/ # Base DFT/experimental activation energies (JSON)
βββ presets/ # Master files assembling a complete simulation (YAML)
| Subdirectory | Purpose | Example files |
|---|---|---|
defects/ |
Species, charge states, sublattices, enabled events, scavenging | VCM_HfO2_defects_config.yaml, PZT_ZrPbO3_defects_config.yaml, ECM_CeO2_Ag_defects_config.yaml |
reactions/ |
Redox, recombination, and passivation reactions | VCM_HfO2_reactions.yaml, PZT_reactions_H_Ovac_passivation.yaml |
electrical/ |
Voltage protocols (CONSTANT, RAMP_CYCLE, ZERO_HOLD) and current models (Schottky, ohmic) |
electrical_RAMP_CYCLE.yaml, electrical_CONSTANT_STEP.yaml, electrical_ZERO_HOLD.yaml |
grain_boundaries/ |
Planar/cylindrical GB geometry and barrier models | gb_cylindrical_VCM_HfO2.yaml, gb_vertical_planar.yaml, gb_cylindrical_PZT_ZrPbO3.yaml |
activation_energies/ |
Base activation energies per species (JSON) | VCM_HfO2.json, PZT_ZrPbO3.json, activation_energies_deposition.json |
presets/ |
Master YAML files referencing components, materials, mesh, and solvers | PZT_ZrTi_PbO3_2.yaml, VCM_HfO2_cylindrical_gb.yaml, PZT_ZrTi_PbO3_2_annealing.yaml |
The following is a real snippet from data/parameters/presets/VCM_HfO2_cylindrical_gb.yaml:
# Master file referencing all component configurations
material:
name: "HfO2"
mp_id: "mp-550893" # Materials Project ID
radius_neighbors: 3.9
epsilon_r: 23.0
crystal:
size: [50, 50, 50] # Angstroms (x, y, z)
miller_indices: [0, 0, 1] # Surface orientation
components:
defects: "defects/VCM_HfO2_defects_config.yaml"
reactions: "reactions/VCM_HfO2_reactions.yaml"
grain_boundaries: "grain_boundaries/gb_cylindrical_VCM_HfO2.yaml"
electrical: "electrical/electrical_RAMP_CYCLE.yaml"
settings:
simulation_type: "electronic_device"
technology: "VCM"
activation_energies: "activation_energies/VCM_HfO2.json"
superbasin:
enabled_superbasin: true
n_search_superbasin: 50
time_step_limits: 1.0e-4 # s
E_min: 0.5 # eV
poisson:
solve_Poisson: true
screening_factor: 0.01
conductivity:
conductive_filament: 1e5 # S/m
dielectric: 1.0e-1 # S/m
heat:
solve_heat: true
kappa_dielectric: 1.1 # W/m-K
kappa_metal: 23 # W/m-K
use_thermal_inertia: trueKinetix is built entirely on free and open-source software. The full pinned environment is provided in environment.yml (conda). Key packages:
| Package | Version (pinned) | Role |
|---|---|---|
| pymatgen | 2025.10.7 | Crystal structures and properties from the Materials Project |
| DOLFINx (FEniCS Project) | 0.8.0 | Finite-element Poisson and heat solvers |
| gmsh | 4.13.1 | Automated 3D mesh generation |
| SciPy | 1.15.1 | Spatial queries (cKDTree), physical constants |
| NumPy | 1.26.4 | Grid and vectorized lattice operations |
| mpi4py + MPICH | 4.0.1 / 4.2.3 | MPI parallelization |
| pandas / Matplotlib / Seaborn / PyVista | 2.2.2 / 3.10.0 / 0.13.2 / 0.44.2 | Data analysis, plotting, 3D visualization |
| pytest | 9.0.2 | Automated test suite |
| Python | 3.12.8 | β |
Additional analysis/visualization packages (scikit-image, imageio, tifffile, mp-pyrho, pymatgen-analysis-defects) are installed through the pip: section of the same file.
Note
License: Kinetix is released under the MIT License β free to use, modify, and distribute, with attribution. See LICENSE for full terms.
Kinetix relies on a heavy scientific stack (DOLFINx, gmsh, MPI, pymatgen) that is easiest to install through the provided conda environment file, environment.yml.
Note
environment.yml was generated on Linux (e.g., for HPC use) and pins some Linux-specific builds (gcc_linux-64, binutils_linux-64, etc.). DOLFINx and the MPI-based solvers are best supported on Linux/macOS.
- Clone the repository:
git clone https://github.com/aldanads/Kinetix.git cd Kinetix - Create the conda environment from
environment.yml(this installs the full FEniCS/DOLFINx + MPI stack and can take several minutes):Mamba also works as a faster drop-in replacement:conda env create -f environment.yml
mamba env create -f environment.yml
- Activate the environment. Its name (
Kinetix) is set by thename:field at the top ofenvironment.yml:conda activate Kinetix
- (Optional) Verify the key dependencies import correctly:
python -c "import dolfinx, gmsh, pymatgen, mpi4py; print('Environment OK')"
The conda environment above is the recommended way to obtain the full scientific stack (FEniCS/DOLFINx, PETSc, MPI, gmsh) β pip alone cannot provide these builds reliably. Once the environment exists, install Kinetix itself as a proper Python package:
conda activate Kinetix
# Development install (editable, includes pytest/ruff/pre-commit)
pip install -e ".[dev]"
# ... or, for end users, a regular install
pip install .
# Optional: MACE-NEB calculator extras (ase, mace-torch, torch)
pip install -e ".[mace]"Kinetix fetches crystal structures and material properties (density, dielectric constants, etc.) directly from the Materials Project via pymatgen. This requires a free personal API key.
- Log in (or register) at the Materials Project and copy your API key from your account dashboard.
- Copy the provided template to create your own local
config.jsonin the project root:cp config.template.json config.json
- Open
config.jsonand replace the placeholder with your key:{ "api_key": "YOUR_API_KEY_HERE" }
Important
config.json is listed in .gitignore and must never be committed β it holds your personal, secret API key. Only the placeholder file, config.template.json, is tracked in the repository.
Kinetix loads this file automatically at runtime (kinetix/configs/config_loader.py β get_api_key()), so no extra command-line flags are needed once config.json exists in the project root. Alternatively, export MP_API_KEY as an environment variable (it takes priority over config.json) β convenient on clusters and for installed copies of the package.
Kinetix is installed as a Python package and can be launched in three ways:
| Invocation | When to use |
|---|---|
kinetix <sim_id> |
Recommended β console script created by pip install (entry point kinetix.cli:main) |
python -m kinetix <sim_id> |
Module invocation β equivalent behavior, useful when the console script is not on PATH |
python -m kinetix.cli <sim_id> |
Direct CLI module β handy for debugging |
Note
The package must be installed first (see Installation): pip install -e ".[dev]" for development, or pip install . for end users.
The CLI drives the kMC loop for the material/defect/reaction/electrical setup described in a preset (see data/parameters/presets/). To see all available options:
kinetix --help| Argument | Type | Description |
|---|---|---|
sim_id (positional, optional) |
int |
Simulation ID used to index the parameter-sweep array in get_parameters_from_sim_id() (default: 0) |
--config, -c |
str |
Preset YAML file name or path (default: the PZT device preset, PZT_ZrTi_PbO3_2.yaml) |
--profile |
flag | Wrap the run in cProfile; prints the top 15 functions by cumulative time and saves kmc_profile.prof |
--allow-multi-rank-profile |
flag | Override the single-core enforcement for --profile (results are distorted by MPI synchronization) |
--dry-run |
flag | Print the resolved arguments and exit before initializing meshes or the kMC lattice |
Note
Always pass --config explicitly: the argparse default currently expands to a name that does not match an on-disk preset, while main() itself defaults to PZT_ZrTi_PbO3_2.yaml. With --config, both code paths resolve to the same file.
conda activate Kinetix
kinetix 0 --config PZT_ZrTi_PbO3_2.yamlsim_id indexes the sweep array defined in get_parameters_from_sim_id() (initial vacancy concentration Γ temperature Γ hydrogen-generation rate; edit that function to customize the mapping). Use --config to select a different preset:
kinetix 4 --config VCM_HfO2_cylindrical_gb.yamlThe DOLFINx-based Poisson/heat solvers run across MPI ranks, while the kMC lattice is evolved on rank 0 and synchronized through broadcasts (kinetix/utils/mpi_context.py). To run on multiple ranks:
mpiexec -n 8 kinetix 4 --config PZT_ZrTi_PbO3_2.yamlUse the --profile flag to wrap the execution in cProfile. This prints the top 15 functions by cumulative time and saves the full profile to kmc_profile.prof.
Warning
Single-core enforcement: cProfile is a single-process profiler. If --profile is used with more than one MPI rank, only rank 0 is instrumented, and the profiler's overhead creates artificial MPI wait times that distort the bottleneck analysis. Kinetix therefore automatically aborts multi-rank profiling runs (see _enforce_single_rank_profiling() in kinetix/cli.py).
Profile on a single core:
kinetix 0 --config PZT_ZrTi_PbO3_2.yaml --profileIf you explicitly want to profile a multi-rank run despite the distortion, use the override flag:
mpiexec -n 4 kinetix 0 --profile --allow-multi-rank-profileNote
In the --profile code path, main() is invoked with default arguments, so the run always uses the default PZT preset even when --config is supplied. Use a single-core profiled run to benchmark a specific preset.
To verify your command-line arguments without initializing the heavy FEM meshes or the kMC lattice:
kinetix 4 --config PZT_ZrTi_PbO3_2.yaml --dry-runscripts/hpc/pbs_template.sh is an example PBS submission script with job-array support (#PBS -t 0-10); PBS_ARRAYID becomes sim_id, and the CONFIG_FILE, PYTHON_EXEC, MPI_EXEC, and #PBS resource directives are edited at the top of the script before submission:
qsub pbs_template.shCluster-specific notes (FEniCSx JIT compilation, GCC β₯ 9.0, shared .dolfin_cache) are documented in scripts/hpc/README.md, and a single-core profiling job script is provided at scripts/hpc/profile_job.sh.
Simulation outputs (crystal snapshots, saved state, IV curves) are written under the program/ and output/ subdirectories of Sim_<id> folders created in the preset's output_path.
The test suite lives in tests/ and covers the FEM Poisson and heat solvers, the shared FEM solver base class, grain-boundary barrier/charge modifications, PBC-aware migration pathways, and loadability of every shipped preset:
tests/
βββ conftest.py # Pytest configuration (markers, --runslow opt-in flag)
βββ test_FEMSolver.py # FEM solver base class
βββ test_poisson_solver.py # Poisson solve, charge spreading, boundary conditions
βββ test_heat_solver.py # Steady-state heat + thermal relaxation
βββ test_gb_charge_and_state_transfer.py # GB barriers and defect state transfer
βββ test_migration_pathways.py # PBC neighbor finding and pathway keys
βββ test_mace_adapter.py # MACE-NEB calculator adapter (slow pathway sweeps need --runslow)
βββ test_percolation.py # Island percolation analysis
βββ test_presets.py # Every shipped preset loads via SimulationConfig.from_yaml
Run the suite from the project root (inside the Kinetix environment):
conda activate Kinetix
python -m pytest tests/The tests use lightweight mocks and do not require an MPI cluster or GPU hardware.
Kinetix/
βββ pyproject.toml # Package metadata, dependencies, CLI entry point
βββ environment.yml # Conda environment (pinned builds)
βββ config.template.json # Template for the Materials Project API key
βββ LICENSE # MIT license
βββ kinetix/ # Core Python package
β βββ cli.py # CLI entry point: argparse + kMC driver loop
β βββ __main__.py # Enables `python -m kinetix`
β βββ __init__.py # Package version and public API re-exports
β βββ initialization.py # Builds crystal, configs, solvers, output paths
β βββ material_fetcher.py # Materials Project structure/property retrieval
β βββ configs/ # Typed YAML loaders (simulation, defects, electrical, ...)
β βββ lattice/ # Crystal_Lattice, Site, GrainBoundary, island, cluster
β βββ solvers/ # FEM solvers: Poisson, heat, electrical (IV)
β βββ calculators/ # Pluggable activation-energy providers (MACE-NEB)
β βββ utils/ # mpi_context, balanced_tree, superbasin, analysis
βββ data/
β βββ parameters/ # All user-facing YAML/JSON parameter files
β βββ grids/ # Saved crystal grids (.pkl, generated locally)
β βββ mesh/ # gmsh meshes (.msh, generated locally)
β βββ cache/ # Materials Project cache (git-ignored)
β βββ experimental/ # Experimental IβV data for comparison
βββ scripts/
β βββ hpc/ # PBS templates and HPC deployment notes
βββ tests/ # pytest suite
If you use Kinetix in your research or adapt part of the code, please cite the following:
The core kMC framework has been validated and used in the following publications:
Aldana, Samuel, and Michael Nolan. "Control of Growth Morphology of Deposited fcc Metals through Tuning SubstrateβMetal Interactions." ACS Applied Materials & Interfaces (2025).
- DOI: 10.1021/acsami.5c18081
- Code: github.com/aldanads/control-of-growth-morphology...
- Zenodo: 10.5281/zenodo.18898755
Aldana, Samuel, Cara-Lena Nies, and Michael Nolan. "Control of Cu morphology on TaN barrier and combined Ru-TaN barrier/liner substrates for nanoscale interconnects from atomistic kinetic Monte Carlo simulations." Nanoscale 17, no. 19 (2025): 12450-12464.