Plug flow reactors in cantera

1,914 views
Skip to first unread message

gorkem....@tei.com.tr

unread,
Dec 11, 2014, 2:21:36 AM12/11/14
to canter...@googlegroups.com
Hi,

I am trying to model a gas turbine combustor using CANTERA and Visual C++ 2013; I will need plug flow reactors for the models of secondary and dilution zones. There is a class named FlowReactor in CANTERA, can it be used to model a plug flow reactor? If that's the case, are there any examples?

Before trying to figure out the code myself, I think getting help from someone who might have had the same problem might be a quicker solution.

I have tried to convert the example for perfectly stirred reactor to plug flow reactor with some minor changes as;

private: void pfr_tut()
{
cout << "Started" << endl;
// use reaction mechanism GRI-Mech 3.0
IdealGasMix gas("gri30.cti", "gri30");
int nsp = gas.nSpecies();

// create a reservoir for the premixed reactants' fuel composition
Reservoir inlet;
gas.setState_TPX(1000, 0.83 * OneAtm, "CH4:0.06, O2:0.2, N2:0.74");
inlet.insert(gas);

// to ignite the fuel/air mixture, we'll introduce a pulse of radicals.
// The steady-state behavior is independent of how we do this, so we'll
// just use a stream of pure atomic hydrogen.
gas.setState_TPX(300.0, 0.83 * OneAtm, "H:1.0");
Reservoir igniter;
igniter.insert(gas);

// create the plug flow reactor, and fill it in initially with N2
FlowReactor pfr;             // not sure about this
pfr.insert(gas);
pfr.setInitialVolume(0.004);

// create a reservoir for the exhaust. The initial composition
// doesn't matter.
Reservoir exhaust;
exhaust.insert(gas);
// create and install the mass flow controllers. Controllers
// m1 is the inlet and m2 provides a short Gaussian pulse only to ignite the mixture
MassFlowController m1;
m1.install(inlet, pfr);
m1.setMassFlowRate(0.001);
// The igniter will use a Gaussian 'functor' object to specify the
// time-dependent igniter mass flow rate.
double A = 0.1;
double FWHM = 0.2;
double t0 = 1.0;
Gaussian igniter_mdot(A, t0, FWHM);

MassFlowController m2;
m2.install(igniter, pfr);
m2.setFunction(&igniter_mdot);
// put a valve on the exhaust line to regulate the pressure
Valve v;
v.install(pfr, exhaust);
double Kv = 1.0;
v.setParameters(1, &Kv);

// the simulation contains a plug flow reactor
                ReactorNet sim;
sim.addReactor(&pfr);  // Not sure about this either

// take single steps to 6 s, writing the results to a CSV file
// for later plotting.
double tfinal = 6.0;
double tnow = 0.0;
double tres;
int k;

std::ofstream f("combustor_cxx.csv");
f << "  Time,Temperature,tres";
f << std::endl;

while (tnow < tfinal) {
tnow = sim.step(tfinal);
tres = pfr.mass() / v.massFlowRate();
f << tnow << ", "
<< pfr.temperature() << tres << ", ";
}

f << std::endl;
}
f.close();
cout << "Program Finished" << endl;
 }

When the program runs i get the following error;


Started
Reactor Type: 3
Reactor Temperature: 300
Reactor Volume: 0.004

***********************************************************************
CanteraError thrown by setState_HPorUV (HP):
No convergence in 500 iterations
        Target Enthalpy         = -1.#IND
        Current Pressure        = -1.#IND
        Starting Temperature    = 2.09075e-005
        Current Temperature     = 50300.9
        Current Enthalpy        = -1.#IND
        Current Delta T         = 100
***********************************************************************


***********************************************************************
CanteraError thrown by setState_HPorUV (HP):
No convergence in 500 iterations
        Target Enthalpy         = -1.#IND
        Current Pressure        = -1.#IND
        Starting Temperature    = 50300.9
        Current Temperature     = 52999.1
        Current Enthalpy        = -1.#IND
        Current Delta T         = 100
***********************************************************************


***********************************************************************
CanteraError thrown by setState_HPorUV (HP):
No convergence in 500 iterations
        Target Enthalpy         = -1.#IND
        Current Pressure        = -1.#IND
        Starting Temperature    = 52999.1
        Current Temperature     = 52999.1
        Current Enthalpy        = -1.#IND
        Current Delta T         = 100
***********************************************************************


***********************************************************************
CanteraError thrown by setState_HPorUV (HP):
No convergence in 500 iterations
        Target Enthalpy         = -1.#IND
        Current Pressure        = -1.#IND
        Starting Temperature    = 52999.1
        Current Temperature     = 52999.1
        Current Enthalpy        = -1.#IND
        Current Delta T         = 100
