#1196 Proposal: Fixes for specific enthalpy units

Stephen Frank Tue 11 Aug

I'd like to propose the following corrections to the definitions for IP specific enthalpy units in units.txt:

  1. Fix the precision difference between the "per lb" and "per lb_dry" versions of the unit
  2. Correct discrepancies in unit names/capitalization
  3. Add the approximately 17.78 kJ/kg offset required to go between the SI and IP definitions for specific enthalpy, as defined by ASHRAE (Fundamentals handbook). More on this below.

SI vs. IP Enthalpy

In HVAC calculations, specific enthalpy has an arbitrary zero point. In SI units, the zero point is 0°C; in IP units it is 0°F. The offset between the IP and SI quantities for enthalpy is equal to the SI specific enthalpy evaluated at 0°F (-17.7778°C):

  • Per the 2025 ASHRAE Handbook: Fundamentals, the specific enthalpy of dry air at -17°C is -17.095 kJ/kg and at -18°C is -18.1 kJ/kg
  • Interpolating between the two values, the estimated offset at -17.7778°C is -17.876689 kJ/kg

Introducing this offset to the units engine prevents the user from having to perform this correction manually when converting between SI and IP units of enthalpy.

Changes to Units.txt

Before...

btu_per_pound, BTU/lb; m2*sec-2; 2325.5576058607867
btus_per_pound_dry_air, btu/lb_dry; m2*sec-2; 2326.0

After...

btu_per_pound, BTU/lb; m2*sec-2; 2325.5576058607867; -17876.689
btu_per_pound_dry_air, BTU/lb_dry; m2*sec-2; 2325.5576058607867; -17876.689
kbtu_per_pound, kBTU/lb; m2*sec-2; 2325557.6058607867; -17876.689
kbtu_per_pound_dry_air, kBTU/lb_dry; m2*sec-2; 2325557.6058607867; -17876.689

I've tested these in SkySpark (v3.1.10) and they appear to work as expected.

Finally, it's also worth noting that the category of units that Haystack calls "enthalpy" are actually specific enthalpy; maybe we should update the units.txt category label as well.

Brian Frank Mon 17 Aug

If no one has any further comments, then I will merge this later this week.

Jason Hogan Thu 20 Aug

Here is a concise summary of proposal #1196 for units.txt:Precision Standardization: Standardizes btu_per_pound_dry_air to match the exact multiplier of btu_per_pound ($2325.5576058607867$).Name & Capitalization Fixes: Corrects minor naming and casing inconsistencies across BTU enthalpy definitions (e.g., updating display symbol from btu/lb_dry to BTU/lb_dry).SI/IP Zero-Point Offset: Adds an absolute offset of $-17,876.689\text{ m}^2\text{s}^{-2}$ ($-17.876689\text{ kJ/kg}$). This accounts for the datum difference between SI ($0^\circ\text{C}$) and IP ($0^\circ\text{F}$) enthalpy baselines per the ASHRAE Fundamentals handbook.Expanded Units: Adds kbtu_per_pound and kbtu_per_pound_dry_air entries with the updated multiplier and offset.Category Labeling: Recommends updating the Haystack unit category name from "enthalpy" to "specific enthalpy" for technical accuracy.

Brian Frank Fri 21 Aug

Stephen, thanks for the post. I started implementing this and think it needs more discussion

I went back to look were the current values came from. The current values were auto-generated almost two decades ago from the oBIX database in 2008 - they have not changed since. Every commit after that only added new units.

The oBIX db had two quantity sections that both carried BTU-per-pound, same dimension, different values:

// enthalpy (m2*sec-2)
  Unit("btu_per_pound, BTU/lb; ...; 2325.5576058607867"),

// specific energy (m2*sec-2)
  Unit("btus_per_pound, btu/lb; ...; 2326.0"),
  Unit("btus_per_pound_dry_air, btu/lb_dry; ...; 2326.0"),

When those merged into one enthalpy block, btus_per_pound got dropped and btu_per_pound survived sitting next to btus_per_pound_dry_air. That is the whole origin of the discrepancy you found.

