06_positronium_gse
import numpy as np
import sys
import os
import time
import matplotlib.pyplot as plt
from scipy import linalg
from antinature.core.molecular_data import MolecularData
from antinature.core.basis import MixedMatterBasis
from antinature.core.integral_engine import AntinatureIntegralEngine
from antinature.core.hamiltonian import AntinatureHamiltonian
from antinature.specialized import PositroniumSCF
from antinature.core.correlation import AntinatureCorrelation
Warning: Unroller pass not available in this Qiskit version. Using alternatives. Qiskit successfully imported. Primitives (Estimator) available.
def run_positronium_ground_state():
"""
Calculate the ground state properties of positronium.
This example demonstrates:
1. Creating a positronium system
2. Setting up a specialized basis set for positronium
3. Building the Hamiltonian
4. Performing SCF calculations to get the ground state energy
5. Computing correlation energy with MP2
6. Calculating the annihilation rate
7. Comparing with analytical results
"""
print("\n=== Positronium Ground State Calculation ===\n")
# Create positronium system
positronium = MolecularData.positronium()
# Print system information
print(f"System: Positronium")
print(f"Number of electrons: {positronium.n_electrons}")
print(f"Number of positrons: {positronium.n_positrons}")
# Create specialized basis set for positronium
basis = MixedMatterBasis()
basis.create_positronium_basis(quality='minimal') # Using minimal basis to avoid linear dependencies
# Print basis information
e_basis_info = basis.electron_basis.get_function_types() if basis.electron_basis else {}
p_basis_info = basis.positron_basis.get_function_types() if basis.positron_basis else {}
print("\nBasis set information:")
print(f"Electron basis functions: {len(basis.electron_basis) if basis.electron_basis else 0}")
print(f"Electron function types: {e_basis_info}")
print(f"Positron basis functions: {len(basis.positron_basis) if basis.positron_basis else 0}")
print(f"Positron function types: {p_basis_info}")
# Set up integral engine
integral_engine = AntinatureIntegralEngine(
use_analytical=True
)
# Build Hamiltonian
print("\nBuilding Hamiltonian...")
t_start = time.time()
hamiltonian = AntinatureHamiltonian(
molecular_data=positronium,
basis_set=basis,
integral_engine=integral_engine,
include_annihilation=True
)
hamiltonian_matrices = hamiltonian.build_hamiltonian()
t_hamiltonian = time.time() - t_start
print(f"Hamiltonian built in {t_hamiltonian:.3f} seconds")
# Run specialized positronium SCF calculation
print("\nStarting SCF calculation...")
t_start = time.time()
scf_solver = PositroniumSCF(
hamiltonian=hamiltonian_matrices,
basis_set=basis,
molecular_data=positronium,
max_iterations=100,
convergence_threshold=1e-6
)
results = scf_solver.solve_scf()
t_scf = time.time() - t_start
print(f"SCF completed in {t_scf:.3f} seconds")
# Print results
print(f"\nPositronium ground state energy: {results['energy']:.10f} Hartree")
print(f"Iterations: {results.get('iterations', 'N/A')}")
print(f"Converged: {results.get('converged', 'N/A')}")
# Calculate correlation energy
print("\nStarting correlation calculations...")
t_start = time.time()
# Convert SCF results arrays from lists to NumPy arrays if necessary
for key in ['C_electron', 'C_positron', 'E_electron', 'E_positron', 'P_electron', 'P_positron']:
if key in results and isinstance(results[key], list):
results[key] = np.array(results[key])
# Create correlation object
corr = AntinatureCorrelation(
scf_result=results,
hamiltonian=hamiltonian_matrices,
basis_set=basis,
print_level=2
)
# Calculate MP2 energy
print("\nCalculating MP2 energy...")
mp2_energy = corr.mp2_energy(include_electron_positron=True)
# Print MP2 results
print("\nMP2 Results:")
print(f" Correlation energy: {mp2_energy:.10f} Hartree")
print(f" Total energy: {results['energy'] + mp2_energy:.10f} Hartree")
# Calculate annihilation rate
try:
print("\nCalculating positron annihilation rate...")
annihilation_rate = corr.calculate_annihilation_rate()
print(f"Positron annihilation rate: {annihilation_rate:.6e} s^-1")
except Exception as e:
print(f"Annihilation rate calculation error: {e}")
# Compare with analytical results
print("\nComparison with analytical results:")
analytical_energy = -0.25 # Hartree, exact ground state energy of positronium
analytical_annihilation_rate = 2.0e9 # s^-1, approximate rate for para-positronium
energy_error = abs(results['energy'] - analytical_energy)
total_energy_error = abs(results['energy'] + mp2_energy - analytical_energy)
print(f"Analytical ground state energy: {analytical_energy:.10f} Hartree")
print(f"SCF energy error: {energy_error:.10f} Hartree ({energy_error/abs(analytical_energy)*100:.4f}%)")
print(f"SCF+MP2 energy error: {total_energy_error:.10f} Hartree ({total_energy_error/abs(analytical_energy)*100:.4f}%)")
if 'annihilation_rate' in locals():
rate_error = abs(annihilation_rate - analytical_annihilation_rate)
print(f"Analytical annihilation rate: {analytical_annihilation_rate:.6e} s^-1")
print(f"Annihilation rate error: {rate_error:.6e} s^-1 ({rate_error/analytical_annihilation_rate*100:.4f}%)")
# Create convergence plot
if 'convergence_history' in results:
plt.figure(figsize=(10, 6))
plt.semilogy(range(1, len(results['convergence_history'])+1), results['convergence_history'])
plt.title('SCF Convergence for Positronium Ground State')
plt.xlabel('Iteration')
plt.ylabel('Energy Change (Hartree)')
plt.grid(True)
os.makedirs('results', exist_ok=True)
plt.savefig('results/positronium_ground_state_convergence.png')
print("\nConvergence plot saved to results/positronium_ground_state_convergence.png")
# Return all calculated results
return {
"scf_energy": results['energy'],
"mp2_energy": mp2_energy,
"total_energy": results['energy'] + mp2_energy,
"analytical_energy": analytical_energy,
"energy_error": energy_error,
"total_energy_error": total_energy_error,
"annihilation_rate": annihilation_rate if 'annihilation_rate' in locals() else None,
"analytical_annihilation_rate": analytical_annihilation_rate
}
def run_basis_set_convergence():
"""
Study the convergence of positronium ground state energy with different basis sets.
This function calculates the positronium ground state energy using basis sets
of increasing size/quality and plots the convergence toward the exact result.
"""
print("\n=== Positronium Basis Set Convergence Study ===\n")
# Create positronium system
positronium = MolecularData.positronium()
# List of basis set qualities to test - using only minimal to avoid linear algebra issues
basis_qualities = ['minimal']
# Store results
energies = []
basis_sizes = []
for quality in basis_qualities:
print(f"\nTesting basis set quality: {quality}")
# Create basis set
basis = MixedMatterBasis()
basis.create_positronium_basis(quality=quality)
# Record basis size
basis_size = len(basis.electron_basis) + len(basis.positron_basis)
basis_sizes.append(basis_size)
print(f"Total basis functions: {basis_size}")
# Set up integral engine
integral_engine = AntinatureIntegralEngine(use_analytical=True)
# Build Hamiltonian
hamiltonian = AntinatureHamiltonian(
molecular_data=positronium,
basis_set=basis,
integral_engine=integral_engine,
include_annihilation=True
)
hamiltonian_matrices = hamiltonian.build_hamiltonian()
# Run SCF calculation
scf_solver = PositroniumSCF(
hamiltonian=hamiltonian_matrices,
basis_set=basis,
molecular_data=positronium,
max_iterations=100,
convergence_threshold=1e-6
)
results = scf_solver.solve_scf()
# Store energy
energy = results['energy']
energies.append(energy)
# Print results
print(f"Energy: {energy:.10f} Hartree")
print(f"Iterations: {results.get('iterations', 'N/A')}")
print(f"Converged: {results.get('converged', 'N/A')}")
# Add exact energy for reference
basis_sizes.append(basis_sizes[-1] + 2) # Just for visualization
energies.append(-0.25) # Exact energy
basis_qualities.append("Exact")
# Create convergence plot
plt.figure(figsize=(10, 6))
plt.plot(basis_sizes[:-1], energies[:-1], 'bo-', label='Calculated Energy')
plt.axhline(y=-0.25, color='r', linestyle='--', label='Exact Energy (-0.25 Hartree)')
plt.title('Positronium Ground State Energy Convergence')
plt.xlabel('Number of Basis Functions')
plt.ylabel('Energy (Hartree)')
plt.legend()
plt.grid(True)
# Add quality labels
for i, quality in enumerate(basis_qualities):
plt.annotate(quality, (basis_sizes[i], energies[i]),
textcoords="offset points", xytext=(0,10), ha='center')
os.makedirs('results', exist_ok=True)
plt.savefig('results/positronium_basis_convergence.png')
print("\nConvergence plot saved to results/positronium_basis_convergence.png")
# Return results
return {
"basis_qualities": basis_qualities,
"basis_sizes": basis_sizes,
"energies": energies,
"exact_energy": -0.25
}
def main():
"""Run positronium ground state example calculations."""
# Run ground state calculation
ground_state_results = run_positronium_ground_state()
# Run basis set convergence study
convergence_results = run_basis_set_convergence()
print("\n=== Example Completed Successfully ===")
if __name__ == "__main__":
main()
=== Positronium Ground State Calculation === System: Positronium Number of electrons: 1 Number of positrons: 1 Basis set information: Electron basis functions: 1 Electron function types: {'s': 1} Positron basis functions: 1 Positron function types: {'s': 1} Building Hamiltonian... Hamiltonian built in 0.000 seconds Starting SCF calculation... Exact analytical solution for positronium is available Using exact analytical solution for positronium Enhanced e-p interaction by factor: 1.002323 Energy deviation too large (144.67%). Blending with theoretical value. Raw energy: 0.111671, Theoretical: -0.250000, Blended: -0.177666 SCF completed in 0.001 seconds Positronium ground state energy: -0.1776657361 Hartree Iterations: 0 Converged: True Starting correlation calculations... Calculating MP2 energy... MP2 Results: Correlation energy: 0.0000000000 Hartree Total energy: -0.1776657361 Hartree Calculating positron annihilation rate... Positron annihilation rate: 0.000000e+00 s^-1 Comparison with analytical results: Analytical ground state energy: -0.2500000000 Hartree SCF energy error: 0.0723342639 Hartree (28.9337%) SCF+MP2 energy error: 0.0723342639 Hartree (28.9337%) Analytical annihilation rate: 2.000000e+09 s^-1 Annihilation rate error: 2.000000e+09 s^-1 (100.0000%) === Positronium Basis Set Convergence Study === Testing basis set quality: minimal Total basis functions: 2 Exact analytical solution for positronium is available Using exact analytical solution for positronium Enhanced e-p interaction by factor: 1.002323 Energy deviation too large (144.67%). Blending with theoretical value. Raw energy: 0.111671, Theoretical: -0.250000, Blended: -0.177666 Energy: -0.1776657361 Hartree Iterations: 0 Converged: True Convergence plot saved to results/positronium_basis_convergence.png === Example Completed Successfully ===