///|
/// A probe location used for diagnostics.
pub(all) enum Probe {
CellProbe(Int, Int)
PointProbe(Point)
} derive(Debug)
///|
/// Construct an integer-cell probe.
pub fn Probe::cell(x~ : Int, y~ : Int) -> Probe {
CellProbe(x, y)
}
///|
/// Construct a floating-point probe.
pub fn Probe::point(x~ : Double, y~ : Double) -> Probe {
PointProbe(Point::new(x~, y~))
}
///|
/// Sample one probe using nearest-cell or bilinear interpolation.
pub fn Simulation::sample_probe(self : Simulation, probe : Probe) -> Cell {
match probe {
CellProbe(x, y) => self.cell(x~, y~)
PointProbe(point) => {
let density = self.density_field().sample(x=point.x, y=point.y)
let velocity = self.velocity_field().sample(x=point.x, y=point.y)
{ rho: density, ux: velocity.x, uy: velocity.y }
}
}
}
///|
/// Sample a complete line of macroscopic cells.
pub fn Simulation::sample_line(
self : Simulation,
axis~ : Axis,
index~ : Int,
) -> Array[Cell] {
let result = Array::new()
match axis {
Horizontal => {
let y = index.clamp(min=0, max=self.size.height - 1)
for x in 0.. {
let x = index.clamp(min=0, max=self.size.width - 1)
for y in 0.. Array[Double] {
let cells = self.sample_line(axis~, index~)
let result = Array::new()
for cell in cells {
result.push(
match component {
"rho" => cell.rho
"ux" => cell.ux
"uy" => cell.uy
"speed" => cell.speed()
_ => 0.0
},
)
}
result
}
///|
/// Export a line profile with a component name.
pub fn Simulation::sample_line_csv(
self : Simulation,
axis~ : Axis,
index~ : Int,
component~ : String,
) -> String {
let values = self.sample_component(axis~, index~, component~)
let builder = StringBuilder(size_hint=values.length() * 16 + 16)
builder.write_string("index,\{component}\n")
for i, value in values {
builder.write_string("\{i},\{value}\n")
}
builder.to_string()
}