Canonical Monte Carlo (NVT) on a bimetallic nanoparticle

This example uses CanonicalEnsemble to sample fixed-composition configurations of a small Au/Pt cluster at constant temperature. Trial configurations are generated by an mcpy MoveSelector (here a single PermutationMove), relaxed locally, and accepted with the Metropolis rule.

Goal

For a 38-atom Au19Pt19 truncated-octahedral cluster at \(T = 800\,\mathrm{K}\), sample low-energy chemical orderings without changing the atom count.

Code

from ase.cluster import Octahedron
from ase.calculators.emt import EMT
from ase.optimize import LBFGS

from mcpy.ensembles.canonical_ensemble import CanonicalEnsemble
from mcpy.moves.move_selector import MoveSelector
from mcpy.moves.permutation_move import PermutationMove

# Build a small Au/Pt cluster (half Au, half Pt).
atoms = Octahedron('Au', length=4, cutoff=1)
half = len(atoms) // 2
atoms.symbols = ['Au'] * half + ['Pt'] * (len(atoms) - half)

# mcpy move set: a single permutation move (species swap).
move_selector = MoveSelector(
    [1.0],
    [PermutationMove(species=['Au', 'Pt'], seed=7)],
)

mc = CanonicalEnsemble(
    atoms=atoms,
    calculator=EMT(),
    optimizer=LBFGS,
    fmax=0.1,
    temperature=800.0,
    move_selector=move_selector,
    random_seed=7,
    outfile='mc_nvt.out',
    traj_file='mc_nvt.xyz',
    outfile_write_interval=10,
    trajectory_write_interval=1,
)
mc.run(steps=2_000)

Outputs

  • mc_nvt.out — step log with the current accepted energy.

  • mc_nvt.xyz — every accepted configuration, one frame per acceptance.

Interpretation

  • CanonicalEnsemble does not insert or delete atoms — the total number of Au and Pt is conserved across the run.

  • The configurations it writes to disk are post-relaxation — energies are directly comparable across frames.

  • Add more moves to the MoveSelector (e.g. a displacement move) with their own weights to sample positional disorder alongside chemical ordering.

Next steps