Added sparge water salt additions. Adjust sparge acid amount if manual calculations and the water volume is changed.

Wed, 20 Jul 2022 12:44:02 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Wed, 20 Jul 2022 12:44:02 +0200
changeset 365
4bc746c65650
parent 364
1efe29f64551
child 366
43bf6cccc4ab

Added sparge water salt additions. Adjust sparge acid amount if manual calculations and the water volume is changed.

src/EditProduct.cpp file | annotate | diff | comparison | revisions
src/EditProductTab8.cpp file | annotate | diff | comparison | revisions
src/EditRecipe.cpp file | annotate | diff | comparison | revisions
src/EditRecipe.h file | annotate | diff | comparison | revisions
src/EditRecipeTab7.cpp file | annotate | diff | comparison | revisions
src/global.h file | annotate | diff | comparison | revisions
--- a/src/EditProduct.cpp	Tue Jul 19 16:00:52 2022 +0200
+++ b/src/EditProduct.cpp	Wed Jul 20 12:44:02 2022 +0200
@@ -460,7 +460,6 @@
     ui->sp_phEdit->setValue(product->sparge_ph);
     ui->sp_acidtypeEdit->setCurrentIndex(product->sparge_acid_type);
     ui->sp_acidpercEdit->setValue(product->sparge_acid_perc);
-    ui->sp_acidvolEdit->setValue(product->sparge_acid_amount);
     check_waters();
 
     // Tab brewday.
