DEV Community

Cover image for Why Heat Pump Calculations Fail: Modeling DOE Appendix M1 HSPF2 Derates, Sub-Zero COP Decay, and Fuel Parity in TypeScript
miad
miad

Posted on Originally published at powelab.org

Why Heat Pump Calculations Fail: Modeling DOE Appendix M1 HSPF2 Derates, Sub-Zero COP Decay, and Fuel Parity in TypeScript

If you have ever used a generic "heat pump vs. gas furnace" web calculator, you have almost certainly encountered an oversimplified static model.

Most online tools perform a simplistic calculation: they take a nameplate efficiency multiplier (e.g., COP = 3.0), divide home square footage by a generic rule-of-thumb heating requirement, and declare that the heat pump will save you 40% on heating bills.

In reality, building engineers know this model fails dramatically in field deployments for three foundational physics and regulatory reasons:

  1. The External Static Pressure (ESP) Penalty: The Department of Energy’s 2023 mandate (10 CFR Part 430 Appendix M1) revealed that testing HVAC equipment against artificially low laboratory static pressures (0.15–0.20 inches of water column) produces nominal ratings that are ~15% higher than real-world ductwork can actually achieve.
  2. Ambient Suction Density Collapse: As outdoor temperatures drop below freezing, refrigerant vapor density plummets. A heat pump rated at COP 3.8 in mild weather can degrade to COP 1.3 at 0°F (-18°C), forcing high-draw electric resistance heat strips (COP = 1.0) to stage on.
  3. Dynamic Fuel Parity: Gas, propane, and electric rates vary wildly by utility tier. The break-even electricity rate fluctuates constantly with outdoor temperature.

In this deep-dive, we will explore how we built a zero-database, deterministic computational engine in pure TypeScript to model thermodynamic fuel equivalence, DOE Appendix M1 HSPF2 conversions, and cold-climate COP decay curves.


1. The Physics: Translating DOE Appendix M1 & AHRI 210/240 to Code

Under the legacy DOE Appendix M test procedure, manufacturers tested residential air-source split systems at external static pressures between 0.10 and 0.20 inches of water column (in. w.c.). However, typical residential ducted installations impose real-world duct resistance between 0.50 and 0.70 in. w.c.

Effective 2023, the DOE mandated Appendix M1, enforcing a realistic testing static pressure of 0.50 in. w.c..

Because the blower fan must work significantly harder against higher static pressure, power draw increases and measured airflow drops. In Region IV (the national standard heating climate), the resulting HSPF2 rating is approximately 15% lower than the legacy HSPF for the identical physical hardware:

HSPF2≈0.85⋅HSPFlegacy \text{HSPF2} \approx 0.85 \cdot \text{HSPF}_{\text{legacy}}

To convert between seasonal BTU-per-watt-hour performance (HSPF2) and the dimensionless seasonal Coefficient of Performance (COPseasonal), we normalize by the mechanical equivalent of heat (3,412.142 BTU per kilowatt-hour):

COPseasonal=HSPF23.412142 \text{COP}_{\text{seasonal}} = \frac{\text{HSPF2}}{3.412142}
Efficiency Tier Legacy HSPF (App. M) Modern HSPF2 (App. M1) Testing Static Pressure Seasonal COP Equivalence Regulatory Status
DOE 2023 Minimum 8.8 HSPF 7.5 HSPF2 0.50 in. w.c. 2.20 COP Mandatory U.S. Baseline
High-Efficiency Standard 9.5–10.0 HSPF 8.1–8.5 HSPF2 0.50 in. w.c. 2.37–2.49 COP ENERGY STAR v6.1 Baseline
Cold-Climate Inverter Tier 10.5–11.5 HSPF 9.0–9.8 HSPF2 0.50 in. w.c. 2.64–2.87 COP ENERGY STAR Cold Climate
Premium Inverter 12.0–13.5+ HSPF 10.2–11.5+ HSPF2 0.50 in. w.c. 2.99–3.37+ COP High-Performance Mini-Splits

2. Cold-Climate COP Decay Kinetics

A single seasonal COP average does not tell the homeowner what happens when an arctic cold front hits.

