Files
VASP_calc/electrochemistry/echem/io_data/gas_sensor.py
2026-01-08 19:47:32 +03:00

115 lines
3.5 KiB
Python

import numpy as np
from typing import Union, List, Iterable
from monty.re import regrep
import re
from echem.io_data.ddec import AtomicNetCharges
class GasSensor:
def __init__(self):
pass
@staticmethod
def read_OUTCAR(filepath) -> float:
"""
This function reads your OUTCAR file to get the final Energy of the system.
"""
file = open(filepath, 'r')
data = file.readlines()
file.close()
patterns = {'energy_ionic': r'free energy\s+TOTEN\s+=\s+(.\d+\.\d+)\s+eV'}
matches = regrep(filepath, patterns)
end_energy = np.array([float(i[0][0]) for i in matches['energy_ionic']])
return end_energy[-1]
@staticmethod
def sort_DDEC_output(filepath, k: int) -> list[int]:
"""
This function sorts atoms in your system to get atoms related to your molecule
k - number of atoms consisting in your molecule
"""
z_coords = {}
idx = 1
with open(filepath, 'r') as file:
while True:
line = file.readline()
if re.search('\sChargemol', line) is not None:
break
list_of_substrings = line.split(' ')
if re.search('^\s|^j', list_of_substrings[0]) is None:
z_coords[idx] = list_of_substrings[-2]
idx += 1
continue
sorted_z_coords = dict(sorted(z_coords.items(), key = lambda item: item[1], reverse = True))
result = []
counter = 0
for item in sorted_z_coords:
if counter < k:
result.append(item)
counter += 1
else:
break
return result
@staticmethod
def get_chrg_mol(filepath, k: int or list[int]) -> float:
"""
This function can help you to get the molecule charge.
filepath - DDEC6 output file: DDEC_even_tempered_net_atomic_charges.xyz
k - the number of atoms, consisting in molecule. Besides, your can write the ordinal number of an atom in your molecule.
"""
atomic_charges = AtomicNetCharges.from_file(filepath)
net_charges = atomic_charges.net_charges
if type(k) == int:
chrg_molecule = 0
targets = GasSensor.sort_DDEC_output(filepath, k)
for i in targets:
chrg_molecule += net_charges[i - 1]
return chrg_molecule
elif isinstance(k, list):
targets = k
chrg_molecule = 0
for i in targets:
chrg_molecule += net_charges[i - 1]
return chrg_molecule
@staticmethod
def get_Ead(filepath, E_surface, E_molecule) -> float:
"""
This function can help you to get the adsorption energy, using energy of whole system, energy of the surface and energy of your molecule.
filepath - your OUTCAR file obtained as a result of VASP optimization.
"""
E_system = GasSensor.read_OUTCAR(filepath)
E_ad = E_system - E_surface - E_molecule
#print(E_ad)
return E_ad
@staticmethod
def get_energy_in_meV(filepath):
"""
This function can help you to get energies in meV.
filepath - your .txt file, consisting of energies in eV.
"""
X = np.genfromtxt(filepath)
X_new = []
for i in X:
X_new = X * 1000
return f'Your energies in meV: {X_new}'