***********************************************************************


[CVODES ERROR]  CVode
  At t = 0 repeated recoverable right-hand side function errors.


***********************************************************************
CanteraError thrown by CVodesIntegrator:
 CVodes error encountered. Error code: -10
Components with largest weighted error estimates:
0: 0
1: 1.#QNAN
2: 1.#QNAN
3: 1.#QNAN
4: 1.#QNAN
5: 1.#QNAN
6: 1.#QNAN
7: 1.#QNAN
8: 1.#QNAN
9: 1.#QNAN
***********************************************************************

 terminating...


Any help would be appreciated...

Thanks in advance,

Ray Speth

unread,
Dec 11, 2014, 4:13:35 PM12/11/14
to canter...@googlegroups.com
Gorkem,

The FlowReactor class works a bit differently from the other reactor classes, and unfortunately I don't know of any good examples of how to use it. The best I am aware of is the basic functionality test that is done in the Python test suite (see class TestFlowReactor). The important difference is that this is a model for a steady-state flow reactor, and does not interact with Reservoirs or Walls or MassFlowControllers. You simply set the initial condition of the gas object to be that at the inlet to the reactor, set the mass flow rate per unit cross-sectional area, and integrate along the reactor length.

Regards,
Ray

Görkem ÖZTARLIK

unread,
Dec 15, 2014, 4:37:33 AM12/15/14
to canter...@googlegroups.com
Ray,

Thank you for your response, it's just like you have said, the flow is integrated along the reactor length, and the area is equal to unity. I have managed to get a solution with not much evaluated boundary conditions. The code is posted below for someone else that might be looking for something similar, but as i have said the boundary conditions and the reactor length is not well studied, quite absurd actually, so its not a complete example. I will post further when i have the chance to run a test case.

Kind regards...

private: void pfr_tut()
{
cout << "Started" << endl;
// use reaction mechanism GRI-Mech 3.0
IdealGasMix gas("gri30.cti", "gri30");
int nsp = gas.nSpecies();
FlowReactor pfr;
gas.setState_TPX(1000, 0.83 * OneAtm, "CH4:0.06, O2:0.2, N2:0.74");
pfr.insert(gas);

double speed = 1;
double massFlow = gas.density() * speed;

pfr.setMassFlowRate(massFlow);

ReactorNet sim;
sim.addReactor(&pfr);

// take single steps to 6 s, writing the results to a CSV file
// for later plotting.
double tfinal = 3.0;
double tnow = 0.0;
double tres;
int k;
double x1;
double ax_end = 2;

cout << "Distance" << pfr.distance() << endl;

std::ofstream f("combustor_cxx.csv");
f << "Time,Distance,Temperature";

f << std::endl;

while (pfr.distance() < ax_end) {
tnow = sim.step(tfinal);
f << tnow << ", " << pfr.distance() << ", "
<< pfr.temperature();

f << std::endl;
}
f.close();
cout << "Finished" << endl;
}

kurt.eck...@gmail.com

unread,
Dec 17, 2014, 5:39:02 AM12/17/14
to canter...@googlegroups.com

Hello Ray,

I read your comment regarding the flow reactor and now I have a question too.
I´d like to model a catalytic combustor using python and the cantera flow reactor. But now I have the problem to initialize the surface reaction mechanism to the flow reactor.

Is there any possibility to add a wall or just the surface reaction mechanism to the reactor?

Kind regards
Kurt

Ray Speth

unread,
Dec 17, 2014, 11:37:46 AM12/17/14
to canter...@googlegroups.com
Hi Kurt,

Unfortunately, adding surface reactions changes the nature of the system of equations. The equations for the steady-state surface species coverages are algebraic equations, which gives you a DAE system that can't be integrated using an ODE integrator. In principle, this system can be solved, but it's not currently implemented in Cantera. The relevant equations are derived in "Chemically Reacting Flow" (Kee et al.) if you want to know more. You could implement the equations yourself, using Cantera to evaluate the properties and rates and the Sundials IDA solver to integrate the DAE system.

Regards,
Ray

Ali Charchi

unread,
Jan 13, 2015, 11:02:49 PM1/13/15
to canter...@googlegroups.com
Hi everyone,
I am trying to model a plug flow reactor with Cantera in C++. I need to prescribe an experimental temperature profile, so I call the setEnergy(0) method to turn off the energy equation.
I am trying to change the gas temperature in each time step before advancing the network but the temperature remains unchanged.

Could anyone help please?

Ray Speth

unread,
Jan 14, 2015, 12:14:41 PM1/14/15
to canter...@googlegroups.com
Hi Ali,

