391 var TpH = 0; |
533 var TpH = 0; |
392 var AcidSG = 0; |
534 var AcidSG = 0; |
393 var AcidPrc = 0; |
535 var AcidPrc = 0; |
394 var protonDeficit = 0; |
536 var protonDeficit = 0; |
395 |
537 |
396 if (dataRecord.w1_name != "") { |
538 if (dataRecord.w1_name == "") { |
397 if (dataRecord.w2_name != "") { |
539 return; |
398 liters = dataRecord.w1_amount + dataRecord.w2_amount; |
540 } |
399 calcium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_calcium, dataRecord.w2_calcium); |
541 |
400 magnesium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_magnesium, dataRecord.w2_magnesium); |
542 // If there is a dillute water source, mix the waters. |
401 sodium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sodium, dataRecord.w2_sodium); |
543 if (dataRecord.w2_name != "") { |
402 chloride = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_chloride, dataRecord.w2_chloride); |
544 liters = dataRecord.w1_amount + dataRecord.w2_amount; |
403 sulfate = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sulfate, dataRecord.w2_sulfate); |
545 calcium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_calcium, dataRecord.w2_calcium); |
404 total_alkalinity = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_total_alkalinity, dataRecord.w2_total_alkalinity); |
546 magnesium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_magnesium, dataRecord.w2_magnesium); |
405 ph = -Math.log10(((Math.pow(10, -dataRecord.w1_ph) * dataRecord.w1_amount) + (Math.pow(10, -dataRecord.w2_ph) * dataRecord.w2_amount)) / liters); |
547 sodium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sodium, dataRecord.w2_sodium); |
406 } else { |
548 chloride = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_chloride, dataRecord.w2_chloride); |
407 liters = dataRecord.w1_amount; |
549 sulfate = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sulfate, dataRecord.w2_sulfate); |
408 calcium = dataRecord.w1_calcium; |
550 total_alkalinity = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_total_alkalinity, dataRecord.w2_total_alkalinity); |
409 magnesium = dataRecord.w1_magnesium; |
551 ph = -Math.log10(((Math.pow(10, -dataRecord.w1_ph) * dataRecord.w1_amount) + (Math.pow(10, -dataRecord.w2_ph) * dataRecord.w2_amount)) / liters); |
410 sodium = dataRecord.w1_sodium; |
552 } else { |
411 chloride = dataRecord.w1_chloride; |
553 liters = dataRecord.w1_amount; |
412 sulfate = dataRecord.w1_sulfate; |
554 calcium = dataRecord.w1_calcium; |
413 total_alkalinity = dataRecord.w1_total_alkalinity; |
555 magnesium = dataRecord.w1_magnesium; |
414 ph = dataRecord.w1_ph; |
556 sodium = dataRecord.w1_sodium; |
415 } |
557 chloride = dataRecord.w1_chloride; |
|
558 sulfate = dataRecord.w1_sulfate; |
|
559 total_alkalinity = dataRecord.w1_total_alkalinity; |
|
560 ph = dataRecord.w1_ph; |
416 } |
561 } |
417 $('#wg_amount').val(liters); |
562 $('#wg_amount').val(liters); |
|
563 var wg_calcium = calcium; |
418 $('#wg_calcium').val(Math.round(calcium * 10) / 10); |
564 $('#wg_calcium').val(Math.round(calcium * 10) / 10); |
|
565 var wg_magnesium = magnesium; |
419 $('#wg_magnesium').val(Math.round(magnesium * 10) / 10); |
566 $('#wg_magnesium').val(Math.round(magnesium * 10) / 10); |
|
567 var wg_sodium = sodium; |
420 $('#wg_sodium').val(Math.round(sodium * 10) / 10); |
568 $('#wg_sodium').val(Math.round(sodium * 10) / 10); |
|
569 var wg_total_alkalinity = total_alkalinity; |
421 $('#wg_total_alkalinity').val(Math.round(total_alkalinity * 10) / 10); |
570 $('#wg_total_alkalinity').val(Math.round(total_alkalinity * 10) / 10); |
|
571 var wg_chloride = chloride; |
422 $('#wg_chloride').val(Math.round(chloride * 10) / 10); |
572 $('#wg_chloride').val(Math.round(chloride * 10) / 10); |
|
573 var wg_sulfate = sulfate; |
423 $('#wg_sulfate').val(Math.round(sulfate * 10) / 10); |
574 $('#wg_sulfate').val(Math.round(sulfate * 10) / 10); |
424 // Note: brouwhulp has the malts included here in the result. |
575 // Note: brouwhulp has the malts included here in the result. |
|
576 var wg_ph = ph; |
425 $('#wg_ph').val(Math.round(ph * 10) / 10); |
577 $('#wg_ph').val(Math.round(ph * 10) / 10); |
|
578 $('#wb_ph').val(Math.round(MashpH() * 10) / 10); |
|
579 bicarbonate = total_alkalinity * 1.22; |
|
580 var wg_bicarbonate = bicarbonate; |
426 |
581 |
427 // Noot: de volgende berekeningen geven bijna gelijke resultaten in Brun'water. |
582 // Noot: de volgende berekeningen geven bijna gelijke resultaten in Brun'water. |
428 // Calculate Ca |
583 // Calculate Ca |
429 RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + |
584 RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + |
430 parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4; |
585 parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4; |
431 calcium += 1000 * RA / parseFloat($("#wg_amount").jqxNumberInput('decimal')); |
586 calcium += 1000 * RA / liters; |
432 |
587 |
433 // Calculate Mg |
588 // Calculate Mg |
434 RA = parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMMg / MMMgSO4; |
589 RA = parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMMg / MMMgSO4; |
435 magnesium += 1000 * RA / parseFloat($("#wg_amount").jqxNumberInput('decimal')); |
590 magnesium += 1000 * RA / liters; |
436 |
591 |
437 // Calculate Na |
592 // Calculate Na |
438 RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + |
593 RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + |
439 parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; |
594 parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; |
440 sodium += 1000 * RA / parseFloat($("#wg_amount").jqxNumberInput('decimal')); |
595 sodium += 1000 * RA / liters; |
441 |
596 |
442 // Calculate SO4 |
597 // Calculate SO4 |
443 RA = parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + |
598 RA = parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + |
444 parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMSO4 / MMMgSO4; |
599 parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMSO4 / MMMgSO4; |
445 sulfate += 1000 * RA / parseFloat($("#wg_amount").jqxNumberInput('decimal')); |
600 sulfate += 1000 * RA / liters; |
446 |
601 |
447 // Calculate Cl |
602 // Calculate Cl |
448 RA = 2 * parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCl / MMCaCl2 + |
603 RA = 2 * parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCl / MMCaCl2 + |
449 parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMCl / MMNaCl; |
604 parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMCl / MMNaCl; |
450 chloride += 1000 * RA / parseFloat($("#wg_amount").jqxNumberInput('decimal')); |
605 chloride += 1000 * RA / liters; |
451 // Einde noot. |
606 // Einde noot. |
452 |
607 |
453 TpH = parseFloat(dataRecord.mash_ph); |
608 if ($("#wa_acid_name").val() == "") { |
454 if (TpH < 5.0 || TpH > 6.0) { |
609 $("#wa_acid_name").val('Melkzuur'); |
455 TpH = 5.4; |
610 last_acid = 'Melkzuur'; |
456 dataRecord.mash_ph = 5.4; |
611 } |
457 $("#mash_ph").val(5.4); |
612 if ($("#wa_base_name").val() == "") { |
458 $("#tgt_mash_ph").val(5.4); |
613 $("#wa_base_name").val('NaHCO3'); |
459 } |
614 last_base = 'NaHCO3'; |
460 var acid_amount = parseFloat($("#wa_acid").jqxNumberInput('decimal')); |
615 } |
461 var acid_perc = parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')); |
616 |
462 |
617 var AT = $("#wa_acid_name").val(); |
463 switch ($("#wa_acid_name").val()) { |
618 var BT = $("#wa_base_name").val(); |
464 case 'Melkzuur': pK1 = 3.08; |
619 |
465 pK2 = 20; |
620 var result = GetAcidSpecs(AT); |
466 pK3 = 20; |
621 pK1 = result.pK1; |
467 MolWt = 90.08; |
622 pK2 = result.pK2; |
468 AcidSG = 1214; //@88% |
623 pK3 = result.pK3; |
469 AcidPrc = 0.88; |
624 MolWt = result.MolWt; |
470 //frac = CalcFrac(TpH, pK1, pK2, pK3); |
625 AcidSG = result.AcidSG; |
471 acid += acid_amount * acid_perc / 100 * AcidSG / MolWt * frac / liters; //mEq/l |
626 AcidPrc = result.AcidPrc; |
472 break; |
627 |
473 |
628 if (dataRecord.calc_acid) { |
474 case 'Zoutzuur': pK1 = -10; |
629 TpH = parseFloat(dataRecord.mash_ph); |
475 pK2 = 20; |
630 protonDeficit = ProtonDeficit(TpH); |
476 pK3 = 20; |
631 console.log("calc_acid tgt: "+TpH+" protonDeficit: "+protonDeficit); |
477 MolWt = 36.46; |
632 if (protonDeficit > 0) { // Add acid |
478 AcidSG = 1142; //@28% |
633 $("#wa_base").val(0); |
479 AcidPrc = 0.28; |
634 setWaterAgent(last_base, 0); |
480 //frac = CalcFrac(TpH, pK1, pK2, pK3); |
635 frac = CalcFrac(TpH, pK1, pK2, pK3); |
481 Acidmg = acid_amount * acid_perc / 100 * AcidSG / liters; |
636 Acid = protonDeficit / frac; |
482 acid += Acidmg / MolWt * frac; //mEq/l |
637 Acid *= MolWt; // mg |
483 chloride += Acidmg / 1000 * MMCl / (MMCl + 1); |
638 Acidmg = Acid; |
484 break; |
639 Acid = Acid / AcidSG; // ml |
485 |
640 |
486 case 'Fosforzuur': pK1 = 2.12; |
641 if (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) == 0) |
487 pK2 = 7.20; |
642 $("#wa_acid_perc").val(AcidPrc); |
488 pK3 = 12.44; |
643 Acid = Acid * AcidPrc / (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) / 100); // ml |
489 MolWt = 98.00; |
644 console.log("Final ml: "+Acid); |
490 AcidSG = 1170; //@25% |
645 $("#wa_acid").val(Math.round(Acid * 100) / 100); |
491 AcidPrc = 0.25; |
646 setWaterAgent(AT, Math.round(Acid * 100) / 100); |
492 //frac = CalcFrac(TpH, pK1, pK2, pK3); |
647 |
493 Acidmg = acid_amount * acid_perc / 100 * AcidSG / liters; |
648 bicarbonate = bicarbonate - protonDeficit * frac / liters; |
494 acid += Acidmg / MolWt * frac; //mEq/l |
649 total_alkalinity = bicarbonate * 50 / 61; |
495 break; |
650 } else if (protonDeficit < 0) { //Add base |
496 |
651 $("#wa_acid").val(0); |
497 case 'Zwavelzuur': pK1 = -10; |
652 setWaterAgent(last_acid, 0); |
498 pK2 = 1.92; |
653 r1d = Math.pow(10, (TpH - 6.38)); |
499 pK3 = 20; |
654 r2d = Math.pow(10, (TpH - 10.38)); |
500 MolWt = 98.07; |
655 f1d = 1 / (1 + r1d + r1d * r2d); |
501 AcidSG = 1700; //@93% |
656 f2d = f1d * r1d; |
502 AcidPrc = 0.93; |
657 f3d = f2d * r2d; |
503 //frac = CalcFrac(TpH, pK1, pK2, pK3); |
658 switch (BT) { |
504 Acidmg = acid_amount * acid_perc / 100 * AcidSG / liters; |
659 case 'NaHCO3': base = -protonDeficit / (f1d - f3d); //mmol totaal |
505 acid += Acidmg / MolWt * frac; //mEq/l |
660 base = base * MMNaHCO3/1000; //gram |
506 sulfate += Acidmg / 1000 * MMSO4 / (MMSO4 + 2); |
661 $("#wa_base").val(Math.round(base * 100) / 100); |
507 break; |
662 setWaterAgent(BT, Math.round(base * 100) / 100); |
508 } |
663 if (liters > 0) { |
509 //protonDeficit = ProtonDeficit(TpH); |
664 // Na |
510 //console.log("frac: "+frac+" acid: "+acid+" protonDeficit: "+protonDeficit); |
665 RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + |
511 //total_alkalinity -= 50 / 61 * protonDeficit * frac / liters; |
666 parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; |
|
667 RA = 1000 * RA / liters; |
|
668 sodium = wg_sodium + RA; |
|
669 // HCO3 |
|
670 RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3; |
|
671 RA = 1000 * RA / liters; |
|
672 bicarbonate = wg_bicarbonate + RA; |
|
673 total_alkalinity = bicarbonate * 50 / 61; |
|
674 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
|
675 } |
|
676 break; |
|
677 case 'Na2CO3': base = -protonDeficit / (2 * f1d + f2d); //mmol totaal |
|
678 base = base * MMNa2CO3/1000; //gram |
|
679 $("#wa_base").val(Math.round(base * 100) / 100); |
|
680 setWaterAgent(BT, Math.round(base * 100) / 100); |
|
681 if (liters > 0) { |
|
682 RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + |
|
683 parseFloat($("#wa_base").jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3; |
|
684 RA = 1000 * RA / liters; |
|
685 sodium = wg_sodium + RA; |
|
686 // HCO3 |
|
687 RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3; |
|
688 RA = 1000 * RA / liters; |
|
689 bicarbonate = wg_bicarbonate + RA; |
|
690 total_alkalinity = bicarbonate * 50 / 61; |
|
691 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
|
692 } |
|
693 break; |
|
694 case 'CaCO3': base = -protonDeficit * (f1d - f3d); //mmol totaal |
|
695 base = base * MMCaCO3/1000; //gram |
|
696 //but only 1/3 is effective, so add 3 times as much |
|
697 base = 3 * base; |
|
698 $("#wa_base").val(Math.round(base * 100) / 100); |
|
699 setWaterAgent(BT, Math.round(base * 100) / 100); |
|
700 if (liters > 0) { |
|
701 //Bicarbonate |
|
702 RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3; |
|
703 RA = 1000 * RA / liters; |
|
704 bicarbonate = wg_bicarbonate + RA; |
|
705 total_alkalinity = bicarbonate * 50 / 61; |
|
706 //Ca precipitates out as Ca10(PO4)6(OH)2 |
|
707 RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + |
|
708 parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4 + |
|
709 parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMCa / MMCaCO3; |
|
710 RA = 1000 * RA / liters; |
|
711 calcium = wg_calcium + RA; |
|
712 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
|
713 } |
|
714 break; |
|
715 case 'Ca(OH)2': base = -protonDeficit / 19.3; // g |
|
716 $("#wa_base").val(Math.round(base * 100) / 100); |
|
717 setWaterAgent(BT, Math.round(base * 100) / 100); |
|
718 if (liters > 0) { |
|
719 // Bicarbonate |
|
720 RA = -protonDeficit / liters; |
|
721 total_alkalinity = wg_total_alkalinity + RA; |
|
722 bicarbonate = total_alkalinity * 61 / 50; |
|
723 // Calcium |
|
724 RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + |
|
725 parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4 + |
|
726 parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMCa / MMCaOH2; |
|
727 RA = 1000 * RA / liters; |
|
728 calcium = wg_calcium + RA; |
|
729 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
|
730 } |
|
731 break; |
|
732 } |
|
733 } |
|
734 ph = TpH; |
|
735 $('#wb_ph').val(Math.round(ph * 10) / 10); |
|
736 } else { // Manual |
|
737 console.log("calc_acid no"); |
|
738 // First add base salts |
|
739 if (parseFloat($("#wa_base").jqxNumberInput('decimal')) > 0) { |
|
740 if (liters > 0) { |
|
741 switch (BT) { |
|
742 case 'NaHCO3': // Na |
|
743 RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + |
|
744 parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMNa / MMNaHCO3; |
|
745 RA = 1000 * RA / liters; |
|
746 sodium = wg_sodium + RA; |
|
747 // HCO3 |
|
748 RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3; |
|
749 RA = 1000 * RA / liters; |
|
750 bicarbonate = wg_bicarbonate + RA; |
|
751 total_alkalinity = bicarbonate * 50 / 61; |
|
752 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
|
753 break; |
|
754 case 'Na2CO3': RA = parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMNa / MMNaCl + |
|
755 parseFloat($("#wa_base").jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3; |
|
756 RA = 1000 * RA / liters; |
|
757 sodium = wg_sodium + RA; |
|
758 // HCO3 |
|
759 RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3; |
|
760 RA = 1000 * RA / liters; |
|
761 bicarbonate = wg_bicarbonate + RA; |
|
762 total_alkalinity = bicarbonate * 50 / 61; |
|
763 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
|
764 break; |
|
765 case 'CaCO3': // Bicarbonate |
|
766 RA = parseFloat($("#wa_base").jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3; |
|
767 RA = 1000 * RA / liters; |
|
768 bicarbonate = wg_bicarbonate + RA; |
|
769 total_alkalinity = bicarbonate * 50 / 61; |
|
770 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
|
771 // Ca |
|
772 RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCa / MMCaCl2 + |
|
773 parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMCa / MMCaSO4 + |
|
774 parseFloat($("#wa_base").jqxNumberInput('decimal')) * MMCa / MMCaCO3; |
|
775 RA = 1000 * RA / liters; |
|
776 calcium = wg_calcium + RA; |
|
777 break; |
|
778 } |
|
779 } |
|
780 } |
|
781 |
|
782 TpH = parseFloat(dataRecord.mash_ph); |
|
783 pHa = MashpH(); // This one is in demi water, should be in adjusted water??? |
|
784 // Then calculate the new pH with added acids |
|
785 if (parseFloat($("#wa_acid").jqxNumberInput('decimal')) > 0) { |
|
786 console.log("TpH: "+TpH+" water: "+pHa); |
|
787 Acid = parseFloat($("#wa_acid").jqxNumberInput('decimal')); |
|
788 if (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) == 0) |
|
789 $("#wa_acid_perc").val(AcidPrc); |
|
790 Acid = Acid / AcidPrc * (parseFloat($("#wa_acid_perc").jqxNumberInput('decimal')) / 100); // ml |
|
791 Acid *= AcidSG; // ml |
|
792 Acid /= MolWt; // mg |
|
793 Acidmg = Acid; |
|
794 |
|
795 //find the pH where the protondeficit = protondeficit by the acid |
|
796 frac = CalcFrac(pHa, pK1, pK2, pK3); |
|
797 protonDeficit = Acid * frac; |
|
798 |
|
799 deltapH = 0.001; |
|
800 deltapd = 0.1; |
|
801 pd = ProtonDeficit(pHa); |
|
802 n = 0; |
|
803 while (((pd < (protonDeficit - deltapd)) || (pd > (protonDeficit + deltapd))) && (n < 2000)) { |
|
804 n++; |
|
805 if (pd < (protonDeficit-deltapd)) |
|
806 pHa -= deltapH; |
|
807 else if (pd > (protonDeficit+deltapd)) |
|
808 pHa += deltapH; |
|
809 frac = CalcFrac(pHa, pK1, pK2, pK3); |
|
810 protonDeficit = Acid * frac; |
|
811 pd = ProtonDeficit(pHa); |
|
812 } |
|
813 console.log("n: "+n+" pd: "+pd+" protonDeficit: "+protonDeficit+" frac: "+frac+" pHa: "+pHa); |
|
814 RA = wg_bicarbonate - protonDeficit * frac / liters; |
|
815 bicarbonate = RA; |
|
816 total_alkalinity = RA * 50 / 61; |
|
817 ph = pHa; |
|
818 $('#wb_ph').val(Math.round(ph * 10) / 10); |
|
819 } |
|
820 } |
|
821 |
|
822 if ((AT == 'Zwavelzuur') && (liters > 0)) { |
|
823 RA = parseFloat($("#wa_caso4").jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + |
|
824 parseFloat($("#wa_mgso4").jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 + |
|
825 Acidmg / 1000 * MMSO4 / (MMSO4 + 2); |
|
826 RA = 1000 * RA / liters; |
|
827 sulfate = wg_sulfate + RA; // Not add to sulfate?? |
|
828 } else if ((AT == 'Zoutzuur') && (liters > 0)) { |
|
829 RA = parseFloat($("#wa_cacl2").jqxNumberInput('decimal')) * MMCl / MMCaCl2 + |
|
830 parseFloat($("#wa_nacl").jqxNumberInput('decimal')) * MMCl / MMNaCl + |
|
831 Acidmg / 1000 * MMCl / (MMCL + 1); |
|
832 RA = 1000 * RA / liters; |
|
833 chloride = wg_chloride + RA; |
|
834 } |
|
835 |
|
836 // 2:1 Sulfate to Chroride IPA's, Pale Ales. |
|
837 // 1:1 Sulfate to Chloride Balanced |
|
838 // 1:2 Sulfate to Chloride Malty |
|
839 $('#tgt_bu').val(Math.round(GetBUGU() * 100) / 100); |
|
840 $('#tgt_cl_so4').val(Math.round(GetOptClSO4ratio() * 10) / 10); // Show real value too |
|
841 if (sulfate > 0) |
|
842 RA = chloride / sulfate; |
|
843 else |
|
844 RA = 10; |
|
845 var piCLSO4_low = 0.8 * GetOptClSO4ratio(); |
|
846 var piCLSO4_high = 1.2 * GetOptClSO4ratio(); |
|
847 console.log("low: "+piCLSO4_low+" val: "+RA+" high: "+piCLSO4_high); |
512 |
848 |
513 $('#wb_calcium').val(Math.round(calcium * 10) / 10); |
849 $('#wb_calcium').val(Math.round(calcium * 10) / 10); |
514 $('#wb_magnesium').val(Math.round(magnesium * 10) / 10); |
850 $('#wb_magnesium').val(Math.round(magnesium * 10) / 10); |
515 $('#wb_sodium').val(Math.round(sodium * 10) / 10); |
851 $('#wb_sodium').val(Math.round(sodium * 10) / 10); |
516 $('#wb_sulfate').val(Math.round(sulfate * 10) / 10); |
852 $('#wb_sulfate').val(Math.round(sulfate * 10) / 10); |
542 if (sulfate <= 350) { |
878 if (sulfate <= 350) { |
543 setRangeIndicator("sulfate", "normal"); |
879 setRangeIndicator("sulfate", "normal"); |
544 } else { |
880 } else { |
545 setRangeIndicator("sulfate", "high"); |
881 setRangeIndicator("sulfate", "high"); |
546 } |
882 } |
|
883 if (ph < 5.2) { |
|
884 setRangeIndicator("ph", "low"); |
|
885 } else if (ph > 5.6) { |
|
886 setRangeIndicator("ph", "high"); |
|
887 } else { |
|
888 setRangeIndicator("ph", "normal"); |
|
889 } |
|
890 calcSparge(); |
|
891 } |
|
892 |
|
893 function calcSparge() { |
|
894 |
|
895 // Code from BrewBuddy/Brouwhulp, who got it from http://www.brewery.org/brewery/library/Acidi0,00fWaterAJD0497.html |
|
896 var TargetpH = dataRecord.sparge_ph; |
|
897 var Source_pH = dataRecord.w1_ph; |
|
898 var Source_alkalinity = dataRecord.w1_total_alkalinity; |
|
899 // Select watersource or fallback to the first source. |
|
900 if (dataRecord.sparge_source == 'Bron 2') { |
|
901 if (dataRecord.w2_ph > 0.0) { |
|
902 Source_pH = dataRecord.w2_ph; |
|
903 Source_alkalinity = dataRecord.w2_total_alkalinity; |
|
904 } else { |
|
905 dataRecord.sparge_source = 'Bron 1'; |
|
906 $("#sparge_source").val('Bron 1'); |
|
907 } |
|
908 } else if (dataRecord.sparge_source == 'Gemengd') { |
|
909 if (dataRecord.w2_ph > 0.0) { |
|
910 Source_pH = parseFloat($("#wg_ph").jqxNumberInput('decimal')); |
|
911 Source_alkalinity = parseFloat($("#wg_total_alkalinity").jqxNumberInput('decimal')); |
|
912 } else { |
|
913 dataRecord.sparge_source = 'Bron 1'; |
|
914 $("#sparge_source").val('Bron 1'); |
|
915 } |
|
916 } |
|
917 |
|
918 console.log("calcSparge() target pH: "+TargetpH+" Source: "+Source_pH+" alkalinity: "+Source_alkalinity); |
|
919 |
|
920 // Step 1: Compute the mole fractions of carbonic (f1o), bicarbonate (f2o) and carbonate(f3o) at the water pH |
|
921 r1 = Math.pow(10, Source_pH - 6.38); |
|
922 r2 = Math.pow(10, Source_pH - 10.33); |
|
923 d = 1 + r1 + r1*r2; |
|
924 f1 = 1/d; |
|
925 f2 = r1/d; |
|
926 f3 = r1 * r2 / d; |
|
927 |
|
928 //Step 2. Compute the mole fractions at pH = 4.3 (the pH which defines alkalinity) |
|
929 r143 = Math.pow(10, 4.3 - 6.38); |
|
930 r243 = Math.pow(10, 4.3 - 10.33); |
|
931 d43 = 1 + r143 + r143*r243; |
|
932 f143 = 1/d43; |
|
933 f243 = r143 / d43; |
|
934 f343 = r143 * r243 / d43; |
|
935 |
|
936 //Step 3. Convert the sample alkalinity to milliequivalents/L |
|
937 alkalinity = Source_alkalinity / 50; |
|
938 //Step 4. Solve |
|
939 alkalinity = alkalinity / ((f143-f1)+(f3-f343)); |
|
940 |
|
941 //Step 5. Compute mole fractions at desired pH |
|
942 r1g = Math.pow(10, TargetpH - 6.38); |
|
943 r2g = Math.pow(10, TargetpH - 10.33); |
|
944 dg = 1 + r1g + r1g*r2g; |
|
945 f1g = 1/dg; |
|
946 f2g = r1g / dg; |
|
947 f3g = r1g * r2g / dg; |
|
948 |
|
949 //Step 6. Use these to compute the milliequivalents acid required per liter (mEq/L) |
|
950 Acid = alkalinity * ((f1g-f1)+(f3-f3g)) + Math.pow(10, -TargetpH) - Math.pow(10, -Source_pH); //mEq/l |
|
951 |
|
952 if ($("#sparge_acid_type").val() == "") { |
|
953 $("#sparge_acid_type").val('Melkzuur'); |
|
954 dataRecord.sparge_acid_type = 'Melkzuur'; |
|
955 } |
|
956 AT = dataRecord.sparge_acid_type; |
|
957 var result = GetAcidSpecs(AT); |
|
958 pK1 = result.pK1; |
|
959 pK2 = result.pK2; |
|
960 pK3 = result.pK3; |
|
961 MolWt = result.MolWt; |
|
962 AcidSG = result.AcidSG; |
|
963 AcidPrc = result.AcidPrc; |
|
964 fract = CalcFrac(TargetpH, pK1, pK2, pK3); |
|
965 |
|
966 //Step 9. Now divide the mEq required by the "fraction". This is the required number of moles of acid. |
|
967 Acid /= fract; |
|
968 |
|
969 //Step 10. Multiply by molecular weight of the acid |
|
970 Acid *= MolWt; //mg |
|
971 |
|
972 Acid = Acid / AcidSG; //ml ; 88% lactic solution |
|
973 f1 = dataRecord.sparge_acid_perc; |
|
974 if (f1 <= 0.1) |
|
975 f1 = AcidPrc; |
|
976 Acid = Acid * AcidPrc / (f1 / 100); |
|
977 |
|
978 Acid *= dataRecord.sparge_volume; //ml lactic acid total |
|
979 Acid = Math.round(Acid * 100) / 100; |
|
980 dataRecord.sparge_acid_amount = Acid / 1000; |
|
981 $("#sparge_acid_amount").val(Acid); |
547 } |
982 } |
548 |
983 |
549 function calcInit () { |
984 function calcInit () { |
550 console.log("calc.init()"); |
985 console.log("calc.init()"); |
551 |
986 |
552 calcSGendMash(); |
987 calcSGendMash(); |
553 calcMashEfficiency(); |
988 calcMashEfficiency(); |
554 |
989 |
|
990 $("#calc_acid").on('checked', function (event) { |
|
991 dataRecord.calc_acid = true; |
|
992 calcWater(); |
|
993 }); |
|
994 $("#calc_acid").on('unchecked', function (event) { |
|
995 dataRecord.calc_acid = false; |
|
996 calcWater(); |
|
997 }); |
555 $("#w1_name").jqxDropDownList('selectItem', dataRecord.w1_name); |
998 $("#w1_name").jqxDropDownList('selectItem', dataRecord.w1_name); |
556 $("#w2_name").jqxDropDownList('selectItem', dataRecord.w2_name); |
999 $("#w2_name").jqxDropDownList('selectItem', dataRecord.w2_name); |
557 // Fix tap water if zero using mash infuse amount. |
1000 // Fix tap water if zero using mash infuse amount. |
558 if (parseFloat($("#wg_amount").jqxNumberInput('decimal')) == 0 && mash_infuse > 0) { |
1001 if (parseFloat($("#wg_amount").jqxNumberInput('decimal')) == 0 && mash_infuse > 0) { |
559 $("#w1_amount").val(mash_infuse); |
1002 $("#w1_amount").val(mash_infuse); |
2580 $("#pr_magnesium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); |
3045 $("#pr_magnesium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); |
2581 $("#pr_sodium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); |
3046 $("#pr_sodium").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); |
2582 $("#pr_total_alkalinity").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); |
3047 $("#pr_total_alkalinity").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); |
2583 $("#pr_chloride").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); |
3048 $("#pr_chloride").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); |
2584 $("#pr_sulfate").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); |
3049 $("#pr_sulfate").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); |
2585 $("#wa_cacl2").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: ' gr', symbolPosition: 'right' }); |
3050 |
2586 $("#wa_caso4").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: ' gr', symbolPosition: 'right' }); |
3051 $("#tgt_bu").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 2, readOnly: true }); |
2587 $("#wa_mgso4").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: ' gr', symbolPosition: 'right' }); |
3052 $("#tgt_cl_so4").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 74, height: 23, decimalDigits: 1, readOnly: true }); |
2588 $("#wa_nacl").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: ' gr', symbolPosition: 'right' }); |
3053 |
|
3054 $("#wa_cacl2").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, max: 1000, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: ' gr', symbolPosition: 'right' }); |
|
3055 $("#wa_caso4").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, max: 1000, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: ' gr', symbolPosition: 'right' }); |
|
3056 $("#wa_mgso4").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, max: 1000, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: ' gr', symbolPosition: 'right' }); |
|
3057 $("#wa_nacl").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, max: 1000, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1, symbol: ' gr', symbolPosition: 'right' }); |
2589 |
3058 |
2590 $("#calc_acid").jqxCheckBox({ theme: theme, width: 120, height: 23 }); |
3059 $("#calc_acid").jqxCheckBox({ theme: theme, width: 120, height: 23 }); |
2591 $("#wa_base_name").jqxDropDownList({ theme: theme, source: srcBase, width: 125, height: 23, dropDownHeight: 128 }); |
3060 $("#wa_base_name").jqxDropDownList({ theme: theme, source: srcBase, width: 100, height: 23, dropDownHeight: 128 }); |
2592 $("#wa_base").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 2, spinButtons: true, spinButtonsStep: 0.05, symbol: ' gr', symbolPosition: 'right' }); |
3061 $("#wa_base").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 2, spinButtons: true, spinButtonsStep: 0.05, symbol: ' gr', symbolPosition: 'right' }); |
2593 $("#wa_acid_name").jqxDropDownList({ theme: theme, source: srcAcid, width: 125, height: 23, dropDownHeight: 128 }) |
3062 $("#wa_acid_name").jqxDropDownList({ theme: theme, source: srcAcid, width: 100, height: 23, dropDownHeight: 128 }) |
2594 $("#wa_acid").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 2, spinButtons: true, spinButtonsStep: 0.05, symbol: ' ml', symbolPosition: 'right' }); |
3063 $("#wa_acid").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 0, decimalDigits: 2, spinButtons: true, spinButtonsStep: 0.05, symbol: ' ml', symbolPosition: 'right' }); |
2595 $("#wa_acid_perc").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 80, height: 23, min: 0, max: 100, decimalDigits: 0, spinButtons: true, symbol: '%', symbolPosition: 'right' }); |
3064 $("#wa_acid_perc").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 80, height: 23, min: 0, max: 100, decimalDigits: 0, spinButtons: true, symbol: '%', symbolPosition: 'right' }); |
2596 |
3065 |
|
3066 $("#sparge_temp").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 70, max: 98, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.5 }); |
2597 $("#sparge_volume").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1 }); |
3067 $("#sparge_volume").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1 }); |
2598 $("#sparge_ph").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1 }); |
3068 $("#sparge_ph").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, min: 4.5, max: 6.5, decimalDigits: 1, spinButtons: true, spinButtonsStep: 0.1 }); |
2599 $("#sparge_acid_amount").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 5, readOnly: true }); |
3069 $("#sparge_source").jqxDropDownList({ theme: theme, source: srcSource, width: 100, height: 23, dropDownHeight: 95 }); |
|
3070 $("#sparge_acid_amount").jqxNumberInput({ inputMode: 'simple', theme: theme, width: 100, height: 23, decimalDigits: 2, readOnly: true, symbol: ' ml', symbolPosition: 'right' }); |
|
3071 $("#sparge_acid_type").jqxDropDownList({ theme: theme, source: srcAcid, width: 100, height: 23, dropDownHeight: 128 }); |
|
3072 $("#sparge_acid_perc").jqxNumberInput({ inputMode: 'simple', spinMode: 'simple', theme: theme, width: 100, height: 23, spinButtons: true, decimalDigits: 0, symbol: '%', symbolPosition: 'right' }); |
2600 |
3073 |
2601 $('#jqxTabs').jqxTabs({ |
3074 $('#jqxTabs').jqxTabs({ |
2602 theme: theme, |
3075 theme: theme, |
2603 width: 1280, |
3076 width: 1280, |
2604 height: 630, |
3077 height: 630, |