[units] conversion_factor in the two directions

Hi, I managed to make CONVERSION_FACTOR definitions to work between to unit systems (atomic and SI). I definied atomic system by following the si example. I can manage to transform lengths (probably because they are base dimensions in both systems, but when I try to do the same for energies (that is a base_dimension only in the atomic system) I can't compile the line with the declaration "en3". The first question is why the first ...CONVERSION_FACTOR doesn't work in the two directions (as it did for lengths). second, why the second ...CONVERSION_FACTOR doesn't help to compile en3. BOOST_UNITS_DEFINE_CONVERSION_FACTOR( atomic::hartree_energy_base_unit, si::energy, double, 4.359744e-18 ); //compiles but doesn't help for en3 BOOST_UNITS_DEFINE_CONVERSION_FACTOR( si::energy, atomic::hartree_energy_base_unit, double, 1./4.359744e-18 ); int main(){ quantity<si::length> l1(1.*si::meter); //works quantity<si::length> l2(1.*atomic::bohr); //works quantity<atomic::length> l3(1.*atomic::bohr); //works quantity<atomic::length> l4(1.*si::meter); //works quantity<si::energy> en1(1.*si::joules); //works quantity<si::energy> en2(1.*atomic::hartree); //works quantity<atomic::energy> en3(1.*atomic::hartree); //work quantity<atomic::energy> en4(1.*si::joules); //does not work, compilation error return 0; } Thank you, Alfredo

AMDG alfC wrote:
I managed to make CONVERSION_FACTOR definitions to work between to unit systems (atomic and SI). I definied atomic system by following the si example. I can manage to transform lengths (probably because they are base dimensions in both systems, but when I try to do the same for energies (that is a base_dimension only in the atomic system) I can't compile the line with the declaration "en3".
The first question is why the first ...CONVERSION_FACTOR doesn't work in the two directions (as it did for lengths). second, why the second ...CONVERSION_FACTOR doesn't help to compile en3.
BOOST_UNITS_DEFINE_CONVERSION_FACTOR( atomic::hartree_energy_base_unit, si::energy, double, 4.359744e-18 );
//compiles but doesn't help for en3 BOOST_UNITS_DEFINE_CONVERSION_FACTOR( si::energy, atomic::hartree_energy_base_unit, double, 1./4.359744e-18 );
This should not compile. I'll look into it. You probably need to fragment it into SI base units. If you could provide either the error message, or even better, the definition of the atomic system, I could help more.
int main(){ quantity<si::length> l1(1.*si::meter); //works quantity<si::length> l2(1.*atomic::bohr); //works quantity<atomic::length> l3(1.*atomic::bohr); //works quantity<atomic::length> l4(1.*si::meter); //works
quantity<si::energy> en1(1.*si::joules); //works quantity<si::energy> en2(1.*atomic::hartree); //works quantity<atomic::energy> en3(1.*atomic::hartree); //work quantity<atomic::energy> en4(1.*si::joules); //does not work, compilation error return 0; }
In Christ, Steven Watanabe

This should not compile. I'll look into it. You probably need to fragment it into SI base units.
yes I was thinking something like that, like creating an si::energy_base_unit but then it will be full of base units if I do it this for every dimension. Besides it worked in one direction.
If you could provide either the error message, or even better, the definition of the atomic system, I could help more.
this is gcc 4.4.1, boost-1.40 error messages, atomic.hpp and main.cpp are attached below. Thank you, Alfredo ---begin error message ----------------------------------- In file included from /usr/include/boost/units/conversion.hpp:14, from /usr/include/boost/units/quantity.hpp:29, from eos.cpp:7: /usr/include/boost/units/detail/conversion_impl.hpp: In instantiation of ‘boost::units::detail::conversion_impl<1>::apply<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::si::second_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::atomic::hartree_energy_base_unit, boost::units::dimensionless_type> > > > >’: /usr/include/boost/units/detail/conversion_impl.hpp:445: instantiated from ‘boost::units::detail::conversion_factor_helper<boost::units::unit<boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::si::second_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type>
, void>, boost::units::unit<boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::si::meter_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::static_rational<1l, 2l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::atomic::hartree_energy_base_unit, boost::units::static_rational<-0x00000000000000001l, 2l> >, boost::units::dimensionless_type> > >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> , void> >’ /usr/include/boost/units/detail/conversion_impl.hpp:274: instantiated from ‘boost::units::detail::call_base_unit_converter_impl<false>::apply<boost::units::si::second_base_unit, boost::units::unit<boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::si::meter_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::static_rational<1l, 2l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::atomic::hartree_energy_base_unit, boost::units::static_rational<-0x00000000000000001l, 2l> >, boost::units::dimensionless_type> > >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> , void> >’ /usr/include/boost/units/detail/conversion_impl.hpp:289: instantiated from ‘boost::units::detail::call_base_unit_converter<boost::units::si::second_base_unit, boost::units::unit<boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::si::meter_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::static_rational<1l, 2l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::atomic::hartree_energy_base_unit, boost::units::static_rational<-0x00000000000000001l, 2l> >, boost::units::dimensionless_type> > >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> , void> >’ /usr/include/boost/units/detail/conversion_impl.hpp:316: instantiated from ‘boost::units::detail::conversion_impl<1>::apply<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::si::second_base_unit, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type>, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::atomic::hartree_energy_base_unit, boost::units::dimensionless_type> > > > >’ /usr/include/boost/units/detail/conversion_impl.hpp:316: instantiated from ‘boost::units::detail::conversion_impl<2>::apply<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::si::second_base_unit, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> >, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::atomic::hartree_energy_base_unit, boost::units::dimensionless_type> > > > >’ /usr/include/boost/units/detail/conversion_impl.hpp:316: instantiated from ‘boost::units::detail::conversion_impl<3>::apply<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::si::meter_base_unit, boost::units::static_rational<2l, 1l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::si::second_base_unit, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> > >, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::atomic::hartree_energy_base_unit, boost::units::dimensionless_type> > > > >’ /usr/include/boost/units/detail/conversion_impl.hpp:445: instantiated from ‘boost::units::detail::conversion_factor_helper<boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<2l, 1l> >, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> > >, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::si::meter_base_unit, boost::units::static_rational<2l, 1l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::si::second_base_unit, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> > >, boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<2l, 1l> >, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> > >, boost::units::dimensionless_type> >, void>, boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<2l, 1l> >, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> > >, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::atomic::hartree_energy_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<2l, 1l> >, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> > >, boost::units::dimensionless_type> >, void> >’ /usr/include/boost/units/detail/conversion_impl.hpp:40: instantiated from ‘boost::units::detail::conversion_factor_helper<boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<2l, 1l> >, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> > >, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > >, void>, boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<2l, 1l> >, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> > >, boost::units::homogeneous_system<boost::units::list<boost::units::atomic::electron_mass_base_unit, boost::units::list<boost::units::atomic::bohr_radius_base_unit, boost::units::list<boost::units::atomic::elementary_charge_base_unit, boost::units::list<boost::units::atomic::reduced_planck_constant_base_unit, boost::units::list<boost::units::atomic::hartree_energy_base_unit, boost::units::dimensionless_type> > > > > >, void> >’ /usr/include/boost/units/detail/conversion_impl.hpp:345: instantiated from ‘static boost::units::quantity<Unit2, T2> boost::units::conversion_helper<boost::units::quantity<Unit1, T1>, boost::units::quantity<Unit2, T2> >::convert(const boost::units::quantity<Unit1, T1>&) [with Unit1 = boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<2l, 1l> >, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> > >, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > >, void>, T1 = double, Unit2 = boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<2l, 1l> >, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> > >, boost::units::homogeneous_system<boost::units::list<boost::units::atomic::electron_mass_base_unit, boost::units::list<boost::units::atomic::bohr_radius_base_unit, boost::units::list<boost::units::atomic::elementary_charge_base_unit, boost::units::list<boost::units::atomic::reduced_planck_constant_base_unit, boost::units::list<boost::units::atomic::hartree_energy_base_unit, boost::units::dimensionless_type> > > > > >, void>, T2 = double]’ /usr/include/boost/units/quantity.hpp:193: instantiated from ‘boost::units::quantity<Unit, Y>::quantity(const boost::units::quantity<Unit2, YY>&, typename boost::disable_if<boost::mpl::and_<typename boost::units::is_implicitly_convertible<Unit2, Unit>::type, boost::units::detail::is_non_narrowing_conversion<YY, Y>, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >, typename boost::units::detail::disable_if_is_same<Unit, Unit2>::type>::type*) [with Unit2 = boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<2l, 1l> >, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> > >, boost::units::homogeneous_system<boost::units::list<boost::units::si::meter_base_unit, boost::units::list<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::list<boost::units::si::second_base_unit, boost::units::list<boost::units::si::ampere_base_unit, boost::units::list<boost::units::si::kelvin_base_unit, boost::units::list<boost::units::si::mole_base_unit, boost::units::list<boost::units::si::candela_base_unit, boost::units::list<boost::units::angle::radian_base_unit, boost::units::list<boost::units::angle::steradian_base_unit, boost::units::dimensionless_type> > > > > > > > > >, void>, YY = double, Unit = boost::units::unit<boost::units::list<boost::units::dim<boost::units::length_base_dimension, boost::units::static_rational<2l, 1l> >, boost::units::list<boost::units::dim<boost::units::mass_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<-0x00000000000000002l, 1l> >, boost::units::dimensionless_type> > >, boost::units::homogeneous_system<boost::units::list<boost::units::atomic::electron_mass_base_unit, boost::units::list<boost::units::atomic::bohr_radius_base_unit, boost::units::list<boost::units::atomic::elementary_charge_base_unit, boost::units::list<boost::units::atomic::reduced_planck_constant_base_unit, boost::units::list<boost::units::atomic::hartree_energy_base_unit, boost::units::dimensionless_type> > > > > >, void>, Y = double]’ eos.cpp:89: instantiated from here /usr/include/boost/units/detail/conversion_impl.hpp:316: error: no type named ‘type’ in ‘struct boost::units::detail::call_base_unit_converter<boost::units::si::second_base_unit, boost::units::unit<boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::heterogeneous_system<boost::units::heterogeneous_system_impl<boost::units::list<boost::units::heterogeneous_system_dim<boost::units::si::meter_base_unit, boost::units::static_rational<1l, 1l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::scaled_base_unit<boost::units::cgs::gram_base_unit, boost::units::scale<10l, boost::units::static_rational<3l, 1l> > >, boost::units::static_rational<1l, 2l> >, boost::units::list<boost::units::heterogeneous_system_dim<boost::units::atomic::hartree_energy_base_unit, boost::units::static_rational<-0x00000000000000001l, 2l> >, boost::units::dimensionless_type> > >, boost::units::list<boost::units::dim<boost::units::time_base_dimension, boost::units::static_rational<1l, 1l> >, boost::units::dimensionless_type>, boost::units::dimensionless_type> , void> >’ compilation terminated due to -Wfatal-errors. ---end error message --------------------------------
---begin atomic.hpp--------------------------------------------------------------------------------------------------------------------------------- #include <boost/units/base_unit.hpp> //equivalent to includes in units/systems/si/base.hpp #include <boost/units/static_constant.hpp> #include <boost/units/unit.hpp> #include <boost/units/make_system.hpp> //#include <boost/units/io.hpp> //do not remove: '...has initializer but incomplete type...' error //equivalent to includes in //equivalent to ./base_units/si/*.hpp #include <boost/units/config.hpp> #include <boost/units/base_unit.hpp> #include <boost/units/scaled_base_unit.hpp> #include <boost/units/physical_dimensions/mass.hpp> #include <boost/units/physical_dimensions/length.hpp> #include <boost/units/physical_dimensions/mass.hpp> #include <boost/units/physical_dimensions/electric_charge.hpp> #include <boost/units/physical_dimensions/angular_momentum.hpp> #include <boost/units/physical_dimensions/energy.hpp> //equivalent to ./base_units/si/*.hpp namespace boost{ namespace units{ namespace atomic{ //define namespace au=boost::units::atomic if necessary using std::string; // taken from http://en.wikipedia.org/wiki/Atomic_units#Fundamental_units struct electron_mass_base_unit : base_unit<electron_mass_base_unit, mass_dimension, 1>{ static string name() {return ("electron_mass");} static string symbol() {return ("me");} }; //equivalent to ./base_units/si/meter.hpp> struct bohr_radius_base_unit : base_unit<bohr_radius_base_unit, length_dimension, 2>{ static string name() {return ("bohr_radius");} static string symbol() {return ("a0");} }; struct elementary_charge_base_unit : base_unit<elementary_charge_base_unit, electric_charge_dimension, 3>{ static string name() {return ("elementary_charge");} static string symbol() {return ("e");} }; struct reduced_planck_constant_base_unit : base_unit<reduced_planck_constant_base_unit, angular_momentum_dimension, 4>{ static string name() {return ("reduced_planck_constant");} static string symbol() {return ("hbar");} }; struct hartree_energy_base_unit : base_unit<hartree_energy_base_unit, energy_dimension, 5>{ static string name() {return ("hartree_energy");} static string symbol() {return ("Eh");} }; }}}//nss //similar to ./systems/si/base.hpp namespace boost{ namespace units{ namespace atomic{ typedef make_system< electron_mass_base_unit, bohr_radius_base_unit, elementary_charge_base_unit, reduced_planck_constant_base_unit, hartree_energy_base_unit >::type system; }}} //equivalent to units/systems/si/.*.hpp namespace boost{ namespace units{ namespace atomic{ typedef unit<dimensionless_type, system> dimensionless; typedef unit<mass_dimension, system> mass; typedef unit<length_dimension, system> length; typedef unit<electric_charge_dimension, system> electric_charge; typedef unit<angular_momentum_dimension,system> angular_momentum; typedef unit<energy_dimension, system> energy; static const mass electron_mass; static const length bohr_radius, bohr; static const electric_charge elementary_charge; static const angular_momentum reduced_planck_constant; static const energy hartree_energy, hartree; }}} #include<boost/units/physical_dimensions.hpp> //derived, equiv for example to units/systems/si/area.hpp namespace boost{ namespace units{ namespace atomic{ typedef unit<area_dimension, system> area; typedef unit<volume_dimension, system> volume; typedef unit<pressure_dimension, system> pressure; }}} ---end atomic.hpp ---begin main.cpp------------------------------------------------------------------------------------------------------------------------------------- #include<boost/units/quantity.hpp> #include<boost/units/io.hpp> #include<boost/units/systems/si.hpp> #include<boost/units/systems/si/io.hpp> //helps transforms the output from kg/m/s^2 to J #include<boost/units/systems/si/prefixes.hpp> #include<boost/units/systems/cgs.hpp> #include<boost/units/scale.hpp> #include<boost/units/pow.hpp> #include"boost/units/atomic.hpp" //#include <boost/units/systems/si/io.hpp> #include<iostream> #include"boost/units/base_units/metric/angstrom.hpp" namespace boost{ namespace units{ namespace metric{ typedef metric::angstrom_base_unit::unit_type angstrom_unit; BOOST_UNITS_STATIC_CONSTANT(angstrom, angstrom_unit); }}} /* namespace boost { namespace units { typedef metric::angstrom_base_unit::unit_type angstrom_unit; BOOST_UNITS_STATIC_CONSTANT(angstrom, angstrom_unit); typedef scaled_base_unit< si::meter_base_unit, scale<10, static_rational<-9> > > nanometer_base_unit; typedef nanometer_base_unit::unit_type nanometer_unit; BOOST_UNITS_STATIC_CONSTANT(nanometer, nanometer_unit); // typedef make_scaled_unit<si::length, scale<10, static_rational<-9> > >::type nanometer; } } // namespace boost::units */ using std::clog; using std::endl; using namespace boost::units; class vinet{ public: class parameters{ public: quantity<atomic::volume> v0; //volume quantity<atomic::energy> phi0; }; }; BOOST_UNITS_DEFINE_CONVERSION_FACTOR( atomic::bohr_radius_base_unit, metric::angstrom_base_unit, double, 0.529177209 ); #include<boost/units/systems/si/energy.hpp> BOOST_UNITS_DEFINE_CONVERSION_FACTOR( atomic::hartree_energy_base_unit, si::energy, double, 4.359744e-18 ); //compiles but doesn't help for en3 BOOST_UNITS_DEFINE_CONVERSION_FACTOR( si::energy, atomic::hartree_energy_base_unit, double, 1./4.359744e-18 ); int main(){ quantity<si::length> l1(1.*si::meter); //works quantity<si::length> l2(1.*atomic::bohr); //works quantity<atomic::length> l3(1.*atomic::bohr); //works quantity<atomic::length> l4(1.*si::meter); //works quantity<si::energy> en1(1.*si::joules); //works quantity<si::energy> en2(1.*atomic::hartree); //works quantity<atomic::energy> en3(1.*atomic::hartree); //work quantity<atomic::energy> en4(1.*si::joules); //does not work, compilation error return 0; } ---end main.cpp

AMDG alfC wrote:
This should not compile. I'll look into it. You probably need to fragment it into SI base units.
yes I was thinking something like that, like creating an si::energy_base_unit but then it will be full of base units if I do it this for every dimension. Besides it worked in one direction.
If you could provide either the error message, or even better, the definition of the atomic system, I could help more.
this is gcc 4.4.1, boost-1.40 error messages, atomic.hpp and main.cpp are attached below.
What you're missing is the conversion from s to m kg^-1 Eh^-1/2. (I think the conversion factor should be sqrt(4.359744e-18)) You could also make it work by adding BOOST_UNITS_DEFAULT_CONVERSION( atomic::hartree_energy_base_unit, si::energy ); In Christ, Steven Watanabe

What you're missing is the conversion from s to m kg^-1 Eh^-1/2. (I think the conversion factor should be sqrt(4.359744e-18))
you probably mean s to m kg^1/2 Eh^-1/2 and yes that is the conversion factor. Now, I have no idea what would be the syntax to transform from second to something with combined units BOOST_UNITS_DEFINE_CONVERSION_FACTOR( si::second, ???, double, sqrt(4.359744e-18) );
You could also make it work by adding BOOST_UNITS_DEFAULT_CONVERSION( atomic::hartree_energy_base_unit, si::energy );
that worked right away. What would be the drawback of using DEFAULT_CONVERSION macro? loss of precision perhaps? Thank you, Alfredo

that worked right away. What would be the drawback of using DEFAULT_CONVERSION macro? loss of precision perhaps?
actually, the question is more profound, from the design of the library it seems that you were very careful not to make any transformation automatically because loss of precision. If that is the case I would like to follow your design principle. On the other hand, even if I want to work in atomic units (motivated by the order of magnitudes of the quantities) it is inevitable to output some of the results in SI. The question is does it make sense to have this transformation from Hartree to Joule with such an huge exponent. Following your design, would it be better to have a conversion from Hartree to some scaled unit of Joule (femtoJoule) instead, so all the machine number have small exponents? Alfredo

AMDG alfC wrote:
that worked right away. What would be the drawback of using DEFAULT_CONVERSION macro? loss of precision perhaps?
actually, the question is more profound, from the design of the library it seems that you were very careful not to make any transformation automatically because loss of precision.
The idea is that you can specify as many direct conversions as you want, and the library will use the default one only if it can't find the one it really wants. In fact, we use DEFAULT_CONVERSION for most of the non-SI units.
If that is the case I would like to follow your design principle. On the other hand, even if I want to work in atomic units (motivated by the order of magnitudes of the quantities) it is inevitable to output some of the results in SI. The question is does it make sense to have this transformation from Hartree to Joule with such an huge exponent.
It's probably okay. double can handle values up to about 10^300
Following your design, would it be better to have a conversion from Hartree to some scaled unit of Joule (femtoJoule) instead, so all the machine number have small exponents?
I'm not a floating point expert, but if you're just doing the conversion for output, it probably doesn't matter. In Christ, Steven Watanabe
participants (2)
-
alfC
-
Steven Watanabe