///|
/// Build a pressure-driven channel with no-slip top and bottom walls.
pub fn poiseuille(
  width~ : Int,
  height~ : Int,
  omega? : Double = 1.0,
  force_x? : Double = 0.00001,
) -> Lattice {
  let lat = Lattice::new(
    size=Size::new(width~, height~),
    config=Config::new(omega~, force_x~),
  )
  lat.set_channel_walls()
  lat
}

///|
/// Build a square cavity with a moving lid encoded as initial velocity near the top.
pub fn lid_driven_cavity(
  size~ : Int,
  omega? : Double = 1.0,
  lid_velocity? : Double = 0.08,
) -> Lattice {
  let lat = Lattice::new(
    size=Size::new(width=size, height=size),
    config=Config::new(omega~),
  )
  lat.set_cavity_walls()
  lat.set_moving_lid(ux=lid_velocity)
  lat
}

///|
/// Build a channel with a circular obstacle for wake experiments.
pub fn cylinder_wake(
  width~ : Int,
  height~ : Int,
  radius? : Int = 6,
  omega? : Double = 1.0,
  inlet_velocity? : Double = 0.04,
) -> Lattice {
  let lat = Lattice::new(
    size=Size::new(width~, height~),
    config=Config::new(omega~),
  )
  lat.set_channel_walls()
  lat.add_cylinder(center_x=width / 4, center_y=height / 2, radius~)
  lat.set_uniform_inlet(x=1, ux=inlet_velocity)
  lat
}

///|
/// Build a named demo scenario with conservative default dimensions.
pub fn scenario(kind : Scenario) -> Lattice {
  match kind {
    Poiseuille => poiseuille(width=64, height=24)
    LidDrivenCavity => lid_driven_cavity(size=40)
    CylinderWake => cylinder_wake(width=96, height=36)
  }
}