unitforge 0.5.2__tar.gz → 0.5.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. {unitforge-0.5.2 → unitforge-0.5.3}/Cargo.lock +2 -2
  2. {unitforge-0.5.2 → unitforge-0.5.3}/Cargo.toml +2 -2
  3. {unitforge-0.5.2 → unitforge-0.5.3}/PKG-INFO +3 -1
  4. {unitforge-0.5.2 → unitforge-0.5.3}/install_hooks.sh +0 -0
  5. {unitforge-0.5.2 → unitforge-0.5.3}/scripts/generate_python_stubs.py +12 -0
  6. {unitforge-0.5.2 → unitforge-0.5.3}/src/errors.rs +2 -0
  7. {unitforge-0.5.2 → unitforge-0.5.3}/src/impl_macros.rs +95 -1
  8. {unitforge-0.5.2 → unitforge-0.5.3}/src/internal.rs +60 -0
  9. {unitforge-0.5.2 → unitforge-0.5.3}/src/lib.rs +12 -0
  10. unitforge-0.5.3/src/quantities/density_rate.rs +32 -0
  11. unitforge-0.5.3/src/quantities/density_temperature.rs +36 -0
  12. unitforge-0.5.3/src/quantities/density_temperature_rate.rs +36 -0
  13. unitforge-0.5.3/src/quantities/pressure_rate.rs +4 -0
  14. unitforge-0.5.3/src/quantities/stress_per_temperature.rs +39 -0
  15. unitforge-0.5.3/src/quantities/stress_rate.rs +50 -0
  16. unitforge-0.5.3/src/quantities/stress_rate_per_temperature.rs +39 -0
  17. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities.template.rs +13 -1
  18. {unitforge-0.5.2 → unitforge-0.5.3}/src/relations.rs +13 -1
  19. {unitforge-0.5.2 → unitforge-0.5.3}/test.sh +0 -0
  20. {unitforge-0.5.2 → unitforge-0.5.3}/tests/quantities.rs +71 -0
  21. {unitforge-0.5.2 → unitforge-0.5.3}/tests/quantity_core/metadata.rs +1 -1
  22. {unitforge-0.5.2 → unitforge-0.5.3}/tests/quantity_core/normalization.rs +12 -1
  23. {unitforge-0.5.2 → unitforge-0.5.3}/tests/quantity_core/plain_storage.rs +25 -1
  24. {unitforge-0.5.2 → unitforge-0.5.3}/tests/quantity_core/runtime_quantity.rs +47 -2
  25. {unitforge-0.5.2 → unitforge-0.5.3}/tests/test_quantities.py +27 -0
  26. {unitforge-0.5.2 → unitforge-0.5.3}/unitforge_macros/Cargo.toml +1 -1
  27. {unitforge-0.5.2 → unitforge-0.5.3}/unitforge_macros/src/lib.rs +20 -0
  28. unitforge-0.5.2/python/unitforge/__init__.pyi +0 -2051
  29. unitforge-0.5.2/python/unitforge/py.typed +0 -0
  30. unitforge-0.5.2/src/quantities/pressure_rate.rs +0 -47
  31. {unitforge-0.5.2 → unitforge-0.5.3}/.gitignore +0 -0
  32. {unitforge-0.5.2 → unitforge-0.5.3}/.gitlab-ci.yml +0 -0
  33. {unitforge-0.5.2 → unitforge-0.5.3}/Readme.md +0 -0
  34. {unitforge-0.5.2 → unitforge-0.5.3}/Readme_py.md +0 -0
  35. {unitforge-0.5.2 → unitforge-0.5.3}/pyproject.toml +0 -0
  36. {unitforge-0.5.2 → unitforge-0.5.3}/python/unitforge/__init__.py +0 -0
  37. {unitforge-0.5.2 → unitforge-0.5.3}/src/prelude.rs +0 -0
  38. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/acceleration.rs +0 -0
  39. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/angle.rs +0 -0
  40. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/angular_acceleration.rs +0 -0
  41. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/angular_velocity.rs +0 -0
  42. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/area.rs +0 -0
  43. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/area_of_moment.rs +0 -0
  44. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/charge.rs +0 -0
  45. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/compliance.rs +0 -0
  46. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/density.rs +0 -0
  47. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/distance.rs +0 -0
  48. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/force.rs +0 -0
  49. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/force_area.rs +0 -0
  50. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/force_distance.rs +0 -0
  51. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/force_div_distance_power_four.rs +0 -0
  52. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/force_per_volume.rs +0 -0
  53. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/force_stress.rs +0 -0
  54. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/force_volume.rs +0 -0
  55. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/frequency.rs +0 -0
  56. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/inverse_angle.rs +0 -0
  57. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/inverse_area.rs +0 -0
  58. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/inverse_distance.rs +0 -0
  59. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/inverse_stress.rs +0 -0
  60. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/mass.rs +0 -0
  61. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/mass_per_distance.rs +0 -0
  62. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/molar_mass.rs +0 -0
  63. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/rotational_stiffness.rs +0 -0
  64. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/specific_gas_constant.rs +0 -0
  65. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/stiffness.rs +0 -0
  66. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/strain.rs +0 -0
  67. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/stress.rs +0 -0
  68. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/stress_squared.rs +0 -0
  69. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/temperature.rs +0 -0
  70. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/time.rs +0 -0
  71. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/universal_gas_constant.rs +0 -0
  72. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/velocity.rs +0 -0
  73. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/velocity_squared.rs +0 -0
  74. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/voltage.rs +0 -0
  75. {unitforge-0.5.2 → unitforge-0.5.3}/src/quantities/volume.rs +0 -0
  76. {unitforge-0.5.2 → unitforge-0.5.3}/src/small_linalg/bindings/matrix3_py.template.rs +0 -0
  77. {unitforge-0.5.2 → unitforge-0.5.3}/src/small_linalg/bindings/vector3_py.template.rs +0 -0
  78. {unitforge-0.5.2 → unitforge-0.5.3}/src/small_linalg/matrix2.rs +0 -0
  79. {unitforge-0.5.2 → unitforge-0.5.3}/src/small_linalg/matrix2x3.rs +0 -0
  80. {unitforge-0.5.2 → unitforge-0.5.3}/src/small_linalg/matrix3.rs +0 -0
  81. {unitforge-0.5.2 → unitforge-0.5.3}/src/small_linalg/matrix3x2.rs +0 -0
  82. {unitforge-0.5.2 → unitforge-0.5.3}/src/small_linalg/vector2.rs +0 -0
  83. {unitforge-0.5.2 → unitforge-0.5.3}/src/small_linalg/vector3.rs +0 -0
  84. {unitforge-0.5.2 → unitforge-0.5.3}/tests/common/mod.rs +0 -0
  85. {unitforge-0.5.2 → unitforge-0.5.3}/tests/matrix2.rs +0 -0
  86. {unitforge-0.5.2 → unitforge-0.5.3}/tests/matrix2x3.rs +0 -0
  87. {unitforge-0.5.2 → unitforge-0.5.3}/tests/matrix3.rs +0 -0
  88. {unitforge-0.5.2 → unitforge-0.5.3}/tests/matrix3x2.rs +0 -0
  89. {unitforge-0.5.2 → unitforge-0.5.3}/tests/ndarray_dot.rs +0 -0
  90. {unitforge-0.5.2 → unitforge-0.5.3}/tests/quantity_core/constants.rs +0 -0
  91. {unitforge-0.5.2 → unitforge-0.5.3}/tests/quantity_core/construction.rs +0 -0
  92. {unitforge-0.5.2 → unitforge-0.5.3}/tests/quantity_core/enum_iter.rs +0 -0
  93. {unitforge-0.5.2 → unitforge-0.5.3}/tests/quantity_core/relations.rs +0 -0
  94. {unitforge-0.5.2 → unitforge-0.5.3}/tests/quantity_core/scalar_edges.rs +0 -0
  95. {unitforge-0.5.2 → unitforge-0.5.3}/tests/quantity_core.rs +0 -0
  96. {unitforge-0.5.2 → unitforge-0.5.3}/tests/quantity_serde.rs +0 -0
  97. {unitforge-0.5.2 → unitforge-0.5.3}/tests/small_linalg_edge_cases.rs +0 -0
  98. {unitforge-0.5.2 → unitforge-0.5.3}/tests/small_linalg_interfaces.rs +0 -0
  99. {unitforge-0.5.2 → unitforge-0.5.3}/tests/test_small_linalg.py +0 -0
  100. {unitforge-0.5.2 → unitforge-0.5.3}/tests/typecheck/mypy_smoke.py +0 -0
  101. {unitforge-0.5.2 → unitforge-0.5.3}/tests/vector2.rs +0 -0
  102. {unitforge-0.5.2 → unitforge-0.5.3}/tests/vector3.rs +0 -0
