Page MenuHomec4science

quantity.hh
No OneTemporary

File Metadata

Created
Tue, Jul 16, 13:32

quantity.hh

/**
* @file quantity.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Mon Nov 25 12:23:57 2013
*
* @brief This is a templated wrapper over float/doubles enabling units
* conversions
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* LibMultiScale is free software: you can redistribute it and/or modify it
* under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* LibMultiScale 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMultiScale. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __LIBMULTISCALE_QUANTITY_HH__
#define __LIBMULTISCALE_QUANTITY_HH__
/* -------------------------------------------------------------------------- */
#include "lm_common.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
/* -------------------------------------------------------------------------- */
template <PhysicalQuantity q, typename T = Real> struct PhysicalScalar {
PhysicalScalar(T v) : val(v) {}
PhysicalScalar(){};
operator T &() { return val; }
operator const T &() const { return val; }
template <typename T2> bool operator<(const T2 &other) const {
return val < other;
}
template <typename T2> bool operator<=(const T2 &other) const {
return val <= other;
}
template <typename T2> bool operator>(const T2 &other) const {
return val > other;
}
template <typename T2> bool operator>=(const T2 &other) const {
return val >= other;
}
T val;
};
using PhysicalLength = PhysicalScalar<Length>;
/* -------------------------------------------------------------------------- */
template <PhysicalQuantity q, typename T = Real>
bool operator<(const T &a, const PhysicalScalar<q, T> &b) {
return a < Real(b);
}
template <PhysicalQuantity q, typename T = Real>
bool operator<=(const T &a, const PhysicalScalar<q, T> &b) {
return a <= Real(b);
}
template <PhysicalQuantity q, typename T = Real>
bool operator>(const T &a, const PhysicalScalar<q, T> &b) {
return a > Real(b);
}
template <PhysicalQuantity q, typename T = Real>
bool operator>=(const T &a, const PhysicalScalar<q, T> &b) {
return a >= Real(b);
}
template <PhysicalQuantity q, typename T = Real>
inline std::ostream &operator<<(std::ostream &os, PhysicalScalar<q, T> a) {
os << a.val;
switch (q) {
case Length:
os << " [Length]";
break;
case Mass:
os << " [Mass]";
break;
case Energy:
os << " [Energy]";
break;
case Time:
os << " [Time]";
break;
case MassDensity:
os << " [MassDensity]";
break;
case Force:
os << " [Force]";
break;
case Pressure:
os << " [Pressure]";
break;
case Temperature:
os << " [Temperature]";
break;
default:
LM_FATAL("unknown physical quantity " << q);
}
return os;
}
/* -------------------------------------------------------------------------- */
template <PhysicalQuantity q, UInt Dim = 1, typename T = Real>
struct Quantity : public Vector<Dim, PhysicalScalar<q, T>> {
using Vector<Dim, PhysicalScalar<q, T>>::Vector;
using Vector<Dim, PhysicalScalar<q, T>>::operator=;
Quantity &operator=(Vector<Dim, T> &v) {
for (UInt i = 0; i < Dim; ++i)
(*this)[i] = v[i];
return *this;
}
Quantity &operator=(const T &v) {
for (UInt i = 0; i < Dim; ++i)
(*this)[i] = v;
return *this;
}
template <UInt other_Dim> operator Quantity<q, other_Dim, T>() {
LM_TOIMPLEMENT;
};
operator T() { return (*this)[0]; }
};
/* -------------------------------------------------------------------------- */
template <PhysicalQuantity q, typename T>
struct Quantity<q, 1, T> : PhysicalScalar<q, T> {
using PhysicalScalar<q, T>::PhysicalScalar;
Quantity &operator=(Vector<1, T> &v) {
(*this)[0] = v[0];
return (*this);
};
const T &operator[](UInt i) const { return *this; };
T &operator[](UInt i) { return *this; };
template <UInt other_Dim> operator Quantity<q, other_Dim, T> &() {
LM_TOIMPLEMENT;
};
};
/* -------------------------------------------------------------------------- */
__END_LIBMULTISCALE__
#endif /* __LIBMULTISCALE_QUANTITY_HH__ */

Event Timeline