You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
5.2 KiB
85 lines
5.2 KiB
#!/usr/bin/env python3 |
|
import pymatgen.analysis.adsorption as pa |
|
import pymatgen.core.structure as st |
|
from pymatgen.core import Structure |
|
import argparse |
|
import sys |
|
import warnings |
|
warnings.filterwarnings("ignore") |
|
parser = argparse.ArgumentParser(description='Build possible adsorbate-adsorbent interactions for the surface reaction') |
|
parser.add_argument('-s', '--slab', type=str, help='structure POSCAR of the surface' ) |
|
parser.add_argument('-height','--height', type=float, help='height criteria for selection of surface sites' ) |
|
parser.add_argument('-d','--distance', type=float, help='distance from the coordinating ensemble of atoms along the miller index for the site (i. e. the distance from the slab itself)' ) |
|
parser.add_argument('-pi','--put_inside', default=True, type=bool, help='whether to put the site inside the cell ' ) |
|
parser.add_argument('-sr','--symm_reduce', type=float, default=0.1, help='symmetry reduction threshold' ) |
|
parser.add_argument('-nr','--near_reduce', type=float, default=0.1, help='near reduction threshold' ) |
|
parser.add_argument('-noh','--no_obtuse_hollow', type=bool, default=True, help='flag to indicate whether to include obtuse triangular ensembles in hollow sites' ) |
|
parser.add_argument('-sel','--selective_dynamics', type=bool, default=True, help='create the selective dynamics options for VASP calculations') |
|
parser.add_argument('-dyn','--dyn', type=float, default=3.50, help='Height for dynamical atoms selections') |
|
parser.add_argument('-t','--type', type=str, help='Type of adsorption site based on the list' ) |
|
parser.add_argument('-ad','--ad', type=str, help='Structure of adsorbate from file' ) |
|
parser.add_argument('-all','--all', type=bool, default=False, help='Print all possible structures') |
|
|
|
opt = parser.parse_args(sys.argv[1:]) |
|
|
|
print('Begin searching for adsorption sites...') |
|
# Defining the slab coordinate |
|
slab_coord = Structure.from_file(opt.slab) |
|
|
|
# Searching the active sites |
|
check_site = pa.AdsorbateSiteFinder(slab_coord, height=opt.height) |
|
# Preparing the adsorbate molecules in xyz cartesian format |
|
ad = st.Molecule.from_file(opt.ad) |
|
|
|
# Defining thke protocol for selective dynamics. Here you need to manually specify the height measured from the top of your slab structure. The default value is 3.50 Angstroms. |
|
adsorbent = pa.AdsorbateSiteFinder(slab_coord, height=opt.dyn, selective_dynamics=opt.selective_dynamics) |
|
adsorbent.slab.to(filename='adsorbent.vasp', fmt='poscar') |
|
# Here, I assume that you want to generate one by one the adsorption types. The choices are 'ontop', 'hollow', and 'bridge' types. |
|
if (opt.all == False): |
|
sites = check_site.find_adsorption_sites(distance=opt.distance, put_inside=opt.put_inside, symm_reduce=opt.symm_reduce, near_reduce=opt.near_reduce, positions=[opt.type], no_obtuse_hollow=opt.no_obtuse_hollow) |
|
site_coord = sites.get(opt.type) |
|
index = 0 |
|
site_all = [] |
|
for site in site_coord: |
|
adsorbed = adsorbent.add_adsorbate(ad, site, repeat=None, reorient=True) |
|
adsorbed.to(filename='{}_{}.vasp'.format(opt.type,index), fmt='poscar') |
|
index += 1 |
|
site_all.append(site.tolist()) |
|
# adsorbed = adsorbent.add_adsorbate(ad, site_all, repeat=None, reorient=True) |
|
# adsorbed.to(filename='{}_all.vasp'.format(opt.type), fmt='poscar') |
|
print('{}: {}'.format(opt.type, len(site_coord))) |
|
print('Done for all possibilities of {} adsorption mode!'.format(opt.type)) |
|
# The following if in case you want to generate all possible adsorption sites. |
|
else: |
|
sites = check_site.find_adsorption_sites(distance=opt.distance, put_inside=opt.put_inside, symm_reduce=opt.symm_reduce, near_reduce=opt.near_reduce, positions=['hollow','ontop','bridge'], no_obtuse_hollow=opt.no_obtuse_hollow) |
|
hollow_coord = sites.get('hollow') |
|
bridge_coord = sites.get('bridge') |
|
ontop_coord = sites.get('ontop') |
|
hollow_ind = 0 |
|
bridge_ind = 0 |
|
ontop_ind = 0 |
|
|
|
for site in hollow_coord: |
|
adsorbed = adsorbent.add_adsorbate(ad, site, repeat=None, reorient=True) |
|
elements = adsorbed.types_of_specie |
|
element = [str(x) for x in elements] |
|
sorted_ads = adsorbed.get_sorted_structure(key=lambda x: element.index(str(x.specie))) |
|
sorted_ads.to(filename='hollow_{}.vasp'.format(hollow_ind), fmt='poscar') |
|
hollow_ind += 1 |
|
for site in ontop_coord: |
|
adsorbed = adsorbent.add_adsorbate(ad, site, repeat=None, reorient=True) |
|
elements = adsorbed.types_of_specie |
|
element = [str(x) for x in elements] |
|
sorted_ads = adsorbed.get_sorted_structure(key=lambda x: element.index(str(x.specie))) |
|
sorted_ads.to(filename='ontop_{}.vasp'.format(ontop_ind), fmt='poscar') |
|
ontop_ind += 1 |
|
for site in bridge_coord: |
|
adsorbed = adsorbent.add_adsorbate(ad, site, repeat=None, reorient=True) |
|
elements = adsorbed.types_of_specie |
|
element = [str(x) for x in elements] |
|
sorted_ads = adsorbed.get_sorted_structure(key=lambda x: element.index(str(x.specie))) |
|
sorted_ads.to(filename='bridge_{}.vasp'.format(bridge_ind), fmt='poscar') |
|
bridge_ind += 1 |
|
print('###############THE LIST OF ADSORPTION SITES####################') |
|
print('hollow:{}, bridge:{}, ontop:{}'.format(len(hollow_coord), len(bridge_coord), len(ontop_coord))) |
|
print('Done for all possibilities of adsorption modes!')
|
|
|