Alamo
Unit.H
Go to the documentation of this file.
1#ifndef UNIT_UNIT_H
2#define UNIT_UNIT_H
3
4
5#include <array>
6#include <charconv>
7#include <cstdlib>
8#include <iostream>
9#include <system_error>
10#include <unordered_map>
11#include <string>
12#include <stdexcept>
13#include <cmath>
14#include <regex>
15
16#include "Util/Util.H"
17//#include "Set/Base.H"
18//#include "String.H"
19
20struct Unit : std::pair<double,std::array<int,7>>
21{
22
23 //
24 // STATIC CONST DEFINITIONS, TRUE EVERYWHERE
25 //
26 enum class Type {
28 };
29 // Fundamental units
30 inline static const std::map<std::string, std::pair<double,std::array<int,7>>> base_units =
31 {
32 {"1", {1.0, {0,0,0,0,0,0,0}}},
33 {"m", {1.0, {1,0,0,0,0,0,0}}},
34 {"s", {1.0, {0,1,0,0,0,0,0}}},
35 {"kg", {1.0, {0,0,1,0,0,0,0}}},
36 {"K", {1.0, {0,0,0,1,0,0,0}}},
37 {"A", {1.0, {0,0,0,0,1,0,0}}},
38 {"mol",{1.0, {0,0,0,0,0,1,0}}},
39 {"cd", {1.0, {0,0,0,0,0,0,1}}}
40 };
41 //
42 // Compound unit relationships and nomenclature
43 // Any desired unit relationship can be added to this list.
44 // The unit conversion can be specified in any desired format, as long as
45 // all of the units on the right hand side are resolvable.
46 //
47 inline static const std::map<std::string, std::pair<double,std::string>> compound = {
48 // Lengths
49 {"km", {1e+3, "m" }},
50 {"hm", {1e+2, "m" }},
51 {"dam", {1e+1, "m" }},
52 {"dm", {1e-1, "m" }},
53 {"cm", {1e-2, "m" }},
54 {"mm", {1e-3, "m" }},
55 {"um", {1e-6, "m" }},
56 {"nm", {1e-9, "m" }},
57 {"pm", {1e-12, "m" }},
58 {"in", {0.0254, "m" }},
59 {"ft", {0.3048, "m" }},
60 {"yd", {0.9144, "m" }},
61 {"mi", {5280.0, "ft" }},
62 {"furlong", {660.0, "ft" }},
63 {"au", {1.495978707e11, "m" }}, // astronomical unit
64 {"ly", {9.4607304725808e15, "m"}}, // lightyear
65 {"pc", {3.08567758149137e16, "m"}}, // parsec
66
67 // Angles
68 {"rad", {1.0, "1"}},
69 {"deg", {0.01745329251, "rad" }},
70
71 // Times
72 {"ms", {1e-3, "s" }},
73 {"us", {1e-6, "s" }},
74 {"ns", {1e-9, "s" }},
75 {"ps", {1e-12, "s" }},
76 {"min", {60.0, "s" }},
77 {"hr", {60.0, "min" }},
78 {"day", {24.0, "hr" }},
79 {"week", {7.0, "day" }},
80 {"fortnight", {14.0, "day" }},
81 {"year", {365.25, "day" }},
82 {"decade", {10.0, "year" }},
83
84 // Mass
85 {"g", {1e-3, "kg" }},
86 {"mg", {1e-6, "kg" }},
87 {"ug", {1e-9, "kg" }},
88 {"tonne", {1000.0, "kg" }},
89 {"lb", {0.45359237, "kg" }},
90 {"oz", {0.0283495, "kg" }},
91 {"slug", {14.5939, "kg" }},
92
93 // Speed
94 {"mph", {1.0, "mi/hr" }},
95 {"kph", {1.0, "km/hr" }},
96 {"mps", {1.0, "m/s" }},
97 {"fps", {1.0, "ft/s" }},
98 {"knot", {1852.0 / 3600.0, "m/s"}},
99
100 // Area
101 {"ha", {1e4, "m^2" }},
102 {"acre", {4046.85642, "m^2" }},
103 {"sqft", {1.0, "ft^2" }},
104 {"sqin", {1.0, "in^2" }},
105 {"sqkm", {1.0, "km^2" }},
106 {"sqmi", {1.0, "mi^2" }},
107
108 // Volume
109 {"L", {1e-3, "m^3" }},
110 {"mL", {1e-6, "m^3" }},
111 {"cc", {1e-6, "m^3" }},
112 {"gal", {3.78541e-3, "m^3" }},
113 {"qt", {0.946353e-3, "m^3" }},
114 {"pt", {0.473176e-3, "m^3" }},
115 {"cup", {0.24e-3, "m^3" }},
116 {"floz", {29.5735e-6, "m^3" }},
117 {"tbsp", {14.7868e-6, "m^3" }},
118 {"tsp", {4.92892e-6, "m^3" }},
119
120 // Force
121 {"N", {1.0, "kg*m/s^2" }},
122 {"kN", {1e3, "N" }},
123 {"lbf", {4.44822162, "N" }},
124 {"dyn", {1e-5, "N" }},
125
126 // Energy
127 {"J", {1.0, "N*m" }},
128 {"mJ", {1e-3, "J" }},
129 {"kJ", {1e3, "J" }},
130 {"MJ", {1e6, "J" }},
131 {"eV", {1.602176634e-19, "J"}},
132 {"cal", {4.184, "J" }},
133 {"kcal", {4184.0, "J" }},
134 {"BTU", {1055.06, "J" }},
135 {"ft*lbf", {1.35582, "J" }},
136
137 // Power
138 {"W", {1.0, "J/s" }},
139 {"mW", {1e-3, "W" }},
140 {"kW", {1e3, "W" }},
141 {"MW", {1e6, "W" }},
142 {"hp", {745.7, "W" }},
143
144 // Pressure
145 {"Pa", {1.0, "N/m^2" }},
146 {"kPa", {1e3, "Pa" }},
147 {"MPa", {1e6, "Pa" }},
148 {"GPa", {1e9, "Pa" }},
149 {"bar", {1e5, "Pa" }},
150 {"atm", {101325.0,"Pa" }},
151 {"psi", {6894.76, "Pa" }},
152 {"mmHg", {133.322, "Pa" }},
153 {"torr", {133.322, "Pa" }},
154
155 // Temperature differences (not absolute temperatures)
156 {"K", {1.0, "K" }},
157 {"degR", {5.0/9.0, "K" }},
158
159 // Charge
160 {"C", {1.0, "A*s" }},
161 {"mAh", {3.6, "C" }},
162
163 // Voltage
164 {"V", {1.0, "J/C" }},
165
166 // Capacitance
167 {"F", {1.0, "C/V" }},
168
169 // Resistance
170 {"ohm", {1.0, "V/A" }},
171 {"kOhm", {1e3, "ohm" }},
172 {"MOhm", {1e6, "ohm" }},
173
174 // Conductance
175 {"S", {1.0, "1/ohm" }},
176
177 // Magnetic
178 {"T", {1.0, "kg/(A*s^2)"}},
179 {"G", {1e-4, "T" }}, // gauss
180
181 // Frequency
182 {"Hz", {1.0, "1/s" }},
183 {"kHz", {1e3, "Hz" }},
184 {"MHz", {1e6, "Hz" }},
185 {"GHz", {1e9, "Hz" }},
186
187 // Moles
188 {"kmol", {1e3, "mol" }}
189 };
190
191
192 //
193 // These static factory functions return unit types.
194 // They are used to check unit compliance, mainly at the parsing stage.
195 //
196 // Primary
197 static Unit Less() { return Unit{1.0, {0,0,0,0,0,0,0}}; } // 1
198 static Unit Length() { return Unit{1.0, {1,0,0,0,0,0,0}}; } // m
199 static Unit Time() { return Unit{1.0, {0,1,0,0,0,0,0}}; } // s
200 static Unit Mass() { return Unit{1.0, {0,0,1,0,0,0,0}}; } // kg
201 static Unit Temperature() { return Unit{1.0, {0,0,0,1,0,0,0}}; } // K
202 static Unit Current() { return Unit{1.0, {0,0,0,0,1,0,0}}; } // A
203 static Unit Amount() { return Unit{1.0, {0,0,0,0,0,1,0}}; } // mol
204 static Unit LuminousIntensity() { return Unit{1.0, {0,0,0,0,0,0,1}}; } // cd
205
206 static Unit Angle() {return Unit::Less();}
207
208 // Geometry and kinematics
209 static Unit Area() { return Length()*Length(); }
210 static Unit Volume() { return Length()*Length()*Length(); }
211 static Unit Velocity() { return Length() / Time();}
212 static Unit Acceleration(){ return Velocity() / Time(); }
213 // Mechanics
214 static Unit Force() { return Mass() * Acceleration(); } // kg·m/s² = N
215 static Unit Momentum() { return Mass() * Velocity(); }
216 static Unit Impulse() { return Force() * Time(); }
217 static Unit Pressure() { return Force() / Area(); } // N/m² = Pa
218 static Unit Energy() { return Force() * Length(); } // N·m = J
219 static Unit Power() { return Energy() / Time(); } // J/s = W
220 static Unit Density() { return Mass() / Volume(); }
221 static Unit SpecificWeight() { return Force() / Volume(); }
222 static Unit Work() { return Energy(); }
223 // Thermodynamics
224 static Unit SpecificHeatCapacity() {return Energy() / Mass() / Temperature() ;}
225 static Unit MolarHeatCapacity() {return Energy() / Amount() / Temperature() ;}
228 static Unit HeatFlux() { return Power() / Area(); }
230 // Electromagnetism
231
232 static Unit Charge() { return Current() * Time(); } // A·s = C
233 static Unit Voltage() { return Power() / Current(); } // W/A = V
234 static Unit Resistance() { return Voltage() / Current(); } // V/A = Ω
235 static Unit Capacitance() { return Charge() / Voltage(); } // C/V = F
236 static Unit Conductance() { return Less() / Resistance(); } // S = 1/Ω
237 static Unit MagneticFlux(){ return Voltage() * Time(); } // V·s = Wb
238 static Unit MagneticField(){ return MagneticFlux() / Area(); } // Wb/m² = T
239 static Unit Inductance() { return MagneticFlux() / Current(); } // Wb/A = H
240 // Chemistry
241 static Unit MolarMass() { return Mass() / Amount(); } // kg/mol
242 static Unit Concentration(){ return Amount() / Volume(); } // mol/m³
243 static Unit MolarEnergy() { return Energy() / Amount(); } // J/mol
244 // Optics and radiation
245 static Unit LuminousFlux() { return LuminousIntensity(); } // for scalar usage (lm)
246 static Unit Illuminance() { return LuminousFlux() / Area(); } // lux = lm/m²
247
248
249 //
250 // This is where SYSTEM NORMALIZATION is stored.
251 // Should usually be set once (at the beginning of the simulation) and then
252 // left constant throughout the simulation.
253 // All normalizations are in terms of standard SI units: m,s,kg,K,A,mol,cd.
254 //
255 inline static std::array<std::pair<std::string,double>, 7> normalization = {
256 std::pair{"m", 1.0},
257 std::pair{"s", 1.0},
258 std::pair{"kg", 1.0},
259 std::pair{"K", 1.0},
260 std::pair{"A", 1.0},
261 std::pair{"mol",1.0},
262 std::pair{"cd", 1.0}
263 };
264
265 using std::pair<double, std::array<int,7>>::pair;
266 Unit(const std::pair<double, std::array<int, 7>>& p) : std::pair<double, std::array<int, 7>>(p) {}
267 static std::map<std::string, int> ParseUnitString(const std::string& input);
268
269
270 static Unit Parse(double val, std::string unitstring, bool verbose = false)
271 {
272 Unit ret = StringParse(unitstring, verbose);
273 ret.first *= val;
274 return ret;
275 }
276 static Unit Parse(std::string unit, bool verbose = false)
277 {
278 if (unit.size() == 0) return Unit::Less();
279 std::vector<std::string> split;
280 std::stringstream ss(unit);
281 std::string item;
282 while (std::getline(ss, item, '_')) {
283 split.push_back(item);
284 }
285 if (split.size() == 2)
286 {
287 return Parse(std::stod(split[0]),split[1], verbose);
288 }
289 else if (split.size() == 1)
290 {
291 // Attempt to parse the string as if it's a unitless number
292 double value = NAN;
293
294 // auto first = unit.data();
295 // auto last = unit.data() + unit.size();
296 // auto result = std::from_chars(first, last, value); // apparently this fails on mac
297
298 char *end = nullptr;
299 value = std::strtod(unit.c_str(), &end);
300
301 // If it is a untless number, then return a unitless result
302 //if (result.ec == std::errc() && result.ptr == last) // fails on mac
303 if (end != unit.data() && *end == '\0')
304 {
305 Unit ret = Unit::Less();
306 ret.first = value;
307 return ret;
308 }
309 // Otherwise, it must be a pure unit, so return that.
310 else
311 {
312 return StringParse(unit);
313 }
314 }
315 else
316 {
317 throw std::runtime_error("Invalid unit string "+unit);
318 }
319 }
320
321
322 static Unit StringParse(std::string unitstring, bool verbose = false)
323 {
324 Unit type = Unit::Less();
325
326 // Get the map of base tokens with signed exponents from ParseUnitString
327 std::map<std::string,int> parsed_units = ParseUnitString(unitstring);
328 if (verbose)
329 {
330 for (auto parsed_unit : parsed_units)
331 {
332 std::cout << parsed_unit.first << " " << parsed_unit.second << std::endl;
333 }
334 }
335
336 for (auto &p : parsed_units)
337 {
338 const std::string &token = p.first;
339 int exp = p.second;
340
341 if (Unit::base_units.find(token) != base_units.end())
342 {
343 // Base unit: apply exponent
344 Unit t = Unit(Unit::base_units.at(token)) ^ exp;
345 type = type * t;
346 }
347 else if (compound.find(token) != compound.end())
348 {
349 // Compound unit: expand recursively
350 auto pair = compound.at(token);
351 double factor = pair.first;
352 const std::string &subunit_str = pair.second;
353
354 Unit t = StringParse(subunit_str); // recursive expansion
355 t = t ^ exp; // apply exponent to both factor and dimension
356 t.first *= std::pow(factor, exp); // scale numeric factor correctly
357
358 type = type * t;
359 }
360 else
361 {
362 throw std::runtime_error("Unknown unit token: " + token);
363 }
364 }
365
366 return type;
367 }
368
369 static void setLengthUnit(std::string unit)
370 {
371 Unit parsed = StringParse(unit);
372 if (parsed.second != Length().second) throw std::runtime_error("Not a unit of length: " + unit);
373 normalization[int(Type::Length)].first = unit;
374 normalization[int(Type::Length)].second = 1.0 / parsed.first;
375 }
376
377 static void setTimeUnit(std::string unit)
378 {
379 Unit parsed = StringParse(unit);
380 if (parsed.second != Time().second) throw std::runtime_error("Not a unit of time: " + unit);
381 normalization[int(Type::Time)].first = unit;
382 normalization[int(Type::Time)].second = 1.0 / parsed.first;
383 }
384
385 static void setMassUnit(std::string unit)
386 {
387 Unit parsed = StringParse(unit);
388 if (parsed.second != Mass().second) throw std::runtime_error("Not a unit of mass: " + unit);
389 normalization[int(Type::Mass)].first = unit;
390 normalization[int(Type::Mass)].second = 1.0 / parsed.first;
391 }
392
393 static void setTemperatureUnit(std::string unit)
394 {
395 Unit parsed = StringParse(unit);
396 if (parsed.second != Temperature().second) throw std::runtime_error("Not a unit of temperature: " + unit);
397 normalization[int(Type::Temperature)].first = unit;
398 normalization[int(Type::Temperature)].second = 1.0 / parsed.first;
399 }
400
401 static void setCurrentUnit(std::string unit)
402 {
403 Unit parsed = StringParse(unit);
404 if (parsed.second != Current().second) throw std::runtime_error("Not a unit of current: " + unit);
405 normalization[int(Type::Current)].first = unit;
406 normalization[int(Type::Current)].second = 1.0 / parsed.first;
407 }
408
409 static void setAmountUnit(std::string unit)
410 {
411 Unit parsed = StringParse(unit);
412 if (parsed.second != Amount().second) throw std::runtime_error("Not a unit of amount: " + unit);
413 normalization[int(Type::Amount)].first = unit;
414 normalization[int(Type::Amount)].second = 1.0 / parsed.first;
415 }
416
417 static void setLuminousIntensityUnit(std::string unit)
418 {
419 Unit parsed = StringParse(unit);
420 if (parsed.second != LuminousIntensity().second) throw std::runtime_error("Not a unit of luminous intensity: " + unit);
421 normalization[int(Type::LuminousIntensity)].first = unit;
422 normalization[int(Type::LuminousIntensity)].second = 1.0 / parsed.first;
423 }
424
425 bool isType(const Unit &test) const
426 {
427 return this->second == test.second;
428 }
429
431 {
432 Unit ret;
433 ret.first = this->first * rhs.first;
434 for (unsigned int i = 0; i < this->second.size(); i++) ret.second[i] = (this->second)[i] + rhs.second[i];
435 return ret;
436 }
437 friend Unit operator*(double lhs, const Unit& rhs) {
438 Unit ret;
439 ret.first = lhs * rhs.first;
440 ret.second = rhs.second;
441 return ret;
442 }
443 friend Unit operator*(const Unit& lhs, double rhs) {
444 Unit ret;
445 ret.first = rhs * lhs.first;
446 ret.second = lhs.second;
447 return ret;
448 }
450 {
451 Unit ret;
452 ret.first = this->first / rhs.first;
453 for (unsigned int i = 0; i < this->second.size(); i++) ret.second[i] = (this->second)[i] - rhs.second[i];
454 return ret;
455 }
456 friend Unit operator / (double lhs, const Unit& rhs) {
457 Unit ret = Unit::Less() / rhs;
458 ret.first = lhs * rhs.first;
459 return ret;
460 }
461 friend Unit operator / (const Unit& lhs, double rhs) {
462 Unit ret;
463 ret.first = lhs.first / rhs;
464 ret.second = lhs.second;
465 return ret;
466 }
468 {
469 Util::Assert(INFO, TEST(this->second == rhs.second), "Error adding values with unequal units");
470 Unit ret;
471 ret.first = this->first + rhs.first;
472 for (unsigned int i = 0; i < this->second.size(); i++) ret.second[i] = (this->second)[i];
473 return ret;
474 }
476 {
477 Util::Assert(INFO, TEST(this->second == rhs.second), "Error subtracting values with unequal units");
478 Unit ret;
479 ret.first = this->first - rhs.first;
480 for (unsigned int i = 0; i < this->second.size(); i++) ret.second[i] = (this->second)[i];
481 return ret;
482 }
483 Unit operator ^ (const int &rhs)
484 {
485 Unit ret;
486 ret.first = std::pow(this->first,rhs);
487 for (unsigned int i = 0; i < this->second.size(); i++)
488 {
489 ret.second[i] = (this->second)[i]*rhs;
490 }
491 return ret;
492 }
493
494 friend std::ostream& operator<<(std::ostream &out, const Unit &a)
495 {
496 out << a.normalized_value() << "_";
497 out << a.normalized_unitstring();
498 return out;
499 }
500
501 double normalized_value() const
502 {
503 double fac = 1.0;
504 for (unsigned int i = 0 ; i < this->second.size(); i++)
505 fac *= std::pow(normalization[i].second, this->second[i]);
506
507 return this->first * fac;
508 }
509
510 std::string normalized_unitstring() const
511 {
512 // little utility to join strings with delimiter
513 auto join = [] (std::vector<std::string>vec,std::string sep){
514 std::ostringstream oss;
515 for (size_t i = 0; i < vec.size(); ++i) {
516 oss << vec[i];
517 if (i < vec.size() - 1) {
518 oss << sep;
519 }
520 }
521 return oss.str();
522 };
523
524 std::vector<std::string> num, den;
525 for (unsigned int i = 0 ; i < this->second.size(); i++)
526 {
527 if (this->second[i] > 1)
528 num.push_back(normalization[i].first + "^" + std::to_string(this->second[i]));
529 else if (this->second[i] == 1)
530 num.push_back(normalization[i].first);
531 else if (this->second[i] == -1)
532 den.push_back(normalization[i].first);
533 else if (this->second[i] < -1)
534 den.push_back(normalization[i].first + "^" + std::to_string(std::abs(this->second[i])));
535 }
536
537 std::string ret;
538 if (num.size()) ret = join(num,"*");
539 else ret = "1";
540 if (den.size()) ret += "/" + join(den,"/");
541
542 return ret;
543 }
544};
545
546
547inline std::map<std::string, int>
548Unit::ParseUnitString(const std::string& input) {
549 std::map<std::string, int> result;
550 enum class Op { Mul = 1, Div = -1 };
551 Op currentOp = Op::Mul;
552 std::string token;
553 size_t i = 0;
554 auto parse_unit = [&](const std::string& t, Op op) {
555 if (t.empty()) return;
556
557 size_t caret = t.find('^');
558 std::string base = t;
559 int exp = 1;
560
561 if (caret != std::string::npos) {
562 base = t.substr(0, caret);
563 std::string exp_str = t.substr(caret + 1);
564 try {
565 exp = std::stoi(exp_str);
566 } catch (...) {
567 throw std::runtime_error("Invalid exponent: " + exp_str);
568 }
569 }
570 int signed_exp = (op == Op::Mul ? +1 : -1) * exp;
571 result[base] += signed_exp;
572 };
573
574 while (i < input.size()) {
575 char c = input[i];
576
577 if (c == '*')
578 {
579 parse_unit(token, currentOp);
580 token.clear();
581 currentOp = Op::Mul;
582 ++i;
583 }
584 else if (c == '/')
585 {
586 parse_unit(token, currentOp);
587 token.clear();
588 currentOp = Op::Div;
589 ++i;
590 }
591 else
592 {
593 token += c;
594 ++i;
595 }
596 }
597
598 // Parse final token
599 parse_unit(token, currentOp);
600
601 return result;
602}
603
604
605
606
607
608
609
610
611
612
613#endif
std::time_t t
#define TEST(x)
Definition Util.H:22
#define INFO
Definition Util.H:21
AMREX_FORCE_INLINE void Assert(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
Definition Util.H:55
Definition Unit.H:21
Unit operator^(const int &rhs)
Definition Unit.H:483
static Unit Resistance()
Definition Unit.H:234
static void setTimeUnit(std::string unit)
Definition Unit.H:377
bool isType(const Unit &test) const
Definition Unit.H:425
static Unit Inductance()
Definition Unit.H:239
static Unit Area()
Definition Unit.H:209
static Unit Voltage()
Definition Unit.H:233
Unit(const std::pair< double, std::array< int, 7 > > &p)
Definition Unit.H:266
static Unit Impulse()
Definition Unit.H:216
friend Unit operator*(double lhs, const Unit &rhs)
Definition Unit.H:437
Unit operator-(const Unit &rhs)
Definition Unit.H:475
static Unit Energy()
Definition Unit.H:218
static Unit Conductance()
Definition Unit.H:236
static Unit MolarMass()
Definition Unit.H:241
static Unit Amount()
Definition Unit.H:203
static Unit HeatTransferCoefficient()
Definition Unit.H:229
friend std::ostream & operator<<(std::ostream &out, const Unit &a)
Definition Unit.H:494
static std::array< std::pair< std::string, double >, 7 > normalization
Definition Unit.H:255
static Unit Density()
Definition Unit.H:220
std::string normalized_unitstring() const
Definition Unit.H:510
static const std::map< std::string, std::pair< double, std::string > > compound
Definition Unit.H:47
static Unit ThermalDiffusivity()
Definition Unit.H:227
static std::map< std::string, int > ParseUnitString(const std::string &input)
Definition Unit.H:548
static Unit Parse(double val, std::string unitstring, bool verbose=false)
Definition Unit.H:270
static Unit Time()
Definition Unit.H:199
double normalized_value() const
Definition Unit.H:501
static Unit Force()
Definition Unit.H:214
static Unit ThermalConductivity()
Definition Unit.H:226
Unit operator+(const Unit &rhs)
Definition Unit.H:467
static Unit Mass()
Definition Unit.H:200
static void setLuminousIntensityUnit(std::string unit)
Definition Unit.H:417
static Unit Temperature()
Definition Unit.H:201
static Unit Volume()
Definition Unit.H:210
static void setLengthUnit(std::string unit)
Definition Unit.H:369
static Unit Charge()
Definition Unit.H:232
static Unit Pressure()
Definition Unit.H:217
static Unit HeatFlux()
Definition Unit.H:228
static void setMassUnit(std::string unit)
Definition Unit.H:385
static Unit Current()
Definition Unit.H:202
static Unit Angle()
Definition Unit.H:206
static Unit Illuminance()
Definition Unit.H:246
friend Unit operator/(double lhs, const Unit &rhs)
Definition Unit.H:456
static Unit LuminousFlux()
Definition Unit.H:245
static Unit Capacitance()
Definition Unit.H:235
static Unit Work()
Definition Unit.H:222
static Unit Power()
Definition Unit.H:219
static Unit Velocity()
Definition Unit.H:211
static Unit Momentum()
Definition Unit.H:215
static void setTemperatureUnit(std::string unit)
Definition Unit.H:393
static Unit LuminousIntensity()
Definition Unit.H:204
static void setCurrentUnit(std::string unit)
Definition Unit.H:401
static Unit Acceleration()
Definition Unit.H:212
static const std::map< std::string, std::pair< double, std::array< int, 7 > > > base_units
Definition Unit.H:30
friend Unit operator*(const Unit &lhs, double rhs)
Definition Unit.H:443
static void setAmountUnit(std::string unit)
Definition Unit.H:409
static Unit MolarEnergy()
Definition Unit.H:243
static Unit Length()
Definition Unit.H:198
static Unit Concentration()
Definition Unit.H:242
static Unit Parse(std::string unit, bool verbose=false)
Definition Unit.H:276
static Unit MolarHeatCapacity()
Definition Unit.H:225
static Unit SpecificWeight()
Definition Unit.H:221
static Unit SpecificHeatCapacity()
Definition Unit.H:224
static Unit MagneticFlux()
Definition Unit.H:237
static Unit StringParse(std::string unitstring, bool verbose=false)
Definition Unit.H:322
static Unit Less()
Definition Unit.H:197
static Unit MagneticField()
Definition Unit.H:238
Type
Definition Unit.H:26