/** * \file units.h \brief Classes to help with converting between units. * * Copyright 2007-2013 IMP Inventors. All rights reserved. * */ #ifndef IMPKERNEL_UNITS_H #define IMPKERNEL_UNITS_H #include "Unit.h" #include "../base_types.h" #include #include #include IMPKERNEL_BEGIN_NAMESPACE namespace internal { // want it for conversions extern IMPKERNELEXPORT const unit::ExponentialNumber<3> JOULES_PER_KILOCALORIE; extern IMPKERNELEXPORT const unit::ExponentialNumber<23> NA; namespace unit { namespace internal { struct AtomsPerMol {}; struct MDEnergyTag; template <> inline std::string get_unit_name(int) { std::string os[]= {"Cal/Mol"}; return os[0]; } struct MDDerivativeTag; template <> inline std::string get_unit_name(int) { std::string os[]= {"Cal/(A Mol)"}; return os[0]; } struct MKSTag{}; template <> inline std::string get_unit_name(int o) { std::string os[]= {"kg", "m", "s", "k", "Cal"}; return os[o]; } struct DaltonTag{}; template <> inline std::string get_unit_name(int) { std::string os[]= {"Da"}; return os[0]; } struct MolarTag{}; template <> inline std::string get_unit_name(int) { std::string os[]= {"Mol"}; return os[0]; } } // namespace unit::internal typedef boost::mpl::vector_c Scalar; typedef boost::mpl::vector_c Mass; typedef boost::mpl::vector_c Length; typedef boost::mpl::vector_c Volume; typedef boost::mpl::vector_c Time; typedef boost::mpl::vector_c Temperature; typedef boost::mpl::vector_c HeatEnergy; typedef boost::mpl::vector_c Energy; typedef boost::mpl::vector_c Force; typedef boost::mpl::vector_c Pressure; typedef boost::mpl::vector_c HeatEnergyDerivative; typedef Unit MKSScalar; typedef Unit Meter; typedef Unit Centimeter; typedef Unit Kilogram; typedef Unit Gram; typedef Unit Second; typedef Unit Joule; typedef Unit Kelvin; typedef Unit Liter; typedef Unit CubicMeter; typedef Shift::type Angstrom; typedef Shift::type Nanometer; typedef Multiply::type SquareAngstrom; typedef Shift::type Femtojoule; typedef Shift::type Picojoule; typedef Divide::type JoulePerKelvin; typedef Multiply::type SquareMeter; typedef Divide::type SquareMeterPerSecond; typedef Unit Femtosecond; typedef Shift::type SquareCentimeterPerSecond; typedef Divide::type SquareAngstromPerFemtosecond; typedef Divide::type PerFemtosecond; typedef Unit Femtonewton; typedef Unit Piconewton; typedef Unit Femtogram; typedef Divide::type PiconewtonPerAngstrom; typedef Unit Pascal; typedef Unit Kilocalorie; typedef Unit YoctoKilocalorie; typedef Divide::type KilocaloriePerMeter; typedef Divide::type KilocaloriePerAngstrom; // Calorie is ambiguous given our naming convention typedef Shift::type YoctoKilocaloriePerMeter; typedef Shift::type YoctoKilocaloriePerAngstrom; typedef Multiply::type, Centimeter>::type CubicCentimeter; typedef Multiply::type, Angstrom>::type CubicAngstrom; typedef Multiply::type SquaredAngstrom; typedef Shift::type Liter; typedef Divide::type GramPerCubicCentimeter; typedef Shift::type Micron; template inline typename Exchange, Kilocalorie, Joule, 4>::type convert_Cal_to_J(Unit i) { typedef typename Exchange, Kilocalorie, Joule, 4>::type Return; return Return(i.get_exponential_value() * JOULES_PER_KILOCALORIE); } template inline typename Exchange, Joule, Kilocalorie, -3>::type convert_J_to_Cal(Unit i) { typedef typename Exchange, Joule, Kilocalorie, -3>::type Return; return Return(i.get_exponential_value() / JOULES_PER_KILOCALORIE); } //! Marker constant to handle coversions extern const IMPKERNELEXPORT internal::AtomsPerMol ATOMS_PER_MOL; typedef Unit KilocaloriePerMol; typedef Unit KilocaloriePerAngstromPerMol; inline Unit operator/(KilocaloriePerMol k, internal::AtomsPerMol) { return Unit(k.get_value()*1.661); } inline Unit operator/(KilocaloriePerAngstromPerMol k, internal::AtomsPerMol) { return Unit(k.get_value()*1.661); } template inline KilocaloriePerMol operator*(Unit k, internal::AtomsPerMol) { return KilocaloriePerMol(k.get_exponential_value() *NA); } template inline KilocaloriePerAngstromPerMol operator*(Unit k, internal::AtomsPerMol) { return KilocaloriePerAngstromPerMol(k.get_exponential_value() *NA*ExponentialNumber<-10>(1)); } template inline KilocaloriePerMol operator*(internal::AtomsPerMol, Unit k) { return operator*(k, ATOMS_PER_MOL); } template inline KilocaloriePerAngstromPerMol operator*(internal::AtomsPerMol, Unit /*typename YoctoKilocaloriePerAngstrom::Units>*/ k) { return operator*(k, ATOMS_PER_MOL); } // define moles typedef Unit Molar; typedef Unit Micromolar; template inline Molar molarity_from_count(double count, Unit volume) { Unit > per_cubic_meter(unit::ExponentialNumber<0>(count)/volume); typedef Inverse::type PerCubicMeter; PerCubicMeter moles_per_cubic_meter(per_cubic_meter/NA); typedef Inverse::type PerLiter; PerLiter moles_per_liter= moles_per_cubic_meter; return Molar(moles_per_liter.get_value()); } template inline Unit > density_from_molarity(Unit molar) { Unit > count_per_liter(molar.get_exponential_value()*NA); return count_per_liter*1000.0; } // define Daltons typedef Unit Dalton; typedef Unit Kilodalton; template inline Unit convert_to_mks(Unit d) { return Unit(d.get_value()/NA.get_value()); } template inline Unit convert_to_Dalton(Unit d) { return Unit(d.get_value()*NA.get_value()); } template inline double strip_units(Unit u) { return u.get_value(); } } // namespace unit } // namespace internal namespace unit= internal::unit; IMPKERNEL_END_NAMESPACE #endif /* IMPKERNEL_UNITS_H */