From 1f217d7ad1a22ff20d8194207c0bc0d9f7555977 Mon Sep 17 00:00:00 2001 From: jens Date: Mon, 12 Jun 2023 18:22:37 +0200 Subject: [PATCH] - cleaned up - refactored - valid values except sulfat --- brew/water_constants.m | 32 ++++++++++++++++-- brew/water_optimizer.m | 73 ++++++++++++++++++++---------------------- 2 files changed, 65 insertions(+), 40 deletions(-) diff --git a/brew/water_constants.m b/brew/water_constants.m index c09ccce..756e2ac 100644 --- a/brew/water_constants.m +++ b/brew/water_constants.m @@ -7,7 +7,7 @@ i_Ca = 6; i_Mg = 7; i_S = 8; i_P = 9; -i_SIZE = 9; +N_mol = 9; M_H = 1.00794; % g/mol M_C = 12.0107; % g/mol @@ -19,7 +19,7 @@ M_Mg = 24.305; % g/mol M_S = 32.06; % g/mol M_P = 30.9738; % g/mol -mol_masses = zeros(1, i_SIZE); +mol_masses = zeros(1, N_mol); mol_masses(i_H) = M_H; mol_masses(i_C) = M_C; mol_masses(i_O) = M_O; @@ -30,3 +30,31 @@ mol_masses(i_Mg) = M_Mg; mol_masses(i_S) = M_S; mol_masses(i_P) = M_P; +# Create single elements [g/mol] +M_EL_Ca = create_mol([i_Ca], [1], mol_masses); +M_EL_Mg = create_mol([i_Mg], [1], mol_masses); +M_EL_Na = create_mol([i_Na], [1], mol_masses); +M_EL_Cl = create_mol([i_Cl], [1], mol_masses); +M_EL_S = create_mol([i_S], [1], mol_masses); + +# Create common used compounds [g/mol] +M_CaSO4 = create_mol([i_Ca i_S i_O], [1 1 4], mol_masses); +M_CaCl2 = create_mol([i_Ca i_Cl], [1 2], mol_masses); +M_NaCl = create_mol([i_Na i_Cl], [1 1], mol_masses); +M_MgSO4 = create_mol([i_Mg i_S i_O], [1 1 4], mol_masses); +M_NaHCO3 = create_mol([i_Na i_H i_C i_O], [1 1 1 3], mol_masses); +M_HCl = create_mol([i_H i_Cl], [1 1], mol_masses); +M_H2SO4 = create_mol([i_H i_S i_O], [2 1 4], mol_masses); +M_H2O = create_mol([i_H i_O], [2 1], mol_masses); + +function mol = create_mol(indices, n, mol_masses) + N = length(mol_masses); + mol = zeros(1, N); + mol(indices) = n.*mol_masses(indices); +endfunction + +function mol = create_vec(indices, quantity, N) + mol = zeros(1, N); + mol(indices) = quantity; +endfunction + diff --git a/brew/water_optimizer.m b/brew/water_optimizer.m index fa39248..e1cc22f 100644 --- a/brew/water_optimizer.m +++ b/brew/water_optimizer.m @@ -27,7 +27,7 @@ function water_optimizer (TEST_SUITE, k_ve, learning_rate) # Load constants water_constants() -# Profile from tap water +# Profile from tap water (Bad Toelz) k_Ca_0_mg = 94.0; % mg/l k_Mg_0_mg = 18.1; % mg/l k_Na_0_mg = 3.6; % mg/l @@ -35,68 +35,64 @@ k_S_0_mg = 44.1; % mg/l k_Cl_0_mg = 4.6; % mg/l k_HCO3_0_mmol = 5.5; % mmol/l +# Profile from tap water (Debug) +k_Ca_0_mg = 100; % mg/l +k_Mg_0_mg = 20; % mg/l +k_Na_0_mg = 5; % mg/l +k_S_0_mg = 50; % mg/l +k_Cl_0_mg = 5; % mg/l + # Target Profile k_Ca_1_mg = 50; % mg/l k_Mg_1_mg = 20; % mg/l -k_Na_1_mg = 20; % mg/l +k_Na_1_mg = 40; % mg/l k_Cl_1_mg = 100; % mg/l k_S_1_mg = 50; % mg/l -# Create common used compounds -M_CaSO4 = create_mol([i_Ca i_S i_O], [1 1 4], mol_masses) -M_CaCl2 = create_mol([i_Ca i_Cl], [1 2], mol_masses) -M_NaCl = create_mol([i_Na i_Cl], [1 1], mol_masses) -M_MgSO4 = create_mol([i_Mg i_S i_O], [1 1 4], mol_masses) -M_NaHCO3 = create_mol([i_Na i_H i_C i_O], [1 1 1 3], mol_masses) -M_HCl = create_mol([i_H i_Cl], [1 1], mol_masses) +# Tap water: Calc Stoffmenge/l [mmol/l] +n_Ca_0 = k_Ca_0_mg/sum(M_EL_Ca); +n_Mg_0 = k_Mg_0_mg/sum(M_EL_Mg); +n_Na_0 = k_Na_0_mg/sum(M_EL_Na); +n_Cl_0 = k_Cl_0_mg/sum(M_EL_Cl); +n_S_0 = k_S_0_mg/sum(M_EL_S); -# Create single elements -M_EL_Ca = create_mol([i_Ca], [1], mol_masses) -M_EL_Mg = create_mol([i_Mg], [1], mol_masses) -M_EL_Na = create_mol([i_Na], [1], mol_masses) -M_EL_Cl = create_mol([i_Cl], [1], mol_masses) -M_EL_S = create_mol([i_S], [1], mol_masses) +# Target: Calc Stoffmenge/l [mmol/l] +n_Ca_1 = k_Ca_1_mg/sum(M_EL_Ca); +n_Mg_1 = k_Mg_1_mg/sum(M_EL_Mg); +n_Na_1 = k_Na_1_mg/sum(M_EL_Na); +n_Cl_1 = k_Cl_1_mg/sum(M_EL_Cl); +n_S_1 = k_S_1_mg/sum(M_EL_S); # Initial profile -M_Ca_0_mmol = k_Ca_0_mg/M_Ca; % mmol/l -M_Mg_0_mmol = k_Mg_0_mg/M_Mg; % mmol/l -M_Na_0_mmol = k_Na_0_mg/M_Na; % mmol/l -M_Cl_0_mmol = k_Cl_0_mg/M_Cl; % mmol/l -M_S_0_mmol = k_S_0_mg/M_S; % mmol/l -A0 = k_ve*create_mol([i_Ca i_Mg i_Na i_Cl i_S], [M_Ca_0_mmol M_Mg_0_mmol M_Na_0_mmol M_Cl_0_mmol M_S_0_mmol], mol_masses) +m_A0 = k_ve*create_mol([i_Ca i_Mg i_Na i_Cl i_S], [n_Ca_0 n_Mg_0 n_Na_0 n_Cl_0 n_S_0], mol_masses) # Target profile -M_Ca_1_mmol = k_Ca_1_mg/M_Ca; % mmol/l -M_Mg_1_mmol = k_Mg_1_mg/M_Mg; % mmol/l -M_Na_1_mmol = k_Na_1_mg/M_Na; % mmol/l -M_Cl_1_mmol = k_Cl_1_mg/M_Cl; % mmol/l -M_S_1_mmol = k_S_1_mg/M_S; % mmol/l -T = create_mol([i_Ca i_Mg i_Na i_Cl i_S], [M_Ca_1_mmol M_Mg_1_mmol M_Na_1_mmol M_Cl_1_mmol M_S_1_mmol], mol_masses) +m_T = create_mol([i_Ca i_Mg i_Na i_Cl i_S], [n_Ca_1 n_Mg_1 n_Na_1 n_Cl_1 n_S_1], mol_masses) if TEST_SUITE == 1, -# Allowed substances, easy -Pp = [M_EL_Ca; M_EL_Mg; M_EL_Na; M_EL_Cl; M_EL_S]; +# Create molar masses of allowed substances, easy +Mp = [M_EL_Ca; M_EL_Mg; M_EL_Na; M_EL_Cl; M_EL_S]; end if TEST_SUITE == 2, -# Allowed substances, difficult -Pp = [M_CaSO4; M_CaCl2; M_MgSO4; M_NaCl; M_HCl]; +# Create molar masses of allowed substances, difficult +Mp = [M_CaSO4+2*M_H2O; M_CaCl2+2*M_H2O; M_MgSO4+7*M_H2O; M_NaCl; M_HCl] end # Init vecfit vars -[N_subst, N_elem] = size(Pp); -Pa = zeros(N_subst, 1); +[N_subst, N_elem] = size(Mp); +# create stoff mengen 'n' [mol] +na = zeros(N_subst, 1); # ignore oxygen mask = create_mol([i_Ca i_Mg i_S i_Cl i_Na], [1 1 1 1 1], mol_masses) > 0; -V = 50; % liter _dn = []; CONV_COUNTER_RELOAD = 20; Dn0 = 1; conv_counter = CONV_COUNTER_RELOAD; while true, - [A1, Pa, Dn1] = vecfit(Pp,mask,T,A0,Pa, learning_rate.*(1-exp(-Dn0))); + [m_A1, na, Dn1] = vecfit(Mp, mask, m_T, m_A0, na, learning_rate.*(1-exp(-Dn0))); Dc = round_n(Dn1,2); if Dn0 == Dc, if conv_counter == 0, @@ -112,9 +108,10 @@ while true, end plot(1:length(_dn), _dn); grid(); title("Distance"); xlabel("Iteration"); ylabel("Dn") -A1=A1 -Dn1 = Dn1 -Pa=Pa +m_A1 +Dn1 +m_elem=sum(Mp.*na) +m_subst_add_g_per_hl = na.*sum(Mp,2)/1000*100 endfunction