244 /* |
244 /* |
245 * Auto calculate the needed acid. |
245 * Auto calculate the needed acid. |
246 */ |
246 */ |
247 TpH = recipe->mash_ph; |
247 TpH = recipe->mash_ph; |
248 protonDeficit = ProtonDeficit(TpH); |
248 protonDeficit = ProtonDeficit(TpH); |
249 qDebug() << "calc_acid tgt:" << TpH << "protonDeficit:" << protonDeficit; |
249 qDebug() << " calc_acid tgt:" << TpH << "protonDeficit:" << protonDeficit; |
250 if (protonDeficit > 0) { |
250 if (protonDeficit > 0) { |
251 qDebug() << "pkn:" << AT << my_acids[AT].pK1 << my_acids[AT].pK2 << my_acids[AT].pK3; |
|
252 frac = Utils::CalcFrac(TpH, my_acids[AT].pK1, my_acids[AT].pK2, my_acids[AT].pK3); |
251 frac = Utils::CalcFrac(TpH, my_acids[AT].pK1, my_acids[AT].pK2, my_acids[AT].pK3); |
253 Acid = protonDeficit / frac; |
252 Acid = protonDeficit / frac; |
254 qDebug() << "1" << frac << Acid << protonDeficit; |
|
255 Acid *= my_acids[AT].MolWt; // mg. |
253 Acid *= my_acids[AT].MolWt; // mg. |
256 Acidmg = Acid; |
254 Acidmg = Acid; |
257 Acid = Acid / my_acids[AT].AcidSG; |
255 Acid = Acid / my_acids[AT].AcidSG; |
258 Acid = round((Acid / (recipe->wa_acid_perc / 100.0)) * 100.0) / 100.0; |
256 Acid = round((Acid / (recipe->wa_acid_perc / 100.0)) * 100.0) / 100.0; |
259 qDebug() << "Mash auto Acid final ml:" << Acid; |
257 qDebug() << " Mash auto Acid final ml:" << Acid; |
260 |
258 |
261 for (int i = 0; i < recipe->miscs.size(); i++) { |
259 QString w = my_acids[AT].name_en + ' ' + my_acids[AT].name_nl; |
262 qDebug() << i << recipe->miscs.at(i).m_name << my_acids[AT].name_en; |
260 brewing_salt_sub(w, Acid); |
263 if (recipe->miscs.at(i).m_name == my_acids[AT].name_en || recipe->miscs.at(i).m_name == my_acids[AT].name_nl) { |
261 this->ignoreChanges = true; |
264 qDebug() << "found at" << i << recipe->miscs.at(i).m_amount << Acid / 1000.0; |
262 ui->mw_acidvolEdit->setValue(Acid); |
265 recipe->miscs[i].m_amount = Acid / 1000.0; |
263 this->ignoreChanges = false; |
266 QTableWidgetItem *item = new QTableWidgetItem(QString("%1 ml").arg(Acid, 3, 'f', 2, '0')); |
264 |
267 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
|
268 ui->miscsTable->setItem(i, 4, item); |
|
269 this->ignoreChanges = true; |
|
270 ui->mw_acidvolEdit->setValue(Acid); |
|
271 this->ignoreChanges = false; |
|
272 break; |
|
273 } |
|
274 } |
|
275 bicarbonate = bicarbonate - protonDeficit * frac / liters; |
265 bicarbonate = bicarbonate - protonDeficit * frac / liters; |
276 total_alkalinity = bicarbonate * 50 / 61; |
266 total_alkalinity = bicarbonate * 50 / 61; |
277 } |
267 } |
278 ph = TpH; |
268 ph = TpH; |
279 ui->wb_phEdit->setValue(ph); |
269 ui->wb_phEdit->setValue(ph); |
280 |
270 recipe->mash_ph = ph; |
281 //recipe->est_mash_ph = ph |
|
282 } else { // Manual |
271 } else { // Manual |
283 /* |
272 /* |
284 * Manual adjust acid, calculate resulting pH. |
273 * Manual adjust acid, calculate resulting pH. |
285 */ |
274 */ |
|
275 double pHa = ph; // Mixed water pH. |
|
276 // Then calculate the new pH with added acids and malts |
|
277 qDebug() << " Mash pH:" << pHa; |
|
278 Acid = my_acids[AT].AcidSG * (recipe->wa_acid_perc / 100.0); // ml |
|
279 Acid *= ui->mw_acidvolEdit->value(); |
|
280 Acid /= my_acids[AT].MolWt; // mg; |
|
281 Acidmg = Acid; |
|
282 |
|
283 //find the pH where the protondeficit = protondeficit by the acid |
|
284 frac = Utils::CalcFrac(pHa, my_acids[AT].pK1, my_acids[AT].pK2, my_acids[AT].pK3); |
|
285 protonDeficit = Acid * frac; |
|
286 //qDebug() << " protonDeficit Acid:" << protonDeficit << "frac:" << frac << "pH:" << pHa; |
|
287 |
|
288 double deltapH = 0.001; |
|
289 double deltapd = 0.1; |
|
290 double pd = round(ProtonDeficit(pHa) * 1000000.0) / 1000000.0; |
|
291 int n = 0; |
|
292 while (((pd < (protonDeficit - deltapd)) || (pd > (protonDeficit + deltapd))) && (n < 4000)) { |
|
293 n++; |
|
294 if (pd < (protonDeficit - deltapd)) |
|
295 pHa -= deltapH; |
|
296 else if (pd > (protonDeficit + deltapd)) |
|
297 pHa += deltapH; |
|
298 frac = Utils::CalcFrac(pHa, my_acids[AT].pK1, my_acids[AT].pK2, my_acids[AT].pK3); |
|
299 protonDeficit = Acid * frac; |
|
300 pd = ProtonDeficit(pHa); |
|
301 } |
|
302 //qDebug() << " n:" << n << "pd:" << pd << "protonDeficit:" << protonDeficit << "frac:" << frac << "pHa:" << pHa; |
|
303 |
|
304 bicarbonate = wg_bicarbonate - protonDeficit * frac / liters; |
|
305 total_alkalinity = bicarbonate * 50 / 61; |
|
306 ph = pHa; |
|
307 ui->wb_phEdit->setValue(ph); |
|
308 ui->mw_phEdit->setValue(ph); |
|
309 recipe->mash_ph = ph; |
|
310 } |
|
311 |
|
312 if ((AT == 3) && (liters > 0)) { // Sulfuctic / Zwavelzuur |
|
313 RA = ui->bs_caso4Edit->value() * MMSO4 / MMCaSO4 + ui->bs_mgso4Edit->value() * MMSO4 / MMMgSO4 + Acidmg / 1000 * MMSO4 / (MMSO4 + 2); |
|
314 RA = 1000 * RA / liters; |
|
315 sulfate = wg_sulfate + RA; // Not add to sulfate?? |
|
316 } else if ((AT == 1) && (liters > 0)) { // Hydrochloric, Zoutzuur |
|
317 RA = ui->bs_cacl2Edit->value() * MMCl / MMCaCl2 + ui->bs_naclEdit->value() * MMCl / MMNaCl + Acidmg / 1000 * MMCl / (MMCl + 1); |
|
318 RA = 1000 * RA / liters; |
|
319 chloride = wg_chloride + RA; |
286 } |
320 } |
287 |
321 |
288 ui->wb_caEdit->setValue(calcium); |
322 ui->wb_caEdit->setValue(calcium); |
289 ui->wb_mgEdit->setValue(magnesium); |
323 ui->wb_mgEdit->setValue(magnesium); |
290 ui->wb_hco3Edit->setValue(bicarbonate); |
324 ui->wb_hco3Edit->setValue(bicarbonate); |
328 is_changed(); |
362 is_changed(); |
329 calcWater(); |
363 calcWater(); |
330 } |
364 } |
331 |
365 |
332 |
366 |
|
367 void EditRecipe::on_mw_ph_changed(double val) |
|
368 { |
|
369 if (! recipe->calc_acid) |
|
370 return; |
|
371 |
|
372 qDebug() << "on_mw_ph_changed" << val; |
|
373 recipe->mash_ph = val; |
|
374 is_changed(); |
|
375 calcWater(); |
|
376 } |
|
377 |
|
378 |
|
379 void EditRecipe::on_mw_acid_changed(double val) |
|
380 { |
|
381 if (recipe->calc_acid) |
|
382 return; |
|
383 |
|
384 qDebug() << "on_mw_acid_changed" << val; |
|
385 QString w = my_acids[recipe->wa_acid_name].name_en + ' ' + my_acids[recipe->wa_acid_name].name_nl; |
|
386 set_brewing_salt(w, val); |
|
387 } |
|
388 |
|
389 |
|
390 void EditRecipe::on_mw_type_changed(int val) |
|
391 { |
|
392 if (val == recipe->wa_acid_name) |
|
393 return; |
|
394 |
|
395 qDebug() << "on_mw_type_changed" << val << "old" << recipe->wa_acid_name; |
|
396 /* |
|
397 * First remove current acid. |
|
398 */ |
|
399 QString w = my_acids[recipe->wa_acid_name].name_en + ' ' + my_acids[recipe->wa_acid_name].name_nl; |
|
400 brewing_salt_sub(w, 0); |
|
401 |
|
402 recipe->wa_acid_name = val; |
|
403 w = my_acids[recipe->wa_acid_name].name_en + ' ' + my_acids[recipe->wa_acid_name].name_nl; |
|
404 |
|
405 recipe->wa_acid_perc = my_acids.at(val).AcidPrc; |
|
406 // ui->mw_acidPick->setCurrentIndex(val); |
|
407 ui->mw_acidpercEdit->setValue(my_acids.at(val).AcidPrc); |
|
408 brewing_salt_sub(w, ui->mw_acidvolEdit->value()); // For now, set old amount. |
|
409 |
|
410 is_changed(); |
|
411 calcWater(); |
|
412 } |
|
413 |
|
414 |
333 void EditRecipe::on_w2_vol_changed(double val) |
415 void EditRecipe::on_w2_vol_changed(double val) |
334 { |
416 { |
335 } |
417 qDebug() << "on_w2_vol_changed" << val; |
336 |
418 } |
337 |
419 |
338 void EditRecipe::on_cacl2_changed(double val) |
420 |
339 { |
421 void EditRecipe::on_cacl2_changed(double val) { set_brewing_salt("CaCl2", val); } |
340 set_brewing_salt("CaCl2", val); |
422 void EditRecipe::on_caso4_changed(double val) { set_brewing_salt("CaSO4", val); } |
341 } |
423 void EditRecipe::on_mgso4_changed(double val) { set_brewing_salt("MgSO4", val); } |
342 |
424 void EditRecipe::on_nacl_changed(double val) { set_brewing_salt("NaCl", val); } |
343 |
425 void EditRecipe::on_mgcl2_changed(double val) { set_brewing_salt("MgCl2", val); } |
344 void EditRecipe::on_caso4_changed(double val) |
426 void EditRecipe::on_nahco3_changed(double val) { set_brewing_salt("NaHCO3", val); } |
345 { |
427 void EditRecipe::on_caco3_changed(double val) { set_brewing_salt("CaCO3", val); } |
346 set_brewing_salt("CaSO4", val); |
428 |
347 } |
429 |
348 |
|
349 |
|
350 void EditRecipe::on_mgso4_changed(double val) |
|
351 { |
|
352 set_brewing_salt("MgSO4", val); |
|
353 } |
|
354 |
|
355 |
|
356 void EditRecipe::on_nacl_changed(double val) |
|
357 { |
|
358 set_brewing_salt("NaCl", val); |
|
359 } |
|
360 |
|
361 |
|
362 void EditRecipe::on_mgcl2_changed(double val) |
|
363 { |
|
364 set_brewing_salt("MgCl2", val); |
|
365 } |
|
366 |
|
367 |
|
368 void EditRecipe::on_nahco3_changed(double val) |
|
369 { |
|
370 set_brewing_salt("NaHCO3", val); |
|
371 } |
|
372 |
|
373 |
|
374 void EditRecipe::on_caco3_changed(double val) |
|
375 { |
|
376 set_brewing_salt("CaCO3", val); |
|
377 } |
|
378 |
|
379 |
|
380 |
|