|
| 1 | +import cellconstructor as CC, cellconstructor.Phonons |
| 2 | +import numpy as np |
| 3 | +import matplotlib.pyplot as plt |
| 4 | + |
| 5 | +import scipy, scipy.optimize |
| 6 | + |
| 7 | +import sys, os |
| 8 | + |
| 9 | +""" |
| 10 | +This simple scripts plot the thermal expansion. |
| 11 | +It either directly plots the file produced at the end of thermal_expansion.py |
| 12 | +or it processes the dynamical matrices generated throughout the minimization. |
| 13 | +
|
| 14 | +It also fits the V(T) cuve and estimates the volumetric thermal expansion coefficient |
| 15 | +
|
| 16 | +alpha = dV/dT / V |
| 17 | +
|
| 18 | +At 300 K |
| 19 | +""" |
| 20 | + |
| 21 | + |
| 22 | +# Load all the dynamical matrices and compute volume |
| 23 | +DIRECTORY = "thermal_expansion" |
| 24 | +FILE = os.path.join(DIRECTORY, "thermal_expansion.dat") |
| 25 | + |
| 26 | + |
| 27 | +# Check if the file with the thermal expansion data exists |
| 28 | +if not os.path.exists( FILE): |
| 29 | + # If the simulation is not ended, load the volume from the dynamical matrices |
| 30 | + |
| 31 | + # Get the dynamical matrices |
| 32 | + all_dyn_files = [x for x in os.listdir(DIRECTORY) if "sscha" in x and x.endswith("dyn1")] |
| 33 | + temperatures = [float(x.split("_")[-2].replace("T", "")) for x in all_dyn_files] |
| 34 | + |
| 35 | + # Now sort in order of temperature |
| 36 | + sortmask = np.argsort(temperatures) |
| 37 | + all_dyn_files = [all_dyn_files[x] for x in sortmask] |
| 38 | + temperatures = np.sort(temperatures) |
| 39 | + |
| 40 | + volumes = np.zeros_like(temperatures) |
| 41 | + |
| 42 | + for i, fname in enumerate(all_dyn_files): |
| 43 | + # Load the dynamical matrix |
| 44 | + # The full_name means that we specify the name including the tail 1 |
| 45 | + dyn = CC.Phonons.Phonons(os.path.join(DIRECTORY, fname), full_name = True) |
| 46 | + volumes[i] = dyn.get_volumes() |
| 47 | + |
| 48 | +else: |
| 49 | + # Load the data from the final data file |
| 50 | + temperatures, volumes = np.loadtxt(FILE, unpack = True) |
| 51 | + |
| 52 | + |
| 53 | +# Prepare the figure and plot the V(T) from the sscha data |
| 54 | +plt.figure(dpi = 150) |
| 55 | +plt.scatter(temperatures, volumes, label = "SSCHA data", color = 'r') |
| 56 | + |
| 57 | +# Fit the data with a quadratic curve |
| 58 | +def parabola(x, a, b, c): |
| 59 | + return a + b*x + c*x**2 |
| 60 | +def diff_parab(x, a, b, c): |
| 61 | + return b + 2*c*x |
| 62 | + |
| 63 | +popt, pcov = scipy.optimize.curve_fit(parabola, temperatures, volumes, |
| 64 | + p0 = [0,0,0]) |
| 65 | + |
| 66 | +# Evaluate the volume thermal expansion |
| 67 | +vol_thermal_expansion = diff_parab(300, *popt) / parabola(300, *popt) |
| 68 | +print("Vol thermal expansion: {} x 10^6 K^-1".format(vol_thermal_expansion * 1e6)) |
| 69 | +plt.text(0.6, 0.2, r"$\alpha_v = "+"{:.1f}".format(vol_thermal_expansion*1e6)+r"\times 10^6 $ K$^{-1}$", |
| 70 | + transform = plt.gca().transAxes) |
| 71 | + |
| 72 | + |
| 73 | +# Plot the fit |
| 74 | +_t_ = np.linspace(np.min(temperatures), np.max(temperatures), 1000) |
| 75 | +plt.plot(_t_, parabola(_t_, *popt), label = "Fit", color = 'k', zorder = 0) |
| 76 | + |
| 77 | +# Adjust the plot adding labels, legend, and saving in eps |
| 78 | +plt.xlabel("Temperature [K]") |
| 79 | +plt.ylabel(r"Volume [$\AA^3$]") |
| 80 | +plt.legend() |
| 81 | +plt.tight_layout() |
| 82 | +plt.savefig("thermal_expansion.png") |
| 83 | +plt.show() |
0 commit comments