Diatomics¶
In this example, we’ll work through how to add two-atom adsorbates to open metal sites in MOFs. The CIF for the MOF we’ll use for this example can be found here
. This MOF is known Ni3(BTP)2, or Ni-BTP for short, and has a sodalite-like structure with square planar Ni cations.
Homoatomic¶
For this example, we will consider the initialization of an O2 molecule to a single coordinatively unsaturated Ni site. O2 can bind in an end-on (η1-O) or side-on (η2-O) mode depending on the structure. We’ll consider both for this example. The code to handle this is shown below.
import os
from mai.adsorbate_constructor import adsorbate_constructor
mof_path = os.path.join('example_MOFs','Ni-BTP.cif') #path to CIF of MOF
#add O2 adsorbate in η1-O mode
ads = adsorbate_constructor(ads='O2_end',d_MX1=1.5,eta=1,
d_X1X2=1.2,ang_MX1X2=120)
new_mof_atoms1 = ads.get_adsorbate(atoms_path=mof_path,site_idx=0)
#add O2 adsorbate in η2-O mode
ads = adsorbate_constructor(ads='O2_side',d_MX1=1.5,eta=2,
d_X1X2=1.2,ang_MX1X2=90)
new_mof_atoms2 = ads.get_adsorbate(atoms_path=mof_path,site_idx=0)
Like with the monatomic example, we need to initialize an adsorbate_constructor
object and then provide it the MOF of interest. In the case of diatomics, we have a few new keywords to introduce. In addition to the arguments described in the monatomic tutorial, we now need to be able to tell MAI what kind of denticity we would like (i.e. end-on or side-on adsorption) and what we want the X1-X2 bond length and M-X1-X2 bond angle to be (if X1-X2 is our diatomic of interest and M is our metal adsorption site). The arguments used here are described below:
- The
ads
argument is a string of the molecule that you want to add to the structure. Note that MAI will internally strip any characters following (and including) an underscore, soads='O2_end'
andads='O2_side'
both get stripped to ‘O2’. That being said, the full string for theads
argument will be used when writing the filenames of the new CIFs, so using an underscore can be helpful for organizational purposes. - The
d_MX1
argument is the desired distance between the adsorption site (i.e. the Ni species) and the adsorbate (in Å). If the adsorbate is bound in an end-on fashion, this represents the M-X1 distance. If the adsorbate is bound in a side-on fashion, this represents the distance between M and the midpoint between X1 and X2. Here, we setd_MX1=1.5
. - The
eta
keyword argument is an integer representing the denticity. In other words,eta=1
would be an end-on adsorption mode, whereaseta=2
would be a side-on adsorption mode. By default,eta=1
if unspecified. For this example, we decided to explore both options. - The
d_X1X2
keyword argument is the desired distance between X1 and X2 (in Å). If not specified, it will default to the value ford_MX1
. Here, we decided to setd_X1X2=1.2
, which is a reasonable O-O bond distance. - The
ang_MX1X2
keyword argument is the angle between the adsorption site and the adsorbate (in degrees). If the adsorbate is bound in an end-on fashion, this represents the M-X1-X2 bond angle. If the adsorbate is bound in a side-on fashion, this represents the angle between M, the midpoint between X1 and X2, and X2. By default, it assumesang_MX1X2=180
ifeta=1
andang_MX1X2=90
ifeta=2
. For this example, we useang_MX1X2=120
andang_MX1X2=90
, respectively, which is representative of common O2 binding geometries.
That takes care of initializing the adsorbate_constructor
object. With this, we provide the object with the path to the MOF and the site index, and it will initialize the adsorbate for us. Now let’s see what happens as a result of running this code! The initialized structures are shown below:
Exactly what we’d expect yet again! You can see that in the first example, O2 is bound end-on, whereas in the second it is bound side-on, as specified in the example script. The bond angles and distances are the same as those specified in the input file.
Heteroatomic¶
MAI also supports heteratomic adsorbates. In this example, we’ll consider the adsorption of a single CO molecule with the same MOF. The only thing that changes for heteroatomic adsorbates is that you need to tell MAI which atom is the “connecting atom” (i.e. the atom of the adsorbate bound to the metal adsorption site) if bound in an end-on fashion. By default, MAI will assume that the first atom in ads
is the connecting atom. Therefore, setting ads='CO'
or ads='OC'
would yield M-C-O or M-O-C binding modes, respectively.
import os
from mai.adsorbate_constructor import adsorbate_constructor
mof_path = os.path.join('example_MOFs','Ni-BTP.cif') #path to CIF of MOF
#add CO adsorbate in η1-C mode
ads = adsorbate_constructor(ads='CO',d_MX1=1.5,d_X1X2=1.13)
new_mof_atoms1 = ads.get_adsorbate(atoms_path=mof_path,site_idx=0)
#add CO adsorbate in η1-O mode
ads = adsorbate_constructor(ads='OC',d_MX1=1.5,d_X1X2=1.13)
new_mof_atoms2 = ads.get_adsorbate(atoms_path=mof_path,site_idx=0)
The result of running this code is shown below:
That concludes our tutorial for diatomic adsorbates. Now onto triatomics!