Page MenuHomec4science

quantity.hh
No OneTemporary

File Metadata

Created
Sun, Feb 9, 19:07

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__
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
template <PhysicalQuantity q, UInt nb=1, typename T = Real>
class Quantity {
public:
Quantity(){
for (UInt i = 0; i < nb; ++i)
this->value[i] = T(0.0);
}
Quantity(T value){
for (UInt i = 0; i < nb; ++i)
this->value[i] = value;
}
template <UInt n>
Quantity(const Quantity<q,n,T> & _q){
for (UInt i = 0; i < nb; ++i)
this->value[i] = _q[i];
}
template <typename T1>
T & operator = (T1 v) {
for (UInt i = 0; i < nb; ++i)
value[i] = v;
return (*this);
}
T operator * (T v) {
Quantity<q,nb,T> res;
for (UInt i = 0; i < nb; ++i)
res.value[i] = value[i] * v;
return res;
}
T & operator [](UInt i) {
return value[i];
}
const T & operator [](UInt i) const {
if (i >= nb)
LM_FATAL("internal error");
return value[i];
}
// operator const T * () const {
// return value;
// }
const T * getValues() const {
return value;
}
// template <PhysicalQuantity q2>
// T operator / (Quantity<q2,1,T> v) {
// if (nb > 1)
// LM_FATAL("this quantity is a vector: "
// << "cannot implicitely cast to scalar");
// return value[0]/v[0];
// }
T operator / (T v) {
Quantity<q,nb,T> res;
for (UInt i = 0; i < nb; ++i)
res.value[i] = value[i]/v;
return res;
}
operator T &() {
if (nb > 1)
LM_FATAL("this quantity is a vector: "
<< "cannot implicitely cast to scalar");
return value[0];
}
template <typename T1, PhysicalQuantity q1, UInt nb2, typename T2>
friend T1 operator/(T1 & a, Quantity<q1,nb2, T2> & b);
private:
T value[nb];
};
/* -------------------------------------------------------------------------- */
template <PhysicalQuantity q1, PhysicalQuantity q2, typename T>
inline T operator *(Quantity<q1,1, T> & a, Quantity<q2,1, T> & b){
return b[0]*a[0];
}
template <typename T1, PhysicalQuantity q, typename T>
inline T1 operator *(T1 & a, Quantity<q,1, T> & b){
return b*a;
}
template <typename T1, PhysicalQuantity q, typename T>
inline T1 operator /(T1 & a, Quantity<q,1,T> & b){
return a/b[0];
}
inline std::ostream& operator << (std::ostream& os, PhysicalQuantity q){
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 nb, typename T>
inline std::ostream& operator << (std::ostream& os, const Quantity<q,nb,T> &value){
for (UInt i = 0; i < nb; ++i) {
const T tmp = value[i];
os << tmp << " ";
}
os << q;
return os;
}
/* -------------------------------------------------------------------------- */
__END_LIBMULTISCALE__
#endif /* __LIBMULTISCALE_QUANTITY_HH__ */

Event Timeline