Just before extinction there will be three steady-state solutions: an ignited one, and unignited one, and an unstable one near the ignited solution. It is the classic S-shaped extinction curve. The numerical solution algorithm is not exactly an unsteady numerical
solution with given initial conditions that evolves to a steady-state, but it is similar to that. That conceptual model helps in understanding what is going on, though. Given that the unstable solution is very close to the ignited solution one can surmise that a converged iginited
solution will require a very good initial guess when close to extinction. So you are correct that things get sensitive near extinction and in the wrong way for your purposes.
There is no "silver bullet" guess that will work. But I can offer a brute force method that will work for you. I am assuming that elegance is not an issue.
One can start well away from the extinction point where a not very good initial guess can converge to an ignited solution. This can then be used as the initial guess for solutions with conditions closer to the extinction point to generate a new ignited solution. Lather, rinse, repeat working your way toward extinction. Smaller and smaller steps will be required as one approaches the extinction condition, of course.
This is the methodology I taught undergrads in Combustion classes for projects/homeworks using Cantera before I retired where I had them calculate extinction conditions using GRI-Mech or some hydrogen/air mechanisms (I mixed it up with new semesters): No hard math, understandable, and works every time.
The same concept works with nonpremixed flames as well. Also with partially premixed flames.
Nothing super exciting, but it does work.
Dave Mikolaitis
Yuanjie,
Yes, I think the method implemented in the diffusion_flame_extinction.py example should be easily adaptable to the twin premixed flame. However, I don’t understand what some of the changes you’ve made are meant to do, and I think these are the source of your problems. For instance, the error you report about the range of the pos vector comes from how you calculate the value of normalized_grid as
normalized_grid = derivative(f.grid, f.u)
when you should just use the definition from the original script of
normalized_grid = f.grid / (f.grid[-1] - f.grid[0])
You may also want to take a look at whether your function for calculating the strain rate does what you want in all cases — it seems like it may have problems in some of the edge cases that can occur during the iteration process.
Regards,
Ray