@beerwright/core
    Preparing search index...

    Function gristKgForTargetOg

    • The total grist mass that puts a bill of shares on a target OG, or null.

      This is the inverse of the waterfall at the top of this file. Each addition contributes kg × pointsPerKgPerL × efficiency, and with fixed shares every kg is the same multiple of the total, so the gravity is proportional to the total mass and the answer is a single division:

      blended = Σ (share_i / 100) × pointsPerKgPerL_i × efficiency_i
      gristKg = (targetOg − 1) × 1000 × postBoilVolumeL / blended

      The result is exact because nothing in the forward calculation adds a term that doesn't scale with mass. Efficiency is a per-class constant (fermentableEfficiencyFraction reads class and use, never a mass). When designing forward, the post-boil volume comes from the target batch size and the equipment's losses. Grain absorption changes the water required, not the volume in the kettle (volumes.ts). gravity.test.ts checks this by sizing a grist and reading the target back out of predictGravities.

      sugarToTargetGravity answers the brew-day question ("my gravity is low, how much DME?") and returns 0 when the deficit isn't positive, because you can't take sugar back out of a kettle. When you're designing a recipe, the most common reason to set a target is that the bill overshoots, so this function has to size down as well as up.

      null covers every grist that no mass can satisfy: nothing in it has extract, every share is zero, the volume isn't positive, or the target is at or below water. These are states a half-entered bill passes through, so we return null and let the caller decide what to show, instead of throwing.

      Parameters

      Returns number | null