I have a problem when solving a system of equations. To understand the code,
the term: (1. - Ni_oct + delta_Ni_mod) used to be a variable. But I have to implement it in order to remove one equation that is not seen here. This equation is what is seen in the variable Q. Q should equal to iterable j from the loop. The goal is to find for which delta_Ni_mod the diff satisfies the tolerance. But for some reason the code goes not find any solutions and is infinitely running. Increasing the tolerance is not an option, as then I get solutions that logically not satisfy a suitable difference. Btw I should have mentionen that values from the iterable j are very small numbers like between 10^-170 and 10^-21
Would be grateful if someone helps out. What I tried so far is below
import numpy as npfrom scipy.optimize import rootdH_3 = 5.02*1.602e-19N_A=6.022e23R = 8.314 T_values = np.arange(0,1300, 50)dH_5_neutr = 0.708*1.602e-19p_H2 = np.logspace(-6,1, num=100)dH_6_neutr = 6.151*1.602e-19p_H2 = np.logspace(-6,1, num=100)K_def3 = np.exp(-(dH_3*N_A)/(R*T_values))Kp_def3=K_def3K_def5_neutr = np.exp(-(dH_5_neutr*N_A)/(R*T_values))Kp_def5_neutr=K_def5_neutrK_def6_neutr = np.exp((205.15/2)/R)*np.exp(-(dH_6_neutr*N_A)/(R*T_values))Kp_def6_neutr = [[K_def6_neutr[i] * (p_H2[j]/10e-5) for j in range(len(p_H2))] for i in range(len(K_def6_neutr))]# Initialize variablesdelta_Ni_mod_max = np.float64(-0.002)delta_Ni_mod_min = np.float64(0.0)tolerance = 1e-20diff_list = []delta_Ni_mod_values = []resultlist_def1_3_4_5_6 = []Q_list = []delta_Ni_mod = (delta_Ni_mod_min + delta_Ni_mod_max) / 2for j, l, Kp_def6_subarray in zip(Kp_def3, Kp_def5_neutr, Kp_def6_neutr): for m in Kp_def6_subarray: def equations(vars): Ni_oct, V_oct, O_o, V_o, Al_tet, Al_oct, V_tet = vars eq1 = Ni_oct + V_oct + (0.999 - Ni_oct + delta_Ni_mod) + Al_oct - 2.0 # Oktaederplätze eq2 = O_o + V_o - 4.0 # Sauerstoffplätze eq3 = -1 * Ni_oct - 3 * V_oct + 2 * V_o + Al_tet - 2 * V_tet # Ladungsbilanz eq7 = Al_tet + V_tet - 1 # Tetraederplätze eq8 = Al_tet + Al_oct - 2.0 # Massebilanz Al eq10 = (Al_oct * V_tet) / (V_oct * Al_tet) - l # Kp_def5_neutr Site exchange eq11 = ((V_o * (Ni_oct ** 2)) / (O_o * ((0.999 - Ni_oct + delta_Ni_mod) ** 2))) - m # K Bildung Sauerstoffvakanzen return [eq1, eq2, eq3, eq7, eq8, eq10, eq11] initial_guess = [0.999, # Ni_oct # 0.999 0.0001, # V_oct 3.999, # O_o 0.0001, # V_o 1., # Al_tet 1., # Al_oct 0.001] # V_tet #delta_Ni_mod = (delta_Ni_mod_min + delta_Ni_mod_max) / 2 while True: sol = root(equations, initial_guess, method='lm', tol=1e-40) Ni_oct, V_oct, O_o, V_o, Al_tet, Al_oct, V_tet = sol.x Q = (V_oct * (0.999 - Ni_oct + delta_Ni_mod) ** 2) / (Ni_oct ** 3) diff = j - Q if abs(diff) <= tolerance: diff_list.append(diff) delta_Ni_mod_values.append(delta_Ni_mod) resultlist_def1_3_4_5_6.append(sol.x) Q_list.append(Q) break if diff > 0: # Q muss positiver gemacht werden, also delta_Ni muss richtung negative Zahl gebtacht werden delta_Ni_mod_min = delta_Ni_mod else: # Hier gilt K < Q, also muss Q negativer gemacht werden # Q muss negativer gemacht werden, also delta_Ni Ri 0 gebracht werden delta_Ni_mod_max = delta_Ni_mod delta_Ni_mod = (delta_Ni_mod_min + delta_Ni_mod_max) / 2```