You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I wanted to confirm what the power loss would be for a mechanical heat recovery fan. I had tried to do this on a calculator but this quickly became annoying: the need to check units, do unit conversions (all scalar!), revise calculations etc.
So I thought that I'd try to use rust to do the same thing. I quickly found the uom library and entered the following program:
#![allow(mixed_script_confusables)]#![allow(unused_variables)]use uom::fmt::DisplayStyle::Description;use uom::si::f32::*;use uom::si::mass_density::kilogram_per_cubic_meter;use uom::si::power::watt;use uom::si::specific_heat_capacity::kilojoule_per_kilogram_kelvin;use uom::si::temperature_interval;use uom::si::volume_rate::liter_per_second;/// Heat loss by ventilation/// https://www.engineeringtoolbox.com/heat-loss-buildings-d_113.html/// Hv = cp ρ qv (ti - to )/// where:/// Hv = ventilation heat loss (W)/// cp = specific heat air (J/kg K)/// ρ = density of air (kg/m3 )/// qv = air volume flow (m3 /s)/// ti = inside air temperature ( oC)/// to = outside air temperature ( oC)/// The heat loss due to ventilation with heat recovery can be expressed as:/// Hv = (1 - β/100) cp ρ qv (ti - to )/// where/// β = heat recovery efficiency (%)///fnmain(){let cp = SpecificHeatCapacity::new::<kilojoule_per_kilogram_kelvin>(0.7171);let ρ = MassDensity::new::<kilogram_per_cubic_meter>(1.276);let ti = TemperatureInterval::new::<temperature_interval::degree_celsius>(20.0);let to = TemperatureInterval::new::<temperature_interval::degree_celsius>(10.0);let qv = VolumeRate::new::<liter_per_second>(15.0);let β = 50.0;//efficiency as percentagelet hv = (1.0 - β / 100.0)* cp * ρ * qv *(ti - to);println!("{hv:?}");// inital ouput// added laterprintln!("{:.0}", hv.into_format_args(watt,Description));doesnt_work(hv);}fndoesnt_work(hv:Power){use uom::fmt::DisplayStyle::Abbreviation;use uom::si::time::second;let s = Time::format_args(second,Abbreviation);// difficult to understand error// println!("{}", s.with(hv));// easy to understand error// println!("{}", hv.into_format_args(second, Description));}
The initial implementation of main ended with line 36: println!("{hv:?}"); with this output 68.62647 m^2 kg^1 s^-3
Because I'm a science/engineering graduate, I recognised the output as base SI units (I knew that 68 was about right) and so looked up the definition of "watt" to confirm that it was correct.
The fact that I was able write this quickly in rust, including using the original Greek letters, and get the output in properly typed SI units is amazing. This illustrates to me why it's worth investing in rust and how great the uom library is.
There were a number of things that tripped me up and took me a long time deal with:
"liter" is used in the uom library for the SI quantity "litre"
ThermodynamicTemperature vs TemperatureInterval
moving from debug println output of "m^2 kg^1 s^-3" base units to "watts" derived unit in "proper" println output
Rust-Analyzer integration: for example it annotates SpecificHeatCapacity as Quantitly<dyn Dimension<L = ... etc
Type annotations: the need to use Power as the type annotation (from uom::si::f32 and not somewhere else). It's difficult to write functions without this.
error messages: try uncommenting println!("{}", s.with(hv)); in doesnt_work function and then try uncommenting println!("{}", hv.into_format_args(second, Description)); instead. See below for the compiler output of each, below.
Checking heating v0.1.0 (C:\Users\...\heating)
error[E0308]: mismatched types
--> src\main.rs:46:27
|
46 | println!("{}", s.with(hv));
| ---- ^^ expected `PInt<UInt<..., ...>>`, found `NInt<UInt<..., ...>>`
| |
| arguments to this method are incorrect
|
= note: expected struct `Quantity<dyn Dimension<I = ..., J = ..., Kind = ..., L = ..., M = ..., N = ..., T = ..., Th = ...>, ..., ...>` (`PInt<UInt<..., ...>>`)
found struct `Quantity<dyn Dimension<I = ..., J = ..., Kind = ..., L = ..., M = ..., N = ..., T = ..., Th = ...>, ..., ...>` (`NInt<UInt<..., ...>>`)
= note: the full type name has been written to 'C:\Users\jackc\git\heating\target\debug\deps\heating-c42011534d221ce9.long-type-2057323855491684842.txt'
note: method defined here
--> C:\Users\jackc\.cargo\registry\src\index.crates.io-6f17d22bba15001f\uom-0.35.0\src\si\time.rs:6:1
|
6 | / quantity! {
7 | | /// Time (base unit second, s).
8 | | quantity: Time; "time";
9 | | /// Dimension of time, T (base unit second, s).
... |
55 | | }
56 | | }
| |_^
= note: this error originates in the macro `quantity` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0308`.
error: could not compile `heating` (bin "heating") due to 1 previous error
}
Checking heating v0.1.0 (C:\Users\...\heating)
error[E0277]: the trait bound `uom::si::time::second: uom::si::power::Unit` is not satisfied
--> src\main.rs:49:40
|
49 | println!("{}", hv.into_format_args(second, Description));
| ---------------- ^^^^^^ the trait `uom::si::power::Unit` is not implemented for `uom::si::time::second`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `uom::si::power::Unit`:
uom::si::power::yottawatt
uom::si::power::zettawatt
uom::si::power::exawatt
uom::si::power::petawatt
uom::si::power::terawatt
uom::si::power::gigawatt
uom::si::power::megawatt
uom::si::power::kilowatt
and 23 others
note: required by a bound in `power::<impl Quantity<(dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UInt<UTerm, B1>, B0>>, M = PInt<UInt<UTerm, B1>>, N = Z0, T = NInt<UInt<UInt<UTerm, B1>, B1>>, Th = Z0> + 'static), U, V>>::into_format_args`
--> C:\Users\jackc\.cargo\registry\src\index.crates.io-6f17d22bba15001f\uom-0.35.0\src\si\power.rs:3:1
|
3 | / quantity! {
4 | | /// Power (base unit watt, m² · kg · s⁻³).
5 | | quantity: Power; "power";
6 | | /// Dimension of power, L²MT⁻³ (base unit watt, m² · kg · s⁻...
... |
56 | | }
57 | | }
| | ^
| | |
| |_required by a bound in this associated function
| required by this bound in `power::<impl Quantity<dyn Dimension<I = Z0, J = Z0, Kind = dyn Kind, L = PInt<UInt<UInt<UTerm, B1>, B0>>, M = PInt<UInt<UTerm, B1>>, N = Z0, T = NInt<UInt<UInt<UTerm, B1>, B1>>, Th = Z0>, U, V>>::into_format_args`
= note: this error originates in the macro `quantity` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0277`.
error: could not compile `heating` (bin "heating") due to 1 previous error
The text was updated successfully, but these errors were encountered:
A bit more feedback about the rest would be great:
Do you have more details about your issues with ThermodynamicTemperature vs. TemperatureInterval?
Do you have more feedback about needing to use uom::si::f32::Power? Is the need to reference the underlying type confusing? There is a type alias at uom::si::power::Power, but this is even less friendly to use.
I wanted to confirm what the power loss would be for a mechanical heat recovery fan. I had tried to do this on a calculator but this quickly became annoying: the need to check units, do unit conversions (all scalar!), revise calculations etc.
So I thought that I'd try to use
rust
to do the same thing. I quickly found theuom
library and entered the following program:The initial implementation of main ended with line 36:
println!("{hv:?}");
with this output68.62647 m^2 kg^1 s^-3
Because I'm a science/engineering graduate, I recognised the output as base SI units (I knew that 68 was about right) and so looked up the definition of "watt" to confirm that it was correct.
The fact that I was able write this quickly in
rust
, including using the original Greek letters, and get the output in properly typed SI units is amazing. This illustrates to me why it's worth investing inrust
and how great theuom
library is.There were a number of things that tripped me up and took me a long time deal with:
uom
library for the SI quantity "litre"ThermodynamicTemperature
vsTemperatureInterval
println
output of "m^2 kg^1 s^-3" base units to "watts" derived unit in "proper"println
outputSpecificHeatCapacity
asQuantitly<dyn Dimension<L = ...
etcPower
as the type annotation (fromuom::si::f32
and not somewhere else). It's difficult to write functions without this.println!("{}", s.with(hv));
indoesnt_work
function and then try uncommentingprintln!("{}", hv.into_format_args(second, Description));
instead. See below for the compiler output of each, below.The text was updated successfully, but these errors were encountered: