377 |
377 |
378 /* |
378 /* |
379 * Formula is from the 'Mash Made Easy' spreadsheet. |
379 * Formula is from the 'Mash Made Easy' spreadsheet. |
380 * https://mashmadeeasy.yolasite.com/ |
380 * https://mashmadeeasy.yolasite.com/ |
381 * https://www.homebrewtalk.com/threads/a-rather-simplified-whirlpool-hop-ibu-computation-method.701093/ |
381 * https://www.homebrewtalk.com/threads/a-rather-simplified-whirlpool-hop-ibu-computation-method.701093/ |
|
382 * |
|
383 * Source of the formula Mark G. Malowicki. |
382 */ |
384 */ |
383 double Utils::IBU_reduction(double Tc) |
385 double Utils::IBU_reduction(double Tc) |
384 { |
386 { |
385 return (2.39 * pow(10, 11) * pow(2.71828182846, - (9773 / (Tc + Kelvin))) ) * 1/1.009231744; |
387 /* |
386 } |
388 * Original formula plus a small correction factor. |
387 |
389 */ |
388 |
390 return (2.39 * pow(10, 11) * exp(-(9773 / (Tc + Kelvin))) ) * 1/1.009231743647; |
389 double Utils::boilIBU(int Form, double SG, double Volume, double Amount, double Time, double Alpha, int Method) |
391 } |
390 { |
392 |
391 double ibu = 0.0, sgfactor, boilfactor; |
393 |
392 |
394 double Utils::TinsethIBU(double SG, double Volume, double Amount, double Time, double Alpha) |
|
395 { |
393 double alpha = Alpha / 100.0; |
396 double alpha = Alpha / 100.0; |
394 double mass = Amount * 1000.0; |
397 double mass = Amount * 1000.0; |
395 |
398 |
396 if (Method == 0) { // Tinseth |
399 /* |
397 /* http://realbeer.com/hops/research.html */ |
400 * Basic Tinseth formula. |
398 double AddedAlphaAcids = (alpha * mass * 1000) / Volume; |
401 * http://realbeer.com/hops/research.html |
399 double Bigness_factor = 1.65 * pow(0.000125, SG - 1); |
402 */ |
400 double BoilTime_factor = ((1 - exp(-0.04 * Time)) / 4.15); |
403 double AddedAlphaAcids = (alpha * mass * 1000) / Volume; |
401 ibu = Bigness_factor * BoilTime_factor * AddedAlphaAcids; |
404 double Bigness_factor = 1.65 * pow(0.000125, SG - 1); |
402 } |
405 double BoilTime_factor = ((1 - exp(-0.04 * Time)) / 4.15); |
403 if (Method == 2) { // Daniels |
406 double ibu = Bigness_factor * BoilTime_factor * AddedAlphaAcids; |
404 if (Form == 2) // Leaf |
407 |
405 boilfactor = -(0.0041 * Time * Time) + (0.6162 * Time) + 1.5779; |
408 qDebug() << "boilIBU" << SG << Volume << Amount << Time << Alpha << "IBU:" << ibu; |
406 else |
|
407 boilfactor = -(0.0051 * Time * Time) + (0.7835 * Time) + 1.9348; |
|
408 if (SG < 1.050) |
|
409 sgfactor = 0; |
|
410 else |
|
411 sgfactor = ((SG * 1000) - 1050) / 200; |
|
412 ibu = (mass * (alpha * 100) * boilfactor * 0.1) / (Volume * (1 + sgfactor)); |
|
413 } |
|
414 if (Method == 1) { // Rager |
|
415 boilfactor = 18.11 + 13.86 * tanh((Time * 31.32) / 18.27); |
|
416 if (SG < 1.050) |
|
417 sgfactor = 0; |
|
418 else |
|
419 sgfactor = ((SG * 1000) - 1050) / 200; |
|
420 ibu = (mass * (alpha * 100) * boilfactor * 0.1) / (Volume * (1 + sgfactor)); |
|
421 } |
|
422 |
|
423 //qDebug() << "boilIBU" << Form << SG << Volume << Amount << Time << Alpha << Method << "IBU:" << ibu; |
|
424 return ibu; |
409 return ibu; |
425 } |
410 } |
426 |
411 |
427 |
412 |
428 double Utils::toIBU(int Use, int Form, double SG, double Volume, double Amount, double Boiltime, double Alpha, |
413 double Utils::toIBU(int Use, int Form, double SG, double Volume, double Amount, double Boiltime, double Alpha, |
429 int Method, double Whirlpool9, double Whirlpool7, double Whirlpool6, double Fulltime) |
414 int Method, double Whirlpool9, double Whirlpool7, double Whirlpool6, double Fulltime) |
430 { |
415 { |
|
416 double loss_boiltemp = 1.0; /* Loss due to the lower boil temperature at higher altitude. */ |
|
417 |
431 double ibu = 0.0, whirlibus = 0.0; |
418 double ibu = 0.0, whirlibus = 0.0; |
432 double alpha = Alpha / 100.0; |
419 double alpha = Alpha / 100.0; |
433 double mass = Amount * 1000.0; |
420 double mass = Amount * 1000.0; |
434 |
421 |
435 // Ideas from Zymurgy March-April 2018. These are not exact formulas! |
422 // Ideas from Zymurgy March-April 2018. These are not exact formulas! |
475 |
462 |
476 /* |
463 /* |
477 * IBU's from hops during Mash, FWH and boil. |
464 * IBU's from hops during Mash, FWH and boil. |
478 */ |
465 */ |
479 if ((Use == HOP_USEAT_MASH) || (Use == HOP_USEAT_FWH) || (Use == HOP_USEAT_BOIL)) { |
466 if ((Use == HOP_USEAT_MASH) || (Use == HOP_USEAT_FWH) || (Use == HOP_USEAT_BOIL)) { |
480 ibu = boilIBU(Form, SG, Volume, Amount, Fulltime, Alpha, Method); |
467 ibu = TinsethIBU(SG, Volume, Amount, Fulltime, Alpha); |
481 /* |
468 /* |
482 * Corrections for Mash and FWH |
469 * Corrections for Mash and FWH |
483 */ |
470 */ |
484 if (Use == HOP_USEAT_MASH) { |
471 if (Use == HOP_USEAT_MASH) { |
485 ibu *= (1 + my_factor_mashhop / 100.0); |
472 ibu *= (1 + my_factor_mashhop / 100.0); |
500 } else if (Form == HOP_FORMS_CRYO) { |
487 } else if (Form == HOP_FORMS_CRYO) { |
501 ibu *= (1 + my_factor_cryohop / 100.0); |
488 ibu *= (1 + my_factor_cryohop / 100.0); |
502 } else if (Form == HOP_FORMS_EXTRACT) { |
489 } else if (Form == HOP_FORMS_EXTRACT) { |
503 // Nothing for now. |
490 // Nothing for now. |
504 } |
491 } |
505 // ibu *= IBU_reduction(boilPoint()); |
492 |
506 // qDebug() << "ibu" << ibu << IBU_reduction(boilPoint()); |
493 if (Method > 0) { |
|
494 loss_boiltemp = IBU_reduction(boilPoint()); |
|
495 ibu *= loss_boiltemp; |
|
496 qDebug() << "ibu" << ibu << "loss_boiltemp" << loss_boiltemp; |
|
497 } |
507 |
498 |
508 // } else if (Use == HOP_USEAT_AROMA) { |
499 // } else if (Use == HOP_USEAT_AROMA) { |
509 /* |
500 /* |
510 * At flameout. The cooling method is important. |
501 * At flameout. The cooling method is important. |
511 * Emersion chiller, Counterflow chiller, Au bain marie or natural. |
502 * Emersion chiller, Counterflow chiller, Au bain marie or natural. |
512 * Assume the hop is removed for all methods except Emersion chilling. |
503 * Assume the hop is removed for all methods except Emersion chilling. |
513 */ |
504 */ |
514 } else { |
505 } else { |
515 // qDebug() << "whirlibus" << whirlibus << Use; |
506 // qDebug() << "whirlibus" << whirlibus << Use; |
516 } |
507 } |
517 |
|
518 |
508 |
519 return round((ibu + whirlibus) * 100.0) / 100.0; |
509 return round((ibu + whirlibus) * 100.0) / 100.0; |
520 } |
510 } |
521 |
511 |
522 |
512 |