def get_gibbs(structure, db_file, eos="vinet", t_step=10, t_min=0, t_max=1000, mesh=(20, 20, 20), plot=False): # other eos options: birch_murnaghan, murnaghan # The physical units of V and T are \AA^3 and K, respectively. # The unit of eV for Helmholtz and Gibbs energies, # J/K/mol for C_V and entropy, GPa for for bulk modulus and pressure are used. try: from phonopy import PhonopyQHA except ImportError: print("Install phonopy. Exiting.") sys.exit() phonon = get_phonopy(structure) energies, volumes, force_constants = get_data(db_file, query={ "task_label": {"$regex": "gibbs*"}, "formula_pretty": structure.composition.reduced_formula}) temperatures = [] free_energy = [] entropy = [] cv = [] for f in force_constants: phonon.set_force_constants(-np.array(f)) phonon.set_mesh(list(mesh)) phonon.set_thermal_properties(t_step=t_step, t_min=t_min, t_max=t_max) t, g, e, c = phonon.get_thermal_properties() temperatures.append(t) free_energy.append(g) entropy.append(e) cv.append(c) phonopy_qha = PhonopyQHA(volumes, energies, eos=eos, temperatures=temperatures[0], free_energy=np.array(free_energy).T, cv=np.array(cv).T, entropy=np.array(entropy).T, t_max=np.max(temperatures[0])) # gibbs free energy max_t_index = phonopy_qha._qha._max_t_index G = phonopy_qha.get_gibbs_temperature()[:max_t_index] T = phonopy_qha._qha._temperatures[:max_t_index] if plot: import warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") import matplotlib.pyplot as plt plt.plot(T, G) plt.savefig("Gibbs.pdf") plt.show() #phonopy_qha.plot_qha(thin_number=10, volume_temp_exp=None).show() else: return T, G
def get_qha(eos, temperatures, fe_phonon, cv, entropy, t_max=1000): from phonopy import PhonopyQHA import numpy as np phonopy_qha = PhonopyQHA(eos.get_array('volumes'), eos.get_array('energies'), eos="vinet", temperatures=np.array(temperatures), free_energy=np.array(fe_phonon).T, cv=np.array(cv), entropy=np.array(entropy), t_max=t_max, verbose=False) # testing if __testing__: import matplotlib.pyplot as plt plt = phonopy_qha.plot_qha() plt.show() qha_results = {'qha_temperatures': phonopy_qha._qha._temperatures[:phonopy_qha._qha._max_t_index], 'helmholtz_volume': phonopy_qha.get_helmholtz_volume(), 'thermal_expansion': phonopy_qha.get_thermal_expansion(), 'volume_temperature': phonopy_qha.get_volume_temperature(), 'heat_capacity_P_numerical': phonopy_qha.get_heat_capacity_P_numerical(), 'volume_expansion': phonopy_qha.get_volume_expansion(), 'gibbs_temperature': phonopy_qha.get_gibbs_temperature()} return qha_results
def volume_shift(self, volume_range=np.arange(-2.0, 2.0, 0.1)): import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 1) volumes = self.phonopy_qha._qha._volumes energies = self.phonopy_qha._qha._electronic_energies free_energy = np.load('free_energy.npy') temperatures = np.load('temperatures.npy') cv = np.load('cv.npy') entropy = np.load('entropy.npy') for i in volume_range: volumesi = np.array(volumes) + i print volumesi phonopy_qha = PhonopyQHA( volumesi, energies, eos= "vinet", # options: 'vinet', 'murnaghan' or 'birch_murnaghan' temperatures=temperatures, free_energy=free_energy, cv=cv, entropy=entropy, t_max=self.fc_fit.get_temperature_range()[-1], verbose=False) cp = phonopy_qha.get_heat_capacity_P_numerical() import matplotlib.pyplot as plt import matplotlib.colors as colors cNorm = colors.Normalize(vmin=volume_range[0], vmax=volume_range[-1]) scalarMap = plt.cm.ScalarMappable(norm=cNorm, cmap=plt.cm.get_cmap('plasma')) ax.plot(phonopy_qha._qha._temperatures[:-3], cp, label='{}'.format(i), color=scalarMap.to_rgba(i)) import matplotlib as mpl ax2 = fig.add_axes([0.93, 0.1, 0.02, 0.8]) mpl.colorbar.ColorbarBase(ax2, cmap=plt.cm.get_cmap('plasma'), norm=cNorm, spacing='proportional', ticks=volume_range, boundaries=None, format='%1i') plt.show()
def volume_shift(self, volume_range=np.arange(-2.0, 2.0, 0.1)): import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 1) volumes = self.phonopy_qha._qha._volumes energies = self.phonopy_qha._qha._electronic_energies free_energy = np.load('free_energy.npy') temperatures = np.load('temperatures.npy') cv = np.load('cv.npy') entropy = np.load('entropy.npy') for i in volume_range: volumesi = np.array(volumes) + i print volumesi phonopy_qha = PhonopyQHA(volumesi, energies, eos="vinet", # options: 'vinet', 'murnaghan' or 'birch_murnaghan' temperatures=temperatures, free_energy=free_energy, cv=cv, entropy=entropy, t_max=self.fc_fit.get_temperature_range()[-1], verbose=False) cp = phonopy_qha.get_heat_capacity_P_numerical() import matplotlib.pyplot as plt import matplotlib.colors as colors cNorm = colors.Normalize(vmin=volume_range[0], vmax=volume_range[-1]) scalarMap = plt.cm.ScalarMappable(norm=cNorm, cmap=plt.cm.get_cmap('plasma')) ax.plot(phonopy_qha._qha._temperatures[:-3], cp, label='{}'.format(i), color=scalarMap.to_rgba(i)) import matplotlib as mpl ax2 = fig.add_axes([0.93, 0.1, 0.02, 0.8]) mpl.colorbar.ColorbarBase(ax2, cmap=plt.cm.get_cmap('plasma'), norm=cNorm, spacing='proportional', ticks=volume_range, boundaries=None, format='%1i') plt.show()
def get_phonopy_qha(energies, volumes, force_constants, structure, t_min, t_step, t_max, mesh, eos, pressure=0): """ Return phonopy QHA interface. Args: energies (list): volumes (list): force_constants (list): structure (Structure): t_min (float): min temperature t_step (float): temperature step t_max (float): max temperature mesh (list/tuple): reciprocal space density eos (str): equation of state used for fitting the energies and the volumes. options supported by phonopy: vinet, murnaghan, birch_murnaghan pressure (float): in GPa, optional. Returns: PhonopyQHA """ from phonopy import Phonopy from phonopy.structure.atoms import Atoms as PhonopyAtoms from phonopy import PhonopyQHA from phonopy.units import EVAngstromToGPa phon_atoms = PhonopyAtoms(symbols=[str(s.specie) for s in structure], scaled_positions=structure.frac_coords, cell=structure.lattice.matrix) scell = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] phonon = Phonopy(phon_atoms, scell) # compute the required phonon thermal properties temperatures = [] free_energy = [] entropy = [] cv = [] for f in force_constants: phonon.set_force_constants(-np.array(f)) phonon.set_mesh(list(mesh)) phonon.set_thermal_properties(t_step=t_step, t_min=t_min, t_max=t_max) t, g, e, c = phonon.get_thermal_properties() temperatures.append(t) free_energy.append(g) entropy.append(e) cv.append(c) # add pressure contribution energies = np.array(energies) + np.array(volumes) * pressure / EVAngstromToGPa # quasi-harmonic approx return PhonopyQHA(volumes, energies, eos=eos, temperatures=temperatures[0], free_energy=np.array(free_energy).T, cv=np.array(cv).T, entropy=np.array(entropy).T, t_max=np.max(temperatures[0]))
def __init__(self, volumes, electronic_energies, temperatures, free_energy, cv, entropy, eos='vinet', t_max=1000.0, Z=1, verbose=True): self._qha = PhonopyQHA(volumes, electronic_energies, eos=eos, temperatures=temperatures, free_energy=fe_phonon, cv=cv, entropy=entropy, t_max=t_max, verbose=True) self._Z = Z
cv = [] fe = [] for index in range(-5,6): filename = "thermal_properties.yaml-%d" % index print("Reading %s" % filename) thermal_properties = yaml.load(open(filename), Loader=Loader)['thermal_properties'] temperatures = [v['temperature'] for v in thermal_properties] cv.append([v['heat_capacity'] for v in thermal_properties]) entropy.append([v['entropy'] for v in thermal_properties]) fe.append([v['free_energy'] for v in thermal_properties]) qha = PhonopyQHA(volumes, energies, temperatures=temperatures, free_energy=np.transpose(fe), cv=np.transpose(cv), entropy=np.transpose(entropy), t_max=400, verbose=True) # qha.plot_helmholtz_volume().show() # qha.plot_volume_temperature().show() qha.plot_thermal_expansion().show() # plot = qha.plot_volume_expansion() # if plot: # plot.show() # qha.plot_gibbs_temperature().show() # qha.plot_bulk_modulus_temperature().show() # qha.plot_heat_capacity_P_numerical().show() # qha.plot_heat_capacity_P_polyfit().show() # qha.plot_gruneisen_temperature().show()
cv = [] fe = [] for index in range(-5, 6): filename = "thermal_properties.yaml-%d" % index print("Reading %s" % filename) thermal_properties = yaml.load(open(filename), Loader=Loader)["thermal_properties"] temperatures = [v["temperature"] for v in thermal_properties] cv.append([v["heat_capacity"] for v in thermal_properties]) entropy.append([v["entropy"] for v in thermal_properties]) fe.append([v["free_energy"] for v in thermal_properties]) qha = PhonopyQHA( volumes, energies, temperatures=temperatures, free_energy=np.transpose(fe), cv=np.transpose(cv), entropy=np.transpose(entropy), t_max=400, verbose=True, ) # qha.plot_helmholtz_volume().show() # qha.plot_volume_temperature().show() qha.plot_thermal_expansion().show() # plot = qha.plot_volume_expansion() # if plot: # plot.show() # qha.plot_gibbs_temperature().show() # qha.plot_bulk_modulus_temperature().show() # qha.plot_heat_capacity_P_numerical().show() # qha.plot_heat_capacity_P_polyfit().show()
def qha_prediction(wf, interval, min, max, use_all_data=True): # max = wf.get_attribute('max') # min = wf.get_attribute('min') wf_complete_list = [] for step_name in ['pressure_expansions', 'collect_data']: if wf.get_step(step_name): wf_complete_list += list( wf.get_step(step_name).get_sub_workflows()) wf_complete_list += list( wf.get_step('start').get_sub_workflows()[0].get_step( 'start').get_sub_workflows()) if use_all_data: # check data is stable good = [ wf_test.get_attribute('pressure') for wf_test in wf_complete_list if check_dos_stable(wf_test, tol=1e-6) ] good = np.sort(good) test_pressures = np.array(good) test_pressures = test_pressures[np.unique( np.round(test_pressures, decimals=4), return_index=True)[1]].tolist() else: test_pressures = np.arange(min, max, interval).tolist() volumes = [] stresses = [] electronic_energies = [] temperatures = [] fe_phonon = [] entropy = [] cv = [] if True: for wf_test in wf_complete_list: for pressure in test_pressures: if wf_test.get_state() == 'FINISHED': if np.isclose(wf_test.get_attribute('pressure'), pressure, atol=interval / 4, rtol=0): thermal_properties = wf_test.get_result( 'thermal_properties') optimized_data = wf_test.get_result( 'optimized_structure_data') final_structure = wf_test.get_result('final_structure') electronic_energies.append(optimized_data.dict.energy) volumes.append(final_structure.get_cell_volume()) stresses.append(pressure) temperatures = thermal_properties.get_array( 'temperature') fe_phonon.append( thermal_properties.get_array('free_energy')) entropy.append(thermal_properties.get_array('entropy')) cv.append(thermal_properties.get_array('cv')) if False: test_pressures = [] for wf_test in wf_complete_list: if wf_test.get_state() != 'ERROR': repeated = False for p in test_pressures: if np.isclose(wf_test.get_attribute('pressure'), p, atol=interval / 4, rtol=0): repeated = True if not repeated: test_pressures.append(wf_test.get_attribute('pressure')) thermal_properties = wf_test.get_result( 'thermal_properties') optimized_data = wf_test.get_result( 'optimized_structure_data') final_structure = wf_test.get_result('final_structure') electronic_energies.append(optimized_data.dict.energy) volumes.append(final_structure.get_cell_volume()) temperatures = thermal_properties.get_array('temperature') fe_phonon.append( thermal_properties.get_array('free_energy')) entropy.append(thermal_properties.get_array('entropy')) cv.append(thermal_properties.get_array('cv')) if len(stresses) < 5: # raise Exception('Not enough points for QHA prediction') return None sort_index = np.argsort(volumes) stresses = np.array(stresses)[sort_index] volumes = np.array(volumes)[sort_index] electronic_energies = np.array(electronic_energies)[sort_index] temperatures = np.array(temperatures) fe_phonon = np.array(fe_phonon).T[:, sort_index] entropy = np.array(entropy).T[:, sort_index] cv = np.array(cv).T[:, sort_index] # Calculate QHA properties phonopy_qha = PhonopyQHA( np.array(volumes), np.array(electronic_energies), eos="vinet", temperatures=np.array(temperatures), free_energy=np.array(fe_phonon), cv=np.array(cv), entropy=np.array(entropy), # t_max=options.t_max, verbose=False) # Get data volume_temperature = phonopy_qha.get_volume_temperature() from scipy.optimize import curve_fit, OptimizeWarning try: # Fit to an exponential equation def fitting_function(x, a, b, c): return np.exp(-b * (x + a)) + c p_b = 0.1 p_c = -200 p_a = -np.log(-p_c) / p_b - volumes[0] popt, pcov = curve_fit(fitting_function, volumes, stresses, p0=[p_a, p_b, p_c], maxfev=100000) min_stresses = fitting_function(volume_temperature, *popt) except OptimizeWarning: fit_vs = np.polyfit(volumes, stresses, 2) min_stresses = np.array( [np.polyval(fit_vs, i) for i in volume_temperature]) # if (np.max(min_stresses) - np.min(min_stresses)) < 1: # return None tolerance = 0.8 addition = (np.max(min_stresses) - np.min(min_stresses)) * tolerance return np.min(min_stresses) - addition, np.max(min_stresses) + addition
def collect_data(self): energies = [] volumes = [] # Get the calculations from workflow from itertools import chain # wf_list = list(chain(self.get_step(self.volume_expansions).get_sub_workflows(), # self.get_step(self.start).get_sub_workflows())) wf_list = self.get_step(self.volume_expansions).get_sub_workflows() for wf in wf_list: dos = wf.get_result('dos').get_array('total_dos') # self.append_to_report('DOS') # self.append_to_report('{}'.format(dos.tolist())) energy = wf.get_result( 'optimized_structure_data').get_dict()['energy'] volume = wf.get_result('final_structure').get_cell_volume() self.append_to_report('{} {}'.format(volume, energy)) energies.append(energy) volumes.append(volume) import numpy as np # data = ArrayData() # data.set_array('energy', np.array(energies)) # data.set_array('volume', np.array(volumes)) # data.store() # self.add_result('data', data) volumes = [] electronic_energies = [] fe_phonon = [] entropy = [] cv = [] thermal_list = [] structures = [] optimized_data = [] inline_params = {} wf_list = list( chain( self.get_step(self.volume_expansions).get_sub_workflows(), self.get_step(self.start).get_sub_workflows())) i = 0 for wf in wf_list: # Check if suitable for qha (no imaginary frequencies in DOS) try: freq = wf.get_result('dos').get_array('frequency') dos = wf.get_result('dos').get_array('total_dos') except: continue mask_neg = np.ma.masked_less(freq, 0.0).mask mask_pos = np.ma.masked_greater(freq, 0.0).mask int_neg = -np.trapz(np.multiply(dos[mask_neg], freq[mask_neg]), x=freq[mask_neg]) int_pos = np.trapz(np.multiply(dos[mask_pos], freq[mask_pos]), x=freq[mask_pos]) if int_neg / int_pos > 1e-6: volume = wf.get_result('final_structure').get_cell_volume() self.append_to_report( 'Volume {} not suitable for QHA (imaginary frequencies in DOS), skipping it' .format(volume)) continue # print ('int_neg: {} int_pos: {} rel: {}'.format(int_neg, int_pos, int_neg/int_pos)) # Get necessary data thermal_list.append(wf.get_result('thermal_properties')) structures.append(wf.get_result('final_structure')) optimized_data.append(wf.get_result('optimized_structure_data')) electronic_energies.append( wf.get_result('optimized_structure_data').get_dict()['energy']) volumes.append(wf.get_result('final_structure').get_cell_volume()) # fe_phonon.append(wf.get_result('thermal_properties').get_array('free_energy')) # entropy.append(wf.get_result('thermal_properties').get_array('entropy')) # cv.append(wf.get_result('thermal_properties').get_array('cv')) temperatures = wf.get_result('thermal_properties').get_array( 'temperature') temperature_fit = np.arange( 0, 1001, 10) #[100, 200, 300, 400, 500, 600, 700, 800, 900, 1000] fe_phonon.append( np.interp( temperature_fit, temperatures, wf.get_result('thermal_properties').get_array( 'free_energy'))) entropy.append( np.interp( temperature_fit, temperatures, wf.get_result('thermal_properties').get_array('entropy'))) cv.append( np.interp(temperature_fit, temperatures, wf.get_result('thermal_properties').get_array('cv'))) temperatures = temperature_fit i += 1 # inline_params['structure_{}'.format(i)] = wf.get_result('final_structure') # inline_params['optimized_data_{}'.format(i)] = wf.get_result('optimized_structure_data') # inline_params['thermal_properties_{}'.format(i)] = wf.get_result('thermal_properties') # self.append_to_report('accepted: {} {}'.format(i, wf.get_result('thermal_properties').pk)) # entropy = [] # cv = [] # fe_phonon = [] # temperatures = None # volumes = [value.get_cell_volume() for key, value in inline_params.items() if 'structure' in key.lower()] # electronic_energies = [value.get_dict()['energy'] for key, value in inline_params.items() if 'optimized_data' in key.lower()] # # thermal_properties_list = [key for key, value in inline_params.items() if 'thermal_properties' in key.lower()] # for key in thermal_properties_list: # thermal_properties = inline_params[key] # fe_phonon.append(thermal_properties.get_array('free_energy')) # entropy.append(thermal_properties.get_array('entropy')) # cv.append(thermal_properties.get_array('cv')) # temperatures = thermal_properties.get_array('temperature') from phonopy import PhonopyQHA import numpy as np # Arrange data sorted by volume and transform them to numpy array sort_index = np.argsort(volumes) volumes = np.array(volumes)[sort_index] electronic_energies = np.array(electronic_energies)[sort_index] temperatures = np.array(temperatures) fe_phonon = np.array(fe_phonon).T[:, sort_index] entropy = np.array(entropy).T[:, sort_index] cv = np.array(cv).T[:, sort_index] opt = np.argmin(electronic_energies) # Check minimum energy volume is within the data if np.ma.masked_less_equal(volumes, volumes[opt]).mask.all(): self.append_to_report( 'higher volume structures are necessary to compute') if np.ma.masked_greater_equal(volumes, volumes[opt]).mask.all(): self.append_to_report( 'Lower volume structures are necessary to compute') self.append_to_report('Dimensions T{} : FE{}'.format( len(temperatures), len(fe_phonon))) # Calculate QHA phonopy_qha = PhonopyQHA( np.array(volumes), np.array(electronic_energies), eos="vinet", temperatures=np.array(temperatures), free_energy=np.array(fe_phonon), cv=np.array(cv), entropy=np.array(entropy), # t_max=options.t_max, verbose=False) #Get data qha_temperatures = phonopy_qha._qha._temperatures[:phonopy_qha._qha. _max_t_index] helmholtz_volume = phonopy_qha.get_helmholtz_volume() thermal_expansion = phonopy_qha.get_thermal_expansion() volume_temperature = phonopy_qha.get_volume_temperature() heat_capacity_P_numerical = phonopy_qha.get_heat_capacity_P_numerical() volume_expansion = phonopy_qha.get_volume_expansion() gibbs_temperature = phonopy_qha.get_gibbs_temperature() qha_output = ArrayData() qha_output.set_array('temperature', np.array(qha_temperatures)) qha_output.set_array('helmholtz_volume', np.array(helmholtz_volume)) qha_output.set_array('thermal_expansion', np.array(thermal_expansion)) qha_output.set_array('volume_temperature', np.array(volume_temperature)) qha_output.set_array('heat_capacity_P_numerical', np.array(heat_capacity_P_numerical)) qha_output.set_array('volume_expansion', np.array(volume_expansion)) qha_output.set_array('gibbs_temperature', np.array(gibbs_temperature)) qha_output.store() # Test to leave something on folder # phonopy_qha.plot_pdf_bulk_modulus_temperature() # import matplotlib # matplotlib.use('Agg') repo_path = self._repo_folder.abspath data_folder = self.current_folder.get_subfolder('DATA_FILES') data_folder.create() # phonopy_qha.plot_pdf_bulk_modulus_temperature(filename=repo_path + '/bulk_modulus-temperature.pdf') phonopy_qha.write_bulk_modulus_temperature(filename='bm') file = open('bm') data_folder.create_file_from_filelike(file, 'bulk_modulus-temperature') # qha_results = calculate_qha_inline(**inline_params)[1] self.append_to_report('QHA properties calculated and retrieved') self.add_result('qha', qha_output) data = ArrayData() data.set_array('energy', np.array(electronic_energies)) data.set_array('volume', np.array(volumes)) data.store() self.add_result('data', data) self.append_to_report('Finishing workflow_workflow') self.next(self.exit)
cv = [] fe = [] for index in range(-5, 6): filename = "thermal_properties.yaml-%d" % index print "Reading", filename thermal_properties = yaml.load(open(filename), Loader=Loader)['thermal_properties'] temperatures = [v['temperature'] for v in thermal_properties] cv.append([v['heat_capacity'] for v in thermal_properties]) entropy.append([v['entropy'] for v in thermal_properties]) fe.append([v['free_energy'] for v in thermal_properties]) qha = PhonopyQHA(volumes, energies, temperatures=temperatures, free_energy=np.transpose(fe), cv=np.transpose(cv), entropy=np.transpose(entropy), t_max=400, verbose=True) # qha.plot_helmholtz_volume().show() # qha.plot_volume_temperature().show() # qha.plot_thermal_expansion().show() # plot = qha.plot_volume_expansion() # if plot: # plot.show() # qha.plot_gibbs_temperature().show() # qha.plot_bulk_modulus_temperature().show() # qha.plot_heat_capacity_P_numerical().show() # qha.plot_heat_capacity_P_polyfit().show() qha.plot_gruneisen_temperature().show()
class QHA: def __init__(self, volumes, electronic_energies, temperatures, free_energy, cv, entropy, eos='vinet', t_max=1000.0, Z=1, verbose=True): self._qha = PhonopyQHA(volumes, electronic_energies, eos=eos, temperatures=temperatures, free_energy=fe_phonon, cv=cv, entropy=entropy, t_max=t_max, verbose=True) self._Z = Z def run(self): self._set_mesh(distance=distance) if self._run_mesh_sampling(): self._run_gruneisen() return True else: return False def get_lattice(self): return self._lattice def get_mesh(self): return self._mesh def get_mesh_gruneisen(self): return self._gruneisen_mesh def plot(self, plt, thin_number=10): fig = plt.figure() fig.subplots_adjust(left=0.09, right=0.97, bottom=0.09, top=0.95) plt1 = fig.add_subplot(2, 3, 1) plt1.tick_params(axis='both', which='major', labelsize=10.5) self._qha.plot_volume_temperature(plt=plt) plt2 = fig.add_subplot(2, 3, 2) plt2.tick_params(axis='both', which='major', labelsize=10.5) self._qha.plot_thermal_expansion(plt=plt) plt3 = fig.add_subplot(2, 3, 3) plt3.tick_params(axis='both', which='major', labelsize=10.5) self._qha.plot_bulk_modulus_temperature(plt=plt, ylabel="Bulk modulus (GPa)") plt4 = fig.add_subplot(2, 3, 4) plt4.tick_params(axis='both', which='major', labelsize=10.5) self._qha.plot_heat_capacity_P_polyfit(plt=plt, Z=self._Z) plt5 = fig.add_subplot(2, 3, 5) plt5.tick_params(axis='both', which='major', labelsize=10.5) self._qha.plot_gibbs_temperature(plt=plt, ylabel='Gibbs free energy (eV)') plt6 = fig.add_subplot(2, 3, 6) plt6.tick_params(axis='both', which='major', labelsize=10.5) self._qha.plot_helmholtz_volume(thin_number=thin_number, plt=plt, ylabel='Free energy (eV)') def save_figure(self, plt): plt.savefig("qha.png")
def get_gibbs(structure, db_file, eos="vinet", t_step=10, t_min=0, t_max=1000, mesh=(20, 20, 20), plot=False): # other eos options: birch_murnaghan, murnaghan # The physical units of V and T are \AA^3 and K, respectively. # The unit of eV for Helmholtz and Gibbs energies, # J/K/mol for C_V and entropy, GPa for for bulk modulus and pressure are used. from phonopy import PhonopyQHA phonon = get_phonopy(structure) energies, volumes, force_constants = get_data( db_file, query={ "task_label": { "$regex": "gibbs*" }, "formula_pretty": structure.composition.reduced_formula }) temperatures = [] free_energy = [] entropy = [] cv = [] for f in force_constants: phonon.set_force_constants(-np.array(f)) phonon.set_mesh(list(mesh)) phonon.set_thermal_properties(t_step=t_step, t_min=t_min, t_max=t_max) t, g, e, c = phonon.get_thermal_properties() temperatures.append(t) free_energy.append(g) entropy.append(e) cv.append(c) phonopy_qha = PhonopyQHA(volumes, energies, eos=eos, temperatures=temperatures[0], free_energy=np.array(free_energy).T, cv=np.array(cv).T, entropy=np.array(entropy).T, t_max=np.max(temperatures[0])) # gibbs free energy max_t_index = phonopy_qha._qha._max_t_index G = phonopy_qha.get_gibbs_temperature()[:max_t_index] T = phonopy_qha._qha._temperatures[:max_t_index] if plot: import warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") import matplotlib.pyplot as plt plt.plot(T, G) plt.savefig("Gibbs.pdf") plt.show() #phonopy_qha.plot_qha(thin_number=10, volume_temp_exp=None).show() else: return T, G
def test_QHA_Si(): """Test of QHA calculation by Si.""" indices = list(range(11)) phonopy_qha = PhonopyQHA( volumes=ev_vs_v[indices, 0], electronic_energies=ev_vs_v[indices, 1], eos="vinet", temperatures=temperatures, free_energy=fe_phonon[:, indices], cv=cv[:, indices], entropy=entropy[:, indices], t_max=1000, verbose=True, ) t_indices = list(range(0, 101, 10)) # Bulk modulus without phonon np.testing.assert_almost_equal(phonopy_qha.bulk_modulus, 0.5559133052877888) # Thermal expansion np.testing.assert_allclose( [phonopy_qha.thermal_expansion[i] for i in t_indices], thermal_expansion * 1e-6, atol=1e-5, ) # Helmholtz free energies vs volumes np.testing.assert_allclose(phonopy_qha.helmholtz_volume[t_indices, 0], helmholtz_volume, atol=1e-5) # Volume vs temperature np.testing.assert_allclose(phonopy_qha.volume_temperature[t_indices], volume_temperature, atol=1e-5) # Volume vs temperature np.testing.assert_allclose(phonopy_qha.gibbs_temperature[t_indices], gibbs_temperature, atol=1e-5) # Bulk modulus vs temperature np.testing.assert_allclose( phonopy_qha.bulk_modulus_temperature[t_indices], bulkmodulus_temperature, atol=1e-5, ) # Cp vs temperature by numerical second derivative np.testing.assert_allclose( np.array(phonopy_qha.heat_capacity_P_numerical)[t_indices], cp_temperature, atol=0.01, ) # Cp vs temperature by polynomial fittings of Cv and S np.testing.assert_allclose( np.array(phonopy_qha.heat_capacity_P_polyfit)[t_indices], cp_temperature_polyfit, atol=1e-5, ) # Gruneisen parameters vs temperature np.testing.assert_allclose( np.array(phonopy_qha.gruneisen_temperature)[t_indices], gruneisen_temperature, atol=1e-5, )
def __init__(self, args, load_data=False, verbose=False, tmin=None): input_parameters = reading.read_parameters_from_input_file(args.input_file) if 'structure_file_name_outcar' in input_parameters: structure = reading.read_from_file_structure_outcar(input_parameters['structure_file_name_outcar']) else: structure = reading.read_from_file_structure_poscar(input_parameters['structure_file_name_poscar']) structure.get_data_from_dict(input_parameters) if 'supercell_phonon' in input_parameters: supercell_phonon = input_parameters['supercell_phonon'] else: supercell_phonon = np.identity(3) structure.set_force_constants(get_force_constants_from_file(file_name=input_parameters['force_constants_file_name'], fc_supercell=supercell_phonon)) if '_mesh_phonopy' in input_parameters: mesh = input_parameters['_mesh_phonopy'] else: mesh = [20, 20, 20] # Default print ('mesh set to: {}'.format(mesh)) if 'bands' in input_parameters is None: self._bands = structure.get_path_using_seek_path() else: self._bands = input_parameters['_band_ranges'] volumes, energies = read_v_e(args.ev, factor=1.0, volume_factor=1.0, pressure=args.pressure) self._fc_fit = ForceConstantsFitting(structure, files_temperature=args.ct_data, files_volume=args.cv_data, temperatures=args.temperatures, volumes=volumes, mesh=mesh, ref_temperature=args.ref_temperature, fitting_order=args.order, tmin=tmin, use_NAC=True) if not load_data: temperatures = self._fc_fit.get_temperature_range() free_energy = [] entropy = [] cv = [] for v, e in zip(volumes, energies): print ('Volume: {} Ang. Energy(U): {} eV'.format(v, e)) tp_data = self._fc_fit.get_thermal_properties(volume=v) free_energy.append(tp_data[0]) entropy.append(tp_data[1]) cv.append(tp_data[2]) free_energy = np.array(free_energy).T entropy = np.array(entropy).T cv = np.array(cv).T np.save('free_energy.npy', free_energy) np.save('temperatures.npy', temperatures) np.save('cv.npy', cv) np.save('entropy.npy', entropy) else: free_energy = np.load('free_energy.npy') temperatures = np.load('temperatures.npy') cv = np.load('cv.npy') entropy = np.load('entropy.npy') self.phonopy_qha = PhonopyQHA(volumes, energies, eos="vinet", # options: 'vinet', 'murnaghan' or 'birch_murnaghan' temperatures=temperatures, free_energy=free_energy, cv=cv, entropy=entropy, t_max=self.fc_fit.get_temperature_range()[-1], verbose=False) # Write data files to disk self.phonopy_qha.write_bulk_modulus_temperature() self.phonopy_qha.write_gibbs_temperature() self.phonopy_qha.write_heat_capacity_P_numerical() self.phonopy_qha.write_gruneisen_temperature() self.phonopy_qha.write_thermal_expansion() self.phonopy_qha.write_helmholtz_volume() self.phonopy_qha.write_volume_expansion() self.phonopy_qha.write_volume_temperature() if verbose: self.phonopy_qha.plot_qha().show()
class QuasiparticlesQHA(): def __init__(self, args, load_data=False, verbose=False, tmin=None): input_parameters = reading.read_parameters_from_input_file(args.input_file) if 'structure_file_name_outcar' in input_parameters: structure = reading.read_from_file_structure_outcar(input_parameters['structure_file_name_outcar']) else: structure = reading.read_from_file_structure_poscar(input_parameters['structure_file_name_poscar']) structure.get_data_from_dict(input_parameters) if 'supercell_phonon' in input_parameters: supercell_phonon = input_parameters['supercell_phonon'] else: supercell_phonon = np.identity(3) structure.set_force_constants(get_force_constants_from_file(file_name=input_parameters['force_constants_file_name'], fc_supercell=supercell_phonon)) if '_mesh_phonopy' in input_parameters: mesh = input_parameters['_mesh_phonopy'] else: mesh = [20, 20, 20] # Default print ('mesh set to: {}'.format(mesh)) if 'bands' in input_parameters is None: self._bands = structure.get_path_using_seek_path() else: self._bands = input_parameters['_band_ranges'] volumes, energies = read_v_e(args.ev, factor=1.0, volume_factor=1.0, pressure=args.pressure) self._fc_fit = ForceConstantsFitting(structure, files_temperature=args.ct_data, files_volume=args.cv_data, temperatures=args.temperatures, volumes=volumes, mesh=mesh, ref_temperature=args.ref_temperature, fitting_order=args.order, tmin=tmin, use_NAC=True) if not load_data: temperatures = self._fc_fit.get_temperature_range() free_energy = [] entropy = [] cv = [] for v, e in zip(volumes, energies): print ('Volume: {} Ang. Energy(U): {} eV'.format(v, e)) tp_data = self._fc_fit.get_thermal_properties(volume=v) free_energy.append(tp_data[0]) entropy.append(tp_data[1]) cv.append(tp_data[2]) free_energy = np.array(free_energy).T entropy = np.array(entropy).T cv = np.array(cv).T np.save('free_energy.npy', free_energy) np.save('temperatures.npy', temperatures) np.save('cv.npy', cv) np.save('entropy.npy', entropy) else: free_energy = np.load('free_energy.npy') temperatures = np.load('temperatures.npy') cv = np.load('cv.npy') entropy = np.load('entropy.npy') self.phonopy_qha = PhonopyQHA(volumes, energies, eos="vinet", # options: 'vinet', 'murnaghan' or 'birch_murnaghan' temperatures=temperatures, free_energy=free_energy, cv=cv, entropy=entropy, t_max=self.fc_fit.get_temperature_range()[-1], verbose=False) # Write data files to disk self.phonopy_qha.write_bulk_modulus_temperature() self.phonopy_qha.write_gibbs_temperature() self.phonopy_qha.write_heat_capacity_P_numerical() self.phonopy_qha.write_gruneisen_temperature() self.phonopy_qha.write_thermal_expansion() self.phonopy_qha.write_helmholtz_volume() self.phonopy_qha.write_volume_expansion() self.phonopy_qha.write_volume_temperature() if verbose: self.phonopy_qha.plot_qha().show() # Designed for test only def volume_shift(self, volume_range=np.arange(-2.0, 2.0, 0.1)): import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 1) volumes = self.phonopy_qha._qha._volumes energies = self.phonopy_qha._qha._electronic_energies free_energy = np.load('free_energy.npy') temperatures = np.load('temperatures.npy') cv = np.load('cv.npy') entropy = np.load('entropy.npy') for i in volume_range: volumesi = np.array(volumes) + i print volumesi phonopy_qha = PhonopyQHA(volumesi, energies, eos="vinet", # options: 'vinet', 'murnaghan' or 'birch_murnaghan' temperatures=temperatures, free_energy=free_energy, cv=cv, entropy=entropy, t_max=self.fc_fit.get_temperature_range()[-1], verbose=False) cp = phonopy_qha.get_heat_capacity_P_numerical() import matplotlib.pyplot as plt import matplotlib.colors as colors cNorm = colors.Normalize(vmin=volume_range[0], vmax=volume_range[-1]) scalarMap = plt.cm.ScalarMappable(norm=cNorm, cmap=plt.cm.get_cmap('plasma')) ax.plot(phonopy_qha._qha._temperatures[:-3], cp, label='{}'.format(i), color=scalarMap.to_rgba(i)) import matplotlib as mpl ax2 = fig.add_axes([0.93, 0.1, 0.02, 0.8]) mpl.colorbar.ColorbarBase(ax2, cmap=plt.cm.get_cmap('plasma'), norm=cNorm, spacing='proportional', ticks=volume_range, boundaries=None, format='%1i') plt.show() def plot_dos_gradient(self): import matplotlib.pyplot as plt import matplotlib.colors as colors import matplotlib.colorbar as colorbar volumes = self.phonopy_qha.get_volume_temperature() temperatures = self.fc_fit.get_temperature_range() fig, ax = plt.subplots(1,1) for t, v in zip(temperatures[::40], volumes[::20]): print ('temperature: {} K'.format(t)) dos = self.fc_fit.get_dos(t, v) cNorm = colors.Normalize(vmin=temperatures[0], vmax=temperatures[-1]) scalarMap = plt.cm.ScalarMappable(norm=cNorm, cmap=plt.cm.get_cmap('plasma')) ax.plot(dos[0], dos[1], color=scalarMap.to_rgba(t)) plt.suptitle('Phonon density of states') plt.xlabel('Frequency [THz]') ax2 = fig.add_axes([0.93, 0.1, 0.02, 0.8]) colorbar.ColorbarBase(ax2, cmap=plt.cm.get_cmap('plasma'), norm=cNorm, spacing='proportional', ticks=temperatures[::40], boundaries=None, format='%1i') plt.show() def plot_band_structure_gradient(self, tmin=300, tmax=1600, tstep=100): import matplotlib.pyplot as plt import matplotlib.colors as colors import matplotlib.colorbar as colorbar def replace_list(text_string): substitutions = {'GAMMA': u'$\Gamma$', } for item in substitutions.iteritems(): text_string = text_string.replace(item[0], item[1]) return text_string volumes = self.phonopy_qha.get_volume_temperature() cNorm = colors.Normalize(vmin=tmin, vmax=tmax) fig, ax = plt.subplots(1,1) for t in np.arange(tmin, tmax, tstep): print ('temperature: {} K'.format(t)) v = self.get_volume_at_temperature(t) scalarMap = plt.cm.ScalarMappable(norm=cNorm, cmap=plt.cm.get_cmap('plasma')) band_data = self.fc_fit.get_band_structure(t, v, band_ranges=self._bands['ranges']) for i, freq in enumerate(band_data[1]): ax.plot(band_data[1][i], band_data[2][i], color=scalarMap.to_rgba(t)) # plt.axes().get_xaxis().set_visible(False) #plt.axes().get_xaxis().set_ticks([]) plt.ylabel('Frequency [THz]') plt.xlabel('Wave vector') plt.xlim([0, band_data[1][-1][-1]]) plt.axhline(y=0, color='k', ls='dashed') plt.suptitle('Phonon dispersion') if 'labels' in self._bands: plt.rcParams.update({'mathtext.default': 'regular'}) labels = self._bands['labels'] labels_e = [] x_labels = [] for i in range(len(band_data[1])): if labels[i][0] == labels[i - 1][1]: labels_e.append(replace_list(labels[i][0])) else: labels_e.append( replace_list(labels[i - 1][1]) + '/' + replace_list(labels[i][0])) x_labels.append(band_data[1][i][0]) x_labels.append(band_data[1][-1][-1]) labels_e.append(replace_list(labels[-1][1])) labels_e[0] = replace_list(labels[0][0]) plt.xticks(x_labels, labels_e, rotation='horizontal') ax2 = fig.add_axes([0.93, 0.1, 0.02, 0.8]) colorbar.ColorbarBase(ax2, cmap=plt.cm.get_cmap('plasma'), norm=cNorm, spacing='proportional', ticks=np.arange(tmin, tmax, tstep), boundaries=None, format='%1i') plt.show() def get_volume_at_temperature(self, temperature): temperatures = self.get_qha_temperatures() volumes = self.phonopy_qha.get_volume_temperature() volume = np.interp(temperature, temperatures, volumes) return volume def plot_band_structure_constant_pressure(self, temperature=300, external_data=None): import matplotlib.pyplot as plt def replace_list(text_string): substitutions = {'GAMMA': u'$\Gamma$', } for item in substitutions.iteritems(): text_string = text_string.replace(item[0], item[1]) return text_string volume = self.get_volume_at_temperature(temperature) fig, ax = plt.subplots(1,1) band_data = self.fc_fit.get_band_structure(temperature, volume, band_ranges=self._bands['ranges']) for i, freq in enumerate(band_data[1]): ax.plot(band_data[1][i], band_data[2][i], color='r') #plt.axes().get_xaxis().set_ticks([]) plt.ylabel('Frequency [THz]') plt.xlabel('Wave vector') plt.xlim([0, band_data[1][-1][-1]]) plt.axhline(y=0, color='k', ls='dashed') plt.suptitle('Phonon dispersion') if 'labels' in self._bands: plt.rcParams.update({'mathtext.default': 'regular'}) labels = self._bands['labels'] labels_e = [] x_labels = [] for i in range(len(band_data[1])): if labels[i][0] == labels[i - 1][1]: labels_e.append(replace_list(labels[i][0])) else: labels_e.append( replace_list(labels[i - 1][1]) + '/' + replace_list(labels[i][0])) x_labels.append(band_data[1][i][0]) x_labels.append(band_data[1][-1][-1]) labels_e.append(replace_list(labels[-1][1])) labels_e[0] = replace_list(labels[0][0]) plt.xticks(x_labels, labels_e, rotation='horizontal') ax.plot(external_data[:, 0], external_data[:, 1], 'o', color='b') plt.show() def get_qha_temperatures(self): max_t_index = self.phonopy_qha._qha._get_max_t_index(self.phonopy_qha._qha._temperatures) temperatures = self.phonopy_qha._qha._temperatures[:max_t_index] return temperatures def get_FC_constant_pressure(self): temperatures = self.get_qha_temperatures() volumes = self.phonopy_qha.get_volume_temperature() for t, v in zip(temperatures[::20], volumes[::20]): fc = self.fc_fit.get_total_force_constants(temperature=t, volume=v) write_FORCE_CONSTANTS(fc.get_array(), filename='FC_{}'.format(t)) def get_total_shift_constant_pressure(self, qpoint=(0, 0, 0)): qindex = self.fc_fit.qpoint_to_index(qpoint) volumes = self.phonopy_qha.get_volume_temperature() temperatures = self.get_qha_temperatures() h_frequencies, ev = self.fc_fit.get_harmonic_frequencies_and_eigenvectors() chk_shift_matrix = [] for v, t in zip(volumes, temperatures): total_shifts = self.fc_fit.get_total_shifts(volume=v, temperature=t) chk_shift_matrix.append(total_shifts) chk_shift_matrix = np.array(chk_shift_matrix).T return chk_shift_matrix[:, qindex] def plot_total_shift_constant_pressure(self, qpoint=(0, 0, 0), branch=None): import matplotlib.pyplot as plt temperatures = self.get_qha_temperatures() chk_shift_matrix = self.get_total_shift_constant_pressure(qpoint=qpoint) plt.suptitle('Total frequency shift at wave vector={} (relative to {} K)'.format(qpoint, self.fc_fit.ref_temperature)) plt.xlabel('Temperature [K]') plt.ylabel('Frequency shift [THz]') if branch is None: plt.plot(temperatures, chk_shift_matrix.T, '-') else: plt.title('Branch {}'.format(branch)) plt.plot(temperatures, chk_shift_matrix[branch].T, '-') plt.show() @property def fc_fit(self): return self._fc_fit
def calculate_qha_inline(**kwargs): from phonopy import PhonopyQHA import numpy as np # thermal_properties_list = [key for key, value in kwargs.items() if 'thermal_properties' in key.lower()] # optimized_structure_data_list = [key for key, value in kwargs.items() if 'optimized_structure_data' in key.lower()] structure_list = [ key for key, value in kwargs.items() if 'final_structure' in key.lower() ] volumes = [] electronic_energies = [] fe_phonon = [] entropy = [] cv = [] for i in range(len(structure_list)): # volumes.append(kwargs.pop(key).get_cell_volume()) volumes.append( kwargs.pop('final_structure_{}'.format(i)).get_cell_volume()) electronic_energies.append( kwargs.pop('optimized_structure_data_{}'.format(i)).dict.energy) thermal_properties = kwargs.pop('thermal_properties_{}'.format(i)) temperatures = thermal_properties.get_array('temperature') fe_phonon.append(thermal_properties.get_array('free_energy')) entropy.append(thermal_properties.get_array('entropy')) cv.append(thermal_properties.get_array('cv')) sort_index = np.argsort(volumes) temperatures = np.array(temperatures) volumes = np.array(volumes)[sort_index] electronic_energies = np.array(electronic_energies)[sort_index] fe_phonon = np.array(fe_phonon).T[:, sort_index] entropy = np.array(entropy).T[:, sort_index] cv = np.array(cv).T[:, sort_index] print volumes print electronic_energies print temperatures print fe_phonon print cv print entropy # Calculate QHA phonopy_qha = PhonopyQHA( volumes, electronic_energies, eos="vinet", temperatures=temperatures, free_energy=fe_phonon, cv=cv, entropy=entropy, # t_max=options.t_max, verbose=True) try: qha_output = ArrayData() qha_output.set_array('temperature', np.array([1, 2, 3, 4])) qha_output.store() except: print qha_output exit() # Get data qha_temperatures = phonopy_qha._qha._temperatures[:phonopy_qha._qha. _max_t_index] helmholtz_volume = phonopy_qha.get_helmholtz_volume() thermal_expansion = phonopy_qha.get_thermal_expansion() volume_temperature = phonopy_qha.get_volume_temperature() heat_capacity_P_numerical = phonopy_qha.get_heat_capacity_P_numerical() volume_expansion = phonopy_qha.get_volume_expansion() gibbs_temperature = phonopy_qha.get_gibbs_temperature() qha_output = ArrayData() qha_output.set_array('temperature', np.array(qha_temperatures)) qha_output.set_array('helmholtz_volume', np.array(helmholtz_volume)) qha_output.set_array('thermal_expansion', np.array(thermal_expansion)) qha_output.set_array('volume_temperature', np.array(volume_temperature)) qha_output.set_array('heat_capacity_P_numerical', np.array(heat_capacity_P_numerical)) qha_output.set_array('volume_expansion', np.array(volume_expansion)) qha_output.set_array('gibbs_temperature', np.array(gibbs_temperature)) qha_output.store() return {'qha_data': qha_output}
def _calculate_quasiharmonic_phonon(self): energies = [] volumes = [] phonons = [] T = [] F = [] S = [] Cv = [] for i, task in enumerate(self._tasks): energies.append(task.get_energy()) volumes.append(task.get_cell().get_volume()) if self._sampling_mesh is not None: phonon = task.get_phonon() phonon.set_mesh(self._sampling_mesh) phonon.set_thermal_properties( t_step=self._t_step, t_max=self._t_max + self._t_step * 2.5, t_min=self._t_min ) (temperatures, free_energies, entropies, heat_capacities) = phonon.get_thermal_properties() T.append(temperatures) F.append(free_energies) S.append(entropies) Cv.append(heat_capacities) phonon.write_yaml_thermal_properties("thermal_properties-%02d.yaml" % i) if self._sampling_mesh: qha = PhonopyQHA( volumes, energies, temperatures=T[0], free_energy=np.transpose(F), cv=np.transpose(Cv), entropy=np.transpose(S), t_max=self._t_max, verbose=False, ) qha.write_helmholtz_volume() qha.write_volume_temperature() qha.write_thermal_expansion() qha.write_volume_expansion() qha.write_gibbs_temperature() qha.write_bulk_modulus_temperature() qha.write_heat_capacity_P_numerical() qha.write_heat_capacity_P_polyfit() qha.write_gruneisen_temperature() w = open("e-v.dat", "w") w.write("# cell volume energy of cell other than phonon\n") for e, v in zip(energies, volumes): w.write("%20.13f %20.13f\n" % (v, e)) self._quasiharmonic_phonon = None
def _calculate_quasiharmonic_phonon(self): energies = [] volumes = [] phonons = [] T = [] F = [] S = [] Cv = [] for i, task in enumerate(self._tasks): energies.append(task.get_energy()) volumes.append(task.get_cell().get_volume()) if self._sampling_mesh is not None: phonon = task.get_phonon() phonon.set_mesh(self._sampling_mesh) phonon.set_thermal_properties(t_step=self._t_step, t_max=self._t_max + self._t_step * 2.5, t_min=self._t_min) (temperatures, free_energies, entropies, heat_capacities) = phonon.get_thermal_properties() T.append(temperatures) F.append(free_energies) S.append(entropies) Cv.append(heat_capacities) phonon.write_yaml_thermal_properties( "thermal_properties-%02d.yaml" % i) if self._sampling_mesh: qha = PhonopyQHA(volumes, energies, temperatures=T[0], free_energy=np.transpose(F), cv=np.transpose(Cv), entropy=np.transpose(S), t_max=self._t_max, verbose=False) qha.write_helmholtz_volume() qha.write_volume_temperature() qha.write_thermal_expansion() qha.write_volume_expansion() qha.write_gibbs_temperature() qha.write_bulk_modulus_temperature() qha.write_heat_capacity_P_numerical() qha.write_heat_capacity_P_polyfit() qha.write_gruneisen_temperature() w = open("e-v.dat", 'w') w.write("# cell volume energy of cell other than phonon\n") for e, v in zip(energies, volumes): w.write("%20.13f %20.13f\n" % (v, e)) self._quasiharmonic_phonon = None
cv = [] fe = [] for index in range(-5,6): filename = "thermal_properties.yaml-%d" % index print "Reading", filename thermal_properties = yaml.load(open(filename), Loader=Loader)['thermal_properties'] temperatures = [v['temperature'] for v in thermal_properties] cv.append([v['heat_capacity'] for v in thermal_properties]) entropy.append([v['entropy'] for v in thermal_properties]) fe.append([v['free_energy'] for v in thermal_properties]) qha = PhonopyQHA(volumes, energies, temperatures=temperatures, free_energy=np.transpose(fe), cv=np.transpose(cv), entropy=np.transpose(entropy), t_max=400, verbose=True) # qha.plot_helmholtz_volume().show() # qha.plot_volume_temperature().show() # qha.plot_thermal_expansion().show() # plot = qha.plot_volume_expansion() # if plot: # plot.show() # qha.plot_gibbs_temperature().show() # qha.plot_bulk_modulus_temperature().show() # qha.plot_heat_capacity_P_numerical().show() # qha.plot_heat_capacity_P_polyfit().show() qha.plot_gruneisen_temperature().show()
volumes = np.array(volumes)[sort_index] electronic_energies = np.array(electronic_energies)[sort_index] temperatures = np.array(temperatures) fe_phonon = np.array(fe_phonon).T[:, sort_index] entropy = np.array(entropy).T[:, sort_index] cv = np.array(cv).T[:, sort_index] opt = np.argmin(electronic_energies) # Calculate QHA phonopy_qha = PhonopyQHA( np.array(volumes), np.array(electronic_energies), eos="vinet", temperatures=np.array(temperatures), free_energy=np.array(fe_phonon), cv=np.array(cv), entropy=np.array(entropy), # t_max=options.t_max, verbose=False) # Get data qha_temperatures = phonopy_qha._qha._temperatures[:phonopy_qha._qha. _max_t_index] helmholtz_volume = phonopy_qha.get_helmholtz_volume() thermal_expansion = phonopy_qha.get_thermal_expansion() volume_temperature = phonopy_qha.get_volume_temperature() heat_capacity_P_numerical = phonopy_qha.get_heat_capacity_P_numerical() volume_expansion = phonopy_qha.get_volume_expansion() gibbs_temperature = phonopy_qha.get_gibbs_temperature()
def calculate_qha_inline(**kwargs): from phonopy import PhonopyQHA from phonopy.structure.atoms import Atoms as PhonopyAtoms import numpy as np # structures = kwargs.pop('structures') # optimized_data = kwargs.pop('optimized_data') # thermodyamic_properties = kwargs.pop('thermodyamic_properties') entropy = [] cv = [] # volumes = [] fe_phonon = [] temperatures = None # structures = [key for key, value in kwargs.items() if 'structure' in key.lower()] # for key in structures: # volumes.append(kwargs.pop(key).get_cell_volume()) volumes = [ value.get_cell_volume() for key, value in kwargs.items() if 'structure' in key.lower() ] electronic_energies = [ value.get_dict()['energy'] for key, value in kwargs.items() if 'optimized_data' in key.lower() ] thermal_properties_list = [ key for key, value in kwargs.items() if 'thermal_properties' in key.lower() ] for key in thermal_properties_list: thermal_properties = kwargs[key] fe_phonon.append(thermal_properties.get_array('free_energy')) entropy.append(thermal_properties.get_array('entropy')) cv.append(thermal_properties.get_array('cv')) temperatures = thermal_properties.get_array('temperature') # Arrange data sorted by volume and transform them to numpy array sort_index = np.argsort(volumes) volumes = np.array(volumes)[sort_index] electronic_energies = np.array(electronic_energies)[sort_index] temperatures = np.array(temperatures) fe_phonon = np.array(fe_phonon).T[:, sort_index] entropy = np.array(entropy).T[:, sort_index] cv = np.array(cv).T[:, sort_index] opt = np.argmin(electronic_energies) # Check minimum energy volume is within the data if np.ma.masked_less_equal(volumes, volumes[opt]).mask.all(): print('higher volume structures are necessary to compute') exit() if np.ma.masked_greater_equal(volumes, volumes[opt]).mask.all(): print('Lower volume structures are necessary to compute') exit() # print volumes.shape # print electronic_energies.shape # print temperatures.shape # print fe_phonon.shape # print cv.shape # print entropy.shape qha_output = ArrayData() qha_output.set_array('volumes', volumes) qha_output.set_array('electronic_energies', electronic_energies) qha_output.set_array('temperatures', temperatures) qha_output.set_array('fe_phonon', fe_phonon) qha_output.set_array('cv', cv) qha_output.set_array('entropy', entropy) # Calculate QHA phonopy_qha = PhonopyQHA( np.array(volumes), np.array(electronic_energies), eos="vinet", temperatures=np.array(temperatures), free_energy=np.array(fe_phonon), cv=np.array(cv), entropy=np.array(entropy), # t_max=options.t_max, verbose=False) # print phonopy_qha.get_gibbs_temperature() qha_output = ArrayData() qha_output.set_array('volumes', volumes) qha_output.set_array('electronic_energies', electronic_energies) qha_output.set_array('temperatures', temperatures) qha_output.set_array('fe_phonon', fe_phonon) qha_output.set_array('cv', cv) qha_output.set_array('entropy', entropy) return {'qha_output': qha_output} #Get data helmholtz_volume = phonopy_qha.get_helmholtz_volume() thermal_expansion = phonopy_qha.get_thermal_expansion() volume_temperature = phonopy_qha.get_volume_temperature() heat_capacity_P_numerical = phonopy_qha.get_heat_capacity_P_numerical() volume_expansion = phonopy_qha.get_volume_expansion() gibbs_temperature = phonopy_qha.get_gibbs_temperature() qha_output = ArrayData() # qha_output.set_array('temperature', temperatures) # qha_output.set_array('helmholtz_volume', np.array(helmholtz_volume)) # qha_output.set_array('thermal_expansion', np.array(thermal_expansion)) # qha_output.set_array('volume_temperature', np.array(volume_temperature)) # qha_output.set_array('heat_capacity_P_numerical', np.array(heat_capacity_P_numerical)) # qha_output.set_array('volume_expansion', np.array(volume_expansion)) # qha_output.set_array('gibbs_temperature', np.array(gibbs_temperature)) # qha_output.store() return {'qha_output': qha_output}
def __init__(self, args, load_data=False, verbose=False, tmin=None): input_parameters = reading.read_parameters_from_input_file( args.input_file) if 'structure_file_name_outcar' in input_parameters: structure = reading.read_from_file_structure_outcar( input_parameters['structure_file_name_outcar']) else: structure = reading.read_from_file_structure_poscar( input_parameters['structure_file_name_poscar']) structure.get_data_from_dict(input_parameters) if 'supercell_phonon' in input_parameters: supercell_phonon = input_parameters['supercell_phonon'] else: supercell_phonon = np.identity(3) structure.set_force_constants( get_force_constants_from_file( file_name=input_parameters['force_constants_file_name'], fc_supercell=supercell_phonon)) if '_mesh_phonopy' in input_parameters: mesh = input_parameters['_mesh_phonopy'] else: mesh = [20, 20, 20] # Default print('mesh set to: {}'.format(mesh)) if 'bands' in input_parameters is None: self._bands = structure.get_path_using_seek_path() else: self._bands = input_parameters['_band_ranges'] volumes, energies = read_v_e(args.ev, factor=1.0, volume_factor=1.0, pressure=args.pressure) self._fc_fit = ForceConstantsFitting( structure, files_temperature=args.ct_data, files_volume=args.cv_data, temperatures=args.temperatures, volumes=volumes, mesh=mesh, ref_temperature=args.ref_temperature, fitting_order=args.order, tmin=tmin, use_NAC=True) if not load_data: temperatures = self._fc_fit.get_temperature_range() free_energy = [] entropy = [] cv = [] for v, e in zip(volumes, energies): print('Volume: {} Ang. Energy(U): {} eV'.format(v, e)) tp_data = self._fc_fit.get_thermal_properties(volume=v) free_energy.append(tp_data[0]) entropy.append(tp_data[1]) cv.append(tp_data[2]) free_energy = np.array(free_energy).T entropy = np.array(entropy).T cv = np.array(cv).T np.save('free_energy.npy', free_energy) np.save('temperatures.npy', temperatures) np.save('cv.npy', cv) np.save('entropy.npy', entropy) else: free_energy = np.load('free_energy.npy') temperatures = np.load('temperatures.npy') cv = np.load('cv.npy') entropy = np.load('entropy.npy') self.phonopy_qha = PhonopyQHA( volumes, energies, eos="vinet", # options: 'vinet', 'murnaghan' or 'birch_murnaghan' temperatures=temperatures, free_energy=free_energy, cv=cv, entropy=entropy, t_max=self.fc_fit.get_temperature_range()[-1], verbose=False) # Write data files to disk self.phonopy_qha.write_bulk_modulus_temperature() self.phonopy_qha.write_gibbs_temperature() self.phonopy_qha.write_heat_capacity_P_numerical() self.phonopy_qha.write_gruneisen_temperature() self.phonopy_qha.write_thermal_expansion() self.phonopy_qha.write_helmholtz_volume() self.phonopy_qha.write_volume_expansion() self.phonopy_qha.write_volume_temperature() if verbose: self.phonopy_qha.plot_qha().show()
class QuasiparticlesQHA(): def __init__(self, args, load_data=False, verbose=False, tmin=None): input_parameters = reading.read_parameters_from_input_file( args.input_file) if 'structure_file_name_outcar' in input_parameters: structure = reading.read_from_file_structure_outcar( input_parameters['structure_file_name_outcar']) else: structure = reading.read_from_file_structure_poscar( input_parameters['structure_file_name_poscar']) structure.get_data_from_dict(input_parameters) if 'supercell_phonon' in input_parameters: supercell_phonon = input_parameters['supercell_phonon'] else: supercell_phonon = np.identity(3) structure.set_force_constants( get_force_constants_from_file( file_name=input_parameters['force_constants_file_name'], fc_supercell=supercell_phonon)) if '_mesh_phonopy' in input_parameters: mesh = input_parameters['_mesh_phonopy'] else: mesh = [20, 20, 20] # Default print('mesh set to: {}'.format(mesh)) if 'bands' in input_parameters is None: self._bands = structure.get_path_using_seek_path() else: self._bands = input_parameters['_band_ranges'] volumes, energies = read_v_e(args.ev, factor=1.0, volume_factor=1.0, pressure=args.pressure) self._fc_fit = ForceConstantsFitting( structure, files_temperature=args.ct_data, files_volume=args.cv_data, temperatures=args.temperatures, volumes=volumes, mesh=mesh, ref_temperature=args.ref_temperature, fitting_order=args.order, tmin=tmin, use_NAC=True) if not load_data: temperatures = self._fc_fit.get_temperature_range() free_energy = [] entropy = [] cv = [] for v, e in zip(volumes, energies): print('Volume: {} Ang. Energy(U): {} eV'.format(v, e)) tp_data = self._fc_fit.get_thermal_properties(volume=v) free_energy.append(tp_data[0]) entropy.append(tp_data[1]) cv.append(tp_data[2]) free_energy = np.array(free_energy).T entropy = np.array(entropy).T cv = np.array(cv).T np.save('free_energy.npy', free_energy) np.save('temperatures.npy', temperatures) np.save('cv.npy', cv) np.save('entropy.npy', entropy) else: free_energy = np.load('free_energy.npy') temperatures = np.load('temperatures.npy') cv = np.load('cv.npy') entropy = np.load('entropy.npy') self.phonopy_qha = PhonopyQHA( volumes, energies, eos="vinet", # options: 'vinet', 'murnaghan' or 'birch_murnaghan' temperatures=temperatures, free_energy=free_energy, cv=cv, entropy=entropy, t_max=self.fc_fit.get_temperature_range()[-1], verbose=False) # Write data files to disk self.phonopy_qha.write_bulk_modulus_temperature() self.phonopy_qha.write_gibbs_temperature() self.phonopy_qha.write_heat_capacity_P_numerical() self.phonopy_qha.write_gruneisen_temperature() self.phonopy_qha.write_thermal_expansion() self.phonopy_qha.write_helmholtz_volume() self.phonopy_qha.write_volume_expansion() self.phonopy_qha.write_volume_temperature() if verbose: self.phonopy_qha.plot_qha().show() # Designed for test only def volume_shift(self, volume_range=np.arange(-2.0, 2.0, 0.1)): import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 1) volumes = self.phonopy_qha._qha._volumes energies = self.phonopy_qha._qha._electronic_energies free_energy = np.load('free_energy.npy') temperatures = np.load('temperatures.npy') cv = np.load('cv.npy') entropy = np.load('entropy.npy') for i in volume_range: volumesi = np.array(volumes) + i print volumesi phonopy_qha = PhonopyQHA( volumesi, energies, eos= "vinet", # options: 'vinet', 'murnaghan' or 'birch_murnaghan' temperatures=temperatures, free_energy=free_energy, cv=cv, entropy=entropy, t_max=self.fc_fit.get_temperature_range()[-1], verbose=False) cp = phonopy_qha.get_heat_capacity_P_numerical() import matplotlib.pyplot as plt import matplotlib.colors as colors cNorm = colors.Normalize(vmin=volume_range[0], vmax=volume_range[-1]) scalarMap = plt.cm.ScalarMappable(norm=cNorm, cmap=plt.cm.get_cmap('plasma')) ax.plot(phonopy_qha._qha._temperatures[:-3], cp, label='{}'.format(i), color=scalarMap.to_rgba(i)) import matplotlib as mpl ax2 = fig.add_axes([0.93, 0.1, 0.02, 0.8]) mpl.colorbar.ColorbarBase(ax2, cmap=plt.cm.get_cmap('plasma'), norm=cNorm, spacing='proportional', ticks=volume_range, boundaries=None, format='%1i') plt.show() def plot_dos_gradient(self): import matplotlib.pyplot as plt import matplotlib.colors as colors import matplotlib.colorbar as colorbar volumes = self.phonopy_qha.get_volume_temperature() temperatures = self.fc_fit.get_temperature_range() fig, ax = plt.subplots(1, 1) for t, v in zip(temperatures[::40], volumes[::20]): print('temperature: {} K'.format(t)) dos = self.fc_fit.get_dos(t, v) cNorm = colors.Normalize(vmin=temperatures[0], vmax=temperatures[-1]) scalarMap = plt.cm.ScalarMappable(norm=cNorm, cmap=plt.cm.get_cmap('plasma')) ax.plot(dos[0], dos[1], color=scalarMap.to_rgba(t)) plt.suptitle('Phonon density of states') plt.xlabel('Frequency [THz]') ax2 = fig.add_axes([0.93, 0.1, 0.02, 0.8]) colorbar.ColorbarBase(ax2, cmap=plt.cm.get_cmap('plasma'), norm=cNorm, spacing='proportional', ticks=temperatures[::40], boundaries=None, format='%1i') plt.show() def plot_band_structure_gradient(self, tmin=300, tmax=1600, tstep=100): import matplotlib.pyplot as plt import matplotlib.colors as colors import matplotlib.colorbar as colorbar def replace_list(text_string): substitutions = { 'GAMMA': u'$\Gamma$', } for item in substitutions.iteritems(): text_string = text_string.replace(item[0], item[1]) return text_string volumes = self.phonopy_qha.get_volume_temperature() cNorm = colors.Normalize(vmin=tmin, vmax=tmax) fig, ax = plt.subplots(1, 1) for t in np.arange(tmin, tmax, tstep): print('temperature: {} K'.format(t)) v = self.get_volume_at_temperature(t) scalarMap = plt.cm.ScalarMappable(norm=cNorm, cmap=plt.cm.get_cmap('plasma')) band_data = self.fc_fit.get_band_structure( t, v, band_ranges=self._bands['ranges']) for i, freq in enumerate(band_data[1]): ax.plot(band_data[1][i], band_data[2][i], color=scalarMap.to_rgba(t)) # plt.axes().get_xaxis().set_visible(False) #plt.axes().get_xaxis().set_ticks([]) plt.ylabel('Frequency [THz]') plt.xlabel('Wave vector') plt.xlim([0, band_data[1][-1][-1]]) plt.axhline(y=0, color='k', ls='dashed') plt.suptitle('Phonon dispersion') if 'labels' in self._bands: plt.rcParams.update({'mathtext.default': 'regular'}) labels = self._bands['labels'] labels_e = [] x_labels = [] for i in range(len(band_data[1])): if labels[i][0] == labels[i - 1][1]: labels_e.append(replace_list(labels[i][0])) else: labels_e.append( replace_list(labels[i - 1][1]) + '/' + replace_list(labels[i][0])) x_labels.append(band_data[1][i][0]) x_labels.append(band_data[1][-1][-1]) labels_e.append(replace_list(labels[-1][1])) labels_e[0] = replace_list(labels[0][0]) plt.xticks(x_labels, labels_e, rotation='horizontal') ax2 = fig.add_axes([0.93, 0.1, 0.02, 0.8]) colorbar.ColorbarBase(ax2, cmap=plt.cm.get_cmap('plasma'), norm=cNorm, spacing='proportional', ticks=np.arange(tmin, tmax, tstep), boundaries=None, format='%1i') plt.show() def get_volume_at_temperature(self, temperature): temperatures = self.get_qha_temperatures() volumes = self.phonopy_qha.get_volume_temperature() volume = np.interp(temperature, temperatures, volumes) return volume def plot_band_structure_constant_pressure(self, temperature=300, external_data=None): import matplotlib.pyplot as plt def replace_list(text_string): substitutions = { 'GAMMA': u'$\Gamma$', } for item in substitutions.iteritems(): text_string = text_string.replace(item[0], item[1]) return text_string volume = self.get_volume_at_temperature(temperature) fig, ax = plt.subplots(1, 1) band_data = self.fc_fit.get_band_structure( temperature, volume, band_ranges=self._bands['ranges']) for i, freq in enumerate(band_data[1]): ax.plot(band_data[1][i], band_data[2][i], color='r') #plt.axes().get_xaxis().set_ticks([]) plt.ylabel('Frequency [THz]') plt.xlabel('Wave vector') plt.xlim([0, band_data[1][-1][-1]]) plt.axhline(y=0, color='k', ls='dashed') plt.suptitle('Phonon dispersion') if 'labels' in self._bands: plt.rcParams.update({'mathtext.default': 'regular'}) labels = self._bands['labels'] labels_e = [] x_labels = [] for i in range(len(band_data[1])): if labels[i][0] == labels[i - 1][1]: labels_e.append(replace_list(labels[i][0])) else: labels_e.append( replace_list(labels[i - 1][1]) + '/' + replace_list(labels[i][0])) x_labels.append(band_data[1][i][0]) x_labels.append(band_data[1][-1][-1]) labels_e.append(replace_list(labels[-1][1])) labels_e[0] = replace_list(labels[0][0]) plt.xticks(x_labels, labels_e, rotation='horizontal') ax.plot(external_data[:, 0], external_data[:, 1], 'o', color='b') plt.show() def get_qha_temperatures(self): max_t_index = self.phonopy_qha._qha._get_max_t_index( self.phonopy_qha._qha._temperatures) temperatures = self.phonopy_qha._qha._temperatures[:max_t_index] return temperatures def get_FC_constant_pressure(self): temperatures = self.get_qha_temperatures() volumes = self.phonopy_qha.get_volume_temperature() for t, v in zip(temperatures[::20], volumes[::20]): fc = self.fc_fit.get_total_force_constants(temperature=t, volume=v) write_FORCE_CONSTANTS(fc.get_array(), filename='FC_{}'.format(t)) def get_total_shift_constant_pressure(self, qpoint=(0, 0, 0)): qindex = self.fc_fit.qpoint_to_index(qpoint) volumes = self.phonopy_qha.get_volume_temperature() temperatures = self.get_qha_temperatures() h_frequencies, ev = self.fc_fit.get_harmonic_frequencies_and_eigenvectors( ) chk_shift_matrix = [] for v, t in zip(volumes, temperatures): total_shifts = self.fc_fit.get_total_shifts(volume=v, temperature=t) chk_shift_matrix.append(total_shifts) chk_shift_matrix = np.array(chk_shift_matrix).T return chk_shift_matrix[:, qindex] def plot_total_shift_constant_pressure(self, qpoint=(0, 0, 0), branch=None): import matplotlib.pyplot as plt temperatures = self.get_qha_temperatures() chk_shift_matrix = self.get_total_shift_constant_pressure( qpoint=qpoint) plt.suptitle( 'Total frequency shift at wave vector={} (relative to {} K)'. format(qpoint, self.fc_fit.ref_temperature)) plt.xlabel('Temperature [K]') plt.ylabel('Frequency shift [THz]') if branch is None: plt.plot(temperatures, chk_shift_matrix.T, '-') else: plt.title('Branch {}'.format(branch)) plt.plot(temperatures, chk_shift_matrix[branch].T, '-') plt.show() @property def fc_fit(self): return self._fc_fit
def calculate_qha_inline(**kwargs): from phonopy import PhonopyQHA from phonon_common import get_helmholtz_volume_from_phonopy_qha import numpy as np # thermal_properties_list = [key for key, value in kwargs.items() if 'thermal_properties' in key.lower()] # optimized_structure_data_list = [key for key, value in kwargs.items() if 'optimized_structure_data' in key.lower()] structure_list = [ key for key, value in kwargs.items() if 'final_structure' in key.lower() ] volumes = [] electronic_energies = [] fe_phonon = [] entropy = [] cv = [] for i in range(len(structure_list)): # volumes.append(kwargs.pop(key).get_cell_volume()) volumes.append( kwargs.pop('final_structure_{}'.format(i)).get_cell_volume()) electronic_energies.append( kwargs.pop('optimized_structure_data_{}'.format(i)).dict.energy) thermal_properties = kwargs.pop('thermal_properties_{}'.format(i)) temperatures = thermal_properties.get_array('temperature') fe_phonon.append(thermal_properties.get_array('free_energy')) entropy.append(thermal_properties.get_array('entropy')) cv.append(thermal_properties.get_array('cv')) sort_index = np.argsort(volumes) temperatures = np.array(temperatures) volumes = np.array(volumes)[sort_index] electronic_energies = np.array(electronic_energies)[sort_index] fe_phonon = np.array(fe_phonon).T[:, sort_index] entropy = np.array(entropy).T[:, sort_index] cv = np.array(cv).T[:, sort_index] # Calculate QHA phonopy_qha = PhonopyQHA( np.array(volumes), np.array(electronic_energies), eos="vinet", temperatures=np.array(temperatures), free_energy=np.array(fe_phonon), cv=np.array(cv), entropy=np.array(entropy), # t_max=options.t_max, verbose=False) # Get data free_energy_volume_fitting = get_helmholtz_volume_from_phonopy_qha( phonopy_qha) qha_temperatures = phonopy_qha._qha._temperatures[:phonopy_qha._qha. _max_t_index] helmholtz_volume = phonopy_qha.get_helmholtz_volume() thermal_expansion = phonopy_qha.get_thermal_expansion() volume_temperature = phonopy_qha.get_volume_temperature() heat_capacity_P_numerical = phonopy_qha.get_heat_capacity_P_numerical() volume_expansion = phonopy_qha.get_volume_expansion() gibbs_temperature = phonopy_qha.get_gibbs_temperature() qha_output = ArrayData() qha_output.set_array('temperatures', np.array(qha_temperatures)) #qha_output.set_array('helmholtz_volume', np.array(helmholtz_volume)) qha_output.set_array('thermal_expansion', np.array(thermal_expansion)) qha_output.set_array('volume_temperature', np.array(volume_temperature)) qha_output.set_array('heat_capacity_P_numerical', np.array(heat_capacity_P_numerical)) qha_output.set_array('volume_expansion', np.array(volume_expansion)) qha_output.set_array('gibbs_temperature', np.array(gibbs_temperature)) qha_output.set_array('helmholtz_volume_points', np.array(free_energy_volume_fitting['points'])) qha_output.set_array('helmholtz_volume_fit', np.array(free_energy_volume_fitting['fit'])) qha_output.set_array('helmholtz_volume_minimum', np.array(free_energy_volume_fitting['minimum'])) return {'qha_output': qha_output}