Replies: 4 comments 6 replies
-
Hi @Damfow - the issue you are facing could be caused by many reasons (e.g., use of inadequate thermodynamic database and activity model for the problem, input conditions, etc.). Without a minimal reproducible example, it's difficult to assist you (but it seems you want to figure out by yourself). The solver fails to compute the solution if, by default, the calculation does not converge in 200 iterations (i.e., the residuals of all linear and non-linear equations governing the equilibrium state of the system do not decrease by 1e-8 by default). You can check the log of the calculation using: options = EquilibriumOptions()
options.optima.output.active = True
# Using EquilibriumSolver
solver = EquilibriumSolver(system) # or using specs
solver.setOptions(options)
result = solver.solve(state)
# Using equilibrate
result = equilibrate(state, options) You'll get a new local text file named |
Beta Was this translation helpful? Give feedback.
-
Hi again, thank you for your super fast answer. Now, obviously, I need some legend to understand the data that pulls out. I see some output parameters with names: error, ex_max, ep_max, ew_max, x[-], y[-], s[-], ex[-], ey[-]. I guess that those with initial "e" correspond to "error". So these should be less than 1e-8, right? Anyway, I think it is better to ask you for a right thermodynamic package for my system... Are supcrtbl or phreeqc correct for my system? |
Beta Was this translation helpful? Give feedback.
-
It is a simple (or not...) acid-base equilibrium that happens inside an scrubber (liquid-gas contactor). Temperature and pressure are almost ambient (slightly heated). Here some piece of the code:
|
Beta Was this translation helpful? Give feedback.
-
Thanks for sharing the code above. From the log of the calculation I could identify the issue. It has to do with how the residual errors are checked and the scale of the species amounts you are using. The calculation essentially converged, but the largest residual could not be decreased below 1.88098e-08 (the default tolerance is 1.0e-8). The code below is a revised version of yours to resolve the convergence check issue (tolerance increased to 1e-6). I'll investigate more this and make the necessary changes in Reaktoro. I'll also check how Reaktoro v2.8.2 (latest version with some improvements in Optima) behaves. I used Reaktoro v2.7.2 for testing your code. from reaktoro import *
db = SupcrtDatabase("supcrtbl")
# %% Initial values of the gas stream
Temp = 60 # ºC
V_gas = 12_500 # m3/h @T
VN_gas = V_gas * 273 / (273 + Temp) # Nm3/h
Conc_H2O = 29.8 # %vol
Conc_CO2 = 30.2 # %vol
Conc_O2 = 0.0001 # %vol
Conc_H2S = 0.5 # %vol
Conc_NH3 = 3.0 # %vol
Conc_N2 = 100-Conc_H2O-Conc_CO2-Conc_O2-Conc_H2S-Conc_NH3 # %vol
n_H2O = Conc_H2O / 100 * VN_gas / (273.15 * 0.082) # kmol/h
n_CO2 = Conc_CO2 / 100 * VN_gas / (273.15 * 0.082) # kmol/h
n_O2 = Conc_O2 / 100 * VN_gas / (273.15 * 0.082) # kmol/h
n_H2S = Conc_H2S / 100 * VN_gas / (273.15 * 0.082) # kmol/h
n_NH3 = Conc_NH3 / 100 * VN_gas / (273.15 * 0.082) # kmol/h
n_N2 = Conc_N2 / 100 * VN_gas / (273.15 * 0.082) # kmol/h
# Scrubber conditions
Q_H2O = 440 # kg/h water
Conc_NaOH = 20 # %w solution
m_H2O = Q_H2O * (1-Conc_NaOH/100) # kg/h
m_NaOH = Q_H2O * Conc_NaOH / 100 # kg/h
Temp_Sc = 30 # ºC, Temp. scrubber
aq_comps = "H2O(aq) H+ OH- Na+ NaOH(aq) HCO3- CO3-2 CO2(aq) "
aq_comps += "H2S(aq) HS- "
aq_comps += "NH3(aq) NH4+"
gas_comps = "CO2(g) H2O(g) N2(g) H2S(g) NH3(g)"
solution = AqueousPhase(aq_comps)
gas = GaseousPhase(gas_comps)
system = ChemicalSystem(db, solution, gas)
state = ChemicalState(system)
solver = EquilibriumSolver(system)
state.setTemperature(Temp_Sc, "celsius")
state.setPressure(1.0, "atm")
state.set("H2O(aq)", m_H2O, "kg")
state.set("NaOH(aq)", m_NaOH, "kg")
state.set("H2S(aq)", n_H2S, "kmol")
state.set("NH3(aq)", n_NH3, "kmol")
state.set("H2O(g)", n_H2O, "kmol")
state.set("CO2(g)", n_CO2, "kmol")
state.set("N2(g)", n_N2, "kmol")
options = EquilibriumOptions()
options.optima.output.active = True
options.optima.convergence.tolerance = 1e-6
solver.setOptions(options)
result = solver.solve(state)
assert result.succeeded()
print("EQ STATE")
print(state)
aprops = AqueousProps(state)
print("AQUEOUS PROPERTIES AT EQUILIBRIUM")
print(aprops)
print("pH: ", aprops.pH())
print("Succeesful?", result.succeeded()) Please note that accuracy is a different story. Your setup above uses ideal activity models for the aqueous and gaseous phases (i.e., activity coefficients are 1 for aqueous species, and fugacity coefficients are 1 for the gases). Let me know if you encounter further issues. |
Beta Was this translation helpful? Give feedback.
-
I am doing some calculations of solution of acid-alkaline gases in acid-base aqueous solution. A simple HCl(g) in air vs NaOH(aq) solution is simple and the calculation is defined as "Succeeded", but I want to go further.
The problem that I wanted to solve is H2S(g) + NH3(g) + CO2(g) vs NaOH(aq). I use the speciation method to know the involved components and my own list of components, but both solution are defined as "Not succeeded", but I do not know the reason, so I am handcuffed with no clue of how to do.
My scope is to figure out myself why is not solved. Is it possible to get more info about the conditions that the solver consider as "Not succeeded"?
Beta Was this translation helpful? Give feedback.
All reactions