--- a/src/EditProductTab8.cpp	Tue Jul 19 16:00:52 2022 +0200
+++ b/src/EditProductTab8.cpp	Wed Jul 20 12:44:02 2022 +0200
@@ -470,52 +470,58 @@
 void EditProduct::calcSparge()
 {
     double TargetpH = product->sparge_ph;
-    double Source_pH = product->w1_ph;
-    double Source_alkalinity = product->w1_total_alkalinity;
+    double Source_pH = 7.0;
 
     qDebug() << "calcSparge()";
-
     setButtons(product->stage > PROD_STAGE_BREW);
 
     if (product->sparge_source == 1 && product->w2_ph > 0.0) {
+	product->ws_calcium = product->w2_calcium;
+	product->ws_magnesium = product->w2_magnesium;
+	product->ws_total_alkalinity = product->w2_total_alkalinity;
+	product->ws_sodium = product->w2_sodium;
+	product->ws_chloride = product->w2_chloride;
+	product->ws_sulfate = product->w2_sulfate;
 	Source_pH = product->w2_ph;
-	Source_alkalinity = product->w2_total_alkalinity;
-	ui->sp_caEdit->setValue(product->w2_calcium);
-        ui->sp_mgEdit->setValue(product->w2_magnesium);
-        ui->sp_hco3Edit->setValue(Utils::Bicarbonate(product->w2_total_alkalinity, product->w2_ph));
-        ui->sp_caco3Edit->setValue(product->w2_total_alkalinity);
-        ui->sp_naEdit->setValue(product->w2_sodium);
-        ui->sp_clEdit->setValue(product->w2_chloride);
-        ui->sp_so4Edit->setValue(product->w2_sulfate);
-        ui->sp_phShow->setValue(product->w2_ph);
-        ui->sp_hardnessEdit->setValue(Utils::Hardness(product->w2_calcium, product->w2_magnesium));
-        ui->sp_raEdit->setValue(Utils::ResidualAlkalinity(product->w2_total_alkalinity, product->w2_calcium, product->w2_magnesium));
     } else if (product->sparge_source == 2 && product->w2_ph > 0.0) {
+	product->ws_calcium = product->wg_calcium;
+	product->ws_magnesium = product->wg_magnesium;
+	product->ws_total_alkalinity = product->wg_total_alkalinity;
+	product->ws_sodium = product->wg_sodium;
+	product->ws_chloride = product->wg_chloride;
+	product->ws_sulfate = product->wg_sulfate;
 	Source_pH = product->wg_ph;
-	Source_alkalinity = product->wg_total_alkalinity;
-	ui->sp_caEdit->setValue(product->wg_calcium);
-	ui->sp_mgEdit->setValue(product->wg_magnesium);
-	ui->sp_hco3Edit->setValue(Utils::Bicarbonate(product->wg_total_alkalinity, product->wg_ph));
-	ui->sp_caco3Edit->setValue(product->wg_total_alkalinity);
-	ui->sp_naEdit->setValue(product->wg_sodium);
-	ui->sp_clEdit->setValue(product->wg_chloride);
-	ui->sp_so4Edit->setValue(product->wg_sulfate);
-	ui->sp_phShow->setValue(product->wg_ph);
-	ui->sp_hardnessEdit->setValue(Utils::Hardness(product->wg_calcium, product->wg_magnesium));
-	ui->sp_raEdit->setValue(Utils::ResidualAlkalinity(product->wg_total_alkalinity, product->wg_calcium, product->wg_magnesium));
     } else {
-	ui->sp_caEdit->setValue(product->w1_calcium);
-	ui->sp_mgEdit->setValue(product->w1_magnesium);
-	ui->sp_hco3Edit->setValue(Utils::Bicarbonate(product->w1_total_alkalinity, product->w1_ph));
-	ui->sp_caco3Edit->setValue(product->w1_total_alkalinity);
-	ui->sp_naEdit->setValue(product->w1_sodium);
-	ui->sp_clEdit->setValue(product->w1_chloride);
-	ui->sp_so4Edit->setValue(product->w1_sulfate);
-	ui->sp_phShow->setValue(product->w1_ph);
-	ui->sp_hardnessEdit->setValue(Utils::Hardness(product->w1_calcium, product->w1_magnesium));
-	ui->sp_raEdit->setValue(Utils::ResidualAlkalinity(product->w1_total_alkalinity, product->w1_calcium, product->w1_magnesium));
+	product->ws_calcium = product->w1_calcium;
+	product->ws_magnesium = product->w1_magnesium;
+	product->ws_total_alkalinity = product->w1_total_alkalinity;
+	product->ws_sodium = product->w1_sodium;
+	product->ws_chloride = product->w1_chloride;
+	product->ws_sulfate = product->w1_sulfate;
+	Source_pH = product->w1_ph;
     }
-    // The spargewater is set.
+
+    /* Calculate Salt additions */
+    if (product->sparge_volume > 0) {
+	product->ws_calcium += ( ui->ss_cacl2Edit->value() * MMCa / MMCaCl2 * 1000 + ui->ss_caso4Edit->value() * MMCa / MMCaSO4 * 1000) / product->sparge_volume;
+	product->ws_magnesium += (ui->ss_mgso4Edit->value() * MMMg / MMMgSO4 * 1000 + ui->ss_mgcl2Edit->value() * MMMg / MMMgCl2 * 1000) / product->sparge_volume;
+	product->ws_sodium += (ui->ss_naclEdit->value() * MMNa / MMNaCl * 1000) / product->sparge_volume;
+	product->ws_sulfate += (ui->ss_caso4Edit->value() * MMSO4 / MMCaSO4 * 1000 + ui->ss_mgso4Edit->value() * MMSO4 / MMMgSO4 * 1000) / product->sparge_volume;
+	product->ws_chloride += (2 * ui->ss_cacl2Edit->value() * MMCl / MMCaCl2 * 1000 + ui->ss_naclEdit->value() * MMCl / MMNaCl * 1000 +
+				ui->ss_mgcl2Edit->value() * MMCl / MMMgCl2 * 1000) / product->sparge_volume;
+    }
+
+    /* Show the spargewater with salt additions. */
+    ui->sp_caEdit->setValue(product->ws_calcium);
+    ui->sp_mgEdit->setValue(product->ws_magnesium);
+    ui->sp_hco3Edit->setValue(Utils::Bicarbonate(product->ws_total_alkalinity, Source_pH));
+    ui->sp_caco3Edit->setValue(product->ws_total_alkalinity);
+    ui->sp_naEdit->setValue(product->ws_sodium);
+    ui->sp_clEdit->setValue(product->ws_chloride);
+    ui->sp_so4Edit->setValue(product->ws_sulfate);
+    ui->sp_phShow->setValue(product->sparge_ph);
+    ui->sp_hardnessEdit->setValue(Utils::Hardness(product->ws_calcium, product->ws_magnesium));
+    ui->sp_raEdit->setValue(Utils::ResidualAlkalinity(product->ws_total_alkalinity, product->ws_calcium, product->ws_magnesium));
 
     int AT = product->sparge_acid_type;
     if (AT < 0 || AT >= my_acids.size()) {
@@ -545,7 +551,7 @@
     	double f343 = r143 * r243 / d43;
 
     	// Step 4. Solve
-    	double Ct = Source_alkalinity / 50 / ((f143 - f1) + (f3 - f343));
+    	double Ct = product->ws_total_alkalinity / 50 / ((f143 - f1) + (f3 - f343));
 
     	// Step 5. Compute mole fractions at desired pH
     	double r1g = pow(10, TargetpH - 6.35);
@@ -581,7 +587,7 @@
     	ui->sp_acidvolEdit->setValue(Acid);
     }
 
-    ui->sp_phShow->setValue(product->sparge_ph);
+//    ui->sp_phShow->setValue(product->sparge_ph);
     // Finally calculate the estimate preboil pH
     product->est_preboil_ph = -log10(((pow(10, -product->mash_ph) * product->wg_amount) + (pow(10, -product->sparge_ph) * product->brew_sparge_est)) /
 		     	      (product->wg_amount + product->brew_sparge_est));
@@ -602,6 +608,12 @@
 
 void EditProduct::sp_volume_changed(double val)
 {
+    if (! product->calc_acid) {
+	product->sparge_acid_amount *= val / product->sparge_volume;
+	const QSignalBlocker blocker1(ui->sp_acidvolEdit);
+	ui->sp_acidvolEdit->setValue(product->sparge_acid_amount * 1000.0);
+    }
+
     product->sparge_volume = val;
     ui->brew_spargevolShow->setValue(val);
     calcSparge();
--- a/src/EditRecipe.cpp	Tue Jul 19 16:00:52 2022 +0200
+++ b/src/EditRecipe.cpp	Wed Jul 20 12:44:02 2022 +0200
@@ -341,7 +341,6 @@
     ui->sp_phEdit->setValue(recipe->sparge_ph);
     ui->sp_acidtypeEdit->setCurrentIndex(recipe->sparge_acid_type);
     ui->sp_acidpercEdit->setValue(recipe->sparge_acid_perc);
-    ui->sp_acidvolEdit->setValue(recipe->sparge_acid_amount);
 
     // All signals from tab "Generic"
     connect(ui->lockedEdit, &QCheckBox::stateChanged, this, &EditRecipe::is_changed);
@@ -410,6 +409,7 @@
     connect(ui->spargeGroup, SIGNAL(buttonClicked(int)), this, SLOT(sp_group_changed(int)));
     connect(ui->sp_acidtypeEdit, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &EditRecipe::sp_type_changed);
     connect(ui->sp_phEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditRecipe::sp_ph_changed);
+    connect(ui->sp_volEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditRecipe::sp_vol_changed);
     connect(ui->sp_acidvolEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &EditRecipe::sp_acid_changed);
     setLocked(recipe->locked);
 
--- a/src/EditRecipe.h	Tue Jul 19 16:00:52 2022 +0200
+++ b/src/EditRecipe.h	Wed Jul 20 12:44:02 2022 +0200
@@ -120,6 +120,7 @@
     void sp_group_changed(int val);
     void sp_type_changed(int val);
     void sp_ph_changed(double val);
+    void sp_vol_changed(double val);
     void sp_acid_changed(double val);
     void step_name_changed(QString val);
     void step_type_changed(int val);
--- a/src/EditRecipeTab7.cpp	Tue Jul 19 16:00:52 2022 +0200
+++ b/src/EditRecipeTab7.cpp	Wed Jul 20 12:44:02 2022 +0200
@@ -470,51 +470,58 @@
 void EditRecipe::calcSparge()
 {
     double TargetpH = recipe->sparge_ph;
-    double Source_pH = recipe->w1_ph;
-    double Source_alkalinity = recipe->w1_total_alkalinity;
+    double Source_pH = 7.0;
 
     qDebug() << "calcSparge()";
     setButtons(recipe->locked);
 
     if (recipe->sparge_source == 1 && recipe->w2_ph > 0.0) {
-	Source_pH = recipe->w2_ph;
-	Source_alkalinity = recipe->w2_total_alkalinity;
-	ui->sp_caEdit->setValue(recipe->w2_calcium);
-        ui->sp_mgEdit->setValue(recipe->w2_magnesium);
-        ui->sp_hco3Edit->setValue(Utils::Bicarbonate(recipe->w2_total_alkalinity, recipe->w2_ph));
-        ui->sp_caco3Edit->setValue(recipe->w2_total_alkalinity);
-        ui->sp_naEdit->setValue(recipe->w2_sodium);
-        ui->sp_clEdit->setValue(recipe->w2_chloride);
-        ui->sp_so4Edit->setValue(recipe->w2_sulfate);
-        ui->sp_phShow->setValue(recipe->w2_ph);
-        ui->sp_hardnessEdit->setValue(Utils::Hardness(recipe->w2_calcium, recipe->w2_magnesium));
-        ui->sp_raEdit->setValue(Utils::ResidualAlkalinity(recipe->w2_total_alkalinity, recipe->w2_calcium, recipe->w2_magnesium));
+	recipe->ws_calcium = recipe->w2_calcium;
+        recipe->ws_magnesium = recipe->w2_magnesium;
+        recipe->ws_total_alkalinity = recipe->w2_total_alkalinity;
+        recipe->ws_sodium = recipe->w2_sodium;
+        recipe->ws_chloride = recipe->w2_chloride;
+        recipe->ws_sulfate = recipe->w2_sulfate;
+        Source_pH = recipe->w2_ph;
     } else if (recipe->sparge_source == 2 && recipe->w2_ph > 0.0) {
-	Source_pH = recipe->wg_ph;
-	Source_alkalinity = recipe->wg_total_alkalinity;
-	ui->sp_caEdit->setValue(recipe->wg_calcium);
-	ui->sp_mgEdit->setValue(recipe->wg_magnesium);
-	ui->sp_hco3Edit->setValue(Utils::Bicarbonate(recipe->wg_total_alkalinity, recipe->wg_ph));
-	ui->sp_caco3Edit->setValue(recipe->wg_total_alkalinity);
-	ui->sp_naEdit->setValue(recipe->wg_sodium);
-	ui->sp_clEdit->setValue(recipe->wg_chloride);
-	ui->sp_so4Edit->setValue(recipe->wg_sulfate);
-	ui->sp_phShow->setValue(recipe->wg_ph);
-	ui->sp_hardnessEdit->setValue(Utils::Hardness(recipe->wg_calcium, recipe->wg_magnesium));
-	ui->sp_raEdit->setValue(Utils::ResidualAlkalinity(recipe->wg_total_alkalinity, recipe->wg_calcium, recipe->wg_magnesium));
+	recipe->ws_calcium = recipe->wg_calcium;
+        recipe->ws_magnesium = recipe->wg_magnesium;
+        recipe->ws_total_alkalinity = recipe->wg_total_alkalinity;
+        recipe->ws_sodium = recipe->wg_sodium;
+        recipe->ws_chloride = recipe->wg_chloride;
+        recipe->ws_sulfate = recipe->wg_sulfate;
+        Source_pH = recipe->wg_ph;
     } else {
-	ui->sp_caEdit->setValue(recipe->w1_calcium);
-	ui->sp_mgEdit->setValue(recipe->w1_magnesium);
-	ui->sp_hco3Edit->setValue(Utils::Bicarbonate(recipe->w1_total_alkalinity, recipe->w1_ph));
-	ui->sp_caco3Edit->setValue(recipe->w1_total_alkalinity);
-	ui->sp_naEdit->setValue(recipe->w1_sodium);
-	ui->sp_clEdit->setValue(recipe->w1_chloride);
-	ui->sp_so4Edit->setValue(recipe->w1_sulfate);
-	ui->sp_phShow->setValue(recipe->w1_ph);
-	ui->sp_hardnessEdit->setValue(Utils::Hardness(recipe->w1_calcium, recipe->w1_magnesium));
-	ui->sp_raEdit->setValue(Utils::ResidualAlkalinity(recipe->w1_total_alkalinity, recipe->w1_calcium, recipe->w1_magnesium));
+	recipe->ws_calcium = recipe->w1_calcium;
+	recipe->ws_magnesium = recipe->w1_magnesium;
+	recipe->ws_total_alkalinity = recipe->w1_total_alkalinity;
+	recipe->ws_sodium = recipe->w1_sodium;
+	recipe->ws_chloride = recipe->w1_chloride;
+	recipe->ws_sulfate = recipe->w1_sulfate;
+	Source_pH = recipe->w1_ph;
     }
-    // The spargewater is set.
+
+    /* Calculate Salt additions */
+    if (recipe->sparge_volume > 0) {
+	recipe->ws_calcium += ( ui->ss_cacl2Edit->value() * MMCa / MMCaCl2 * 1000 + ui->ss_caso4Edit->value() * MMCa / MMCaSO4 * 1000) / recipe->sparge_volume;
+	recipe->ws_magnesium += (ui->ss_mgso4Edit->value() * MMMg / MMMgSO4 * 1000 + ui->ss_mgcl2Edit->value() * MMMg / MMMgCl2 * 1000) / recipe->sparge_volume;
+	recipe->ws_sodium += (ui->ss_naclEdit->value() * MMNa / MMNaCl * 1000) / recipe->sparge_volume;
+	recipe->ws_sulfate += (ui->ss_caso4Edit->value() * MMSO4 / MMCaSO4 * 1000 + ui->ss_mgso4Edit->value() * MMSO4 / MMMgSO4 * 1000) / recipe->sparge_volume;
+	recipe->ws_chloride += (2 * ui->ss_cacl2Edit->value() * MMCl / MMCaCl2 * 1000 + ui->ss_naclEdit->value() * MMCl / MMNaCl * 1000 +
+				ui->ss_mgcl2Edit->value() * MMCl / MMMgCl2 * 1000) / recipe->sparge_volume;
+    }
+
+    /* Show the spargewater with salt additions. */
+    ui->sp_caEdit->setValue(recipe->ws_calcium);
+    ui->sp_mgEdit->setValue(recipe->ws_magnesium);
+    ui->sp_hco3Edit->setValue(Utils::Bicarbonate(recipe->ws_total_alkalinity, Source_pH));
+    ui->sp_caco3Edit->setValue(recipe->ws_total_alkalinity);
+    ui->sp_naEdit->setValue(recipe->ws_sodium);
+    ui->sp_clEdit->setValue(recipe->ws_chloride);
+    ui->sp_so4Edit->setValue(recipe->ws_sulfate);
+    ui->sp_phShow->setValue(recipe->sparge_ph);
+    ui->sp_hardnessEdit->setValue(Utils::Hardness(recipe->ws_calcium, recipe->ws_magnesium));
+    ui->sp_raEdit->setValue(Utils::ResidualAlkalinity(recipe->ws_total_alkalinity, recipe->ws_calcium, recipe->ws_magnesium));
 
     int AT = recipe->sparge_acid_type;
     if (AT < 0 || AT >= my_acids.size()) {
@@ -544,7 +551,7 @@
     	double f343 = r143 * r243 / d43;
 
     	// Step 4. Solve
-    	double Ct = Source_alkalinity / 50 / ((f143 - f1) + (f3 - f343));
+    	double Ct = recipe->ws_total_alkalinity / 50 / ((f143 - f1) + (f3 - f343));
 
     	// Step 5. Compute mole fractions at desired pH
     	double r1g = pow(10, TargetpH - 6.35);
@@ -578,7 +585,6 @@
     	ui->sp_acidvolEdit->setValue(Acid);
     }
 
-    ui->sp_phShow->setValue(recipe->sparge_ph);
     // Finally calculate the estimate preboil pH
     recipe->preboil_ph = -log10(((pow(10, -recipe->mash_ph) * recipe->wg_amount) + (pow(10, -recipe->sparge_ph) * recipe->sparge_volume)) /
                              (recipe->wg_amount + recipe->sparge_volume));
@@ -629,6 +635,20 @@
 }
 
 
+void EditRecipe::sp_vol_changed(double val)
+{
+    if (! recipe->calc_acid) {
+	recipe->sparge_acid_amount *= val / recipe->sparge_volume;
+	const QSignalBlocker blocker1(ui->sp_acidvolEdit);
+	ui->sp_acidvolEdit->setValue(recipe->sparge_acid_amount * 1000.0);
+    }
+
+    recipe->sparge_volume = val;
+    calcSparge();
+    is_changed();
+}
+
+
 void EditRecipe::sp_acid_changed(double val)
 {
     if (recipe->calc_acid)
--- a/src/global.h	Tue Jul 19 16:00:52 2022 +0200
+++ b/src/global.h	Wed Jul 20 12:44:02 2022 +0200
@@ -399,6 +399,12 @@
     int		mashs_time;		///< Total mash time.
     double	preboil_sg;
     double      preboil_ph;
+    double	ws_calcium;		///< Sparge water calculated.
+    double      ws_sulfate;
+    double      ws_chloride;
+    double      ws_sodium;
+    double      ws_magnesium;
+    double      ws_total_alkalinity;
 };
 
 
@@ -651,12 +657,18 @@
     double	est_mash_sg;
     double	est_preboil_ph;
     double	preboil_sg;
-    double	final_abv;		/// ABV after dilution/infusion.
+    double	final_abv;		///< ABV after dilution/infusion.
     double	bottle_abv;
     double	bottle_bar;
     double	keg_abv;
     double	keg_bar;
-    QList<Splits>	splits;		/// Used during building a split batch
+    QList<Splits>	splits;		///< Used during building a split batch
+    double      ws_calcium;             ///< Sparge water calculated.
+    double      ws_sulfate;
+    double      ws_chloride;
+    double      ws_sodium;
+    double      ws_magnesium;
+    double      ws_total_alkalinity;
 };
 
 

mercurial