1062 $('#wa_nacl').val(row.m_amount * 1000); |
1062 $('#wa_nacl').val(row.m_amount * 1000); |
1063 break; |
1063 break; |
1064 case 'Melkzuur': |
1064 case 'Melkzuur': |
1065 $('#wa_acid_name').val(0); |
1065 $('#wa_acid_name').val(0); |
1066 $('#wa_acid').val(row.m_amount * 1000); |
1066 $('#wa_acid').val(row.m_amount * 1000); |
1067 $('#wa_acid_perc').val(80); |
1067 $('#wa_acid_perc').val(AcidTypeData[0].AcidPrc); // TODO: this ignores changed percentages. |
1068 last_acid = 'Melkzuur'; |
1068 last_acid = 'Melkzuur'; |
1069 break; |
1069 break; |
1070 case 'Zoutzuur': |
1070 case 'Zoutzuur': |
1071 $('#wa_acid_name').val(1); |
1071 $('#wa_acid_name').val(1); |
1072 $('#wa_acid').val(row.m_amount * 1000); |
1072 $('#wa_acid').val(row.m_amount * 1000); |
1073 $('#wa_acid_perc').val(80); |
1073 $('#wa_acid_perc').val(AcidTypeData[1].AcidPrc); |
1074 last_acid = 'Zoutzuur'; |
1074 last_acid = 'Zoutzuur'; |
1075 break; |
1075 break; |
1076 case 'Fosforzuur': |
1076 case 'Fosforzuur': |
1077 $('#wa_acid_name').val(2); |
1077 $('#wa_acid_name').val(2); |
1078 $('#wa_acid').val(row.m_amount * 1000); |
1078 $('#wa_acid').val(row.m_amount * 1000); |
1079 $('#wa_acid_perc').val(80); |
1079 $('#wa_acid_perc').val(AcidTypeData[2].AcidPrc); |
1080 last_acid = 'Fosforzuur'; |
1080 last_acid = 'Fosforzuur'; |
1081 break; |
1081 break; |
1082 case 'Zwavelzuur': |
1082 case 'Zwavelzuur': |
1083 $('#wa_acid_name').val(3); |
1083 $('#wa_acid_name').val(3); |
1084 $('#wa_acid').val(row.m_amount * 1000); |
1084 $('#wa_acid').val(row.m_amount * 1000); |
1085 $('#wa_acid_perc').val(80); |
1085 $('#wa_acid_perc').val(AcidTypeData[3].AcidPrc); |
1086 last_acid = 'Zwavelzuur'; |
1086 last_acid = 'Zwavelzuur'; |
1087 break; |
1087 break; |
1088 case 'NaHCO3': |
1088 case 'NaHCO3': |
1089 $('#wa_base_name').val(0); |
1089 $('#wa_base_name').val(0); |
1090 $('#wa_base').val(row.m_amount * 1000); |
1090 $('#wa_base').val(row.m_amount * 1000); |
2792 Magn = parseFloat($('#wg_magnesium').jqxNumberInput('decimal')) / (MMMg / 2); |
2792 Magn = parseFloat($('#wg_magnesium').jqxNumberInput('decimal')) / (MMMg / 2); |
2793 Z = ZAlkalinity(pHZ); |
2793 Z = ZAlkalinity(pHZ); |
2794 return Z - (Calc / 3.5 + Magn / 7); |
2794 return Z - (Calc / 3.5 + Magn / 7); |
2795 } |
2795 } |
2796 |
2796 |
2797 function ProtonDeficit(pHZ) { |
2797 function BufferCapacity(di_ph, acid_to_ph_57, ebc, graintype) { |
2798 |
2798 C1 = 0; |
2799 var rows, i, C1, ebc, x, Result = ZRA(pHZ) * parseFloat($('#wg_amount').jqxNumberInput('decimal')); |
2799 if ((di_ph != 5.7) && ((acid_to_ph_57 < - 0.1) || (acid_to_ph_57 > 0.1))) { |
2800 // proton deficit for the grist |
2800 C1 = acid_to_ph_57 / (di_ph - 5.7); |
2801 if ((rows = $('#fermentableGrid').jqxGrid('getrows'))) { |
2801 } else { |
2802 for (i = 0; i < rows.length; i++) { |
|
2803 row = rows[i]; |
|
2804 if (row.f_added == 0 && row.f_graintype != 6) { // Added == Mash && graintype != No Malt |
|
2805 // Check if acid is required |
|
2806 C1 = 0; |
|
2807 if ((row.f_di_ph != 5.7) && ((row.f_acid_to_ph_57 < - 0.1) || (row.f_acid_to_ph_57 > 0.1))) { |
|
2808 C1 = row.f_acid_to_ph_57 / (row.f_di_ph - 5.7); |
|
2809 } else { |
|
2810 // If the acid_to_ph_5.7 is unknown from the maltster, guess the required acid. |
2802 // If the acid_to_ph_5.7 is unknown from the maltster, guess the required acid. |
2811 ebc = row.f_color; |
2803 switch (graintype) { |
2812 switch (row.f_graintype) { |
|
2813 case 0: // Base, Special, Kilned |
2804 case 0: // Base, Special, Kilned |
2814 case 3: |
2805 case 3: |
2815 case 5: C1 = 0.014 * ebc - 34.192; |
2806 case 5: C1 = 0.014 * ebc - 34.192; |
2816 break; |
2807 break; |
2817 case 2: C1 = -0.0597 * ebc - 32.457; // Crystal |
2808 case 2: C1 = -0.0597 * ebc - 32.457; // Crystal |
2912 chloride = dataRecord.w1_chloride; |
2900 chloride = dataRecord.w1_chloride; |
2913 sulfate = dataRecord.w1_sulfate; |
2901 sulfate = dataRecord.w1_sulfate; |
2914 total_alkalinity = dataRecord.w1_total_alkalinity; |
2902 total_alkalinity = dataRecord.w1_total_alkalinity; |
2915 ph = dataRecord.w1_ph; |
2903 ph = dataRecord.w1_ph; |
2916 } |
2904 } |
|
2905 var bicarbonate = total_alkalinity * 1.22; |
|
2906 |
|
2907 /* Save mixed water ions for later */ |
|
2908 var wg_calcium = calcium; |
|
2909 var wg_sodium = sodium; |
|
2910 var wg_total_alkalinity = total_alkalinity; |
|
2911 var wg_chloride = chloride; |
|
2912 var wg_sulfate = sulfate; |
|
2913 var wg_bicarbonate = bicarbonate; |
|
2914 |
2917 $('#wg_amount').val(liters); |
2915 $('#wg_amount').val(liters); |
2918 wg_calcium = calcium; |
2916 $('#wg_calcium').val(Round(calcium, 1)); |
2919 $('#wg_calcium').val(Math.round(calcium * 10) / 10); |
2917 $('#wg_magnesium').val(Round(magnesium, 1)); |
2920 //var wg_magnesium = magnesium; |
2918 $('#wg_sodium').val(Round(sodium, 1)); |
2921 $('#wg_magnesium').val(Math.round(magnesium * 10) / 10); |
2919 $('#wg_total_alkalinity').val(Round(total_alkalinity, 1)); |
2922 wg_sodium = sodium; |
2920 $('#wg_chloride').val(Round(chloride, 1)); |
2923 $('#wg_sodium').val(Math.round(sodium * 10) / 10); |
2921 $('#wg_sulfate').val(Round(sulfate, 1)); |
2924 wg_total_alkalinity = total_alkalinity; |
2922 $('#wg_ph').val(Round(ph, 2)); |
2925 $('#wg_total_alkalinity').val(Math.round(total_alkalinity * 10) / 10); |
2923 |
2926 wg_chloride = chloride; |
2924 var mash_ph = Round(MashpH(), 3); |
2927 $('#wg_chloride').val(Math.round(chloride * 10) / 10); |
2925 console.log('Distilled water mash pH: ' + mash_ph); |
2928 wg_sulfate = sulfate; |
2926 |
2929 $('#wg_sulfate').val(Math.round(sulfate * 10) / 10); |
2927 /* Calculate Salt additions */ |
2930 // Note: brouwhulp has the malts included here in the result. |
2928 if (liters > 0) { |
2931 //var wg_ph = ph; |
2929 calcium += (parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 * 1000 + |
2932 var mash_ph = Round(MashpH(), 1); |
2930 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 * 1000) / liters; |
2933 $('#wg_ph').val(Round(ph, 1)); |
2931 magnesium += (parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMMg / MMMgSO4 * 1000) / liters; |
2934 $('#wb_ph').val(mash_ph); |
2932 sodium += (parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl * 1000 + |
2935 $('#est_mash_ph').val(mash_ph); |
2933 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMNa / MMNaHCO3 * 1000) / liters; |
2936 bicarbonate = total_alkalinity * 1.22; |
2934 sulfate += (parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 * 1000 + |
2937 wg_bicarbonate = bicarbonate; |
2935 parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 * 1000) / liters; |
2938 |
2936 chloride += (2 * parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCl / MMCaCl2 * 1000 + |
2939 // Noot: de volgende berekeningen geven bijna gelijke resultaten in Brun'water. |
2937 parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMCl / MMNaCl * 1000) / liters; |
2940 // Calculate Ca |
2938 } |
2941 RA = parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 + |
2939 |
2942 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4; |
2940 if (dataRecord.wa_acid_name < 0 || dataRecord,wa_acid_name >= AcidTypeData.length) { |
2943 calcium += 1000 * RA / liters; |
|
2944 |
|
2945 // Calculate Mg |
|
2946 RA = parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMMg / MMMgSO4; |
|
2947 magnesium += 1000 * RA / liters; |
|
2948 |
|
2949 // Calculate Na |
|
2950 RA = parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl + |
|
2951 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMNa / MMNaHCO3; |
|
2952 sodium += 1000 * RA / liters; |
|
2953 |
|
2954 // Calculate SO4 |
|
2955 RA = parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + |
|
2956 parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4; |
|
2957 sulfate += 1000 * RA / liters; |
|
2958 |
|
2959 // Calculate Cl |
|
2960 RA = 2 * parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCl / MMCaCl2 + |
|
2961 parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMCl / MMNaCl; |
|
2962 chloride += 1000 * RA / liters; |
|
2963 // Einde noot. |
|
2964 |
|
2965 if (parseInt($('#wa_acid_name').val()) < 0 || parseInt($('#wa_acid_name').val()) > 3) { |
|
2966 $('#wa_acid_name').val(0); |
2941 $('#wa_acid_name').val(0); |
2967 dataRecord.wa_acid_name = 0; |
2942 dataRecord.wa_acid_name = 0; |
|
2943 dataRecord.wa_acid_perc = AcidTypeData[0].AcidPrc; |
|
2944 $('#wa_acid_perc').val(AcidTypeData[0].AcidPrc); |
2968 } |
2945 } |
2969 if (last_acid == '') |
2946 if (last_acid == '') |
2970 last_acid = AcidTypeData[$('#wa_acid_name').val()].nl; |
2947 last_acid = AcidTypeData[dataRecord.wa_acid_name].nl; |
2971 |
2948 |
2972 if (parseInt($('#wa_base_name').val()) < 0 || parseInt($('#wa_base_name').val()) > 3) { |
2949 if (parseFloat(dataRecord.wa_acid_perc) == 0) { |
|
2950 dataRecord.wa_acid_perc = AcidTypeData[AT].AcidPrc; |
|
2951 $('#wa_acid_perc').val(AcidTypeData[AT].AcidPrc); |
|
2952 } |
|
2953 |
|
2954 if (dataRecord.wa_base_name < 0 || dataRecord.wa_base_name > 3) { |
2973 $('#wa_base_name').val(0); |
2955 $('#wa_base_name').val(0); |
2974 dataRecord.wa_base_name = 0; |
2956 dataRecord.wa_base_name = 0; |
2975 } |
2957 } |
2976 if (last_base == '') |
2958 if (last_base == '') |
2977 last_base = BaseTypeData[$('#wa_base_name').val()].nl; |
2959 last_base = BaseTypeData[dataRecord.wa_base_name].nl; |
2978 |
2960 |
2979 AT = dataRecord.wa_acid_name; |
2961 AT = dataRecord.wa_acid_name; |
2980 BT = dataRecord.wa_base_name; |
2962 BT = dataRecord.wa_base_name; |
2981 |
2963 |
2982 result = GetAcidSpecs(AT); |
2964 /* Note that the next calculations do not correct the pH change by the added salts. |
2983 pK1 = result.pK1; |
2965 This pH change is at most 0.1 pH and is a minor difference in Acid amount. */ |
2984 pK2 = result.pK2; |
|
2985 pK3 = result.pK3; |
|
2986 MolWt = result.MolWt; |
|
2987 AcidSG = result.AcidSG; |
|
2988 AcidPrc = result.AcidPrc; |
|
2989 |
2966 |
2990 if (dataRecord.calc_acid) { |
2967 if (dataRecord.calc_acid) { |
|
2968 /* Auto calculate pH */ |
|
2969 $('.c_mashph').show(); |
2991 TpH = parseFloat(dataRecord.mash_ph); |
2970 TpH = parseFloat(dataRecord.mash_ph); |
2992 protonDeficit = ProtonDeficit(TpH); |
2971 protonDeficit = ProtonDeficit(TpH); |
2993 //console.log('calc_acid tgt: ' + TpH + ' protonDeficit: ' + protonDeficit); |
2972 //console.log('calc_acid tgt: ' + TpH + ' protonDeficit: ' + protonDeficit); |
2994 if (protonDeficit > 0) { // Add acid |
2973 if (protonDeficit > 0) { // Add acid |
2995 $('#wa_base').val(0); |
2974 $('#wa_base').val(0); |
|
2975 dataRecord.wa_base = 0; |
2996 setWaterAgent(last_base, 0); |
2976 setWaterAgent(last_base, 0); |
2997 frac = CalcFrac(TpH, pK1, pK2, pK3); |
2977 frac = CalcFrac(TpH, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3); |
2998 Acid = protonDeficit / frac; |
2978 Acid = protonDeficit / frac; |
2999 Acid *= MolWt; // mg |
2979 Acid *= AcidTypeData[AT].MolWt; // mg |
3000 Acidmg = Acid; |
2980 Acidmg = Acid; |
3001 Acid = Acid / AcidSG; // ml |
2981 Acid = Acid / AcidTypeData[AT].AcidSG; // ml |
3002 |
2982 Acid = Round(Acid / (parseFloat(dataRecord.wa_acid_perc) / 100), 2); // ml |
3003 if (parseFloat($('#wa_acid_perc').jqxNumberInput('decimal')) == 0) |
2983 console.log('Mash auto Acid final ml: ' + Acid); |
3004 $('#wa_acid_perc').val(AcidPrc); |
|
3005 Acid = Round(Acid * AcidPrc / (parseFloat($('#wa_acid_perc').jqxNumberInput('decimal')) / 100), 2); // ml |
|
3006 //console.log('Final ml: ' + Acid); |
|
3007 $('#wa_acid').val(Acid); |
2984 $('#wa_acid').val(Acid); |
3008 setWaterAgent(AcidTypeData[AT].nl, Acid); |
2985 setWaterAgent(AcidTypeData[AT].nl, Acid); |
3009 |
2986 |
3010 bicarbonate = bicarbonate - protonDeficit * frac / liters; |
2987 bicarbonate = bicarbonate - protonDeficit * frac / liters; |
3011 total_alkalinity = bicarbonate * 50 / 61; |
2988 total_alkalinity = bicarbonate * 50 / 61; |
3012 } else if (protonDeficit < 0) { //Add base |
2989 } else if (protonDeficit < 0) { //Add base |
3013 $('#wa_acid').val(0); |
2990 $('#wa_acid').val(0); |
|
2991 dataRecord.wa_acid = 0; |
3014 setWaterAgent(last_acid, 0); |
2992 setWaterAgent(last_acid, 0); |
3015 r1d = Math.pow(10, (TpH - 6.38)); |
2993 r1d = Math.pow(10, (TpH - 6.35)); |
3016 r2d = Math.pow(10, (TpH - 10.38)); |
2994 r2d = Math.pow(10, (TpH - 10.33)); |
3017 f1d = 1 / (1 + r1d + r1d * r2d); |
2995 f1d = 1 / (1 + r1d + r1d * r2d); |
3018 f2d = f1d * r1d; |
2996 f2d = f1d * r1d; |
3019 f3d = f2d * r2d; |
2997 f3d = f2d * r2d; |
3020 switch (BT) { |
2998 switch (BT) { |
3021 case 0: |
2999 case 0: |
3085 // Bicarbonate |
3057 // Bicarbonate |
3086 RA = -protonDeficit / liters; |
3058 RA = -protonDeficit / liters; |
3087 total_alkalinity = wg_total_alkalinity + RA; |
3059 total_alkalinity = wg_total_alkalinity + RA; |
3088 bicarbonate = total_alkalinity * 61 / 50; |
3060 bicarbonate = total_alkalinity * 61 / 50; |
3089 // Calcium |
3061 // Calcium |
3090 RA = parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 + |
3062 RA = (parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 * 1000 + |
3091 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 + |
3063 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 * 1000 + |
3092 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMCa / MMCaOH2; |
3064 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMCa / MMCaOH2 * 1000) / liters; |
3093 RA = 1000 * RA / liters; |
|
3094 calcium = wg_calcium + RA; |
3065 calcium = wg_calcium + RA; |
3095 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
3066 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
3096 } |
3067 } |
3097 break; |
3068 break; |
3098 } |
3069 } |
3099 } |
3070 } |
3100 ph = TpH; |
3071 ph = TpH; |
3101 $('#wb_ph').val(Round(ph, 1)); |
3072 $('#wb_ph').val(Round(ph, 2)); |
3102 $('#est_mash_ph').val(Round(ph, 1)); |
3073 $('#est_mash_ph').val(Round(ph, 2)); |
3103 } else { // Manual |
3074 } else { |
|
3075 /* Manual calculate pH */ |
|
3076 $('.c_mashph').hide(); |
3104 console.log('calc_acid no'); |
3077 console.log('calc_acid no'); |
3105 // First add base salts |
3078 if (parseFloat($('#wa_base').jqxNumberInput('decimal')) > 0 && liters > 0) { |
3106 if (parseFloat($('#wa_base').jqxNumberInput('decimal')) > 0) { |
3079 /* First add the base salts */ |
3107 if (liters > 0) { |
3080 switch (BT) { |
3108 switch (BT) { |
3081 case 0: // Sodiumbicarbonate, Na |
3109 case 0: // Sodiumbicarbonate, Na |
3082 RA = (parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl * 1000 + |
3110 RA = parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl + |
3083 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMNa / MMNaHCO3 * 1000) / liters; |
3111 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMNa / MMNaHCO3; |
3084 sodium = wg_sodium + RA; |
3112 RA = 1000 * RA / liters; |
3085 // HCO3 |
3113 sodium = wg_sodium + RA; |
3086 RA = (parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3 * 1000) / liters; |
3114 // HCO3 |
3087 bicarbonate = wg_bicarbonate + RA; |
3115 RA = parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3; |
3088 total_alkalinity = bicarbonate * 50 / 61; |
3116 RA = 1000 * RA / liters; |
3089 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
3117 bicarbonate = wg_bicarbonate + RA; |
3090 break; |
3118 total_alkalinity = bicarbonate * 50 / 61; |
3091 case 1: // Sodiumcarbonate |
3119 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
3092 RA = (parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl * 1000 + |
3120 break; |
3093 parseFloat($('#wa_base').jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3 * 1000) / liters; |
3121 case 1: // Sodiumcarbonate |
3094 sodium = wg_sodium + RA; |
3122 RA = parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl + |
3095 // HCO3 |
3123 parseFloat($('#wa_base').jqxNumberInput('decimal')) * 2 * MMNa / MMNa2CO3; |
3096 RA = (parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3 * 1000) / liters; |
3124 RA = 1000 * RA / liters; |
3097 bicarbonate = wg_bicarbonate + RA; |
3125 sodium = wg_sodium + RA; |
3098 total_alkalinity = bicarbonate * 50 / 61; |
3126 // HCO3 |
3099 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
3127 RA = parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMHCO3 / MMNa2CO3; |
3100 break; |
3128 RA = 1000 * RA / liters; |
3101 case 2: // Calciumcarbonate: Bicarbonate |
3129 bicarbonate = wg_bicarbonate + RA; |
3102 RA = (parseFloat($('#wa_base').jqxNumberInput('decimal')) / 3 * MMHCO3 * 1000 / MMCaCO3) / liters; |
3130 total_alkalinity = bicarbonate * 50 / 61; |
3103 bicarbonate = wg_bicarbonate + RA; |
3131 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
3104 total_alkalinity = bicarbonate * 50 / 61; |
3132 break; |
3105 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
3133 case 2: // Calciumcarbonate: Bicarbonate |
3106 // Ca |
3134 RA = parseFloat($('#wa_base').jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3; |
3107 RA = (parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa * 1000 / MMCaCl2 + |
3135 RA = 1000 * RA / liters; |
3108 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa * 1000 / MMCaSO4 + |
3136 bicarbonate = wg_bicarbonate + RA; |
3109 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMCa * 1000/ MMCaCO3) / liters; |
3137 total_alkalinity = bicarbonate * 50 / 61; |
3110 calcium = wg_calcium + RA; |
3138 RA = ResidualAlkalinity(wb_total_alkalinity, wb_calcium, wb_magnesium); |
3111 break; |
3139 // Ca |
|
3140 RA = parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 + |
|
3141 parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 + |
|
3142 parseFloat($('#wa_base').jqxNumberInput('decimal')) * MMCa / MMCaCO3; |
|
3143 RA = 1000 * RA / liters; |
|
3144 calcium = wg_calcium + RA; |
|
3145 break; |
|
3146 } |
|
3147 } |
3112 } |
3148 } |
3113 } |
3149 |
3114 |
3150 TpH = parseFloat(dataRecord.mash_ph); |
3115 pHa = Round(ph, 3); // Adjusted water pH |
3151 pHa = MashpH(); // This one is in demi water, should be in adjusted water??? |
3116 // Then calculate the new pH with added acids and malts |
3152 // Then calculate the new pH with added acids |
3117 console.log('Mash pH: ' + pHa); |
3153 if (parseFloat($('#wa_acid').jqxNumberInput('decimal')) > 0) { |
3118 Acid = AcidTypeData[AT].AcidSG * (parseFloat(dataRecord.wa_acid_perc) / 100); // ml |
3154 console.log('TpH: ' + TpH + ' water: ' + pHa); |
3119 Acid *= parseFloat($('#wa_acid').jqxNumberInput('decimal')); |
3155 Acid = parseFloat($('#wa_acid').jqxNumberInput('decimal')); |
3120 Acid /= AcidTypeData[AT].MolWt; // mg |
3156 if (parseFloat($('#wa_acid_perc').jqxNumberInput('decimal')) == 0) |
3121 Acidmg = Acid; |
3157 $('#wa_acid_perc').val(AcidPrc); |
3122 |
3158 Acid = Acid / AcidPrc * (parseFloat($('#wa_acid_perc').jqxNumberInput('decimal')) / 100); // ml |
3123 //find the pH where the protondeficit = protondeficit by the acid |
3159 Acid *= AcidSG; // ml |
3124 frac = CalcFrac(pHa, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3); |
3160 Acid /= MolWt; // mg |
3125 protonDeficit = Round(Acid * frac, 3); |
3161 Acidmg = Acid; |
3126 //console.log('protonDeficit Acid: ' + protonDeficit + ' frac: ' + frac + ' pH: ' + pHa); |
3162 |
3127 |
3163 //find the pH where the protondeficit = protondeficit by the acid |
3128 deltapH = 0.001; |
3164 frac = CalcFrac(pHa, pK1, pK2, pK3); |
3129 deltapd = 0.1; |
3165 protonDeficit = Acid * frac; |
3130 pd = Round(ProtonDeficit(pHa), 6); |
3166 |
3131 n = 0; |
3167 deltapH = 0.001; |
3132 while (((pd < (protonDeficit - deltapd)) || (pd > (protonDeficit + deltapd))) && (n < 4000)) { |
3168 deltapd = 0.1; |
|
3169 console.log('in calcWater() manual'); |
|
3170 pd = ProtonDeficit(pHa); |
|
3171 n = 0; |
|
3172 while (((pd < (protonDeficit - deltapd)) || (pd > (protonDeficit + deltapd))) && (n < 2000)) { |
|
3173 n++; |
3133 n++; |
3174 if (pd < (protonDeficit - deltapd)) |
3134 if (pd < (protonDeficit - deltapd)) |
3175 pHa -= deltapH; |
3135 pHa -= deltapH; |
3176 else if (pd > (protonDeficit + deltapd)) |
3136 else if (pd > (protonDeficit + deltapd)) |
3177 pHa += deltapH; |
3137 pHa += deltapH; |
3178 frac = CalcFrac(pHa, pK1, pK2, pK3); |
3138 frac = CalcFrac(pHa, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3); |
3179 protonDeficit = Acid * frac; |
3139 protonDeficit = Acid * frac; |
3180 pd = ProtonDeficit(pHa); |
3140 pd = ProtonDeficit(pHa); |
3181 } |
3141 } |
3182 console.log('n: ' + n + ' pd: ' + pd + ' protonDeficit: ' + protonDeficit + ' frac: ' + frac + ' pHa: ' + pHa); |
3142 //console.log('n: ' + n + ' pd: ' + pd + ' protonDeficit: ' + protonDeficit + ' frac: ' + frac + ' pHa: ' + pHa); |
3183 RA = wg_bicarbonate - protonDeficit * frac / liters; |
3143 RA = wg_bicarbonate - protonDeficit * frac / liters; |
3184 bicarbonate = RA; |
3144 bicarbonate = RA; |
3185 total_alkalinity = RA * 50 / 61; |
3145 total_alkalinity = RA * 50 / 61; |
3186 ph = pHa; |
3146 ph = pHa; |
3187 $('#wb_ph').val(Round(ph, 1)); |
3147 $('#wb_ph').val(Round(ph, 2)); |
3188 $('#est_mash_ph').val(Round(ph, 1)); |
3148 $('#est_mash_ph').val(Round(ph, 2)); |
3189 } |
3149 } |
3190 } |
3150 |
3191 |
3151 if ((AT == 3) && (liters > 0)) { // Sulfuric / Zwavelzuur |
3192 if ((AT == 3) && (liters > 0)) { // Sulfuctic / Zwavelzuur |
|
3193 RA = parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + |
3152 RA = parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 + |
3194 parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 + |
3153 parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 + |
3195 Acidmg / 1000 * MMSO4 / (MMSO4 + 2); |
3154 Acidmg / 1000 * MMSO4 / (MMSO4 + 2); |
3196 RA = 1000 * RA / liters; |
3155 RA = 1000 * RA / liters; |
3197 sulfate = wg_sulfate + RA; // Not add to sulfate?? |
3156 sulfate = wg_sulfate + RA; // Not add to sulfate?? |
3302 calcSupplies(); |
3261 calcSupplies(); |
3303 } |
3262 } |
3304 |
3263 |
3305 function calcSparge() { |
3264 function calcSparge() { |
3306 |
3265 |
3307 var TargetpH, Source_pH, Source_alkalinity, r1, r2, d, f1, f3, r143, r243, d43, f143, f343, |
3266 /* Based on the work of ajDeLange. */ |
3308 alkalinity, Ct, r1g, r2g, dg, f1g, f3g, Acid, AT, result, pK1, pK2, pK3, MolWt, AcidSG, AcidPrc, fract; |
3267 var TargetpH = dataRecord.sparge_ph; |
3309 |
3268 var Source_pH = dataRecord.w1_ph; |
3310 // Code from BrewBuddy/Brouwhulp, who got it from http://www.brewery.org/brewery/library/Acidi0,00fWaterAJD0497.html |
3269 var Source_alkalinity = dataRecord.w1_total_alkalinity; |
3311 TargetpH = dataRecord.sparge_ph; |
|
3312 Source_pH = dataRecord.w1_ph; |
|
3313 Source_alkalinity = dataRecord.w1_total_alkalinity; |
|
3314 // Select watersource or fallback to the first source. |
3270 // Select watersource or fallback to the first source. |
3315 if (dataRecord.sparge_source == 1) { // Source 2 |
3271 if (dataRecord.sparge_source == 1) { // Source 2 |
3316 if (dataRecord.w2_ph > 0.0) { |
3272 if (dataRecord.w2_ph > 0.0) { |
3317 Source_pH = dataRecord.w2_ph; |
3273 Source_pH = dataRecord.w2_ph; |
3318 Source_alkalinity = dataRecord.w2_total_alkalinity; |
3274 Source_alkalinity = dataRecord.w2_total_alkalinity; |
3320 dataRecord.sparge_source = 0; // Source 1 |
3276 dataRecord.sparge_source = 0; // Source 1 |
3321 $('#sparge_source').val(0); |
3277 $('#sparge_source').val(0); |
3322 } |
3278 } |
3323 } else if (dataRecord.sparge_source == 2) { // Mixed |
3279 } else if (dataRecord.sparge_source == 2) { // Mixed |
3324 if (dataRecord.w2_ph > 0.0) { |
3280 if (dataRecord.w2_ph > 0.0) { |
3325 Source_pH = parseFloat($('#wg_ph').jqxNumberInput('decimal')); |
3281 Source_pH = parseFloat(dataRecord.wg_ph); |
3326 Source_alkalinity = parseFloat($('#wg_total_alkalinity').jqxNumberInput('decimal')); |
3282 Source_alkalinity = parseFloat(dataRecord.wg_total_alkalinity); |
3327 } else { |
3283 } else { |
3328 dataRecord.sparge_source = 0; |
3284 dataRecord.sparge_source = 0; |
3329 $('#sparge_source').val(0); |
3285 $('#sparge_source').val(0); |
3330 } |
3286 } |
3331 } |
3287 } |
3332 |
3288 |
3333 // Step 1: Compute the mole fractions of carbonic (f1o), bicarbonate (f2o) and carbonate(f3o) at the water pH |
3289 // Step 1: Compute the mole fractions of carbonic (f1) and carbonate(f3) at the source water pH |
3334 r1 = Math.pow(10, Source_pH - 6.38); |
3290 var r1 = Math.pow(10, Source_pH - 6.35); |
3335 r2 = Math.pow(10, Source_pH - 10.373); |
3291 var r2 = Math.pow(10, Source_pH - 10.33); |
3336 d = 1 + r1 + r1 * r2; |
3292 var d = 1 + r1 + r1 * r2; |
3337 f1 = 1 / d; |
3293 var f1 = 1 / d; |
3338 f3 = r1 * r2 / d; |
3294 var f3 = r1 * r2 / d; |
3339 |
3295 |
3340 //Step 2. Compute the mole fractions at pH = 4.3 (the pH which defines alkalinity) |
3296 //Step 2. Compute the mole fractions at pH = 4.3 (the pH which defines alkalinity) |
3341 r143 = Math.pow(10, 4.3 - 6.38); |
3297 var r143 = Math.pow(10, 4.3 - 6.35); |
3342 r243 = Math.pow(10, 4.3 - 10.373); |
3298 var r243 = Math.pow(10, 4.3 - 10.33); |
3343 d43 = 1 + r143 + r143 * r243; |
3299 var d43 = 1 + r143 + r143 * r243; |
3344 f143 = 1 / d43; |
3300 var f143 = 1 / d43; |
3345 f343 = r143 * r243 / d43; |
3301 var f343 = r143 * r243 / d43; |
3346 |
|
3347 //Step 3. Convert the water alkalinity to milliequivalents/L |
|
3348 alkalinity = Source_alkalinity / 50; |
|
3349 |
3302 |
3350 //Step 4. Solve |
3303 //Step 4. Solve |
3351 Ct = (alkalinity - 1000 * (Math.pow(10, -4.3) - Math.pow(10, -Source_pH))) / ((f143 - f1) + (f3 - f343)); |
3304 var Ct = Source_alkalinity / 50 / ((f143 - f1) + (f3 - f343)); |
3352 |
3305 |
3353 //Step 5. Compute mole fractions at desired pH |
3306 //Step 5. Compute mole fractions at desired pH |
3354 r1g = Math.pow(10, TargetpH - 6.38); |
3307 var r1g = Math.pow(10, TargetpH - 6.35); |
3355 r2g = Math.pow(10, TargetpH - 10.373); |
3308 var r2g = Math.pow(10, TargetpH - 10.33); |
3356 dg = 1 + r1g + r1g * r2g; |
3309 var dg = 1 + r1g + r1g * r2g; |
3357 f1g = 1 / dg; |
3310 var f1g = 1 / dg; |
3358 f3g = r1g * r2g / dg; |
3311 var f3g = r1g * r2g / dg; |
3359 |
3312 |
3360 //Step 6. Use these to compute the milliequivalents acid required per liter (mEq/L) |
3313 //Step 6. Use these to compute the milliequivalents acid required per liter (mEq/L) |
3361 Acid = Ct * ((f1g - f1) + (f3 - f3g)) + Math.pow(10, -TargetpH) - Math.pow(10, -Source_pH); //mEq/l |
3314 var Acid = Ct * ((f1g - f1) + (f3 - f3g)) + Math.pow(10, -TargetpH) - Math.pow(10, -Source_pH); //mEq/l |
3362 Acid += 0.01; // Add acid that would be required for distilled water. |
3315 Acid += 0.01; // Add acid that would be required for distilled water. |
3363 if (dataRecord.sparge_acid_type < 0 || dataRecord.sparge_acid_type > 3) { |
3316 |
|
3317 //Step 8. Get the acid data. |
|
3318 var AT = dataRecord.sparge_acid_type; |
|
3319 if (AT < 0 || AT >= AcidTypeData.length) { |
|
3320 AT = 0; |
3364 dataRecord.sparge_acid_type = 0; |
3321 dataRecord.sparge_acid_type = 0; |
3365 $('#sparge_acid_type').val(0); |
3322 $('#sparge_acid_type').val(0); |
3366 } |
3323 dataRecord.sparge_acid_perc = AcidTypeData[0].AcidPrc; |
3367 |
3324 $('#sparge_acid_perc').val(dataRecord.sparge_acid_perc); |
3368 //Step 8. Get the acid data. |
3325 } |
3369 AT = dataRecord.sparge_acid_type; |
3326 var fract = CalcFrac(TargetpH, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3); |
3370 result = GetAcidSpecs(AT); |
|
3371 pK1 = result.pK1; |
|
3372 pK2 = result.pK2; |
|
3373 pK3 = result.pK3; |
|
3374 MolWt = result.MolWt; |
|
3375 AcidSG = result.AcidSG; |
|
3376 AcidPrc = result.AcidPrc; |
|
3377 fract = CalcFrac(TargetpH, pK1, pK2, pK3); |
|
3378 |
3327 |
3379 //Step 9. Now divide the mEq required by the "fraction". This is the required number of moles of acid. |
3328 //Step 9. Now divide the mEq required by the "fraction". This is the required number of moles of acid. |
3380 Acid /= fract; |
3329 Acid /= fract; |
3381 |
3330 |
3382 //Step 10. Multiply by molecular weight of the acid |
3331 //Step 10. Multiply by molecular weight of the acid |
3383 Acid *= MolWt; //mg |
3332 Acid *= AcidTypeData[AT].MolWt; //mg |
3384 |
3333 |
3385 Acid = Acid / AcidSG; //ml ; 88% lactic solution |
3334 //Step 11. Divide by Specific Gravity and Percentage to get the final ml. |
3386 f1 = dataRecord.sparge_acid_perc; |
3335 Acid = Acid / AcidTypeData[AT].AcidSG / (dataRecord.sparge_acid_perc / 100); //ml |
3387 if (f1 <= 0.1) |
3336 Acid *= dataRecord.sparge_volume; //ml acid total |
3388 f1 = AcidPrc; |
|
3389 Acid = Acid * AcidPrc / (f1 / 100); |
|
3390 |
|
3391 Acid *= dataRecord.sparge_volume; //ml lactic acid total |
|
3392 Acid = Round(Acid, 2); |
3337 Acid = Round(Acid, 2); |
3393 dataRecord.sparge_acid_amount = Acid / 1000; |
3338 dataRecord.sparge_acid_amount = Acid / 1000; |
3394 $('#sparge_acid_amount').val(Acid); |
3339 $('#sparge_acid_amount').val(Acid); |
3395 } |
3340 } |
3396 |
3341 |
3921 calcWater(); |
3866 calcWater(); |
3922 }); |
3867 }); |
3923 $('#wa_acid_name').on('select', function(event) { |
3868 $('#wa_acid_name').on('select', function(event) { |
3924 if (event.args) { |
3869 if (event.args) { |
3925 var index = event.args.index; |
3870 var index = event.args.index; |
3926 console.log('wa_acid_name ' + index); |
3871 console.log('wa_acid_name ' + index + ' last_acid: ' + last_acid); |
3927 setWaterAgent(last_acid, 0); |
3872 setWaterAgent(last_acid, 0); |
3928 last_acid = AcidTypeData[index].nl; |
3873 last_acid = AcidTypeData[index].nl; |
|
3874 dataRecord.wa_acid_name = index; |
|
3875 dataRecord.wa_acid_perc = AcidTypeData[index].AcidPrc; |
|
3876 $('#wa_acid_perc').val(dataRecord.wa_acid_perc); |
|
3877 calcWater(); |
3929 setWaterAgent(last_acid, parseFloat($('#wa_acid').jqxNumberInput('decimal'))); |
3878 setWaterAgent(last_acid, parseFloat($('#wa_acid').jqxNumberInput('decimal'))); |
3930 dataRecord.wa_acid_name = index; |
|
3931 calcWater(); |
|
3932 } |
3879 } |
3933 }); |
3880 }); |
3934 $('#wa_acid').on('change', function(event) { |
3881 $('#wa_acid').on('change', function(event) { |
3935 var name = AcidTypeData[$('#wa_acid_name').val()].nl; |
3882 var name = AcidTypeData[dataRecord.wa_acid_name].nl; |
3936 setWaterAgent(name, parseFloat(event.args.value)); |
3883 setWaterAgent(name, parseFloat(event.args.value)); |
3937 calcWater(); |
3884 calcWater(); |
3938 }); |
3885 }); |
3939 $('#wa_acid_perc').on('change', function(event) { calcWater(); }); |
3886 $('#wa_acid_perc').on('change', function(event) { |
|
3887 dataRecord.wa_acid_perc = parseFloat(event.args.value); |
|
3888 calcWater(); |
|
3889 }); |
3940 |
3890 |
3941 $('#color_method').on('select', function(event) { |
3891 $('#color_method').on('select', function(event) { |
3942 dataRecord.color_method = event.args.index; |
3892 dataRecord.color_method = event.args.index; |
3943 calcFermentables(); |
3893 calcFermentables(); |
3944 }); |
3894 }); |
5666 $('#w2_amount').jqxTooltip({ content: 'De verdeling van het hoofd en meng water. Het totale maisch water volume blijft gelijk.'}); |
5619 $('#w2_amount').jqxTooltip({ content: 'De verdeling van het hoofd en meng water. Het totale maisch water volume blijft gelijk.'}); |
5667 $('#w2_amount').jqxNumberInput({ |
5620 $('#w2_amount').jqxNumberInput({ |
5668 inputMode: 'simple', spinMode: 'simple', theme: theme, width: 94, height: 23, min: 0, max: 0, decimalDigits: 1, |
5621 inputMode: 'simple', spinMode: 'simple', theme: theme, width: 94, height: 23, min: 0, max: 0, decimalDigits: 1, |
5669 spinButtons: true, spinButtonsStep: 0.1, readOnly: true |
5622 spinButtons: true, spinButtonsStep: 0.1, readOnly: true |
5670 }); |
5623 }); |
5671 $('#w2_calcium,#w2_magnesium,#w2_sodium,#w2_total_alkalinity,#w2_chloride,#w2_sulfate,#w2_ph').jqxNumberInput(Show1wat); |
5624 $('#w2_calcium,#w2_magnesium,#w2_sodium,#w2_total_alkalinity,#w2_chloride,#w2_sulfate').jqxNumberInput(Show1wat); |
|
5625 $('#w2_ph').jqxNumberInput(Show2wat); |
5672 // Water mixed |
5626 // Water mixed |
5673 $('#wg_amount,#wg_calcium,#wg_magnesium,#wg_sodium,#wg_total_alkalinity,#wg_chloride,#wg_sulfate,#wg_ph').jqxNumberInput(Show1wat); |
5627 $('#wg_amount,#wg_calcium,#wg_magnesium,#wg_sodium,#wg_total_alkalinity,#wg_chloride,#wg_sulfate').jqxNumberInput(Show1wat); |
|
5628 $('#wg_ph').jqxNumberInput(Show2wat); |
5674 // Water treated |
5629 // Water treated |
5675 $('#wb_calcium').jqxTooltip({ content: 'De ideale hoeveelheid Calcium is tussen 40 en 150.'}); |
5630 $('#wb_calcium').jqxTooltip({ content: 'De ideale hoeveelheid Calcium is tussen 40 en 150.'}); |
5676 $('#wb_magnesium').jqxTooltip({ content: 'De ideale hoeveelheid Magnesium is tusse 10 en 30.'}); |
5631 $('#wb_magnesium').jqxTooltip({ content: 'De ideale hoeveelheid Magnesium is tusse 10 en 30.'}); |
5677 $('#wb_sodium').jqxTooltip({ content: 'De ideale hoeveelheid Natrium is lager dan 150.'}); |
5632 $('#wb_sodium').jqxTooltip({ content: 'De ideale hoeveelheid Natrium is lager dan 150.'}); |
5678 $('#wb_chloride').jqxTooltip({ content: 'De ideale hoeveelheid Chloride is tussen 50 en 100.'}); |
5633 $('#wb_chloride').jqxTooltip({ content: 'De ideale hoeveelheid Chloride is tussen 50 en 100.'}); |
5679 $('#wb_sulfate').jqxTooltip({ content: 'De ideale hoeveelheid Sulfaat is tussen 50 en 350.'}); |
5634 $('#wb_sulfate').jqxTooltip({ content: 'De ideale hoeveelheid Sulfaat is tussen 50 en 350.'}); |
5680 $('#wb_calcium,#wb_magnesium,#wb_sodium,#wb_total_alkalinity,#wb_chloride,#wb_sulfate,#wb_ph').jqxNumberInput(Show1wat); |
5635 $('#wb_calcium,#wb_magnesium,#wb_sodium,#wb_total_alkalinity,#wb_chloride,#wb_sulfate').jqxNumberInput(Show1wat); |
|
5636 $('#wb_ph').jqxNumberInput(Show2wat); |
5681 // Water target profile |
5637 // Water target profile |
5682 $('#pr_name').jqxDropDownList({ |
5638 $('#pr_name').jqxDropDownList({ |
5683 placeHolder: 'Kies doel profiel:', |
5639 placeHolder: 'Kies doel profiel:', |
5684 theme: theme, |
5640 theme: theme, |
5685 source: waterprofiles, |
5641 source: waterprofiles, |