Files
drug-discovery-prompts/upstream/K-Dense-AI-scientific-agent-skills/skills/pymatgen/references/analysis_modules.md

13 KiB

title, task, lineage_type, upstream_source, upstream_sha, imported_at, prompt_class, upstream_changes, author, validated
title task lineage_type upstream_source upstream_sha imported_at prompt_class upstream_changes author validated
Pymatgen Analysis Modules Reference import https://github.com/K-Dense-AI/scientific-agent-skills/blob/9c9bd2e9/skills/pymatgen/references/analysis_modules.md 9c9bd2e9 2026-06-27 prompt accepted upstream false

Pymatgen Analysis Modules Reference

This reference documents pymatgen's extensive analysis capabilities for materials characterization, property prediction, and computational analysis.

Phase Diagrams and Thermodynamics

Phase Diagram Construction

from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotter
from pymatgen.entries.computed_entries import ComputedEntry

# Create entries (composition and total energy)
entries = [
    ComputedEntry("Fe", -8.4),
    ComputedEntry("O2", -4.9),
    ComputedEntry("FeO", -6.7),
    ComputedEntry("Fe2O3", -8.3),
    ComputedEntry("Fe3O4", -9.1),
]

# Build phase diagram
pd = PhaseDiagram(entries)

# Get stable entries
stable_entries = pd.stable_entries

# Get energy above hull (stability)
entry_to_test = ComputedEntry("Fe2O3", -8.0)
energy_above_hull = pd.get_e_above_hull(entry_to_test)

# Get decomposition products
decomp = pd.get_decomposition(entry_to_test.composition)
# Returns: {entry1: fraction1, entry2: fraction2, ...}

# Get equilibrium reaction energy
rxn_energy = pd.get_equilibrium_reaction_energy(entry_to_test)

# Plot phase diagram
plotter = PDPlotter(pd)
plotter.show()
plotter.write_image("phase_diagram.png")

Chemical Potential Diagrams

from pymatgen.analysis.phase_diagram import ChemicalPotentialDiagram

# Create chemical potential diagram
cpd = ChemicalPotentialDiagram(entries, limits={"O": (-10, 0)})

# Get domains (stability regions)
domains = cpd.domains

Pourbaix Diagrams

Electrochemical phase diagrams with pH and potential axes.

from pymatgen.analysis.pourbaix_diagram import PourbaixDiagram, PourbaixPlotter
from pymatgen.entries.computed_entries import ComputedEntry

# Create entries with corrections for aqueous species
entries = [...]  # Include solids and ions

# Build Pourbaix diagram
pb = PourbaixDiagram(entries)

# Get stable entry at specific pH and potential
stable_entry = pb.get_stable_entry(pH=7, V=0)

# Plot
plotter = PourbaixPlotter(pb)
plotter.show()

Structure Analysis

Structure Matching and Comparison

from pymatgen.analysis.structure_matcher import StructureMatcher

matcher = StructureMatcher()

# Check if structures match
is_match = matcher.fit(struct1, struct2)

# Get mapping between structures
mapping = matcher.get_mapping(struct1, struct2)

# Group similar structures
grouped = matcher.group_structures([struct1, struct2, struct3, ...])

Ewald Summation

Calculate electrostatic energy of ionic structures.

from pymatgen.analysis.ewald import EwaldSummation

ewald = EwaldSummation(struct)
total_energy = ewald.total_energy  # In eV
forces = ewald.forces  # Forces on each site

Symmetry Analysis

from pymatgen.symmetry.analyzer import SpacegroupAnalyzer

sga = SpacegroupAnalyzer(struct)

# Get space group information
spacegroup_symbol = sga.get_space_group_symbol()  # e.g., "Fm-3m"
spacegroup_number = sga.get_space_group_number()   # e.g., 225
crystal_system = sga.get_crystal_system()           # e.g., "cubic"

# Get symmetrized structure
sym_struct = sga.get_symmetrized_structure()
equivalent_sites = sym_struct.equivalent_sites

# Get conventional/primitive cells
conventional = sga.get_conventional_standard_structure()
primitive = sga.get_primitive_standard_structure()

# Get symmetry operations
symmetry_ops = sga.get_symmetry_operations()

Local Environment Analysis

Coordination Environment

from pymatgen.analysis.local_env import (
    VoronoiNN,           # Voronoi tessellation
    CrystalNN,           # Crystal-based
    MinimumDistanceNN,   # Distance cutoff
    BrunnerNN_real,      # Brunner method
)

# Voronoi nearest neighbors
voronoi = VoronoiNN()
neighbors = voronoi.get_nn_info(struct, n=0)  # Neighbors of site 0

# CrystalNN (recommended for most cases)
crystalnn = CrystalNN()
neighbors = crystalnn.get_nn_info(struct, n=0)

# Analyze all sites
for i, site in enumerate(struct):
    neighbors = voronoi.get_nn_info(struct, i)
    coordination_number = len(neighbors)
    print(f"Site {i} ({site.species_string}): CN = {coordination_number}")

