Issues with the Interface function to code a TGA apparatus model

168 views
Skip to first unread message

francesco_sm64

unread,
May 13, 2025, 10:48:17 AM5/13/25
to Cantera Users' Group
Dear Cantera users,

I would ask for your help to understand some functionalities of Cantera.
I would create an application that reproduces a TGA apparatus for the analysis of the pyrolysis of solids.
My starting point was the example of CaCO3 calcination, but I am trying to avoid the use of superficial species to directly use the kinetics provided in the literature.
The network built is simple:
- a reactor for the gas phase (the phase contains pyrolysis intermediates and products)
- a reactor for the solid phase (the phase contains the original solid pyrolyzed)
- a reservoir for the inert gas stream feeding into the gas reactor
- an ambient reservoir for the exit of products diluted in the inert stream.
Each reactor has a surface, and the two phases are connected by an interface at which the pyrolysis reactions belong.
Finally, two walls are defined, one to add the heat of the TGA furnace to the gas reactor, the second to exchange heat between the gas and solid reactors.

I have looked at the documentation of the Interface (https://cantera.org/stable/python/thermo.html#interfacephase), but not so much is said about the equations that govern this type of phase.

I am unable to understand:
1) Which temperature is assigned to the interface (apparently always that of the gas phase)?
2) Why do the temperatures immediately change to (for me) strange values and do not change anymore during the computation?

I am attaching the required codes to run the case (.py and .yaml)

If I am not asking too much, can you point me to an example showing how to program a custom function q(t) for the heat addition?

Thank you in advance, and sorry if I am overlooking a stupid mistake.

Best regards,

Francesco
PLATGA2.ipynb
PLA-test_05interface.yaml

Ray Speth

unread,
May 30, 2025, 10:54:52 PM5/30/25
to Cantera Users' Group

Hi Francesco,

This is an interesting problem, and it poses a bit of a challenge for Cantera’s current reactor network model. I think the main problem that you’re running into is that by defining:

SurfArea = (GAS_reactor.volume**(1/3))**2/6 surfPLA = ct.ReactorSurface(pyrolysis_phase, r=PLA_reactor, A=SurfArea) surfGAS = ct.ReactorSurface(pyrolysis_phase, r=GAS_reactor, A=SurfArea)

You’re really creating two separate reactor surfaces which have their own independent reaction rates but communicate with only one bulk phase. The reaction rates on the surface will be computed using the temperature of the bulk phase in the linked reactor, and then bulk phase species produced / consumed in that phase will be accounted for in the governing equations for that reactor. No accounting is done for production/consumption of species in the other bulk phase, however. If the two reactors stay at the same temperature, then these two ReactorSurface objects will give consistent results, and the transfer of species from one bulk phase to the other will be modeled correctly. But as soon as the temperatures (and therefore reaction rates) diverge, this will no longer be correct.

There’s been some discussion on how to improve this situation with a revised handling of reactor surfaces, which you can find in this Enhancement discussion.

In the meantime, I think your situation could be a good use case for the ExtensibleReactor concept. Instead of having a full reactor for the solid phase, you would just augment the equations for the gas phase reactor to include a variable for the mass of the solid phase. The equation for this mass would be defined in terms of the net rate of consumption on the (one) ReactorSurface, and there would be an additional term in the energy equation for the heat capacity of the solid. A couple relevant examples can be found in custom2.py and the User Guide.

If you’re able to get this working, it might be another good example for the ExtensibleReactor feature to include with Cantera.

Regards,
Ray

francesco_sm64

unread,
Jun 18, 2025, 7:02:04 AM6/18/25
to Cantera Users' Group
Dear Ray,

thank you very much for your answer and the extensive explanation, it helps me a lot. I am very sorry that I did not notice your answer until now, so I am replying so late.

I still have an unclear point. I avoided assigning reactions to the phases assigned to the two reactors, GAS and PLA. The only phase containing reactions is the so-called pyrolysis phase assigned to the Interface called pyrolysis_phase in the code I posted. Then, in my example, no reactions should actually occur separately in the two Reactor Surfaces objects.
The only phase where they occur should be the Interface called pyrolysis_phase.

Now, I am unsure what it really is. The documentation reports (https://cantera.org/dev/python/importing.html#cantera.Interface):
"Instances of class Interface represent reacting 2D surfaces between bulk 3D phases..."
but actually, an Interface is built upon phases.

Then, I tried to run a slightly modified example here attached, eliminating the two Reactor Surface and renaming the Interface pyrolysis_surf. This example runs smoothly, but this surface appears not to be linked to the reactors that include the adjacent phases indicated. To check that this object acts as a surface, the code runs even adding the indication of a surface extent, as done in the commented equivalent line of code.

So, the question is, what is really an Interface? How to link it to two bulk reactors if not through ReactorSurfaces?

Regarding the very interesting Enhancement discussion you pointed me to, I am having the impression that you are approaching the problem as to avoid using an Interface object, i.e. building the Surfaces  from lower level objects instead of building a superstructure like the Interface based upon already high level objects.

I will try to follow your suggestion to use an ExtensibleReactor object, which looks very promising,  and I will keep you updated about my progress, if any ...

Thank you again and best regards,

Francesco
PLATGA2_interface.yaml
PLATGA2onlyInterface.ipynb

Eduardo Cano Pleite

unread,
Aug 5, 2025, 1:16:02 PM8/5/25
to Cantera Users' Group
Dear Francesco and Ray,

My apologies to jump into the conversation. I am facing a similar issue and I would like to know if there has been any progress in this regard or if you have any piece of advice that may help, as I am very new to Cantera. 
My issue is similar, but instead of a solid I have an initial mass of a liquid, which is decomposing on other liquids + gas species. I would like to keep track of the mass of the liquid phase/phases, while ramping up the temperature of the rector, thus forcing the temperature of the liquid reactor (TGA-like behavior). Is the approach of using two independent reactors proposed for Francesco also valid? Is the ExtensibleReactor working for this?

Thank you for your kind help and kind regards,
Eduardo
Reply all
Reply to author
Forward
0 new messages