qsym2/target/noci/
basis_orbit.rs1use anyhow::Context;
4use derive_builder::Builder;
5
6use crate::{
7 analysis::{Orbit, OrbitIterator},
8 group::GroupProperties,
9 symmetry::{
10 symmetry_group::SymmetryGroupProperties,
11 symmetry_transformation::{SymmetryTransformable, SymmetryTransformationKind},
12 },
13 target::noci::basis::Basis,
14};
15
16#[derive(Builder, Clone)]
27pub struct BasisSymmetryOrbit<'a, 'g, G, B>
28where
29 G: GroupProperties,
30 B: Basis,
31{
32 group: &'g G,
34
35 origin: &'a B,
37
38 symmetry_transformation_kind: SymmetryTransformationKind,
41}
42
43impl<'a, 'g, G, B> BasisSymmetryOrbit<'a, 'g, G, B>
48where
49 G: GroupProperties + Clone,
50 B: Basis + Clone,
51{
52 pub fn builder() -> BasisSymmetryOrbitBuilder<'a, 'g, G, B> {
54 BasisSymmetryOrbitBuilder::default()
55 }
56
57 pub fn origin(&self) -> &B {
59 self.origin
60 }
61
62 pub fn symmetry_transformation_kind(&self) -> &SymmetryTransformationKind {
64 &self.symmetry_transformation_kind
65 }
66}
67
68impl<'a, 'g, G, B> Orbit<G, B> for BasisSymmetryOrbit<'a, 'g, G, B>
77where
78 G: SymmetryGroupProperties,
79 B: Basis + Clone + SymmetryTransformable,
80{
81 type OrbitIter = OrbitIterator<'a, G, B>;
82
83 fn group(&self) -> &G {
84 self.group
85 }
86
87 fn origin(&self) -> &B {
88 self.origin
89 }
90
91 fn iter(&self) -> Self::OrbitIter {
92 OrbitIterator::new(
93 self.group,
94 self.origin,
95 match self.symmetry_transformation_kind {
96 SymmetryTransformationKind::Spatial => |op, basis| {
97 basis.sym_transform_spatial(op).with_context(|| {
98 format!("Unable to apply `{op}` spatially on the origin basis")
99 })
100 },
101 SymmetryTransformationKind::SpatialWithSpinTimeReversal => |op, basis| {
102 basis.sym_transform_spatial_with_spintimerev(op).with_context(|| {
103 format!("Unable to apply `{op}` spatially (with spin-including time reversal) on the origin basis")
104 })
105 },
106 SymmetryTransformationKind::Spin => |op, basis| {
107 basis.sym_transform_spin(op).with_context(|| {
108 format!("Unable to apply `{op}` spin-wise on the origin basis")
109 })
110 },
111 SymmetryTransformationKind::SpinSpatial => |op, basis| {
112 basis.sym_transform_spin_spatial(op).with_context(|| {
113 format!("Unable to apply `{op}` spin-spatially on the origin basis")
114 })
115 },
116 },
117 )
118 }
119}