Invariant Calculation Example

In the following example, we demonstrate the calculation and plotting of invariant points with quantified uncertainty.

Set-up

First we import all of the required packages, and set the seaborn color codes so that we have pretty plots later.

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from dask.distributed import Client
from distributed.deploy.local import LocalCluster
from pycalphad import Database, equilibrium, variables as v
from pduq.invariant_calc import invariant_samples
from pduq.uq_plot import plot_contour
sns.set(color_codes=True)

Now we use dask distributed to start up a cluster so we can do our invariant calculations in parallel. Set n_workers to the number of cores/processes on the cpu or fewer.

c = LocalCluster(n_workers=8, threads_per_worker=1)
client = Client(c)
print(client)

By printing the client we can see that we have the correct number of workers.

<Client: scheduler='tcp://127.0.0.1:56581' processes=8 cores=8>

Now we load the database file, and load the parameter sets into a numpy array with the following shape: (# parameter sets, # parameters)

dbf = Database('CU-MG_param_gen.tdb')
params = np.load('trace.npy')[:, -1, :]

Invariant Calculations

We then set up and run the invariant calculation for all of our parameter sets using the invariant_samples function from the invariant_calc module. We start by defining the important variables. This includes a guesses for the composition of the invariant and for the temperature bounds.

X = .2  # X_MG guess for invariant
P = 101324  # pressure
Tl = 600  # lower temperature bound for invariant
Tu = 1400  # upper temperature bound for invariant
comp = 'MG'  # species to reference for composition

Tv, phv, bndv = invariant_samples(
    dbf, params, X, P, Tl, Tu, comp, client=client)

Data Analysis and Plotting

Now that the calculation has completed, let’s calculate the mean composition and temperature of the invariant:

print('mean invariant composition:', np.mean(bndv[:, 1]))
print('mean invariant temperature:', np.mean(Tv))
mean invariant composition: 0.21396602343616997
mean invariant temperature: 1003.1419270833334

Let’s also plot the invariant points calculated for each parameter set and some uncertainty contours

# form an array for the invariant points
points = np.zeros((len(Tv), 2))
points[:, 0] = bndv[:, 1]
points[:, 1] = Tv
c = sns.color_palette("Blues", 2)

plt.figure(figsize=(4, 3))

# plot the raw invariant points
plt.plot(points[:, 0], points[:, 1], 'k.',
         label="invariant\nsamples")

# plot KDE estimated uncertainty intervals
plot_contour(points, c, 0.6)

plt.xlabel(r'$\mathrm{x_{Mg}}$', fontsize="large")
plt.ylabel('T (K)', fontsize="large")
plt.tight_layout()
plt.legend()
plt.show()

resulting in the following figure

Raw Cu-Mg invariant points and uncertainty contours

Finally, we can calculate how many of the total 150 points fall within some desired composition and temperature domain

reg = (.212<=points[:, 0])*(points[:, 0]<.217)* \
      (999<=points[:, 1])*(points[:, 1]<1007)
print('points for .212<=X<.217, 999<=T<1007:', np.sum(reg))
points for .212<=X<.217, 999<=T<1007: 51

This means that the invariant has 34% probability of falling in the defined region