Mon, 12 Nov 2018 16:34:43 +0100
Missing Water agent costs from Brouwhulp import are now added from the imported miscs database. The printed recipe report now calculates the beer color from the ingredients. Also set during recipes import. This will later allow to set the color method for each recipe individually.
<?php define('EURO', chr(128)); define('MMCa', '40.048'); define('MMMg', '24.305'); define('MMNa', '22.98976928'); define('MMCl', '35.453'); define('MMSO4', '96.0626'); define('MMCO3', '60.01684'); define('MMHCO3', '61.01684'); define('MMCaSO4', '172.171'); define('MMCaCl2', '147.015'); define('MMCaCO3', '100.087'); define('MMMgSO4', '246.475'); define('MMNaHCO3', '84.007'); define('MMNa2CO3', '105.996'); define('MMNaCl', '58.443'); define('MMCaOH2', '74.06268'); function ebc_to_srm($ebc) { // Srm = -1.32303E-12*Ebc4-0.00000000291515*Ebc3+0.00000818515*Ebc2+0.372038*Ebc+0.596351 return -1.32303E-12 * pow($ebc, 4) - 0.00000000291515 * pow($ebc, 3) + 0.00000818515 * pow($ebc, 2) + 0.372038 * $ebc + 0.596351; // return $ebc * 0.508; } function srm_to_ebc($srm) { // EBC = 0.000000000176506*Srm4+ 0.000000154529*Srm3-0.000159428*Srm2+2.68837*Srm-1.6004 // // Formule van Adrie Otten. brouwhulp. $ebc = 0.000000000176506 * pow($srm, 4) + 0.000000154529 * pow($srm, 3) - 0.000159428 * pow($srm, 2) + 2.68837 * $srm - 1.6004; return round($ebc); } function ebc_to_color($ebc) { return srm_to_color(ebc_to_srm($ebc)); } function srm_to_color($srm) { $i = abs($srm * 10); if ($i < 0) { $i = 0; } if ($i > 299) { $i = 299; } /* Table copied from Brouwhulp/BrewBuddy */ $R = array( 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, // 0 250, 250, 250, 250, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, // 2 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 223, 222, 221, 220, 219, 218, 217, 216, 215, // 4 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, 200, 199, 199, 198, 198, // 6 197, 197, 196, 196, 195, 195, 194, 194, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 8 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 10 192, 192, 192, 192, 192, 192, 192, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, 180, // 12 179, 178, 177, 175, 174, 172, 171, 169, 168, 167, 195, 164, 162, 161, 159, 158, 157, 155, 154, 152, // 14 151, 149, 148, 147, 145, 144, 142, 141, 139, 138, 137, 135, 134, 132, 131, 129, 128, 127, 125, 124, // 16 122, 121, 119, 118, 117, 115, 114, 112, 111, 109, 108, 107, 105, 104, 102, 101, 99, 98, 97, 95, // 18 94, 92, 91, 89, 88, 87, 85, 84, 82, 81, 79, 78, 77, 75, 74, 72, 71, 69, 68, 67, // 20 65, 64, 62, 61, 59, 58, 57, 55, 54, 52, 51, 49, 48, 47, 45, 44, 43, 41, 39, 38, // 22 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 32, 32, 31, 31, 30, 30, 29, 29, 28, 28, // 24 27, 27, 26, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, // 26 17, 17, 16, 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8 ); $G = array( 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 249, 248, 247, 246, 245, 244, 242, 240, 238, 236, 234, 232, 230, 228, 226, 224, 222, 220, 218, 216, 214, 212, 210, 208, 206, 204, 202, 200, 198, 196, 194, 192, 190, 188, 186, 184, 182, 180, 178, 176, 174, 172, 170, 168, 166, 164, 162, 160, 158, 156, 154, 152, 150, 148, 146, 144, 142, 141, 140, 139, 139, 138, 137, 136, 136, 135, 134, 133, 133, 132, 131, 130, 130, 129, 128, 127, 127, 126, 125, 124, 124, 123, 122, 121, 121, 120, 119, 118, 118, 117, 116, 115, 115, 114, 113, 112, 112, 111, 110, 109, 109, 108, 107, 106, 106, 105, 104, 103, 103, 102, 101, 100, 100, 99, 98, 97, 97, 96, 95, 94, 94, 93, 92, 91, 91, 90, 89, 88, 88, 87, 86, 85, 85, 84, 83, 82, 82, 81, 80, 79, 78, 77, 76, 75, 75, 74, 73, 72, 72, 71, 70, 69, 69, 68, 67, 66, 66, 65, 64, 63, 63, 62, 61, 60, 60, 59, 58, 57, 57, 56, 55, 54, 54, 53, 52, 51, 51, 50, 49, 48, 48, 47, 46, 45, 45, 44, 43, 42, 42, 41, 40, 39, 39, 38, 37, 36, 36, 35, 34, 33, 33, 32, 31, 30, 30, 29, 28, 27, 27, 26, 25, 24, 24, 23, 22, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3 ); $B = array( 210, 204, 199, 193, 188, 182, 177, 171, 166, 160, 155, 149, 144, 138, 133, 127, 122, 116, 111, 105, 100, 94, 89, 83, 78, 72, 67, 61, 56, 50, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 54, 54, 54, 54, 53, 53, 53, 53, 52, 52, 52, 52, 51, 51, 51, 51, 50, 50, 50, 50, 49, 49, 48, 47, 47, 46, 45, 45, 44, 43, 43, 42, 41, 41, 40, 39, 39, 38, 37, 37, 36, 35, 34, 33, 32, 31, 29, 28, 27, 26, 25, 24, 23, 21, 20, 19, 18, 17, 16, 15, 13, 12, 11, 10, 9, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2 ); return array($R[$i],$G[$i],$B[$i]); } function sg_to_plato($sg) { if ($sg > 0.5) return 259 - 259 / $sg; return 0; } function plato_to_sg($plato) { if ($plato < 259) return 259 / (259 - $plato); return 1.000; } /* * sugars is the total extract weight of sugars. */ function estimate_og($sugars, $batch_size) { $plato = 100 * $sugars / $batch_size; $sg = plato_to_sg($plato); /* Average loops, HansH 5x. Brouwhulp 20x, about 10x is enough so keep 20. */ for ($i = 0; $i < 20; $i++) { if ($sg > 0) $plato = 100 * $sugars / ($batch_size * $sg); $sg = plato_to_sg($plato); } return $sg; } function estimate_fg($percSugar, $percCara, $WGratio, $TotTme, $Temp, $attenuation, $og) { if ($percSugar > 40) $percSugar = 0; if ($percCara > 50) $percCara = 0; if (($WGratio > 0) && ($TotTme > 0)) { $BD = $WGratio; $BD = max(2, min(5.5, $BD)); $Temp = max(60, min(72, $Temp)); } else { $BD = 3.5; $Temp = 67; $TotTme = 75; } if ($attenuation < 30) $attenuation = 77; $AttBeer = 0.00825 * $attenuation + 0.00817 * $BD - 0.00684 * $Temp + 0.00026 * $TotTme - 0.00356 * $percCara + 0.00553 * $percSugar + 0.547; $fg = 1 + (1 - $AttBeer) * ($og - 1); return $fg; } function abvol($og, $fg) { if ((4.749804 - $fg) <> 0) return 486.8693 * ($og - $fg) / (4.749804 - $fg); return 0; } /* * Kleurwerking naar SRM */ function kw_to_srm($colormethod, $c) { if ($colormethod == "Morey") return 1.49 * pow($c, 0.69); if ($colormethod == "Mosher") return 0.3 * $c + 4.7; if ($colormethod == "Daniels") return 0.2 * $c + 8.4; } function kw_to_ebc($colormethod, $c) { return srm_to_ebc(kw_to_srm($colormethod, $c)); } /* Brouwhulp data.pas Function THop.FlavourContribution : double; //in % * concentration in g/l var bt, vol : double; begin bt:= FTime.Value; vol:= 0; if FRecipe <> NIL then vol:= FRecipe.BatchSize.Value; if FUse = huFirstWort then Result:= 0.15 * FAmount.Value * 1000 //assume 15% flavourcontribution for fwh else if bt > 50 then Result:= 0.10 * FAmount.Value * 1000 //assume 10% flavourcontribution as a minimum else begin Result:= 15.25 / (6 * sqrt(2 * PI)) * Exp(-0.5*Power((bt-21)/6, 2)) * FAmount.Value * 1000; if result < 0.10 * FAmount.Value * 1000 then Result:= 0.10 * FAmount.Value * 1000 //assume 10% flavourcontribution as a minimum end; if vol > 0 then Result:= Result / vol; end; Function THop.AromaContribution : double; //in % * concentration in g/l var bt, vol : double; begin bt:= FTime.Value; vol:= 0; if FRecipe <> NIL then vol:= FRecipe.BatchSize.Value; if bt > 20 then Result:= 0 else if bt > 7.5 then Result:= 10.03 / (4 * sqrt(2 * PI)) * Exp(-0.5*Power((bt-7.5)/4, 2)) * FAmount.Value * 1000 else if FUse = huBoil then Result:= FAmount.Value * 1000 else if FUse = huAroma then Result:= 1.2 * FAmount.Value * 1000 else if FUse = huWhirlpool then Result:= 1.2 * FAmount.Value * 1000 else if FUse = huDryHop then Result:= 1.33 * FAmount.Value * 1000; if vol > 0 then Result:= Result / vol; end; Procedure TFermentable.SetpHParameters(force : boolean); var x, ebc : double; begin if Between(FDIpH.Value, -0.01, 0.01) or Between(FAcidTo57.Value, -0.1, 0.1) or force then begin ebc:= SRMtoEBC(FColor.Value); case FGrainType of gtBase, gtKilned: begin FDIpH.Value:= -0.0132 * ebc + 5.7605; x:= 0.4278 * ebc - 1.8106; FAcidTo57.Value:= x; end; gtRoast: begin FDIpH.Value:= 0.00018 * ebc + 4.558; FAcidTo57.Value:= -0.0176 * ebc + 60.04; end; gtCrystal: begin FDIpH.Value:= -0.0019 * ebc + 5.2175; FAcidTo57.Value:= 0.132 * ebc + 14.277; end; gtSour: begin FDIpH.Value:= 3.44; FAcidTo57.Value:= 337; end; gtSpecial: //this could be anything. Assume for now it is a non-acidulated base or kilned malt begin FDIpH.Value:= -0.0132 * ebc + 5.7605; FAcidTo57.Value:= 0.4278 * ebc - 1.8106; end; end; end; //known parameters should be filled in here if FSupplier.Value = 'Weyermann' then begin if FName.Value = 'Vienna mout' then begin FDIpH.Value:= 5.65; FAcidTo57.Value:= 1.6; end; if FName.Value = 'Münchner I' then begin FDIpH.Value:= 5.44; FAcidTo57.Value:= 8.4; end; if FName.Value = 'Münchner II' then begin FDIpH.Value:= 5.54; FAcidTo57.Value:= 5.6; end; if FName.Value = 'Caramunich I' then begin FDIpH.Value:= 5.1; FAcidTo57.Value:= 22.4; end; if FName.Value = 'Caramunich II' then begin FDIpH.Value:= 4.71; FAcidTo57.Value:= 49; end; if FName.Value = 'Caramunich III' then begin FDIpH.Value:= 4.92; FAcidTo57.Value:= 31.2; end; if FName.Value = 'Cara-aroma' then begin FDIpH.Value:= 4.48; FAcidTo57.Value:= 74.4; end; if FName.Value = 'Carafa I' then begin FDIpH.Value:= 4.71; FAcidTo57.Value:= 42; end; if FName.Value = 'Carafa III' then begin FDIpH.Value:= 4.81; FAcidTo57.Value:= 35.4; end; if FName.Value = 'Carafa II' then begin FDIpH.Value:= 4.76; FAcidTo57.Value:= 38.7; end; if FName.Value = 'Carafa Special I' then begin FDIpH.Value:= 4.73; FAcidTo57.Value:= 46.4; end; if FName.Value = 'Carafa Special II' then begin FDIpH.Value:= 4.78; FAcidTo57.Value:= 42.9; end; if FName.Value = 'Carafa Special III' then begin FDIpH.Value:= 4.83; FAcidTo57.Value:= 38.9; end; if IsInString(FName.Value, 'Zuurmout') then begin FDIpH.Value:= 3.44; FAcidTo57.Value:= 358.2; end; end; end; function TFermentable.GetExtract: double; begin Result := 0; if FRecipe <> nil then begin Result := FAmount.Value * FYield.Value / 100 * (1 - FMoisture.Value / 100); if FAdded = atMash then Result := Result * FRecipe.Efficiency / 100; end; end; function TFermentable.GetKolbachIndex: double; begin if FProtein.Value > 0 then Result := FDissolvedProtein.Value / FProtein.Value else Result := 0; end; Procedure TWater.AddMinerals(Ca, Mg, Na, HCO3, Cl, SO4 : double); begin FCalcium.Add(Ca); FMagnesium.Add(Mg); FSodium.Add(Na); FBicarbonate.Add(HCO3); FChloride.Add(Cl); FSulfate.Add(SO4); end; function TWater.GetResidualAlkalinity: double; begin //Result in mg/l as CaCO3 Result:= FTotalAlkalinity.Value - (FCalcium.Value / 1.4 + FMagnesium.Value / 1.7); end; const Ka1 = 0.0000004445; Ka2 = 0.0000000000468; Function PartCO3(pH : double) : double; var H : double; begin H:= Power(10, -pH); Result:= 100 * Ka1 * Ka2 / (H*H + H * Ka1 + Ka1 * Ka2); end; Function PartHCO3(pH : double) : double; var H : double; begin H:= Power(10, -pH); Result:= 100 * Ka1 * H / (H*H + H * Ka1 + Ka1 * Ka2); end; Function PartH2CO3(pH : double) : double; var H : double; begin H:= Power(10, -pH); Result:= 100 * H * H / (H*H + H * Ka1 + Ka1 * Ka2); end; Function Charge(pH : double) : double; begin Result:= (-2 * PartCO3(pH) - PartHCO3(pH)); end; //Z alkalinity is the amount of acid (in mEq/l) needed to bring water to the target pH (Z pH) Function TWater.ZAlkalinity(pHZ : double) : double; //in mEq/l var CT, DeltaCNaught, DeltaCZ, C43, Cw, Cz : double; begin C43:= Charge(4.3); Cw:= Charge(FpH.Value); Cz:= Charge(pHz); DeltaCNaught:= -C43+Cw; CT:= GetAlkalinity / 50 / DeltaCNaught; DeltaCZ:= -Cz+Cw; Result:= CT * DeltaCZ; end; //Z Residual alkalinity is the amount of acid (in mEq/l) needed to bring the water in the mash to the target pH (Z pH) Function TWater.ZRA(pHZ : double) : double; //in mEq/l var Calc, Magn, Z : double; begin Calc:= FCalcium.Value / (MMCa / 2); Magn:= FMagnesium.Value / (MMMg / 2); Z:= ZAlkalinity(pHZ); Result:= Z - (Calc / 3.5 + Magn / 7); end; Function TWater.ProtonDeficit(pHZ : double) : double; var i : integer; F : TFermentable; x : double; begin Result:= ZRA(pHZ) * FAmount.Value; //proton deficit for the added malts for i:= 0 to FRecipe.NumFermentables - 1 do begin F:= FRecipe.Fermentable[i]; if (F.AddedType = atMash) and (F.GrainType <> gtNone) then begin x:= F.AcidRequired(pHZ) * F.Amount.Value; Result:= Result + x; end; end; end; Function TWater.MashpH : double; var n : integer; pd : double; pH, deltapH, deltapd : double; begin Result:= 0; n:= 0; pH:= 5.4; deltapH:= 0.001; deltapd:= 0.1; pd:= ProtonDeficit(pH); while ((pd < -deltapd) or (pd > deltapd)) and (n < 1000) do begin inc(n); if pd < -deltapd then ph:= ph - deltapH else if pd > deltapd then pH:= pH + deltapH; pd:= ProtonDeficit(pH); end; Result:= pH; end; Function TWater.MashpH2(PrDef : double) : double; var n : integer; pd : double; pH, deltapH, deltapd : double; begin Result:= 0; n:= 0; pH:= 5.4; deltapH:= 0.001; deltapd:= 0.1; pd:= ProtonDeficit(pH); while ((pd < PrDef-deltapd) or (pd > PrDef + deltapd)) and (n < 1000) do begin inc(n); if pd < PrDef-deltapd then ph:= ph - deltapH else if pd > PrDef+deltapd then pH:= pH + deltapH; pd:= ProtonDeficit(pH); end; Result:= pH; end; function TWater.GetAlkalinity: double; begin Result := FBicarbonate.Value / 1.22; //mEq/l end; function TWater.GetHardness: double; begin Result := 0.14 * FCalcium.Value - 0.23 * FMagnesium.Value; end; function TWater.GetEstPhMash: double; {var pHdemi, S: double;} begin Result:= MashpH; { Result := 0; if FRecipe <> nil then begin pHDemi := FRecipe.pHdemi; S := 0.013 * FRecipe.MashThickness + 0.013; Result := pHDemi + ResidualAlkalinity / 50 * S; end;} end; function TBeerStyle.GetBUGUMin: double; var B, G: double; begin Result:= 0; if ((FOGMax.Value + FOGMin.Value) > 0) and ((FIBUMax.Value + FIBUMin.Value) > 0) then begin G := (FOGMax.Value - FOGMin.Value) / ((FOGMax.Value + FOGMin.Value) / 2); B := (FIBUMax.Value - FIBUMin.Value) / ((FIBUMax.Value + FIBUMin.Value) / 2); if G > B then Result := ((FIBUMin.Value + FIBUMax.Value) / 2) / (1000 * (FOGMax.Value - 1)) else Result := FIBUMin.Value / (1000 * (((FOGMax.Value + FOGMin.Value) / 2) - 1)); end; end; function TBeerStyle.GetBUGUMax: double; var B, G: double; begin Result:= 0; if ((FOGMax.Value + FOGMin.Value) > 0) and ((FIBUMax.Value + FIBUMin.Value) > 0) and (FOGMin.Value > 1) then begin G := (FOGMax.Value - FOGMin.Value) / ((FOGMax.Value + FOGMin.Value) / 2); B := (FIBUMax.Value - FIBUMin.Value) / ((FIBUMax.Value + FIBUMin.Value) / 2); if G > B then Result := ((FIBUMin.Value + FIBUMax.Value) / 2) / (1000 * (FOGMin.Value - 1)) else Result := FIBUMax.Value / (1000 * (((FOGMax.Value + FOGMin.Value) / 2) - 1)); end; end; CalcBitterness; // Get concentration of ions in diluted brewwater (1) and target water (2) in mmol/l Ca1 := W.Calcium.Value / MMCa; Ca2 := W2.Calcium.Value / MMCa; Mg1 := W.Magnesium.Value / MMMg; Mg2 := W2.Magnesium.Value / MMMg; Na1 := W.Sodium.Value / MMNa; Na2 := W2.Sodium.Value / MMNa; CO31 := W.Bicarbonate.Value / MMHCO3; CO32 := W2.Bicarbonate.Value / MMHCO3; SO41 := W.Sulfate.Value / MMSO4; SO42 := W2.Sulfate.Value / MMSO4; Cl1 := W.Sulfate.Value / MMSO4; Cl2 := W2.Sulfate.Value / MMSO4; procedure MixWater(W1, W2, Wr: TWater); function Mix(V1, V2, C1, C2: double): double; begin if (V1 + V2) > 0 then Result := (V1 * C1 + V2 * C2) / (V1 + V2) else Result := 0; end; var vol1, vol2: double; phnew: double; begin vol1 := W1.Amount.Value; vol2 := W2.Amount.Value; if (vol1 + vol2) > 0 then begin Wr.Amount.Value := vol1 + vol2; Wr.Calcium.Value := Mix(vol1, vol2, W1.Calcium.Value, W2.Calcium.Value); Wr.Magnesium.Value := Mix(vol1, vol2, W1.Magnesium.Value, W2.Magnesium.Value); Wr.Sodium.Value := Mix(vol1, vol2, W1.Sodium.Value, W2.Sodium.Value); Wr.Bicarbonate.Value := Mix(vol1, vol2, W1.Bicarbonate.Value, W2.Bicarbonate.Value); Wr.Sulfate.Value := Mix(vol1, vol2, W1.Sulfate.Value, W2.Sulfate.Value); Wr.Chloride.Value := Mix(vol1, vol2, W1.Chloride.Value, W2.Chloride.Value); pHnew := -log10((power(10, -W1.pHWater.Value) * vol1 + power(10, -W2.pHWater.Value) * vol2) / (vol1 + vol2)); Wr.pHwater.Value := pHnew; end; end; function TRecipe.CalcColorWort : double; var i: integer; F: TFermentable; c, v: double; begin c := 0; v := FBatchSize.Value; if (v > 0) and (High(FFermentables) >= 0) then begin for i := Low(FFermentables) to High(FFermentables) do begin F := TFermentable(FFermentables[i]); c := c + F.Amount.Value * F.Color.Value / v; end; c := c * 8.34436; case FColorMethod of cmMorey: c := 1.49 * Power(c, 0.69); cmMosher: c := 0.3 * c + 4.7; cmDaniels: c := 0.2 * c + 8.4; end; end; Result:= c; end; procedure TRecipe.CalcWaterBalance; var i: integer; F: TFermentable; begin FAbsorbedByGrain := 0; for i := Low(FFermentables) to High(FFermentables) do begin F := TFermentable(FFermentables[i]); if (F.FermentableType = ftGrain) or (F.FermentableType = ftAdjunct) then FAbsorbedByGrain := FAbsorbedByGrain + F.Amount.Value; end; FAbsorbedByGrain := FAbsorbedByGrain * Settings.GrainAbsorption.Value; if FEquipment.CalcBoilVolume.Value then {FBoilSize.Value := FBatchSize.Value / (1 - (FEquipment.EvapRate.Value / 100) * (FBoilTime.Value / 60));} FBoilSize.Value:= FBatchSize.Value + FEquipment.BoilSize.Value * FEquipment.EvapRate.Value / 100 * (FBoilTime.Value / 60); end; Procedure TRecipe.CalcCalories; var sug, alc, org, fig : double; begin if FOGFermenter.Value > 1.001 then org:= FOGFermenter.Value else if FOG.Value > 1.001 then org:= FOG.Value else org:= 0; if FFG.Value > 0.999 then fig:= FFG.Value else if FEstFG.Value > 1.000 then fig:= FEstFG.Value else if FEstFG2.Value > 1.000 then fig:= FEstFG2.Value else fig:= 0; if (org > 0) and (fig > 0) then begin alc:= 1881.22 * fig * (org - fig) / (1.775 - org); sug:= 3550 * fig * (0.1808 * org + 0.8192 * fig - 1.0004); FCalories.Value:= (alc + sug) / (12 * 0.0295735296); end else FCalories.Value:= 0; end; */ ?>