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
00049 template<class PQ, class SU = typename PQ::DefaultUnit::Unit,
00050 class DD = typename DefaultDedimensionalizer<PQ, SU>::F> class Constant;
00051
00053
00056 template<long RL_N, long RL_D, long RM_N, long RM_D,
00057 long RT_N, long RT_D, long RE_N, long RE_D, long RTE_N, long RTE_D,
00058 long RA_N, long RA_D, long RLU_N, long RLU_D,
00059 class BT, class UL, class DU, class SU, class ST, class R,
00060 class DDH, class DDT>
00061 class Constant<Quantity<dimension::Dimension<
00062 BSUtilities::Rational<RL_N, RL_D>,
00063 BSUtilities::Rational<RM_N, RM_D>,
00064 BSUtilities::Rational<RT_N, RT_D>,
00065 BSUtilities::Rational<RE_N, RE_D>,
00066 BSUtilities::Rational<RTE_N, RTE_D>,
00067 BSUtilities::Rational<RA_N, RA_D>,
00068 BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, ST>,
00069 SU, Loki::Functor<R, Loki::Typelist<DDH, DDT> > >
00070 : public
00071 Quantity<dimension::Dimension<BSUtilities::Rational<RL_N, RL_D>,
00072 BSUtilities::Rational<RM_N, RM_D>,
00073 BSUtilities::Rational<RT_N, RT_D>,
00074 BSUtilities::Rational<RE_N, RE_D>,
00075 BSUtilities::Rational<RTE_N, RTE_D>,
00076 BSUtilities::Rational<RA_N, RA_D>,
00077 BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, ST>
00078
00079 {
00080 public:
00082
00084 typedef dimension::Dimension<BSUtilities::Rational<RL_N, RL_D>,
00085 BSUtilities::Rational<RM_N, RM_D>,
00086 BSUtilities::Rational<RT_N, RT_D>,
00087 BSUtilities::Rational<RE_N, RE_D>,
00088 BSUtilities::Rational<RTE_N, RTE_D>,
00089 BSUtilities::Rational<RA_N, RA_D>,
00090 BSUtilities::Rational<RLU_N, RLU_D> > DIM;
00091
00093 typedef typename Loki::Typelist<DDH, DDT> DDL;
00094
00096
00103 typedef typename Loki::TL::TypeAt<DDL, 0>::Result DDP;
00104
00106 typedef typename Loki::Functor<R, DDL> DD;
00107
00109
00112 typedef Quantity<DIM, BT, UL, DU, ST> ABQ;
00113
00115
00117 typedef Constant<ABQ, SU, DD> C;
00118
00120
00125 typedef ABQ PQ;
00126
00128 typedef typename BSUtilities::IF<BSUtilities::SameType
00129 <DD, typename DefaultDedimensionalizer<PQ, SU>::F>::sameType,
00130 DedimReturn<PQ, SU>, C>::RET DDR;
00131
00132 private:
00134
00138 static DDR defaultDedimensionalizer (DDP) {return DDR(ST(1.));}
00139
00141
00143 static const DD _defaultDD;
00144
00146
00153 DD _dedimensionalizer;
00154
00155
00157
00161 ST constant_value;
00162
00163 public:
00165
00170 typedef typename
00171 unit::CheckUnit<unit::Unit<BT>, SU>::Check Unit;
00172
00174
00177 Constant (void) : ABQ (), _dedimensionalizer (_defaultDD),
00178 constant_value (ST(0)) {}
00179
00181
00183 Constant (const DDR &dedimensionalizer)
00184 : ABQ (), _dedimensionalizer (dedimensionalizer),
00185 constant_value (ST(0)) {}
00186
00188
00191 Constant (const ST value) : ABQ (), _dedimensionalizer (_defaultDD),
00192 constant_value (value) {}
00193
00195
00198 Constant (const ST value, const SU &)
00199 : ABQ (), constant_value (value) {}
00200
00202
00208 template<class NU>
00209 Constant (const ST value, const NU &)
00210 : ABQ (), constant_value (Reverse<SU, ST>::VAL
00211 (Standardize<typename CheckAgainstAllUnits<NU, UL>::RET,
00212 ST>::VAL (value))) {}
00213
00214
00216
00223 Constant (const ST value, const std::string &symbol)
00224 : ABQ ()
00225 {::unit::Unit<BT> *unitp = PQ::findBySymbol (symbol);
00226
00227 constant_value = Reverse<SU, ST>::VAL
00228 (dynamic_standardize<UL>::VAL (value, *unitp));
00229
00230 delete (unitp);
00231 }
00232
00234
00241 Constant (const ST new_value, const char *symbol)
00242 : ABQ ()
00243 {::unit::Unit<BT> *unitp
00244 = PQ::findBySymbol (std::string (symbol));
00245
00246 constant_value = Reverse<SU, ST>::VAL
00247 (dynamic_standardize<UL>::VAL (new_value, *unitp));
00248
00249 delete (unitp);
00250 }
00251
00253
00256 template<template<class, class, class> class Q1, class DD1>
00257 Constant (const Q1<PQ, SU, DD1> &quantity)
00258 : ABQ (), constant_value (quantity.value ())
00259 {ABQ::namestring = quantity.name ();
00260 ABQ::symbolstring = quantity.symbol ();
00261 }
00262
00264
00275 template<template<class, class, class> class Q1, class SU1,
00276 class DD1>
00277 Constant (const Q1<PQ, SU1, DD1> &quantity)
00278 : ABQ (), constant_value (Reverse<SU, ST>::VAL
00279 (Standardize<SU1, ST>::VAL (quantity.value ())))
00280 {ABQ::namestring = quantity.name ();
00281 ABQ::symbolstring = quantity.symbol ();
00282 }
00283
00285
00292 template<template<class, class, class> class Q1, class BT1,
00293 class DIM1, class DU1, class SU1, class DD1>
00294 Constant (const Q1<Quantity<DIM1, BT1,
00295 Loki::Typelist<unit::NonPrefixable<BT1, unit::GenericUnit>,
00296 Loki::NullType>, DU1, ST>, SU1, DD1> &quantity)
00297 : ABQ (), constant_value (Reverse<Unit, ST>::VAL
00298 (Standardize<typename
00299 CheckSecondDimension<Variable<PQ, SU, DD>,
00300 Q1<Quantity<DIM1, BT1,
00301 Loki::Typelist<unit::NonPrefixable<BT1,
00302 unit::GenericUnit>, Loki::NullType>,
00303 DU1, ST>, SU1, DD1> >::RET::Unit, ST>::VAL
00304 (quantity.value ())))
00305 {ABQ::namestring = quantity.name ();
00306 ABQ::symbolstring = quantity.symbol ();
00307 }
00308
00310
00315 Constant (const Dynamic<ST> &dynamic)
00316 {if (dynamic._rl_n == RL_N/BSUtilities::Gcd<RL_N, RL_D>::RET
00317 && dynamic._rl_d == RL_D/BSUtilities::Gcd<RL_N, RL_D>::RET
00318 && dynamic._rm_n == RM_N/BSUtilities::Gcd<RM_N, RM_D>::RET
00319 && dynamic._rm_d == RM_D/BSUtilities::Gcd<RM_N, RM_D>::RET
00320 && dynamic._rt_n == RT_N/BSUtilities::Gcd<RT_N, RT_D>::RET
00321 && dynamic._rt_d == RT_D/BSUtilities::Gcd<RT_N, RT_D>::RET
00322 && dynamic._re_n == RE_N/BSUtilities::Gcd<RE_N, RE_D>::RET
00323 && dynamic._re_d == RE_D/BSUtilities::Gcd<RE_N, RE_D>::RET
00324 && dynamic._rte_n
00325 == RTE_N/BSUtilities::Gcd<RTE_N, RTE_D>::RET
00326 && dynamic._rte_d
00327 == RTE_D/BSUtilities::Gcd<RTE_N, RTE_D>::RET
00328 && dynamic._ra_n == RA_N/BSUtilities::Gcd<RA_N, RA_D>::RET
00329 && dynamic._ra_d == RA_D/BSUtilities::Gcd<RA_N, RA_D>::RET
00330 && dynamic._rlu_n
00331 == RLU_N/BSUtilities::Gcd<RLU_N, RLU_D>::RET
00332 && dynamic._rlu_d
00333 == RLU_D/BSUtilities::Gcd<RLU_N, RLU_D>::RET)
00334
00335 constant_value = Reverse<SU, ST>::VAL (dynamic.value ());
00336
00337 else
00338 {throw DimensionMismatch ();}
00339
00340 }
00341
00342 private:
00344
00347 template<template<class, class> class Q1, class DIM1, class BT1,
00348 class UL1, class DU1, class ST1, class SU1>
00349 Constant & operator=
00350 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST1>, SU1> &);
00351
00353
00356 template<class TQ> Constant & operator= (const TQ&);
00357
00358 public:
00360
00362 ST value (void) const {return constant_value;}
00363
00365
00368 ST standard_value (void) const
00369 {return Standardize<SU, ST>::VAL (constant_value);}
00370
00372
00377 template<class NU>
00378 ST value (const unit::NonPrefixable<BT, NU> &) const
00379 {return Reverse<typename CheckAgainstAllUnits<
00380 unit::NonPrefixable<BT, NU>, UL>::RET, ST>::VAL
00381 (Standardize<SU, ST>::VAL (constant_value));}
00382
00384
00389 template<class NU, class P>
00390 ST value
00391 (const unit::Prefixed<unit::Prefixable<BT, NU>, P> &) const
00392 {return Reverse<typename CheckAgainstAllUnits<
00393 unit::Prefixed<unit::Prefixable<BT, NU>, P>, UL>::RET,
00394 ST>::VAL (Standardize<SU, ST>::VAL (constant_value));}
00395
00397
00402 template<class CUL, class EL>
00403 ST value
00404 (const unit::Composed<unit::ComposeBase<BT, CUL>, EL> &)
00405 const
00406 {return Reverse<typename CheckAgainstAllUnits<
00407 unit::Composed<unit::ComposeBase<BT, CUL>, EL>, UL>::RET,
00408 ST>::VAL (Standardize<SU, ST>::VAL (constant_value));}
00409
00411
00418 ST value (const std::string &symbol)
00419 {
00420 ST value;
00421 ::unit::Unit<BT> *unitp = PQ::findBySymbol (symbol);
00422
00423 value = dynamic_reverse<UL>::VAL
00424 (Standardize<SU, ST>::VAL (constant_value), *unitp);
00425
00426 delete (unitp);
00427
00428 return value;
00429 }
00430
00432
00437 template<class NU>
00438 Constant<PQ, NU> operator () (const NU &) const
00439 {return Constant<PQ, NU> (constant_value, SU());}
00440
00442
00444 const std::string unitsymbol (void) const
00445 {return SU::Symbol ();}
00446
00448
00450 static std::string Unitsymbol (void) {return SU::Symbol ();}
00451
00453
00455 const std::string unitname (void) const {return SU::Name ();}
00456
00458
00460 static std::string Unitname (void) {return SU::Name ();}
00461
00463
00466 Variable<PQ, SU> operator+ (void) const
00467 {Variable<PQ, SU> new_constant (*this);
00468 return new_constant;
00469 }
00470
00472
00475 Variable<PQ, SU> operator- (void) const
00476 {Variable<PQ, SU> new_constant (*this);
00477 return new_constant *= -ST(1.0);
00478 }
00479
00481
00484 template <class Q>
00485 Variable<PQ, SU> operator+ (const Q &new_variable) const
00486 {Variable<PQ, SU> new_object = *this;
00487 return (new_object + new_variable);
00488 }
00489
00491
00494 template <class Q>
00495 Variable<PQ, SU> operator- (const Q &new_variable) const
00496 {Variable<PQ, SU> new_object = *this;
00497 return new_object -= new_variable;
00498 }
00499
00501
00503 Variable<PQ, SU> operator* (const ST factor) const
00504 {Variable<PQ, SU> new_object = *this;
00505 return new_object *= factor;
00506 }
00507
00509
00511 Variable<PQ, SU> operator/ (const ST factor) const
00512 {Variable<PQ, SU> new_object = *this;
00513 return new_object /= factor;
00514 }
00515
00517
00521 bool operator== (const Constant &rhs_variable) const
00522 {return constant_value == rhs_variable.value ();}
00523
00525
00530 template <template<class, class> class Q1, class SU1>
00531 bool operator== (const Q1<PQ, SU1> &rhs_variable) const
00532 {return standard_value () == rhs_variable.standard_value ();
00533 }
00534
00536
00541 template <template<class, class> class Q1,
00542 class DIM1, class BT1, class UL1, class DU1, class SU1>
00543 bool operator==
00544 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00545 &rhs_variable) const
00546 {
00547 return standard_value () == Standardize<typename
00548 CheckSecondDimension<Variable<PQ, SU>,
00549 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00550 >::RET::Unit, ST>::VAL (rhs_variable.value ());
00551 }
00552
00554
00558 bool operator!= (const Constant &rhs_variable) const
00559 {return constant_value != rhs_variable.value ();}
00560
00562
00567 template <template<class, class> class Q1, class SU1>
00568 bool operator!= (const Q1<PQ, SU1> &rhs_variable) const
00569 {return standard_value () != rhs_variable.standard_value ();
00570 }
00571
00573
00578 template <template<class, class> class Q1,
00579 class DIM1, class BT1, class UL1, class DU1, class SU1>
00580 bool operator!=
00581 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00582 &rhs_variable) const
00583 {
00584 return standard_value () != Standardize<typename
00585 CheckSecondDimension<Variable<PQ, SU>,
00586 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00587 >::RET::Unit, ST>::VAL (rhs_variable.value ());
00588 }
00589
00591
00595 bool operator> (const Constant &rhs_variable) const
00596 {return constant_value > rhs_variable.value ();}
00597
00599
00604 template <template<class, class> class Q1, class SU1>
00605 bool operator> (const Q1<PQ, SU1> &rhs_variable) const
00606 {return standard_value () > rhs_variable.standard_value ();
00607 }
00608
00610
00615 template <template<class, class> class Q1,
00616 class DIM1, class BT1, class UL1, class DU1, class SU1>
00617 bool operator>
00618 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00619 &rhs_variable) const
00620 {
00621 return standard_value () > Standardize<typename
00622 CheckSecondDimension<Variable<PQ, SU>,
00623 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00624 >::RET::Unit, ST>::VAL (rhs_variable.value ());
00625 }
00626
00628
00632 bool operator< (const Constant &rhs_variable) const
00633 {return constant_value < rhs_variable.value ();}
00634
00636
00641 template <template<class, class> class Q1, class SU1>
00642 bool operator< (const Q1<PQ, SU1> &rhs_variable) const
00643 {return standard_value () < rhs_variable.standard_value ();
00644 }
00645
00647
00652 template <template<class, class> class Q1,
00653 class DIM1, class BT1, class UL1, class DU1, class SU1>
00654 bool operator<
00655 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00656 &rhs_variable) const
00657 {
00658 return standard_value () < Standardize<typename
00659 CheckSecondDimension<Variable<PQ, SU>,
00660 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00661 >::RET::Unit, ST>::VAL (rhs_variable.value ());
00662 }
00663
00665
00669 bool operator>= (const Constant &rhs_variable) const
00670 {return constant_value >= rhs_variable.value ();}
00671
00673
00678 template <template<class, class> class Q1, class SU1>
00679 bool operator>= (const Q1<PQ, SU1> &rhs_variable) const
00680 {return standard_value ()
00681 >= rhs_variable.standard_value ();}
00682
00684
00689 template <template<class, class> class Q1,
00690 class DIM1, class BT1, class UL1, class DU1, class SU1>
00691 bool operator>=
00692 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00693 &rhs_variable) const
00694 {
00695 return standard_value () >= Standardize<typename
00696 CheckSecondDimension<Variable<PQ, SU>,
00697 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00698 >::RET::Unit, ST>::VAL (rhs_variable.value ());
00699 }
00700
00702
00706 bool operator<= (const Constant &rhs_variable) const
00707 {return constant_value <= rhs_variable.value ();}
00708
00710
00715 template <template<class, class> class Q1, class SU1>
00716 bool operator<= (const Q1<PQ, SU1> &rhs_variable) const
00717 {return standard_value ()
00718 <= rhs_variable.standard_value ();}
00719
00721
00726 template <template<class, class> class Q1,
00727 class DIM1, class BT1, class UL1, class DU1, class SU1>
00728 bool operator<=
00729 (const Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00730 &rhs_variable) const
00731 {
00732 return standard_value () <= Standardize<typename
00733 CheckSecondDimension<Variable<PQ, SU>,
00734 Q1<Quantity<DIM1, BT1, UL1, DU1, ST>, SU1>
00735 >::RET::Unit, ST>::VAL (rhs_variable.value ());
00736 }
00737
00739
00744 template<class Q>
00745 typename GenerateVariable<Constant, Q>::Add operator*
00746 (const Q &factor)
00747 {
00748 return typename GenerateVariable<Constant, Q>::Add
00749 (standard_value () * factor.standard_value ());
00750 }
00751
00753
00758 template<class Q>
00759 typename GenerateVariable<Constant, Q>::Sub operator/
00760 (const Q &factor)
00761 {
00762 return typename GenerateVariable<Constant, Q>::Sub
00763 (standard_value () / factor.standard_value ());
00764 }
00765
00767
00770 friend
00771 typename GenerateVariable<Constant, Loki::NullType>::Inv
00772 operator/ (const ST numerator, const Constant &factor)
00773 {
00774 return typename
00775 GenerateVariable<Constant, Loki::NullType>::Inv
00776 (numerator / factor.standard_value ());
00777 }
00778
00780
00787 template<long N, long D>
00788 typename GenerateVariable<Constant,
00789 BSUtilities::Rational<N, D> >::Mult
00790 pow (const BSUtilities::Rational<N, D> &) const
00791 {return std::pow (standard_value (),
00792 static_cast<double>(N)/static_cast<double>(D));}
00793
00795
00802 template<int I>
00803 typename GenerateVariable<Constant,
00804 BSUtilities::Rational<I, long(1)> >::Mult
00805 pow (const typename Loki::Int2Type<I>) const
00806 {return std::pow (standard_value (), I);}
00807
00809
00815 template<class T>
00816 Dynamic<ST> pow (const T &exp) const
00817 {return Dynamic<ST>::pow (*this, exp);}
00818
00819
00821
00823 friend
00824 typename
00825 GenerateVariable<Constant, BSUtilities::Rational<1, 2>
00826 >::Mult sqrt (const Constant &constant)
00827 {
00828 return typename
00829 GenerateVariable<Constant, BSUtilities::Rational<1, 2>
00830 >::Mult (std::sqrt(constant.standard_value ()));
00831 }
00832
00834
00836 typename
00837 GenerateVariable<Constant, BSUtilities::Rational<1, 2>
00838 >::Mult sqrt (void)
00839 {
00840 return typename
00841 GenerateVariable<Constant, BSUtilities::Rational<1, 2>
00842 >::Mult (std::sqrt(standard_value ()));
00843 }
00844
00846
00849 std::ostream & print_value (std::ostream &os) const
00850 {return os << constant_value << " " << SU::Symbol ();}
00851
00853
00855 void operator>> (std::string &str) const
00856 {str = BSUtilities::Conversion<Constant>::to_string (*this);}
00857
00859
00863 std::ostream & operator>> (std::ostream &os) const
00864 {return this->print (os);}
00865
00867
00871 void save (BSUtilities::xmlw::XmlStream &os) const
00872 {
00873 os << BSUtilities::xmlw::tag (Quantities::TAG)
00874 << BSUtilities::xmlw::attr (Quantities::MODETAG) << MODE
00875
00876 << BSUtilities::xmlw::endtag (Quantities::TAG);
00877 }
00878
00880
00883 void load (const TiXmlHandle node) const
00884 {
00885 TiXmlElement *element = node.Element();
00886
00887 if (element
00888 && (element->ValueStr () == Quantities::TAG)
00889 && (element->Attribute (Quantities::MODETAG) == MODE))
00890 {
00891
00892 }
00893 else
00894 throw LoadError
00895 ("error loading constant quantity: incorrect element");
00896 }
00897
00899
00903
00904
00905
00906
00908
00910 static const std::string MODE;
00911
00912 };
00913
00915 template<long RL_N, long RL_D, long RM_N, long RM_D,
00916 long RT_N, long RT_D, long RE_N, long RE_D, long RTE_N, long RTE_D,
00917 long RA_N, long RA_D, long RLU_N, long RLU_D,
00918 class BT, class UL, class DU, class SU, class ST, class R,
00919 class NH, class NT>
00920 const std::string Constant<Quantity<dimension::Dimension<
00921 BSUtilities::Rational<RL_N, RL_D>,
00922 BSUtilities::Rational<RM_N, RM_D>,
00923 BSUtilities::Rational<RT_N, RT_D>,
00924 BSUtilities::Rational<RE_N, RE_D>,
00925 BSUtilities::Rational<RTE_N, RTE_D>,
00926 BSUtilities::Rational<RA_N, RA_D>,
00927 BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, ST>,
00928 SU, Loki::Functor<R, Loki::Typelist<NH, NT> > >::MODE
00929 = "constant";
00930
00932 template<long RL_N, long RL_D, long RM_N, long RM_D,
00933 long RT_N, long RT_D, long RE_N, long RE_D, long RTE_N, long RTE_D,
00934 long RA_N, long RA_D, long RLU_N, long RLU_D,
00935 class BT, class UL, class DU, class SU, class ST, class R,
00936 class NH, class NT>
00937 const typename Loki::Functor<R, typename Loki::Typelist<NH, NT> >
00938 Constant<Quantity<dimension::Dimension<
00939 BSUtilities::Rational<RL_N, RL_D>,
00940 BSUtilities::Rational<RM_N, RM_D>,
00941 BSUtilities::Rational<RT_N, RT_D>,
00942 BSUtilities::Rational<RE_N, RE_D>,
00943 BSUtilities::Rational<RTE_N, RTE_D>,
00944 BSUtilities::Rational<RA_N, RA_D>,
00945 BSUtilities::Rational<RLU_N, RLU_D> >, BT, UL, DU, ST>,
00946 SU, Loki::Functor<R, Loki::Typelist<NH, NT>
00947 > >::_defaultDD =
00948 typename Loki::Functor<R, typename Loki::Typelist<NH, NT> >
00949 (defaultDedimensionalizer);
00950
00951 }
00952
00953 #endif