Skip to main content

gammalooprs/cff/
surface.rs

1use super::{
2    esurface::{Esurface, EsurfaceID},
3    hsurface::{Hsurface, HsurfaceID},
4};
5use bincode_trait_derive::{Decode, Encode};
6use derive_more::From;
7use linnet::half_edge::involution::EdgeIndex;
8use serde::{Deserialize, Serialize};
9use symbolica::{atom::Atom, parse};
10use typed_index_collections::TiVec;
11
12use crate::graph::LoopMomentumBasis;
13
14#[derive(Serialize, Deserialize, Debug, Clone)]
15
16/// A esurface that is equal to 1, useful for represnting a single vertex
17pub struct UnitSurface {}
18
19/// Esurface whose inverse is equal to 0, useful for setting surfaces to zero
20#[derive(Serialize, Deserialize, Debug, Clone)]
21pub struct InfiniteSurface {}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub enum HybridSurface {
25    Esurface(Esurface),
26    Hsurface(Hsurface),
27    Unit(UnitSurface),
28    Infinite(InfiniteSurface),
29}
30
31impl HybridSurface {
32    #[allow(dead_code)]
33    pub(crate) fn to_atom(&self, cut_edges: &[EdgeIndex]) -> Atom {
34        match self {
35            HybridSurface::Esurface(surface) => surface.to_atom(cut_edges),
36            HybridSurface::Hsurface(surface) => surface.to_atom(cut_edges),
37            HybridSurface::Unit(_) => Atom::num(1),
38            HybridSurface::Infinite(_) => parse!("η_inf"),
39        }
40    }
41}
42
43#[derive(Debug, Clone)]
44pub enum HybridSurfaceRef<'a> {
45    Esurface(&'a Esurface),
46    Hsurface(&'a Hsurface),
47    Unit(UnitSurface),
48    Infinite(InfiniteSurface),
49}
50
51impl HybridSurfaceRef<'_> {
52    pub(crate) fn to_atom(&self, cut_edges: &[EdgeIndex]) -> Atom {
53        match self {
54            HybridSurfaceRef::Esurface(surface) => surface.to_atom(cut_edges),
55            HybridSurfaceRef::Hsurface(surface) => surface.to_atom(cut_edges),
56            HybridSurfaceRef::Unit(_) => Atom::num(1),
57            HybridSurfaceRef::Infinite(_) => parse!("η_inf"),
58        }
59    }
60
61    pub(crate) fn to_atom_in_lmb(&self, cut_edges: &[EdgeIndex], lmb: &LoopMomentumBasis) -> Atom {
62        match self {
63            HybridSurfaceRef::Esurface(surface) => surface.to_atom_in_lmb(cut_edges, lmb),
64            HybridSurfaceRef::Hsurface(surface) => surface.to_atom_in_lmb(cut_edges, lmb),
65            HybridSurfaceRef::Unit(_) => Atom::num(1),
66            HybridSurfaceRef::Infinite(_) => parse!("η_inf"),
67        }
68    }
69}
70
71#[derive(From, Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Encode, Decode, Hash)]
72pub enum HybridSurfaceID {
73    Esurface(EsurfaceID),
74    Hsurface(HsurfaceID),
75    Unit,
76    Infinite,
77}
78
79pub type HybridSurfaceCollection = TiVec<HybridSurfaceID, HybridSurface>;
80pub type HybridSurfaceCache<T> = TiVec<HybridSurfaceID, T>;
81
82impl From<HybridSurfaceID> for Atom {
83    fn from(id: HybridSurfaceID) -> Atom {
84        match id {
85            HybridSurfaceID::Esurface(id) => Atom::from(id),
86            HybridSurfaceID::Hsurface(id) => Atom::from(id),
87            HybridSurfaceID::Unit => Atom::num(1),
88            HybridSurfaceID::Infinite => parse!("η_inf"),
89        }
90    }
91}