Install any skill in seconds. Free to start, no credit card required.
Get Started Free →DFT, molecular simulation, and reaction prediction tools for chemists
.claude/skills/brycewang-stanford-computational-chemistry-guide/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 98% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 51% | 0% |
| case-22 | ✗→✓ | ▲ Improved | 53% | 0% |
| case-11 | ✓→✗ | ▼ Worse | 122% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 78% | 0% |
Computational chemistry bridges quantum mechanics and practical chemistry, enabling researchers to predict molecular properties, reaction mechanisms, and material behaviors without stepping into a wet lab. From drug design to catalyst optimization, computational methods accelerate discovery by screening thousands of candidates before committing to synthesis.
This guide covers the major computational chemistry paradigms: Density Functional Theory (DFT) for electronic structure calculations, molecular dynamics (MD) for simulating atomic motion, machine learning potentials for scaling up simulations, and reaction prediction tools for retrosynthesis and mechanism elucidation. Each section includes tool recommendations, typical workflows, and code examples.
Whether you are a chemistry PhD student running your first Gaussian calculations, a materials scientist exploring new alloys with VASP, or a medicinal chemist using ML-based property prediction, this skill provides the conceptual framework and practical recipes to get productive quickly.
DFT is the workhorse of quantum chemistry. It provides a good balance of accuracy and computational cost for systems of up to a few hundred atoms.
| Property | DFT Suitability | Typical Error | |----------|----------------|---------------| | Molecular geometry | Excellent | < 0.02 Angstrom | | Vibrational frequencies | Good | 3-5% | | Reaction barriers | Good with correction | 2-5 kcal/mol | | Band gaps | Fair (tends to underestimate) | 0.5-1.0 eV | | Van der Waals interactions | Requires dispersion correction | Varies | | Excited states | Fair (TD-DFT) | 0.2-0.5 eV |
| Software | License | Strengths | Basis Sets | |----------|---------|-----------|-----------| | Gaussian | Commercial | Broad functionality, well-documented | Gaussian-type | | ORCA | Free (academic) | DFT + wavefunction methods, excellent support | Gaussian-type | | VASP | Commercial | Periodic systems, materials science | Plane-wave | | Quantum ESPRESSO | Open source | Periodic DFT, phonons | Plane-wave | | Psi4 | Open source | Reference implementations, Python API | Gaussian-type | | CP2K | Open source | Mixed Gaussian/plane-wave, large systems | Mixed |
# geometry_optimization.inp
! B3LYP def2-TZVP D3BJ OPT FREQ
# B3LYP functional, triple-zeta basis, D3 dispersion, optimize + frequencies
%pal
nprocs 8
end
%maxcore 4000
* xyz 0 1
C 0.000 0.000 0.000
O 1.200 0.000 0.000
H -0.500 0.866 0.000
H -0.500 -0.866 0.000
*Run with:
bashorca geometry_optimization.inp > geometry_optimization.out
pythonfrom ase.io import read from ase.visualize import view # Read optimized geometry from ORCA output atoms = read('geometry_optimization.xyz') # Extract energies from output file import re with open('geometry_optimization.out') as f: text = f.read() # Total energy energy = float(re.search(r'FINAL SINGLE POINT ENERGY\s+([-\d.]+)', text).group(1)) print(f"Total energy: {energy:.6f} Hartree") print(f"Total energy: {energy * 627.509:.2f} kcal/mol") # Thermochemistry gibbs_match = re.search(r'Final Gibbs free energy\s+\.\.\.\s+([-\d.]+)', text) if gibbs_match: gibbs = float(gibbs_match.group(1)) print(f"Gibbs free energy: {gibbs:.6f} Hartree")
Initial Structure (.pdb/.mol2)
|
v
[Parameterization] --> Force field assignment (AMBER, CHARMM, OPLS)
|
v
[Solvation] --> Add solvent box, ions
|
v
[Minimization] --> Energy minimization (steepest descent)
|
v
[Equilibration] --> NVT then NPT ensemble (100 ps - 1 ns)
|
v
[Production] --> NPT ensemble (10 ns - microseconds)
|
v
[Analysis] --> RMSD, RMSF, hydrogen bonds, free energypythonfrom openmm.app import * from openmm import * from openmm.unit import * # Load structure pdb = PDBFile('protein.pdb') forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml') # Create system modeller = Modeller(pdb.topology, pdb.positions) modeller.addSolvent(forcefield, model='tip3p', padding=1.0*nanometers) system = forcefield.createSystem( modeller.topology, nonbondedMethod=PME, nonbondedCutoff=1.0*nanometers, constraints=HBonds ) # Set up simulation integrator = LangevinMiddleIntegrator(300*kelvin, 1/picosecond, 0.004*picoseconds) simulation = Simulation(modeller.topology, system, integrator) simulation.context.setPositions(modeller.positions) # Minimize simulation.minimizeEnergy() # Run production (10 ns) simulation.reporters.append(DCDReporter('trajectory.dcd', 1000)) simulation.reporters.append( StateDataReporter('log.csv', 1000, step=True, potentialEnergy=True, temperature=True) ) simulation.step(2500000) # 10 ns at 4 fs timestep
Machine learning potentials achieve near-DFT accuracy at a fraction of the cost:
| Method | Speed vs DFT | Accuracy | Training Data | |--------|-------------|----------|---------------| | ANI | 1000x faster | ~1 kcal/mol | Pre-trained | | SchNet | 100-1000x | ~1 kcal/mol | 1K-100K configs | | MACE | 100-1000x | < 1 kcal/mol | 1K-100K configs | | GemNet | 100-1000x | < 1 kcal/mol | 1K-100K configs |
pythonfrom rdkit import Chem from rdkit.Chem import Descriptors, AllChem import numpy as np def compute_molecular_features(smiles): """Compute molecular descriptors from SMILES string.""" mol = Chem.MolFromSmiles(smiles) if mol is None: return None features = { 'molecular_weight': Descriptors.MolWt(mol), 'logp': Descriptors.MolLogP(mol), 'hbd': Descriptors.NumHDonors(mol), 'hba': Descriptors.NumHAcceptors(mol), 'tpsa': Descriptors.TPSA(mol), 'rotatable_bonds': Descriptors.NumRotatableBonds(mol), 'aromatic_rings': Descriptors.NumAromaticRings(mol), 'heavy_atoms': mol.GetNumHeavyAtoms(), } # Morgan fingerprint (ECFP4) fp = AllChem.GetMorganFingerprintAsBitVect(mol, 2, nBits=2048) features['fingerprint'] = np.array(fp) return features # Lipinski's Rule of Five check def check_druglikeness(smiles): feats = compute_molecular_features(smiles) if feats is None: return False return (feats['molecular_weight'] <= 500 and feats['logp'] <= 5 and feats['hbd'] <= 5 and feats['hba'] <= 10)
| Tool | Approach | Access | |------|----------|--------| | ASKCOS | Template-based + ML | MIT, web interface | | IBM RXN | Transformer-based | Free API | | Syntheseus | Multi-model framework | Open source | | RetroTRAE | Transformer | Open source |
pythonfrom rdkit.Chem import AllChem, Draw # Define a reaction (Suzuki coupling) rxn_smarts = '[c:1][B](O)O.[c:2][Cl]>>[c:1][c:2]' rxn = AllChem.ReactionFromSmarts(rxn_smarts) # Apply reaction reactant1 = Chem.MolFromSmiles('c1ccc(B(O)O)cc1') # Phenylboronic acid reactant2 = Chem.MolFromSmiles('c1ccc(Cl)cc1') # Chlorobenzene products = rxn.RunReactants((reactant1, reactant2)) for product_set in products: for product in product_set: print(Chem.MolToSmiles(product)) # Biphenyl
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 17,043 | 23,132 | +36% | 1 | 1 | 0% | 3,067 | 6,062 | +98% | 0 | 0 | — |
case-02 | fail→fail | 17,807 | 16,331 | -8% | 1 | 1 | 0% | 3,351 | 5,874 | +75% | 0 | 0 | — |
case-03 | pass→pass | 16,781 | 11,212 | -33% | 1 | 1 | 0% | 2,445 | 4,356 | +78% | 0 | 0 | — |
case-04 | fail→fail | 19,007 | 21,617 | +14% | 1 | 1 | 0% | 3,393 | 6,393 | +88% | 0 | 0 | — |
case-05 | pass→pass | 17,962 | 20,730 | +15% | 1 | 1 | 0% | 2,828 | 5,677 | +101% | 0 | 0 | — |
case-06 | fail→fail | 13,306 | 16,079 | +21% | 1 | 1 | 0% | 2,365 | 5,440 | +130% | 0 | 0 | — |
case-07 | pass→pass | 12,877 | 13,191 | +2% | 1 | 1 | 0% | 2,179 | 4,676 | +115% | 0 | 0 | — |
case-08 | pass→pass | 12,680 | 10,766 | -15% | 1 | 1 | 0% | 1,946 | 4,314 | +122% | 0 | 0 | — |
case-09 | pass→pass | 14,244 | 10,780 | -24% | 1 | 1 | 0% | 2,313 | 4,429 | +91% | 0 | 0 | — |
case-10 | fail→pass | 18,523 | 10,849 | -41% | 1 | 1 | 0% | 2,852 | 4,319 | +51% | 0 | 0 | — |
case-11 | pass→fail | 12,611 | 11,422 | -9% | 1 | 1 | 0% | 1,992 | 4,418 | +122% | 0 | 0 | — |
case-12 | pass→pass | 13,279 | 13,770 | +4% | 1 | 1 | 0% | 1,982 | 4,714 | +138% | 0 | 0 | — |
case-13 | pass→pass | 5,725 | 6,647 | +16% | 1 | 1 | 0% | 1,058 | 3,588 | +239% | 0 | 0 | — |
case-14 | fail→fail | 21,199 | 19,908 | -6% | 1 | 1 | 0% | 3,134 | 5,588 | +78% | 0 | 0 | — |
case-15 | pass→pass | 10,594 | 9,585 | -10% | 1 | 1 | 0% | 1,663 | 4,037 | +143% | 0 | 0 | — |
case-16 | pass→pass | 5,636 | 4,846 | -14% | 1 | 1 | 0% | 1,011 | 3,374 | +234% | 0 | 0 | — |
case-17 | pass→pass | 19,064 | 21,678 | +14% | 1 | 1 | 0% | 3,175 | 5,996 | +89% | 0 | 0 | — |
case-18 | pass→pass | 10,840 | 9,914 | -9% | 1 | 1 | 0% | 1,865 | 4,384 | +135% | 0 | 0 | — |
case-19 | pass→pass | 11,631 | 18,019 | +55% | 1 | 1 | 0% | 1,708 | 5,313 | +211% | 0 | 0 | — |
case-20 | pass→pass | 20,456 | 22,248 | +9% | 1 | 1 | 0% | 3,617 | 6,883 | +90% | 0 | 0 | — |
case-21 | pass→pass | 21,459 | 22,482 | +5% | 1 | 1 | 0% | 4,058 | 6,584 | +62% | 0 | 0 | — |
case-22 | fail→pass | 20,508 | 12,787 | -38% | 1 | 1 | 0% | 3,011 | 4,601 | +53% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.