pub fn tolerance(epsilon: f64) -> f64 {
#[cfg(feature = "storage-f32")]
{
epsilon.max(1.0e-4)
}
#[cfg(not(feature = "storage-f32"))]
{
epsilon
}
}
pub fn approx_eq(a: f64, b: f64, epsilon: f64) -> bool {
(a - b).abs() < tolerance(epsilon)
}
#[cfg(test)]
mod test_force {
#[cfg(feature = "ndarray")]
use ndarray::{arr1, arr2};
use num_traits::Zero;
use unitforge::prelude::*;
use unitforge::quantities::Force;
use unitforge::quantities::ForceUnit;
use unitforge::{Distance, DistanceUnit};
#[test]
fn test_force_creation() {
let f = Force::new(100.0, ForceUnit::kN);
assert_eq!(f.to(ForceUnit::N), 100_000.0);
}
#[test]
fn test_is_not_nan() {
let f = Force::new(100.0, ForceUnit::kN);
assert!(!f.is_nan());
}
#[test]
fn test_is_nan() {
let f = Force::new(f64::NAN, ForceUnit::kN);
assert!(f.is_nan());
}
#[test]
fn test_distance_weird() {
let f = Distance::new(100.0, DistanceUnit::m);
assert!(crate::approx_eq(
f.to(DistanceUnit::AU),
6.684587122268447e-10,
1.0e-24
));
}
#[test]
fn test_force_addition() {
let f1 = Force::new(50.0, ForceUnit::kN);
let f2 = Force::new(50.0, ForceUnit::kN);
let f3 = f1 + f2;
assert_eq!(f3.to(ForceUnit::kN), 100.0);
}
#[test]
fn test_force_subtraction() {
let f1 = Force::new(80.0, ForceUnit::kN);
let f2 = Force::new(30.0, ForceUnit::kN);
let f3 = f1 - f2;
assert_eq!(f3.to(ForceUnit::kN), 50.0);
}
#[test]
fn test_min() {
let f1 = Force::new(80.0, ForceUnit::kN);
let f2 = Force::new(30.0, ForceUnit::kN);
let f3 = f1.min(f2);
assert_eq!(f3.to(ForceUnit::kN), 30.0);
}
#[test]
fn test_max() {
let f1 = Force::new(80.0, ForceUnit::kN);
let f2 = Force::new(30.0, ForceUnit::kN);
let f3 = f1.max(f2);
assert_eq!(f3.to(ForceUnit::kN), 80.0);
}
#[test]
#[cfg(feature = "ndarray")]
fn test_force_addition_arr1() {
let f1 = arr1(&[
Force::new(50.0, ForceUnit::kN),
Force::new(75.0, ForceUnit::kN),
]);
let f2 = arr1(&[
Force::new(25.0, ForceUnit::kN),
Force::new(15.0, ForceUnit::kN),
]);
let f3 = f1 + f2;
assert_eq!(f3[0].to(ForceUnit::kN), 75.0);
assert_eq!(f3[1].to(ForceUnit::kN), 90.0);
}
#[test]
#[cfg(feature = "ndarray")]
fn test_force_addition_arr2() {
let f1 = arr2(&[[
Force::new(50.0, ForceUnit::kN),
Force::new(75.0, ForceUnit::kN),
]]);
let f2 = arr2(&[[
Force::new(25.0, ForceUnit::kN),
Force::new(15.0, ForceUnit::kN),
]]);
let f3 = f1 + f2;
assert_eq!(f3[[0, 0]].to(ForceUnit::kN), 75.0);
assert_eq!(f3[[0, 1]].to(ForceUnit::kN), 90.0);
}
#[test]
#[cfg(feature = "ndarray")]
fn test_force_subtraction_arr1() {
let f1 = arr1(&[
Force::new(50.0, ForceUnit::kN),
Force::new(75.0, ForceUnit::kN),
]);
let f2 = arr1(&[
Force::new(25.0, ForceUnit::kN),
Force::new(15.0, ForceUnit::kN),
]);
let f3 = f1 - f2;
assert_eq!(f3[0].to(ForceUnit::kN), 25.0);
assert_eq!(f3[1].to(ForceUnit::kN), 60.0);
}
#[test]
#[cfg(feature = "ndarray")]
fn test_force_subtraction_arr2() {
let f1 = arr2(&[[
Force::new(50.0, ForceUnit::kN),
Force::new(75.0, ForceUnit::kN),
]]);
let f2 = arr2(&[[
Force::new(25.0, ForceUnit::kN),
Force::new(15.0, ForceUnit::kN),
]]);
let f3 = f1 - f2;
assert_eq!(f3[[0, 0]].to(ForceUnit::kN), 25.0);
assert_eq!(f3[[0, 1]].to(ForceUnit::kN), 60.0);
}
#[test]
fn test_force_multiplication() {
let f = Force::new(10.0, ForceUnit::kN);
let f2 = f * 2.5;
assert_eq!(f2.to(ForceUnit::kN), 25.0);
}
#[test]
#[cfg(feature = "ndarray")]
fn test_force_multiplication_arr1() {
let f1 = arr1(&[Force::new(10.0, ForceUnit::kN)]);
let f2 = f1 * 2.5;
assert_eq!(f2[0].to(ForceUnit::kN), 25.0);
}
#[test]
#[cfg(feature = "ndarray")]
fn test_force_multiplication_arr2() {
let f1 = arr2(&[[Force::new(10.0, ForceUnit::kN)]]);
let f2 = f1 * 2.5;
assert_eq!(f2[[0, 0]].to(ForceUnit::kN), 25.0);
}
#[test]
fn test_force_division() {
let f = Force::new(25.0, ForceUnit::kN);
let f2 = f / 5.0;
assert_eq!(f2.to(ForceUnit::kN), 5.0);
}
#[test]
#[cfg(feature = "ndarray")]
fn test_force_division_arr1() {
let f1 = arr1(&[Force::new(25.0, ForceUnit::kN)]);
let f2 = f1 / 5.;
assert_eq!(f2[0].to(ForceUnit::kN), 5.0);
}
#[test]
#[cfg(feature = "ndarray")]
fn test_force_division_arr2() {
let f1 = arr2(&[[Force::new(25.0, ForceUnit::kN)]]);
let f2 = f1 / 5.;
assert_eq!(f2[[0, 0]].to(ForceUnit::kN), 5.);
}
#[test]
fn test_force_display() {
let f = Force::new(10.0, ForceUnit::N);
assert_eq!(f.to_string(), "10 N");
}
#[test]
fn test_force_rounding() {
let f = Force::new(9.9999, ForceUnit::N);
assert_eq!(f.to_string(), "10 N");
}
#[test]
fn test_force_rounding_zero() {
let f = Force::zero();
assert_eq!(f.to_string(), "0 N");
}
#[test]
fn test_force_rounding_override() {
let f = Force::new(100000., ForceUnit::N);
assert_eq!(f.to_string(), "100000 N");
}
#[test]
fn test_inf() {
let f = Force::new(f64::INFINITY, ForceUnit::N);
#[cfg(not(any(feature = "storage-f64", feature = "storage-f32")))]
assert!(f.get_multiplier().is_infinite());
#[cfg(not(any(feature = "storage-f64", feature = "storage-f32")))]
assert!(!f.get_multiplier().is_sign_negative());
assert!(f.as_f64().is_infinite());
assert!(!f.as_f64().is_sign_negative());
}
#[test]
fn test_neg_inf() {
let f = Force::new(f64::NEG_INFINITY, ForceUnit::N);
#[cfg(not(any(feature = "storage-f64", feature = "storage-f32")))]
assert!(f.get_multiplier().is_infinite());
#[cfg(not(any(feature = "storage-f64", feature = "storage-f32")))]
assert!(f.get_multiplier().is_sign_negative());
assert!(f.as_f64().is_infinite());
assert!(f.as_f64().is_sign_negative());
}
#[test]
fn test_format() {
let a = Distance::a_0();
let neg_a = -a;
assert!(format!("{:?}", a) == "0.0000000529 mm");
assert!(format!("{:?}", neg_a) == "-0.0000000529 mm");
}
}
#[cfg(test)]
mod test_thermo_and_rates {
use unitforge::prelude::*;
use unitforge::quantities::*;
#[test]
fn temperature_converts_linear_kelvin_units_and_allows_negative_kelvin() {
let temperature = Temperature::new(-273_150.0, TemperatureUnit::mK);
assert!(crate::approx_eq(
temperature.to(TemperatureUnit::K),
-273.15,
1e-12
));
}
#[test]
fn molar_mass_converts_common_units() {
let molar_mass = MolarMass::new(28.97, MolarMassUnit::g_mol);
assert!(crate::approx_eq(
molar_mass.to(MolarMassUnit::kg_mol),
0.02897,
1e-12
));
assert!(crate::approx_eq(
molar_mass.to(MolarMassUnit::kg_kmol),
28.97,
1e-12
));
}
#[test]
fn universal_gas_constant_has_si_constant() {
assert!(crate::approx_eq(
UniversalGasConstant::r().to(UniversalGasConstantUnit::J_molK),
8.31446261815324,
1e-12
));
}
#[test]
fn specific_gas_constant_times_temperature_returns_specific_energy() {
let r_air = SpecificGasConstant::new(287.05, SpecificGasConstantUnit::J_kgK);
let temperature = Temperature::new(300.0, TemperatureUnit::K);
let specific_energy = r_air * temperature;
assert!(crate::approx_eq(
specific_energy.to(VelocitySquaredUnit::msq_ssq),
86115.0,
1e-10
));
assert!(crate::approx_eq(
specific_energy.to(VelocitySquaredUnit::kJ_kg),
86.115,
1e-10
));
}
#[test]
fn specific_and_molar_gas_constants_relate_through_molar_mass() {
let molar_mass = MolarMass::new(28.97, MolarMassUnit::g_mol);
let r_air = UniversalGasConstant::r() / molar_mass;
assert!(crate::approx_eq(
r_air.to(SpecificGasConstantUnit::J_kgK),
287.00250666735315,
1e-10
));
assert!(crate::approx_eq(
(r_air * molar_mass).to(UniversalGasConstantUnit::J_molK),
UniversalGasConstant::r().to(UniversalGasConstantUnit::J_molK),
1e-12
));
}
#[test]
fn pressure_rate_integrates_over_time_to_stress() {
let pressure_rate = PressureRate::new(2.0, PressureRateUnit::MPa_s);
let duration = Time::new(0.5, TimeUnit::s);
let pressure = pressure_rate * duration;
assert!(crate::approx_eq(pressure.to(StressUnit::MPa), 1.0, 1e-12));
assert!(crate::approx_eq(
(pressure / duration).to(PressureRateUnit::MPa_s),
2.0,
1e-12
));
}
#[test]
fn stress_rate_integrates_over_time_to_stress() {
let stress_rate = StressRate::new(2.0, StressRateUnit::MPa_s);
let duration = Time::new(0.5, TimeUnit::s);
let stress = stress_rate * duration;
assert!(crate::approx_eq(stress.to(StressUnit::MPa), 1.0, 1e-12));
assert!(crate::approx_eq(
(stress / duration).to(StressRateUnit::MPa_s),
2.0,
1e-12
));
}
#[test]
fn stress_rate_relates_to_frequency_inverse_stress_and_force_per_volume() {
let stress = Stress::new(3.0, StressUnit::MPa);
let frequency = Frequency::new(2.0, FrequencyUnit::Hz);
let stress_rate = stress * frequency;
assert!(crate::approx_eq(
stress_rate.to(StressRateUnit::MPa_s),
6.0,
1e-12
));
assert!(crate::approx_eq(
(stress_rate / frequency).to(StressUnit::MPa),
3.0,
1e-12
));
assert!(crate::approx_eq(
(InverseStress::new(0.5, InverseStressUnit::_Pa) * stress_rate).to(FrequencyUnit::Hz),
3.0e6,
1e-6
));
assert!(crate::approx_eq(
(ForcePerVolume::new(4.0, ForcePerVolumeUnit::N_mcb)
* Velocity::new(2.0, VelocityUnit::m_s))
.to(StressRateUnit::Pa_s),
8.0,
1e-12
));
}
#[test]
fn frequency_converts_and_relates_to_time() {
let frequency = Frequency::new(120.0, FrequencyUnit::rpm);
assert!(crate::approx_eq(
frequency.to(FrequencyUnit::Hz),
2.0,
1e-12
));
assert!(crate::approx_eq(
frequency * Time::new(0.5, TimeUnit::s),
1.0,
1e-12
));
assert!(crate::approx_eq(
(1.0 / Time::new(0.5, TimeUnit::s)).to(FrequencyUnit::Hz),
2.0,
1e-12
));
assert!(crate::approx_eq(
(1.0 / frequency).to(TimeUnit::s),
0.5,
1e-12
));
}
}
#[cfg(test)]
mod test_alias {
use unitforge::prelude::*;
use unitforge::quantities::*;
#[test]
fn test_alias() {
let a = Moment::new(12., MomentUnit::Nm);
assert_eq!(a.to(MomentUnit::Nmm), 12000.0);
}
#[test]
fn test_alias_format() {
let a = Moment::new(12., MomentUnit::Nm);
assert_eq!(format!("{}", a), "12 Nm, J");
}
}
#[cfg(test)]
mod test_distance {
use unitforge::prelude::*;
use unitforge::quantities::*;
use unitforge::AreaUnit;
#[test]
fn test_distance_creation() {
let d = Distance::new(100.0, DistanceUnit::km);
assert_eq!(d.to(DistanceUnit::m), 100_000.0);
}
#[test]
fn test_distance_conversion() {
let d = Distance::new(1.0, DistanceUnit::km);
assert_eq!(d.to(DistanceUnit::m), 1_000.0);
assert_eq!(d.to(DistanceUnit::dm), 10_000.0);
assert_eq!(d.to(DistanceUnit::cm), 100_000.0);
assert_eq!(d.to(DistanceUnit::mm), 1_000_000.0);
}
#[test]
fn test_distance_addition() {
let d1 = Distance::new(500.0, DistanceUnit::m);
let d2 = Distance::new(1.0, DistanceUnit::km);
let d3 = d1 + d2;
assert_eq!(d3.to(DistanceUnit::m), 1_500.0);
}
#[test]
fn test_distance_subtraction() {
let d1 = Distance::new(2.0, DistanceUnit::km);
let d2 = Distance::new(500.0, DistanceUnit::m);
let d3 = d1 - d2;
assert_eq!(d3.to(DistanceUnit::m), 1_500.0);
}
#[test]
fn test_distance_multiplication() {
let d = Distance::new(100.0, DistanceUnit::m);
let d_multiplied = d * 2.5;
let d_multiplied_swapped = 2.5 * d;
assert_eq!(d_multiplied.to(DistanceUnit::m), 250.0);
assert_eq!(d_multiplied_swapped.to(DistanceUnit::m), 250.0);
}
#[test]
fn test_distance_division() {
let d = Distance::new(500.0, DistanceUnit::m);
let d_divided = d / 5.0;
assert_eq!(d_divided.to(DistanceUnit::m), 100.0);
}
#[test]
fn test_distance_division_by_division() {
let d_1 = Distance::new(500.0, DistanceUnit::m);
let d_2 = Distance::new(250.0, DistanceUnit::m);
assert_eq!(d_1 / d_2, 2.0);
}
#[test]
fn test_distance_display() {
let d = Distance::new(100.0, DistanceUnit::m);
assert_eq!(d.to_string(), "100000 mm");
}
#[test]
fn test_distance_multiplication_with_self() {
let d_1 = Distance::new(100.0, DistanceUnit::m);
let d_2 = Distance::new(2.0, DistanceUnit::m);
let a = d_1 * d_2;
assert_eq!(a.to(AreaUnit::msq), 200.0);
}
#[test]
fn test_equality() {
let d_1 = Distance::new(100.0, DistanceUnit::m);
let d_2 = Distance::new(2.0, DistanceUnit::m);
assert!(d_1.is_close(&(d_2 * 50.0), &(d_2 / 100.0)));
}
}
#[cfg(test)]
mod test_time {
use super::approx_eq;
use std::time::Duration;
use unitforge::prelude::*;
use unitforge::{Time, TimeUnit};
#[test]
fn test_time_from_duration() {
let duration = Duration::new(12, 345_000_000);
let time = Time::from_duration(duration);
assert!(approx_eq(time.to(TimeUnit::s), 12.345, 1.0e-6));
}
#[test]
fn test_time_as_duration() {
let time = Time::new(1.5, TimeUnit::min);
let duration = time.as_duration();
assert!(approx_eq(duration.as_secs_f64(), 90.0, 1.0e-6));
}
#[test]
fn test_time_duration_round_trip() {
let duration = Duration::new(2, 750_000_000);
let round_tripped = Time::from_duration(duration).as_duration();
assert!(approx_eq(round_tripped.as_secs_f64(), 2.75, 1.0e-6));
}
}
#[cfg(test)]
mod test_stiffness {
use unitforge::prelude::*;
use unitforge::quantities::{Stiffness, StiffnessUnit};
#[test]
fn test_stiffness_creation() {
let s = Stiffness::new(1.0, StiffnessUnit::N_m);
assert_eq!(s.to(StiffnessUnit::N_m), 1.0);
assert_eq!(s.to(StiffnessUnit::kN_m), 0.001);
}
#[test]
fn test_stiffness_conversion() {
let s = Stiffness::new(1.0, StiffnessUnit::N_m);
assert_eq!(s.to(StiffnessUnit::N_mm), 0.001);
assert_eq!(s.to(StiffnessUnit::kN_mm), 0.000001);
}
#[test]
fn test_stiffness_addition() {
let s1 = Stiffness::new(1.0, StiffnessUnit::N_m);
let s2 = Stiffness::new(1.0, StiffnessUnit::N_m);
let s3 = s1 + s2;
assert_eq!(s3.to(StiffnessUnit::N_m), 2.0);
}
#[test]
fn test_stiffness_subtraction() {
let s1 = Stiffness::new(3.0, StiffnessUnit::N_m);
let s2 = Stiffness::new(1.0, StiffnessUnit::N_m);
let s3 = s1 - s2;
assert_eq!(s3.to(StiffnessUnit::N_m), 2.0);
}
#[test]
fn test_stiffness_multiplication() {
let s = Stiffness::new(1.0, StiffnessUnit::N_m);
let s_multiplied = s * 2.5;
assert_eq!(s_multiplied.to(StiffnessUnit::N_m), 2.5);
}
#[test]
fn test_stiffness_division() {
let s = Stiffness::new(5.0, StiffnessUnit::N_m);
let s_divided = s / 5.0;
assert_eq!(s_divided.to(StiffnessUnit::N_m), 1.0);
}
#[test]
fn test_stiffness_display() {
let s = Stiffness::new(1.0, StiffnessUnit::N_m);
assert_eq!(s.to_string(), "0.001 N/mm");
}
}
#[cfg(test)]
mod test_inverse_distance {
use super::approx_eq;
use unitforge::quantities::*;
use unitforge::{InverseDistanceUnit, PhysicsQuantity};
#[test]
fn test_new() {
let id = InverseDistance::new(10_f64, InverseDistanceUnit::_mm);
assert!(approx_eq(id.to(InverseDistanceUnit::_cm), 100_f64, 10E-10));
}
#[test]
fn test_mul_with_distance() {
let d = Distance::new(0.1_f64, DistanceUnit::mm);
let id = InverseDistance::new(10_f64, InverseDistanceUnit::_mm);
assert!(approx_eq(d * id, 1_f64, 10E-10));
assert!(approx_eq(id * d, 1_f64, 10E-10));
}
}
#[cfg(test)]
mod test_angle {
use super::{approx_eq, tolerance};
use num_traits::Zero;
use std::f64::consts::PI;
use unitforge::prelude::*;
use unitforge::{Angle, AngleUnit};
#[test]
fn test_angle_creation_and_conversion() {
let angle_rad = Angle::new(PI, AngleUnit::rad);
assert!(approx_eq(angle_rad.to(AngleUnit::rad), PI, 1e-10));
assert!(approx_eq(angle_rad.to(AngleUnit::deg), 180.0, 1e-10));
let angle_deg = Angle::new(90.0, AngleUnit::deg);
assert!(approx_eq(angle_deg.to(AngleUnit::rad), PI / 2.0, 1e-10));
assert!(approx_eq(angle_deg.to(AngleUnit::deg), 90.0, 1e-10));
}
#[test]
fn test_trigonometric_functions() {
let angle = Angle::new(PI / 2.0, AngleUnit::rad);
assert!(approx_eq(angle.sin(), 1.0, 1e-10));
assert!(angle.cos().abs() < tolerance(1e-10));
assert!(approx_eq(Angle::new(45., AngleUnit::deg).tan(), 1.0, 1e-10));
}
#[test]
fn test_arc_functions() {
let sin_value = 0.5;
let arc_sin = Angle::arc_sin(sin_value);
assert!(approx_eq(
arc_sin.to(AngleUnit::rad),
sin_value.asin(),
1e-10
));
let cos_value = 0.5;
let arc_cos = Angle::arc_cos(cos_value);
assert!(approx_eq(
arc_cos.to(AngleUnit::rad),
cos_value.acos(),
1e-10
));
let tan_value = 1.0;
let arc_tan = Angle::arc_tan(tan_value);
assert!(approx_eq(
arc_tan.to(AngleUnit::rad),
tan_value.atan(),
1e-10
));
}
#[test]
fn test_angle_display() {
let angle = Angle::new(PI, AngleUnit::rad);
assert_eq!(format!("{}", angle), "180°");
}
#[test]
fn test_zero_angle() {
let zero_angle = Angle::zero();
assert!((zero_angle.to(AngleUnit::rad) - 0.0).abs() < 1e-10);
assert!((zero_angle.to(AngleUnit::deg) - 0.0).abs() < 1e-10);
}
#[test]
fn test_arctan2_45_deg() {
let angle = Angle::arc_tan_2(1.0, 1.0);
let expected_deg = 45.0;
let diff = (angle.to(AngleUnit::deg) - expected_deg).abs();
assert!(diff < tolerance(1e-10));
}
#[test]
fn test_arctan2_90_deg() {
let angle = Angle::arc_tan_2(1.0, 0.0);
let expected_deg = 90.0;
let diff = (angle.to(AngleUnit::deg) - expected_deg).abs();
assert!(diff < tolerance(1e-10));
}
#[test]
fn test_arctan2_minus_45_deg() {
let angle = Angle::arc_tan_2(-1.0, 1.0);
let expected_deg = -45.0;
let diff = (angle.to(AngleUnit::deg) - expected_deg).abs();
assert!(diff < tolerance(1e-10));
}
#[test]
fn test_arctan2_180_deg() {
let angle = Angle::arc_tan_2(0.0, -1.0);
let expected_deg = 180.0;
let actual_deg = angle.to(AngleUnit::deg);
let wrapped = if actual_deg < -180.0 {
actual_deg + 360.0
} else if actual_deg > 180.0 {
actual_deg - 360.0
} else {
actual_deg
};
let diff = (wrapped.abs() - expected_deg).abs();
assert!(diff < tolerance(1e-10));
}
}
#[cfg(test)]
mod test_constant {
use super::approx_eq;
use unitforge::{PhysicsQuantity, Velocity, VelocityUnit};
#[test]
fn c() {
let c = Velocity::c();
assert!(approx_eq(c.to(VelocityUnit::m_s), 299792458.0, 16.0));
}
}
#[cfg(test)]
mod test_connections {
use super::approx_eq;
#[cfg(feature = "ndarray")]
use ndarray::{arr1, arr2};
use unitforge::prelude::*;
use unitforge::quantities::*;
#[test]
fn test_force_division_to_stiffness() {
let f = Force::new(100.0, ForceUnit::N);
let d = Distance::new(10.0, DistanceUnit::m);
let s = f / d;
assert!(approx_eq(s.to(StiffnessUnit::N_m), 10.0, 1E-10));
}
#[test]
#[cfg(feature = "ndarray")]
fn test_force_multiplication_to_moment_arr1() {
let f = arr1(&[Force::new(100.0, ForceUnit::N)]);
let d = arr1(&[Distance::new(5.0, DistanceUnit::m)]);
let m_1 = f.clone().mul_array1(d.clone());
let m_2 = d.clone().mul_array1(f.clone());
assert!(approx_eq(m_1[0].to(ForceDistanceUnit::Nm), 500.0, 1E-10));
assert!(approx_eq(m_2[0].to(ForceDistanceUnit::Nm), 500.0, 1E-10));
}
#[test]
#[cfg(feature = "ndarray")]
fn test_force_multiplication_to_moment_arr2() {
let f = arr2(&[[Force::new(100.0, ForceUnit::N)]]);
let d = arr2(&[[Distance::new(5.0, DistanceUnit::m)]]);
let m_1 = d.clone().mul_array2(f.clone()).unwrap();
let m_2 = f.clone().mul_array2(d.clone()).unwrap();
assert!(approx_eq(
m_1[[0, 0]].to(ForceDistanceUnit::Nm),
500.0,
1E-10
));
assert!(approx_eq(
m_2[[0, 0]].to(ForceDistanceUnit::Nm),
500.0,
1E-10
));
}
#[test]
fn test_stiffness_multiplication_to_force() {
let s = Stiffness::new(10.0, StiffnessUnit::N_m);
let d = Distance::new(10.0, DistanceUnit::m);
let f = s * d;
assert!(approx_eq(f.to(ForceUnit::N), 100.0, 1E-10));
}
#[test]
fn test_force_division_to_distance() {
let f = Force::new(100.0, ForceUnit::N);
let s = Stiffness::new(10.0, StiffnessUnit::N_m);
let d = f / s;
assert!(approx_eq(d.to(DistanceUnit::m), 10.0, 1E-10));
}
#[test]
fn test_area_division_by_distance() {
let a = Area::new(100.0, AreaUnit::msq);
let d = Distance::new(500., DistanceUnit::cm);
let d_2 = a / d;
assert!(approx_eq(d_2.to(DistanceUnit::m), 20.0, 1E-10));
}
#[test]
fn test_distance_times_distance() {
let d = Distance::new(500., DistanceUnit::cm);
let d_2 = Distance::new(20., DistanceUnit::m);
let a = d * d_2;
assert!(approx_eq(a.to(AreaUnit::msq), 100.0, 1E-10));
}
#[test]
#[cfg(feature = "ndarray")]
fn test_distance_multiplication_with_self_arr1() {
let d_1 = arr1(&[Distance::new(100.0, DistanceUnit::m)]);
let d_2 = arr1(&[Distance::new(2.0, DistanceUnit::m)]);
let a = d_1.mul_array1(d_2);
assert_eq!(a[0].to(AreaUnit::msq), 200.0);
}
#[test]
#[cfg(feature = "ndarray")]
fn test_distance_multiplication_with_self_arr2() {
let d_1 = arr2(&[[Distance::new(100.0, DistanceUnit::m)]]);
let d_2 = arr2(&[[Distance::new(2.0, DistanceUnit::m)]]);
let a = d_1.mul_array2(d_2).unwrap();
assert_eq!(a[[0, 0]].to(AreaUnit::msq), 200.0);
}
#[test]
fn test_moment_division_by_distance() {
let m = ForceDistance::new(100., ForceDistanceUnit::Ncm);
let d = Distance::new(0.2, DistanceUnit::m);
let f = m / d;
assert!(approx_eq(f.to(ForceUnit::N), 5., 1E-10));
}
#[test]
#[cfg(feature = "ndarray")]
fn test_moment_division_by_distance_arr1() {
let m = arr1(&[ForceDistance::new(100., ForceDistanceUnit::Ncm)]);
let d = arr1(&[Distance::new(0.2, DistanceUnit::m)]);
let f = m.div_array1(d);
assert!(approx_eq(f[0].to(ForceUnit::N), 5., 1E-10));
}
#[test]
#[cfg(feature = "ndarray")]
fn test_moment_division_by_distance_arr2() {
let m = arr2(&[[ForceDistance::new(100., ForceDistanceUnit::Ncm)]]);
let d = arr2(&[[Distance::new(0.2, DistanceUnit::m)]]);
let f = m.div_array2(d).unwrap();
assert!(approx_eq(f[[0, 0]].to(ForceUnit::N), 5., 1E-10));
}
#[test]
fn test_moment_division_by_force() {
let m = ForceDistance::new(100., ForceDistanceUnit::Ncm);
let f = Force::new(5.0, ForceUnit::N);
let d = m / f;
assert!(approx_eq(d.to(DistanceUnit::m), 0.2, 1E-10));
}
#[test]
fn test_multiply_distance_with_force() {
let f = Force::new(5.0, ForceUnit::N);
let d = Distance::new(0.2, DistanceUnit::m);
let m_sol = ForceDistance::new(100., ForceDistanceUnit::Ncm);
assert!(approx_eq((d * f).as_f64(), m_sol.as_f64(), 1E-10));
assert!(approx_eq((f * d).as_f64(), m_sol.as_f64(), 1E-10));
}
#[test]
fn test_multiply_stress_with_area() {
let a = Area::new(100., AreaUnit::mmsq);
let s = Stress::new(50., StressUnit::MPa);
assert!(approx_eq((s * a).to(ForceUnit::kN), 5., 1E-10));
assert!(approx_eq((a * s).to(ForceUnit::kN), 5., 1E-10));
}
#[test]
fn test_multiply_stress_with_force() {
let f = Force::new(5., ForceUnit::kN);
let s = Stress::new(50., StressUnit::MPa);
assert!(approx_eq((f / s).to(AreaUnit::mmsq), 100., 1E-10));
}
#[test]
fn test_divide_force_by_area() {
let f = Force::new(5., ForceUnit::kN);
let a = Area::new(100., AreaUnit::mmsq);
assert!(approx_eq((f / a).to(StressUnit::MPa), 50., 1E-10));
}
#[test]
fn test_mod_force_by_area() {
let f = Force::new(5.5, ForceUnit::N);
let a = Area::new(2., AreaUnit::msq);
assert!(approx_eq((f % a).to(StressUnit::Pa), 1.5, 1E-10));
}
#[test]
fn test_mod_force_distance_by_force() {
let fd = ForceDistance::new(5.5, ForceDistanceUnit::Nm);
let f = Force::new(2.0, ForceUnit::N);
assert!(approx_eq((fd % f).to(DistanceUnit::m), 1.5, 1E-10));
}
#[test]
fn test_mod_distance_by_distance_returns_float() {
let lhs = Distance::new(5.5, DistanceUnit::m);
let rhs = Distance::new(2.0, DistanceUnit::m);
assert!(approx_eq(lhs % rhs, 1.5, 1E-10));
}
#[test]
fn test_mod_distance_by_scalar() {
let lhs = Distance::new(5.5, DistanceUnit::m);
assert!(approx_eq((lhs % 2.0).to(DistanceUnit::m), 1.5, 1E-10));
}
#[test]
fn test_divide_volume_by_area() {
let v = Volume::new(100., VolumeUnit::mcb);
let a = Area::new(10., AreaUnit::msq);
assert!(approx_eq((v / a).to(DistanceUnit::m), 10., 1E-10));
}
#[test]
fn test_divide_volume_by_distance() {
let v = Volume::new(100., VolumeUnit::mcb);
let d = Distance::new(10., DistanceUnit::m);
assert!(approx_eq((v / d).to(AreaUnit::msq), 10., 1E-10));
}
#[test]
fn test_multiply_distance_with_volume() {
let a = Area::new(10., AreaUnit::msq);
let d = Distance::new(10., DistanceUnit::m);
assert!(approx_eq((d * a).to(VolumeUnit::mcb), 100., 1E-10));
assert!(approx_eq((a * d).to(VolumeUnit::mcb), 100., 1E-10));
}
#[test]
fn test_divide_mass_by_volume() {
let v = Volume::new(10., VolumeUnit::mcb);
let m = Mass::new(0.02, MassUnit::t);
assert!(approx_eq((m / v).to(DensityUnit::kg_mcb), 2., 1E-10));
}
#[test]
fn test_multiply_density_with_volume() {
let rho = Density::new(2., DensityUnit::kg_mcb);
let v = Volume::new(10., VolumeUnit::mcb);
assert!(approx_eq((rho * v).to(MassUnit::kg), 20., 1E-10));
assert!(approx_eq((v * rho).to(MassUnit::kg), 20., 1E-10));
}
#[test]
fn test_divide_mass_by_density() {
let rho = Density::new(2., DensityUnit::kg_mcb);
let m = Mass::new(20., MassUnit::kg);
assert!(approx_eq((m / rho).to(VolumeUnit::mcb), 10., 1E-10));
}
#[test]
fn test_mul_inverse_distance_by_stress() {
let id = InverseDistance::new(100_f64, InverseDistanceUnit::_mm);
let s = Stress::new(10_f64, StressUnit::MPa);
assert!(approx_eq(
(s * id).to(ForcePerVolumeUnit::N_mmcb),
1000.,
1E-10
));
}
#[test]
fn test_mul_inverse_distance_by_moment() {
let id = InverseDistance::new(100_f64, InverseDistanceUnit::_mm);
let m = ForceDistance::new(10_f64, ForceDistanceUnit::Nmm);
assert!(approx_eq((m * id).to(ForceUnit::N), 1000., 1E-10));
}
#[test]
fn test_comparison() {
let a = Area::new(100., AreaUnit::mmsq);
let b = Area::new(100., AreaUnit::mmsq);
let c = Area::new(200., AreaUnit::mmsq);
assert_eq!(a, b);
assert_ne!(a, c);
assert!(a < c);
assert!(c > a);
assert!(a <= b);
assert!(a >= b);
assert!(a <= c);
assert!(c >= a);
}
}