CalebBell / thermo

Thermodynamics and Phase Equilibrium component of Chemical Engineering Design Library (ChEDL)
MIT License
594 stars 114 forks source link

Heat capacity calculations "get stuck" after phase change #26

Closed taljaards closed 3 years ago

taljaards commented 4 years ago

Hi

I'm likely missing something. It seems that even though a new Chemical object is created each time, as soon as the relevant chemical undergoes a phase change, heat capacity calculations get "stuck".

In [1]: from thermo import Chemical

In [2]: Chemical('water', T=320).Cpl
Out[2]: 4177.518996988284

In [3]: Chemical('water', T=-2+273.15).Cpl  # Cpl is a bit nonsensical at this T, but so what
Out[3]: 1687.9369348841108

In [4]: Chemical('water', T=320).Cpl  # now Cpl is different compared to the first calculation
Out[4]: 1891.2006096310665

I did not expect the second calculation at T=320 to give that answer, since each Chemical is a new object?

CalebBell commented 4 years ago

Hi Stéphan,

Although each chemical object is unique, the property classes such as HeatCapacityLiquid are global for memory and performance reasons. The last "valid" method is cached for each property calculation for speed, and further calculations are routed through the previously used method, provided it is still within a valid temperature range of that method. As the higher accuracy methods tend to have a smaller valid temperature range, once any point outside of their range is calculated, the next accurate method will continue to be used until it is out of range. As some methods are only estimates, they can have a very wide range and will generally continue to be used from then on. It is possible to configure the property objects to use only a user-specified method or methods to avoid the issue.

Sincerely, Caleb

jfkonecn commented 4 years ago

This could be change into a repository pattern.

Any direct call to the init would create an entirely new non-cached instance of the Chemical object.

You could then also have a "Chemical_Repository" object where you pass query parameters like id, pressure, temperature. The repository would first check to see if it has something its cache else it would create it. Maybe it we could even give the user the option to delete stale records to free memory?

This change would slow down users' existing code, but would not break it. They could then have the option to switch to the repository if they need the speed boost.

CalebBell commented 3 years ago

Hi all, That particular cache is one of the worst decisions I've made. It severely hindered my development of the library and also made me not want to work on those TDependentProperty objects at all.

The new Thermo update resolve the issue. Thermo won't try to switch between methods anymore, it will just use the selected method, and perform configurable extrapolation when outside of bounds.

I'm very sorry I wrote the code this way originally. The only consolation you will find is that it has very likely caused me much more pain than you.

Sincerely, Caleb