qsym2/projection/
mod.rs

1//! Symmetry projection via group orbits.
2
3use anyhow::format_err;
4
5use crate::analysis::Orbit;
6use crate::chartab::CharacterTable;
7use crate::chartab::character::Character;
8use crate::chartab::chartab_group::CharacterProperties;
9use crate::group::GroupProperties;
10
11/// Trait to facilitate the application of a group projection operator.
12pub trait Projectable<G, I>: Orbit<G, I>
13where
14    G: GroupProperties + CharacterProperties,
15{
16    /// The type of the result of the projection.
17    type Projected<'p>
18    where
19        Self: 'p;
20
21    // ----------------
22    // Required methods
23    // ----------------
24    /// Projects the orbit onto a symmetry subspace.
25    fn project_onto(&self, row: &G::RowSymbol) -> Self::Projected<'_>;
26
27    // ----------------
28    // Provided methods
29    // ----------------
30    /// Returns an iterator containing each term in the projection summation and the accompanying
31    /// character value (without complex conjugation).
32    fn generate_orbit_algebra_terms<'a>(
33        &'a self,
34        row: &G::RowSymbol,
35    ) -> impl Iterator<Item = Result<(&'a Character, I), anyhow::Error>>
36    where
37        I: 'a,
38        G: 'a,
39    {
40        self.iter().enumerate().map(|(i, item_res)| {
41            let chr = self
42                .group()
43                .get_cc_of_element_index(i)
44                .and_then(|cc_i| self.group().get_cc_symbol_of_index(cc_i))
45                .map(|cc| self.group().character_table().get_character(row, &cc))
46                .ok_or_else(|| {
47                    format_err!(
48                        "Unable to obtain the character of the row {} for element index {i}.",
49                        row.clone()
50                    )
51                })?;
52            item_res.map(|item| (chr, item))
53        })
54    }
55}