diff -r 31419b7cee69 -r 349c0c5bd512 src/Utils.cpp --- a/src/Utils.cpp Wed Nov 16 17:26:27 2022 +0100 +++ b/src/Utils.cpp Thu Nov 17 17:23:54 2022 +0100 @@ -419,9 +419,10 @@ double Utils::toIBU(int Use, int Form, double preSG, double postSG, double Volume, double Amount, double Boiltime, double Alpha, int Method, double Whirlpool9, double Whirlpool7, double Whirlpool6, double Fulltime, - int Cooltype, double Coolparm1, double Coolparm2, double Utilisation, double BU_factor) + int Cooltype, double CoolTo79, double CoolLPM, double Utilisation, double BU_factor) { double ibu = 0.0; + double bp = boilPoint(); if (Use == HOP_USEAT_MASH) { /* @@ -453,19 +454,59 @@ } if (Method > 0) { + /* + * Extra IBU's during flameout, chilling, hopstands for hops added during boil or first wort. + */ double nibu = ibu; - nibu *= IBU_reduction(boilPoint()); + if (Use == HOP_USEAT_BOIL) /* Correct for brewery height above sealevel */ + nibu *= IBU_reduction(bp); /* * Flameout, currently fixed 1 minute. */ double flameout_time = 1; double fibu = TinsethIBU(Form, postSG, Volume, Amount, boil_time, boil_time + flameout_time, Alpha, Utilisation, BU_factor); - fibu *= IBU_reduction(98.0); - //qDebug() << "during flameout" << fibu; + fibu *= IBU_reduction(bp - 0.5); /* Boilpoint minus 0.5 degree */ + //qDebug() << "during flameout" << fibu << bp; nibu += fibu; - // Add this hop during cooling + if ((Cooltype == CHILLER_TYPE_IMMERSION || Cooltype == CHILLER_TYPE_AUBAINMARIE || Cooltype == CHILLER_TYPE_NOCHILL) && CoolTo79 > 0) { + /* + * Direct wort chilling, calculate the IBU's when chilling down to 79 degrees. + */ + double cibu = 0, tibu; + for (int i = 1; i < int(CoolTo79); i++) { + tibu = TinsethIBU(Form, postSG, Volume, Amount, boil_time + flameout_time + i, boil_time + flameout_time + i + 1, Alpha, Utilisation, BU_factor); + tibu *= IBU_reduction((bp - 1) - (i * ((bp - 80) / CoolTo79))); + //qDebug() << " chill" << i << "time" << boil_time + flameout_time + i << "temp" << (bp - 1) - (i * ((bp - 80) / CoolTo79)) << "ibu" << tibu; + cibu += tibu; + } + //qDebug() << " immersion" << cibu; + nibu += cibu; + } + + if (Cooltype == CHILLER_TYPE_COUNTERFLOW && CoolLPM > 0) { + /* + * Counterflow chilling, calculate the IBU's isomerized in the kettle during transfer the hot wort to the chiller. + */ + double cibu = 0, tibu, V, A; + int steps = trunc(Volume / CoolLPM); + for (int i = 1; i <= steps; i++) { + V = Volume - (i * CoolLPM); + A = Amount - (i * (Amount / steps)); + tibu = TinsethIBU(Form, postSG, V, A, boil_time + flameout_time + i, boil_time + flameout_time + i + 1, Alpha, Utilisation, BU_factor); + /* + * Correction for the natural cooling of the wort in the kettle. + * Asume 0.1 degree per minute. + */ + tibu *= IBU_reduction((bp - 1) - (i * 0.1)); + //qDebug() << " chill" << i << steps << "left" << V << A << "time" << boil_time + flameout_time + i << "ibu" << tibu; + cibu += tibu; + } + //qDebug() << " counterflow" << cibu; + nibu += cibu; + } + /* * Hopstands, this boil hop adds some IBU's too. */ @@ -497,7 +538,45 @@ */ double flameout_time = 1; ibu = TinsethIBU(Form, postSG, Volume, Amount, 0, flameout_time, Alpha, Utilisation, BU_factor); - ibu *= IBU_reduction(98.0); + ibu *= IBU_reduction(bp - 0.5); + + if ((Cooltype == CHILLER_TYPE_IMMERSION || Cooltype == CHILLER_TYPE_AUBAINMARIE || Cooltype == CHILLER_TYPE_NOCHILL) && CoolTo79 > 0) { + /* + * Direct wort chilling, calculate the IBU's when chilling down to 79 degrees. + */ + double cibu = 0, tibu; + for (int i = 1; i < int(CoolTo79); i++) { + tibu = TinsethIBU(Form, postSG, Volume, Amount, flameout_time + i, flameout_time + i + 1, Alpha, Utilisation, BU_factor); + tibu *= IBU_reduction((bp - 1) - (i * ((bp - 80) / CoolTo79))); + //qDebug() << " chill" << i << "time" << flameout_time + i << "temp" << (bp - 1) - (i * ((bp - 80) / CoolTo79)) << "ibu" << tibu; + cibu += tibu; + } + //qDebug() << " immersion" << cibu; + ibu += cibu; + } + + if (Cooltype == CHILLER_TYPE_COUNTERFLOW && CoolLPM > 0) { + /* + * Counterflow chilling, calculate the IBU's isomerized in the kettle during transfer the hot wort to the chiller. + */ + double cibu = 0, tibu, V, A; + int steps = trunc(Volume / CoolLPM); + for (int i = 1; i <= steps; i++) { + V = Volume - (i * CoolLPM); + A = Amount - (i * (Amount / steps)); + tibu = TinsethIBU(Form, postSG, V, A, flameout_time + i, flameout_time + i + 1, Alpha, Utilisation, BU_factor); + /* + * Correction for the natural cooling of the wort in the kettle. + * Asume 0.1 degree per minute. + */ + tibu *= IBU_reduction((bp - 1) - (i * 0.1)); + //qDebug() << " chill" << i << steps << "left" << V << A << "time" << flameout_time + i << "ibu" << tibu; + cibu += tibu; + } + //qDebug() << " counterflow" << cibu; + ibu += cibu; + } + /* * Hopstands, this flameout hop adds some IBU's too. */ @@ -559,7 +638,7 @@ double rc = round(ibu * 1000.0) / 1000.0; - qDebug() << "toIBU" << Use << Form << preSG << postSG << Volume << Amount << Boiltime << Alpha << Method << Whirlpool9 << Whirlpool7 << Whirlpool6 << Fulltime << Cooltype << Coolparm1 << Coolparm2 << Utilisation << BU_factor << "rc:" << rc; + qDebug() << "toIBU" << Use << Form << preSG << postSG << Volume << Amount << Boiltime << Alpha << Method << Whirlpool9 << Whirlpool7 << Whirlpool6 << Fulltime << Cooltype << CoolTo79 << CoolLPM << Utilisation << BU_factor << "rc:" << rc; return rc; }