qsym2/target/determinant/
determinant_projection.rs1use anyhow::{self, format_err};
4use duplicate::duplicate_item;
5use ndarray::Array1;
6use num::{Complex, ToPrimitive};
7
8use crate::analysis::Orbit;
9use crate::angmom::spinor_rotation_3d::{SpinConstraint, SpinOrbitCoupled};
10use crate::chartab::chartab_symbols::LinearSpaceSymbol;
11use crate::projection::Projectable;
12use crate::symmetry::symmetry_group::SymmetryGroupProperties;
13use crate::target::noci::basis::OrbitBasis;
14use crate::target::noci::multideterminant::MultiDeterminant;
15
16use super::SlaterDeterminant;
17use super::determinant_analysis::SlaterDeterminantSymmetryOrbit;
18
19#[duplicate_item(
20 [
21 dtype_ [ f64 ]
22 sctype_ [ SpinConstraint ]
23 coeffs_ [
24 let coeffs = self
25 .generate_orbit_algebra_terms(row)
26 .map(|item_res| item_res.and_then(|(chr, _)| {
27 let chr_complex = chr.complex_conjugate().complex_value();
28 if chr_complex.im > self.origin().threshold() {
29 Err(format_err!("Complex characters encountered. Slater determinant projection fails over the reals."))
30 } else {
31 Ok(dim_f64 / group_order * chr_complex.re)
32 }
33 }))
34 .collect::<Result<Vec<_>, _>>()?
35 ]
36 ]
37 [
38 dtype_ [ Complex<f64> ]
39 sctype_ [ SpinConstraint ]
40 coeffs_ [
41 let coeffs = self
42 .generate_orbit_algebra_terms(row)
43 .map(|item_res| {
44 item_res
45 .map(|(chr, _)| dim_f64 / group_order * chr.complex_conjugate().complex_value())
46 })
47 .collect::<Result<Vec<_>, _>>()?
48 ]
49 ]
50 [
51 dtype_ [ Complex<f64> ]
52 sctype_ [ SpinOrbitCoupled ]
53 coeffs_ [
54 let coeffs = self
55 .generate_orbit_algebra_terms(row)
56 .map(|item_res| {
57 item_res
58 .map(|(chr, _)| dim_f64 / group_order * chr.complex_conjugate().complex_value())
59 })
60 .collect::<Result<Vec<_>, _>>()?
61 ]
62 ]
63)]
64impl<'a, G> Projectable<G, SlaterDeterminant<'a, dtype_, sctype_>>
65 for SlaterDeterminantSymmetryOrbit<'a, G, dtype_, sctype_>
66where
67 G: SymmetryGroupProperties + Clone,
68{
69 type Projected<'p>
70 = Result<
71 MultiDeterminant<
72 'p,
73 dtype_,
74 OrbitBasis<'p, G, SlaterDeterminant<'p, dtype_, sctype_>>,
75 sctype_,
76 >,
77 anyhow::Error,
78 >
79 where
80 Self: 'p;
81
82 fn project_onto(&self, row: &G::RowSymbol) -> Self::Projected<'_> {
83 let group_order = self
84 .group()
85 .order()
86 .to_f64()
87 .ok_or_else(|| format_err!("Unable to convert the group order to `f64`."))?;
88 let dim_f64 = row
89 .dimensionality()
90 .to_f64()
91 .ok_or_else(|| format_err!("Unable to convert the degeneracy to `f64`."))?;
92
93 let orbit_basis = OrbitBasis::builder()
94 .origins(vec![self.origin().clone()])
95 .group(self.group())
96 .action(self.action())
97 .prefactors(None)
98 .build()
99 .map_err(|err| format_err!(err))?;
100
101 coeffs_;
102
103 MultiDeterminant::builder()
104 .basis(orbit_basis)
105 .coefficients(Array1::from_vec(coeffs))
106 .threshold(self.origin().threshold())
107 .build()
108 .map_err(|err| format_err!(err))
109 }
110}