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.
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:
adsargument 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, so
ads='O2_side'both get stripped to ‘O2’. That being said, the full string for the
adsargument will be used when writing the filenames of the new CIFs, so using an underscore can be helpful for organizational purposes.
d_MX1argument 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 set
etakeyword argument is an integer representing the denticity. In other words,
eta=1would be an end-on adsorption mode, whereas
eta=2would be a side-on adsorption mode. By default,
eta=1if unspecified. For this example, we decided to explore both options.
d_X1X2keyword argument is the desired distance between X1 and X2 (in Å). If not specified, it will default to the value for
d_MX1. Here, we decided to set
d_X1X2=1.2, which is a reasonable O-O bond distance.
ang_MX1X2keyword 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 assumes
eta=2. For this example, we use
ang_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.
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='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!