def cluster(): from matplotlib import pyplot as plt fig_free = plt.figure() ax_free = fig_free.add_subplot(1, 1, 1) ax_entropy = ax_free.twinx() colors = ["#5D5C61", "#379683", "#7395AE", "#557A95", "#B1A296"] for col, db_name in zip(colors, DB_NAME_CLUSTER): db = dataset.connect(db_name) energy = [] temperature = [] tbl = db["thermodynamic"] for row in tbl.find(): energy.append(row["energy"]) temperature.append(row["temperature"]) comp = {"Al": 0.75, "Mg": 0.25} free_eng = CanonicalFreeEnergy(comp, limit="lte") T, U, F = free_eng.get(temperature, energy) S = (U - F) / T # Plot free energy ax_free.plot(T, F - F[0], marker="o", mfc="none", color=col, label=size[db_name]) ax_entropy.plot(T, S * 1000.0, marker="v", mfc="none", color=col) ax_free.set_xlabel("Temperature (K)") ax_free.set_ylabel("Free energy change (eV)") ax_free.legend(loc="best", frameon=False) ax_entropy.set_ylabel("Entropy (meV/K)")
def get_free_energies(): db = dataset.connect("sqlite:///" + mc_db_name) tbl = db["systems"] result = {} res_tbl = db["results"] for row in tbl.find(status="finished"): formula = get_formula(row["mg_conc"], row["si_conc"]) internal_energy = [] temperature = [] mg_conc = row["mg_conc"] si_conc = row["si_conc"] conc = {"Mg": mg_conc, "Si": si_conc, "Al": 1.0 - mg_conc - si_conc} n_atoms = 1000 for resrow in res_tbl.find(sysID=row["id"]): internal_energy.append(resrow["internal_energy"] / n_atoms) temperature.append(resrow["temperature"]) free_eng = CanonicalFreeEnergy(conc) temp, internal, F = free_eng.get(temperature, internal_energy) result[formula] = {} result[formula]["temperature"] = temp result[formula]["internal_energy"] = internal result[formula]["free_energy"] = F result[formula]["entropy"] = (internal - F) / temp result[formula]["TS"] = internal - F result[formula]["conc"] = conc return result
def get_free_energies(mfa=False): """ Compute the Free Energy for all entries in the database """ unique_formulas = [] db = connect(mc_db_name) for row in db.select(converged=1): if (row.formula not in unique_formulas): unique_formulas.append(row.formula) result = {} for formula in unique_formulas: conc = None internal_energy = [] temperature = [] for row in db.select(formula=formula, converged=1): if (conc is None): count = row.count_atoms() conc = {} for key, value in count.iteritems(): conc[key] = float(value) / row.natoms internal_energy.append( row.internal_energy / row.natoms) # Normalize by the number of atoms temperature.append(row.temperature) free_eng = CanonicalFreeEnergy(conc) temp, internal, F = free_eng.get(temperature, internal_energy) result[formula] = {} result[formula]["temperature"] = temp result[formula]["internal_energy"] = internal result[formula]["free_energy"] = F result[formula]["conc"] = conc result[formula]["entropy"] = (internal - F) / temp result[formula]["TS"] = internal - F return result
def free_energy_of_formation(db_name, ref_energy): """Computes the free energy of formation.""" db = dataset.connect("sqlite:///{}".format(db_name)) tbl = db["results"] temps = [800, 700, 600, 500, 400, 300, 200, 100] concs = np.arange(0.05, 1, 0.05) all_F = {} c_found = [] for c in concs: statement = "SELECT temperature, energy FROM results WHERE al_conc > {} AND al_conc < {}".format(c-0.01, c+0.01) T = [] U = [] for res in db.query(statement): T.append(res["temperature"]) U.append(res["energy"]/1000.0) comp = {"Al": c, "Zn": 1-c} if not T: continue c_found.append(c) free_eng = CanonicalFreeEnergy(comp) T, U, F = free_eng.get(T, U) for temp, f in zip(list(T), list(F)): if temp not in all_F.keys(): all_F[temp] = [f] else: all_F[temp].append(f) cmap = mpl.cm.copper norm = mpl.colors.Normalize(vmin=np.min(temps), vmax=np.max(temps)) scalar_map = mpl.cm.ScalarMappable(cmap=cmap, norm=norm) scalar_map.set_array(temps) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) concs = np.array(c_found) for T in temps: f_form = np.array(all_F[T]) - concs * ref_energy["Al"] - (1.0-concs)*ref_energy["Zn"] f_form *= mol/kJ f_form = f_form.tolist() f_form.insert(0, 0) f_form.append(0) ax.plot([0.0]+concs.tolist()+[1.0], f_form, color=scalar_map.to_rgba(T), marker="^") ax.set_xlabel("Al concentration") ax.set_ylabel("Free energy of formation (kJ/mol)") ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) ax_divider = make_axes_locatable(ax) c_ax = ax_divider.append_axes("top", size="7%", pad="2%") cb = fig.colorbar(scalar_map, orientation="horizontal", cax=c_ax) cb.ax.xaxis.set_ticks_position('top') cb.ax.xaxis.set_label_position('top') cb.set_label("Temperature (K)") plt.show()
def test_free_energy(self): if (not available): self.skipTest("Test not available") return T = np.linspace(100, 1000, 40) energy = 0.1 * T**2 msg = "" no_throw = True comp = {"Al": 0.5, "Mg": 0.5} try: free_eng = CanonicalFreeEnergy(comp) temp, U, F = free_eng.get(T, energy) except Exception as exc: msg = str(exc) no_throw = False self.assertTrue(no_throw, msg=msg)
def pure_phase(): from matplotlib import pyplot as plt db = dataset.connect(DB_NAME_PURE) energy = [] temperature = [] order_param = [] tbl = db["thermodynamic"] for row in tbl.find(): energy.append(row["energy"]) temperature.append(row["temperature"]) order_param.append(row["site_order"]) comp = {"Al": 0.75, "Mg": 0.25} free_eng = CanonicalFreeEnergy(comp, limit="lte") T, U, F = free_eng.get(temperature, energy) S = (U - F) / T F *= (4.0 / 1000.0) # Convert to per f.u. S *= (4.0 / 1000.0) # Convert to per f.u. # Plot the order parameter f = 1.0 - (np.array(order_param) / 1000.0) * 8.0 / 3.0 fig_order = plt.figure() ax_order = fig_order.add_subplot(1, 1, 1) ax_order.plot(temperature, f, marker="o", mfc="none", color="#5D5C61") ax_order.set_xlabel("Temperature (K)") ax_order.set_ylabel("Order parameter") ax_order.spines["right"].set_visible(False) ax_order.spines["top"].set_visible(False) # Plot free energy fig_free = plt.figure() ax_free = fig_free.add_subplot(1, 1, 1) ax_free.plot(T, (F - F[0]) * 1000.0, marker="o", mfc="none", color="#557A95") ax_entropy = ax_free.twinx() ax_entropy.plot(T, S * 1000.0, marker="v", mfc="none", color="#5D5C61") #ax_free.axvline(x=293, ls="--", color="#B1A296") ax_free.set_xlabel("Temperature (K)") ax_free.set_ylabel("Free energy change (meV/f.u.)") ax_entropy.set_ylabel("Entropy (meV/f.u./K)")
def free_energy_vs_size(temps=[293, 353]): db_name = "sqlite:///data/heat_almg_cluster_size_all_size.db" outfname = "data/almg_review/free_energy_size.json" sizes = range(3, 51) db = dataset.connect(db_name) tbl = db["thermodynamic"] free_energies = {int(T): [] for T in temps} entropy = {int(T): [] for T in temps} internal_energy = {int(T): [] for T in temps} for size in sizes: energy = [] temperature = [] for row in tbl.find(size=size): energy.append(row["energy"]) temperature.append(row["temperature"]) energy = np.array(energy) temperature = np.array(temperature) indx = np.argsort(temperature) temperature = temperature[indx] energy = energy[indx] comp = {"Al": 0.75, "Mg": 0.25} free_eng = CanonicalFreeEnergy(comp, limit="lte") T, U, F = free_eng.get(temperature, energy) S = (U - F) / T for target_temp in temps: indx = np.argmin(np.abs(target_temp - T)) free_energies[target_temp].append(F[indx]) internal_energy[target_temp].append(U[indx]) entropy[target_temp].append(S[indx]) data = {} data["sizes"] = list(sizes) data["free_energy"] = free_energies data["entropy"] = entropy data["internal_energy"] = internal_energy # for target_temp in temps: # free_energies[target_temp] = list(free_energies[target_temp]) with open(outfname, 'w') as outfile: json.dump(data, outfile) print("Free energies written to {}".format(outfname))
def update_entries(): db = dataset.connect("sqlite:///{}".format(db_name)) # Find all unique compositions in the db statement = "SELECT au_conc FROM results" concs = [] for conc in db.query(statement): concs.append(float(conc["au_conc"])) concs = np.array(concs) concs *= 100 concs = concs.astype(np.int32) concs = np.unique(concs) / 100.0 tbl = db["results"] # concs = [0.1, 0.3, 0.95] for c in list(concs): sql = "SELECT id, temperature, energy FROM results WHERE au_conc > {} AND au_conc < {}".format( c - 0.01, c + 0.01) T = [] U = [] for res in db.query(sql): T.append(res["temperature"]) U.append(res["energy"] / 1000.0) comp = {"Au": c, "Cu": 1 - c} free_eng = CanonicalFreeEnergy(comp) T, U, F = free_eng.get(T, U) for temp, u, f in zip(list(T), list(U), list(F)): # Update the database sql = "SELECT id FROM results WHERE au_conc > {} AND au_conc < {} AND temperature={}".format( c - 0.01, c + 0.01, temp) res = db.query(sql) uid = res.next()["id"] new_cols = {"id": uid, "free_energy": f, "entropy": (u - f) / temp} tbl.update(new_cols, ["id"])
"Mg":0.25, "Al":0.75 } # Import the Canonical Free Energy class from cemc.tools import CanonicalFreeEnergy free_eng = CanonicalFreeEnergy(conc) import numpy as np temperature, internal_energy = np.loadtxt( fname, delimiter=",", unpack=True ) # The function also return internal energy and temperature # Because the data in a file might not be sorted # In the case of unsorted data the function will sort the data temperature,internal_energy,helmholtz_free_energy = free_eng.get( temperature, internal_energy/n_atoms ) entropy = (internal_energy-helmholtz_free_energy)/temperature enthalpy = helmholtz_free_energy + temperature*entropy # Plot the results from matplotlib import pyplot as plt fig, ax = plt.subplots( ncols=2, nrows=2 ) ax[0,0].plot( temperature, internal_energy, marker="o" ) ax[0,1].plot( temperature, helmholtz_free_energy, marker="o" ) ax[1,0].plot( temperature, entropy, marker="o" ) ax[1,1].plot( temperature, enthalpy, marker="o") ax[0,0].set_xlabel( "Temperature (K)" ) ax[0,1].set_xlabel( "Temperature (K)" ) ax[1,0].set_xlabel( "Temperature (K)" )