Hello, I am Richard Otis from Prof. Zi-Kui Liu's research group.

Tonight I present pycalphad, a free and open-source library for CALPHAD computations. It works on Mac, Windows, and Linux.

Phase Equilibria Computation

Al-Fe (M.Seiersten et al., 1991)


In [1]:
%matplotlib inline
import matplotlib.pyplot as plt
from pycalphad import Database, binplot
db_alfe = Database('alfe_sei.TDB')
my_phases_alfe = ['LIQUID', 'B2_BCC', 'FCC_A1', 'HCP_A3', 'AL5FE2', 'AL2FE', 'AL13FE4', 'AL5FE4']

fig = plt.figure(figsize=(9,6))
pdens = [{'B2_BCC': 20000}, 2000]
%time binplot(db_alfe, ['AL', 'FE', 'VA'] , my_phases_alfe, 'X(AL)', 300, 2000, steps=100, \
              pdens=pdens, ax=fig.gca(), mode='numexpr')
plt.show()


CPU times: user 18.9 s, sys: 1.15 s, total: 20.1 s
Wall time: 13 s

Energy Surfaces of Al-Ni (N. Dupin et al., 2001)


In [4]:
%matplotlib inline
from pycalphad import energy_surf, Database
from pycalphad.plot.utils import phase_legend
import numpy as np
import matplotlib.pyplot as plt
db_alni = Database('NI_AL_DUPIN_2001.TDB')
my_phases_alni = ['LIQUID', 'FCC_L12', 'BCC_B2', 'AL3NI5', 'AL3NI2', 'AL3NI1']

fig = plt.figure(figsize=(9,6))
ax = fig.gca()
%time nrg_df = energy_surf(db_alni, ['AL', 'NI', 'VA'], my_phases_alni, T=1000.0)

legend_handles, colorlist = phase_legend(my_phases_alni)
group_df = nrg_df.groupby('Phase')
for phase, phase_df in group_df:
    ax = phase_df.plot(kind='scatter', x='X(AL)', y='GM', ax=ax, color=colorlist[phase.upper()], s=1, xlim=(0,1), ylim=(-11e4, -3e4))
ax = ax.legend(handles=legend_handles, loc='center left', bbox_to_anchor=(1, 0.6))
plt.title('Al-Ni Gibbs Energy at 1000 K', fontsize=20)
plt.show()


CPU times: user 4.22 s, sys: 0 ns, total: 4.22 s
Wall time: 4.21 s

In [7]:
nrg_df