Coordination Geometry (ChemEnv)

Detailed coordination environment identification.

from pymatgen.analysis.chemenv.coordination_environments.coordination_geometry_finder import LocalGeometryFinder
from pymatgen.analysis.chemenv.coordination_environments.chemenv_strategies import SimplestChemenvStrategy

lgf = LocalGeometryFinder()
lgf.setup_structure(struct)

# Get coordination environment for site
se = lgf.compute_structure_environments(only_indices=[0])
strategy = SimplestChemenvStrategy()
lse = strategy.get_site_coordination_environment(se[0])

print(f"Coordination: {lse}")

Bond Valence Sum

from pymatgen.analysis.bond_valence import BVAnalyzer

bva = BVAnalyzer()

# Calculate oxidation states
valences = bva.get_valences(struct)

# Get structure with oxidation states
struct_with_oxi = bva.get_oxi_state_decorated_structure(struct)

Surface and Interface Analysis

Surface (Slab) Generation

from pymatgen.core.surface import SlabGenerator, generate_all_slabs

# Generate slabs for a specific Miller index
slabgen = SlabGenerator(
    struct,
    miller_index=(1, 1, 1),
    min_slab_size=10.0,     # Minimum slab thickness (Å)
    min_vacuum_size=10.0,   # Minimum vacuum thickness (Å)
    center_slab=True
)

slabs = slabgen.get_slabs()

# Generate all slabs up to a Miller index
all_slabs = generate_all_slabs(
    struct,
    max_index=2,
    min_slab_size=10.0,
    min_vacuum_size=10.0
)

Wulff Shape Construction

from pymatgen.analysis.wulff import WulffShape

# Define surface energies (J/m²)
surface_energies = {
    (1, 0, 0): 1.0,
    (1, 1, 0): 1.1,
    (1, 1, 1): 0.9,
}

wulff = WulffShape(struct.lattice, surface_energies, symm_reduce=True)

# Get effective radius and surface area
effective_radius = wulff.effective_radius
surface_area = wulff.surface_area
volume = wulff.volume

# Visualize
wulff.show()

Adsorption Site Finding

from pymatgen.analysis.adsorption import AdsorbateSiteFinder

asf = AdsorbateSiteFinder(slab)

# Find adsorption sites
ads_sites = asf.find_adsorption_sites()
# Returns dictionary: {"ontop": [...], "bridge": [...], "hollow": [...]}

# Generate structures with adsorbates
from pymatgen.core import Molecule
adsorbate = Molecule("O", [[0, 0, 0]])

ads_structs = asf.generate_adsorption_structures(
    adsorbate,
    repeat=[2, 2, 1],  # Supercell to reduce adsorbate coverage
)

Interface Construction

from pymatgen.analysis.interfaces.coherent_interfaces import CoherentInterfaceBuilder

# Build interface between two materials
builder = CoherentInterfaceBuilder(
    substrate_structure=substrate,
    film_structure=film,
    substrate_miller=(0, 0, 1),
    film_miller=(1, 1, 1),
)

interfaces = builder.get_interfaces()

Magnetism

Magnetic Structure Analysis

from pymatgen.analysis.magnetism import CollinearMagneticStructureAnalyzer

analyzer = CollinearMagneticStructureAnalyzer(struct)

# Get magnetic ordering
ordering = analyzer.ordering  # e.g., "FM" (ferromagnetic), "AFM", "FiM"

# Get magnetic space group
mag_space_group = analyzer.get_structure_with_spin().get_space_group_info()

Magnetic Ordering Enumeration

from pymatgen.transformations.advanced_transformations import MagOrderingTransformation

# Enumerate possible magnetic orderings
mag_trans = MagOrderingTransformation({"Fe": 5.0})  # Magnetic moment in μB
transformed_structures = mag_trans.apply_transformation(struct, return_ranked_list=True)

Electronic Structure Analysis

Band Structure Analysis

from pymatgen.electronic_structure.bandstructure import BandStructureSymmLine
from pymatgen.electronic_structure.plotter import BSPlotter

# Read band structure from VASP calculation
from pymatgen.io.vasp import Vasprun
vasprun = Vasprun("vasprun.xml")
bs = vasprun.get_band_structure()

# Get band gap
band_gap = bs.get_band_gap()
# Returns: {'energy': gap_value, 'direct': True/False, 'transition': '...'}

# Check if metal
is_metal = bs.is_metal()

# Get VBM and CBM
vbm = bs.get_vbm()
cbm = bs.get_cbm()

# Plot band structure
plotter = BSPlotter(bs)
plotter.show()
plotter.save_plot("band_structure.png")

Density of States (DOS)

from pymatgen.electronic_structure.dos import CompleteDos
from pymatgen.electronic_structure.plotter import DosPlotter