As outdoor ambient temperature (Toutdoor) drops:

  • Refrigerant suction pressure decreases.
  • Vapor mass flow through the scroll compressor drops.
  • Outdoor coils begin frosting between 32°F and 40°F, requiring energy-intensive periodic reverse-cycle defrost.
  • Below the building's thermal balance point (typically 15°F to 25°F in standard homes), heat pump output drops below the building envelope's heat loss rate, triggering auxiliary electric resistance heat strips (COP = 1.00).

Modern cold-climate heat pumps (ccASHP) mitigate this using Enhanced Vapor Injection (EVI) and variable-speed inverters, but efficiency still decays predictably:

COP(T)=max⁡(1.0,  COPrated⋅[1−α⋅(Trated−Toutdoor)]) \text{COP}(T) = \max\left(1.0,\; \text{COP}{\text{rated}} \cdot \left[1 - \alpha \cdot (T{\text{rated}} - T_{\text{outdoor}})\right]\right)

Where α is the empirical thermal decay constant (~0.018 for standard single-stage compressors, dropping to ~0.009 for inverter systems with vapor injection).


3. Deriving the Fuel Parity & Break-Even Electricity Rate

When is a heat pump truly cheaper than burning natural gas, propane, or heating oil?

To find the exact break-even electricity rate (Pelec,break-even in $/kWh), we set the cost per delivered thermal BTU equal across both systems using Higher Heating Values (HHV):

Pelec,break-even=(PfuelHHVfuel)⋅3412.142⋅(COPhpηfurnace) P_{\text{elec,break-even}} = \left(\frac{P_{\text{fuel}}}{\text{HHV}{\text{fuel}}}\right) \cdot 3412.142 \cdot \left(\frac{\text{COP}{\text{hp}}}{\eta_{\text{furnace}}}\right)

Where:

  • Natural Gas: HHV = 100,000 BTU/Therm
  • Delivered Propane: HHV = 91,500 BTU/Gallon
  • Heating Oil #2: HHV = 138,500 BTU/Gallon
  • ηfurnace: Annual Fuel Utilization Efficiency (AFUE, e.g., 0.80 for standard draft, 0.96 for condensing)

If your actual utility electricity price is below Pelec,break-even, heating with your heat pump saves money on every thermal unit delivered.


4. Pure TypeScript Implementation: Deterministic Engine Design

At PowerLab, all calculators follow a strict architectural rule: zero client-side state in the engine, zero external network calls, zero DOM dependencies, and 100% deterministic TypeScript.

Here is how the core calculation interface and engine are structured:

export type FuelType = "natural-gas" | "propane" | "heating-oil" | "electric-resistance";

export interface HeatPumpCostInputs {
  annualHeatingDemandBtu: number; // typically 40,000,000 to 70,000,000 BTU
  heatPumpHspf2: number;          // modern DOE Appendix M1 rating (e.g., 8.5)
  electricityRatePerKwh: number;  // e.g., 0.1834 ($/kWh)
  comparisonFuel: FuelType;
  fuelPricePerUnit: number;       // $/Therm for gas, $/gal for oil/propane
  combustionAfue: number;         // e.g., 0.80 or 0.96
}

export interface FuelBenchmark {
  hhvBtuPerUnit: number;
  unitLabel: string;
}

export const FUEL_BENCHMARKS: Record<FuelType, FuelBenchmark> = {
  "natural-gas": { hhvBtuPerUnit: 100000, unitLabel: "Therms" },
  "propane": { hhvBtuPerUnit: 91500, unitLabel: "Gallons" },
  "heating-oil": { hhvBtuPerUnit: 138500, unitLabel: "Gallons" },
  "electric-resistance": { hhvBtuPerUnit: 3412.142, unitLabel: "kWh" },
};

export interface HeatPumpCostResult {
  seasonalCop: number;
  heatPumpAnnualKwh: number;
  heatPumpAnnualCostUsd: number;
  combustionUnitsRequired: number;
  combustionAnnualCostUsd: number;
  netAnnualSavingsUsd: number;
  breakEvenElectricityRateUsd: number;
}