@@ -351,7 +351,7 @@ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
351
351
 
352
352
  [[package]]
353
353
  name = "unitforge"
354
- version = "0.5.2"
354
+ version = "0.5.3"
355
355
  dependencies = [
356
356
  "ndarray",
357
357
  "num-traits",
@@ -367,7 +367,7 @@ dependencies = [
367
367
 
368
368
  [[package]]
369
369
  name = "unitforge_macros"
370
- version = "0.5.2"
370
+ version = "0.5.3"
371
371
  dependencies = [
372
372
  "regex",
373
373
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "unitforge"
3
- version = "0.5.2"
3
+ version = "0.5.3"
4
4
  edition = "2021"
5
5
  authors = ["Dr.Q team <info@askdrq.com>", "Henrik Stromberg <henrik@askdrq.com>"]
6
6
  description = "A library for unit and quantity consistent computations in Rust"
@@ -20,7 +20,7 @@ pyo3 = { version = "0.28.3", features = ["extension-module", "auto-initialize",
20
20
  numpy = { version = "0.28.0", optional = true }
21
21
  strum = { version = "0.28.0", optional = true }
22
22
  strum_macros = { version = "0.28.0", optional = true }
23
- unitforge_macros = { version = "0.5.2", path = "unitforge_macros" }
23
+ unitforge_macros = { version = "0.5.3", path = "unitforge_macros" }
24
24
 
25
25
  [features]
26
26
  default = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unitforge
3
- Version: 0.5.2
3
+ Version: 0.5.3
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -9,7 +9,9 @@ Classifier: Topic :: Scientific/Engineering :: Physics
9
9
  Requires-Dist: numpy>=2.2.0
10
10
  Summary: A library for unit and quantity consistent computations in Rust
11
11
  Keywords: units,quantities,simulation,physics
12
+ Author: Dr.Q team <info@askdrq.com>, Henrik Stromberg <henrik@askdrq.com>
12
13
  Author-email: "Dr.Q team" <info@askdrq.com>, Henrik Stromberg <henrik@askdrq.com>
14
+ License: MIT
13
15
  Requires-Python: >=3.7
14
16
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
15
17
  Project-URL: Repository, https://gitlab.com/henrikjstromberg/unitforge
File without changes
@@ -372,6 +372,18 @@ def render_quantity_stub(
372
372
  lines.append(f' def __truediv__(self, rhs: "{rhs}") -> {res}: ...')
373
373
  lines.append(" @overload")
374
374
  lines.append(" def __truediv__(self, rhs: Any) -> Any: ...")
375
+ lines.append(" @overload")
376
+ lines.append(f' def __mod__(self, rhs: float) -> "{q}": ...')
377
+ for rhs in sorted(div_ops):
378
+ if rhs not in quantity_names:
379
+ continue
380
+ res = _format_result_annotation(div_ops[rhs], quantity_names)
381
+ if res is None:
382
+ continue
383
+ lines.append(" @overload")
384
+ lines.append(f' def __mod__(self, rhs: "{rhs}") -> {res}: ...')
385
+ lines.append(" @overload")
386
+ lines.append(" def __mod__(self, rhs: Any) -> Any: ...")
375
387
  lines.append(f' def __rmul__(self, rhs: float) -> "{q}": ...')
376
388
  lines.append(" def __repr__(self) -> str: ...")
377
389
  lines.append(" def __str__(self) -> str: ...")
@@ -88,6 +88,7 @@ pub enum QuantityOperationError {
88
88
  SubError,
89
89
  MulError,
90
90
  DivError,
91
+ ModError,
91
92
  PowError,
92
93
  SqrtError,
93
94
  ComparisonError,
@@ -102,6 +103,7 @@ impl fmt::Display for QuantityOperationError {
102
103
  QuantityOperationError::SubError => write!(f, "Subtraction operation failed"),
103
104
  QuantityOperationError::MulError => write!(f, "Multiplication operation failed"),
104
105
  QuantityOperationError::DivError => write!(f, "Division operation failed"),
106
+ QuantityOperationError::ModError => write!(f, "Modulo operation failed"),
105
107
  QuantityOperationError::PowError => write!(f, "Power operation failed"),
106
108
  QuantityOperationError::SqrtError => write!(f, "Sqrt operation failed"),
107
109
  QuantityOperationError::ComparisonError => write!(f, "Comparison operation failed"),
@@ -3,7 +3,7 @@ macro_rules! impl_quantity {
3
3
  ($type:ident, $unit:ident, $display_units:expr) => {
4
4
  use core::cmp::Ordering;
5
5
  use core::fmt;
6
- use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
6
+ use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
7
7
  #[cfg(feature = "ndarray")]
8
8
  use ndarray::{Array1, Array2, ArrayView1, ArrayView2};
9
9
  use num_traits::FromPrimitive;
@@ -434,6 +434,22 @@ macro_rules! impl_quantity {
434
434
  }
435
435
  }
436
436
 
437
+ fn __mod__(lhs: PyRef<Self>, rhs: Py<PyAny>) -> PyResult<Py<PyAny>> {
438
+ let py = lhs.py();
439
+ let rhs_ref = rhs.bind(py);
440
+ let lhs_ref = lhs.into_pyobject(py)?;
441
+ let rhs_quantity = Quantity::from_py_any(rhs_ref)
442
+ .map_err(|e| PyTypeError::new_err(e.to_string()))?;
443
+ let lhs_quantity = Quantity::from_py_any(&lhs_ref)
444
+ .map_err(|e| PyTypeError::new_err(e.to_string()))?;
445
+ match lhs_quantity % rhs_quantity {
446
+ Ok(value) => Ok(value.to_pyobject(py)?),
447
+ Err(_) => Err(PyTypeError::new_err(
448
+ "Modulo of given objects is not possible.",
449
+ )),
450
+ }
451
+ }
452
+
437
453
  fn __rmul__(&self, rhs: f64) -> PyResult<Self> {
438
454
  Ok(*self * rhs)
439
455
  }
@@ -645,6 +661,32 @@ macro_rules! impl_quantity {
645
661
  }
646
662
  }
647
663
 
664
+ impl Rem<f64> for $type {
665
+ type Output = Self;
666
+
667
+ fn rem(self, rhs: f64) -> Self::Output {
668
+ #[cfg(not(any(feature = "storage-f64", feature = "storage-f32")))]
669
+ {
670
+ let (rhs_multiplier, rhs_power) = Self::split_value(rhs);
671
+ let (multiplier, power) = $crate::internal::quantity_parts_rem(
672
+ self.multiplier,
673
+ self.power,
674
+ rhs_multiplier,
675
+ rhs_power,
676
+ );
677
+ Self::from_parts(multiplier, power)
678
+ }
679
+ #[cfg(feature = "storage-f64")]
680
+ {
681
+ Self::from_base_value(self.value % rhs)
682
+ }
683
+ #[cfg(feature = "storage-f32")]
684
+ {
685
+ Self::from_base_value(f64::from(self.value % rhs as f32))
686
+ }
687
+ }
688
+ }
689
+
648
690
  impl Mul<f64> for $type {
649
691
  type Output = Self;
650
692
 
@@ -1079,6 +1121,31 @@ macro_rules! impl_div_with_self_to_f64 {
1079
1121
  }
1080
1122
  }
1081
1123
  }
1124
+
1125
+ impl core::ops::Rem<$lhs> for $lhs {
1126
+ type Output = f64;
1127
+
1128
+ fn rem(self, rhs: Self) -> Self::Output {
1129
+ #[cfg(not(any(feature = "storage-f64", feature = "storage-f32")))]
1130
+ {
1131
+ let (multiplier, power) = $crate::internal::quantity_parts_rem(
1132
+ self.multiplier,
1133
+ self.power,
1134
+ rhs.multiplier,
1135
+ rhs.power,
1136
+ );
1137
+ $crate::internal::quantity_parts_to_value(multiplier, power)
1138
+ }
1139
+ #[cfg(feature = "storage-f64")]
1140
+ {
1141
+ self.value % rhs.value
1142
+ }
1143
+ #[cfg(feature = "storage-f32")]
1144
+ {
1145
+ f64::from(self.value % rhs.value)
1146
+ }
1147
+ }
1148
+ }
1082
1149
  };
1083
1150
  }
1084
1151
 
@@ -1341,6 +1408,33 @@ macro_rules! impl_div {
1341
1408
  }
1342
1409
  }
1343
1410
 
1411
+ impl core::ops::Rem<$rhs> for $lhs {
1412
+ type Output = $result;
1413
+
1414
+ fn rem(self, rhs: $rhs) -> Self::Output {
1415
+ #[cfg(not(any(feature = "storage-f64", feature = "storage-f32")))]
1416
+ {
1417
+ let (multiplier, power) = $crate::internal::quantity_parts_rem(
1418
+ self.multiplier,
1419
+ self.power,
1420
+ rhs.multiplier,
1421
+ rhs.power,
1422
+ );
1423
+ <$result>::from_exponential(multiplier, power)
1424
+ }
1425
+ #[cfg(feature = "storage-f64")]
1426
+ {
1427
+ <$result as $crate::PhysicsQuantity>::from_raw(self.value % rhs.value)
1428
+ }
1429
+ #[cfg(feature = "storage-f32")]
1430
+ {
1431
+ <$result as $crate::PhysicsQuantity>::from_raw(f64::from(
1432
+ self.value % rhs.value,
1433
+ ))
1434
+ }
1435
+ }
1436
+ }
1437
+
1344
1438
  #[cfg(feature = "ndarray")]
1345
1439
  impl DivArray1<$rhs> for Array1<$lhs> {
1346
1440
  type Output = Array1<$result>;
@@ -242,6 +242,66 @@ pub fn pow10_delta(lhs: i32, rhs: i32) -> f64 {
242
242
  pow10(saturating_power_sub(lhs, rhs))
243
243
  }
244
244
 
245
+ #[cfg(not(any(feature = "storage-f64", feature = "storage-f32")))]
246
+ pub fn quantity_parts_rem(
247
+ lhs_multiplier: f64,
248
+ lhs_power: i32,
249
+ rhs_multiplier: f64,
250
+ rhs_power: i32,
251
+ ) -> (f64, i32) {
252
+ if lhs_multiplier.is_nan() || rhs_multiplier.is_nan() {
253
+ return (f64::NAN, 0);
254
+ }
255
+
256
+ if rhs_multiplier == 0.0 {
257
+ return (f64::NAN, 0);
258
+ }
259
+
260
+ if lhs_multiplier == 0.0 {
261
+ return (0.0, 0);
262
+ }
263
+
264
+ if lhs_multiplier.is_infinite() {
265
+ return (f64::NAN, 0);
266
+ }
267
+
268
+ if rhs_multiplier.is_infinite() {
269
+ return canonicalize_quantity_parts(lhs_multiplier, lhs_power);
270
+ }
271
+
272
+ let lhs_abs = lhs_multiplier.abs();
273
+ let rhs_abs = rhs_multiplier.abs();
274
+ let common_power = lhs_power.max(rhs_power);
275
+ let scaled_lhs = lhs_abs * pow10_delta(lhs_power, common_power);
276
+ let scaled_rhs = rhs_abs * pow10_delta(rhs_power, common_power);
277
+
278
+ if scaled_lhs < scaled_rhs {
279
+ return canonicalize_quantity_parts(lhs_multiplier, lhs_power);
280
+ }
281
+
282
+ if scaled_lhs == scaled_rhs {
283
+ return (0.0, 0);
284
+ }
285
+
286
+ let sign = if lhs_multiplier.is_sign_negative() {
287
+ -1.0
288
+ } else {
289
+ 1.0
290
+ };
291
+ let delta = i64::from(lhs_power) - i64::from(rhs_power);
292
+ let rem_multiplier = if delta >= 0 {
293
+ let mut rem = lhs_abs % rhs_abs;
294
+ for _ in 0..delta {
295
+ rem = (rem * 10.0) % rhs_abs;
296
+ }
297
+ rem
298
+ } else {
299
+ lhs_abs * pow10_delta(lhs_power, rhs_power) % rhs_abs
300
+ };
301
+
302
+ canonicalize_quantity_parts(sign * rem_multiplier, rhs_power)
303
+ }
304
+
245
305
  #[cfg(feature = "no_std")]
246
306
  pub fn sqrt(value: f64) -> f64 {
247
307
  if value < 0.0 {
@@ -73,6 +73,12 @@ pub mod quantities {
73
73
  pub use compliance::*;
74
74
  pub mod density;
75
75
  pub use density::*;
76
+ pub mod density_rate;
77
+ pub use density_rate::*;
78
+ pub mod density_temperature;
79
+ pub use density_temperature::*;
80
+ pub mod density_temperature_rate;
81
+ pub use density_temperature_rate::*;
76
82
  pub mod distance;
77
83
  pub use distance::*;
78
84
  pub mod force;
@@ -115,6 +121,12 @@ pub mod quantities {
115
121
  pub use strain::*;
116
122
  pub mod stress;
117
123
  pub use stress::*;
124
+ pub mod stress_per_temperature;
125
+ pub use stress_per_temperature::*;
126
+ pub mod stress_rate;
127
+ pub use stress_rate::*;
128
+ pub mod stress_rate_per_temperature;
129
+ pub use stress_rate_per_temperature::*;
118
130
  pub mod stress_squared;
119
131
  pub use stress_squared::*;
120
132
  pub mod temperature;
@@ -0,0 +1,32 @@
1
+ use crate::impl_macros::macros::*;
2
+
3
+ #[cfg_attr(feature = "strum", derive(EnumIter))]
4
+ #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5
+ #[derive(Copy, Clone, PartialEq, Debug, Hash, Eq)]
6
+ #[cfg_attr(feature = "pyo3", pyclass(eq, eq_int, from_py_object))]
7
+ pub enum DensityRateUnit {
8
+ kg_mcbs,
9
+ }
10
+
11
+ impl DensityRateUnit {
12
+ pub const fn base_per_x_const(self) -> (f64, i32) {
13
+ match self {
14
+ DensityRateUnit::kg_mcbs => (1., 0),
15
+ }
16
+ }
17
+ }
18
+
19
+ impl PhysicsUnit for DensityRateUnit {
20
+ fn name(&self) -> &str {
21
+ match &self {
22
+ DensityRateUnit::kg_mcbs => "kg/(m³*s)",
23
+ }
24
+ }
25
+
26
+ fn base_per_x(&self) -> (f64, i32) {
27
+ (*self).base_per_x_const()
28
+ }
29
+ }
30
+
31
+ impl_quantity!(DensityRate, DensityRateUnit, [DensityRateUnit::kg_mcbs]);
32
+ impl_div_with_self_to_f64!(DensityRate);
@@ -0,0 +1,36 @@
1
+ use crate::impl_macros::macros::*;
2
+
3
+ #[cfg_attr(feature = "strum", derive(EnumIter))]
4
+ #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5
+ #[derive(Copy, Clone, PartialEq, Debug, Hash, Eq)]
6
+ #[cfg_attr(feature = "pyo3", pyclass(eq, eq_int, from_py_object))]
7
+ pub enum DensityTemperatureUnit {
8
+ kgK_mcb,
9
+ }
10
+
11
+ impl DensityTemperatureUnit {
12
+ pub const fn base_per_x_const(self) -> (f64, i32) {
13
+ match self {
14
+ DensityTemperatureUnit::kgK_mcb => (1., 0),
15
+ }
16
+ }
17
+ }
18
+
19
+ impl PhysicsUnit for DensityTemperatureUnit {
20
+ fn name(&self) -> &str {
21
+ match &self {
22
+ DensityTemperatureUnit::kgK_mcb => "kg*K/m³",
23
+ }
24
+ }
25
+
26
+ fn base_per_x(&self) -> (f64, i32) {
27
+ (*self).base_per_x_const()
28
+ }
29
+ }
30
+
31
+ impl_quantity!(
32
+ DensityTemperature,
33
+ DensityTemperatureUnit,
34
+ [DensityTemperatureUnit::kgK_mcb]
35
+ );
36
+ impl_div_with_self_to_f64!(DensityTemperature);
@@ -0,0 +1,36 @@
1
+ use crate::impl_macros::macros::*;
2
+
3
+ #[cfg_attr(feature = "strum", derive(EnumIter))]
4
+ #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5
+ #[derive(Copy, Clone, PartialEq, Debug, Hash, Eq)]
6
+ #[cfg_attr(feature = "pyo3", pyclass(eq, eq_int, from_py_object))]
7
+ pub enum DensityTemperatureRateUnit {
8
+ kgK_mcbs,
9
+ }
10
+
11
+ impl DensityTemperatureRateUnit {
12
+ pub const fn base_per_x_const(self) -> (f64, i32) {
13
+ match self {
14
+ DensityTemperatureRateUnit::kgK_mcbs => (1., 0),
15
+ }
16
+ }
17
+ }
18
+
19
+ impl PhysicsUnit for DensityTemperatureRateUnit {
20
+ fn name(&self) -> &str {
21
+ match &self {
22
+ DensityTemperatureRateUnit::kgK_mcbs => "kg*K/(m³*s)",
23
+ }
24
+ }
25
+
26
+ fn base_per_x(&self) -> (f64, i32) {
27
+ (*self).base_per_x_const()
28
+ }
29
+ }
30
+
31
+ impl_quantity!(
32
+ DensityTemperatureRate,
33
+ DensityTemperatureRateUnit,
34
+ [DensityTemperatureRateUnit::kgK_mcbs]
35
+ );
36
+ impl_div_with_self_to_f64!(DensityTemperatureRate);
@@ -0,0 +1,4 @@
1
+ use crate::impl_macros::macros::*;
2
+ use crate::{StressRate, StressRateUnit};
3
+
4
+ make_alias!(StressRate, StressRateUnit, PressureRate, PressureRateUnit);
@@ -0,0 +1,39 @@
1
+ use crate::impl_macros::macros::*;
2
+
3
+ #[cfg_attr(feature = "strum", derive(EnumIter))]
4
+ #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5
+ #[derive(Copy, Clone, PartialEq, Debug, Hash, Eq)]
6
+ #[cfg_attr(feature = "pyo3", pyclass(eq, eq_int, from_py_object))]
7
+ pub enum StressPerTemperatureUnit {
8
+ Pa_K,
9
+ MPa_K,
10
+ }
11
+
12
+ impl StressPerTemperatureUnit {
13
+ pub const fn base_per_x_const(self) -> (f64, i32) {
14
+ match self {
15
+ StressPerTemperatureUnit::Pa_K => (1., 0),
16
+ StressPerTemperatureUnit::MPa_K => (1., 6),
17
+ }
18
+ }
19
+ }
20
+
21
+ impl PhysicsUnit for StressPerTemperatureUnit {
22
+ fn name(&self) -> &str {
23
+ match &self {
24
+ StressPerTemperatureUnit::Pa_K => "Pa/K",
25
+ StressPerTemperatureUnit::MPa_K => "MPa/K",
26
+ }
27
+ }
28
+
29
+ fn base_per_x(&self) -> (f64, i32) {
30
+ (*self).base_per_x_const()
31
+ }
32
+ }
33
+
34
+ impl_quantity!(
35
+ StressPerTemperature,
36
+ StressPerTemperatureUnit,
37
+ [StressPerTemperatureUnit::Pa_K]
38
+ );
39
+ impl_div_with_self_to_f64!(StressPerTemperature);
@@ -0,0 +1,50 @@
1
+ use crate::impl_macros::macros::*;
2
+
3
+ #[cfg_attr(feature = "strum", derive(EnumIter))]
4
+ #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5
+ #[derive(Copy, Clone, PartialEq, Debug, Hash, Eq)]
6
+ #[cfg_attr(feature = "pyo3", pyclass(eq, eq_int, from_py_object))]
7
+ pub enum StressRateUnit {
8
+ Pa_s,
9
+ kPa_s,
10
+ MPa_s,
11
+ GPa_s,
12
+ bar_s,
13
+ psi_s,
14
+ bar_min,
15
+ }
16
+
17
+ impl StressRateUnit {
18
+ pub const fn base_per_x_const(self) -> (f64, i32) {
19
+ match self {
20
+ StressRateUnit::Pa_s => (1., 0),
21
+ StressRateUnit::kPa_s => (1., 3),
22
+ StressRateUnit::MPa_s => (1., 6),
23
+ StressRateUnit::GPa_s => (1., 9),
24
+ StressRateUnit::bar_s => (1., 5),
25
+ StressRateUnit::psi_s => (6.895, 3),
26
+ StressRateUnit::bar_min => (1.0 / 60.0, 5),
27
+ }
28
+ }
29
+ }
30
+
31
+ impl PhysicsUnit for StressRateUnit {
32
+ fn name(&self) -> &str {
33
+ match &self {
34
+ StressRateUnit::Pa_s => "Pa/s",
35
+ StressRateUnit::kPa_s => "kPa/s",
36
+ StressRateUnit::MPa_s => "MPa/s",
37
+ StressRateUnit::GPa_s => "GPa/s",
38
+ StressRateUnit::bar_s => "bar/s",
39
+ StressRateUnit::psi_s => "psi/s",
40
+ StressRateUnit::bar_min => "bar/min",
41
+ }
42
+ }
43
+
44
+ fn base_per_x(&self) -> (f64, i32) {
45
+ (*self).base_per_x_const()
46
+ }
47
+ }
48
+
49
+ impl_quantity!(StressRate, StressRateUnit, [StressRateUnit::MPa_s]);
50
+ impl_div_with_self_to_f64!(StressRate);
@@ -0,0 +1,39 @@
1
+ use crate::impl_macros::macros::*;
2
+
3
+ #[cfg_attr(feature = "strum", derive(EnumIter))]
4
+ #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5
+ #[derive(Copy, Clone, PartialEq, Debug, Hash, Eq)]
6
+ #[cfg_attr(feature = "pyo3", pyclass(eq, eq_int, from_py_object))]
7
+ pub enum StressRatePerTemperatureUnit {
8
+ Pa_sK,
9
+ MPa_sK,
10
+ }
11
+
12
+ impl StressRatePerTemperatureUnit {
13
+ pub const fn base_per_x_const(self) -> (f64, i32) {
14
+ match self {
15
+ StressRatePerTemperatureUnit::Pa_sK => (1., 0),
16
+ StressRatePerTemperatureUnit::MPa_sK => (1., 6),
17
+ }
18
+ }
19
+ }
20
+
21
+ impl PhysicsUnit for StressRatePerTemperatureUnit {
22
+ fn name(&self) -> &str {
23
+ match &self {
24
+ StressRatePerTemperatureUnit::Pa_sK => "Pa/(s*K)",
25
+ StressRatePerTemperatureUnit::MPa_sK => "MPa/(s*K)",
26
+ }
27
+ }
28
+
29
+ fn base_per_x(&self) -> (f64, i32) {
30
+ (*self).base_per_x_const()
31
+ }
32
+ }
33
+
34
+ impl_quantity!(
35
+ StressRatePerTemperature,
36
+ StressRatePerTemperatureUnit,
37
+ [StressRatePerTemperatureUnit::Pa_sK]
38
+ );
39
+ impl_div_with_self_to_f64!(StressRatePerTemperature);
@@ -1,7 +1,7 @@
1
1
  use core::cmp::Ordering;
2
2
  use core::fmt;
3
3
  use core::fmt::{Display, Formatter};
4
- use core::ops::{Add, Div, Mul, Neg, Sub};
4
+ use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
5
5
  #[cfg(feature = "pyo3")]
6
6
  use pyo3::{Bound, PyAny, prelude::*};
7
7
 
@@ -107,6 +107,18 @@ impl Div for Quantity {
107
107
  }
108
108
  }
109
109
 
110
+ impl Rem for Quantity {
111
+ type Output = crate::QuantityOperationResult<Quantity>;
112
+ fn rem(self, other: Quantity) -> crate::QuantityOperationResult<Quantity> {
113
+ use Quantity::*;
114
+ match (self, other) {
115
+ (FloatQuantity(v_lhs), FloatQuantity(v_rhs)) => Ok(FloatQuantity(v_lhs % v_rhs)),
116
+ // __MOD_MATCHES__
117
+ _ => Err(crate::QuantityOperationError::ModError)
118
+ }
119
+ }
120
+ }
121
+
110
122
  impl Add for Quantity {
111
123
  type Output = crate::QuantityOperationResult<Quantity>;
112
124
  fn add(self, other: Quantity) -> crate::QuantityOperationResult<Quantity> {
@@ -43,7 +43,10 @@ impl_mul_relation_with_other!(ForcePerVolume, Area, Stiffness);
43
43
  impl_mul_relation_with_other!(ForcePerVolume, Distance, Stress);
44
44
  impl_mul_relation_with_other!(InverseDistance, Stress, ForcePerVolume);
45
45
  impl_mul_relation_with_other!(InverseDistance, ForceDistance, Force);
46
- impl_mul_relation_with_other!(PressureRate, Time, Stress);
46
+ impl_mul_relation_with_other!(StressRate, Time, Stress);
47
+ impl_mul_relation_with_other!(Stress, Frequency, StressRate);
48
+ impl_mul_relation_with_other!(InverseStress, StressRate, Frequency);
49
+ impl_mul_relation_with_other!(ForcePerVolume, Velocity, StressRate);
47
50
  impl_mul_relation_with_other!(Stress, Distance, Stiffness);
48
51
  impl_mul_relation_with_other!(StressSquared, Area, ForceStress);
49
52
  impl_mul_relation_with_other!(Velocity, Distance, Time);
@@ -60,6 +63,15 @@ impl_mul_relation_with_other!(Velocity, AngularVelocity, Acceleration);
60
63
  impl_mul_relation_with_other!(SpecificGasConstant, MolarMass, UniversalGasConstant);
61
64
  impl_mul_relation_with_other!(SpecificGasConstant, Temperature, VelocitySquared);
62
65
  impl_mul_relation_with_other!(Density, VelocitySquared, Stress);
66
+ impl_mul_relation_with_other!(Density, Temperature, DensityTemperature);
67
+ impl_mul_relation_with_other!(SpecificGasConstant, DensityTemperature, Stress);
68
+ impl_mul_relation_with_other!(Density, SpecificGasConstant, StressPerTemperature);
69
+ impl_mul_relation_with_other!(StressPerTemperature, Temperature, Stress);
70
+ impl_mul_relation_with_other!(DensityRate, VelocitySquared, StressRate);
71
+ impl_mul_relation_with_other!(DensityRate, Temperature, DensityTemperatureRate);
72
+ impl_mul_relation_with_other!(SpecificGasConstant, DensityTemperatureRate, StressRate);
73
+ impl_mul_relation_with_other!(DensityRate, SpecificGasConstant, StressRatePerTemperature);
74
+ impl_mul_relation_with_other!(StressRatePerTemperature, Temperature, StressRate);
63
75
  impl_mul!(InverseDistance, Distance, f64);
64
76
  impl_mul!(InverseAngle, Angle, f64);
65
77
  impl_mul!(InverseStress, Stress, f64);
File without changes