Newer
Older
#ifndef _include_QUANTITYVECTOR_H_
#define _include_QUANTITYVECTOR_H_
#include <Units/PhysicalUnits.h>
#include <Eigen/Dense>
#include <iostream>
#include <utility>
template <typename dim>
class QuantityVector
{
protected:
using Quantity = phys::units::quantity<dim, double>;
//using QuantitySquared = decltype(std::declval<Quantity>() * std::declval<Quantity>());
public:
Eigen::Vector3d eVector;
typedef dim dimension;
QuantityVector(Quantity a, Quantity b, Quantity c) :
eVector{a.magnitude(), b.magnitude(), c.magnitude()}
{
}
QuantityVector(Eigen::Vector3d pBareVector) :
eVector(pBareVector)
{
}
auto operator[](size_t index) const
{
return Quantity(phys::units::detail::magnitude_tag, eVector[index]);
}
{
return Quantity(phys::units::detail::magnitude_tag, eVector.norm());
}
using QuantitySquared = decltype(std::declval<Quantity>() * std::declval<Quantity>());
return QuantitySquared(phys::units::detail::magnitude_tag, eVector.squaredNorm());
}
auto operator+(QuantityVector<dim> const& pQVec) const
{
return QuantityVector<dim>(eVector + pQVec.eVector);
}
auto operator-(QuantityVector<dim> const& pQVec) const
{
return QuantityVector<dim>(eVector - pQVec.eVector);
}
template <typename ScalarDim>
auto operator*(phys::units::quantity<ScalarDim, double> const p) const
{
Maximilian Reininghaus
committed
using ResQuantity = phys::units::detail::Product<ScalarDim, dim, double, double>;
if constexpr (std::is_same<ResQuantity, double>::value) // result dimensionless, not a "Quantity" anymore
{
return QuantityVector<phys::units::dimensionless_d>(eVector * p.magnitude());
}
else
{
return QuantityVector<typename ResQuantity::dimension_type>(eVector * p.magnitude());
}
template <typename ScalarDim>
auto operator/(phys::units::quantity<ScalarDim, double> const p) const
{
return (*this) * (1 / p);
}
auto operator*(double const p) const
{
return QuantityVector<dim>(eVector * p);
}
auto operator/(double const p) const
{
return QuantityVector<dim>(eVector / p);
}
auto& operator/=(double const p)
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
auto& operator*=(double const p)
{
eVector *= p;
return *this;
}
auto& operator+=(QuantityVector<dim> const& pQVec)
{
eVector += pQVec.eVector;
return *this;
}
auto& operator-=(QuantityVector<dim> const& pQVec)
{
eVector -= pQVec.eVector;
return *this;
}
auto& operator-() const
{
return QuantityVector<dim>(-eVector);
}
auto normalized() const
{
return (*this) * (1 / norm());
}
};
template <typename dim>
auto& operator<<(std::ostream& os, QuantityVector<dim> qv)
{
using Quantity = phys::units::quantity<dim, double>;
os << '(' << qv.eVector(0) << ' ' << qv.eVector(1) << ' ' << qv.eVector(2)
<< ") " << phys::units::to_unit_symbol<dim, double>(Quantity(phys::units::detail::magnitude_tag, 1));
return os;
}
#endif