There are at least four BTU definitions in the db right now:

entry                  value           implies BTU of
---------------------  --------------  --------------
btu                    1054.852        no standard
BTU/h * 3600           1054.35         BTU_th
kBTU/h * 3600          1055055.85      BTU_IT
BTU/lb                 2325.5576       1054.8552, no standard
btu/lb_dry             2326.0          BTU_IT
therm                  105506000       disagree with
therm/h * 3600         105435000       each other

So BTU/h * h does not equal BTU today

2325.5576058607867 is the odd one out. Back it into a BTU and you get 1054.8552, which is not any standard and does not match our own btu two hundred lines up. 2326.0 is exact by construction:

1 lb     = 0.45359237 kg 
1 cal_IT = 4.1868 J 

BTU_IT      = 4.1868 * 453.59237 * 5/9 = 1055.05585262 J exactly
BTU_IT / lb = 2326 exactly

This is what I would propose - pick BTU_IT and apply it everywhere, not just in the enthalpy section:

btu, BTU; kg1*m2*sec-2; 1055.05585262
kilobtu, kBTU; kg1*m2*sec-2; 1055055.85262
megabtu, MBTU, MMBTU; kg1*m2*sec-2; 1.05505585262E9
therm; kg1*m2*sec-2; 1.05505585262E8

btu_per_square_foot, BTU/ft²; kg1*sec-2; 1.1356526682226975E4
kilobtu_per_square_foot, kBTU/ft²; kg1*sec-2; 1.1356526682226975E7
megabtu_per_square_foot, MBTU/ft²; kg1*sec-2; 1.1356526682226975E10

-- specific enthalpy (m2*sec-2)
btu_per_pound, BTU/lb; m2*sec-2; 2326.0
btu_per_pound_dry_air, BTU/lb_dry, btu/lb_dry; m2*sec-2; 2326.0
kilobtu_per_pound, kBTU/lb; m2*sec-2; 2326000.0
kilobtu_per_pound_dry_air, kBTU/lb_dry; m2*sec-2; 2326000.0

btus_per_hour, BTU/h; kg1*m2*sec-3; 0.2930710701722222
kilobtus_per_hour, kBTU/h; kg1*m2*sec-3; 293.0710701722222
megabtus_per_hour, MBTU/h, MMBTU/h; kg1*m2*sec-3; 293071.0701722222
therms_per_hour, therm/h; kg1*m2*sec-3; 29307.10701722222
kilobtus_per_hour_per_square_foot, kBTU/h/ft²; kg1*sec-3; 3154.590745063049

That should include all your naming fixes: btus_ to btu_, lowercase btu/lb_dry to BTU/lb_dry, and the missing k variants. I kept btu/lb_dry as a secondary alias so its not a breaking change. And rename the section label to specific enthalpy.

With these BTU/h * h == BTU is exact in floating point for BTU, kBTU, MBTU, and therm

On the 17.78 offset

The problem is that an offset changes what subtraction means. Right now if you have two enthalpies in BTU/lb and subtract them, the answer is a real difference you can convert to kJ/kg and multiply by mass flow. Add the offset and that only works if you convert both numbers first and subtract afterward. Anyone who subtracts first and converts second is off by 17.88 kJ/kg, and there is no way for us to tell those two cases apart. That is why I had to create the temp vs temp_delta mess.

The offset also means 0 BTU/lb is no longer zero energy.

So I would say lets focus on the precision and numbers here, and that needs to be a separate discussion

Stephen Frank Mon 24 Aug

Thanks for all that info Brian! ASHRAE uses the International Table (IT) definition, so I agree it would be best to standardize on that. ASHRAE's value for it is 1 BTU = 1055.05585262 J, which matches what you have above.

I see your point on the enthalpy offset math. Agreed to leave it alone for now.

Brian Frank Tue 25 Aug

Thanks, I pushed these changes:

unit db changeset

xeto quantity changeset

Login or Signup to reply.