Examples
This page provides practical examples of using KIM_API.jl for various molecular simulation tasks.
Basic Examples
Computing Energy and Forces with KIMModel
using KIM_API
using StaticArrays
using LinearAlgebra
# Create a KIM model for silicon
model = KIMModel("SW_StillingerWeber_1985_Si__MO_405512056662_006")
# Define a silicon dimer
species = ["Si", "Si"]
positions = [
SVector(0.0, 0.0, 0.0), # First silicon atom
SVector(2.35, 0.0, 0.0) # Second silicon atom at equilibrium distance
]
# Set up periodic cell (large enough to avoid self-interaction)
cell = Matrix(10.0 * I(3)) # 10×10×10 Å cubic cell
pbc = [true, true, true]
# Compute properties
results = model(species, positions, cell, pbc)
println("Energy: $(results[:energy]) eV")
println("Force on atom 1: $(results[:forces][:, 1]) eV/Å")
println("Force on atom 2: $(results[:forces][:, 2]) eV/Å")Using AtomsBase and AtomsCalculators
using KIM_API, AtomsBase, AtomsCalculators
using StaticArrays, Unitful
# Create a KIM calculator
calc = KIMCalculator("SW_StillingerWeber_1985_Si__MO_405512056662_006")
# Create AtomsBase system with units
particles = [
:Si => SVector(0.0u"Å", 0.0u"Å", 0.0u"Å"),
:Si => SVector(2.35u"Å", 0.0u"Å", 0.0u"Å")
]
cell_vectors = (
SVector(10.0u"Å", 0.0u"Å", 0.0u"Å"),
SVector(0.0u"Å", 10.0u"Å", 0.0u"Å"),
SVector(0.0u"Å", 0.0u"Å", 10.0u"Å")
)
system = FlexibleSystem(particles; cell_vectors=cell_vectors, periodicity=(true, true, true));
# Use AtomsCalculators interface
energy = AtomsCalculators.potential_energy(calc, system)
forces = AtomsCalculators.forces(calc, system)
println("Energy: $(energy) eV")
println("Forces: $(forces)")
# Or call calculator directly for all properties
results = calc(system)
println("All results: $(results)")Energy Minimization
using KIM_API, Optim
using StaticArrays, LinearAlgebra
# Set up model and initial structure
model = KIM_API.KIMModel("SW_StillingerWeber_1985_Si__MO_405512056662_006")
species = ["Si", "Si"]
cell = [5.43 0.0 0.0; 0.0 5.43 0.0; 0.0 0.0 5.43]
pbc = [true, true, true]
# Objective function for optimization
function objective(x)
pos = [SVector(0.0, 0.0, 0.0), SVector(x[1], x[2], x[3])]
results = model(species, pos, cell, pbc)
return results[:energy]
end
# Optimize second atom position
initial_pos = [2.5, 0.0, 0.0] # Starting guess
result = result = optimize(objective, initial_pos, BFGS(), Optim.Options(f_tol=1e-4))
println("Optimized position: ", result.minimizer)
println("Minimum energy: ", result.minimum)Advanced Examples
Equivalence Between Methods
This example demonstrates that KIMModel (raw arrays) and KIMCalculator (AtomsBase) produce identical results:
using KIM_API, AtomsBase, StaticArrays
model_name = "SW_StillingerWeber_1985_Si__MO_405512056662_006"
# Method 1: Raw arrays with KIMModel
model = KIMModel(model_name)
species = ["Si", "Si"]
positions = [SVector(0.0, 0.0, 0.0), SVector(2.35, 0.0, 0.0)]
cell = [5.43 0.0 0.0; 0.0 5.43 0.0; 0.0 0.0 5.43]
pbc = [true, true, true]
raw_results = model(species, positions, cell, pbc)
# Method 2: AtomsBase system with KIMCalculator
calc = KIMCalculator(model_name)
particles = [
:Si => SVector(0.0u"Å", 0.0u"Å", 0.0u"Å"),
:Si => SVector(2.35u"Å", 0.0u"Å", 0.0u"Å")
]
cell_vectors = (
SVector(5.43u"Å", 0.0u"Å", 0.0u"Å"),
SVector(0.0u"Å", 5.43u"Å", 0.0u"Å"),
SVector(0.0u"Å", 0.0u"Å", 5.43u"Å")
)
system = FlexibleSystem(particles; cell_vectors=cell_vectors, periodicity=(true, true, true));
atomsbase_results = calc(system)
# Verify equivalence
@assert raw_results[:energy] ≈ atomsbase_results[:energy]
@assert raw_results[:forces] ≈ atomsbase_results[:forces]
println("Both methods produce identical results!")
println("Energy: $(raw_results[:energy]) eV")Different Unit Systems
using KIM_API, StaticArrays, LinearAlgebra
model_name = "SW_StillingerWeber_1985_Si__MO_405512056662_006"
species = ["Si", "Si"]
positions = [SVector(0.0, 0.0, 0.0), SVector(2.35, 0.0, 0.0)]
cell = Matrix(5.43 * I(3))
pbc = [true, true, true]
# Different unit systems
units_list = [:metal, :real, :si]
results = Dict()
for units in units_list
calc = KIMCalculator(model_name, units=units)
model_fn = calc.model_fn
result = model_fn(species, positions, cell, pbc)
results[units] = result[:energy]
end
println("Energy in different units:")
println(" Metal (eV): $(results[:metal])")
println(" Real (kcal/mol): $(results[:real])")
println(" SI (J): $(results[:si])")
# Convert real units to eV for comparison
energy_real_in_eV = results[:real] * 0.043364
println(" Real-> eV: $(energy_real_in_eV)")