328 double factor = og * 3157 * pow(10, -5) + 9.716 * pow(10, -2); |
328 double factor = og * 3157 * pow(10, -5) + 9.716 * pow(10, -2); |
329 return round((og * 1000 - fg * 1000) * factor * 100) / 100; |
329 return round((og * 1000 - fg * 1000) * factor * 100) / 100; |
330 } |
330 } |
331 |
331 |
332 |
332 |
|
333 double Utils::toIBU(int Use, int Form, double SG, double Volume, double Amount, double Boiltime, double Alpha, |
|
334 int Method, double Whirlpool9, double Whirlpool7, double Whirlpool6) |
|
335 { |
|
336 double fmoment = 1.0, pfactor = 1.0, ibu = 0, boilfactor; |
|
337 double sgfactor, AddedAlphaAcids, Bigness_factor, BoilTime_factor, utiisation; |
|
338 |
|
339 double gravity = SG; |
|
340 double liters = Volume; |
|
341 double alpha = Alpha / 100.0; |
|
342 double mass = Amount * 1000.0; |
|
343 double time = Boiltime; |
|
344 |
|
345 if ((Use == 3) || (Use == 4) || (Use == 5)) { // Aroma, Whirlpool or Dry hop. |
|
346 fmoment = 0.0; |
|
347 } else if (Use == 0) { // Mash |
|
348 fmoment += my_factor_mashhop / 100.0; // Brouwhulp |
|
349 } else if (Use == 1) { // First wort |
|
350 fmoment += my_factor_fwh / 100.0; // Brouwhulp, Louis, Ozzie |
|
351 } |
|
352 |
|
353 if (Form == 0) { // Pellet |
|
354 pfactor += my_factor_pellet / 100.0; |
|
355 } else if (Form == 1) { // Plug |
|
356 pfactor += my_factor_plug / 100.0; |
|
357 } else if (Form == 3) { // Wet leaf |
|
358 pfactor += my_factor_wethop / 100.0; // From https://github.com/chrisgilmerproj/brewday/blob/master/brew/constants.py |
|
359 } else if (Form == 4) { // Cryo hop |
|
360 pfactor += my_factor_cryohop / 100.0; |
|
361 } |
|
362 |
|
363 // Ideas from Zymurgy March-April 2018. These are not exact formulas! |
|
364 double whirlibus = 0.0; |
|
365 if (Use == 3 || Use == 4) { // Flameout or any whirlpool |
|
366 |
|
367 if (Whirlpool9) { |
|
368 // 20 mg/l/50 min |
|
369 whirlibus += (alpha * mass * 20) / liters * (Whirlpool9 / 50.0); |
|
370 qDebug() << "Whirlpool9" << alpha * mass * 20 << " liter:" << liters << " time:" << Whirlpool9 << " ibu" << (alpha * mass * 20) / liters * (Whirlpool9 / 50.0); |
|
371 } else { |
|
372 if (Use == 3) { // Flameout hops are 2 minutes in this range. |
|
373 whirlibus += (alpha * mass * 20) / liters * (2.0 / 50.0); |
|
374 } |
|
375 } |
|
376 if (Whirlpool7) { |
|
377 // 6 mg/l/50 min |
|
378 whirlibus += (alpha * mass * 6) / liters * (Whirlpool7 / 50.0); |
|
379 qDebug() << "Whirlpool7" << alpha * mass * 6 << " liter:" << liters << " time:" << Whirlpool7 << " ibu" << (alpha * mass * 6) / liters * (Whirlpool7 / 50.0); |
|
380 } else { |
|
381 if (Use == 3) { // Flameout hops are 4 minutes in this range. |
|
382 whirlibus += (alpha * mass * 6) / liters * (4.0 / 50.0); |
|
383 } |
|
384 } |
|
385 if (Whirlpool6) { |
|
386 // 2 mg/l/50 min |
|
387 whirlibus += (alpha * mass * 2) / liters * (Whirlpool6 / 50.0); |
|
388 //console.log('Whirlpool6:' + alpha * mass * 2 + ' liter:' + liters + ' time:' + Whirlpool6 + ' ibu' + (alpha * mass * 2) / liters * (Whirlpool6 / 50)); |
|
389 } |
|
390 } |
|
391 |
|
392 if (Method == 0) { // Tinseth |
|
393 /* http://realbeer.com/hops/research.html */ |
|
394 AddedAlphaAcids = (alpha * mass * 1000) / liters; |
|
395 Bigness_factor = 1.65 * pow(0.000125, gravity - 1); |
|
396 BoilTime_factor = ((1 - exp(-0.04 * time)) / 4.15); |
|
397 utiisation = Bigness_factor * BoilTime_factor; |
|
398 ibu = round((utiisation * AddedAlphaAcids * fmoment * pfactor + whirlibus) * 100) / 100; |
|
399 } |
|
400 if (Method == 2) { // Daniels |
|
401 if (Form == 2) // Leaf |
|
402 boilfactor = -(0.0041 * time * time) + (0.6162 * time) + 1.5779; |
|
403 else |
|
404 boilfactor = -(0.0051 * time * time) + (0.7835 * time) + 1.9348; |
|
405 if (gravity < 1050) |
|
406 sgfactor = 0; |
|
407 else |
|
408 sgfactor = (gravity - 1050) / 200; |
|
409 ibu = round((fmoment * ((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor))) + whirlibus) * 100) / 100; |
|
410 } |
|
411 if (Method == 1) { // Rager |
|
412 boilfactor = fmoment * 18.11 + 13.86 * tanh((time * 31.32) / 18.27); |
|
413 if (gravity < 1050) |
|
414 sgfactor = 0; |
|
415 else |
|
416 sgfactor = (gravity - 1050) / 200; |
|
417 ibu = round(((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor)) + whirlibus) * 100) / 100; |
|
418 } |
|
419 |
|
420 return ibu; |
|
421 } |
|
422 |
|
423 |
|
424 double Utils::hopFlavourContribution(double bt, double vol, int use, double amount) |
|
425 { |
|
426 double result; |
|
427 |
|
428 if (use == 4 || use == 5) // Whirlpool or Dry-hop |
|
429 return 0; |
|
430 if (use == 1) { // First wort |
|
431 result = 0.15; // assume 15% flavourcontribution for fwh |
|
432 } else if (bt > 50) { |
|
433 result = 0.10; // assume 10% flavourcontribution as a minimum |
|
434 } else { |
|
435 result = 15.25 / (6 * sqrt(2 * 3.1416)) * exp(-0.5 * pow((bt - 21.0) / 6.0, 2.0)); |
|
436 if (result < 0.10) |
|
437 result = 0.10; // assume 10% flavourcontribution as a minimum |
|
438 } |
|
439 return (result * amount * 1000.0) / vol; |
|
440 } |
|
441 |
|
442 |
|
443 double Utils::hopAromaContribution(double bt, double vol, int use, double amount) |
|
444 { |
|
445 double result = 0.0; |
|
446 |
|
447 if (use == 5) { // Dry hop |
|
448 result = 1.33; |
|
449 } else if (use == 4) { // Whirlpool |
|
450 if (bt > 30) |
|
451 bt = 30; // Max 30 minutes |
|
452 result = 0.62 * bt / 30.0; |
|
453 } else if (bt > 20) { |
|
454 result = 0.0; |
|
455 } else if (bt > 7.5) { |
|
456 result = 10.03 / (4 * sqrt(2 * 3.1416)) * exp(-0.5 * pow((bt - 7.5) / 4.0, 2.0)); |
|
457 } else if (use == 2) { // Boil |
|
458 result = 1; |
|
459 } else if (use == 3) { // Aroma |
|
460 result = 1.2; |
|
461 } |
|
462 return (result * amount * 1000.0) / vol; |
|
463 } |
|
464 |
|
465 |