117 lines
4.7 KiB
Python
117 lines
4.7 KiB
Python
from monty.re import regrep
|
|
import matplotlib.pyplot as plt
|
|
from pathlib import Path
|
|
from echem.io_data.jdftx import Output
|
|
from echem.core.constants import Hartree2eV
|
|
import numpy as np
|
|
|
|
def get_energies_from_logs(folderpath, plot=False, dpi=200):
|
|
patterns = {'en': r'(\d+).(\d+)\s+Current Energy:\s+(.\d+\.\d+)', 'iter': r'Now starting iteration (\d+) on\s+\[(.+)\]'}
|
|
NEBlogpath = Path(folderpath) / 'logfile_NEB.log'
|
|
pylogpath = Path(folderpath) / 'py.log'
|
|
matches_neb = regrep(str(NEBlogpath), patterns)
|
|
matches_py = regrep(str(pylogpath), patterns)
|
|
iterations_number = len(matches_py['iter'])
|
|
energies = []
|
|
n_images_list = []
|
|
for i in range(iterations_number):
|
|
energies.append([])
|
|
images_list = matches_py['iter'][i][0][1].split(', ')
|
|
energies[i] = {key: [] for key in images_list}
|
|
n_images = len(images_list)
|
|
n_images_list.append(n_images)
|
|
for i in range(len(matches_neb['en'])):
|
|
iteration = int(matches_neb['en'][i][0][0])
|
|
image = matches_neb['en'][i][0][1]
|
|
energies[iteration - 1][image].append(float(matches_neb['en'][i][0][2]))
|
|
if plot:
|
|
max_i = 0
|
|
for i in range(len(energies)):
|
|
plt.figure(dpi=dpi)
|
|
barrier = []
|
|
all_images = []
|
|
for image in energies[i].keys():
|
|
if int(image) > max_i:
|
|
max_i = int(image)
|
|
plt.scatter([int(image) for _ in range(len(energies[i][image]))], energies[i][image], c=f'C{int(image)}')
|
|
if len(energies[i][image]) != 0:
|
|
plt.scatter(int(image), energies[i][image][-1], c=f'C{int(image)}')
|
|
barrier.append(energies[i][image][-1])
|
|
all_images.append(int(image))
|
|
plt.plot(all_images, barrier, c='black')
|
|
return plt, energies
|
|
else:
|
|
return energies
|
|
|
|
def get_energies_from_outs(folderpath, opt_history=False, plot=False, dpi=200):
|
|
folderpath /= 'iterations'
|
|
neb_barriers_hist = []
|
|
neb_barriers = []
|
|
for iter, iter_path in enumerate(folderpath.glob('iter_*')):
|
|
neb_barriers.append([])
|
|
neb_barriers_hist.append([])
|
|
for f_path in iter_path.glob('[0-9]'):
|
|
out = Output.from_file(f_path / 'output.out')
|
|
if opt_history:
|
|
neb_barriers_hist[iter].append(out.energy_ionic_hist['G'] * Hartree2eV)
|
|
neb_barriers[iter].append(out.energy_ionic_hist['G'][-1] * Hartree2eV)
|
|
if plot:
|
|
if opt_history:
|
|
for i, barrier in enumerate(neb_barriers_hist):
|
|
plt.figure(dpi=dpi)
|
|
plt.title(f'Iteration {i}')
|
|
for i, traj in enumerate(barrier):
|
|
plt.plot(traj, label=i)
|
|
plt.legend(frameon=False)
|
|
plt.figure(dpi=dpi)
|
|
for i, barrier in enumerate(neb_barriers):
|
|
plt.plot(barrier, label=i)
|
|
plt.legend(frameon=False)
|
|
return plt, neb_barriers, neb_barriers_hist
|
|
else:
|
|
plt.figure(dpi=dpi)
|
|
for i, barrier in enumerate(neb_barriers):
|
|
plt.plot(barrier, label=i)
|
|
plt.legend(frameon=False)
|
|
return plt, neb_barriers
|
|
else:
|
|
return neb_barriers
|
|
|
|
def get_energies_from_pylog(filepath, plot=False, dpi=200):
|
|
energies = []
|
|
with open(filepath) as f:
|
|
data = f.readlines()
|
|
for line in data:
|
|
if 'Energies after iteration' in line:
|
|
energies.append(list(map(float, line.strip().split('[')[1][:-1].split(', '))))
|
|
if plot:
|
|
plt.figure(dpi=dpi)
|
|
for i, e in enumerate(energies):
|
|
plt.plot(e, label=i)
|
|
plt.legend(frameon=False)
|
|
return plt, energies
|
|
else:
|
|
return energies
|
|
|
|
def get_energies_from_NEBlog(folderpath, plot=False, dpi=200):
|
|
patterns = {'en': r'(\d+)\s+Current Energy:\s+(.\d+\.\d+)', \
|
|
'images': r'Successfully initialized JDFTx calculator(.+)/(\d+)'}
|
|
NEBlogpath = Path(folderpath) / 'logfile_NEB.log'
|
|
matches_neb = regrep(str(NEBlogpath), patterns)
|
|
nimages = len(matches_neb['images'])
|
|
energies = [[] for i in range(nimages)]
|
|
for i in range(len(matches_neb['en'])):
|
|
image = int(matches_neb['en'][i][0][0])
|
|
energies[image-1].append(float(matches_neb['en'][i][0][1]))
|
|
if plot:
|
|
plt.figure(dpi=dpi)
|
|
barrier = []
|
|
all_images = []
|
|
for image in range(len(energies)):
|
|
plt.scatter([image for _ in range(len(energies[image]))], energies[image], c=f'C{image}')
|
|
barrier.append(energies[image][-1])
|
|
all_images.append(int(image))
|
|
plt.plot(all_images, barrier, c='black')
|
|
return plt, energies
|
|
else:
|
|
return energies |