skills/materials-properties/SKILL.md
Expert assistant for calculating materials properties from first-principles using ASE - structure relaxation, surface energies, adsorption, reaction barriers, phonons, elastic constants, and thermodynamic modeling with proper scientific methodology
npx skillsauth add Hongyu-yu/matsci-ai-skills materials-propertiesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are an expert assistant for calculating materials properties from first-principles using the Atomic Simulation Environment (ASE) and specialized packages. Help users perform structure relaxations, compute ground state properties, and calculate advanced materials properties using scientifically rigorous methods with proper citations.
This skill covers comprehensive materials property calculations including:
Core Capabilities:
Advanced Properties:
# Core packages
pip install ase spglib matplotlib
# Specialized packages
pip install phonopy elastic icet pycalphad
# Optional DFT calculators
pip install gpaw # Real DFT (requires compilation)
# VASP requires separate license and installation
# Quantum ESPRESSO via ase.calculators.espresso
from ase import Atoms
from ase.optimize import BFGS
from ase.calculators.emt import EMT
# Create or load structure
atoms = Atoms('Cu', positions=[[0, 0, 0]], cell=[2.5, 2.5, 2.5], pbc=True)
# Set calculator
atoms.calc = EMT()
# Optimize geometry
opt = BFGS(atoms, trajectory='opt.traj')
opt.run(fmax=0.01) # Force convergence criterion
# Get optimized energy
E_opt = atoms.get_potential_energy()
print(f"Optimized energy: {E_opt:.3f} eV")
Key Parameters:
fmax: Maximum force (eV/Å) - typical values: 0.01-0.05steps: Maximum optimization stepsfrom ase.optimize import BFGS
from ase.constraints import ExpCellFilter
# Relax both positions and cell
ecf = ExpCellFilter(atoms)
opt = BFGS(ecf, trajectory='cell_opt.traj')
opt.run(fmax=0.01)
# Get optimized lattice
a = atoms.cell.cellpar()[0]
print(f"Optimized lattice constant: {a:.3f} Å")
Applications:
import spglib
# Get space group
cell = (atoms.cell, atoms.get_scaled_positions(), atoms.get_atomic_numbers())
spacegroup = spglib.get_spacegroup(cell, symprec=1e-5)
print(f"Space group: {spacegroup}")
# Get lattice parameters
a, b, c, alpha, beta, gamma = atoms.cell.cellpar()
print(f"Lattice: a={a:.3f}, b={b:.3f}, c={c:.3f} Å")
print(f"Angles: α={alpha:.1f}, β={beta:.1f}, γ={gamma:.1f}°")
# Volume
V = atoms.get_volume()
print(f"Volume: {V:.3f} ų")
# Crystal system
dataset = spglib.get_symmetry_dataset(cell)
print(f"Crystal system: {dataset['international']}")
from ase.calculators.emt import EMT
atoms.calc = EMT()
Advantages:
Limitations:
from gpaw import GPAW, PW
atoms.calc = GPAW(mode=PW(500), # Plane-wave cutoff (eV)
xc='PBE', # Exchange-correlation functional
kpts=(8, 8, 8), # k-point sampling
txt='gpaw.txt') # Output file
Parameters:
mode: PW(cutoff) for plane waves, grid-based for real-spacexc: PBE, LDA, RPBE, BEEF-vdW, etc.kpts: k-point mesh or specific k-pointsconvergence: Energy convergence criterionfrom ase.calculators.vasp import Vasp
atoms.calc = Vasp(xc='PBE',
encut=500, # Cutoff energy (eV)
kpts=(8,8,8),
ismear=1, # Smearing method
sigma=0.1) # Smearing width
VASP-specific:
references/calculator_setup.md for detailsMethod: Slab model approach
Formula:
γ = (E_slab - N × E_bulk) / (2 × A)
Where:
Workflow:
ase.build.surface()See: references/surface_energy.md for detailed methods
Key References:
Method: Compare slab+adsorbate to separated systems
Formula:
E_ads = E_slab+ads - E_slab - E_molecule
More negative = stronger adsorption
Workflow:
See: references/adsorption_energy.md
Key References:
Method: Find minimum energy path between reactant and product
Workflow:
from ase.neb import NEB
from ase.optimize import BFGS
# Create images interpolating between initial and final
images = [initial]
images += [initial.copy() for i in range(5)] # 5 intermediate images
images += [final]
# Interpolate
neb = NEB(images)
neb.interpolate()
# Set calculators
for image in images[1:-1]:
image.calc = EMT()
# Optimize NEB
optimizer = BFGS(neb, trajectory='neb.traj')
optimizer.run(fmax=0.05)
# Extract barrier
from ase.neb import NEBTools
nebtools = NEBTools(images)
barrier = nebtools.get_barrier()[0]
print(f"Activation barrier: {barrier:.2f} eV")
See: references/reaction_barriers.md
Key References:
Method: Finite displacement or DFPT
Workflow:
from ase.vibrations import Vibrations
# Calculate vibrations
vib = Vibrations(atoms)
vib.run()
# Get frequencies
vib.summary()
# Zero-point energy
zpe = vib.get_zero_point_energy()
See: references/vibrational_analysis.md
Key References:
Method: Supercell approach with force constants
Workflow:
from phonopy import Phonopy
# Create phonopy object
phonon = Phonopy(atoms, supercell_matrix=[[2,0,0],[0,2,0],[0,0,2]])
# Generate displacements
phonon.generate_displacements(distance=0.01)
supercells = phonon.supercells_with_displacements
# Calculate forces for each displacement
for scell in supercells:
scell.calc = calc
forces = scell.get_forces()
# Set forces back to phonopy
# Calculate phonon properties
phonon.produce_force_constants()
phonon.auto_band_structure()
phonon.plot_band_structure()
Applications:
See: references/phonons.md
Key References:
Method: Apply strain, measure stress
Properties Calculated:
See: references/elastic_constants.md
Key References:
Method: Volume-energy curve fitting
Workflow:
from ase.eos import calculate_eos
eos = calculate_eos(atoms, trajectory='eos.traj')
v, e, B = eos.fit() # Volume, energy, bulk modulus
eos.plot('eos.png')
EOS Types:
See: references/equation_of_state.md
Key References:
Formula:
E_form = E_compound - Σ(n_i × μ_i)
Where μ_i are chemical potentials (reference energies)
Applications:
See: references/formation_energy.md
Key References:
Method: Expand configurational energy in cluster interactions
Applications:
See: references/cluster_expansion.md
Key References:
Method: Combine DFT with thermochemical databases
Applications:
See: references/calphad.md
Key References:
Types:
See: references/defect_energy.md
Key References:
Method: Compare interface structure to separated surfaces
See: references/interface_energy.md
Key References:
Method: Spin-polarized DFT
Properties:
See: references/magnetic_properties.md
Method: Quasi-harmonic approximation
See: references/thermal_expansion.md
Key References:
Properties:
See: references/electronic_structure.md
Key References:
Always test convergence of:
Example:
# k-point convergence
for k in [2, 4, 6, 8, 10, 12]:
atoms.calc = GPAW(kpts=(k,k,k), ...)
E = atoms.get_potential_energy()
print(f"k={k}: E={E:.4f} eV")
fmax = 0.01-0.05 eV/Åfmax = 0.001 eV/Åmax(np.linalg.norm(atoms.get_forces(), axis=1))Fix atoms during relaxation:
from ase.constraints import FixAtoms
# Fix bottom 2 layers of slab
c = FixAtoms(indices=[atom.index for atom in atoms if atom.position[2] < 5])
atoms.set_constraint(c)
from ase.io import read
# Read optimization trajectory
traj = read('opt.traj', ':')
# Plot energy vs step
energies = [atoms.get_potential_energy() for atoms in traj]
import matplotlib.pyplot as plt
plt.plot(energies)
plt.xlabel('Step')
plt.ylabel('Energy (eV)')
plt.show()
from ase.build import bulk
from ase.eos import calculate_eos
atoms = bulk('Cu', 'fcc', a=3.6)
atoms.calc = EMT()
eos = calculate_eos(atoms, trajectory='eos.traj')
v, e, B = eos.fit()
a_opt = v**(1/3)
print(f"Optimal lattice constant: {a_opt:.3f} Å")
print(f"Bulk modulus: {B/1e9:.1f} GPa")
from ase.build import bulk, surface, add_vacuum
# Bulk energy
bulk_atoms = bulk('Cu', 'fcc', a=3.6)
bulk_atoms.calc = EMT()
E_bulk_per_atom = bulk_atoms.get_potential_energy() / len(bulk_atoms)
# Create slab
slab = surface('Cu', (1,1,1), layers=7, vacuum=10)
slab.calc = EMT()
E_slab = slab.get_potential_energy()
# Surface energy
N = len(slab)
A = slab.get_cell()[0,0] * slab.get_cell()[1,1]
gamma = (E_slab - N * E_bulk_per_atom) / (2 * A)
print(f"Surface energy: {gamma*1000:.1f} meV/ų")
from ase.build import fcc111, molecule, add_adsorbate
# Clean slab
slab = fcc111('Cu', size=(3,3,4), vacuum=10)
slab.calc = EMT()
E_slab = slab.get_potential_energy()
# Adsorbate in gas phase
mol = molecule('CO')
mol.calc = EMT()
E_mol = mol.get_potential_energy()
# Adsorbed system
add_adsorbate(slab, mol, height=2.0, position='ontop')
slab.calc = EMT()
E_ads_system = slab.get_potential_energy()
# Adsorption energy
E_ads = E_ads_system - E_slab - E_mol
print(f"Adsorption energy: {E_ads:.2f} eV")
1. SCF Not Converging:
2. Forces Not Converging:
3. Unstable Structures:
4. Memory Issues:
Core ASE:
DFT Theory: 2. Hohenberg & Kohn, "Inhomogeneous electron gas," Phys. Rev. 136, B864 (1964) 3. Kohn & Sham, "Self-consistent equations," Phys. Rev. 140, A1133 (1965) 4. Sholl & Steckel, Density Functional Theory: A Practical Introduction (Wiley, 2009)
Symmetry Analysis: 5. Spglib: https://spglib.github.io/spglib/
See individual reference files in references/ for detailed citations for each method.
examples/ directoryreferences/ directoryworkflows/ directorytools
Spreadsheet toolkit (.xlsx/.csv). Create/edit with formulas/formatting, analyze data, visualization, recalculate formulas, for spreadsheet processing and analysis.
tools
Expert assistant for VASP (Vienna Ab initio Simulation Package) calculations - input file generation, parameter selection, workflow setup, and best practices for accurate DFT calculations
data-ai
This skill should be used when working with pre-trained transformer models for natural language processing, computer vision, audio, or multimodal tasks. Use for text generation, classification, question answering, translation, summarization, image classification, object detection, speech recognition, and fine-tuning models on custom datasets.
tools
Graph Neural Networks (PyG). Node/graph classification, link prediction, GCN, GAT, GraphSAGE, heterogeneous graphs, molecular property prediction, for geometric deep learning.