lattice-core 0.1.0

Simple Lattice/Graph Library
Documentation
use crate::types::{CoordinateVector, OffsetVector};

#[derive(Clone, Debug, PartialEq)]
pub struct Site {
  pub coordinate: CoordinateVector,
  pub site_type: i32,
}

#[derive(Clone, Debug, PartialEq)]
pub struct Bond {
  pub source: usize,
  pub target: usize,
  pub target_offset: OffsetVector,
  pub bond_type: i32,
}

#[derive(Clone, Debug, PartialEq)]
pub struct Unitcell {
  dim: usize,
  sites: Vec<Site>,
  bonds: Vec<Bond>,
}

impl Unitcell {
  pub fn new(dim: usize) -> Self {
    Self { dim, sites: Vec::new(), bonds: Vec::new() }
  }

  pub fn simple(dim: usize) -> Self {
    let mut cell = Self::new(dim);
    cell.add_site(CoordinateVector::zeros(dim), 0);
    for axis in 0..dim {
      let mut offset = OffsetVector::zeros(dim);
      offset[axis] = 1;
      cell.add_bond(0, 0, offset, 0);
    }
    cell
  }

  pub fn dimension(&self) -> usize {
    self.dim
  }

  pub fn num_sites(&self) -> usize {
    self.sites.len()
  }

  pub fn num_bonds(&self) -> usize {
    self.bonds.len()
  }

  pub fn site(&self, index: usize) -> &Site {
    &self.sites[index]
  }

  pub fn bond(&self, index: usize) -> &Bond {
    &self.bonds[index]
  }

  pub fn max_neighbors(&self) -> usize {
    let mut counts = vec![0usize; self.num_sites()];
    for bond in &self.bonds {
      counts[bond.source] += 1;
      counts[bond.target] += 1;
    }
    counts.into_iter().max().unwrap_or(0)
  }

  pub fn add_site(&mut self, coordinate: CoordinateVector, site_type: i32) -> usize {
    assert_eq!(coordinate.len(), self.dim, "site coordinate dimension mismatch");
    for value in coordinate.iter() {
      if *value < 0.0 || *value >= 1.0 {
        panic!("site coordinate out of range");
      }
    }
    let index = self.sites.len();
    self.sites.push(Site { coordinate, site_type });
    index
  }

  pub fn add_bond(&mut self, source: usize, target: usize, target_offset: OffsetVector, bond_type: i32) -> usize {
    if source >= self.num_sites() || target >= self.num_sites() {
      panic!("site index out of range");
    }
    if target_offset.len() != self.dim {
      panic!("unitcell offset dimension mismatch");
    }
    let index = self.bonds.len();
    self.bonds.push(Bond { source, target, target_offset, bond_type });
    index
  }
}