4. Energies and relaxation¶
So far the atoms stayed where they were put. With an interatomic potential they have an energy and forces, and can relax. This lesson computes a real number, the energy it takes to form a vacancy in copper, in a few lines.
A potential¶
A calculator takes a system and computes what you ask of it. EAM.zhou makes
the embedded atom potential of Zhou et al., with no file to download:
import numpy as np
from mdapy.build import build_crystal
from mdapy.calculators import EAM
potential = EAM.zhou(["Cu"])
crystal = build_crystal("fcc", 3.615, elements="Cu", repeat=(5, 5, 5))
result = potential.compute(crystal, ("energy", "forces", "virial"))
print(f"{result.energy / len(crystal):.3f} eV per atom")
print(f"largest force {np.abs(result.forces).max():.1e} eV/Å")
A perfect crystal has no forces, as every atom is pulled alike from all sides.
Take out one atom¶
gather picks atoms by index, so all the indices but the first remove one atom.
The atoms around the hole now feel a force:
vacancy = crystal.gather(np.arange(1, len(crystal)))
forces = potential.compute(vacancy, ("forces",)).forces
print(f"largest force {np.abs(forces).max():.3f} eV/Å")
Relax it¶
minimize moves the atoms until the forces vanish. It returns the relaxed
system, its energy, and whether it converged:
from mdapy.simulation import minimize
relaxed = minimize(vacancy, potential)
print(relaxed.converged, relaxed.steps)
print(f"largest force {relaxed.max_force:.5f} eV/Å")
The energy of a vacancy¶
Forming a vacancy moves one atom from inside the crystal to its surface, so it costs the energy of the relaxed system less that of N − 1 atoms of the perfect crystal:
perfect = result.energy / len(crystal)
formation = relaxed.energy - (len(crystal) - 1) * perfect
print(f"{formation:.3f} eV")
Experiments give about 1.28 eV. A system this size has converged, as the tutorial on defect energies shows.
Energy per atom¶
The relaxed system has new columns, as anything that computes per-atom values does. Here is the energy of each atom against that of the crystal, in a nanoparticle:
from mdapy.visualization import render
large = build_crystal("fcc", 3.615, elements="Cu", repeat=(10, 10, 10))
center = large["positions"].mean(axis=0)
particle = large.filter(np.linalg.norm(large["positions"] - center, axis=1) < 14)
relaxed = minimize(particle, potential)
particle = relaxed.system.with_columns(
excess=relaxed.system["atomic_energies"] - perfect
)
print(particle)
render(
particle,
"images/excess.png",
atoms=particle["positions.x"] < center[0],
color="excess",
box=False,
width=800,
height=600,
legend="excess energy (eV)",
)
System: 952 atoms (Cu952)
box: 36.15 × 36.15 × 36.15 Å, orthogonal, periodic x y z
columns: positions (3), element, forces (3), atomic_energies, atomic_virials (3),
excess
info: energy = -3099.06, virial (3, 3), stress (3, 3)

The atoms of the surface are bound less strongly, most of all at the corners. This is why a small particle melts below the bulk, as the next lesson shows.
Try it¶
- Compute the formation energy in a smaller crystal,
repeat=(3, 3, 3). How far is it from 1.273 eV? - Use
minimize(vacancy, potential, cell="full"), which also relaxes the box. What changes?
An answer
Next: a nanoparticle melts. See also Calculators, Energy minimization and Defect energies.