A comparision between PSR in CHEMKIN and Reactor in Cantera

2,299 views
Skip to first unread message

Fanne

unread,
Feb 6, 2014, 12:17:48 PM2/6/14
to canter...@googlegroups.com
Hi everyone !!


I am a total noob in CANTERA, so my questions might be totally stupid... However, I could not find any topic on this matter, and would really appreciate some help !

I am currently using a Python interface.

Here we go : I was using CHEMKIN II to model a sort of "extinction" residence time with the PSR option, by restarting calculations with a smaller and smaller residence time.
Also, I had a good enough grasp onto the equations (for mass fractions & temperature) that solver used to come up with solutions.
I am currently failing in both areas with CANTERA in that :
- I cannot find a way to model that kind of, I guess would be a Reactor for which I could control the residence time & the pressure, and not worry so much about neither the mass
flow rate nor the rho
- I cannot for the life of me understand what kind of equations CANTERA is solving when launching a Reactor calculation.

My questions are, then :
- Has anyone ever tried to capture that type of "extinction" values with CANTERA ? And if so, how did you do it ?? What type of classes did you use, how did you specify the inlet temp and the
tau !
- Is CANTERA solving the same equations for mass frac & temp when using the ReactorNet option as CHEMKIN - PSR did ? Does he perform an equil as a first guess ? Is he taking the T provided
at the beginning of a simulation to be the inlet temperature then ? And does he uses that temperature for each "time step"  (sim = ReactorNet(blabla);  sim.advance(t) ) ?
(redirection towards a comprehensive manual, and not http://cantera.github.io/dev-docs/sphinx/html/index.html would be totaly acceptable :) )


I guess the inlet temperature and residence time really bug me in that I don't know if CANTERA makes use of them somewhere... Maybe Reactor is more similar to SENKIN ?
I find it really weird though that such an extinction procedure would be impossible to perform with Cantera, as it is a test broadly used in the literature today !


Anyway, help will be greatly appreciated, and thank you for reading !!

AF

Bryan W. Weber

unread,
Feb 6, 2014, 4:16:03 PM2/6/14
to canter...@googlegroups.com
Hello,

Welcome to Cantera! I hope I can answer some of your questions.

1) Cantera does not provide a way to set the residence time directly. However, if you specify the residence time and you can get the mass of the contents of the reactor (e.g. Reactor.mass), you can easily calculate the required mass flow rate for a given residence time. I think this is what CHEMKIN does in the background anyways, although the variables there are mass flow rate, density, reactor volume, and residence time.

2) Cantera also does not provide a steady state solver (see https://code.google.com/p/cantera/issues/detail?id=95), so you will have to use the time stepping to advance to the equilibrium conditions. The equations that Cantera solves can be found at http://cantera.github.io/dev-docs/sphinx/html/reactors.html#general-reactor, and I don't know of a more comprehensive reference than that, except the source code itself. I'm not sure how different the equations that CHEMKIN solves are, but of course they represent the same physical situation, so the rest is just details. If you're interested, the manual for AURORA (which PSR became part of) is here: http://www.cvd.louisville.edu/Course/Chemical%20Vapour%20Deposition/Manuals/chemkin/AURORA.pdf

3) The inlet temperature I'm not so sure about, but you can look at the examples at http://cantera.github.io/dev-docs/sphinx/html/cython/examples.html, in particular the "mix1.py" example may help.

Hope it helps,
Bryan

Nick Curtis

unread,
Feb 6, 2014, 6:05:44 PM2/6/14
to canter...@googlegroups.com
Just to add what Bryan said,
If I understand your question correctly, you would set the inlet temperature for your PSR through the state of the gas installed in the upstream reservoir.  I'd recommend Charles Martin Reed's page to get an idea of how you'd set up a PSR.  It's a bit dated and written for fortran I believe, but most of the concepts should be the same.

As another note, if I recall correctly reactors have a method that returns their residence time calculated as:

tau = M_reactor / M_dot_out

However, this cannot be used to set the residence time.  Further, I'm not sure it's callable from the Python interface :/

Nick

At which point you'd install the mass flow controller between the two

Ray Speth

