Files
2025-11-30 08:30:10 +08:00

531 lines
13 KiB
Markdown

# 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
```python
from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotter
from pymatgen.entries.computed_entries import ComputedEntry
# Create entries (composition and energy per atom)
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
```python
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.
```python
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
```python
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.
```python
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
```python
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
```python
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.
```python
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
```python
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
```python
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
```python
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
```python
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
```python
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
```python
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
```python
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
```python
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)
```python
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
```python
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)
```python
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
```python
from pymatgen.analysis.diffraction.neutron import NDCalculator
nd = NDCalculator()
pattern = nd.get_pattern(struct)
```
## Elasticity and Mechanical Properties
```python
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
```python
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
```python
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
```python
# 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
```python
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)
```python
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
```python
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
```python
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