use crate::error::{Result, SimulatorError};
use scirs2_core::ndarray::{Array1, Array2, Array3, Array4};
use scirs2_core::random::prelude::*;
use std::collections::HashMap;
use super::types::{
AccuracyLevel, AtomicCenter, BasisSetType, ConvergenceInfo, DMRGResult, DMRGState,
ElectronicStructureMethod, MemoryStatistics, PointGroupSymmetry,
QuantumChemistryBenchmarkResults, QuantumChemistryDMRGConfig, QuantumChemistryDMRGSimulator,
QuantumChemistryDMRGUtils, QuantumNumberSector, SpectroscopicProperties, TimingStatistics,
};
pub fn benchmark_quantum_chemistry_dmrg() -> Result<QuantumChemistryBenchmarkResults> {
let test_molecules = QuantumChemistryDMRGUtils::create_standard_test_molecules();
let config = QuantumChemistryDMRGConfig::default();
let mut simulator = QuantumChemistryDMRGSimulator::new(config)?;
simulator.benchmark_performance(test_molecules)
}
#[cfg(test)]
#[allow(clippy::field_reassign_with_default)]
mod tests {
use super::*;
#[test]
fn test_quantum_chemistry_dmrg_initialization() {
let config = QuantumChemistryDMRGConfig::default();
let simulator = QuantumChemistryDMRGSimulator::new(config);
assert!(simulator.is_ok());
}
#[test]
fn test_hamiltonian_construction() {
let mut config = QuantumChemistryDMRGConfig::default();
config.molecular_geometry = vec![
AtomicCenter {
symbol: "H".to_string(),
atomic_number: 1,
position: [0.0, 0.0, 0.0],
nuclear_charge: 1.0,
basis_functions: Vec::new(),
},
AtomicCenter {
symbol: "H".to_string(),
atomic_number: 1,
position: [1.4, 0.0, 0.0],
nuclear_charge: 1.0,
basis_functions: Vec::new(),
},
];
let mut simulator =
QuantumChemistryDMRGSimulator::new(config).expect("Failed to create DMRG simulator");
let hamiltonian = simulator.construct_hamiltonian();
assert!(hamiltonian.is_ok());
let h = hamiltonian.expect("Failed to construct Hamiltonian");
assert!(h.nuclear_repulsion > 0.0);
assert_eq!(h.one_electron_integrals.shape(), [10, 10]);
assert_eq!(h.two_electron_integrals.shape(), [10, 10, 10, 10]);
}
#[test]
fn test_dmrg_state_initialization() {
let config = QuantumChemistryDMRGConfig::default();
let simulator =
QuantumChemistryDMRGSimulator::new(config).expect("Failed to create DMRG simulator");
let state = simulator.initialize_dmrg_state();
assert!(state.is_ok());
let s = state.expect("Failed to initialize DMRG state");
assert_eq!(s.site_tensors.len(), 10);
assert!(!s.bond_matrices.is_empty());
assert_eq!(s.quantum_numbers.particle_number, 10);
}
#[test]
fn test_ground_state_calculation() {
let mut config = QuantumChemistryDMRGConfig::default();
config.max_sweeps = 2;
config.num_orbitals = 4;
config.num_electrons = 4;
let mut simulator =
QuantumChemistryDMRGSimulator::new(config).expect("Failed to create DMRG simulator");
let result = simulator.calculate_ground_state();
assert!(result.is_ok());
let r = result.expect("Failed to calculate ground state");
assert!(r.ground_state_energy < 0.0);
assert!(r.correlation_energy.abs() > 0.0);
assert_eq!(r.natural_occupations.len(), 4);
}
#[test]
fn test_excited_state_calculation() {
let mut config = QuantumChemistryDMRGConfig::default();
config.state_averaging = true;
config.num_excited_states = 2;
config.max_sweeps = 2;
config.num_orbitals = 4;
config.num_electrons = 4;
let mut simulator =
QuantumChemistryDMRGSimulator::new(config).expect("Failed to create DMRG simulator");
let result = simulator.calculate_excited_states(2);
assert!(result.is_ok());
let r = result.expect("Failed to calculate excited states");
assert_eq!(r.excited_state_energies.len(), 2);
assert_eq!(r.excited_states.len(), 2);
assert!(r.excited_state_energies[0] > r.ground_state_energy);
}
#[test]
fn test_correlation_energy_calculation() {
let mut config = QuantumChemistryDMRGConfig::default();
config.num_orbitals = 4;
config.num_electrons = 4;
let mut simulator =
QuantumChemistryDMRGSimulator::new(config).expect("Failed to create DMRG simulator");
let result = simulator
.calculate_ground_state()
.expect("Failed to calculate ground state");
let correlation_energy = simulator.calculate_correlation_energy(&result);
assert!(correlation_energy.is_ok());
assert!(
correlation_energy
.expect("Failed to calculate correlation energy")
.abs()
> 0.0
);
}
#[test]
fn test_active_space_analysis() {
let mut config = QuantumChemistryDMRGConfig::default();
config.num_orbitals = 6;
let mut simulator =
QuantumChemistryDMRGSimulator::new(config).expect("Failed to create DMRG simulator");
simulator
.construct_hamiltonian()
.expect("Failed to construct Hamiltonian");
let analysis = simulator.analyze_active_space();
assert!(analysis.is_ok());
let a = analysis.expect("Failed to analyze active space");
assert_eq!(a.orbital_contributions.len(), 6);
assert!(!a.suggested_active_orbitals.is_empty());
assert!(a.correlation_strength >= 0.0 && a.correlation_strength <= 1.0);
}
#[test]
fn test_molecular_properties_calculation() {
let mut config = QuantumChemistryDMRGConfig::default();
config.molecular_geometry = vec![
AtomicCenter {
symbol: "H".to_string(),
atomic_number: 1,
position: [0.0, 0.0, 0.0],
nuclear_charge: 1.0,
basis_functions: Vec::new(),
},
AtomicCenter {
symbol: "H".to_string(),
atomic_number: 1,
position: [1.4, 0.0, 0.0],
nuclear_charge: 1.0,
basis_functions: Vec::new(),
},
];
config.num_orbitals = 4;
config.num_electrons = 2;
let mut simulator =
QuantumChemistryDMRGSimulator::new(config).expect("Failed to create DMRG simulator");
let result = simulator
.calculate_ground_state()
.expect("Failed to calculate ground state");
assert_eq!(result.dipole_moments.len(), 3);
assert_eq!(result.quadrupole_moments.shape(), [3, 3]);
assert_eq!(result.mulliken_populations.len(), 4);
assert_eq!(result.bond_orders.shape(), [2, 2]);
assert!(!result
.spectroscopic_properties
.oscillator_strengths
.is_empty());
}
#[test]
fn test_test_molecule_creation() {
let molecules = QuantumChemistryDMRGUtils::create_standard_test_molecules();
assert_eq!(molecules.len(), 3);
let h2 = &molecules[0];
assert_eq!(h2.name, "H2");
assert_eq!(h2.geometry.len(), 2);
assert_eq!(h2.num_electrons, 2);
assert_eq!(h2.num_orbitals, 2);
}
#[test]
fn test_result_validation() {
let mut result = DMRGResult {
ground_state_energy: -1.170,
excited_state_energies: Vec::new(),
ground_state: DMRGState {
bond_dimensions: vec![10],
site_tensors: Vec::new(),
bond_matrices: Vec::new(),
left_canonical: Vec::new(),
right_canonical: Vec::new(),
center_position: 0,
quantum_numbers: QuantumNumberSector {
total_spin: 0,
spatial_irrep: 0,
particle_number: 2,
additional: HashMap::new(),
},
energy: -1.170,
entanglement_entropy: Vec::new(),
},
excited_states: Vec::new(),
correlation_energy: -0.1,
natural_occupations: Array1::zeros(2),
dipole_moments: [0.0; 3],
quadrupole_moments: Array2::zeros((3, 3)),
mulliken_populations: Array1::zeros(2),
bond_orders: Array2::zeros((2, 2)),
spectroscopic_properties: SpectroscopicProperties {
oscillator_strengths: Vec::new(),
transition_dipoles: Vec::new(),
vibrational_frequencies: Vec::new(),
ir_intensities: Vec::new(),
raman_activities: Vec::new(),
nmr_chemical_shifts: HashMap::new(),
},
convergence_info: ConvergenceInfo {
energy_convergence: 1e-8,
wavefunction_convergence: 1e-8,
num_sweeps: 10,
max_bond_dimension_reached: 100,
truncation_errors: Vec::new(),
energy_history: Vec::new(),
converged: true,
},
timing_stats: TimingStatistics {
total_time: 10.0,
hamiltonian_time: 1.0,
dmrg_sweep_time: 7.0,
diagonalization_time: 1.5,
property_time: 0.5,
memory_stats: MemoryStatistics {
peak_memory_mb: 100.0,
mps_memory_mb: 20.0,
hamiltonian_memory_mb: 50.0,
intermediate_memory_mb: 30.0,
},
},
};
let reference_energy = -1.174;
let validation = QuantumChemistryDMRGUtils::validate_results(&result, reference_energy);
assert!(validation.validation_passed);
assert_eq!(
validation.accuracy_level,
AccuracyLevel::QualitativeAccuracy
);
assert!(validation.energy_error < 0.01);
}
#[test]
fn test_computational_cost_estimation() {
let config = QuantumChemistryDMRGConfig::default();
let cost = QuantumChemistryDMRGUtils::estimate_computational_cost(&config);
assert!(cost.estimated_time_seconds > 0.0);
assert!(cost.estimated_memory_mb > 0.0);
assert!(cost.hamiltonian_construction_cost > 0.0);
assert!(cost.dmrg_sweep_cost > 0.0);
assert!(cost.total_operations > 0.0);
}
#[test]
fn test_benchmark_function() {
let result = benchmark_quantum_chemistry_dmrg();
assert!(result.is_ok());
let benchmark = result.expect("Failed to run benchmark");
assert!(benchmark.total_molecules_tested > 0);
assert!(benchmark.success_rate >= 0.0 && benchmark.success_rate <= 1.0);
assert!(!benchmark.individual_results.is_empty());
}
#[test]
fn test_point_group_symmetry() {
let mut config = QuantumChemistryDMRGConfig::default();
config.point_group_symmetry = Some(PointGroupSymmetry::D2h);
let simulator = QuantumChemistryDMRGSimulator::new(config);
assert!(simulator.is_ok());
}
#[test]
fn test_basis_set_types() {
let basis_sets = [
BasisSetType::STO3G,
BasisSetType::DZ,
BasisSetType::CCPVDZ,
BasisSetType::AUGCCPVTZ,
];
for basis_set in &basis_sets {
let mut config = QuantumChemistryDMRGConfig::default();
config.basis_set = *basis_set;
let simulator = QuantumChemistryDMRGSimulator::new(config);
assert!(simulator.is_ok());
}
}
#[test]
fn test_electronic_structure_methods() {
let methods = [
ElectronicStructureMethod::CASSCF,
ElectronicStructureMethod::DMRG,
ElectronicStructureMethod::TDDMRG,
ElectronicStructureMethod::FTDMRG,
];
for method in &methods {
let mut config = QuantumChemistryDMRGConfig::default();
config.electronic_method = *method;
let simulator = QuantumChemistryDMRGSimulator::new(config);
assert!(simulator.is_ok());
}
}
}