 Boost :

From: Matthias Schabel (boost_at_[hidden])
Date: 2007-03-26 18:14:45

Phil,

Thanks for taking a look.

> The units of the heat transfer coefficient are W C^-1 m^-2. As far
> as I was able to see, I was not able to write anything like
>
> typedef quantity<power/temperature/area> heat_transfer_coefficient_t;

If your compiler supports native typeof, you can just write this:

typedef typeof(watts/kelvin/pow<2>(meter))
heat_transfer_coefficient_unit_type;

typedef quantity<heat_transfer_coefficient_unit_type>
heat_transfer_coefficient_t;

> Rather, it was necessary for me to reduce W C^-1 m^-2 to basic
> dimensions manually. This is not easy for me. I have to remember
> phyics that I

If and when auto type deduction becomes a reality in C++, this will
all become much simpler. For the meantime, you can either use the
typeof trick above or you can compute the unit in a small test
program like this :

std::cout << watts/kelvin/pow<2>(meter) << std::endl;

to get the units :

kg s^(-3) K^(-1)

> so I concluded that the dimensions of power are mass length time^-3
> and hence of heat transfer coefficient are mass time^-3
> temperature^-1 length^-1, and wrote this:

Congrats - you got it right. Here's a complete program that does what
you want (to this point, anyway) :

#include <iostream>

#include <boost/units/io.hpp>
#include <boost/units/unit.hpp>
#include <boost/units/quantity.hpp>
#include <boost/units/systems/si.hpp>

using namespace boost::units;
using namespace boost::units::SI;

typedef quantity<power> power_t;
typedef quantity<area> area_t;
typedef quantity<temperature> temp_diff_t;

typedef typeof(watts/kelvin/pow<2>(meter))
heat_transfer_coefficient_unit_type;

typedef quantity<heat_transfer_coefficient_unit_type>
heat_transfer_coefficient_t;

int main()
{
const heat_transfer_coefficient_t
watts_per_square_meter_per_kelvin = 1.0*watts/square_meter/kelvin;

std::cout << heat_transfer_coefficient_unit_type() << std::endl
<< watts_per_square_meter_per_kelvin << std::endl
<< std::endl;

return 0;
}

outputting

kg s^(-3) K^(-1)
1 kg s^(-3) K^(-1)

> typedef composite_dimension<mass_tag,
> 1,time_tag,-3,temperature_tag,-1,length_tag,-1>
> heat_transfer_coefficient_t;

This is the correct dimension. You need to associate it with a unit
system to get a unit :

typedef unit<heat_transfer_coefficient_t,SI::system> si_htc_unit_t;

> Defining the unit was easier:
>
> const heat_transfer_coefficient_t watts_per_square_meter_per_celcis
> = watts / square_meter / kelvin;
>
> But this fails to compile, with this error:

<snip>

You tried to assign a unit to a quantity; quantities can be expressed
as value_type*unit, so what you want to do is

const quantity<si_htc_unit_t> watts_per_square_meter_per_celcius =
7.4*watts/square_meter/kelvin;

> For this library to be useful for me, it needs to be quick to learn
> and easy to apply. Working only with the included units it does
> look like it would work reasonably well, but in the situation I
> have described above it was quickly obvious that it was taking more
> effort to apply it to my program than the benefit that would result.

All I can say is that dimensional analysis and units is more
complicated than it seems it ought to be... Compiler support for
typeof and auto or emulation using Boost.Typeof goes a long way to
simplify things. I am also happy to add more commonly used units to
the library as they crop up...

> 1. What is the effect on compile time? I used #if to switch
> between units and plain floats.

Since the work is done with metaprogramming on lists, the overhead
depends on how numerous and how complex the units used are. Steven's
work on the implementation side has made, I believe, the compile
times quite manageable for the examples we present, even those that
use many different units.

> 2. Is there any increase in object file size? I know there
> shouldn't be, but it would be interesting to know for sure.

Steven seems to have addressed this.

> 3. Are the error messages comprehensible? The one show above is
> not great, but it could have been worse; there are some Boost
> libraries which I find unusable because of the volumne and
> inpenetrability of the error messages that result from a simple
> typo (though the compiler must share the blame for this).

We've done what we could to make error messages occur near the point
of the actual error and be as reasonable as possible, but, as with
most template metaprogramming code, errors can't really be described
as terse. If you're doing a lot of programming with units, they begin
to become easier to decipher...

> - "io" is a misnomer since it only does output, as far as I can see.

Good point. We'll have to think of a better name, I guess...

> - I tend to refer to temperature differences in Celcius, rather
> than Kelvin. There is an obvious issue when dealing with absolute
> temperatures though.

Take a look at unit_example_20 - this deals specifically with the
absolute/relative temperature conversion issue...

> - Please don't call the units used in the U.S. "English" units.
> Here in England, we use the S.I. system for everything except pints
> of beer and miles on roadsigns. The units that we did use here
> until about 50 years ago were not the same as the ones that the
> Americans use.

In boost/units/systems/other/non_si_units.hpp I have included
conversion factors for Imperial units (the ones used in the recent
past in England), US Customary units, US Survey units, nautical
units, some non-SI metric units, etc... English units generally refer
to heterogeneous and obsolete units, while Imperial and US Customary
are the main non-SI systems still in some use... See here, also :

> I hope this helps. I will not express an opinion about whether the
> library should be included; I leave that to people who have made
> more progress with it.

Thank you for your input and comments. If you do find some more time
to work with it, I would certainly appreciate any additional input
you might have.

Matthias