The shares that put a grist on a target colour, or the reason it can't be done.
Every crystal and roasted row is scaled by one factor, so their ratio to each
other (a recipe decision, not a colour one) stays the same. The base and
kilned rows give or take the difference in proportion to their own shares.
The shares still add up to the same total as before, which a grist stated in
percentages needs, and nothing else in the bill changes.
MCU is linear in mass and every fit in this file is monotonic in MCU, so the
colour is monotonic in that one factor and bisection finds it. There's no
closed form because danielsSrm and mosherSrm are piecewise,
and we want the same solver to be exact for all three fits.
Refusals
no-colour-malt when the bill has no crystal or roast in it. We don't invent
an addition, because which malt and how dark is up to the recipe.
unreachable when no factor inside MAX_COLOUR_MALT_FRACTION (half the
grist) reaches the colour. It's also returned for bills with no base or kilned malt, since
there's nothing to trade against and the shares can't move.
Limits
It keeps the total mass fixed, so moving share from base malt to crystal
changes the gravity a little, because crystal and roast yield less extract
than base. A caller that also has a target OG can follow this with
gristKgForTargetOg.
The shares that put a grist on a target colour, or the reason it can't be done.
Every crystal and roasted row is scaled by one factor, so their ratio to each other (a recipe decision, not a colour one) stays the same. The base and kilned rows give or take the difference in proportion to their own shares. The shares still add up to the same total as before, which a grist stated in percentages needs, and nothing else in the bill changes.
MCU is linear in mass and every fit in this file is monotonic in MCU, so the colour is monotonic in that one factor and bisection finds it. There's no closed form because danielsSrm and mosherSrm are piecewise, and we want the same solver to be exact for all three fits.
Refusals
no-colour-maltwhen the bill has no crystal or roast in it. We don't invent an addition, because which malt and how dark is up to the recipe.unreachablewhen no factor insideMAX_COLOUR_MALT_FRACTION(half the grist) reaches the colour. It's also returned for bills with no base or kilned malt, since there's nothing to trade against and the shares can't move.Limits
It keeps the total mass fixed, so moving share from base malt to crystal changes the gravity a little, because crystal and roast yield less extract than base. A caller that also has a target OG can follow this with gristKgForTargetOg.