Cantera / cantera

Chemical kinetics, thermodynamics, and transport tool suite
https://cantera.org
Other
580 stars 341 forks source link

Different methods for indexing solution arrays lead to different results #1690

Closed ShJPatel closed 2 days ago

ShJPatel commented 2 months ago

Problem description

Accessing properties in a solution array via:

solnArr[10].T
solnArr.T[10]

produce two different results if that solution array was generated by indexing a different solution array. This only occurs in cantera 3.0, not 2.5

Steps to reproduce

Run the following code in cantera 2.5.1 and in cantera 3.0

import cantera as ct
gas = ct.Solution('gri30.yaml')
gas.TP = 650, 10 * ct.one_atm
gas.set_equivalence_ratio(.5, "CH4", "N2:0.79,O2:0.21")

r = ct.IdealGasConstPressureReactor(gas)
sim = ct.ReactorNet([r])
solnArr = ct.SolutionArray(gas)
for i in range(1000):
    sim.step()
    solnArr.append(r.thermo.state)

print("Original Soln Arr From Reactor Network")
print(solnArr[0].T)
print(solnArr.T[0])

print("Truncated Soln Arr From Reactor Network")
solnArr_trunc = solnArr[800:]
print(solnArr_trunc[0].T)
print(solnArr_trunc.T[0])

Behavior In cantera 2.5.1, the output looks like: Original Soln Arr From Reactor Network 650.0 650.0 Truncated Soln Arr From Reactor Network 661.89 661.89

whereas in cantera 3.0 the output looks like Original Soln Arr From Reactor Network 650.0 650.0 Truncated Soln Arr From Reactor Network 650.0 657.191402864133

The method by which you index a truncated solution array (i.e. one that was generated as a slice of another) in cantera 3.0 affects the value you access. The truncated solution array should not return 650K when accessed via solnArr_trunc[0].T , instead it should return 657K because solnArr_trunc starts at the 800th index of solnArr, not the 0th index (solnArr_trunc = solnArr[800:]).

System information

Attachments

import cantera as ct gas = ct.Solution('gri30.yaml') gas.TP = 650, 10 * ct.one_atm gas.set_equivalence_ratio(.5, "CH4", "N2:0.79,O2:0.21")

r = ct.IdealGasConstPressureReactor(gas) sim = ct.ReactorNet([r]) solnArr = ct.SolutionArray(gas) for i in range(1000): sim.step() solnArr.append(r.thermo.state)

print("Original Soln Arr From Reactor Network") print(solnArr[0].T) print(solnArr.T[0])

print("Truncated Soln Arr From Reactor Network") solnArr_trunc = solnArr[800:] print(solnArr_trunc[0].T) print(solnArr_trunc.T[0])

gas = ct.Solution('gri30.yaml') gas.TP = 650, 10 * ct.one_atm gas.set_equivalence_ratio(.5, "CH4", "N2:0.79,O2:0.21") f = ct.FreeFlame(gas) f.solve(loglevel=0) solnArr_f = f.to_array()

print("Original Soln Arr From Flame") print(solnArr_f[0].T) print(solnArr_f.T[0])

print("Truncated Soln Arr From Flame") solnArr_f_truncated = f.to_array()[10:] print(solnArr_f_truncated[0].T) print(solnArr_f_truncated.T[0])

ShJPatel commented 2 months ago

The truncated solution array appears to be the right size and if I make a new solution array as shown below, I get the expected behavior, both ways of indexing solnArr_trunc_fixed produce the same result

solnArr_trunc_fixed = ct.SolutionArray(gas)
solnArr_trunc_fixed.append(solnArr_trunc._get_state(0))
print("Fixed Truncated Solution Array")
print(solnArr_trunc_fixed[0].T)
print(solnArr_trunc_fixed.T[0]) 
ischoegl commented 2 months ago

@ShJPatel .. thank you for reporting. I can reproduce the behavior. The implementation of SolutionArray changed in Cantera 3.0 and while there is an extensive test suite, this case slipped through.