Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsuccessful calculation of chemical equilibrium (a question). #1139

Open
Dmitriy-Filatov-A opened this issue Nov 10, 2021 · 8 comments
Open

Comments

@Dmitriy-Filatov-A
Copy link

Hello!
I use the Cantera 2.5 in C++. When I try to calculate the chemical equilibrium using the method "MultiPhaseEquil::equilibrate", the Cantera can finish failing (the Cantera doesn't send messages). I tried to find a mistake and it seems to me that it can depend on the calculation of the parameter "MultiPhaseEquil::error()"

doublereal MultiPhaseEquil::error()
. To be more precise, this parameter can take a large constant value during each iteration.
I have a question. Why are you using this parameter (m_deltaG_RT[j]) as an "error"
err = fabs(m_deltaG_RT[j]);
?
I tried to use the parameter "max(m_dxi)" as an error and the Cantera finished successfully. Can I use this parameter?
The parameter m_dxi is calculated in method "MultiPhaseEquil::computeReactionSteps(vector_fp& dxi)"
doublereal MultiPhaseEquil::computeReactionSteps(vector_fp& dxi)
in line
dxi[j] = -fctr*dg_rt;

P.S. The Cantera performs most calculations successfully without modifying the code but the Cantera does not perform some calculations (very few) for the reason I indicated.

Thank you in advance for your help.

@Dmitriy-Filatov-A
Copy link
Author

P.S.
The method "MultiPhaseEquil::equilibrate" return the parameter "error" that was discussed.

return error();

@ischoegl
Copy link
Member

Hi @Dmitriy-Filatov-A ... Thank you for reporting this issue. Could you provide an example with numerical input so this can be reproduced?

@Dmitriy-Filatov-A
Copy link
Author

Hello! Yes, of course. How can I send my project? (it has several files)

@Dmitriy-Filatov-A
Copy link
Author

Before I submit the project, I write about problems that I found for some calculation points.
The Cantera does not return a result when I call the method "MultiPhaseEquil::equilibrate()"

doublereal MultiPhaseEquil::equilibrate(int XY, doublereal err,

I think this is because the value of "error" from the method "MultiPhaseEquil::error()" stops changing at some iterative step and takes on a large value.

doublereal MultiPhaseEquil::error()

I also noticed that when calling method "MultiPhaseEquil::computeReactionSteps(vector_fp& dxi)" in line

doublereal grad0 = computeReactionSteps(m_dxi);

, the values of the vectors "m_dxi" and "m_moles" do not change but the values of the vector "m_work" aren't zero

multiply(m_N, m_dxi.data(), m_work.data());

and vector "m_works" uses to calculate vector "m_moles" in the method "MultiPhaseEquil::step()"

m_moles[k] += omega * deltaN[k];

m_moles[k] += omega * deltaN[k];

m_moles[k] = fabs(m_moles[k])*std::min(10.0,

So I think that the parameter "omega" tends to zero.

void MultiPhaseEquil::step(doublereal omega, vector_fp& deltaN,

@ischoegl
Copy link
Member

Thank you for providing more details here, @Dmitriy-Filatov-A ... the equilibrium solver is - to my knowledge - one of the older parts of Cantera (meaning that the original authors may not be available). So providing these insights is appreciated.

Regarding the example, is there a way to reproduce the behavior with a simple Python example script that specifies conditions (or C++ or Matlab if those are your preferences), together with a YAML (or CTI) input file that provides the species definitiions? That way, the behavior could be easily reproduced and would document a clear starting point.

@Dmitriy-Filatov-A
Copy link
Author

I am sending a link with files.
https://github.com/Dmitriy-Filatov-A/test_Cantera.git

@Dmitriy-Filatov-A
Copy link
Author

P.S. There are indicated temperatures for which the program does not work correctly (main.cpp)

@speth
Copy link
Member

speth commented Apr 17, 2022

Thanks for reporting this issue. I've put together a somewhat simpler version based on built-in input files that can be run in Python, and involves fewer species and elements. Input file:

phases:
- name: gas
  thermo: ideal-gas
  species: [{nasa_gas.yaml/species: [O2, O, Fe, FeO]}]
  state: {T: 300, P: 1 atm}
- name: Fe(a)
  thermo: fixed-stoichiometry
  species: [{nasa_condensed.yaml/species: [Fe(a)]}]
  state: {T: 300, P: 1 atm}
- name: FeO(s)
  thermo: fixed-stoichiometry
  species: [{nasa_condensed.yaml/species: [FeO(s)]}]
  state: {T: 300, P: 1 atm}
- name: Fe2O3(s)
  thermo: fixed-stoichiometry
  species: [{nasa_condensed.yaml/species: [Fe2O3(s)]}]
  state: {T: 300, P: 1 atm}
- name: Fe3O4(s)
  thermo: fixed-stoichiometry
  species: [{nasa_condensed.yaml/species: [Fe3O4(s)]}]
  state: {T: 300, P: 1 atm}

code:

import cantera as ct

phase_names = [
	"Fe(a)", "FeO(s)", "Fe2O3(s)", "Fe3O4(s)", "gas"
]

phases = [ct.Solution("all_phases.yaml", name) for name in phase_names]
gas = phases[-1]
successes = 0
failures = 0

for T in range(300, 1000):
    gas.TPX = None, None, "O2: 2"
    moles = {"Fe(a)": 20, "gas": 50}
    mix = ct.Mixture([(p, moles.get(p.name, 0.0)) for p in phases])

    mix.T = T
    mix.P = 5 * ct.one_atm
    try:
        mix.equilibrate("TP", "gibbs")
        successes += 1
    except ct.CanteraError as err:
        print(f"Failed at T = {T}")
        failures += 1
        print(err)

print(f"{successes} successes, {failures} failures")

For this code, I get 688 successes and 12 failures, though I wouldn't be too surprised if this varies a bit on different platforms or with different compilers.

I don't know the logic behind basing the error condition on m_deltaG_RT, but I didn't find that changing it to use m_dxi instead had any benefit in terms of reducing the number of cases where the solver fails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants