00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _Constant_h
00025 #define _Constant_h
00026
00027 #include "Quantity/Quantity.h"
00028 #include "Quantity/QuantityError.h"
00029 #include "Quantity/Dedimensionalization.h"
00030 #include "Quantity/Variable.h"
00031
00032 namespace quantity {
00033
00035
00036
00037
00039
00041
00046 template<class PQ, class SU = typename PQ::DefaultUnit::Unit,
00047 class N = typename DefaultDedimensionalizer<PQ, SU>::F> class Constant;
00048
00050
00053 template<long RL_N, long RL_D, long RM_N, long RM_D,
00054 long RT_N, long RT_D, long RE_N, long RE_D, long RTE_N, long RTE_D,
00055 long RA_N, long RA_D, long RLU_N, long RLU_D,
00056 class BT, class UL, class DU, class SU, class ST, class R,
00057 class NH, class NT>
00058 class Constant<Quantity<dimension::Dimension<
00059 BSUtilities::Rational<RL_N, RL_D>,
00060 BSUtilities::Rational<RM_N, RM_D>,
00061 BSUtilities::Rational<RT_N, RT_D>,
00062 BSUtilities::Rational<RE_N, RE_D>,
00063 BSUtilities::Rational<RTE_N, RTE_D>,
00064 BSUtilities::Rational<RA_N, RA_D>,
00065 BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, ST>,
00066 SU, Loki::Functor<R, Loki::Typelist<NH, NT> > >
00067 : public
00068 Quantity<dimension::Dimension<BSUtilities::Rational<RL_N, RL_D>,
00069 BSUtilities::Rational<RM_N, RM_D>,
00070 BSUtilities::Rational<RT_N, RT_D>,
00071 BSUtilities::Rational<RE_N, RE_D>,
00072 BSUtilities::Rational<RTE_N, RTE_D>,
00073 BSUtilities::Rational<RA_N, RA_D>,
00074 BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, ST>
00075
00076 {
00077 public:
00079
00081 typedef dimension::Dimension<BSUtilities::Rational<RL_N, RL_D>,
00082 BSUtilities::Rational<RM_N, RM_D>,
00083 BSUtilities::Rational<RT_N, RT_D>,
00084 BSUtilities::Rational<RE_N, RE_D>,
00085 BSUtilities::Rational<RTE_N, RTE_D>,
00086 BSUtilities::Rational<RA_N, RA_D>,
00087 BSUtilities::Rational<RLU_N, RLU_D> > DIM;
00088
00090 typedef typename Loki::Typelist<NH, NT> NL;
00091
00093
00100 typedef typename Loki::TL::TypeAt<NL, 0>::Result NP;
00101
00103 typedef typename Loki::Functor<R, NL> N;
00104
00106
00109 typedef Quantity<DIM, BT, UL, DU, ST> ABQ;
00110
00112
00114 typedef Constant<ABQ, SU, N> C;
00115
00117
00122 typedef ABQ PQ;
00123
00125
00130 typedef typename
00131 unit::CheckUnit<unit::Unit<BT>, SU>::Check Unit;
00132
00134 typedef typename BSUtilities::IF<BSUtilities::SameType
00135 <N, typename DefaultDedimensionalizer<PQ, SU>::F>::sameType,
00136 DedimReturn<PQ, SU>, C>::RET NR;
00137
00138 private:
00140
00144 static NR defaultDedimensionalizer (NP) {return NR(ST(1.));}
00145
00147
00149 static const N _defaultN;
00150
00152
00159 N _dedimensionalizer;
00160
00161
00163
00167 ST constant_value;
00168
00169 public:
00171
00174 Constant (void) : ABQ (), _dedimensionalizer (_defaultN),
00175 constant_value (ST(0)) {}
00176
00178
00180 Constant (const NR &dedimensionalizer)
00181 : ABQ (), _dedimensionalizer (dedimensionalizer), constant_value (ST(0)) {}
00182
00184
00187 Constant (const ST value) : ABQ (), _dedimensionalizer (_defaultN),
00188 constant_value (value) {}
00189
00191
00194 Constant (const ST value, const SU &)
00195 : ABQ (), constant_value (value) {}
00196
00198
00204 template<class NU>
00205 Constant (const ST value, const NU &)
00206 : ABQ (), constant_value (Reverse<SU, ST>::VAL
00207 (Standardize<typename CheckAgainstAllUnits<NU, UL>::RET,
00208 ST>::VAL (value))) {}
00209
00210
00212
00219 Constant (const ST value, const std::string &symbol)
00220 : ABQ ()
00221 {::unit::Unit<BT> *unitp = PQ::findBySymbol (symbol);
00222
00223 constant_value = Reverse<SU, ST>::VAL
00224 (dynamic_standardize<UL>::VAL (value, *unitp));
00225
00226 delete (unitp);
00227 }
00228
00230
00237 Constant (const ST new_value, const char *symbol)
00238 : ABQ ()
00239 {::unit::Unit<BT> *unitp
00240 = PQ::findBySymbol (std::string (symbol));
00241
00242 constant_value = Reverse<SU, ST>::VAL
00243 (dynamic_standardize<UL>::VAL (new_value, *unitp));
00244
00245 delete (unitp);
00246 }
00247
00249
00252 template<template<class, class> class Q1>
00253 Constant (const Q1<PQ, SU> &quantity)
00254 : ABQ (), constant_value (quantity.value ())
00255 {namestring = quantity.name ();
00256 symbolstring = quantity.symbol ();
00257 }
00258
00260
00271 template<template<class, class> class Q1, class SU1>
00272 Constant (const Q1<PQ, SU1> &quantity)
00273 : ABQ (), constant_value (Reverse<SU, ST>::VAL
00274 (Standardize<SU1, ST>::VAL (quantity.value ())))
00275 {namestring = quantity.name ();
00276 symbolstring = quantity.symbol ();
00277 }
00278
00280
00287 template<template<class, class> class Q1, class BT1,
00288 class DIM1, class DU1, class SU1>
00289 Constant (const Q1<Quantity<DIM1, BT1,
00290 Loki::Typelist<unit::NonPrefixable<BT1, unit::GenericUnit>,
00291 Loki::NullType>, DU1, ST>, SU1> &quantity)
00292 : ABQ (), constant_value (Reverse<Unit, ST>::VAL
00293 (Standardize<typename
00294 CheckSecondDimension<Variable<PQ, SU>,
00295 Q1<Quantity<DIM1, BT1,
00296 Loki::Typelist<unit::NonPrefixable<BT1,
00297 unit::GenericUnit>, Loki::NullType>,
00298 DU1, ST>, SU1> >::RET::Unit, ST>::VAL
00299 (quantity.value ())))
00300 {namestring = quantity.name ();
00301 symbolstring = quantity.symbol ();
00302 }
00303
00305
00310 Constant (const Dynamic<ST> &dynamic)
00311 {if (dynamic._rl_n == RL_N/BSUtilities::Gcd<RL_N, RL_D>::RET
00312 && dynamic._rl_d == RL_D/BSUtilities::Gcd<RL_N, RL_D>::RET
00313 && dynamic._rm_n == RM_N/BSUtilities::Gcd<RM_N, RM_D>::RET
00314 && dynamic._rm_d == RM_D/BSUtilities::Gcd<RM_N, RM_D>::RET
00315 && dynamic._rt_n == RT_N/BSUtilities::Gcd<RT_N, RT_D>::RET
00316 && dynamic._rt_d == RT_D/BSUtilities::Gcd<RT_N, RT_D>::RET
00317 && dynamic._re_n == RE_N/BSUtilities::Gcd<RE_N, RE_D>::RET
00318 && dynamic._re_d == RE_D/BSUtilities::Gcd<RE_N, RE_D>::RET
00319 && dynamic._rte_n
00320 == RTE_N/BSUtilities::Gcd<RTE_N, RTE_D>::RET
00321 && dynamic._rte_d
00322 == RTE_D/BSUtilities::Gcd<RTE_N, RTE_D>::RET
00323 && dynamic._ra_n == RA_N/BSUtilities::Gcd<RA_N, RA_D>::RET
00324 && dynamic._ra_d == RA_D/BSUtilities::Gcd<RA_N, RA_D>::RET
00325 && dynamic._rlu_n
00326 == RLU_N/BSUtilities::Gcd<RLU_N, RLU_D>::RET
00327 && dynamic._rlu_d
00328 == RLU_D/BSUtilities::Gcd<RLU_N, RLU_D>::RET)
00329
00330 constant_value = Reverse<SU, ST>::VAL (dynamic.value ());
00331
00332 else
00333 {throw DimensionMismatch ();}
00334
00335 }
00336
00337 private:
00339
00342 template<template<class, class> class Q1, class DIM1, class BT1,
00343 class UL1, class DU1, class ST1, class SU1>
00344 Constant & operator=
00345 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST1>, SU1> &);
00346
00348
00351 template<class TQ> Constant & operator= (const TQ&);
00352
00353 public:
00355
00357 ST value (void) const {return constant_value;}
00358
00360
00363 ST standard_value (void) const
00364 {return Standardize<SU, ST>::VAL (constant_value);}
00365
00367
00372 template<class NU>
00373 ST value (const unit::NonPrefixable<BT, NU> &) const
00374 {return Reverse<typename CheckAgainstAllUnits<
00375 unit::NonPrefixable<BT, NU>, UL>::RET, ST>::VAL
00376 (Standardize<SU, ST>::VAL (constant_value));}
00377
00379
00384 template<class NU, class P>
00385 ST value
00386 (const unit::Prefixed<unit::Prefixable<BT, NU>, P> &) const
00387 {return Reverse<typename CheckAgainstAllUnits<
00388 unit::Prefixed<unit::Prefixable<BT, NU>, P>, UL>::RET,
00389 ST>::VAL (Standardize<SU, ST>::VAL (constant_value));}
00390
00392
00397 template<class CUL, class EL>
00398 ST value
00399 (const unit::Composed<unit::ComposeBase<BT, CUL>, EL> &)
00400 const
00401 {return Reverse<typename CheckAgainstAllUnits<
00402 unit::Composed<unit::ComposeBase<BT, CUL>, EL>, UL>::RET,
00403 ST>::VAL (Standardize<SU, ST>::VAL (constant_value));}
00404
00406
00413 ST value (const std::string &symbol)
00414 {
00415 ST value;
00416 ::unit::Unit<BT> *unitp = PQ::findBySymbol (symbol);
00417
00418 value = dynamic_reverse<UL>::VAL
00419 (Standardize<SU, ST>::VAL (constant_value), *unitp);
00420
00421 delete (unitp);
00422
00423 return value;
00424 }
00425
00427
00432 template<class NU>
00433 Constant<PQ, NU> operator () (const NU &) const
00434 {return Constant<PQ, NU> (constant_value, SU());}
00435
00437
00439 const std::string unitsymbol (void) const
00440 {return SU::Symbol ();}
00441
00443
00445 static std::string Unitsymbol (void) {return SU::Symbol ();}
00446
00448
00450 const std::string unitname (void) const {return SU::Name ();}
00451
00453
00455 static std::string Unitname (void) {return SU::Name ();}
00456
00458
00461 Variable<PQ, SU> operator+ (void) const
00462 {Variable<PQ, SU> new_constant (*this);
00463 return new_constant;
00464 }
00465
00467
00470 Variable<PQ, SU> operator- (void) const
00471 {Variable<PQ, SU> new_constant (*this);
00472 return new_constant *= -ST(1.0);
00473 }
00474
00476
00479 template <class Q>
00480 Variable<PQ, SU> operator+ (const Q &new_variable) const
00481 {Variable<PQ, SU> new_object = *this;
00482 return (new_object + new_variable);
00483 }
00484
00486
00489 template <class Q>
00490 Variable<PQ, SU> operator- (const Q &new_variable) const
00491 {Variable<PQ, SU> new_object = *this;
00492 return new_object -= new_variable;
00493 }
00494
00496
00498 Variable<PQ, SU> operator* (const ST factor) const
00499 {Variable<PQ, SU> new_object = *this;
00500 return new_object *= factor;
00501 }
00502
00504
00506 Variable<PQ, SU> operator/ (const ST factor) const
00507 {Variable<PQ, SU> new_object = *this;
00508 return new_object /= factor;
00509 }
00510
00512
00516 bool operator== (const Constant &rhs_variable) const
00517 {return constant_value == rhs_variable.value ();}
00518
00520
00525 template <template<class, class> class Q1, class SU1>
00526 bool operator== (const Q1<PQ, SU1> &rhs_variable) const
00527 {return standard_value () == rhs_variable.standard_value ();
00528 }
00529
00531
00536 template <template<class, class> class Q1,
00537 class DIM1, class BT1, class UL1, class DU1, class SU1>
00538 bool operator==
00539 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00540 &rhs_variable) const
00541 {
00542 return standard_value () == Standardize<typename
00543 CheckSecondDimension<Variable<PQ, SU>,
00544 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00545 >::RET::Unit, ST>::VAL (rhs_variable.value ());
00546 }
00547
00549
00553 bool operator!= (const Constant &rhs_variable) const
00554 {return constant_value != rhs_variable.value ();}
00555
00557
00562 template <template<class, class> class Q1, class SU1>
00563 bool operator!= (const Q1<PQ, SU1> &rhs_variable) const
00564 {return standard_value () != rhs_variable.standard_value ();
00565 }
00566
00568
00573 template <template<class, class> class Q1,
00574 class DIM1, class BT1, class UL1, class DU1, class SU1>
00575 bool operator!=
00576 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00577 &rhs_variable) const
00578 {
00579 return standard_value () != Standardize<typename
00580 CheckSecondDimension<Variable<PQ, SU>,
00581 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00582 >::RET::Unit, ST>::VAL (rhs_variable.value ());
00583 }
00584
00586
00590 bool operator> (const Constant &rhs_variable) const
00591 {return constant_value > rhs_variable.value ();}
00592
00594
00599 template <template<class, class> class Q1, class SU1>
00600 bool operator> (const Q1<PQ, SU1> &rhs_variable) const
00601 {return standard_value () > rhs_variable.standard_value ();
00602 }
00603
00605
00610 template <template<class, class> class Q1,
00611 class DIM1, class BT1, class UL1, class DU1, class SU1>
00612 bool operator>
00613 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00614 &rhs_variable) const
00615 {
00616 return standard_value () > Standardize<typename
00617 CheckSecondDimension<Variable<PQ, SU>,
00618 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00619 >::RET::Unit, ST>::VAL (rhs_variable.value ());
00620 }
00621
00623
00627 bool operator< (const Constant &rhs_variable) const
00628 {return constant_value < rhs_variable.value ();}
00629
00631
00636 template <template<class, class> class Q1, class SU1>
00637 bool operator< (const Q1<PQ, SU1> &rhs_variable) const
00638 {return standard_value () < rhs_variable.standard_value ();
00639 }
00640
00642
00647 template <template<class, class> class Q1,
00648 class DIM1, class BT1, class UL1, class DU1, class SU1>
00649 bool operator<
00650 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00651 &rhs_variable) const
00652 {
00653 return standard_value () < Standardize<typename
00654 CheckSecondDimension<Variable<PQ, SU>,
00655 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00656 >::RET::Unit, ST>::VAL (rhs_variable.value ());
00657 }
00658
00660
00664 bool operator>= (const Constant &rhs_variable) const
00665 {return constant_value >= rhs_variable.value ();}
00666
00668
00673 template <template<class, class> class Q1, class SU1>
00674 bool operator>= (const Q1<PQ, SU1> &rhs_variable) const
00675 {return standard_value ()
00676 >= rhs_variable.standard_value ();}
00677
00679
00684 template <template<class, class> class Q1,
00685 class DIM1, class BT1, class UL1, class DU1, class SU1>
00686 bool operator>=
00687 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00688 &rhs_variable) const
00689 {
00690 return standard_value () >= Standardize<typename
00691 CheckSecondDimension<Variable<PQ, SU>,
00692 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00693 >::RET::Unit, ST>::VAL (rhs_variable.value ());
00694 }
00695
00697
00701 bool operator<= (const Constant &rhs_variable) const
00702 {return constant_value <= rhs_variable.value ();}
00703
00705
00710 template <template<class, class> class Q1, class SU1>
00711 bool operator<= (const Q1<PQ, SU1> &rhs_variable) const
00712 {return standard_value ()
00713 <= rhs_variable.standard_value ();}
00714
00716
00721 template <template<class, class> class Q1,
00722 class DIM1, class BT1, class UL1, class DU1, class SU1>
00723 bool operator<=
00724 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00725 &rhs_variable) const
00726 {
00727 return standard_value () <= Standardize<typename
00728 CheckSecondDimension<Variable<PQ, SU>,
00729 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00730 >::RET::Unit, ST>::VAL (rhs_variable.value ());
00731 }
00732
00734
00739 template<class Q>
00740 typename GenerateVariable<Constant, Q>::Add operator*
00741 (const Q &factor)
00742 {
00743 return typename GenerateVariable<Constant, Q>::Add
00744 (standard_value () * factor.standard_value ());
00745 }
00746
00748
00753 template<class Q>
00754 typename GenerateVariable<Constant, Q>::Sub operator/
00755 (const Q &factor)
00756 {
00757 return typename GenerateVariable<Constant, Q>::Sub
00758 (standard_value () / factor.standard_value ());
00759 }
00760
00762
00765 friend
00766 typename GenerateVariable<Constant, Loki::NullType>::Inv
00767 operator/ (const ST numerator, const Constant &factor)
00768 {
00769 return typename
00770 GenerateVariable<Constant, Loki::NullType>::Inv
00771 (numerator / factor.standard_value ());
00772 }
00773
00775
00781 template<long N, long D>
00782 typename GenerateVariable<Constant,
00783 BSUtilities::Rational<N, D> >::Mult
00784 pow (const BSUtilities::Rational<N, D> &)
00785 {return
00786 ::quantity::pow (*this, BSUtilities::Rational<N, D> ());}
00787
00789
00795 template<int I>
00796 typename GenerateVariable<Constant,
00797 BSUtilities::Rational<I, long(1)> >::Mult
00798 pow (typename Loki::Int2Type<I>)
00799 {return ::quantity::pow (*this, Loki::Int2Type<I> ());}
00800
00802
00808 template<class T>
00809 Dynamic<ST> pow (const T &exp) const
00810 {return ::quantity::pow (*this, exp);}
00811
00812
00814
00816 friend
00817 typename
00818 GenerateVariable<Constant, BSUtilities::Rational<1, 2>
00819 >::Mult sqrt (const Constant &constant)
00820 {
00821 return typename
00822 GenerateVariable<Constant, BSUtilities::Rational<1, 2>
00823 >::Mult (std::sqrt(constant.standard_value ()));
00824 }
00825
00827
00829 typename
00830 GenerateVariable<Constant, BSUtilities::Rational<1, 2>
00831 >::Mult sqrt (void)
00832 {
00833 return typename
00834 GenerateVariable<Constant, BSUtilities::Rational<1, 2>
00835 >::Mult (std::sqrt(standard_value ()));
00836 }
00837
00839
00842 std::ostream & print_value (std::ostream &os) const
00843 {return os << constant_value << " " << SU::Symbol ();}
00844
00846
00848 void operator>> (std::string &str) const
00849 {str = BSUtilities::Conversion<Constant>::to_string (*this);}
00850
00852
00856 std::ostream & operator>> (std::ostream &os) const
00857 {return this->print (os);}
00858
00860
00864 void save (BSUtilities::xmlw::XmlStream &os) const
00865 {
00866 os << BSUtilities::xmlw::tag(TAG)
00867 << BSUtilities::xmlw::attr (MODETAG) << MODE
00868
00869 << BSUtilities::xmlw::endtag(TAG);
00870 }
00871
00873
00876 void load (const TiXmlHandle node) const
00877 {
00878 TiXmlElement *element = node.Element();
00879
00880 if (element
00881 && (element->ValueStr () == Quantities::TAG)
00882 && (element->Attribute(MODETAG) == MODE))
00883 {
00884
00885 }
00886 else
00887 throw LoadError
00888 ("error loading constant quantity: incorrect element");
00889 }
00890
00892
00896
00897
00898
00899
00901
00903 static const std::string MODE;
00904
00905 };
00906
00908 template<long RL_N, long RL_D, long RM_N, long RM_D,
00909 long RT_N, long RT_D, long RE_N, long RE_D, long RTE_N, long RTE_D,
00910 long RA_N, long RA_D, long RLU_N, long RLU_D,
00911 class BT, class UL, class DU, class SU, class ST, class R,
00912 class NH, class NT>
00913 const std::string Constant<Quantity<dimension::Dimension<
00914 BSUtilities::Rational<RL_N, RL_D>,
00915 BSUtilities::Rational<RM_N, RM_D>,
00916 BSUtilities::Rational<RT_N, RT_D>,
00917 BSUtilities::Rational<RE_N, RE_D>,
00918 BSUtilities::Rational<RTE_N, RTE_D>,
00919 BSUtilities::Rational<RA_N, RA_D>,
00920 BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, ST>,
00921 SU, Loki::Functor<R, Loki::Typelist<NH, NT> > >::MODE
00922 = "constant";
00923
00925 template<long RL_N, long RL_D, long RM_N, long RM_D,
00926 long RT_N, long RT_D, long RE_N, long RE_D, long RTE_N, long RTE_D,
00927 long RA_N, long RA_D, long RLU_N, long RLU_D,
00928 class BT, class UL, class DU, class SU, class ST, class R,
00929 class NH, class NT>
00930 const typename Loki::Functor<R, typename Loki::Typelist<NH, NT> >
00931 Constant<Quantity<dimension::Dimension<
00932 BSUtilities::Rational<RL_N, RL_D>,
00933 BSUtilities::Rational<RM_N, RM_D>,
00934 BSUtilities::Rational<RT_N, RT_D>,
00935 BSUtilities::Rational<RE_N, RE_D>,
00936 BSUtilities::Rational<RTE_N, RTE_D>,
00937 BSUtilities::Rational<RA_N, RA_D>,
00938 BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, ST>,
00939 SU, Loki::Functor<R, Loki::Typelist<NH, NT>
00940 > >::_defaultN =
00941 typename Loki::Functor<R, typename Loki::Typelist<NH, NT> >
00942 (defaultDedimensionalizer);
00943
00944 }
00945
00946 #endif