Cantera  3.1.0a1
Units.h
Go to the documentation of this file.
1 /**
2  * @file Units.h
3  * Header for unit conversion utilities, which are used to translate
4  * user input from input files (See @ref inputGroup and
5  * class @link Cantera::Units Units@endlink).
6  */
7 
8 // This file is part of Cantera. See License.txt in the top-level directory or
9 // at https://cantera.org/license.txt for license and copyright information.
10 
11 #ifndef CT_UNITS_H
12 #define CT_UNITS_H
13 
14 #include "cantera/base/ct_defs.h"
15 
16 namespace Cantera
17 {
18 
19 class AnyValue;
20 class AnyMap;
21 
22 //! @defgroup unitsGroup Unit Conversion
23 //! Unit conversion utilities.
24 //! @ingroup ioGroup
25 
26 //! A representation of the units associated with a dimensional quantity.
27 /*!
28  * Used for converting quantities between unit systems and checking for
29  * dimensional consistency. Units objects are mainly used within UnitSystem
30  * class to convert values from a user-specified Unit system to %Cantera's
31  * base units (SI + kmol).
32  * @ingroup unitsGroup
33  */
34 class Units
35 {
36 public:
37  //! Create a Units object with the specified dimensions.
38  explicit Units(double factor=1.0, double mass=0, double length=0,
39  double time=0, double temperature=0, double current=0,
40  double quantity=0);
41 
42  //! Create an object with the specified dimensions
43  //! @param units A string representation of the units. See UnitSystem
44  //! for a description of the formatting options.
45  //! @param force_unity ensure that conversion factor is equal to one
46  explicit Units(const string& units, bool force_unity=false);
47 
48  //! Returns `true` if the specified Units are dimensionally consistent
49  bool convertible(const Units& other) const;
50 
51  //! Return the factor for converting from this unit to Cantera's base
52  //! units.
53  double factor() const { return m_factor; }
54 
55  //! Multiply two Units objects, combining their conversion factors and
56  //! dimensions
57  Units& operator*=(const Units& other);
58 
59  //! Provide a string representation of these Units
60  //! @param skip_unity do not print '1' if conversion factor is equal to one
61  string str(bool skip_unity=true) const;
62 
63  //! Raise these Units to a power, changing both the conversion factor and
64  //! the dimensions of these Units.
65  Units pow(double exponent) const;
66 
67  bool operator==(const Units& other) const;
68 
69  //! Return dimension of primary unit component
70  //! ("mass", "length", "time", "temperature", "current", or "quantity")
71  double dimension(const string& primary) const;
72 
73 private:
74  //! Scale the unit by the factor `k`
75  void scale(double k) { m_factor *= k; }
76 
77  double m_factor = 1.0; //!< conversion factor to %Cantera base units
78  double m_mass_dim = 0.0;
79  double m_length_dim = 0.0;
80  double m_time_dim = 0.0;
81  double m_temperature_dim = 0.0;
82  double m_current_dim = 0.0;
83  double m_quantity_dim = 0.0;
84  double m_pressure_dim = 0.0; //!< pseudo-dimension to track explicit pressure units
85  double m_energy_dim = 0.0; //!< pseudo-dimension to track explicit energy units
86 
87  friend class UnitSystem;
88 };
89 
90 
91 //! Unit aggregation utility
92 /*!
93  * Provides functions for updating and calculating effective units from a stack
94  * of unit-exponent pairs. Matching units are aggregated, where a standard unit
95  * simplifies access when joining exponents. The utility is used in the context
96  * of effective reaction rate units.
97  *
98  * @note Helper utility class for internal use within Cantera.
99  *
100  * @warning This class is an experimental part of the %Cantera API and
101  * may be changed or removed without notice.
102  * @ingroup unitsGroup
103  */
104 struct UnitStack
105 {
106  UnitStack(const Units& standardUnits) {
107  stack.reserve(2); // covers memory requirements for most applications
108  stack.emplace_back(standardUnits, 0.);
109  }
110 
111  //! Alternative constructor allows for direct assignment of vector
112  UnitStack(std::initializer_list<pair<Units, double>> units)
113  : stack(units) {}
114 
115  UnitStack() = default;
116 
117  //! Size of UnitStack
118  size_t size() const { return stack.size(); }
119 
120  //! Get standard unit used by UnitStack
121  Units standardUnits() const;
122 
123  //! Set standard units
125 
126  //! Effective exponent of standard unit
127  double standardExponent() const;
128 
129  //! Join (update) exponent of standard units, where the updated exponent is
130  //! the sum of the pre-existing exponent and the exponent passed as the argument.
131  void join(double exponent);
132 
133  //! Update exponent of item with matching units; if it does not exist,
134  //! add unit-exponent pair at end of stack
135  void update(const Units& units, double exponent);
136 
137  //! Calculate product of units-exponent stack
138  Units product() const;
139 
140  vector<pair<Units, double>> stack; //!< Stack uses vector of pairs
141 };
142 
143 
144 //! Unit conversion utility
145 /*!
146  * Provides functions for converting dimensional values from a given unit system.
147  * The main use is for converting values specified in input files to Cantera's
148  * native unit system, which is SI units except for the use of kmol as the base
149  * unit of quantity, that is, kilogram, meter, second, kelvin, ampere, and kmol.
150  *
151  * String representations of units can be written using multiplication,
152  * division, and exponentiation. Spaces are ignored. Positive, negative, and
153  * decimal exponents are permitted. Examples:
154  *
155  * kg*m/s^2
156  * J/kmol
157  * m*s^-2
158  * J/kg/K
159  *
160  * Metric prefixes are recognized for all units, such as nm, hPa, mg, EJ, mL, kcal.
161  *
162  * Special functions for converting activation energies allow these values to be
163  * expressed as either energy per quantity, energy (for example, eV), or temperature by
164  * applying a factor of the Avogadro number or the gas constant where needed.
165  *
166  * @ingroup unitsGroup
167  */
169 {
170 public:
171  //! Create a unit system with the specified default units
172  UnitSystem(std::initializer_list<string> units);
173 
174  //! Default constructor for unit system (needed as VS2019 does not
175  //! recognize an optional argument with a default value)
177 
178  //! Return default units used by the unit system
179  map<string, string> defaults() const;
180 
181  //! Set the default units to convert from when explicit units are not
182  //! provided. Defaults can be set for mass, length, time, quantity, energy,
183  //! and pressure. Conversion using the pressure or energy units is done only
184  //! when the target units explicitly contain pressure or energy units.
185  //!
186  //! * To use SI+kmol: `setDefaults({"kg", "m", "s", "Pa", "J", "kmol"});`
187  //! * To use CGS+mol: `setDefaults({"cm", "g", "dyn/cm^2", "erg", "mol"});`
188  void setDefaults(std::initializer_list<string> units);
189 
190  //! Set the default units using a map of dimension to unit pairs.
191  //!
192  //! Defaults for dimensions not specified will be left unchanged. To use
193  //! Cantera's default units:
194  //! ```
195  //! UnitSystem system;
196  //! map<string, string> defaults{
197  //! {"length", "m"}, {"mass", "kg"}, {"time", "s"},
198  //! {"quantity", "kmol"}, {"pressure", "Pa"}, {"energy", "J"},
199  //! {"activation-energy", "J/kmol"}
200  //! };
201  //! setDefaults(defaults);
202  //! ```
203  void setDefaults(const map<string, string>& units);
204 
205  //! Set the default units to convert from when using the
206  //! `convertActivationEnergy` function.
207  void setDefaultActivationEnergy(const string& e_units);
208 
209  //! Convert `value` from the units of `src` to the units of `dest`.
210  double convert(double value, const string& src, const string& dest) const;
211  double convert(double value, const Units& src, const Units& dest) const;
212 
213  //! Convert `value` to the specified `dest` units from the appropriate units
214  //! for this unit system (defined by `setDefaults`)
215  double convertTo(double value, const string& dest) const;
216  double convertTo(double value, const Units& dest) const;
217 
218  //! Convert `value` from the specified `src` units to units appropriate for
219  //! this unit system (defined by `setDefaults`)
220  double convertFrom(double value, const string& src) const;
221  double convertFrom(double value, const Units& src) const;
222 
223  //! Convert a generic AnyValue node to the units specified in `dest`. If the
224  //! input is a double, convert it using the default units. If the input is a
225  //! string, treat this as a dimensioned value, such as '988 kg/m^3' and convert
226  //! from the specified units.
227  double convert(const AnyValue& val, const string& dest) const;
228  double convert(const AnyValue& val, const Units& dest) const;
229 
230  //! Convert a generic AnyValue node representing a reaction rate coefficient to the
231  //! units specified in `dest`. Works like `convert(AnyValue&, Units&)` but with
232  //! special handling for the case where the destination units are undefined.
233  //!
234  //! @since New in %Cantera 3.0
235  double convertRateCoeff(const AnyValue& val, const Units& dest) const;
236 
237  //! Convert an array of AnyValue nodes to the units specified in `dest`. For
238  //! each node, if the value is a double, convert it using the default units,
239  //! and if it is a string, treat it as a value with the given dimensions.
240  vector<double> convert(const vector<AnyValue>& vals, const string& dest) const;
241  vector<double> convert(const vector<AnyValue>& vals, const Units& dest) const;
242 
243  //! Convert `value` from the units of `src` to the units of `dest`, allowing
244  //! for the different dimensions that can be used for activation energies
245  double convertActivationEnergy(double value, const string& src,
246  const string& dest) const;
247 
248  //! Convert `value` to the units specified by `dest` from the default
249  //! activation energy units
250  double convertActivationEnergyTo(double value, const string& dest) const;
251  double convertActivationEnergyTo(double value, const Units& dest) const;
252 
253  //! Convert `value` from the units specified by `src` to the default
254  //! activation energy units
255  double convertActivationEnergyFrom(double value, const string& src) const;
256 
257  //! Convert a generic AnyValue node to the units specified in `dest`. If the
258  //! input is a double, convert it using the default units. If the input is a
259  //! string, treat this as a dimensioned value, such as '2.7e4 J/kmol', and
260  //! convert from the specified units.
261  double convertActivationEnergy(const AnyValue& val, const string& dest) const;
262 
263  //! Get the changes to the defaults from `other` to this UnitSystem
264  AnyMap getDelta(const UnitSystem& other) const;
265 
266 private:
267  //! Factor to convert mass from this unit system to kg
268  double m_mass_factor = 1.0;
269 
270  //! Factor to convert length from this unit system to meters
271  double m_length_factor = 1.0;
272 
273  //! Factor to convert time from this unit system to seconds
274  double m_time_factor = 1.0;
275 
276  //! Factor to convert pressure from this unit system to Pa
277  double m_pressure_factor = 1.0;
278 
279  //! Factor to convert energy from this unit system to J
280  double m_energy_factor = 1.0;
281 
282  //! Factor to convert activation energy from this unit system to J/kmol
284 
285  //! Factor to convert quantity from this unit system to kmol
286  double m_quantity_factor = 1.0;
287 
288  //! True if activation energy units are set explicitly, rather than as a
289  //! combination of energy and quantity units
291 
292  //! Map of dimensions (mass, length, etc.) to names of specified default
293  //! units
294  map<string, string> m_defaults;
295 };
296 
297 }
298 
299 #endif
Unit conversion utility.
Definition: Units.h:169
double m_activation_energy_factor
Factor to convert activation energy from this unit system to J/kmol.
Definition: Units.h:283
bool m_explicit_activation_energy
True if activation energy units are set explicitly, rather than as a combination of energy and quanti...
Definition: Units.h:290
double convertFrom(double value, const string &src) const
Convert value from the specified src units to units appropriate for this unit system (defined by setD...
Definition: Units.cpp:570
double convertActivationEnergyTo(double value, const string &dest) const
Convert value to the units specified by dest from the default activation energy units.
Definition: Units.cpp:705
double m_time_factor
Factor to convert time from this unit system to seconds.
Definition: Units.h:274
double convertTo(double value, const string &dest) const
Convert value to the specified dest units from the appropriate units for this unit system (defined by...
Definition: Units.cpp:554
double m_pressure_factor
Factor to convert pressure from this unit system to Pa.
Definition: Units.h:277
UnitSystem()
Default constructor for unit system (needed as VS2019 does not recognize an optional argument with a ...
Definition: Units.h:176
double m_energy_factor
Factor to convert energy from this unit system to J.
Definition: Units.h:280
double convertRateCoeff(const AnyValue &val, const Units &dest) const
Convert a generic AnyValue node representing a reaction rate coefficient to the units specified in de...
Definition: Units.cpp:631
double m_length_factor
Factor to convert length from this unit system to meters.
Definition: Units.h:271
double convertActivationEnergyFrom(double value, const string &src) const
Convert value from the units specified by src to the default activation energy units.
Definition: Units.cpp:725
map< string, string > m_defaults
Map of dimensions (mass, length, etc.) to names of specified default units.
Definition: Units.h:294
double convertActivationEnergy(double value, const string &src, const string &dest) const
Convert value from the units of src to the units of dest, allowing for the different dimensions that ...
Definition: Units.cpp:673
void setDefaults(std::initializer_list< string > units)
Set the default units to convert from when explicit units are not provided.
Definition: Units.cpp:428
double m_mass_factor
Factor to convert mass from this unit system to kg.
Definition: Units.h:268
double convert(double value, const string &src, const string &dest) const
Convert value from the units of src to the units of dest.
Definition: Units.cpp:538
double m_quantity_factor
Factor to convert quantity from this unit system to kmol.
Definition: Units.h:286
AnyMap getDelta(const UnitSystem &other) const
Get the changes to the defaults from other to this UnitSystem.
Definition: Units.cpp:757
map< string, string > defaults() const
Return default units used by the unit system.
Definition: Units.cpp:398
void setDefaultActivationEnergy(const string &e_units)
Set the default units to convert from when using the convertActivationEnergy function.
Definition: Units.cpp:521
A representation of the units associated with a dimensional quantity.
Definition: Units.h:35
double m_energy_dim
pseudo-dimension to track explicit energy units
Definition: Units.h:85
double m_pressure_dim
pseudo-dimension to track explicit pressure units
Definition: Units.h:84
void scale(double k)
Scale the unit by the factor k
Definition: Units.h:75
double m_factor
conversion factor to Cantera base units
Definition: Units.h:77
Units pow(double exponent) const
Raise these Units to a power, changing both the conversion factor and the dimensions of these Units.
Definition: Units.cpp:223
Units & operator*=(const Units &other)
Multiply two Units objects, combining their conversion factors and dimensions.
Definition: Units.cpp:209
string str(bool skip_unity=true) const
Provide a string representation of these Units.
Definition: Units.cpp:234
double dimension(const string &primary) const
Return dimension of primary unit component ("mass", "length", "time", "temperature",...
Definition: Units.cpp:303
bool convertible(const Units &other) const
Returns true if the specified Units are dimensionally consistent.
Definition: Units.cpp:199
double factor() const
Return the factor for converting from this unit to Cantera's base units.
Definition: Units.h:53
Units(double factor=1.0, double mass=0, double length=0, double time=0, double temperature=0, double current=0, double quantity=0)
Create a Units object with the specified dimensions.
Definition: Units.cpp:109
This file contains definitions of constants, types and terms that are used in internal routines and a...
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:564
Unit aggregation utility.
Definition: Units.h:105
double standardExponent() const
Effective exponent of standard unit.
Definition: Units.cpp:344
size_t size() const
Size of UnitStack.
Definition: Units.h:118
void update(const Units &units, double exponent)
Update exponent of item with matching units; if it does not exist, add unit-exponent pair at end of s...
Definition: Units.cpp:362
UnitStack(std::initializer_list< pair< Units, double >> units)
Alternative constructor allows for direct assignment of vector.
Definition: Units.h:112
Units standardUnits() const
Get standard unit used by UnitStack.
Definition: Units.cpp:323
Units product() const
Calculate product of units-exponent stack.
Definition: Units.cpp:377
void join(double exponent)
Join (update) exponent of standard units, where the updated exponent is the sum of the pre-existing e...
Definition: Units.cpp:352
vector< pair< Units, double > > stack
Stack uses vector of pairs.
Definition: Units.h:140
void setStandardUnits(Units &standardUnits)
Set standard units.
Definition: Units.cpp:331