///|
/// Integer size of a rectangular simulation domain.
pub(all) struct Size {
  width : Int
  height : Int
} derive(Debug, Eq)

///|
/// Construct a domain size.
pub fn Size::new(width~ : Int, height~ : Int) -> Size {
  { width, height }
}

///|
/// A macroscopic cell sampled from the distribution field.
pub(all) struct Cell {
  rho : Double
  ux : Double
  uy : Double
} derive(Debug)

///|
/// Euclidean velocity magnitude.
pub fn Cell::speed(self : Cell) -> Double {
  (self.ux * self.ux + self.uy * self.uy).sqrt()
}

///|
/// Runtime stability summary for a lattice.
pub(all) struct Stability {
  min_rho : Double
  max_rho : Double
  max_speed : Double
  mass : Double
  has_nan : Bool
  recommended : Bool
} derive(Debug)

///|
/// BGK relaxation and forcing configuration.
pub(all) struct Config {
  omega : Double
  force_x : Double
  force_y : Double
} derive(Debug)

///|
/// Create a BGK config. `omega` should stay between 0 and 2 for normal use.
pub fn Config::new(
  omega~ : Double,
  force_x? : Double = 0.0,
  force_y? : Double = 0.0,
) -> Config {
  { omega, force_x, force_y }
}

///|
/// High level demo scenario.
pub(all) enum Scenario {
  Poiseuille
  LidDrivenCavity
  CylinderWake
} derive(Debug, Eq)