Files
LBPM/common/Units.h
2020-10-12 06:08:29 -04:00

157 lines
3.9 KiB
C++

/*
Copyright 2013--2018 James E. McClure, Virginia Polytechnic & State University
Copyright Equnior ASA
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef included_Units
#define included_Units
#include <array>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <vector>
//! Unit system class
class Units final
{
public:
//! Enum to hold prefix
enum class UnitPrefix : int8_t {
yocto = 0,
zepto = 1,
atto = 2,
femto = 3,
pico = 4,
nano = 5,
micro = 6,
milli = 7,
centi = 8,
deci = 9,
none = 10,
deca = 11,
hecto = 12,
kilo = 13,
mega = 14,
giga = 15,
tera = 16,
peta = 17,
exa = 18,
zetta = 19,
yotta = 20,
unknown = 21
};
//! Enum to unit type
enum class UnitType : uint8_t {
length,
mass,
time,
current,
temperature,
energy,
angle,
unknown
};
//! Enum to hold unit
enum class UnitValue : uint8_t {
meter,
gram,
second,
ampere,
kelvin,
joule,
erg,
degree,
radian,
unknown
};
public:
//! Constructor
Units();
//! Constructor
explicit Units( const std::string& unit );
//! Constructor
explicit Units( UnitPrefix, UnitValue );
//! Get the prefix
inline UnitPrefix getPrefix() const noexcept { return d_prefix; }
//! Get the unit
inline UnitValue getUnit() const noexcept { return d_unit; }
//! Get the unit
inline UnitType getUnitType() const noexcept { return getUnitType( d_unit ); }
//! Get the unit
static UnitType getUnitType( UnitValue ) noexcept;
//! Get the prefix from a string
static UnitPrefix getUnitPrefix( const std::string& ) noexcept;
//! Get the unit value from a string
static UnitValue getUnitValue( const std::string& ) noexcept;
//! Convert to the given unit system
double convert( const Units& ) const noexcept;
//! Convert a prefix to a scalar
static inline double convert( UnitPrefix x ) noexcept
{
return d_pow10[static_cast<int8_t>( x )];
}
//! Get a string representation of the units
std::string str() const;
//! Get a string representation for the prefix
static std::array<char, 3> str( UnitPrefix ) noexcept;
//! Get a string representation for the unit value
static std::string str( UnitValue );
//! Operator ==
inline bool operator==( const Units& rhs ) const noexcept
{
return d_prefix == rhs.d_prefix && d_unit == rhs.d_unit;
}
//! Operator !=
inline bool operator!=( const Units& rhs ) const noexcept
{
return d_prefix != rhs.d_prefix || d_unit != rhs.d_unit;
}
//! Check if unit is null
bool isNull() const { return d_prefix == UnitPrefix::unknown || d_unit == UnitValue::unknown; }
protected:
UnitPrefix d_prefix;
UnitValue d_unit;
private:
constexpr static double d_pow10[22] = { 1e-24, 1e-21, 1e-18, 1e-15, 1e-12, 1e-9, 1e-6, 1e-3,
1e-2, 0.1, 1, 10, 100, 1000, 1e6, 1e9, 1e12, 1e15, 1e18, 1e21, 1e24, 0 };
constexpr static char d_prefixSymbol[] = "yzafpnumcd\0dhkMGTPEZYu";
};
#endif