chmarti1 / PYroMat

PYroMat thermodynamic properties in Python
http://pyromat.org
Other
71 stars 13 forks source link

Numerical iteration chokes on non-monotonic functions. #45

Closed jranalli closed 1 year ago

jranalli commented 2 years ago

I encountered two example test cases where we get iteration/bracketing issues due to the function we're iterating becoming non-monotonic at the conditions of interest. This means there will always be multiple possible solutions, which is a difficult problem to fix period, but right now they're not even reporting a possible answer because they choke on the bracketing.

Here if we call things based on entropy

sub = pm.get('mp.CH4')
ref = sub.d(T=223, s=-5.529)   # should be legit, 
# value expected is around 460 based on the forward calculation with p=2475 & T=223

The underlying codes do an iteration of _s based on density. Plotting _s(d, T) reveals that two possible density values correspond to the target entropy and so the iteration code breaks.

Here's a similar test condition that results from _p(T, d)

sub = pm.get('mp.N2')
sub.T(p=1.6e4, d=1355)  # errors out, should come out to be around 68
chmarti1 commented 2 years ago

This is something that we should be able to address in the code where _argparse identifies the solution region. It should be possible to detect the possibility for multiple solutions. I'll throw this on the pile for the next release.

chmarti1 commented 2 years ago

OK, this is actually yet another instance of issue #46. The non-monotonic behavior is due to extreme extrapolation outside of reasonable densities. That also explains why the existing bracketing algorithms weren't preventing the problem. A temporary fix is to just tighten the density limits set at the back-end.

>>> ch4 = pm.get('mp.CH4')
>>> ch4.data['dlim'] = [0, 1000.]
>>> ch4.d(s=-5.529, T=223)
array([460.287385])
chmarti1 commented 1 year ago

This is now resolved with new density limits in version 2.2.2.