boost::units - converting from one derived_dimension to another across systems (imperial to metric)

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

boost::units - converting from one derived_dimension to another across systems (imperial to metric)

Boost - Users mailing list
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-----------------------------------------------------

//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
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: boost::units - converting from one derived_dimension to another across systems (imperial to metric)

Boost - Users mailing list
On Tue, Nov 20, 2018 at 8:47 PM Matt Vinson via Boost-users
<[hidden email]> 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
> [hidden email]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: boost::units - converting from one derived_dimension to another across systems (imperial to metric)

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
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
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users