Out[7]:
GM Phase T X(AL) X(NI) Y(AL3NI1,0,AL) Y(AL3NI1,1,NI) Y(AL3NI2,0,AL) Y(AL3NI2,1,AL) Y(AL3NI2,1,NI) ... Y(BCC_B2,1,NI) Y(BCC_B2,1,VA) Y(BCC_B2,2,VA) Y(FCC_L12,0,AL) Y(FCC_L12,0,NI) Y(FCC_L12,1,AL) Y(FCC_L12,1,NI) Y(FCC_L12,2,VA) Y(LIQUID,0,AL) Y(LIQUID,0,NI)
0 -78820.96 AL3NI1 1000 0.750000 0.250000 1 1 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 -42406.27 AL3NI2 1000 0.833333 0.166667 NaN NaN 1 1.000000 0.000000 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 -31245.28 AL3NI2 1000 1.000000 0.000000 NaN NaN 1 1.000000 0.000000 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 -96138.68 AL3NI2 1000 0.500000 0.500000 NaN NaN 1 0.000000 1.000000 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 -95724.16 AL3NI2 1000 0.600000 0.400000 NaN NaN 1 0.000000 1.000000 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 -78441.97 AL3NI2 1000 0.699594 0.300406 NaN NaN 1 0.405684 0.594316 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6 -83711.23 AL3NI2 1000 0.666261 0.333739 NaN NaN 1 0.306762 0.693238 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
7 -52357.6 AL3NI2 1000 0.856900 0.143100 NaN NaN 1 0.811368 0.188632 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
8 -53907.05 AL3NI2 1000 0.852927 0.147073 NaN NaN 1 0.784209 0.215791 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 -94605.5 AL3NI2 1000 0.593467 0.406533 NaN NaN 1 0.072421 0.927579 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
10 -70472.13 AL3NI2 1000 0.773870 0.226130 NaN NaN 1 0.513128 0.486872 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
11 -78455.38 AL3NI2 1000 0.650357 0.349643 NaN NaN 1 0.417235 0.582765 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
12 -88702.35 AL3NI2 1000 0.584153 0.415847 NaN NaN 1 0.208809 0.791191 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
13 -45764.46 AL3NI2 1000 0.836801 0.163199 NaN NaN 1 0.949757 0.050243 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
14 -85180.4 AL3NI2 1000 0.604807 0.395193 NaN NaN 1 0.282256 0.717744 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
15 -86633.83 AL3NI2 1000 0.673257 0.326743 NaN NaN 1 0.216330 0.783670 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
16 -55505.88 AL3NI2 1000 0.868494 0.131506 NaN NaN 1 0.722351 0.277649 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
17 -59649.33 AL3NI2 1000 0.849447 0.150553 NaN NaN 1 0.654595 0.345405 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
18 -67201.6 AL3NI2 1000 0.740282 0.259718 NaN NaN 1 0.615686 0.384314 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
19 -79900.42 AL3NI2 1000 0.670879 0.329121 NaN NaN 1 0.389007 0.610993 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
20 -83727.73 AL3NI2 1000 0.649001 0.350999 NaN NaN 1 0.314701 0.685299 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
21 -93610.27 AL3NI2 1000 0.577309 0.422691 NaN NaN 1 0.105298 0.894702 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
22 -48055.96 AL3NI2 1000 0.863983 0.136017 NaN NaN 1 0.887928 0.112072 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
23 -45576.63 AL3NI2 1000 0.881772 0.118228 NaN NaN 1 0.915031 0.084969 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
24 -91739.02 AL3NI2 1000 0.612108 0.387892 NaN NaN 1 0.140717 0.859283 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
25 -67033.34 AL3NI2 1000 0.711129 0.288871 NaN NaN 1 0.622735 0.377265 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
26 -70011.83 AL3NI2 1000 0.769478 0.230522 NaN NaN 1 0.531118 0.468882 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
27 -79884.3 AL3NI2 1000 0.702313 0.297687 NaN NaN 1 0.368791 0.631209 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
28 -39460.32 AL3NI2 1000 0.930066 0.069934 NaN NaN 1 0.967530 0.032470 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
29 -93850.99 AL3NI2 1000 0.602490 0.397510 NaN NaN 1 0.087437 0.912563 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
46018 -45828.58 LIQUID 1000 0.050061 0.949939 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.050061 0.949939
46019 -84954.36 LIQUID 1000 0.620452 0.379548 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.620452 0.379548
46020 -87462.71 LIQUID 1000 0.503316 0.496684 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.503316 0.496684
46021 -76348.12 LIQUID 1000 0.290815 0.709185 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.290815 0.709185
46022 -51225.52 LIQUID 1000 0.086494 0.913506 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.086494 0.913506
46023 -57128.03 LIQUID 1000 0.902927 0.097073 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.902927 0.097073
46024 -72423.77 LIQUID 1000 0.252032 0.747968 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.252032 0.747968
46025 -83824.5 LIQUID 1000 0.642015 0.357985 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.642015 0.357985
46026 -86248.2 LIQUID 1000 0.588732 0.411268 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.588732 0.411268
46027 -79458.53 LIQUID 1000 0.325945 0.674055 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.325945 0.674055
46028 -71009.83 LIQUID 1000 0.239095 0.760905 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.239095 0.760905
46029 -81115.29 LIQUID 1000 0.683374 0.316626 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.683374 0.316626
46030 -38616.7 LIQUID 1000 0.004592 0.995408 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.004592 0.995408
46031 -63184.88 LIQUID 1000 0.857187 0.142813 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.857187 0.142813
46032 -72116.98 LIQUID 1000 0.781606 0.218394 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.781606 0.218394
46033 -87480.46 LIQUID 1000 0.507160 0.492840 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.507160 0.492840
46034 -81341.86 LIQUID 1000 0.350256 0.649744 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.350256 0.649744
46035 -47413.72 LIQUID 1000 0.970456 0.029544 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.970456 0.029544
46036 -60905.8 LIQUID 1000 0.156344 0.843656 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.156344 0.843656
46037 -87482.29 LIQUID 1000 0.522727 0.477273 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.522727 0.477273
46038 -76699.85 LIQUID 1000 0.294551 0.705449 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.294551 0.705449
46039 -85232.33 LIQUID 1000 0.614469 0.385531 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.614469 0.385531
46040 -86957.71 LIQUID 1000 0.466996 0.533004 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.466996 0.533004
46041 -59245.8 LIQUID 1000 0.887299 0.112701 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.887299 0.112701
46042 -58699.88 LIQUID 1000 0.139826 0.860174 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.139826 0.860174
46043 -71762.15 LIQUID 1000 0.784881 0.215119 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.784881 0.215119
46044 -51452.58 LIQUID 1000 0.943187 0.056813 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.943187 0.056813
46045 -64214.46 LIQUID 1000 0.181979 0.818021 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.181979 0.818021
46046 -45140.79 LIQUID 1000 0.045538 0.954462 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.045538 0.954462
46047 -58334.11 LIQUID 1000 0.894071 0.105929 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 0.894071 0.105929