unread,
Feb 6, 2014, 6:52:25 PM2/6/14
to canter...@googlegroups.com
Hi all,

Using the new version of the Python module, it is actually possible to control the residence time of the reactor by using a creatively-defined mass flow rate function for the inlet to the reactor. You can define the mass flow rate as a Python function that can inspect the instantaneous state of the reactor object, and update the mass flow rate continuously to keep the residence time constant. For example:

import cantera as ct
import numpy as np

gas = ct.Solution('h2o2.xml')

gas.TPX = 300, ct.one_atm, 'H2:1.0, O2:2.0, AR:4.0'
upstream = ct.Reservoir(gas)
downstream = ct.Reservoir(gas)

gas.equilibrate('HP')
r1 = ct.IdealGasReactor(gas)

residence_time = 1e-4

def mdot_out(t):
    return r1.mass / residence_time

inlet = ct.Valve(upstream, r1, K=100)
outlet = ct.MassFlowController(r1, downstream)
outlet.set_mass_flow_rate(mdot_out)

net = ct.ReactorNet([r1])

t = np.linspace(0, 5*residence_time, 200)
T = np.zeros(t.shape)
mdot = np.zeros(t.shape)
for i,ti in enumerate(t):
    if ti:
        net.advance(ti)
    T[i] = r1.T
    mdot[i] = outlet.mdot(ti)

Regards,
Ray

Fanne

unread,
Feb 19, 2014, 10:32:26 AM2/19/14
to canter...@googlegroups.com
Hi everyone and thank you a lot for your replies

@ Nick,


No the res time functionality is only callable from the C interface unfortunately ...
Regardless, we can calculate it at each time step and find a way to change it "dynamically" : However, it did not seem to have an effect, and the mixture simply refuses to ignite for low temperatures.
I've seen methods that make use of a small ingoing flow of radicals to help with the ignition : but won't that have an impact on the final concentrations and temperature ?

@ Ray,

This python fonctionality must not be implemented in my python version... which one are you using ? Did you try your script ?


I think this problem requires to look at the way concentrations and temperature are evaluated at each time step (which I would like to be able to do anyway !) : does someone know where it is implemented in the C++ kernel ? I've been struggling
with this for a while now ...


Thanks again !

AF

Ray Speth

unread,
Feb 19, 2014, 12:18:30 PM2/19/14
to canter...@googlegroups.com
Hi,

To use the script I gave, you need to be using the "new" Python module introduced in Cantera 2.1 (named lowercase 'cantera'). Of course I tested the script.

I would not recommend introducing radicals to help with the ignition -- you're right that that will change the reactor's thermodynamics and stoichiometry. 

I think you may not be accounting for the fact that there are multiple steady-state solutions for some range of mass flow rates. What you probably need to do is make sure you're starting off with a state corresponding to a reacting flow by setting the initial composition of the reactor to correspond to equilibrium, as in the example I gave, and start off with a long residence time. Otherwise, you'll start off on the non-reacting branch and depending on the inlet conditions, you will not find a mass flow rate for which the mixture ignites.

If you want to see how the Reactor classes are implemented, the source code is in the 'src/zeroD' directory, with the .cpp file names corresponding to the different types of reactor (i.e. IdealGasReactor). Specifically, the "evalEqs" function is what you're looking for. It calculates the time derivatives of the state variables, given their current values.

Regards,
Ray

charlesreid1

unread,
Feb 20, 2014, 7:20:13 PM2/20/14
to canter...@googlegroups.com
Hi Fanne,

The stream of radicals doesn't have a significant impact on the final concentrations, as long as its small (1e-6 or smaller). It's like adding a spark to a mixture. It is needed because methane is stable and not easy to ignite. Alternatively, you could use a natural gas-like mixture that has ethane and/or propane, which are less stable and will ignite easier than pure methane.

If you want to see the reactor equations Cantera is actually solving, I have them written, along with the corresponding Cantera source code, here: http://charlesmartinreid.com/wiki/Cantera/Reactor_Equations

If you want to make a reactor where you can specify the residence time, its very easy to extend the Cantera Reactor class to make your own reactor that takes whatever arguments you'd like. So, you could take residence time as an argument, and in the constructor, create an upstream/downstream reservoir, install them, and set their mass flowrates appropriately.

