pycalphad icon indicating copy to clipboard operation
pycalphad copied to clipboard

write_tdb function outputs incorrect tdb due to symengine

Open wahab2604 opened this issue 3 years ago • 6 comments

The write_tdb function produces an unreadable tdb due to how symengine evaluates EXP and LN. symengine.sympify is used here and is where the evaluation takes places: https://github.com/pycalphad/pycalphad/blob/ebcfbdb4dadfcce98a40db41c444a19842d8849e/pycalphad/io/tdb.py#L62

I have attached a two line script which opens a tdb then writes it out again, as you can see the input (which pycalphad reads and plot correctly ) is very different to the output tdb

According to Brandon the issue may be related to this: https://github.com/symengine/symengine/pull/1828

test.zip

wahab2604 avatar Jun 14 '22 20:06 wahab2604

Does pycalphad produce the same phase diagram for both TDBs?

For example this input:

FUNCTION CAO0 1 (1 - EXP(-314.8272896/T)); 10000 N !
FUNCTION CAO1 1 (1 - EXP(-125.12812657/T)); 10000 N !
FUNCTION CAO2 1 (1 - EXP(-598.37301449/T)); 10000 N !
FUNCTION CAOL0 1 (1 - EXP(-629.27558/T)); 10000 N !
FUNCTION CAOL1 1 (1 - EXP(-234.0578/T)); 10000 N !

and this output:

FUNCTION CAO0 1.0 1.0-1.0 * 2.71828182845905**(-314.8272896 * T**(-1.0));
   10000.0 N !
FUNCTION CAO1 1.0 1.0-1.0 * 2.71828182845905**(-125.12812657 * T**(-1.0));
   10000.0 N !
FUNCTION CAO2 1.0 1.0-1.0 * 2.71828182845905**(-598.37301449 * T**(-1.0));
   10000.0 N !
FUNCTION CAOL0 1.0 1.0-1.0 * 2.71828182845905**(-629.27558 * T**(-1.0));
   10000.0 N !
FUNCTION CAOL1 1.0 1.0-1.0 * 2.71828182845905**(-234.0578 * T**(-1.0));
   10000.0 N !

These two should be identical for many significant figures, and I would expect pycalphad to produce identical phase diagrams for both. This is still a bug because most other Calphad implementations will not accept this output, but I want to understand if this is only a compatibility bug or if it's also a correctness bug in pycalphad.

richardotis avatar Jun 14 '22 20:06 richardotis

Related: https://github.com/symengine/symengine/pull/1828#issuecomment-907627485, in particular:

We evaluate things like sin(2.0). Reason is that 2.0 is only accurate to 53 bits, so it doesn't make sense to evaluate sin(2.0) to more precision than the precision of 2.0. That's one reason to do it. The other is that it prevents explosion of the symbolic tree. So, the policy that symengine uses is that if you send in floating point number to a function like (sin, exp, etc) you get back a floating point number.

bocklund avatar Jun 14 '22 21:06 bocklund

The binplot in Pycalphad doesn’t produce a plot for the output tdb but does produce one for the input.

It’s specifically the EXP causing the issue, removing those functions will produce a TDB that will plot in pycalphad.

wahab2604 avatar Jun 14 '22 22:06 wahab2604

We have logic in the TDB writer that is supposed to detect this case: https://github.com/pycalphad/pycalphad/blob/ebcfbdb4dadfcce98a40db41c444a19842d8849e/pycalphad/io/tdb.py#L469-L478

We just need to work out why it isn't being triggered here.

richardotis avatar Jun 14 '22 23:06 richardotis

I believe that part is working as intended, but from my small investigation its the reading of the TDB that might be causing the issue specifically the tdb_grammar() function: https://github.com/pycalphad/pycalphad/blob/ebcfbdb4dadfcce98a40db41c444a19842d8849e/pycalphad/io/tdb.py#L207

which then points to: https://github.com/pycalphad/pycalphad/blob/ebcfbdb4dadfcce98a40db41c444a19842d8849e/pycalphad/io/tdb.py#L107-L116

and then points to the sympify evaluation: https://github.com/pycalphad/pycalphad/blob/ebcfbdb4dadfcce98a40db41c444a19842d8849e/pycalphad/io/tdb.py#L62

The logic you referenced doesn't work in this case because the expr has already been evaluated upon creation of a Database object, so the 2.71** is written out according to the else:

https://github.com/pycalphad/pycalphad/blob/ebcfbdb4dadfcce98a40db41c444a19842d8849e/pycalphad/io/tdb.py#L473-L478

wahab2604 avatar Jun 15 '22 00:06 wahab2604

It doesn't solve the general problem, but can we tweak the writing logic for Pow to treat a base number of ~2.71 as the exponential function, for writing purposes?

richardotis avatar Jul 24 '22 18:07 richardotis