Unfortunately, specifying the temperature as a function of position is not supported. Manually changing properties of a reactor or its contents is inconsistent with the use of a multistep time integration scheme like that used by CVODES. Support for specifying time-varying inputs has to be added on a case-by-case basis, e.g. in the manner that the wall velocity can be set for well-stirred reactors, but the plug flow reactor is more rudimentary and does not currently have any of these capabilities.

Regards,
Ray

Ali Charchi

unread,
Jan 14, 2015, 9:49:50 PM1/14/15
to canter...@googlegroups.com
Ray,
Thanks for your response.

ZD

unread,
Mar 26, 2015, 8:52:01 PM3/26/15
to canter...@googlegroups.com
Hi, Görkem and Ray, 

I recently is trying the FlowReactor model under python. The purpose is to calculate induction time of certain fuel under isobaric condition. I realized this using PSR and Wall functions. But the reactors we are simulating is more like 1D PFR. So I would like to repeat the similar simulation using FlowReactor. 

Thank to Görkem's share, I successfully built my own python version. It runs very well except the convergence is highly sensitive to the initial speed. I tried different speed values and the model only gets converged within a certain region, although all converged cases yield close induction time. I guess this speed range relates to laminar flame speed. Then I tried a stoichiometric case of hydrogen/air mixture, whose laminar flame speed is known to be 210 cm/s. I plugged several points in: 
 
100 cm/s --> fail
150 cm/s --> succeed
200 cm/s --> succeed
250 cm/s --> succeed
300 cm/s --> succeed
350 cm/s --> failed

I've no idea if my hypothesis is universally correct. If it is, I may need to estimate laminar flame speed before running this model. It is kinda painful. So I'm wondering if you guys have any suggestion on this issue. Or maybe "catch&throw" with tolerance modification helps?

Thank you

Here is the source code: 
pfr_test.py

Ray Speth

unread,
Mar 27, 2015, 4:02:00 PM3/27/15
to canter...@googlegroups.com
Hi,

I would not expect that the laminar flame speed has anything to do with success or failure in integrating the PFR model. The convergence problems with the PFR model are more to do with a poor choice of state variables that makes it difficult to get a good Jacobian, resulting in numerical stability issues. This has been mostly fixed for the WSR model, but the PFR model has not been updated. I would suggest that if possible, you're better off using a constant pressure WSR and treating it as a Lagrangian particle flowing through your PFR.

Regards,
Ray

ZD

unread,
Mar 27, 2015, 4:27:58 PM3/27/15
to canter...@googlegroups.com
Hi, Ray,

Thank you for your reply. I tried more speed values in the model and I found the model eventually converge if the speed value is small enough. The result I had yesterday may just be a coincidence. 

Per your suggestion, do you mean creating a constant pressure WSR by installing a wall onto the WSR? Then set a large enough expansion parameter? I tired that and the associated induction time is close to that from PFR model.    

By the way, I learned from other discussions that the FlowReactor is a steady state reactor, so it can not work with walls. However, there is a FlowReactor.Wall module. I'm wondering if it is a new update that we can use it as it works for WSR?

Thank you
Zhixuan

Ray Speth

unread,
Mar 27, 2015, 5:18:27 PM3/27/15
to canter...@googlegroups.com
Zhixuan,

I mean that you should use ConstPressureReactor (or better yet, IdealGasConstPressureReactor), with no wall. The "wall with high expansion rate coefficient" idiom is an unfortunate one that just leads to more convergence problems.

That FlowReactor objects have a "walls" attribute is just an artifact of the fact that class FlowReactor is derived from class Reactor, which allows walls. However, they don't do anything for this class.

Regards,
Ray

Zhixuan

unread,
Mar 30, 2015, 1:04:42 PM3/30/15
to canter...@googlegroups.com
Ray, 

Thank you a lot for the suggestion. I tired the ConstPressureReactor. The results is nearly the same as that I got from PFR and the model converges much faster. 

I greatly appreciate your support. 

Zhixuan

christo...@gmail.com

unread,
Feb 18, 2017, 6:33:10 AM2/18/17
to Cantera Users' Group


Hello everyone,

I just started with cantera. I have to programm a PFR Reactor, my Problem is this, normally in the Tutorials that I saw, you have a given, Inlet flow: u_0, and reactor measurements: lenght: L, and Diameter: d, Area=A.
And than with these Input parameter you, perform a time integration(Lagrangian Method). But I was told, that I have to program it without this given input parameters, and only with a given Residence Time, lets call it Tau.
I know thath in a PFR Tau= (L*A)/u.
But I have no clue how to go further, does anyone have an Example for this kind of Problem?

I would appreciate any help.
Kind regards Chris

Reply all
Reply to author
Forward
0 new messages