charlesreid1

unread,
Feb 20, 2014, 7:50:37 PM2/20/14
to canter...@googlegroups.com
Here's an example script that extends the reactor class to create inlets/outlets/etc: http://charlesmartinreid.com/wiki/Cantera:ResidenceTimeReactor

This may not do exactly what you want, but it'll at least give you an idea of how you might create your own Reactor class, so that you could perform the extinction parameter study you described above.

Carlos Felipe Forigua Rodriguez

unread,
May 6, 2014, 8:52:12 PM5/6/14
to canter...@googlegroups.com
Hi all,

As an exercise i'm trying to translate Ray's Python script in this thread into c++ code. I've used this equilibrium example, the combustor example in c++, the combustor example in Python and an example code from Ray.

It compiles and runs but it won't find a solution if tfinal >= 1.0e-7. I would like to know what's wrong with my translation.

In the code the spanish comments are very basic personal notes and aren't important. For the next time ¿should I delete the comments?

I'm also a Noob in Cantera and c++ and object oriented language. It may be a sightly different question but i think it would be neat to have a direct translation of the examples in the same thread to see the differences.

Thank you very much.
My best regards,
Carlos
PSR_de_Ray.cpp
Makefile.tmp

Ray Speth

unread,
May 9, 2014, 5:45:21 PM5/9/14
to canter...@googlegroups.com
Hi Carlos,

If you change the code to use the C++ class "IdealGasReactor" instead of just "Reactor", it will work for larger values of tfinal. You will also need to #include "cantera/zeroD/IdealGasReactor.h".

For the mdot_out function, I would recommend defining a class derived from "Func1" (see the header numerics/Func1.h) which has a pointer to the reactor object as a member variable and overrides the "eval" method. Then you would create an instance of this class and pass it to the outlet object using the "setFunction" method.

Regards,
Ray

Fanne

unread,
May 22, 2014, 7:50:37 AM5/22/14
to canter...@googlegroups.com
Hi everyone !



I recently came back to this "problem" and found a way to get what I want with the "old" python interface. Actually, I suppose this is what I want, as I compared with CHEMKIN PSR results and values for T, mass flow rate, pressure, rho etc. are almost identical for a broad range of conditions.

But I still do have a couple of questions maybe some of you can help me with: (I join a copy of my script along with this message... I apologize for the inconvenience of having everything written out on screen with it, as it is still a beta version !)
First of all, can anyone explain the concept of the time in the simulation.advance(time) in this case ? I tried a bunch of different values for what I call nt and dt on my script: it did not seem to change anything on the results (except the time of computation)... Was it luck ? Or is it normal ? Are those time steps related to the newton time intergration in some way ? I guess this is a way to perform a continuation : feeding the outlet of a reactor to its inlet ... right ?
Second, Ray in his script, controlled the res time by controlling the outlet mass flow rate. I, on the other hand, control the inlet mass flow rate : are we sure this will produce the same result for all cases? (I know they are supposed to be equal, but still ...)

Thank you all
Anne
test.py

Carlos Felipe Forigua Rodriguez

unread,
Aug 20, 2014, 3:50:10 PM8/20/14
to canter...@googlegroups.com
simulation.advance(time)=Cantera Advances with an internal time step until it gets to time
simulation.step(time) = Take a single internal time step toward time time. The time after taking the step is returned.

This means that Sundials used the internal time step to resolve simulation.advance(time) no matter the value of time. If i understand well that's why you didn't see any difference in the results: Sundials takes the same time steps always.
On the second question I really don't know. But maybe testing and comparing for several extreme conditions would resolve your doubdt. Don't forget to make the test within the ranges in which the mechanism is validated.

I'd really recommend you to use the new interface.

Regards, Carlos



--
You received this message because you are subscribed to a topic in the Google Groups "Cantera Users' Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cantera-users/dMUhi5kVVDk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cantera-user...@googlegroups.com.
To post to this group, send email to canter...@googlegroups.com.
Visit this group at http://groups.google.com/group/cantera-users.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages