417 } |
417 } |
418 |
418 |
419 |
419 |
420 double Utils::toIBU(int Use, int Form, double preSG, double postSG, double Volume, double Amount, double Boiltime, double Alpha, |
420 double Utils::toIBU(int Use, int Form, double preSG, double postSG, double Volume, double Amount, double Boiltime, double Alpha, |
421 int Method, double Whirlpool9, double Whirlpool7, double Whirlpool6, double Fulltime, |
421 int Method, double Whirlpool9, double Whirlpool7, double Whirlpool6, double Fulltime, |
422 int Cooltype, double Coolparm1, double Coolparm2, double Utilisation, double BU_factor) |
422 int Cooltype, double CoolTo79, double CoolLPM, double Utilisation, double BU_factor) |
423 { |
423 { |
424 double ibu = 0.0; |
424 double ibu = 0.0; |
|
425 double bp = boilPoint(); |
425 |
426 |
426 if (Use == HOP_USEAT_MASH) { |
427 if (Use == HOP_USEAT_MASH) { |
427 /* |
428 /* |
428 * Mash hops. About -30% to -90% utilization. Is a global setting. |
429 * Mash hops. About -30% to -90% utilization. Is a global setting. |
429 * They count for 60 minutes, this is a fixed value. |
430 * They count for 60 minutes, this is a fixed value. |
451 if (Use == HOP_USEAT_FWH) { |
452 if (Use == HOP_USEAT_FWH) { |
452 ibu *= (1 + my_factor_fwh / 100.0); |
453 ibu *= (1 + my_factor_fwh / 100.0); |
453 } |
454 } |
454 |
455 |
455 if (Method > 0) { |
456 if (Method > 0) { |
|
457 /* |
|
458 * Extra IBU's during flameout, chilling, hopstands for hops added during boil or first wort. |
|
459 */ |
456 double nibu = ibu; |
460 double nibu = ibu; |
457 nibu *= IBU_reduction(boilPoint()); |
461 if (Use == HOP_USEAT_BOIL) /* Correct for brewery height above sealevel */ |
|
462 nibu *= IBU_reduction(bp); |
458 |
463 |
459 /* |
464 /* |
460 * Flameout, currently fixed 1 minute. |
465 * Flameout, currently fixed 1 minute. |
461 */ |
466 */ |
462 double flameout_time = 1; |
467 double flameout_time = 1; |
463 double fibu = TinsethIBU(Form, postSG, Volume, Amount, boil_time, boil_time + flameout_time, Alpha, Utilisation, BU_factor); |
468 double fibu = TinsethIBU(Form, postSG, Volume, Amount, boil_time, boil_time + flameout_time, Alpha, Utilisation, BU_factor); |
464 fibu *= IBU_reduction(98.0); |
469 fibu *= IBU_reduction(bp - 0.5); /* Boilpoint minus 0.5 degree */ |
465 //qDebug() << "during flameout" << fibu; |
470 //qDebug() << "during flameout" << fibu << bp; |
466 nibu += fibu; |
471 nibu += fibu; |
467 |
472 |
468 // Add this hop during cooling |
473 if ((Cooltype == CHILLER_TYPE_IMMERSION || Cooltype == CHILLER_TYPE_AUBAINMARIE || Cooltype == CHILLER_TYPE_NOCHILL) && CoolTo79 > 0) { |
|
474 /* |
|
475 * Direct wort chilling, calculate the IBU's when chilling down to 79 degrees. |
|
476 */ |
|
477 double cibu = 0, tibu; |
|
478 for (int i = 1; i < int(CoolTo79); i++) { |
|
479 tibu = TinsethIBU(Form, postSG, Volume, Amount, boil_time + flameout_time + i, boil_time + flameout_time + i + 1, Alpha, Utilisation, BU_factor); |
|
480 tibu *= IBU_reduction((bp - 1) - (i * ((bp - 80) / CoolTo79))); |
|
481 //qDebug() << " chill" << i << "time" << boil_time + flameout_time + i << "temp" << (bp - 1) - (i * ((bp - 80) / CoolTo79)) << "ibu" << tibu; |
|
482 cibu += tibu; |
|
483 } |
|
484 //qDebug() << " immersion" << cibu; |
|
485 nibu += cibu; |
|
486 } |
|
487 |
|
488 if (Cooltype == CHILLER_TYPE_COUNTERFLOW && CoolLPM > 0) { |
|
489 /* |
|
490 * Counterflow chilling, calculate the IBU's isomerized in the kettle during transfer the hot wort to the chiller. |
|
491 */ |
|
492 double cibu = 0, tibu, V, A; |
|
493 int steps = trunc(Volume / CoolLPM); |
|
494 for (int i = 1; i <= steps; i++) { |
|
495 V = Volume - (i * CoolLPM); |
|
496 A = Amount - (i * (Amount / steps)); |
|
497 tibu = TinsethIBU(Form, postSG, V, A, boil_time + flameout_time + i, boil_time + flameout_time + i + 1, Alpha, Utilisation, BU_factor); |
|
498 /* |
|
499 * Correction for the natural cooling of the wort in the kettle. |
|
500 * Asume 0.1 degree per minute. |
|
501 */ |
|
502 tibu *= IBU_reduction((bp - 1) - (i * 0.1)); |
|
503 //qDebug() << " chill" << i << steps << "left" << V << A << "time" << boil_time + flameout_time + i << "ibu" << tibu; |
|
504 cibu += tibu; |
|
505 } |
|
506 //qDebug() << " counterflow" << cibu; |
|
507 nibu += cibu; |
|
508 } |
|
509 |
469 /* |
510 /* |
470 * Hopstands, this boil hop adds some IBU's too. |
511 * Hopstands, this boil hop adds some IBU's too. |
471 */ |
512 */ |
472 if (Whirlpool9) { |
513 if (Whirlpool9) { |
473 double wibu9 = TinsethIBU(Form, postSG, Volume, Amount, boil_time + flameout_time, boil_time + flameout_time + Whirlpool9, Alpha, Utilisation, BU_factor); |
514 double wibu9 = TinsethIBU(Form, postSG, Volume, Amount, boil_time + flameout_time, boil_time + flameout_time + Whirlpool9, Alpha, Utilisation, BU_factor); |
495 /* |
536 /* |
496 * At flameout, and only using extended calculation. |
537 * At flameout, and only using extended calculation. |
497 */ |
538 */ |
498 double flameout_time = 1; |
539 double flameout_time = 1; |
499 ibu = TinsethIBU(Form, postSG, Volume, Amount, 0, flameout_time, Alpha, Utilisation, BU_factor); |
540 ibu = TinsethIBU(Form, postSG, Volume, Amount, 0, flameout_time, Alpha, Utilisation, BU_factor); |
500 ibu *= IBU_reduction(98.0); |
541 ibu *= IBU_reduction(bp - 0.5); |
|
542 |
|
543 if ((Cooltype == CHILLER_TYPE_IMMERSION || Cooltype == CHILLER_TYPE_AUBAINMARIE || Cooltype == CHILLER_TYPE_NOCHILL) && CoolTo79 > 0) { |
|
544 /* |
|
545 * Direct wort chilling, calculate the IBU's when chilling down to 79 degrees. |
|
546 */ |
|
547 double cibu = 0, tibu; |
|
548 for (int i = 1; i < int(CoolTo79); i++) { |
|
549 tibu = TinsethIBU(Form, postSG, Volume, Amount, flameout_time + i, flameout_time + i + 1, Alpha, Utilisation, BU_factor); |
|
550 tibu *= IBU_reduction((bp - 1) - (i * ((bp - 80) / CoolTo79))); |
|
551 //qDebug() << " chill" << i << "time" << flameout_time + i << "temp" << (bp - 1) - (i * ((bp - 80) / CoolTo79)) << "ibu" << tibu; |
|
552 cibu += tibu; |
|
553 } |
|
554 //qDebug() << " immersion" << cibu; |
|
555 ibu += cibu; |
|
556 } |
|
557 |
|
558 if (Cooltype == CHILLER_TYPE_COUNTERFLOW && CoolLPM > 0) { |
|
559 /* |
|
560 * Counterflow chilling, calculate the IBU's isomerized in the kettle during transfer the hot wort to the chiller. |
|
561 */ |
|
562 double cibu = 0, tibu, V, A; |
|
563 int steps = trunc(Volume / CoolLPM); |
|
564 for (int i = 1; i <= steps; i++) { |
|
565 V = Volume - (i * CoolLPM); |
|
566 A = Amount - (i * (Amount / steps)); |
|
567 tibu = TinsethIBU(Form, postSG, V, A, flameout_time + i, flameout_time + i + 1, Alpha, Utilisation, BU_factor); |
|
568 /* |
|
569 * Correction for the natural cooling of the wort in the kettle. |
|
570 * Asume 0.1 degree per minute. |
|
571 */ |
|
572 tibu *= IBU_reduction((bp - 1) - (i * 0.1)); |
|
573 //qDebug() << " chill" << i << steps << "left" << V << A << "time" << flameout_time + i << "ibu" << tibu; |
|
574 cibu += tibu; |
|
575 } |
|
576 //qDebug() << " counterflow" << cibu; |
|
577 ibu += cibu; |
|
578 } |
|
579 |
501 /* |
580 /* |
502 * Hopstands, this flameout hop adds some IBU's too. |
581 * Hopstands, this flameout hop adds some IBU's too. |
503 */ |
582 */ |
504 if (Whirlpool9) { |
583 if (Whirlpool9) { |
505 double wibu9 = TinsethIBU(Form, postSG, Volume, Amount, flameout_time, flameout_time + Whirlpool9, Alpha, Utilisation, BU_factor); |
584 double wibu9 = TinsethIBU(Form, postSG, Volume, Amount, flameout_time, flameout_time + Whirlpool9, Alpha, Utilisation, BU_factor); |