Prelude 1: Run_Adsorber.py - Running Adsorber¶
In this article, we will look at how to run the Adsorber
program. This program is run though the Run_Adsorber.py script, which includes all the information required for Adsorber
to adsorb species to surface sites of surfaces and clusters. You can find an example of Run_Adsorber.py
files at github.com/GardenGroupUO/Adsorber under Examples
.
Running the Adsorber Program¶
We will explain how the Run_Adsorber.py
code works by running though the example shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | from ase.build import molecule
from Adsorber import Adsorber_Program
# ------------------------------------------------------------------------------------------------------------------------------------
# Initial inputs for the Adsorber program
part_to_perform = 'Part B'
# General Variables
cluster_or_surface_model = 'cluster'
# Part A information
system_filename = '15-3-3629_with_vacuum_6.0_Ang.xyz'
# Part B information
path_to_VASP_optimised_non_adsorbate_system = 'Part_A_Non_Adsorbed_Files_For_VASP/system/OUTCAR'
cutoff = 3.5
surface_atoms = [11,25,28,13,3,8,6,23,22,59,34,62,66,1,0,4,30,15,14,16,5,12,29,2,7,10,24,26,70,35,47,50,60,63,48,39,41,44,54,68,76,71,32,31,74,42,56,52,43,40,46,61,53,45,57,72,73,77]
# ------------------------------------------------------------------------------------------------------------------------------------
# Give the Atoms objects for the atoms and molecules you want to adsorb to your cluster or surface model
adsorbed_species = []
COOH_symmetric = molecule('HCOOH') # note the carbon is index 1
COOH_symmetric.center(vacuum=10.0)
del COOH_symmetric[4] # remove the hydrogen atom
COOH_symmetric_axis = (0.1,-1,0)
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
COOH_symmetric_adsorbed_species = {'name': 'COOH_symmetric', 'molecule': COOH_symmetric, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 1, 'axis': COOH_symmetric_axis, 'rotations': rotations, 'sites_to_bind_adsorbate_to': ['Top_Sites','Bridge_Sites','Three_Fold_Sites']}
adsorbed_species.append(COOH_symmetric_adsorbed_species)
COOH_O_tilted = molecule('HCOOH') # note the carbon is index 1
COOH_O_tilted.center(vacuum=10.0)
del COOH_O_tilted[4] # remove the hydrogen atom
COOH_O_tilted_axis = (-0.4,-1,0)
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
COOH_O_tilted_adsorbed_species = {'name': 'COOH_O_tilted', 'molecule': COOH_O_tilted, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 1, 'axis': COOH_O_tilted_axis, 'rotations': rotations, 'sites_to_bind_adsorbate_to': 'Top_Sites'}
#adsorbed_species.append(COOH_O_tilted_adsorbed_species)
CO = molecule('CO') # note the carbon is index 1
CO.center(vacuum=10.0)
CO_axis = 'z'
distance_of_adatom_from_surface = 1.5
CO_adsorbed_species = {'name': 'CO', 'molecule': CO, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 1, 'axis': CO_axis}
#adsorbed_species.append(CO_adsorbed_species)
# --------------------------------------------
# option1
COH = molecule('H2COH') # note the carbon is index 0
COH.center(vacuum=10.0)
del COH[4] # remove the hydrogen atom
del COH[3] # remove the hydrogen atom
COH_axis = '-x'
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
COH_adsorbed_species = {'name': 'COH', 'molecule': COH, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': COH_axis, 'rotations': rotations}
#adsorbed_species.append(COH_adsorbed_species)
#option2
CHO = molecule('HCO') # note the carbon is index 0
CHO.center(vacuum=10.0)
CHO_axis = (-(3.0**0.5)/2.0,-1.0/2.0,0)
rotations = 'automatic' #range(0,360,10)
CHO_adsorbed_species = {'name': 'CHO', 'molecule': CHO, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': CHO_axis, 'rotations': rotations}
#adsorbed_species.append(CHO_adsorbed_species)
# --------------------------------------------
# option1
CH2O = molecule('H2CO') # note the carbon is index 1
CH2O.center(vacuum=10.0)
CH2O_axis = 'x'
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
CH2O_adsorbed_species = {'name': 'CH2O', 'molecule': CH2O, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 1, 'axis': CH2O_axis, 'rotations': rotations}
#adsorbed_species.append(CH2O_adsorbed_species)
# option1
CHOH = molecule('H2COH') # note the carbon is index 0
CHOH.center(vacuum=10.0)
del CHOH[3]
CHOH_axis = (-1,-1,0)
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
CHOH_adsorbed_species = {'name': 'CHOH', 'molecule': CHOH, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': CHOH_axis, 'rotations': rotations}
#adsorbed_species.append(CHOH_adsorbed_species)
# --------------------------------------------
# new option 1
CH3O = molecule('CH3O') # note the oxygen is index 1
CH3O.center(vacuum=10.0)
CH3O_axis = '-y'
distance_of_adatom_from_surface = 1.5
CH3O_adsorbed_species = {'name': 'CH3O', 'molecule': CH3O, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 1, 'axis': CH3O_axis}
#adsorbed_species.append(CH3O_adsorbed_species)
# new option 2
CH2OH = molecule('CH3OH') # carbon is index 0
CH2OH.center(vacuum=10.0)
del CH2OH[2] # remove the hydrogen atom
CH2OH_axis = (1,-1,0)
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
CH2OH_adsorbed_species = {'name': 'CH2OH', 'molecule': CH2OH, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': CH2OH_axis, 'rotations': rotations}
#adsorbed_species.append(CH2OH_adsorbed_species)
# --------------------------------------------
# new new option 1
CH2 = molecule('CH4') # carbon is index 0
CH2.center(vacuum=10.0)
del CH2[4] # remove the hydrogen atom
del CH2[3] # remove the hydrogen atom
CH2_axis = 'z'
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,180,10)
CH2_adsorbed_species = {'name': 'CH2', 'molecule': CH2, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': CH2_axis, 'rotations': rotations}
#adsorbed_species.append(CH2_adsorbed_species)
CH3 = molecule('CH4') # carbon is index 0
CH3.center(vacuum=10.0)
del CH3[4] # remove the hydrogen atom
CH3_axis = (1,-1,1)
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,120,10)
CH3_adsorbed_species = {'name': 'CH3', 'molecule': CH3, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': CH3_axis, 'rotations': rotations}
#adsorbed_species.append(CH3_adsorbed_species)
# new new option 2
O = molecule('O')
O.center(vacuum=10.0)
distance_of_adatom_from_surface = 1.5
O_adsorbed_species = {'name': 'O', 'molecule': O, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface}
#adsorbed_species.append(O_adsorbed_species)
OH = molecule('OH') # note the oxygen is index 0
OH.center(vacuum=10.0)
OH_axis = '-z'
distance_of_adatom_from_surface = 1.5
OH_adsorbed_species = {'name': 'OH', 'molecule': OH, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': OH_axis}
#adsorbed_species.append(OH_adsorbed_species)
C = molecule('C')
C.center(vacuum=10.0)
distance_of_adatom_from_surface = 1.5
C_adsorbed_species = {'name': 'C', 'molecule': C, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface}
#adsorbed_species.append(C_adsorbed_species)
# ------------------------------------------------------------------------------------------------------------------------------------
# Add here any other atoms and molecules that you need to locally optimise in VASP for energy calculations
Other_molecules_to_obtain_VASP_energies_for = []
graphene = molecule('C')
graphene.center(vacuum=10.0)
graphene_optimise_energy = {'name': 'graphene', 'molecule': graphene}
Other_molecules_to_obtain_VASP_energies_for.append(graphene_optimise_energy)
H2 = molecule('H2')
H2.center(vacuum=10.0)
H2_optimised_energy = {'name': 'H2', 'molecule': H2}
Other_molecules_to_obtain_VASP_energies_for.append(H2_optimised_energy)
H2O = molecule('H2O')
H2O.center(vacuum=10.0)
H2O_optimised_energy = {'name': 'H2O', 'molecule': H2O}
Other_molecules_to_obtain_VASP_energies_for.append(H2O_optimised_energy)
# ------------------------------------------------------------------------------------------------------------------------------------
# slurm informaion for making the submit.sl files for submitting VASP jobs in slurm
slurm_information = {}
slurm_information['project'] = 'uoo02568'
slurm_information['partition'] = 'large'
slurm_information['time'] = '72:00:00'
slurm_information['nodes'] = 1
slurm_information['ntasks_per_node'] = 12
slurm_information['mem-per-cpu'] = '1200MB'
slurm_information['email'] = 'yourslurmnotificationemailaddress@gmail.com'
slurm_information['vasp_version'] = 'VASP/5.3.5-intel-2017a-VTST-BEEF'
slurm_information['vasp_execution'] = 'vasp_cd'
# ------------------------------------------------------------------------------------------------------------------------------------
# Run the Adsorber program
Adsorber_Program(part_to_perform,cluster_or_surface_model,system_filename,path_to_VASP_optimised_non_adsorbate_system,cutoff,surface_atoms,adsorbed_species,slurm_information,Other_molecules_to_obtain_VASP_energies_for)
|
Lets go through each part of the Run_Adsorber.py file one by one to understand how to use it.
1) Things to import into this script¶
First you will want to import the Adsorber
program, as well as any other methods that you want to use to import atoms and molecules to adsorb upon your cluster or surface. Here, we have imported the molecule
method from the ase.build
module.
1 2 | from ase.build import molecule
from Adsorber import Adsorber_Program
|
2) Initial inputs for Adsorber
¶
To begin, there are six inputs you will need to give to Adsorber. These are:
part_to_perform (str.): This variable indicates which Part of of Adsorber protocol you would like to perform. This is either
'Part A'
,'Part B'
, or'Part C'
.cluster_or_surface_model (str.): This tells
Adsorber
if you are wanting to adsorb atoms and clusters to the surface of a cluster or a surface model. If you are dealing with a cluster, setcluster_or_surface_model = 'cluster'
, else if you are dealing with a surface model, setcluster_or_surface_model = 'surface model'
and make sure that your surface and vacuum point in the positive z direction. Also if you want to constrain any atoms in your model, this should be done in this file.
Part A options:
system_filename (str.): The name of the file of the cluster or the surface model that you will like to import into Adsorber. This file should be a
.xyz
or.traj
file, but in reality any file type will do that ASE can read (see https://wiki.fysik.dtu.dk/ase/ase/io/io.html for more information on formats that ASE can read). For surfaces, you should have already performed surface convergence studies before proceeding with part A.
Part B options:
path_to_VASP_optimised_non_adsorbate_system (str.): This is the directory to your surface or cluster model without adsorbate after you have optimised it with VASP.
For clusters, this should be set to
path_to_VASP_optimised_non_adsorbate_system = 'Part_A_Non_Adsorbed_Files_For_VASP/system/OUTCAR'
For surfaces, this should be pointed to the file that you want to bind your adsorbate to. This may be
path_to_VASP_optimised_non_adsorbate_system = 'Part_A_Non_Adsorbed_Files_For_VASP/system/OUTCAR'
, or if you have surface converged your surface model, then to the file that represents the surface converged model.
cutoff (float or dict.): This is the maximum distance between atoms to be considered
bonded
orneighbouring
. This is used to determine bridging, three-fold, and four-fold sites. This is given as a float for monoatomic cluster and surface systems, or for a multiatomic system if you are happy for the max bonding distance between any two elements to be the same. If you would like different element pairs to have different maximum bonding distances, this is given as a dictionary. For example, for a CuPd system:cutoff = {'Cu': 3.2, 'Pd': 3.6, ('Cu','Pd'): 3.4}
surface_atoms (list of ints): This is a list of the indices of all the surface atoms in your cluster or surface model. See How to Mark Surface Atoms in your Cluster/Surface model in Adsorber for how to determine which of your atoms are surface atoms and to get those clusters indices to add to the
surface_atoms
list. Note that if there are surface atoms that you do not want molecules to adsorb to, dont include them in this list.
This is given in this example as below:
5 6 7 8 9 10 11 12 13 14 15 16 17 | # Initial inputs for the Adsorber program
part_to_perform = 'Part B'
# General Variables
cluster_or_surface_model = 'cluster'
# Part A information
system_filename = '15-3-3629_with_vacuum_6.0_Ang.xyz'
# Part B information
path_to_VASP_optimised_non_adsorbate_system = 'Part_A_Non_Adsorbed_Files_For_VASP/system/OUTCAR'
cutoff = 3.5
surface_atoms = [11,25,28,13,3,8,6,23,22,59,34,62,66,1,0,4,30,15,14,16,5,12,29,2,7,10,24,26,70,35,47,50,60,63,48,39,41,44,54,68,76,71,32,31,74,42,56,52,43,40,46,61,53,45,57,72,73,77]
|
3) Add the Atoms and Molecules on to the Surface of your Cluster/Surface Model¶
We will now add all the atoms and molecules that you want to adsorb to the surface of your cluster or surface model. We first want to import all of these into this script. In ASE, there are a variety of molecules you can obtain from the molecule
method in the ase.build
module. This is imported into the Run_Adsorber.py
script with the following
from ase.build import molecule
This is what we have done here. You can also import molecules from other .xyz
or .traj
files with the read
method from ASE:
from ase.io import read
For each atom and molecule that you make you want to add it to a dictionary that has the following inputs:
name (str.): The name you want to give for this atom or molecule
molecule (ase.Atoms): The is the
Atoms
object for the atom or molecule, as obtained from themolecule
orread
method as mentioned above.distance_of_adatom_from_surface (float): This is the binding distance that you would like the atom or molecule to be initially placed from the cluster or surface model before you perform further optimisation with DFT.
For single atoms, this is all that is needed. If you want to adsorb molecules that have two or more atoms in it, you want to give two or three additional inputs into this dictionary.
index (int.): This is the index of the atom in the molecule to adsorb to the surface for the cluster/surface model. See How to Bind Molecule to the Surface of your Cluster/Surface Model in Adsorber for more information on how to select the index of the atom in the molecule you would like to be adsorbed to the surface.
axis (str./list/tuple): This is the axis in your molecule that you would like to point away from the surface of the cluster/surface model, as well as to rotate your moleule around (if you would like to rotate your molecule around the axis). See How to Bind Molecule to the Surface of your Cluster/Surface Model in Adsorber for more information for how to specify this axis.
rotations (list/tuple, optional): These are the angles of rotation that you would like to rotate the molecules around the axis on the surface of your cluster/surface model. If you have a linear molecule that is alligned to the axis or you do not want to rotate your molecule around the axis, you do not need to add this as this is an optional input. See How to Bind Molecule to the Surface of your Cluster/Surface Model in Adsorber for more information about how to specify how to best rotate your molecule about the axis on the surface of your cluster/surface model.
An example of this is shown below:
20 21 22 23 24 25 26 27 28 29 30 | # Give the Atoms objects for the atoms and molecules you want to adsorb to your cluster or surface model
adsorbed_species = []
COOH_symmetric = molecule('HCOOH') # note the carbon is index 1
COOH_symmetric.center(vacuum=10.0)
del COOH_symmetric[4] # remove the hydrogen atom
COOH_symmetric_axis = (0.1,-1,0)
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
COOH_symmetric_adsorbed_species = {'name': 'COOH_symmetric', 'molecule': COOH_symmetric, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 1, 'axis': COOH_symmetric_axis, 'rotations': rotations, 'sites_to_bind_adsorbate_to': ['Top_Sites','Bridge_Sites','Three_Fold_Sites']}
adsorbed_species.append(COOH_symmetric_adsorbed_species)
|
You want to make sure that you append each of your adsorbates to the adsorbed_species
list. If you dont want to include certain adsorbates as you go about your studies, comment their adsorbed_species.append(...)
line. For example, see line 39 below:
32 33 34 35 36 37 38 39 | COOH_O_tilted = molecule('HCOOH') # note the carbon is index 1
COOH_O_tilted.center(vacuum=10.0)
del COOH_O_tilted[4] # remove the hydrogen atom
COOH_O_tilted_axis = (-0.4,-1,0)
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
COOH_O_tilted_adsorbed_species = {'name': 'COOH_O_tilted', 'molecule': COOH_O_tilted, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 1, 'axis': COOH_O_tilted_axis, 'rotations': rotations, 'sites_to_bind_adsorbate_to': 'Top_Sites'}
#adsorbed_species.append(COOH_O_tilted_adsorbed_species)
|
The full example of the atoms and molecules that have been adsorbed to this cluster (called 15-3-3629.xyz
) is shown below:
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | # Give the Atoms objects for the atoms and molecules you want to adsorb to your cluster or surface model
adsorbed_species = []
COOH_symmetric = molecule('HCOOH') # note the carbon is index 1
COOH_symmetric.center(vacuum=10.0)
del COOH_symmetric[4] # remove the hydrogen atom
COOH_symmetric_axis = (0.1,-1,0)
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
COOH_symmetric_adsorbed_species = {'name': 'COOH_symmetric', 'molecule': COOH_symmetric, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 1, 'axis': COOH_symmetric_axis, 'rotations': rotations, 'sites_to_bind_adsorbate_to': ['Top_Sites','Bridge_Sites','Three_Fold_Sites']}
adsorbed_species.append(COOH_symmetric_adsorbed_species)
COOH_O_tilted = molecule('HCOOH') # note the carbon is index 1
COOH_O_tilted.center(vacuum=10.0)
del COOH_O_tilted[4] # remove the hydrogen atom
COOH_O_tilted_axis = (-0.4,-1,0)
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
COOH_O_tilted_adsorbed_species = {'name': 'COOH_O_tilted', 'molecule': COOH_O_tilted, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 1, 'axis': COOH_O_tilted_axis, 'rotations': rotations, 'sites_to_bind_adsorbate_to': 'Top_Sites'}
#adsorbed_species.append(COOH_O_tilted_adsorbed_species)
CO = molecule('CO') # note the carbon is index 1
CO.center(vacuum=10.0)
CO_axis = 'z'
distance_of_adatom_from_surface = 1.5
CO_adsorbed_species = {'name': 'CO', 'molecule': CO, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 1, 'axis': CO_axis}
#adsorbed_species.append(CO_adsorbed_species)
# --------------------------------------------
# option1
COH = molecule('H2COH') # note the carbon is index 0
COH.center(vacuum=10.0)
del COH[4] # remove the hydrogen atom
del COH[3] # remove the hydrogen atom
COH_axis = '-x'
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
COH_adsorbed_species = {'name': 'COH', 'molecule': COH, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': COH_axis, 'rotations': rotations}
#adsorbed_species.append(COH_adsorbed_species)
#option2
CHO = molecule('HCO') # note the carbon is index 0
CHO.center(vacuum=10.0)
CHO_axis = (-(3.0**0.5)/2.0,-1.0/2.0,0)
rotations = 'automatic' #range(0,360,10)
CHO_adsorbed_species = {'name': 'CHO', 'molecule': CHO, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': CHO_axis, 'rotations': rotations}
#adsorbed_species.append(CHO_adsorbed_species)
# --------------------------------------------
# option1
CH2O = molecule('H2CO') # note the carbon is index 1
CH2O.center(vacuum=10.0)
CH2O_axis = 'x'
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
CH2O_adsorbed_species = {'name': 'CH2O', 'molecule': CH2O, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 1, 'axis': CH2O_axis, 'rotations': rotations}
#adsorbed_species.append(CH2O_adsorbed_species)
# option1
CHOH = molecule('H2COH') # note the carbon is index 0
CHOH.center(vacuum=10.0)
del CHOH[3]
CHOH_axis = (-1,-1,0)
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
CHOH_adsorbed_species = {'name': 'CHOH', 'molecule': CHOH, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': CHOH_axis, 'rotations': rotations}
#adsorbed_species.append(CHOH_adsorbed_species)
# --------------------------------------------
# new option 1
CH3O = molecule('CH3O') # note the oxygen is index 1
CH3O.center(vacuum=10.0)
CH3O_axis = '-y'
distance_of_adatom_from_surface = 1.5
CH3O_adsorbed_species = {'name': 'CH3O', 'molecule': CH3O, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 1, 'axis': CH3O_axis}
#adsorbed_species.append(CH3O_adsorbed_species)
# new option 2
CH2OH = molecule('CH3OH') # carbon is index 0
CH2OH.center(vacuum=10.0)
del CH2OH[2] # remove the hydrogen atom
CH2OH_axis = (1,-1,0)
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,360,10)
CH2OH_adsorbed_species = {'name': 'CH2OH', 'molecule': CH2OH, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': CH2OH_axis, 'rotations': rotations}
#adsorbed_species.append(CH2OH_adsorbed_species)
# --------------------------------------------
# new new option 1
CH2 = molecule('CH4') # carbon is index 0
CH2.center(vacuum=10.0)
del CH2[4] # remove the hydrogen atom
del CH2[3] # remove the hydrogen atom
CH2_axis = 'z'
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,180,10)
CH2_adsorbed_species = {'name': 'CH2', 'molecule': CH2, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': CH2_axis, 'rotations': rotations}
#adsorbed_species.append(CH2_adsorbed_species)
CH3 = molecule('CH4') # carbon is index 0
CH3.center(vacuum=10.0)
del CH3[4] # remove the hydrogen atom
CH3_axis = (1,-1,1)
distance_of_adatom_from_surface = 1.5
rotations = 'automatic' #range(0,120,10)
CH3_adsorbed_species = {'name': 'CH3', 'molecule': CH3, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': CH3_axis, 'rotations': rotations}
#adsorbed_species.append(CH3_adsorbed_species)
# new new option 2
O = molecule('O')
O.center(vacuum=10.0)
distance_of_adatom_from_surface = 1.5
O_adsorbed_species = {'name': 'O', 'molecule': O, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface}
#adsorbed_species.append(O_adsorbed_species)
OH = molecule('OH') # note the oxygen is index 0
OH.center(vacuum=10.0)
OH_axis = '-z'
distance_of_adatom_from_surface = 1.5
OH_adsorbed_species = {'name': 'OH', 'molecule': OH, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface, 'index': 0, 'axis': OH_axis}
#adsorbed_species.append(OH_adsorbed_species)
C = molecule('C')
C.center(vacuum=10.0)
distance_of_adatom_from_surface = 1.5
C_adsorbed_species = {'name': 'C', 'molecule': C, 'distance_of_adatom_from_surface': distance_of_adatom_from_surface}
#adsorbed_species.append(C_adsorbed_species)
|
4) Obtain VASP energies for molecules that you do not want to adsorb to your cluster/surface model¶
You made also want to obtain locally optimised VASP energies of atoms and molecules for energy calculations later on in your studies. To do this, you want to add your atoms and molecules in the same way as before, such as with xyz
files or using the molecule
method in the ase.build
module, as mentioned in 3) Add the Atoms and Molecules on to the Surface of your Cluster/Surface Model. For each atom and molecule that you make you want to add it to a dictionary that has the following inputs:
name (str.): The name you want to give for this atom or molecule
molecule (ase.Atoms): The is the
Atoms
object for the atom or molecule, as obtained from themolecule
orread
method as mentioned above.
Example of this are shown below for obtaining VASP minimised energies only of graphene, H 2 , and H 2 O:
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | # Add here any other atoms and molecules that you need to locally optimise in VASP for energy calculations
Other_molecules_to_obtain_VASP_energies_for = []
graphene = molecule('C')
graphene.center(vacuum=10.0)
graphene_optimise_energy = {'name': 'graphene', 'molecule': graphene}
Other_molecules_to_obtain_VASP_energies_for.append(graphene_optimise_energy)
H2 = molecule('H2')
H2.center(vacuum=10.0)
H2_optimised_energy = {'name': 'H2', 'molecule': H2}
Other_molecules_to_obtain_VASP_energies_for.append(H2_optimised_energy)
H2O = molecule('H2O')
H2O.center(vacuum=10.0)
H2O_optimised_energy = {'name': 'H2O', 'molecule': H2O}
Other_molecules_to_obtain_VASP_energies_for.append(H2O_optimised_energy)
|
5) Information required to make submit.sl
siles for submitting files to Slurm¶
Adsorber
is able to create folders with the files required to run VASP jobs of your system for all of the adsorbed species and orientations that you would like to consider. Do you this, you will want to include a dictionary called slurm_information
that contains all the information about the submit.sl
file required to submit jobs to the Slurm workload Manager (https://slurm.schedmd.com/documentation.html). The following information is required in the slurm_information
dictionary:
'project'
(str.): The name of the project to run this on.
'partition'
(str.): The partition to run this on.
'time'
(str.): The length of time to give these jobs. This is given in ‘HH:MM:SS’, where HH is the number of hours, MM is the number of minutes, and SS is the number of seconds to runAdsorber
for.
'nodes'
(int): The number of nodes to use. Best to set this to 1.
'ntasks_per_node'
(int): The number of cpus to run these jobs across on a node for a VASP job.
'mem-per-cpu'
(str.): This is the memory that is used per cpu by the job.
'email'
(str.): This is the email address to send slurm messages to about this job. If you do not want to give an email, write here eitherNone
or''
.
'vasp_version'
(str.): This is the version of VASP that you want to use for your VASP job. Default:'VASP/5.4.4-intel-2017a'
'vasp_execution'
(str.): This is the command that is required to run a VASP job. Default:'vasp_std'
An example of a slurm_information
dictionary in the Run_Adsorber.py
script is shown below:
165 166 167 168 169 170 171 172 173 174 175 176 | # slurm informaion for making the submit.sl files for submitting VASP jobs in slurm
slurm_information = {}
slurm_information['project'] = 'uoo02568'
slurm_information['partition'] = 'large'
slurm_information['time'] = '72:00:00'
slurm_information['nodes'] = 1
slurm_information['ntasks_per_node'] = 12
slurm_information['mem-per-cpu'] = '1200MB'
slurm_information['email'] = 'yourslurmnotificationemailaddress@gmail.com'
slurm_information['vasp_version'] = 'VASP/5.3.5-intel-2017a-VTST-BEEF'
slurm_information['vasp_execution'] = 'vasp_cd'
|
Run the Adsorber Program!¶
You have got to the end of all the parameter setting stuff! Now on to the fun stuff! The next part of the Run_Adsorber.py
file will run the Adsorber program. This is written as follows in the Run_Adsorber.py
script:
160 161 | # Run the Adsorber program
Adsorber_Program(part_to_perform,cluster_or_surface_model,system_filename,path_to_VASP_optimised_non_adsorbate_system,cutoff,surface_atoms,adsorbed_species,slurm_information,Other_molecules_to_obtain_VASP_energies_for)
|