Write A Custom Model¶
Most users should start with LocalBarrierModel, LocalClusterExpansion, or
SiteEnergyModel. Write a custom model only when those do not represent the
scientific quantity you need.
What kMC Needs¶
The simulator needs a rate model with:
compute_probability(event=event, runtime_config=runtime_config, simulation_state=state)
The method should return an event rate in Hz. It can use the current
occupations from simulation_state.occupations and the event endpoints from
event.mobile_ion_indices.
Minimal Example¶
from kmcpy.models import BaseModel
from kmcpy.units import BOLTZMANN_CONSTANT_MEV_PER_K
class ConstantRateBarrierModel(BaseModel):
def __init__(self, barrier_mev, name="ConstantRateBarrierModel"):
super().__init__(name=name)
self.barrier_mev = float(barrier_mev)
def compute_probability(self, event, runtime_config, simulation_state):
import numpy as np
return runtime_config.attempt_frequency * np.exp(
-self.barrier_mev
/ (BOLTZMANN_CONSTANT_MEV_PER_K * runtime_config.temperature)
)
def as_dict(self):
return {
"@module": self.__class__.__module__,
"@class": self.__class__.__name__,
"barrier_mev": self.barrier_mev,
"name": self.name,
}
@classmethod
def from_dict(cls, data):
return cls(
barrier_mev=data["barrier_mev"],
name=data.get("name", "ConstantRateBarrierModel"),
)
This is intentionally small. Avoid adding a new abstraction unless multiple models truly share meaningful logic.
Optional Hooks¶
Stateful models can implement:
initialize_state(simulation_state=state, event_lib=event_lib, structure=structure, config=config)
apply_event(event=event, simulation_state=state)
Use these hooks to build caches once and update them after accepted events. Do
not rebuild full external occupations inside every compute_probability(...)
call.
Serialization¶
kMCpy follows Monty-style serialization:
as_dict()returns structured data,from_dict(...)restores the object,to("model.json")writes the model,from_file("model.json")loads it.
For reusable public models, add tests that cover serialization, rate
calculation, and integration with KMC.from_config(...).