Final set the default utilisation to 20. Selecting another hop in a product now sets the new utilisation and bu_factor too. Removed experimental CO2 extract calculation and let it handle by the Tinseth formula. The Tinseth formula uses the Utilisation value in the final calculation. Moved the ISO extract formula for extract at bottling to the main toIBU function.

Fri, 29 Jul 2022 16:21:20 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Fri, 29 Jul 2022 16:21:20 +0200
changeset 375
c21567bfd703
parent 374
74d541ac514c
child 376
81ae1b4e25db

Final set the default utilisation to 20. Selecting another hop in a product now sets the new utilisation and bu_factor too. Removed experimental CO2 extract calculation and let it handle by the Tinseth formula. The Tinseth formula uses the Utilisation value in the final calculation. Moved the ISO extract formula for extract at bottling to the main toIBU function.

src/EditHop.cpp file | annotate | diff | comparison | revisions
src/EditProductTab4.cpp file | annotate | diff | comparison | revisions
src/Utils.cpp file | annotate | diff | comparison | revisions
ui/EditHop.ui file | annotate | diff | comparison | revisions
--- a/src/EditHop.cpp	Fri Jul 29 13:20:24 2022 +0200
+++ b/src/EditHop.cpp	Fri Jul 29 16:21:20 2022 +0200
@@ -73,7 +73,7 @@
 	/* Set some defaults */
 	ui->typeEdit->setCurrentIndex(0);
 	ui->formEdit->setCurrentIndex(0);
-	ui->utilisationEdit->setValue(35.0);
+	ui->utilisationEdit->setValue(20.0);
 	ui->bufactorEdit->setValue(1.0);
 	ui->prodEdit->clear();
 	ui->thtEdit->clear();
--- a/src/EditProductTab4.cpp	Fri Jul 29 13:20:24 2022 +0200
+++ b/src/EditProductTab4.cpp	Fri Jul 29 16:21:20 2022 +0200
@@ -325,6 +325,8 @@
     newh.myrcene = 0;
     newh.total_oil = 0;
     newh.inventory = 0;
+    newh.utilisation = 20;
+    newh.bu_factor = 1;
 
     product->hops.append(newh);
     emit refreshAll();
@@ -430,7 +432,7 @@
     /*
      * Search the hop pointed by the index and instock flag.
      */
-    QString sql = "SELECT name,origin,alpha,beta,humulene,caryophyllene,cohumulone,myrcene,hsi,total_oil,type,form,cost,inventory FROM inventory_hops ";
+    QString sql = "SELECT * FROM inventory_hops ";
     if (instock)
         sql.append("WHERE inventory > 0 ");
     sql.append("ORDER BY origin,name");
@@ -444,20 +446,22 @@
     /*
      * Replace the hop record contents
      */
-    product->hops[product->hops_row].name = query.value(0).toString();
-    product->hops[product->hops_row].origin = query.value(1).toString();
-    product->hops[product->hops_row].alpha = query.value(2).toDouble();
-    product->hops[product->hops_row].beta = query.value(3).toDouble();
-    product->hops[product->hops_row].humulene = query.value(4).toDouble();
-    product->hops[product->hops_row].caryophyllene = query.value(5).toDouble();
-    product->hops[product->hops_row].cohumulone = query.value(6).toDouble();
-    product->hops[product->hops_row].myrcene = query.value(7).toDouble();
-    product->hops[product->hops_row].hsi = query.value(8).toDouble();
-    product->hops[product->hops_row].total_oil = query.value(9).toDouble();
-    product->hops[product->hops_row].type = query.value(10).toInt();
-    product->hops[product->hops_row].form = query.value(11).toInt();
-    product->hops[product->hops_row].cost = query.value(12).toDouble();
-    product->hops[product->hops_row].inventory = query.value(13).toDouble();
+    product->hops[product->hops_row].name = query.value("name").toString();
+    product->hops[product->hops_row].origin = query.value("origin").toString();
+    product->hops[product->hops_row].alpha = query.value("alpha").toDouble();
+    product->hops[product->hops_row].beta = query.value("beta").toDouble();
+    product->hops[product->hops_row].humulene = query.value("humulene").toDouble();
+    product->hops[product->hops_row].caryophyllene = query.value("caryophyllene").toDouble();
+    product->hops[product->hops_row].cohumulone = query.value("cohumulone").toDouble();
+    product->hops[product->hops_row].myrcene = query.value("myrcene").toDouble();
+    product->hops[product->hops_row].hsi = query.value("hsi").toDouble();
+    product->hops[product->hops_row].total_oil = query.value("total_oil").toDouble();
+    product->hops[product->hops_row].type = query.value("type").toInt();
+    product->hops[product->hops_row].form = query.value("form").toInt();
+    product->hops[product->hops_row].cost = query.value("cost").toDouble();
+    product->hops[product->hops_row].inventory = query.value("inventory").toDouble();
+    product->hops[product->hops_row].utilisation = query.value("utilisation").toDouble();
+    product->hops[product->hops_row].bu_factor = query.value("bu_factor").toDouble();
 
     /*
      * Update the visible fields
--- a/src/Utils.cpp	Fri Jul 29 13:20:24 2022 +0200
+++ b/src/Utils.cpp	Fri Jul 29 16:21:20 2022 +0200
@@ -398,55 +398,20 @@
     double ibu = 0.0;
 
     /*
-     * Most suppliers of CO2 hop extract (not isomerized) use formulas
-     * like this. For now, manual set a utilisation factor of 35%.
+     * Basic Glenn Tinseth formula.
+     * http://realbeer.com/hops/research.html
+     *
+     * kUtilisation was hardcoded as 4.15.
+     * It is now a formula since we need variable Utilisation values per hop.
+     * Default "normal" hops Utilisation is 20.
      */
