liquid-gas mass transfer

103 views
Skip to first unread message

james jery

unread,
Nov 7, 2024, 2:41:17 AM11/7/24
to Cantera Users' Group
Hi all,
I met serveal problems dealing with simulation of liquid-gas mass transfer.

After browsing Group for a while, I think there are mainly 2 main methods for simulating gas-liquid phase transport: 1. Using the Cantera module in combination, such Boyang Xu's idea https://groups.google.com/g/cantera-users/c/gky1tn3vKnc/m/x_DSoQhaBAAJ, which utilizes 'Reservoir + MassFlowController' to simulate the phase changes of a single substance; 2. Using the Interface module, by setting up a dummy element for the interface reaction. Taking the AB2 molecule as an example: AB2(gas) -> AB2(dummy) -> AB2(aq). Based on my understanding, if the Gibbs free energy of AB2(gas), AB2(dummy), and AB2(aq) all are the same, they will not react with each other, is my understanding correct? If you want to simulate the gas-liquid interface and mass transfer, should I "rewrite" the thermodynamic methods into an absorption methods, such as modifying the piecewise-Gibbs methods, to make the ratio of AB2(gas) to AB2(dummy) equal to the Henry constant.

I conducted an experiment on SO2 absorption in water, using the latter approach, but no reaction occurred. I'm not sure what went wrong?

Additionally, I think both methods employ approaches outside of Cantera's reactors, I could use a self-defined method to achieve the transformation (perhaps I am not yet familiar enough with Cantera) and then import it into Cantera's reactors.Both methods don't give me convenience. For mass transfer, is there a better method available?

Regards,
James

-------------------py code---------------------------
import cantera as ct

test7 = ct.Interface('SO2Absorbing.yaml',name = 'gas_solution_surf',adjacent = ['Gas','Solution'])
g = test7.adjacent["Gas"]
l = test7.adjacent["Solution"]

g.TPX = 273.15+56.28,ct.one_atm-1057,'SO2(g):0.0001'
l.TPX = 273.15+56.28,ct.one_atm-1057,'H2O(L):55.51'
test7.TP = 273.15+56.28,ct.one_atm-1057

r1 = ct.ConstPressureReactor(g,energy="off", volume=1)
r2 = ct.ConstPressureReactor(l,energy="off", volume=0.001)

sim = ct.ReactorNet([r1,r2])
sim.advance(1)
r2.thermo()

-------------------SO2Absorbing.yaml---------------------------
phases:
- name: Solution
  elements: [S,O,H]
  species: [H2O(L),SO2]
  thermo: ideal-molal-solution
  cutoff:
    model: none
    gamma_o: 1.0
    gamma_k: 1.0
    X_o: 1.0
    c_0: 1.0
    slope_f: 1.0
    slope_g: 1.0
  kinetics: bulk
  reactions: none
  state: {T: 298.15 K, P: 1.0 atm}
  transport: water
- name: Gas
  thermo: Redlich-Kwong
  elements: [S,O]
  species: [SO2(g)]
  kinetics: gas
  reactions: none
  state:
    T: 300.0
    P: 1.01325e+05
    reference_pressure: 101325
- name: gas_solution_surf
  thermo: ideal-surface
  adjacent-phases: [PowerPlantSmoke, SodiumCarbonateSolution]
  species: [(dummy),SO2,SO2(surf)]
  reactions: [reactions_surf]
  kinetics: surface
  state: {T: 298.15 K, P: 1.0 atm}
  sites-density: 55 mol/cm^2

species:
- name: H2O(L)
  composition: {H: 2.0, O: 1.0}
  thermo:
    model: NASA7
    temperature-ranges: [273.15, 600.0]
    data:
    - [72.5575005, -0.662445402, 2.56198746e-03, -4.36591923e-06, 2.78178981e-09,
      -4.18865499e+04, -288.280137]
  #sites: 0.0
  equation-of-state:
    model: liquid-water-IAPWS95
