use crate::element::Element;
#[derive(Debug, Clone)]
pub struct Crystal {
pub name: String,
pub lattice: LatticeType,
pub base: Element,
pub solutes: Vec<(Element, f32)>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum LatticeType {
BCC,
FCC,
HCP,
BCT,
Diamond,
Ionic,
}
impl LatticeType {
pub fn packing_fraction(&self) -> f32 {
match self {
LatticeType::BCC => 0.680,
LatticeType::FCC => 0.740,
LatticeType::HCP => 0.740,
LatticeType::BCT => 0.700,
LatticeType::Diamond => 0.340,
LatticeType::Ionic => 0.660,
}
}
pub fn coordination_number(&self) -> u32 {
match self {
LatticeType::BCC => 8,
LatticeType::FCC => 12,
LatticeType::HCP => 12,
LatticeType::BCT => 8,
LatticeType::Diamond => 4,
LatticeType::Ionic => 6,
}
}
}
impl Crystal {
pub fn cohesive_energy(&self) -> f32 {
let base_frac: f32 = 1.0 - self.solutes.iter().map(|(_, f)| f).sum::<f32>();
let mut energy = self.base.cohesive_energy() * base_frac;
for &(elem, frac) in &self.solutes {
energy += elem.cohesive_energy() * frac;
}
energy
}
pub fn iron() -> Self {
Self {
name: "iron".into(),
lattice: LatticeType::BCC,
base: Element::Fe,
solutes: Vec::new(),
}
}
pub fn steel(carbon_pct: f32) -> Self {
Self {
name: format!("steel_{:.1}C", carbon_pct * 100.0),
lattice: LatticeType::BCC,
base: Element::Fe,
solutes: vec![(Element::C, carbon_pct)],
}
}
pub fn copper() -> Self {
Self {
name: "copper".into(),
lattice: LatticeType::FCC,
base: Element::Cu,
solutes: Vec::new(),
}
}
pub fn gold() -> Self {
Self {
name: "gold".into(),
lattice: LatticeType::FCC,
base: Element::Au,
solutes: Vec::new(),
}
}
pub fn aluminum() -> Self {
Self {
name: "aluminum".into(),
lattice: LatticeType::FCC,
base: Element::Al,
solutes: Vec::new(),
}
}
pub fn diamond() -> Self {
Self {
name: "diamond".into(),
lattice: LatticeType::Diamond,
base: Element::C,
solutes: Vec::new(),
}
}
}