Expand description
dualis: physics for simulated worlds, in one dependency.
A facade over the workspace. Nothing is implemented here — the point is that a
consumer writes dualis = "0.2" rather than naming seven crates, and that the
integration tests which need two domains at once have somewhere to live.
use dualis::prelude::*;
// A lamp, a filter, and the question that needs both.
let lamp = SpectralPower::new(
Spectrum::blackbody(3200.0),
Power::w(1.0),
VISIBLE_RANGE,
);
let green = Spectrum::bands(vec![[500.0, 560.0]], 0.95, 0.0);
let through = lamp.through(&green);
assert!(through < lamp.total());§Start here
Three ideas carry the whole library.
- Units are types. Dimensions live in the type, so
Length + Timedoes not compile. One place may hold a factor of a thousand — a unit-bearing constructor — andto_si()is the only way back to a baref64. - A domain is anything that steps.
Domainrequiresnameandstep; everything else has a default. Overrideledgerso the audit has something to check. - Domains never call each other. They meet on
Exchange, a bus of named channels carrying SI amounts — joules, not watts. A ledger says what you are holding, not what has passed through you.
And the reason to pick this over a general-purpose engine: conservation is audited every
step, so a wrong model does not run quietly. advance returns a
Violation naming the quantity, the site, and the before and
after — a correctness signal you can act on without a human noticing first.
energy destroyed at simulation: 5.000000e2 became 4.995000e2,
a relative change of 1.000e-3 against a tolerance of 1.000e-9Be clear about the limit: the audit catches quantities appearing or vanishing, amounts
left unclaimed on the bus, and fluxes disagreeing face by face across a shared boundary.
It does not catch a model that is internally consistent and physically wrong — publish
a power where a joule was wanted and both sides agree perfectly about a number off by
1/dt. For that, check against something the code did not compute: a closed form, an
exact limit, or a convergence rate.
cargo run --example agents_quickstart is all of the above as a running program,
including a deliberate leak so the failure is visible. AGENTS.md in the repository is
the one-page version.
§The dependency rule
dualis-units no dependencies but glam and serde
dualis-core depends on units
dualis-optics depends on core
dualis-thermal depends on core
dualis-mechanics depends on core
dualis-acoustic depends on core
dualis-molecular depends on core
dualis depends on all of themNone of the five domains knows about any of the others. They meet on the kernel’s
Exchange, and each one that arrived left the others
untouched — which is the claim the split was made to test, now held five times.
Re-exports§
pub use dualis_acoustic as acoustic;pub use dualis_core as core;pub use dualis_electrical as electrical;pub use dualis_mechanics as mechanics;pub use dualis_molecular as molecular;pub use dualis_optics as optics;pub use dualis_thermal as thermal;pub use dualis_units as units;
Modules§
- prelude
- Everything most simulations need, in one
use.