thepeg is hosted by Hepforge, IPPP Durham
ThePEG 2.3.0
PhysicalQty.h
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// PhysicalQty.h is a part of ThePEG - Toolkit for HEP Event Generation
4// Copyright (C) 2006-2019 David Grellscheid, Leif Lonnblad
5//
6// ThePEG is licenced under version 3 of the GPL, see COPYING for details.
7// Please respect the MCnet academic guidelines, see GUIDELINES for details.
8//
9#ifndef Physical_Qty_H
10#define Physical_Qty_H
11#include "TemplateTools.h"
12#include <sstream>
13#include <ratio>
14#include <type_traits>
15
26namespace ThePEG {
27
29struct ZeroUnit {
31 constexpr operator double() const { return 0.0; }
32};
33
35constexpr ZeroUnit ZERO = ZeroUnit();
36
50// only specialization is with std::ratio below
51template <typename L, typename E, typename T>
52class Qty;
53
54template <typename T, typename U>
55struct qty_equal {
56 static constexpr bool value = false;
57};
58
59template<typename L1, typename L2, typename E1, typename E2, typename Q1, typename Q2>
60struct qty_equal<Qty<L1,E1,Q1>, Qty<L2,E2,Q2>> {
61 static constexpr bool value
62 = std::ratio_equal<L1,L2>::value
63 && std::ratio_equal<E1,E2>::value
64 && std::ratio_equal<Q1,Q2>::value;
65};
66
67template <typename T>
68struct is_qty {
69 static constexpr bool value = qty_equal<T,T>::value;
70};
71
72template <typename ResultT, typename T, typename U = T>
73using enable_if_same_qty = typename std::enable_if<qty_equal<T,U>::value, ResultT>::type;
74
75template<long int L, long int E, long int Q, long int DL, long int DE, long int DQ>
76class Qty<std::ratio<L,DL>, std::ratio<E,DE>, std::ratio<Q,DQ>>
77{
78private:
80 constexpr Qty(double val) : rawValue_(val) {}
81
82public:
83
85 static std::string className() {
86 std::ostringstream os;
87 os << "Qty<"
88 << L << ','
89 << E << ','
90 << Q << ','
91 << DL << ','
92 << DE << ','
93 << DQ << '>';
94
95 return os.str();
96 }
97
99 template <long int Num, long int Den>
101 typename std::ratio<Num*E,Den*DE>::type,
102 typename std::ratio<Num*Q,Den*DQ>::type>;
108 using Inverse = Power<-1,1>;
111
113 static constexpr Type baseunit()
114 {
115 return Type(1.0);
116 }
117
119 constexpr Qty() : rawValue_(0.0) {}
120
122 constexpr Qty(ZeroUnit) : rawValue_(0.0) {}
123
125 template <typename U>
126 constexpr Qty(const U & q, double factor = 1.0,
127 enable_if_same_qty<void,Type,U> * = nullptr)
128 : rawValue_(q.rawValue() * factor) {}
129
131 constexpr double rawValue() const { return rawValue_; }
132
134 Type & operator*=(double x) { rawValue_ *= x; return *this; }
135
137 Type & operator/=(double x) { rawValue_ /= x; return *this; }
138
140 Type & operator+=(const Type & x)
141 {
142 rawValue_ += x.rawValue();
143 return *this;
144 }
145
147 Type & operator-=(const Type & x)
148 {
149 rawValue_ -= x.rawValue();
150 return *this;
151 }
152
153private:
155 double rawValue_;
156};
157
159template<>
160class Qty<std::ratio<0>,std::ratio<0>,std::ratio<0>>
161{
162public:
164 using Type = Qty<std::ratio<0>,std::ratio<0>,std::ratio<0>>;
166 template <long int Num, long int Den>
167 using Power = Type;
169 using Squared = Type;
171 using Inverse = Type;
173 using Sqrt = Type;
174
175
177 static constexpr Type baseunit() {
178 return 1.0;
179 }
180
182 constexpr Qty(ZeroUnit) : rawValue_(0.0) {}
183
185 constexpr Qty(double x = 0.0, double factor=1.0)
186 : rawValue_(x * factor) {}
187
189 template <typename U>
190 constexpr Qty(const U & q, double factor=1.0,
191 enable_if_same_qty<void,Type,U> * = nullptr)
192 : rawValue_(q.rawValue() * factor) {}
193
195 constexpr double rawValue() const { return rawValue_; }
196
198 constexpr operator double() const { return rawValue_; }
199
201 Type & operator*=(double x) { rawValue_ *= x; return *this; }
202
204 Type & operator/=(double x) { rawValue_ /= x; return *this; }
205
207 Type & operator+=(const Type & x) {
208 rawValue_ += x.rawValue();
209 return *this;
210 }
211
213 Type & operator-=(const Type & x) {
214 rawValue_ -= x.rawValue();
215 return *this;
216 }
217
219 Type & operator+=(double x) {
220 rawValue_ += x;
221 return *this;
222 }
223
225 Type & operator-=(double x) {
226 rawValue_ -= x;
227 return *this;
228 }
229
230private:
232 double rawValue_;
233};
234
235using QtyDouble = Qty<std::ratio<0>,std::ratio<0>,std::ratio<0>>;
236
238
239
244template <typename T, typename U>
246
249template<typename L1, typename L2,
250 typename E1, typename E2,
251 typename Q1, typename Q2>
252struct BinaryOpTraits<Qty<L1,E1,Q1>, Qty<L2,E2,Q2>> {
256 std::ratio_add<E1,E2>,
257 std::ratio_add<Q1,Q2>> MulT;
261 std::ratio_subtract<E1,E2>,
262 std::ratio_subtract<Q1,Q2>> DivT;
263};
264
268template<typename L, typename E, typename Q>
269struct BinaryOpTraits<double, Qty<L,E,Q>> {
271 typedef Qty<L,E,Q> MulT;
273 typedef typename BinaryOpTraits<QtyDouble, Qty<L,E,Q>>::DivT DivT;
274};
275
279template<typename L, typename E, typename Q>
280struct BinaryOpTraits<Qty<L,E,Q>, double> {
282 typedef Qty<L,E,Q> MulT;
284 typedef Qty<L,E,Q> DivT;
285};
287
289
290
291template <typename L, typename E, typename Q>
292struct TypeTraits<Qty<L,E,Q>>
293{
295 enum { hasDimension = true };
297 typedef DimensionT DimType;
299 static constexpr Qty<L,E,Q> baseunit()
300 { return Qty<L,E,Q>::baseunit(); }
301};
302
304template <>
305struct TypeTraits<QtyDouble>
306{
308 enum { hasDimension = false };
310 typedef StandardT DimType;
312 static constexpr QtyDouble baseunit() { return 1.0; }
313};
314
316
319}
320
321#endif
Useful template machinery.
Specialization of Qty for <0,0,0> with conversions to double.
Definition: PhysicalQty.h:161
Type & operator*=(double x)
Assignment multiplication by dimensionless number.
Definition: PhysicalQty.h:201
Type & operator-=(const Type &x)
Assignment subtraction with compatible quantity.
Definition: PhysicalQty.h:213
constexpr Qty(const U &q, double factor=1.0, enable_if_same_qty< void, Type, U > *=nullptr)
Constructor from a compatible quantity.
Definition: PhysicalQty.h:190
Type & operator+=(double x)
Assignment addition with double.
Definition: PhysicalQty.h:219
constexpr Qty(double x=0.0, double factor=1.0)
Default constructor from a double.
Definition: PhysicalQty.h:185
Type & operator+=(const Type &x)
Assignment addition with compatible quantity.
Definition: PhysicalQty.h:207
constexpr double rawValue() const
Access to the raw value.
Definition: PhysicalQty.h:195
Type & operator-=(double x)
Assignment subtraction with double.
Definition: PhysicalQty.h:225
static constexpr Type baseunit()
Basic unit of this quantity.
Definition: PhysicalQty.h:177
Type & operator/=(double x)
Assignment division by dimensionless number.
Definition: PhysicalQty.h:204
constexpr Qty(ZeroUnit)
Default constructor to 0.
Definition: PhysicalQty.h:182
constexpr Qty(double val)
Constructor from raw values. Breaks consistency.
Definition: PhysicalQty.h:80
Type & operator/=(double x)
Assignment division by dimensionless number.
Definition: PhysicalQty.h:137
constexpr Qty(const U &q, double factor=1.0, enable_if_same_qty< void, Type, U > *=nullptr)
Constructor from a compatible quantity.
Definition: PhysicalQty.h:126
static std::string className()
The name of the class for persistent IO.
Definition: PhysicalQty.h:85
Type & operator+=(const Type &x)
Assignment addition with compatible quantity.
Definition: PhysicalQty.h:140
constexpr double rawValue() const
Access to the raw value. Breaks consistency.
Definition: PhysicalQty.h:131
Type & operator*=(double x)
Assignment multiplication by dimensionless number.
Definition: PhysicalQty.h:134
static constexpr Type baseunit()
Basic unit of this quantity.
Definition: PhysicalQty.h:113
double rawValue_
The raw value in units of Qty::baseunit().
Definition: PhysicalQty.h:155
Type & operator-=(const Type &x)
Assignment subtraction with compatible quantity.
Definition: PhysicalQty.h:147
This template class allows the compiler to check calculations with physical quantities for dimensiona...
Definition: PhysicalQty.h:52
ThePEG::Qty< std::ratio< L, DL >, std::ratio< E, DE >, std::ratio< Q, DQ > > Qty
adapter for the old style of naming quantities
Definition: Unitsystem.h:39
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
constexpr ZeroUnit ZERO
ZERO can be used as zero for any unitful quantity.
Definition: PhysicalQty.h:35
Int2Type< Dimensioned > DimensionT
Typedef for dimensioned types.
Definition: TemplateTools.h:37
Int2Type< Standard > StandardT
Typedef for non-dimensioned types.
Definition: TemplateTools.h:40
STL namespace.
BinaryOpTraits should be specialized with typdefs called MulT and DivT which gives the type resulting...
Definition: PhysicalQty.h:245
static constexpr std::enable_if<(std::is_arithmetic< U >::value &&std::is_same< U, T >::value), U >::type baseunit()
Base unit for arithmetic types.
Definition: TemplateTools.h:61
StandardT DimType
Implementation selector.
Definition: TemplateTools.h:53
Helper class to construct zero unitful quantities.
Definition: PhysicalQty.h:29