-    if (Form == HOP_FORMS_CO2EXTRACT) {
-	double utilisation = 0.35;	// 35%
-	double factor_sg = 1.0;
-	double factor_bt = 1.0;
-	double bt = T2 - T1;
-
-	/* Table from Wildabouthops */
-	if (SG >= 1.150)
-	    factor_sg = 1.3;
-	else if (SG >= 1.110)
-	    factor_sg = 1.2;
-	else if (SG >= 1.080)
-	    factor_sg = 1.1;
-
-	if (bt > 60) {
-	    factor_bt = ((bt - 60) / 300) + 1.0;
-	} else {
-	    factor_bt = (bt / 60.0);
-	}
-	qDebug() << "factor_sg" << factor_sg << "factor_bt" << factor_bt;
-
-	ibu = ((Utilisation / 100.0) * alpha * mass * 1000.0) / Volume;
-	ibu = (ibu * factor_bt) / factor_sg;
-	qDebug() << "TinsethIBU CO2" << Amount << Alpha << Volume << Utilisation << BU_factor << "SG" << SG << "T" << T1 << T2 << "ibu:" << ibu;
-	return ibu;
-    }
-
-    if (Form == HOP_FORMS_ISOEXTRACT) {
-
-	double dosageHl = ((100.0 / Utilisation) * (100.0 / Alpha) * 0.001) / BU_factor;	// IBU per liter
-	qDebug() << (100 / Utilisation) << (100 / Alpha) << dosageHl << dosageHl * Volume << mass / (dosageHl * Volume);
-	ibu = mass / (dosageHl * Volume);
-	qDebug() << "TinsethIBU ISO" << Amount << Alpha << Volume << Utilisation << BU_factor << "ibu:" << ibu;
-	return ibu;
-    }
-
-    /*
-     * Basic Tinseth formula.
-     * http://realbeer.com/hops/research.html
-     */
+    double kUtilisation = 83.0 / Utilisation;
     double AddedAlphaAcids = (alpha * mass * 1000) / Volume;
     double Bigness_factor = 1.65 * pow(0.000125, SG - 1);
-    double BoilTime_factor1 = ((1 - exp(-0.04 * T1)) / 4.15);
-    double BoilTime_factor2 = ((1 - exp(-0.04 * T2)) / 4.15);
+    double BoilTime_factor1 = ((1 - exp(-0.04 * T1)) / kUtilisation);
+    double BoilTime_factor2 = ((1 - exp(-0.04 * T2)) / kUtilisation);
     ibu = Bigness_factor * (BoilTime_factor2 - BoilTime_factor1) * AddedAlphaAcids;
-    qDebug() << "TinsethIBU nor" << SG << Amount << Alpha << Volume << Bigness_factor * (BoilTime_factor2 - BoilTime_factor1) << "ibu:" << ibu;
+    qDebug() << "TinsethIBU" << SG << Amount << Alpha << Volume << kUtilisation << Bigness_factor * (BoilTime_factor2 - BoilTime_factor1) << "ibu:" << ibu;
 
     /*
      * Correction for hop forms
@@ -596,7 +561,14 @@
 	 * Isomerized hop extracts to use at bottling.
 	 * Assume 10% volume is lost during fermentation and transfers.
 	 */
-	ibu = TinsethIBU(Form, postSG, Volume * 0.9, Amount, 0, 0, Alpha, Utilisation, BU_factor);
+	if (Form == HOP_FORMS_ISOEXTRACT) {
+	    /*
+	     * ISO-alpha-extract hops, Tetra etc.
+	     */
+	    double dosageHl = ((100.0 / Utilisation) * (100.0 / Alpha) * 0.001) / BU_factor;        // IBU per liter
+	    ibu = (Amount * 1000.0) / (dosageHl * Volume * 0.9);
+	    qDebug() << "ISO extract" << Amount << Alpha << Volume * 0.9 << Utilisation << BU_factor << "ibu:" << ibu;
+	}
     }
 
     double rc = round(ibu * 1000.0) / 1000.0;
--- a/ui/EditHop.ui	Fri Jul 29 13:20:24 2022 +0200
+++ b/ui/EditHop.ui	Fri Jul 29 16:21:20 2022 +0200
@@ -956,7 +956,8 @@
        </rect>
       </property>
       <property name="toolTip">
-       <string>35% .. 90% for hop extracts</string>
+       <string>20% is a good default for T-90 Pellet and Leaf hops.
+Use 35% .. 90% for hop extracts.</string>
       </property>
       <property name="alignment">
        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>

mercurial