# Read DOS from VASP calculation
vasprun = Vasprun("vasprun.xml")
dos = vasprun.complete_dos

# Get total DOS
total_dos = dos.densities

# Get projected DOS
pdos = dos.get_element_dos()  # By element
site_dos = dos.get_site_dos(struct[0])  # For specific site
spd_dos = dos.get_spd_dos()  # By orbital (s, p, d)

# Plot DOS
plotter = DosPlotter()
plotter.add_dos("Total", dos)
plotter.show()

Fermi Surface

from pymatgen.electronic_structure.boltztrap2 import BoltztrapRunner

runner = BoltztrapRunner(struct, nelec=n_electrons)
runner.run()

# Get transport properties at different temperatures
results = runner.get_results()

Diffraction

X-ray Diffraction (XRD)

from pymatgen.analysis.diffraction.xrd import XRDCalculator

xrd = XRDCalculator()

pattern = xrd.get_pattern(struct, two_theta_range=(0, 90))

# Get peak data
for peak in pattern.hkls:
    print(f"2θ = {peak['2theta']:.2f}°, hkl = {peak['hkl']}, I = {peak['intensity']:.1f}")

# Plot pattern
pattern.plot()

Neutron Diffraction

from pymatgen.analysis.diffraction.neutron import NDCalculator

nd = NDCalculator()
pattern = nd.get_pattern(struct)

Elasticity and Mechanical Properties

from pymatgen.analysis.elasticity import ElasticTensor, Stress, Strain

# Create elastic tensor from matrix
elastic_tensor = ElasticTensor([[...]])  # 6x6 or 3x3x3x3 matrix

# Get mechanical properties
bulk_modulus = elastic_tensor.k_voigt  # Voigt bulk modulus (GPa)
shear_modulus = elastic_tensor.g_voigt  # Shear modulus (GPa)
youngs_modulus = elastic_tensor.y_mod  # Young's modulus (GPa)

# Apply strain
strain = Strain([[0.01, 0, 0], [0, 0, 0], [0, 0, 0]])
stress = elastic_tensor.calculate_stress(strain)

Reaction Analysis

Reaction Computation

from pymatgen.analysis.reaction_calculator import ComputedReaction

reactants = [ComputedEntry("Fe", -8.4), ComputedEntry("O2", -4.9)]
products = [ComputedEntry("Fe2O3", -8.3)]

rxn = ComputedReaction(reactants, products)

# Get balanced equation
balanced_rxn = rxn.normalized_repr  # e.g., "2 Fe + 1.5 O2 -> Fe2O3"

# Get reaction energy
energy = rxn.calculated_reaction_energy  # eV per formula unit

Reaction Path Finding

from pymatgen.analysis.path_finder import ChgcarPotential, NEBPathfinder

# Read charge density
chgcar_potential = ChgcarPotential.from_file("CHGCAR")

# Find diffusion path
neb_path = NEBPathfinder(
    start_struct,
    end_struct,
    relax_sites=[i for i in range(len(start_struct))],
    v=chgcar_potential
)

images = neb_path.images  # Interpolated structures for NEB

Molecular Analysis

Bond Analysis

# Get covalent bonds
bonds = mol.get_covalent_bonds()

for bond in bonds:
    print(f"{bond.site1.species_string} - {bond.site2.species_string}: {bond.length:.2f} Å")

Molecule Graph

from pymatgen.analysis.graphs import MoleculeGraph
from pymatgen.analysis.local_env import OpenBabelNN

# Build molecule graph
mg = MoleculeGraph.with_local_env_strategy(mol, OpenBabelNN())

# Get fragments
fragments = mg.get_disconnected_fragments()

# Find rings
rings = mg.find_rings()

Spectroscopy

X-ray Absorption Spectroscopy (XAS)

from pymatgen.analysis.xas.spectrum import XAS

# Read XAS spectrum
xas = XAS.from_file("xas.dat")

# Normalize and process
xas.normalize()

Additional Analysis Tools

Grain Boundaries

from pymatgen.analysis.gb.grain import GrainBoundaryGenerator

gb_gen = GrainBoundaryGenerator(struct)
gb_structures = gb_gen.generate_grain_boundaries(
    rotation_axis=[0, 0, 1],
    rotation_angle=36.87,  # degrees
)

Prototypes and Structure Matching

from pymatgen.analysis.prototypes import AflowPrototypeMatcher

matcher = AflowPrototypeMatcher()
prototype = matcher.get_prototypes(struct)

Best Practices

  1. Start simple: Use basic analysis before advanced methods
  2. Validate results: Cross-check analysis with multiple methods
  3. Consider symmetry: Use SpacegroupAnalyzer to reduce computational cost
  4. Check convergence: Ensure input structures are well-converged
  5. Use appropriate methods: Different analyses have different accuracy/speed tradeoffs
  6. Visualize results: Use built-in plotters for quick validation
  7. Save intermediate results: Complex analyses can be time-consuming