Python-based quantum chemistry framework providing electronic structure methods for molecular simulations
—
Molecular properties including analytical derivatives, vibrational analysis, and response properties for structure optimization, transition state searches, and spectroscopic property calculations.
First derivatives of the energy with respect to nuclear coordinates for geometry optimization and force calculations.
class Gradients:
"""
Base analytical gradient class.
Provides framework for calculating analytical first derivatives
of electronic energy with respect to nuclear coordinates.
"""
def __init__(self, method):
"""Initialize gradient calculation for given method."""
def run(self, mo_coeff=None, mo_occ=None, atmlst=None):
"""
Calculate analytical gradients.
Parameters:
- mo_coeff: ndarray, molecular orbital coefficients
- mo_occ: ndarray, orbital occupations
- atmlst: list, atoms for which to calculate gradients
Returns:
ndarray, gradients for each atom (natm, 3)
"""
class RHF_Gradients:
"""Analytical gradients for restricted Hartree-Fock."""
class UHF_Gradients:
"""Analytical gradients for unrestricted Hartree-Fock."""
class RKS_Gradients:
"""Analytical gradients for restricted Kohn-Sham DFT."""
class UKS_Gradients:
"""Analytical gradients for unrestricted Kohn-Sham DFT."""
class MP2_Gradients:
"""Analytical gradients for MP2 correlation method."""
class CCSD_Gradients:
"""Analytical gradients for CCSD correlation method."""Second derivatives for vibrational frequency analysis, transition state optimization, and reaction path following.
class Hessian:
"""
Base analytical Hessian class.
Calculates second derivatives of energy with respect to
nuclear coordinates for vibrational analysis.
"""
def __init__(self, method):
"""Initialize Hessian calculation for given method."""
def run(self, mo_coeff=None, mo_occ=None, atmlst=None):
"""
Calculate analytical Hessian matrix.
Returns:
ndarray, Hessian matrix (3*natm, 3*natm)
"""
def freq(self, anharm=False):
"""
Calculate vibrational frequencies from Hessian.
Parameters:
- anharm: bool, include anharmonic corrections
Returns:
tuple of (frequencies, normal_modes)
"""
class RHF_Hessian:
"""Analytical Hessian for restricted Hartree-Fock."""
class UHF_Hessian:
"""Analytical Hessian for unrestricted Hartree-Fock."""
class RKS_Hessian:
"""Analytical Hessian for restricted Kohn-Sham DFT."""Linear response methods for excited states, transition properties, and dynamic response functions.
class TDHF:
"""
Time-dependent Hartree-Fock (Random Phase Approximation).
Calculates excited state energies and transition properties
using linear response theory with HF reference.
Attributes:
- nstates: int, number of excited states (default: 3)
- singlet: bool, calculate singlet states (default: True)
- triplet: bool, calculate triplet states (default: False)
"""
def __init__(self, mf):
"""Initialize TDHF from SCF reference."""
def run(self, nstates=None):
"""
Run TDHF calculation.
Returns:
tuple of (excitation_energies, transition_dipoles)
"""
class TDDFT:
"""
Time-dependent Density Functional Theory.
Linear response DFT including exchange-correlation kernel
for improved treatment of excitation energies.
"""
class TDA:
"""
Tamm-Dancoff Approximation.
Simplified TDDFT with only particle-hole excitations,
neglecting hole-particle coupling terms.
"""Response properties for describing molecular response to external electric fields.
def polarizability(mf, freq=0):
"""
Calculate static or frequency-dependent polarizability.
Parameters:
- mf: SCF object
- freq: float or array, frequencies (default: 0 for static)
Returns:
ndarray, polarizability tensor (3, 3) or (nfreq, 3, 3)
"""
def hyperpolarizability(mf, freq=None):
"""
Calculate first hyperpolarizability (beta tensor).
Parameters:
- mf: SCF object
- freq: frequency specification
Returns:
ndarray, hyperpolarizability tensor
"""NMR chemical shifts, coupling constants, and magnetic properties.
def nmr_shielding(mf, atoms=None):
"""
Calculate NMR shielding tensors.
Parameters:
- mf: SCF object
- atoms: list, atom indices (default: all atoms)
Returns:
dict, shielding tensors for each atom
"""
def spin_spin_coupling(mf, atom1, atom2):
"""
Calculate spin-spin coupling constant between two nuclei.
Parameters:
- mf: SCF object
- atom1, atom2: int, atom indices
Returns:
float, coupling constant in Hz
"""Quadrupolar coupling and electric field gradient calculations.
def efg(mf, atoms=None):
"""
Calculate electric field gradients at nuclei.
Parameters:
- mf: SCF object
- atoms: list, atom indices
Returns:
dict, EFG tensors for each atom
"""import pyscf
from pyscf import geomopt
# Calculate analytical gradients
mol = pyscf.M(atom='H2O', basis='6-31g')
mf = mol.RHF().run()
grad = pyscf.grad.RHF(mf)
forces = grad.run()
print("Forces on atoms:", forces)
# Geometry optimization using gradients
mol_opt = geomopt.optimize(mf)
print("Optimized geometry:", mol_opt.atom_coords())
# DFT gradients
mf_dft = mol.RKS(xc='b3lyp').run()
grad_dft = pyscf.grad.RKS(mf_dft).run()# Calculate Hessian and frequencies
mol = pyscf.M(atom='H2O', basis='6-31g')
mf = mol.RHF().run()
hess = pyscf.hessian.RHF(mf)
hessian_matrix = hess.run()
# Extract vibrational frequencies
freqs, modes = hess.freq()
print("Vibrational frequencies (cm^-1):")
for i, freq in enumerate(freqs):
if freq > 0:
print(f"Mode {i}: {freq:.1f}")
else:
print(f"Mode {i}: {freq:.1f}i (imaginary)")# TDDFT for excited states
mol = pyscf.M(atom='CH2O', basis='6-31g')
mf = mol.RKS(xc='b3lyp').run()
td = pyscf.tdscf.TDDFT(mf)
td.nstates = 5
excitation_energies = td.run()
print("Excitation energies (eV):")
for i, energy in enumerate(excitation_energies):
eV = energy * 27.2114
print(f"State {i+1}: {eV:.2f} eV")
# Calculate oscillator strengths
osc_strengths = td.oscillator_strength()
for i, f in enumerate(osc_strengths):
print(f"State {i+1} oscillator strength: {f:.4f}")# Static polarizability
mol = pyscf.M(atom='H2O', basis='aug-cc-pvdz')
mf = mol.RHF().run()
alpha = pyscf.prop.polarizability.polarizability(mf)
print("Polarizability tensor:", alpha)
# Frequency-dependent polarizability
freqs = [0.0, 0.1, 0.2] # atomic units
alpha_w = pyscf.prop.polarizability.polarizability(mf, freq=freqs)
print("Frequency-dependent polarizability:", alpha_w)# NMR shielding constants
mol = pyscf.M(atom='CH4', basis='pcSseg-1')
mf = mol.RHF().run()
nmr_data = pyscf.prop.nmr.shielding(mf)
for i, atom in enumerate(mol.atom):
symbol = atom[0]
shielding = nmr_data[i]
isotropic = (shielding[0,0] + shielding[1,1] + shielding[2,2]) / 3
print(f"{symbol} NMR shielding: {isotropic:.1f} ppm")# Electric field gradient
mol = pyscf.M(atom='H2O', basis='6-311g')
mf = mol.RHF().run()
efg_tensors = pyscf.prop.efg.efg(mf)
# Spin-orbit coupling matrix elements
soc = pyscf.prop.soc.soc_matrix(mf)
# Magnetic susceptibility
chi = pyscf.prop.magnetizability.magnetizability(mf)from typing import Dict, TypedDict
import numpy as np
ndarray = np.ndarray
# Property result types
PropertyTensor = ndarray # General property tensor
# Gradient types
Forces = ndarray # Shape (natm, 3)
Hessian = ndarray # Shape (3*natm, 3*natm)
# Excited state properties
ExcitationData = TypedDict('ExcitationData', {
'energies': ndarray,
'oscillator_strengths': ndarray,
'transition_dipoles': ndarray
})
# Vibrational data
VibrationalData = TypedDict('VibrationalData', {
'frequencies': ndarray,
'normal_modes': ndarray,
'reduced_masses': ndarray,
'force_constants': ndarray
})
# NMR data structures
NMRShielding = Dict[int, ndarray] # atom_id -> shielding tensorInstall with Tessl CLI
npx tessl i tessl/pypi-pyscf