///|
/// Integer plane indices, bounded to avoid overflow in combinatorial operations.
pub struct Hkl {
h : Int
k : Int
l : Int
} derive(Eq, Debug)
///|
pub fn hkl(h : Int, k : Int, l : Int) -> Result[Hkl, Problem] {
if h < -1000 || h > 1000 || k < -1000 || k > 1000 || l < -1000 || l > 1000 {
return Err(Invalid("Miller index outside [-1000,1000]"))
}
if h == 0 && k == 0 && l == 0 {
return Err(Invalid("origin is not a reflection"))
}
Ok({ h, k, l, })
}
///|
pub fn Hkl::opposite(self : Hkl) -> Hkl {
{ h: -self.h, k: -self.k, l: -self.l, }
}
///|
/// Select one of a Friedel pair without changing index magnitude.
pub fn Hkl::canonical(self : Hkl) -> Hkl {
if self.h < 0 ||
(self.h == 0 && self.k < 0) ||
(self.h == 0 && self.k == 0 && self.l < 0) {
self.opposite()
} else {
self
}
}
///|
/// Squared reciprocal length, 1/d^2; NOT (2*pi/d)^2.
pub fn Metric::q2(self : Metric, index : Hkl) -> Double {
let h = index.h.to_double()
let k = index.k.to_double()
let l = index.l.to_double()
self.aa * h * h +
self.bb * k * k +
self.cc * l * l +
2.0 * (self.ab * h * k + self.ac * h * l + self.bc * k * l)
}
///|
pub fn Metric::spacing(self : Metric, index : Hkl) -> Double {
1.0 / self.q2(index).sqrt()
}