- name: SO2(g)
  composition: {S: 1, O: 2}
  thermo:
    model: NASA7
    temperature-ranges: [300.0, 1000.0, 5000.0]
    data:
    - [3.2665338, 5.3237902e-03, 6.8437552e-07, -5.2810047e-09, 2.5590454e-12,
      -3.6908148e+04, 9.66465108]
    - [5.2451364, 1.9704204e-03, -8.0375769e-07, 1.5149969e-10, -1.0558004e-14,
      -3.7558227e+04, -1.07404892]
    note: J 6/61
  equation-of-state:
    model: Redlich-Kwong
    a: [1.4480e+13, 0]
    b: 39.45
- name: (dummy)
  composition: {}
  thermo:
    model: constant-cp
    h0: 0.0 kJ/mol
    s0: 0.0 J/mol/K
  note: Dummy species (needed for defining the interfaces)
- name: SO2(surf)
  sites: 0.0
  composition: {S: 1, O: 2}
  thermo:
    model: constant-cp
    T0: 298.15 #K
    #h0: -296.84 kJ/mol
    #s0:  248.21     J/mol/K
    cp0: 0  J/mol/K
- name: SO2
  sites: 0.0
  composition: {S: 1, O: 2}
  thermo:
    model: constant-cp
    T0: 298.15 #K
    h0: -100.81 kJ/mol
    s0:  100.223     J/mol/K
    cp0: 0  J/mol/K
  equation-of-state:
    model: constant-volume
    molar-volume: 0.038


reactions_surf:
- equation: SO2(g) => SO2(surf)  # reaction
  rate-constant: {A: 3.4E06, b: 0.0, Ea: 0.0}
- equation: SO2(surf) => SO2 # reaction
  rate-constant: {A: 3.4E06, b: 0.0, Ea: 0.0}

-----------------------end----------------------------

Ray Speth

unread,
Nov 21, 2024, 10:37:13 PM11/21/24
to Cantera Users' Group

Hi James,

This is a somewhat tricky system to represent in Cantera, and there are a few pitfalls to be wary of. Some of these issues are documented in Enhancement #202, and I hope we can simplify some of this modeling in a future version of Cantera.

One thing you should be careful about is the units of the Redlich-Kwong coefficients. Based on the magnitudes of the “a” parameter, I think these values are in CGS units. You can specify this unit system locally within the equation-of-state field of the species entry, for example:

equation-of-state: units: {length: cm, quantity: mol, activation-energy: cal/mol} model: Redlich-Kwong a: [1.4480e+13, 0] b: 39.45

With the mis-interpreted coefficients, the phase was giving activity coefficients of zero, which caused the reaction rates to be zero. I also noticed that the site-density key in the input file is typoed as sites-density.

Second, while you have imported an Interface phase, that interface hasn’t been connected to the reactor network as a surface with a particular extent. As shown in Enhancement #202, you currently need to create two ReactorSurface objects, one to represent the interaction with each bulk phase, something like:

area = 1.0 s1 = ct.ReactorSurface(test7, r=r1, A=area) s1 = ct.ReactorSurface(test7, r=r2, A=area)

I think you can simplify your reaction definition and skip defining a “surface” SO2 species, and define a reaction that goes directly from the gas to the liquid phase:

- equation: SO2(g) => SO2 # reaction rate-constant: {A: 3.4E+02, b: 0.0, Ea: 0.0}

One other thing is that you want to make sure that the system of equations is well behaved as the reactants are consumed. In the given setup, the gas phase is specified as only having a single component (SO2) and being a constant pressure reactor. In this case, as the reaction proceeds, the volume and mass of the reactor will go down, but the reaction rate will remain constant even as the mass approaches zero because the concentration of SO2 is held fixed. This can be fixed either by using a gas with at least some diluent species, or by using a constant volume reactor, in which case the concentration (and therefore reaction rate) will decrease as the reactant is consumed.

Regarding a couple of your other questions:

  • If you define several species with the same Gibbs free energies, then the rate of reversible reactions between them will be zero. But irreversible reactions will still proceed at whatever rate is specified.
  • I would not recommend using the piecewise-Gibbs species thermo model. See Issue #1641 for details.
  • A third option for representing this mass flux between phases could be to use the ExtensibleReactor class.

Regards,
Ray

Reply all
Reply to author
Forward
0 new messages