boost::units - converting from one derived_dimension to another across systems (imperial to metric)
degski: I do not think am making the "nauseam" mistake. My issue is using Boost.Units correctly which I concede is difficult for me but I am reading the docs and trying to get it. In our field of engineering, we use Kg as a force; not a mass. (We also use pound as a force; not a mass - for your "UK's Weights and Measures Act 1963" counterpart). That said, I should not have made the mistake of using Kg as a force in Boost.Units, it's true. Shame on me. My task is to convert between lineal forces: k/ft, k/in, lb/ft, lb/in, kN/m, kN/cm, kN/m, N/m, N/cm, N/m, Metric ton/m, Metric ton/cm, Metric ton/mm, Kg/m, Kg/cm, Kg/mm. These are all force/length. Steven Watanabe: Thank you, again.#1: I was not trying to say it's wrong; sorry. Just that I did not see 'length' and opted for the one that did. The unit's are correct, as you say. #2: This is an error to start with Kg(force)/meter. I can start with N/meter. I've changed this variable name to newton_per_meter and the conversion factors. *.h----------------------------------------------------- namespace dimensional_analysis{ typedef boost::units::length_base_dimension::dimension_type length_dimension; typedef boost::units::mass_base_dimension::dimension_type mass_dimension; typedef boost::units::make_system<boost::units::us::inch_base_unit,boost::units::us::pound_base_unit>::type ip_system; namespace lineal_force { typedef boost::mpl::divides<boost::units::force_dimension,boost::units::length_dimension>::type lineal_force_dimension; namespace imperial { //////////////// ////lb/in, right? ////boost::units::force_dimension =pound ////boost::units::length_dimension = in //////////////// typedef boost::units::unit<lineal_force_dimension,lengths::ip_system> lineal_force_unit; } namespace si { //////////////// ////N/m, right? ////boost::units::force_dimension = newton ////boost::units::length_dimension = meter //////////////// typedef boost::units::unit<lineal_force_dimension,boost::units::si::system> lineal_force_unit; } }//lineal_force }//dimensional_analysis *.cpp----------------------------------------------------- //Imperiallb/in to SI N/m BOOST_UNITS_DEFINE_CONVERSION_FACTOR( dimensional_analysis::lineal_force::imperial::lineal_force_unit, dimensional_analysis::lineal_force::si::lineal_force_unit, double, 175.1268369864); // exact conversion BOOST_UNITS_DEFAULT_CONVERSION( dimensional_analysis::lineal_force::imperial::lineal_force_unit, dimensional_analysis::lineal_force::si::lineal_force_unit); //SI N/mto Imperial lb/in BOOST_UNITS_DEFINE_CONVERSION_FACTOR( dimensional_analysis::lineal_force::si::lineal_force_unit, dimensional_analysis::lineal_force::imperial::lineal_force_unit, double, 0.1837185501); // exact conversion BOOST_UNITS_DEFAULT_CONVERSION( dimensional_analysis::lineal_force::si::lineal_force_unit, dimensional_analysis::lineal_force::imperial::lineal_force_unit); //Imperialto SI. This should convert lb/in to N/m andreturn 175.1268369864(N/m) //But itdoes not. Its converting lb (mass) to Kg(mass), 0.454 const auto t2 = static_cast<boost::units::quantity<dimensional_analysis::lineal_force::si::lineal_force_unit>>( 1.0 *dimensional_analysis::lineal_force::imperial::lineal_force_unit::unit_type()); //Again, Imperial to SI. This should convert lb/in to N/m and return 175.1268369864 (N/m) //But itdoes not. It returns lb (mass) to Kg(mass) const auto t3 = boost::units::conversion_factor( dimensional_analysis::lineal_force::imperial::lineal_force_unit::unit_type(), dimensional_analysis::lineal_force::si::lineal_force_unit::unit_type()); //SI toImperial. This should convert N/m tolb/in and return 0.1837185501 (lb/in) //But itdoes not. Its converting Kg (mass) to lb(mass), 2.205 const auto t1 = static_cast<boost::units::quantity<dimensional_analysis::lineal_force::imperial::lineal_force_unit>>( 1.0 *dimensional_analysis::lineal_force::si::lineal_force_unit::unit_type()); //So, I don’t know whythe library is converting mass; I’ve tuned it to use boost::units::force_dimension/boost::units::length_dimension //I am doing something wrongwhere the library is not using force/length. //Below does work, mainly. //This isconvert Si to SI and return value of 1.0 is correct. const auto t4 = static_cast<boost::units::quantity<dimensional_analysis::lineal_force::si::lineal_force_unit>>( 1.0 *boost::units::si::newton / boost::units::si::meter); //This convert lb/in to SI and return value is 175.1268369864 is correct. const auto t5 = static_cast<boost::units::quantity<dimensional_analysis::lineal_force::si::lineal_force_unit>>( 1.0 * boost::units::us::pound_force_base_unit::unit_type() / boost::units::us::inch_base_unit::unit_type()); //This converts lb/in to lb/in and return value is of 1.0 is correct. const auto t6 = static_cast<boost::units::quantity<dimensional_analysis::lineal_force::imperial::lineal_force_unit>>( 1.0 * boost::units::us::pound_force_base_unit::unit_type() / boost::units::us::inch_base_unit::unit_type()); //This is2.205 and not correct. //It’s notconverting SI-force/length to Imperial-force/length //Itsconverting Kg (mass) to lb (mass), 2.205 const auto t7 = static_cast<boost::units::quantity<dimensional_analysis::lineal_force::imperial::lineal_force_unit>>( 1.0 * boost::units::si::newton /boost::units::si::meter); //What have I done wrong? //Any help is appreciated.
On Tue, Nov 20, 2018 at 8:47 PM Matt Vinson via Boost-users <boost-users@lists.boost.org> wrote:
degski: I do not think am making the "nauseam" mistake. My issue is using Boost.Units correctly which I concede is difficult for me but I am reading the docs and trying to get it. In our field of engineering, we use Kg as a force; not a mass. (We also use pound as a force; not a mass - for your "UK's Weights and Measures Act 1963" counterpart). That said, I should not have made the mistake of using Kg as a force in Boost.Units, it's true. Shame on me. My task is to convert between lineal forces: k/ft, k/in, lb/ft, lb/in, kN/m, kN/cm, kN/m, N/m, N/cm, N/m, Metric ton/m, Metric ton/cm, Metric ton/mm, Kg/m, Kg/cm, Kg/mm. These are all force/length.
Coming from an energy oil and gas background applying Boost.Units, that's a difficult conversation to have especially when "units" are used, but in fact are masking certain details, magic numbers, etc, confounding their dimensions.
Steven Watanabe: Thank you, again. #1: I was not trying to say it's wrong; sorry. Just that I did not see 'length' and opted for the one that did. The unit's are correct, as you say. #2: This is an error to start with Kg(force)/meter. I can start with N/meter. I've changed this variable name to newton_per_meter and the conversion factors.
I can tell you this much; once you get reasonably proficient with Boost.Units, there is a strong compiler confidence in correctness once you have your dimensions, units, etc, meshing well together. By that I mean, in truth, compile time confidence. The compiler / Boost.Units will tell you when you have it wrong, and it will compile when you have it correct. That's a major plus in my book. Cheers, best of luck!
*.h-----------------------------------------------------
namespace dimensional_analysis {
typedef boost::units::length_base_dimension::dimension_type length_dimension;
typedef boost::units::mass_base_dimension::dimension_type mass_dimension;
typedef boost::units::make_system<boost::units::us::inch_base_unit,boost::units::us::pound_base_unit>::type ip_system;
namespace lineal_force {
typedef boost::mpl::divides<boost::units::force_dimension,boost::units::length_dimension>::type lineal_force_dimension;
namespace imperial {
////////////////
////lb/in, right?
////boost::units::force_dimension = pound
////boost::units::length_dimension = in
////////////////
typedef boost::units::unit<lineal_force_dimension,lengths::ip_system> lineal_force_unit;
}
namespace si {
////////////////
////N/m, right?
////boost::units::force_dimension = newton
////boost::units::length_dimension = meter
////////////////
typedef boost::units::unit<lineal_force_dimension,boost::units::si::system> lineal_force_unit;
}
}//lineal_force
}//dimensional_analysis
*.cpp-----------------------------------------------------
//Imperial lb/in to SI N/m
BOOST_UNITS_DEFINE_CONVERSION_FACTOR(
dimensional_analysis::lineal_force::imperial::lineal_force_unit,
dimensional_analysis::lineal_force::si::lineal_force_unit,
double,
175.1268369864); // exact conversion
BOOST_UNITS_DEFAULT_CONVERSION(
dimensional_analysis::lineal_force::imperial::lineal_force_unit,
dimensional_analysis::lineal_force::si::lineal_force_unit);
//SI N/m to Imperial lb/in
BOOST_UNITS_DEFINE_CONVERSION_FACTOR(
dimensional_analysis::lineal_force::si::lineal_force_unit,
dimensional_analysis::lineal_force::imperial::lineal_force_unit,
double,
0.1837185501); // exact conversion
BOOST_UNITS_DEFAULT_CONVERSION(
dimensional_analysis::lineal_force::si::lineal_force_unit,
dimensional_analysis::lineal_force::imperial::lineal_force_unit);
//Imperial to SI. This should convert lb/in to N/m and return 175.1268369864 (N/m)
//But it does not. Its converting lb (mass) to Kg (mass), 0.454
const auto t2 = static_cast<boost::units::quantity<dimensional_analysis::lineal_force::si::lineal_force_unit>>(
1.0 * dimensional_analysis::lineal_force::imperial::lineal_force_unit::unit_type());
//Again, Imperial to SI. This should convert lb/in to N/m and return 175.1268369864 (N/m)
//But it does not. It returns lb (mass) to Kg (mass)
const auto t3 = boost::units::conversion_factor(
dimensional_analysis::lineal_force::imperial::lineal_force_unit::unit_type(),
dimensional_analysis::lineal_force::si::lineal_force_unit::unit_type());
//SI to Imperial. This should convert N/m to lb/in and return 0.1837185501 (lb/in)
//But it does not. Its converting Kg (mass) to lb (mass), 2.205
const auto t1 = static_cast<boost::units::quantity<dimensional_analysis::lineal_force::imperial::lineal_force_unit>>(
1.0 * dimensional_analysis::lineal_force::si::lineal_force_unit::unit_type());
//So, I don’t know why the library is converting mass; I’ve tuned it to use boost::units::force_dimension/boost::units::length_dimension
//I am doing something wrong where the library is not using force/length.
//Below does work, mainly.
//This is convert Si to SI and return value of 1.0 is correct.
const auto t4 = static_cast<boost::units::quantity<dimensional_analysis::lineal_force::si::lineal_force_unit>>(
1.0 * boost::units::si::newton / boost::units::si::meter);
//This convert lb/in to SI and return value is 175.1268369864 is correct.
const auto t5 = static_cast<boost::units::quantity<dimensional_analysis::lineal_force::si::lineal_force_unit>>(
1.0 * boost::units::us::pound_force_base_unit::unit_type() / boost::units::us::inch_base_unit::unit_type());
//This converts lb/in to lb/in and return value is of 1.0 is correct.
const auto t6 = static_cast<boost::units::quantity<dimensional_analysis::lineal_force::imperial::lineal_force_unit>>(
1.0 * boost::units::us::pound_force_base_unit::unit_type() / boost::units::us::inch_base_unit::unit_type());
//This is 2.205 and not correct.
//It’s not converting SI-force/length to Imperial-force/length
//Its converting Kg (mass) to lb (mass), 2.205
const auto t7 = static_cast<boost::units::quantity<dimensional_analysis::lineal_force::imperial::lineal_force_unit>>(
1.0 * boost::units::si::newton / boost::units::si::meter);
//What have I done wrong?
//Any help is appreciated. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
AMDG On 11/20/2018 06:46 PM, Matt Vinson via Boost-users wrote:
<snip> <some reformatting to reduce line wrapping> *.h-----------------------------------------------------
namespace dimensional_analysis {
typedef length_base_dimension::dimension_type length_dimension; typedef mass_base_dimension::dimension_type mass_dimension;
typedef make_system<inch_base_unit,pound_base_unit>::type ip_system;
This should be pound_force_base_unit.
namespace lineal_force { typedef mpl::divides<force_dimension,length_dimension>::type lineal_force_dimension;
namespace imperial {
//////////////// ////lb/in, right?
////boost::units::force_dimension =pound ////boost::units::length_dimension = in //////////////// typedef unit<lineal_force_dimension,lengths::ip_system> lineal_force_unit;
This unit is nonsensical because the ip_system as written is unable to represent the lineal_force_dimension. That this doesn't give a hard compiler error is a bug in the library. Once you fix ip_system, the conversions should be right.
} namespace si { //////////////// ////N/m, right?
Yep.
////boost::units::force_dimension = newton ////boost::units::length_dimension = meter //////////////// typedef unit<lineal_force_dimension,si::system> lineal_force_unit; } }//lineal_force }//dimensional_analysis
*.cpp-----------------------------------------------------
//Imperiallb/in to SI N/m
The following conversion definitions are unnecessary and have no effect:
BOOST_UNITS_DEFINE_CONVERSION_FACTOR( dimensional_analysis::lineal_force::imperial::lineal_force_unit, dimensional_analysis::lineal_force::si::lineal_force_unit, double, 175.1268369864); // exact conversion
BOOST_UNITS_DEFAULT_CONVERSION( dimensional_analysis::lineal_force::imperial::lineal_force_unit, dimensional_analysis::lineal_force::si::lineal_force_unit);
//SI N/mto Imperial lb/in
BOOST_UNITS_DEFINE_CONVERSION_FACTOR( dimensional_analysis::lineal_force::si::lineal_force_unit, dimensional_analysis::lineal_force::imperial::lineal_force_unit, double, 0.1837185501); // exact conversion
BOOST_UNITS_DEFAULT_CONVERSION( dimensional_analysis::lineal_force::si::lineal_force_unit, dimensional_analysis::lineal_force::imperial::lineal_force_unit);
<snip>
In Christ, Steven Watanabe
participants (3)
-
Matt Vinson
-
Michael Powell
-
Steven Watanabe