use crate::applications::{
ApplicationError, ApplicationResult, IndustrySolution, OptimizationProblem,
};
use super::types::{
Angle, Atom, BasisFunction, BasisFunctionType, Bond, BondOrder, ChemistryObjective,
CoordinateSystem, MolecularGeometry, MolecularSystem, QuantumChemistryConfig,
QuantumChemistryOptimizer, QuantumChemistryProblem, QuantumChemistryResult,
};
pub fn create_example_molecular_systems() -> ApplicationResult<Vec<MolecularSystem>> {
let mut systems = Vec::new();
let water = MolecularSystem {
id: "water".to_string(),
charge: 0,
multiplicity: 1,
atoms: vec![
Atom {
atomic_number: 8,
symbol: "O".to_string(),
mass: 15.999,
position: [0.0, 0.0, 0.0],
partial_charge: Some(-0.834),
basis_functions: vec![BasisFunction {
function_type: BasisFunctionType::GTO,
angular_momentum: (0, 0, 0),
exponent: 130.7093,
coefficients: vec![0.1543],
center: [0.0, 0.0, 0.0],
}],
},
Atom {
atomic_number: 1,
symbol: "H".to_string(),
mass: 1.008,
position: [0.758, 0.0, 0.586],
partial_charge: Some(0.417),
basis_functions: vec![BasisFunction {
function_type: BasisFunctionType::GTO,
angular_momentum: (0, 0, 0),
exponent: 3.425_251,
coefficients: vec![0.1543],
center: [0.758, 0.0, 0.586],
}],
},
Atom {
atomic_number: 1,
symbol: "H".to_string(),
mass: 1.008,
position: [-0.758, 0.0, 0.586],
partial_charge: Some(0.417),
basis_functions: vec![BasisFunction {
function_type: BasisFunctionType::GTO,
angular_momentum: (0, 0, 0),
exponent: 3.425_251,
coefficients: vec![0.1543],
center: [-0.758, 0.0, 0.586],
}],
},
],
geometry: MolecularGeometry {
coordinate_system: CoordinateSystem::Cartesian,
bonds: vec![
Bond {
atom1: 0,
atom2: 1,
length: 0.96,
order: BondOrder::Single,
strength: 460.0,
},
Bond {
atom1: 0,
atom2: 2,
length: 0.96,
order: BondOrder::Single,
strength: 460.0,
},
],
angles: vec![Angle {
atom1: 1,
atom2: 0,
atom3: 2,
angle: 104.5_f64.to_radians(),
}],
dihedrals: vec![],
point_group: Some("C2v".to_string()),
},
external_fields: vec![],
constraints: vec![],
};
systems.push(water);
let methane = MolecularSystem {
id: "methane".to_string(),
charge: 0,
multiplicity: 1,
atoms: vec![
Atom {
atomic_number: 6,
symbol: "C".to_string(),
mass: 12.011,
position: [0.0, 0.0, 0.0],
partial_charge: Some(-0.4),
basis_functions: vec![BasisFunction {
function_type: BasisFunctionType::GTO,
angular_momentum: (0, 0, 0),
exponent: 71.6168,
coefficients: vec![0.1543],
center: [0.0, 0.0, 0.0],
}],
},
Atom {
atomic_number: 1,
symbol: "H".to_string(),
mass: 1.008,
position: [0.629, 0.629, 0.629],
partial_charge: Some(0.1),
basis_functions: vec![BasisFunction {
function_type: BasisFunctionType::GTO,
angular_momentum: (0, 0, 0),
exponent: 3.425_251,
coefficients: vec![0.1543],
center: [0.629, 0.629, 0.629],
}],
},
Atom {
atomic_number: 1,
symbol: "H".to_string(),
mass: 1.008,
position: [-0.629, -0.629, 0.629],
partial_charge: Some(0.1),
basis_functions: vec![BasisFunction {
function_type: BasisFunctionType::GTO,
angular_momentum: (0, 0, 0),
exponent: 3.425_251,
coefficients: vec![0.1543],
center: [-0.629, -0.629, 0.629],
}],
},
Atom {
atomic_number: 1,
symbol: "H".to_string(),
mass: 1.008,
position: [-0.629, 0.629, -0.629],
partial_charge: Some(0.1),
basis_functions: vec![BasisFunction {
function_type: BasisFunctionType::GTO,
angular_momentum: (0, 0, 0),
exponent: 3.425_251,
coefficients: vec![0.1543],
center: [-0.629, 0.629, -0.629],
}],
},
Atom {
atomic_number: 1,
symbol: "H".to_string(),
mass: 1.008,
position: [0.629, -0.629, -0.629],
partial_charge: Some(0.1),
basis_functions: vec![BasisFunction {
function_type: BasisFunctionType::GTO,
angular_momentum: (0, 0, 0),
exponent: 3.425_251,
coefficients: vec![0.1543],
center: [0.629, -0.629, -0.629],
}],
},
],
geometry: MolecularGeometry {
coordinate_system: CoordinateSystem::Cartesian,
bonds: vec![
Bond {
atom1: 0,
atom2: 1,
length: 1.09,
order: BondOrder::Single,
strength: 414.0,
},
Bond {
atom1: 0,
atom2: 2,
length: 1.09,
order: BondOrder::Single,
strength: 414.0,
},
Bond {
atom1: 0,
atom2: 3,
length: 1.09,
order: BondOrder::Single,
strength: 414.0,
},
Bond {
atom1: 0,
atom2: 4,
length: 1.09,
order: BondOrder::Single,
strength: 414.0,
},
],
angles: vec![],
dihedrals: vec![],
point_group: Some("Td".to_string()),
},
external_fields: vec![],
constraints: vec![],
};
systems.push(methane);
Ok(systems)
}
pub fn create_benchmark_problems(
num_problems: usize,
) -> ApplicationResult<
Vec<Box<dyn OptimizationProblem<Solution = QuantumChemistryResult, ObjectiveValue = f64>>>,
> {
let mut problems = Vec::new();
let systems = create_example_molecular_systems()?;
for i in 0..num_problems {
let system = systems[i % systems.len()].clone();
let problem = QuantumChemistryProblem {
system,
config: QuantumChemistryConfig::default(),
objectives: vec![ChemistryObjective::MinimizeEnergy],
};
problems.push(Box::new(problem)
as Box<
dyn OptimizationProblem<Solution = QuantumChemistryResult, ObjectiveValue = f64>,
>);
}
Ok(problems)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_quantum_chemistry_optimizer_creation() {
let config = QuantumChemistryConfig::default();
let optimizer = QuantumChemistryOptimizer::new(config);
assert!(optimizer.is_ok());
}
#[test]
fn test_molecular_system_creation() {
let systems =
create_example_molecular_systems().expect("should create example molecular systems");
assert_eq!(systems.len(), 2);
assert_eq!(systems[0].id, "water");
assert_eq!(systems[1].id, "methane");
}
#[test]
fn test_benchmark_problems() {
let problems = create_benchmark_problems(5).expect("should create benchmark problems");
assert_eq!(problems.len(), 5);
}
#[test]
fn test_quantum_chemistry_problem_validation() {
let systems =
create_example_molecular_systems().expect("should create molecular systems for test");
let problem = QuantumChemistryProblem {
system: systems[0].clone(),
config: QuantumChemistryConfig::default(),
objectives: vec![ChemistryObjective::MinimizeEnergy],
};
assert!(problem.validate().is_ok());
assert!(!problem.description().is_empty());
}
}