SPH
Units.cpp
Go to the documentation of this file.
1 #include "physics/Units.h"
3 
5 
7 
8 struct UnitDesc {
9  std::string label;
11 
12  bool operator<(const UnitDesc& other) const {
13  return unit < other.unit;
14  }
15 };
16 
18  FlatSet<UnitDesc> length = {
19  { "mm", 1._mm },
20  { "cm", 1._cm },
21  { "m", 1._m },
22  { "km", 1._km },
23  { "au", Unit::meter(Constants::au) },
24  };
25  FlatSet<UnitDesc> mass = {
26  { "g", 1.e-3_kg },
27  { "kg", 1._kg },
28  { "M_sun", Unit::kilogram(Constants::M_sun) },
29  { "M_earth", Unit::kilogram(Constants::M_earth) },
30  };
31  FlatSet<UnitDesc> time = {
32  { "s", 1._s },
33  { "min", 60._s },
34  { "h", 3600._s },
35  { "d", 86400._s },
36  { "y", 31556926._s },
37  };
38  FlatSet<UnitDesc> angle = {
39  { "rad", 1._rad },
40  };
41 
43  units.insert(BasicDimension::LENGTH, std::move(length));
44  units.insert(BasicDimension::MASS, std::move(mass));
45  units.insert(BasicDimension::TIME, std::move(time));
46  units.insert(BasicDimension::ANGLE, std::move(angle));
47  return units;
48 }();
49 
50 std::ostream& operator<<(std::ostream& stream, const Unit& u) {
52  stream << u.value(UnitSystem::SI()); // unit system irrelevant
53  } else {
55  for (Size i = 0; i < DIMENSION_CNT; ++i) {
56  const int power = u.dimension()[BasicDimension(i)];
57  if (power != 0) {
58  dim = BasicDimension(i);
59  break;
60  }
61  }
62  SPH_ASSERT(dim != BasicDimension(-1));
63 
64  UnitSystem system = CODE_UNITS;
65  Optional<UnitDesc> selectedDesc;
66  for (UnitDesc& desc : UNITS[dim]) {
67  if (!selectedDesc) {
68  selectedDesc = desc;
69  } else {
70  system[dim] = desc.unit.value(CODE_UNITS);
71  if (u.value(system) >= 1._f) {
72  selectedDesc = desc;
73  }
74  }
75  }
76  system[dim] = selectedDesc->unit.value(CODE_UNITS);
77  stream << u.value(system) << selectedDesc->label;
78  if (u.dimension()[dim] != 1) {
79  stream << "^" << u.dimension()[dim];
80  }
81  }
82 
83  return stream;
84 }
85 
86 Expected<Unit> parseUnit(const std::string& text) {
87  Unit u = Unit::dimensionless(1._f);
88  Array<std::string> parts = split(text, ' ');
89  for (std::string& part : parts) {
90  if (part.empty()) {
91  // multiple spaces or empty input string; allow and continue
92  continue;
93  }
94  Array<std::string> valueAndPower = split(part, '^');
95  if (valueAndPower.size() > 2) {
96  return makeUnexpected<Unit>("More than one exponent");
97  }
98  SPH_ASSERT(valueAndPower.size() == 1 || valueAndPower.size() == 2);
99  int power;
100  if (valueAndPower.size() == 1) {
101  // just unit without any power
102  power = 1;
103  (void)power;
104  } else {
105  if (Optional<int> optPower = fromString<int>(valueAndPower[1])) {
106  power = optPower.value();
107  } else {
108  return makeUnexpected<Unit>("Cannot convert power to int");
109  }
110  }
111  }
112  return u;
113 }
114 
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
Container storing sorted unique values.
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
#define NAMESPACE_SPH_END
Definition: Object.h:12
Array< std::string > split(const std::string &s, const char delimiter)
Splits a string into an array of string using given delimiter.
Expected< Unit > parseUnit(const std::string &text)
Definition: Units.cpp:86
std::ostream & operator<<(std::ostream &stream, const Unit &u)
Definition: Units.cpp:50
NAMESPACE_SPH_BEGIN UnitSystem CODE_UNITS
Definition: Units.cpp:6
FlatMap< BasicDimension, FlatSet< UnitDesc > > UNITS
Definition: Units.cpp:17
BasicDimension
Definition: Units.h:29
constexpr Size DIMENSION_CNT
Definition: Units.h:36
INLINE TCounter size() const noexcept
Definition: Array.h:193
Wrapper of type that either contains a value of given type, or an error message.
Definition: Expected.h:25
Container of key-value pairs.
Definition: FlatMap.h:19
INLINE TValue & insert(const TKey &key, const TValue &value)
Adds a new element into the map or sets new value of element with the same key.
Definition: FlatMap.h:65
Wrapper of type value of which may or may not be present.
Definition: Optional.h:23
INLINE Type & value()
Returns the reference to the stored value.
Definition: Optional.h:172
static UnitDimensions dimensionless()
Definition: Units.h:135
static UnitSystem SI()
Definition: Units.h:226
Single benchmark unit.
Definition: Session.h:118
static Unit dimensionless(const Float value)
Definition: Units.h:354
static Unit kilogram(const Float value)
Definition: Units.h:358
Float value(const UnitSystem &system) const
Returns the value in given unit system.
Definition: Units.h:255
UnitDimensions dimension() const
Definition: Units.h:259
static Unit meter(const Float value)
Definition: Units.h:362
constexpr Float au
Astronomical unit (exactly)
Definition: Constants.h:38
constexpr Float M_earth
Earth mass.
Definition: Constants.h:54
constexpr Float M_sun
Definition: Constants.h:51
Unit unit
Definition: Units.cpp:10
std::string label
Definition: Units.cpp:9
bool operator<(const UnitDesc &other) const
Definition: Units.cpp:12