Cantera / cantera

Chemical kinetics, thermodynamics, and transport tool suite
https://cantera.org
Other
580 stars 341 forks source link

Improve error message for flames initialized with bad boundary conditions #1694

Closed speth closed 2 weeks ago

speth commented 1 month ago

Problem description

Creating CounterflowPremixedFlame, CounterflowDiffusionFlame, CounterflowTwinPremixedFlame, or CounterflowPremixedFlame objects and attempting to solve them without setting appropriate boundary conditions leads to error messages that are difficult to interpret. I think this problem could be detected while generating initial guesses and used to provide more helpful error messages.

Steps to reproduce

For CounterflowPremixedFlame

import cantera as ct

gas = ct.Solution('h2o2.yaml') 
gas.TP = 300, ct.one_atm
gas.set_equivalence_ratio(0.6, 'H2:1.0', 'O2:1.0, N2:3.76')

f = ct.CounterflowPremixedFlame(gas, width=0.03)  
f.solve(loglevel=1, auto=True)

This starts by generating the output:

************ Solving on 5 point grid with energy equation enabled ************

..............................................................................
Attempt Newton solution of steady-state problem...

*******************************************************************************
CanteraError thrown by Phase::setTemperature:
temperature must be positive. T = nan
*******************************************************************************

******** Initial solve failed; Retrying with energy equation disabled ********

followed by many additional failures while trying different grids, ultimately raising the exception

RuntimeWarning: invalid value encountered in scalar divide
  x0 = rhou*uu * dz / (rhou*uu + rhob*ub)
---------------------------------------------------------------------------
CanteraError                              Traceback (most recent call last)
Cell In[5], line 9
      6 gas.set_equivalence_ratio(0.6, 'H2:1.0', 'O2:1.0, N2:3.76')
      8 f = ct.CounterflowPremixedFlame(gas, width=0.03)  
----> 9 f.solve(loglevel=1, auto=True)

File cantera/_onedim.pyx, in cantera._onedim.Sim1D.solve()

CanteraError: Could not find a solution for the 1D problem

For CounterflowDiffusionFlame

import cantera as ct

gas = ct.Solution('h2o2.yaml') 
gas.TP = 300, ct.one_atm
gas.set_equivalence_ratio(0.6, 'H2:1.0', 'O2:1.0, N2:3.76')

f = ct.CounterflowDiffusionFlame(gas, width=0.03)  
f.solve(loglevel=1, auto=True)

Generates the error:

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
Cell In[3], line 8
      5 gas.set_equivalence_ratio(0.6, 'H2:1.0', 'O2:1.0, N2:3.76')
      7 f = ct.CounterflowDiffusionFlame(gas, width=0.03)  
----> 8 f.solve(loglevel=1, auto=True)

File cantera/onedim.py:1015, in CounterflowDiffusionFlame.solve(self, loglevel, refine_grid, auto, stage)
   1010     warnings.warn(
   1011         "The 'ionized-gas' transport model is untested for "
   1012         "'CounterflowDiffusionFlame' objects.", UserWarning)
   1013     self.flame.solving_stage = stage
-> 1015 super().solve(loglevel, refine_grid, auto)
   1016 # Do some checks if loglevel is set
   1017 if loglevel > 0:

File cantera/_onedim.pyx:1097, in cantera._onedim.Sim1D.solve()

File cantera/onedim.py:941, in CounterflowDiffusionFlame.set_initial_guess(self, data, group)
    938 if 'H' in self.gas.element_names:
    939     sOx -= 0.5 * moles('H')
--> 941 zst = 1.0 / (1 - sFuel / sOx)
    942 Yst = zst * Yin_f + (1.0 - zst) * Yin_o
    944 # get adiabatic flame temperature and composition

ZeroDivisionError: float division by zero

For CounterflowTwinPremixedFlame:

import cantera as ct

gas = ct.Solution('h2o2.yaml') 
gas.TPX = 300, ct.one_atm, 'H2:1.0'
f = ct.CounterflowTwinPremixedFlame(gas, width=0.03)  
f.solve(loglevel=1, auto=True)

Generates output that starts with


************ Solving on 7 point grid with energy equation enabled ************

..............................................................................
Attempt Newton solution of steady-state problem...    failure. 
Take 10 timesteps     0.0005767     -11.22
Attempt Newton solution of steady-state problem...

*******************************************************************************
CanteraError thrown by Phase::setDensity:
density must be positive. density = -818939.2759868323
*******************************************************************************

******** Initial solve failed; Retrying with energy equation disabled ********

and ultimately failing with the exception:

CanteraError                              Traceback (most recent call last)
Cell In[13], line 9
      6 #gas.set_equivalence_ratio(0.0, 'H2:1.0', 'O2:0.0, N2:3.76')
      8 f = ct.CounterflowTwinPremixedFlame(gas, width=0.03)  
----> 9 f.solve(loglevel=1, auto=True)

File cantera/_onedim.pyx:1181, in cantera._onedim.Sim1D.solve()

CanteraError: Could not find a solution for the 1D problem

For CounterflowPremixedFlame:

import cantera as ct

gas = ct.Solution('h2o2.yaml') 
gas.TP = 300, ct.one_atm
gas.set_equivalence_ratio(0.5, 'H2:1.0', 'O2:1.0, N2:3.76')
f = ct.CounterflowPremixedFlame(gas, width=0.03)
f.solve(loglevel=1, auto=True)

Starts by generating the output:

************ Solving on 5 point grid with energy equation enabled ************

..............................................................................
Attempt Newton solution of steady-state problem...

*******************************************************************************
CanteraError thrown by Phase::setTemperature:
temperature must be positive. T = nan
*******************************************************************************

******** Initial solve failed; Retrying with energy equation disabled ********

and ultimately failing with the exception:

CanteraError                              Traceback (most recent call last)
Cell In[16], line 7
      5 gas.set_equivalence_ratio(0.5, 'H2:1.0', 'O2:1.0, N2:3.76')
      6 f = ct.CounterflowPremixedFlame(gas, width=0.03)
----> 7 f.solve(loglevel=1, auto=True)

File cantera/_onedim.pyx:1181, in cantera._onedim.Sim1D.solve()

CanteraError: Could not find a solution for the 1D problem

System information

Additional context

Based on a question from the Users' Group: https://groups.google.com/g/cantera-users/c/XrjpRh47coY