Interactions
An interaction is any object paired with a neighbour finder in MDSys's interactions list. Each step, simulate! calls update_acceleration! on every (interaction, finder) pair to accumulate forces, and a logger may separately call energy to record that interaction's contribution.
Built-in interactions
ExTinyMD.LennardJones — Type
LennardJones(; ϵ = 1.0, cutoff = 3.5, σ = 1.0)Pairwise Lennard-Jones interaction, E(r) = 4ϵ[(σ/r)^12 - (σ/r)^6] for r < cutoff, evaluated over the pairs in the associated neighbour finder.
ExTinyMD.SubLennardJones — Type
SubLennardJones(sub_down, sub_up; ϵ = 1.0, cutoff = 3.5, σ = 1.0)Lennard-Jones interaction between each particle and two flat substrates at z = sub_down and z = sub_up, acting only in z on particles within cutoff of a wall (see SubNeighborFinder).
ExTinyMD.ExternalField — Type
ExternalField(; E = Point((0.0, 0.0, 0.0)))A uniform external electric field E; each particle feels a force charge * E. Pair with a NoNeighborFinder, since no neighbour list is needed.
ExTinyMD.NoInteraction — Type
NoInteraction()A placeholder interaction that contributes no force and no energy.
The electrostatic interactions (Ewald3D, Ewald2D, ICMEwald2D, ICMEwald3D) are documented separately on the Electrostatics page — they share the same update_acceleration!/energy contract described below, but also work standalone, without any MDSys.
The interaction contract
ExTinyMD.update_acceleration! — Function
update_acceleration!(interaction, neighborfinder, sys, info)Accumulate the acceleration contributed by interaction into info.particle_info[i].acceleration for every particle i. This is the interface every AbstractInteraction implements to plug into simulate!; NoInteraction is a no-op. See README.md for how to add a new interaction.
ExTinyMD.energy — Function
energy(interaction, neighborfinder, sys, info) -> TThe energy contributed by interaction. This is the interface every energy-reporting AbstractInteraction implements (used by EnergyLogger); not every interaction defines a method — one that only ever appears inside a logger-free MDSys need not.
To add a new interaction, define a struct (optionally <: AbstractInteraction, though this is not required — dispatch only needs the methods below) and implement:
function ExTinyMD.update_acceleration!(
interaction::YourInteraction,
neighborfinder::YourFinder,
sys::MDSys{T},
info::SimulationInfo{T},
) where {T<:Number}
update_finder!(neighborfinder, info)
# accumulate into info.particle_info[i].acceleration for every particle i,
# using neighborfinder.neighbor_list (or neighborfinder.up_neighbor /
# down_neighbor for a SubNeighborFinder-style finder) to find pairs.
return nothing
endupdate_acceleration! accumulates — it must not overwrite info.particle_info[i].acceleration, since VerletProcess zeroes it once per step before calling every interaction in turn.
If the interaction should also be logged with EnergyLogger, add a matching method for energy:
function ExTinyMD.energy(
interaction::YourInteraction,
neighborfinder::YourFinder,
sys::MDSys{T},
info::SimulationInfo{T},
) where {T<:Number}
# return the total energy, without mutating anything
endLennardJones in src/interactions/lennard_jones.jl is the simplest complete example of both methods; the electrostatics adapter in src/interactions/electrostatics/adapter.jl is a more involved one, showing how to bridge to a framework-free core API (see Electrostatics).