
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 : http://en.wikipedia.org/wiki/English_unit
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