diff -r b36d249512cc -r 19156b8b339f src/EditRecipeTab7.cpp --- a/src/EditRecipeTab7.cpp Mon Apr 25 12:53:36 2022 +0200 +++ b/src/EditRecipeTab7.cpp Mon Apr 25 15:52:21 2022 +0200 @@ -396,7 +396,120 @@ ui->wb_hco3Edit->setStyleSheet((bicarbonate > 250) ? "background-color: red":"background-color: green"); ui->wb_caco3Edit->setStyleSheet((bicarbonate > 250) ? "background-color: red":"background-color: green"); - // calcSparge(); + calcSparge(); +} + + +/* + * Based on the work of ajDeLange. + */ +void EditRecipe::calcSparge() +{ + double TargetpH = recipe->sparge_ph; + double Source_pH = recipe->w1_ph; + double Source_alkalinity = recipe->w1_total_alkalinity; + + qDebug() << "calcSparge()"; + + const QSignalBlocker blocker1(ui->sp_sourceEdit); + + // Select watersource or fallback to the first source. + if (recipe->sparge_source == 1) { // Source 2 + if (recipe->w2_ph > 0.0 && recipe->w2_amount > 0) { + Source_pH = recipe->w2_ph; + Source_alkalinity = recipe->w2_total_alkalinity; + } else { + recipe->sparge_source = 0; // Source 1 + ui->sp_sourceEdit->setCurrentIndex(0); + } + } else if (recipe->sparge_source == 2) { // Mixed + if (recipe->w2_ph > 0.0 && recipe->w2_amount > 0) { + Source_pH = recipe->wg_ph; + Source_alkalinity = recipe->wg_total_alkalinity; + } else { + recipe->sparge_source = 0; // Source 1 + ui->sp_sourceEdit->setCurrentIndex(0); + } + } + + // Step 1: Compute the mole fractions of carbonic (f1o), bicarbonate (f2o) and carbonate(f3o) at the water pH + double r1 = pow(10, Source_pH - 6.35); + double r2 = pow(10, Source_pH - 10.33); + double d = 1 + r1 + r1 * r2; + double f1 = 1 / d; + double f3 = r1 * r2 / d; + + // Step 2. Compute the mole fractions at pH = 4.3 (the pH which defines alkalinity) + double r143 = pow(10, 4.3 - 6.35); + double r243 = pow(10, 4.3 - 10.33); + double d43 = 1 + r143 + r143 * r243; + double f143 = 1 / d43; + double f343 = r143 * r243 / d43; + + // Step 4. Solve + //double Ct = (Source_alkalinity - 1000 * (pow(10, -4.3) - pow(10, -Source_pH))) / ((f143 - f1) + (f3 - f343)); + double Ct = Source_alkalinity / 50 / ((f143 - f1) + (f3 - f343)); + + // Step 5. Compute mole fractions at desired pH + double r1g = pow(10, TargetpH - 6.35); + double r2g = pow(10, TargetpH - 10.33); + double dg = 1 + r1g + r1g * r2g; + double f1g = 1 / dg; + double f3g = r1g * r2g / dg; + + // Step 6. Use these to compute the milliequivalents acid required per liter (mEq/L) + double Acid = Ct * ((f1g - f1) + (f3 - f3g)) + pow(10, -TargetpH) - pow(10, -Source_pH); //mEq/l + Acid += 0.01; // Add acid that would be required for distilled water. + + //Step 8. Get the acid data. + int AT = recipe->sparge_acid_type; + if (AT < 0 || AT >= my_acids.size()) { + AT = 0; + recipe->sparge_acid_type = 0; + ui->sp_acidtypeEdit->setCurrentIndex(0); + recipe->sparge_acid_perc = my_acids[0].AcidPrc; + ui->sp_acidpercEdit->setValue(recipe->sparge_acid_perc); + } + double fract = Utils::CalcFrac(TargetpH, my_acids[AT].pK1, my_acids[AT].pK2, my_acids[AT].pK3); + + // Step 9. Now divide the mEq required by the "fraction". This is the required number of moles of acid. + Acid /= fract; + + // Step 10. Multiply by molecular weight of the acid + Acid *= my_acids[AT].MolWt; //mg + + // Step 11. Divide by Specific Gravity and Percentage to get the final ml. + Acid = Acid / my_acids[AT].AcidSG / (recipe->sparge_acid_perc / 100); //ml + Acid *= recipe->sparge_volume; //ml acid total + Acid = round(Acid * 100.0) / 100.0; + recipe->sparge_acid_amount = Acid / 1000; + ui->sp_acidvolEdit->setValue(Acid); +} + + +void EditRecipe::sp_source_changed(int val) +{ + recipe->sparge_source = val; + calcSparge(); + is_changed(); +} + + +void EditRecipe::sp_type_changed(int val) +{ + recipe->sparge_acid_type = val; + recipe->sparge_acid_perc = my_acids[val].AcidPrc; + ui->sp_acidpercEdit->setValue(recipe->sparge_acid_perc); + calcSparge(); + is_changed(); +} + + +void EditRecipe::sp_ph_changed(double val) +{ + recipe->sparge_ph = val; + calcSparge(); + is_changed(); }