Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thermo inconsistencies in LatticeSolidPhase #1310

Open
speth opened this issue Jun 3, 2022 · 1 comment
Open

Thermo inconsistencies in LatticeSolidPhase #1310

speth opened this issue Jun 3, 2022 · 1 comment

Comments

@speth
Copy link
Member

speth commented Jun 3, 2022

Problem description

The phase does not satisfy basic thermodynamic identities. Some of these are due to #1309, but I think the discrepancies here may be a separate bug.

I am also suspicious of the implementation of activities and activity coefficients for this phase, which has some unusual behavior that is not documented in any way.

Steps to reproduce

Thermo identities:

>>> import cantera as ct
>>> p = ct.Solution('test/data/thermo-models.yaml', 'Li7Si3_and_interstitials')
>>> p.TP = 725, 50 * ct.one_atm
>>> p.h, p.u + p.P * p.v
-2066297.4664435755 -2077226.57539485  # should be equal
>>> p.chemical_potentials
[-4.62330156e+08 -4.56142503e+07  5.03718894e+05]
>>> p.partial_molar_enthalpies - p.T * p.partial_molar_entropies
[-4.62330156e+08 -4.66072353e+07  2.92167222e+04]

The discrepancy between h and u + Pv seems to grow with pressure.

Activities:

>>> p.X = [0.2, 0.5, 0.3]
>>> p.activity_coefficients
array([1., 1., 1.])
>>> p.activities
array([1.   , 0.625, 0.375])  # should equal X * activity_coefficients

System information

  • Cantera version: 2.6.0 or main at 1ab81ac

Additional context

This was discovered as part of #1299, which implements Cantera/enhancements#114.

@speth
Copy link
Member Author

speth commented Aug 13, 2023

The docstring of the LatticeSolidPhase notes a rather peculiar modeling choice:

 * The mole fraction vector is redefined within the LatticeSolidPhase object.
 * Each of the mole fractions sum to one on each of the sublattices.  The
 * routine getMoleFraction() and setMoleFraction() have been redefined to use
 * this convention.

However, while the phase attempts to override getMoleFractions(), the base class method Phase::getMoleFractions is not virtual. This leads to some surprising behavior, where calls to getMoleFractions from within the LatticeSolidPhase class will use LatticeSolidPhase::getMoleFractions, any external calls from a base class pointer will use Phase::getMoleFractions. I believe that this is the reason for the problem with computing consistent activities and activity coefficients.

I do not think it makes sense to have a phase where the sum of the mole fractions does not equal 1, and I think this needs to be changed to use a definition for mass and mole fractions that satisfies normal expectations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

No branches or pull requests

1 participant