export function calculateHeatPumpEconomics(
  inputs: HeatPumpCostInputs
): HeatPumpCostResult {
  const {
    annualHeatingDemandBtu,
    heatPumpHspf2,
    electricityRatePerKwh,
    comparisonFuel,
    fuelPricePerUnit,
    combustionAfue,
  } = inputs;

  // 1. Convert HSPF2 to Seasonal COP (AHRI 210/240 & DOE App M1)
  const seasonalCop = heatPumpHspf2 / 3.412142;

  // 2. Heat Pump Electrical Consumption
  const heatPumpKwh = annualHeatingDemandBtu / (seasonalCop * 3412.142);
  const heatPumpCost = heatPumpKwh * electricityRatePerKwh;

  // 3. Comparison Fossil Fuel Consumption
  const fuelSpec = FUEL_BENCHMARKS[comparisonFuel];
  const effectiveFuelBtuPerUnit = fuelSpec.hhvBtuPerUnit * combustionAfue;
  const unitsRequired = annualHeatingDemandBtu / effectiveFuelBtuPerUnit;
  const combustionCost = unitsRequired * fuelPricePerUnit;

  // 4. Net Savings & Dynamic Break-Even Solver
  const netSavings = combustionCost - heatPumpCost;
  const breakEvenRate =
    (fuelPricePerUnit / fuelSpec.hhvBtuPerUnit) *
    3412.142 *
    (seasonalCop / combustionAfue);

  return {
    seasonalCop: Number(seasonalCop.toFixed(2)),
    heatPumpAnnualKwh: Math.round(heatPumpKwh),
    heatPumpAnnualCostUsd: Number(heatPumpCost.toFixed(2)),
    combustionUnitsRequired: Number(unitsRequired.toFixed(1)),
    combustionAnnualCostUsd: Number(combustionCost.toFixed(2)),
    netAnnualSavingsUsd: Number(netSavings.toFixed(2)),
    breakEvenElectricityRateUsd: Number(breakEvenRate.toFixed(4)),
  };
}
Enter fullscreen mode Exit fullscreen mode

5. Validating Monotonic Thermodynamic Invariants with Vitest

Because calculation engines power user decisions on multi-thousand dollar equipment retrofits, every mathematical engine must pass invariant unit tests:

import { describe, it, expect } from "vitest";
import { calculateHeatPumpEconomics } from "./engine";

describe("Heat Pump Economics Engine", () => {
  const baseline = {
    annualHeatingDemandBtu: 50000000, // 50 MMBTU
    heatPumpHspf2: 8.5,               // COP ~2.49
    electricityRatePerKwh: 0.1834,    // EIA national average
    comparisonFuel: "propane" as const,
    fuelPricePerUnit: 3.20,           // $/gal propane
    combustionAfue: 0.85,
  };

  it("should prove propane replacement generates substantial annual savings", () => {
    const res = calculateHeatPumpEconomics(baseline);
    expect(res.netAnnualSavingsUsd).toBeGreaterThan(800);
    expect(res.breakEvenElectricityRateUsd).toBeGreaterThan(baseline.electricityRatePerKwh);
  });

  it("should maintain strict mathematical parity at the break-even rate", () => {
    const res = calculateHeatPumpEconomics(baseline);
    const parityRun = calculateHeatPumpEconomics({
      ...baseline,
      electricityRatePerKwh: res.breakEvenElectricityRateUsd,
    });
    // At break-even rate, net savings must be approximately zero
    expect(Math.abs(parityRun.netAnnualSavingsUsd)).toBeLessThan(1.0);
  });

  it("should monotonically increase savings as heat pump HSPF2 rises", () => {
    const standard = calculateHeatPumpEconomics({ ...baseline, heatPumpHspf2: 7.5 });
    const premium = calculateHeatPumpEconomics({ ...baseline, heatPumpHspf2: 10.5 });
    expect(premium.netAnnualSavingsUsd).toBeGreaterThan(standard.netAnnualSavingsUsd);
  });
});
Enter fullscreen mode Exit fullscreen mode

6. Open Architecture & Resources

You can explore the live, interactive simulation workbench and inspect full building science derivations at:

By eliminating black-box estimates and modeling the real physical properties of heat pumps under modern DOE Appendix M1 test standards, we give homeowners and engineers transparent, verifiable data to make informed electrification decisions.

Top comments (0)