Flow123d  JS_before_hm-1602-g5680f2c
unit_converter.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file unit_converter.hh
15  * @brief
16  */
17 
18 #ifndef UNIT_CONVERTER_HH_
19 #define UNIT_CONVERTER_HH_
20 
21 
22 #include <map> // for map, map<>::value_compare
23 #include <string> // for string
24 #include <vector> // for vector
25 
26 #include "tools/unit_si.hh" // for UnitSI
27 #include "input/input_exception.hh" // for DECLARE_INPUT_EXCEPTION, Exception
28 #include "system/asserts.hh" // for Assert, ASSERT
29 #include "system/exceptions.hh" // for operator<<, ExcStream, EI, TYPED...
30 
31 namespace Input {
32  namespace Type {
33  class Record;
34  }
35 }
36 
37 // Declaration of exceptions
38 TYPEDEF_ERR_INFO(EI_UnitDefinition, std::string);
39 TYPEDEF_ERR_INFO(EI_ExpectedUnit, std::string);
40 TYPEDEF_ERR_INFO(EI_UnitError, std::string);
41 DECLARE_INPUT_EXCEPTION(ExcInvalidUnit,
42  << "Invalid definition of unit: " << EI_UnitDefinition::qval << "\n" << EI_UnitError::val << ".\n");
43 DECLARE_INPUT_EXCEPTION(ExcNoncorrespondingUnit,
44  << "Non-corresponding definition of unit: " << EI_UnitDefinition::qval << "\nExpected: unit with base format "
45  << EI_ExpectedUnit::qval << ".\n");
46 
47 
48 /// Store structure given by parser
49 struct Factor {
50  /// Constructor
51  Factor() : exponent_(1), basic_(true) {}
52  Factor(std::string factor, int exponent, bool basic = true) : factor_(factor), exponent_(exponent), basic_(basic) {}
53 
54  std::string factor_; //!< string represantation of unit or user defined constant
55  int exponent_; //!< exponent
56  bool basic_; //!< unit is basic (strict defined in application) / derived (defined by user as formula)
57 };
58 struct Formula {
59  /// Constructor
60  Formula() : coef_(1.0) {}
61 
62  double coef_; //!< multiplicative coeficient
63  std::vector<struct Factor> factors_; //!< factors of formula
64 };
66 
67 
68 
69 /**
70  * @brief Helper class. Defines basic factors of SI, non-SI and derived units.
71  *
72  * Class is instantiated as static object of UnitConverter class and provides check
73  * of user defined units.
74  */
75 class BasicFactors {
76 public:
77  struct DerivedUnit {
78  double coef_; //!< multiplicative coeficient
79  UnitSI unit_; //!< derived SI unit
80  };
81 
83 
84  /// Define all base and derived units given by their symbol.
85  UnitsMap units_map_;
86 
87  /// Constructor
88  BasicFactors();
89 
90 };
91 
92 
94 public:
95  /// Define all base and derived units given by their symbol.
97 
98  /// Constructor
99  UnitConverter();
100 
101  static const Input::Type::Record & get_input_type();
102 
103  /* Compute a multiplicative constant to convert from 'actual_unit' to the SI unit.
104  *
105  * The 'actual_unit' string convains a unit expression the is parsed and converted to the 'coef_' and 'unit_si_' so that
106  * 'actual unit' == coef_ * unit_si_
107  *
108  * The coefficient coef_ is returned.
109  *
110  * TODO: pass the actual_unit to the constructor so that we avoid object modifications.
111  */
112  double convert(std::string actual_unit);
113 
114  /// Return @p unit_si_
115  inline UnitSI unit_si() const {
116  ASSERT(unit_si_.is_def()).error("UnitSI is not defined, first call convert method.");
117  return unit_si_;
118  }
119 
120 protected:
121  /**
122  * @brief Parse and check unit defined in string format.
123  *
124  * Return data in format \p UnitData
125  */
126  UnitData read_unit(std::string s);
127 
128  /// Calculates UnitSi and coeficient of Factor, recursively calls this method for user defined formula
129  void add_converted_unit(Factor factor, UnitData &unit_data, UnitSI &unit_si, double &coef);
130 
131  /**
132  * Coeficient of unit.
133  *
134  * Coeficient is used if unit is not in basic format. Example: if the unit is specified
135  * in minutes, coeficient has value 60.
136  */
137  double coef_;
138 
139  /**
140  * Basic format of converted SI unit
141  */
143 
144 };
145 
146 
147 #endif /* UNIT_CONVERTER_HH_ */
UnitSI unit_
derived SI unit
Helper class. Defines basic factors of SI, non-SI and derived units.
UnitsMap units_map_
Define all base and derived units given by their symbol.
bool basic_
unit is basic (strict defined in application) / derived (defined by user as formula) ...
TYPEDEF_ERR_INFO(EI_KeyName, const string)
Abstract linear system class.
Definition: balance.hh:40
Definitions of ASSERTS.
std::vector< struct Factor > factors_
factors of formula
UnitSI unit_si() const
Return unit_si_.
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
std::map< std::string, struct DerivedUnit > UnitsMap
Yes & convert(fmt::ULongLong)
Formula()
Constructor.
Factor(std::string factor, int exponent, bool basic=true)
int exponent_
exponent
std::string factor_
string represantation of unit or user defined constant
Store structure given by parser.
Record type proxy class.
Definition: type_record.hh:182
std::map< std::string, struct Formula > UnitData
Class for representation SI units of Fields.
Definition: unit_si.hh:40
DECLARE_INPUT_EXCEPTION(ExcInputMessage,<< EI_Message::val)
Simple input exception that accepts just string message.
Factor()
Constructor.
static const BasicFactors basic_factors
Define all base and derived units given by their symbol.
double coef_
multiplicative coeficient
double coef_
multiplicative coeficient