0

I need to find volume through area times the height in mm^3. The problem in area, it must be in mm^2 but boost doesn't have such built-in option, so I need to make this unit (with make_scaled_unit I suppose). I tried to do it like it was shown in this answer and in the boost documentation but I get error in quantity.hpp of boost library:

C2338 (is_implicitly_convertible<Unit2,unit_type>::value == true).

and a message see reference to function template instantiation with huge type names that I completely don't understand. How do I fix this properly?

Here is the code with my attempts to make it work

    #include <iostream>
    #include <boost/units/systems/si/volume.hpp>
    #include <boost/units/systems/si/mass.hpp>
    #include "string"
    #include <boost/units/systems/si/io.hpp>
    #include <boost/units/systems/si/prefixes.hpp>
    #include <boost/units/systems/angle/degrees.hpp>
    #include <cmath>
    
    using namespace boost::units;
    using namespace boost::units::si;
    using Volume = boost::units::quantity<boost::units::si::volume>;
    using Square = boost::units::quantity<boost::units::area_dimension>;

    // like in stackoverflow answer
    namespace extended_area_names {
    namespace squared_millimeters_system
    {
        // "area" is not a base unit
        typedef make_scaled_unit<area, scale<10, static_rational<-6>>>::type millimeter_unit;
        typedef make_system<millimeter_unit>::type system;
        typedef unit<area_dimension, system> area;

        BOOST_UNITS_STATIC_CONSTANT(squared_millimeter, area);
        BOOST_UNITS_STATIC_CONSTANT(squared_millimeters, area);
    } // namespace squared_millimeters_system

    typedef quantity<squared_millimeters_system::area> quantity_area_square_millimeter;
    using squared_millimeters_system::squared_millimeter;
    using squared_millimeters_system::squared_millimeters;
    } // namespace extended_area_names

        // like in boost documentation, I use only one of these per try
    typedef make_scaled_unit<area, scale<10, static_rational<-6>>>::type millimeter_unit;

    Volume ContentVolume(std::string tankType, double contentLevel_raw, double tankHeight_raw, double tankDiameter_raw)
    {
    quantity<length> contentLevel(contentLevel_raw * milli * meters);
    quantity<length> tankHeight(tankHeight_raw * milli * meters);
    quantity<length> tankDiameter(tankDiameter_raw * milli * meters);
    quantity<length> tankRadius = tankDiameter / 2.0;
    Volume tankVolume(3.1415 * (tankRadius * tankRadius) * tankHeight);
    Volume contentVolume;


    using namespace extended_area_names;

    quantity
        <unit<plane_angle_dimension, degree::system>
        > sectorAngle(2 * acos((tankRadius - tankHeight) / tankRadius)
            * degree::degree);

    quantity<millimeter_unit> sectorSquare(
        (sectorAngle.value() * (tankRadius.value() * tankRadius.value()) / 2.0)
        * square_meter);

    quantity<length> triangleBase(
        sqrt(
            (tankRadius.value() * tankRadius.value()) -
            ((tankRadius.value() - tankHeight.value()) *
                (tankRadius.value() - tankHeight.value())))
        * milli * meters);

    quantity<length> p(
        (tankRadius + tankRadius + triangleBase) / 2.0);

    quantity<millimeter_unit> triangleSquare(
        sqrt(
            p.value() *
            (p.value() - tankRadius.value()) *
            (p.value() - tankRadius.value()) *
            (p.value() - triangleBase.value()))
        * square_meter);

    // the message says the problem is here
    contentVolume = (sectorSquare - triangleSquare) * tankHeight;

    return contentVolume; //m^3
    }
    }
    }
wohlstad
  • 12,661
  • 10
  • 26
  • 39

1 Answers1

0

boost doesn't have such built-in option

As I found out, actually there is. All you need is to use <boost/units/systems/si/prefixes.hpp> library, then construction like

quantity<area> example(2.0 * milli * milli * square_meters)

will work just fine. But I must say, that on any output it will print something like 2e-06 m^2, so in case you need to also change output this method won't work for you. Hope this'll help anyone encountered same problem