nholthaus / units

a compile-time, header-only, dimensional analysis and unit conversion library built on c++14 with no dependencies.
http://nholthaus.github.io/units/
MIT License
952 stars 135 forks source link

Suggest adding two new units for molar mass and molar concentration #157

Open rsivek opened 6 years ago

rsivek commented 6 years ago

Currently the units::substance_unit is somewhat detached from the rest of the library (i.e. mole_t doesn't have any relationships to other units without adding custom types).

I suggest adding two new units to rectify this: molar mass and molar concentration.

My thoughts are these may be defined as follows:

units::substance_mass namespace containing molar_mass which is a compound type defined as compound_unit<mass::kilograms, substance::mole>.

and

units::substance_concentration namespace containing molar_concentration compound type defined as compound_unit<substance::moles, inverse<cubed<length::meter>>

Note that although these units are commonly expressed as g/mol and mol/L respectively, the above definitions are in accordance with their SI unit definitions.

In case you're wondering, I'm working on a physiology engine of sorts for which these units are particularly relevant. Existing physiological & pharmacological models often use these types of units (particularly molar concentration).

rsivek commented 6 years ago

Along the same lines, it may be prudent to define the molar mass constant in the units::constants namespace.

nholthaus commented 6 years ago

absolutely!

Thanks for providing your use-case, it definitely helps me prioritize the direction of the library. Substance is the black sheep of the library right now since most applications have been gaming, physics, or related to spacial processing like drones/self driving vehicles. Glad to see we're moving into chemistry and life sciences too.

rsivek commented 6 years ago

Here's how I ended up defining things in my modified version of units.h for now.

// ...
namespace category
{
// ...
        typedef base_unit<detail::meter_ratio<0>,   std::ratio<1>,  std::ratio<0>,  std::ratio<0>,  std::ratio<0>,  std::ratio<0>,  std::ratio<-1>>    substance_mass_unit;                 ///< Represents an SI base unit of substance mass
        typedef base_unit<detail::meter_ratio<-3>,  std::ratio<0>,  std::ratio<0>,  std::ratio<0>,  std::ratio<0>,  std::ratio<0>,  std::ratio<1>>       substance_concentration_unit;                  ///< Represents an SI base unit of substance concentration
// ...
}

// ...

    //-----------------------------------
    //  UNITS OF SUBSTANCE MASS
    //-----------------------------------

#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_SUBSTANCE_MASS_UNITS)
    UNIT_ADD(substance_mass, molar_mass, molar_mass, mol_mass, unit<std::ratio<1>, units::category::substance_mass_unit>)
    UNIT_ADD_WITH_METRIC_PREFIXES(substance_mass, gram_per_mole, grams_per_mole, g_per_mol, unit<std::ratio<1, 1000>, molar_mass>)

    UNIT_ADD_CATEGORY_TRAIT(substance_mass)
#endif

    //------------------------------------------------
    //  UNITS OF SUBSTANCE CONCENTRATION
    //------------------------------------------------

#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_SUBSTANCE_CONCENTRATION_UNITS)
    UNIT_ADD(substance_concentration, molar_concentration, molar_concentration, mol_conc, unit<std::ratio<1>, units::category::substance_concentration_unit>)
    UNIT_ADD_WITH_METRIC_PREFIXES(substance_concentration, mole_per_liter, moles_per_liter, mol_per_L, unit<std::ratio<1, 1000>, molar_concentration>)
    UNIT_ADD(substance_concentration, mole_per_milliliter, moles_per_milliliter, mol_per_mL, unit<std::ratio<1, 1000000>, molar_concentration>)
    UNIT_ADD(substance_concentration, mole_per_microliter, moles_per_microliter, mol_per_uL, unit<std::ratio<1, 1000000000>, molar_concentration>)
    UNIT_ADD(substance_concentration, mole_per_nanoliter, moles_per_nanoliter, mol_per_nL, unit<std::ratio<1, 1000000000000>, molar_concentration>)
    UNIT_ADD(substance_concentration, mole_per_picoliter, moles_per_picoliter, mol_per_pL, unit<std::ratio<1, 1000000000000000>, molar_concentration>)

    UNIT_ADD_CATEGORY_TRAIT(substance_concentration)
#endif

// ...

Matter of fact I could fork and submit pull requests for these and other units which may be helpful in the chemistry / life sciences arena in a few weeks.

I probably won't have time to do so in the near future though. I'm on crunch time to get this project completed before the end of July. Come August, however, I would be more than happy to contribute these additions to your lib if you'd like.

nholthaus commented 6 years ago

@nanowizard Still want to put a PR together? I was about to incorporate this but don't want to rob you of your GitHub contributor status. Only thing to watch out for is we split each dimension into it's own header... should be easy enough to follow the pattern.

If you're not into it or don't have time, just send me a byline and I'll add a shout-out for you in the code and documentation somewhere.

Thanks again!

rsivek commented 6 years ago

@nholthaus thanks for putting this back on my radar. Past few months have been crazy. I'll put a PR together and try to have that to you tonight or tomorrow. :)

nholthaus commented 6 years ago

thanks! No rush though

a-jp commented 5 years ago

Could I ask if this is going anywhere? I have just posted an issue and this looks directly relevant to that. Thanks, Andy