46048 rows × 28 columns


In [6]:
nrg_df.to_excel('alni_energies.xlsx')

Al-Zn (S. Mey et al., 1993)

Next, we show values from Mey et al.'s 1993 assessment of the Al-Zn system. We have not done any fitting here; we are just showing how arbitrary values for the parameters may be specified and easily used to plot the phase diagram. Note the optional parameters keyword argument specified for each call to Model. This feature is what makes it easy to perform arbitrary variable substitutions in our thermodynamic models.


In [5]:
from pycalphad import Model, Database, binplot

db_alzn = Database('alzn_noparams.tdb')

assessed_parameters = {
    'LIQALZN0H': 10465.3,
    'LIQALZN0S': 3.39259,
    'FCCALZN0H': 7297.5,
    'FCCALZN0S': -0.47512,
    'FCCALZN1H': 6612.9,
    'FCCALZN1S': 4.5911,
    'FCCALZN2H': -3097.2,
    'FCCALZN2S': -3.306635,
    'HCPALZN0H': 18821.0,
    'HCPALZN0S': 8.95255,
    'HCPALZN3H': -702.8,
    'HCPALZN3S': 0.0
    }

# Initialize phase models
assessed_models = {
    'LIQUID': Model(db_alzn, ['AL', 'ZN'], 'LIQUID', parameters=assessed_parameters),
    'FCC_A1': Model(db_alzn, ['AL', 'ZN', 'VA'], 'FCC_A1', parameters=assessed_parameters),
    'HCP_A3': Model(db_alzn, ['AL', 'ZN', 'VA'], 'HCP_A3', parameters=assessed_parameters)
    }

fig = plt.figure(figsize=(9,6))
ax = binplot(db_alzn, ['AL', 'ZN', 'VA'] , ['LIQUID', 'FCC_A1', 'HCP_A3'], \
                   'X(ZN)', 300, 1000, ax=plt.gca(), model=assessed_models)
ax = ax.set_title('Al-Zn', fontsize=20)



In [6]:
blank_parameters = {
    'LIQALZN0H': 0.0,
    'LIQALZN0S': 0.0,
    'FCCALZN0H': 0.0,
    'FCCALZN0S': 0.0,
    'FCCALZN1H': 0.0,
    'FCCALZN1S': 0.0,
    'FCCALZN2H': 0.0,
    'FCCALZN2S': 0.0,
    'HCPALZN0H': 0.0,
    'HCPALZN0S': 0.0,
    'HCPALZN3H': 0.0,
    'HCPALZN3S': 0.0
    }

models = {
    'LIQUID': Model(db_alzn, ['AL', 'ZN'], 'LIQUID', parameters=blank_parameters),
    'FCC_A1': Model(db_alzn, ['AL', 'ZN', 'VA'], 'FCC_A1', parameters=blank_parameters),
    'HCP_A3': Model(db_alzn, ['AL', 'ZN', 'VA'], 'HCP_A3', parameters=blank_parameters)
    }

fig = plt.figure(figsize=(9,6))
ax = binplot(db_alzn, ['AL', 'ZN', 'VA'] , ['LIQUID', 'FCC_A1', 'HCP_A3'], \
             'X(ZN)', 300, 1000, ax=plt.gca(), model=models)
