hydra_engine_wds/lib.rs
1//! `hydra-engine` — complete water distribution simulation engine.
2//!
3//! Hydra simulates the hydraulic behaviour and water quality dynamics of
4//! pressurised water distribution networks over time. Its output is the complete
5//! time history of flows, pressures, and constituent concentrations at every
6//! point in the network.
7//!
8//! # Scope
9//!
10//! Hydra models:
11//! - Extended-period steady-state hydraulics
12//! - Pressure-driven and demand-driven demand models
13//! - Conservative and reactive constituent transport (water quality, age, source tracing)
14//!
15//! Hydra does **not** model pressure transients, water-hammer effects, or
16//! multi-phase (gas/liquid) flow.
17//!
18//! # Correctness criteria
19//!
20//! - **Solver convergence**: head and flow residuals satisfy the GGA stopping
21//! criteria to within the configured tolerances at every hydraulic time step.
22//! - **Physical conservation**: mass balance and energy balance hold across the
23//! network to within floating-point precision.
24//! - **INP compatibility**: a valid EPANET 2.3 `.inp` file is parsed faithfully
25//! and its network topology is represented without loss.
26//!
27//! Agreement with EPANET's numerical output is not a correctness criterion. On
28//! well-posed networks the two will agree closely because they solve the same
29//! governing equations; where they diverge, Hydra's result is authoritative.
30//!
31//! # Crate ownership
32//!
33//! This crate owns the WD network data model, EPANET INP/OUT format parsers and
34//! writers, unit conversion, the GGA hydraulic solver, the Lagrangian quality
35//! engine, the simulation session API, and post-simulation analytics.
36//!
37//! It does **not** own interface logic (CLI, GUI) or filesystem/network I/O —
38//! callers supply bytes. all types are defined within this crate.
39//!
40//! # Internal module structure
41//!
42//! | Module | Responsibility |
43//! |---|---|
44//! | `model` | Network data model, state types, validation |
45//! | `io` | Unit conversion, INP/OUT/RPT/analysis parsers and writers |
46//! | `hydraulics` | GGA Newton-Raphson solver (see `../hydraulics/spec.md`) |
47//! | `quality` | Lagrangian transport engine (see `../quality/spec.md`) |
48//! | `simulation` | Session API, controls, timestep, accounting |
49//! | `analysis` | Post-simulation analytics |
50//!
51//! Downstream crates (`hydra`, `hydra-cli`, `hydra-gui`) depend only on this
52//! crate's public re-export surface; they do not depend on any internal module.
53
54pub mod analysis;
55#[allow(clippy::too_many_arguments, clippy::needless_range_loop)]
56mod hydraulics;
57/// Parsing and output-writing utilities: INP parser, binary `.out` reader/writer, `.rpt` writer, and unit conversion.
58pub mod io;
59pub mod model;
60mod quality;
61pub mod simulation;
62
63#[cfg(feature = "test-support")]
64pub mod test_support;
65
66#[cfg(feature = "test-support")]
67pub use hydraulics::{build_solver_context, solve_hydraulic_step, SolverContext};
68
69// ── Data model ────────────────────────────────────────────────────────────────
70
71pub use model::{
72 ActionValue, Curve, CurveKind, CurvePoint, DemandCategory, DemandModel, FavadCoeffs, FlowUnits,
73 HeadLossFormula, Junction, Link, LinkBase, LinkKind, LinkState, LinkStatus, LogicOp, MixModel,
74 Network, Node, NodeBase, NodeKind, NodeState, Pattern, Pipe, Premise, PremiseAttribute,
75 PremiseObject, PremiseOperator, Pump, PumpCurveType, QualityMode, QualitySource,
76 ReportFieldOption, ReportOptions, ReportSelection, ReportStatus, Reservoir, Rule, RuleAction,
77 RuntimeEstimate, SimpleControl, SimulationOptions, SourceType, StatisticType, Tank,
78 TriggerType, ValidationError, Valve, ValveType, WallOrder,
79};
80
81// ── Session API ───────────────────────────────────────────────────────────────
82
83pub use simulation::{
84 classify_simulation_runtime_millis, estimate_simulation_runtime,
85 estimate_simulation_runtime_from_summary, estimate_simulation_runtime_millis_from_summary,
86 FlowBalance, FlowBalanceSummary, HydSnapshot, HydraulicError, LinkProperty, LinkQuantity,
87 LinkResult, MassBalance, NodeProperty, NodeQuantity, NodeResult, PumpEnergy, QualityError,
88 ResultRanges, SessionError, SimWarning, Simulation, WarningKind, WritableSimulation,
89 HYDRA_HYDRAULICS_VERSION, HYDRA_QUALITY_VERSION, HYDRA_SIMULATION_VERSION,
90};
91
92// ── Analytics ─────────────────────────────────────────────────────────────────
93
94pub use analysis::{
95 build_analysis_artifact, build_analysis_artifact_from_out,
96 build_analysis_artifact_from_out_with_progress,
97 build_analysis_artifact_from_out_with_progress_and_selection,
98 compute_demand_reliability_from_out, compute_demand_reliability_from_out_with_options,
99 compute_service_compliance_from_out, decode_analysis_artifact, encode_analysis_artifact,
100 estimate_analysis_runtime_millis, AnalysisBytesError, AnalysisComputeError, AnalysisSelection,
101 DemandReliabilityNode, DemandReliabilityOptions, DemandReliabilityReport,
102 DemandReliabilitySummary, ServiceComplianceNode, ServiceComplianceReport,
103 ServiceComplianceSummary, ServiceComplianceThresholds, HYDRA_ANALYSIS_VERSION,
104};
105
106// ── I/O helpers ───────────────────────────────────────────────────────────────
107
108/// Serialise a [`Network`] back to EPANET 2.3 INP bytes.
109pub fn write_inp(network: &Network) -> Vec<u8> {
110 io::write_inp(network)
111}