///|
fn format_double(value : Double, decimals : Int) -> String {
if value.is_nan() {
return "NaN"
}
if value.is_inf() {
return "Inf"
}
if value < 0.0 {
return "-" + format_double(-value, decimals)
}
let mut factor = 1.0
let mut index = 0
while index < decimals {
factor = factor * 10.0
index = index + 1
}
let rounded = (value * factor + 0.5).floor().to_int()
let digits = rounded.to_string()
if decimals == 0 {
return digits
}
if digits.length() <= decimals {
let mut prefix = "0."
let mut padding = 0
while padding < decimals - digits.length() {
prefix = prefix + "0"
padding = padding + 1
}
return prefix + digits
}
let split = digits.length() - decimals
digits.sub(start=0, end=split).to_owned() +
"." +
digits.sub(start=split, end=digits.length()).to_owned()
}
///|
fn status_name(status : @lib.ParticleStatus) -> String {
match status {
@lib.ParticleStatus::Transmitted => "transmitted"
@lib.ParticleStatus::Absorbed => "absorbed"
@lib.ParticleStatus::Backscattered => "backscattered"
@lib.ParticleStatus::Active => "active"
}
}
///|
fn main {
println("MoonBit Radiation Transport and Shielding")
println("===========================================")
let energy = 1.25
let layers = @lib.lead_concrete_wall(5.0, 20.0)
let stack = @lib.LayerStack::from_layers(layers)
let narrow_beam = stack.analytic_transmission(energy)
let buildup = stack.analytic_buildup_transmission(energy)
let total_thickness = stack.total_thickness
println("Scenario: 5 cm lead + 20 cm concrete slab")
println("Reference energy: " + format_double(energy, 2) + " MeV")
println(
"Total thickness: " +
format_double(total_thickness, 1) +
" cm, " +
"areal density: " +
format_double(@lib.areal_density(layers), 2) +
" g/cm2",
)
println(
"Analytical narrow-beam transmission: " +
format_double(narrow_beam * 100.0, 5) +
"%",
)
println(
"Analytical buildup transmission: " +
format_double(buildup * 100.0, 5) +
"%",
)
let options = @lib.demo_transport_options(5000)
let result = @lib.run_transport(options)
let quality = @lib.quality_metrics(result, layers, 1.2525)
println("")
println("Monte Carlo run: " + result.histories.to_string() + " histories")
println(
"Transmission: " +
format_double(result.transmission_fraction * 100.0, 4) +
"% +/- " +
format_double(result.transmission_sem * 100.0, 4) +
"% SEM",
)
println(
"Terminal status: transmitted=" +
result.transmitted.to_string() +
", absorbed=" +
result.absorbed.to_string() +
", backscattered=" +
result.backscattered.to_string() +
", cutoff=" +
result.cutoff.to_string(),
)
println(
"Mean deposited energy: " +
format_double(result.mean_deposited_energy, 6) +
" MeV/history",
)
println(
"Quality gates: probability=" +
quality.probability_conservation.to_string() +
", energy=" +
quality.energy_conservation.to_string() +
", geometry=" +
quality.geometry_valid.to_string() +
", errors=" +
quality.errors.to_string(),
)
println("")
println("Recorded history sample:")
let mut history_index = 0
while history_index < result.recorded_histories.length() {
let history = result.recorded_histories[history_index]
println(
" #" +
history.id.to_string() +
" " +
status_name(history.status) +
", path=" +
format_double(history.path_length, 3) +
" cm, events=" +
history.events.length().to_string(),
)
history_index = history_index + 1
}
println("")
println("Run the full verification suite with:")
println(" moon check --target all --deny-warn")
println(" moon test --target native --deny-warn")
println("===========================================")
}