ax = ax.set_title('Al-Zn with endmembers only', fontsize=20)


Prototyping New Models (Advanced)

What if we have a new kind of functional form for the Gibbs energy we would like to experiment with?


In [50]:
from sympy import Piecewise, log
from tinydb import where
import pycalphad.variables as v

class MyMagneticModel(Model):
    def __init__(self, db, comps, phase, **kwargs):
        super().__init__(db, comps, phase, **kwargs)
        self.models['mag'] = self.my_magnetic_energy(db.phases[phase], db.search)

    def my_magnetic_energy(self, phase, param_search):
        """
        Return the energy from magnetic ordering in symbolic form.
        The implemented model is the Inden-Hillert-Jarl formulation.
        The approach follows from the background section of W. Xiong, 2011.
        
        Note that this is a demonstration model; use pycalphad's builtin
        implementation as a reference.
        """
        site_ratio_normalization = self._site_ratio_normalization(phase)
        # define basic variables
        afm_factor = phase.model_hints['ihj_magnetic_afm_factor']

        bm_param_query = (
            (where('phase_name') == phase.name) & \
            (where('parameter_type') == 'BMAGN') & \
            (where('constituent_array').test(self._array_validity))
        )
        tc_param_query = (
            (where('phase_name') == phase.name) & \
            (where('parameter_type') == 'TC') & \
            (where('constituent_array').test(self._array_validity))
        )

        mean_magnetic_moment = \
            self.redlich_kister_sum(phase, param_search, bm_param_query)
        beta = Piecewise(
            (mean_magnetic_moment, mean_magnetic_moment > 0),
            (mean_magnetic_moment/afm_factor, mean_magnetic_moment <= 0)
            )

        curie_temp = \
            self.redlich_kister_sum(phase, param_search, tc_param_query)
        tc = Piecewise(
            (curie_temp, curie_temp > 0),
            (curie_temp/afm_factor, curie_temp <= 0)
            )

        tau = Piecewise(
            (v.T / tc, tc > 0),
            (10000., tc == 0) # tau is 'infinity'
            )

        # define model parameters
        p = phase.model_hints['ihj_magnetic_structure_factor']
        A = 518/1125 + (11692/15975)*(1/p - 1)
        # factor when tau < 1
        sub_tau = 1 - (1/A) * ((79/(140*p))*(tau**(-1)) + (474/497)*(1/p - 1) \
            * ((tau**3)/6 + (tau**9)/135 + (tau**15)/600)
                              )
        # factor when tau >= 1
        super_tau = -(1/A) * ((tau**-5)/10 + (tau**-15)/315 + (tau**-25)/1500)

        expr_cond_pairs = [(sub_tau, tau < 1),
                           (super_tau, tau >= 1)
                          ]

        g_term = Piecewise(*expr_cond_pairs)

        return 1e6 * v.R * v.T * log(beta+1) * \
            g_term / site_ratio_normalization

In [53]:
%matplotlib inline
import matplotlib.pyplot as plt
from pycalphad import Database, binplot
db_alfe = Database('alfe_sei.TDB')
my_phases_alfe = ['LIQUID', 'B2_BCC', 'FCC_A1', 'HCP_A3', 'AL5FE2', 'AL2FE', 'AL13FE4', 'AL5FE4']

models = [{'FCC_A1': MyMagneticModel}, Model]

fig = plt.figure(figsize=(9,6))
pdens = [{'B2_BCC': 20000}, 2000]
%time binplot(db_alfe, ['AL', 'FE', 'VA'] , my_phases_alfe, 'X(AL)', 300, 2000, steps=100, \
              pdens=pdens, ax=fig.gca(), model=models, mode='numexpr')
plt.title('Al-Fe with toy magnetic model', fontsize=20)
plt.show()


CPU times: user 18.9 s, sys: 786 ms, total: 19.6 s
Wall time: 12.5 s

Experimental Ternary support (if time)

CALPHAD modeling (assessment) will be covered tomorrow morning

Source code available at https://github.com/richardotis/pycalphad

Version 0.1 available on PyPI: "pip install pycalphad"

Version 0.2 coming soon, with new performance improvements and features

Please contact me if you would like to collaborate! Thank you!

Richard Otis

rao140@psu.edu


In [ ]: