I trying to use pymatgen to generate slab structure.
I just want to generate slabs with a fixed number of atom layers and a fixed length of vacuum layer with the max_normal_search opened. But I am kind of fail to do this.
I am confuse about the min_slab_size and min_vauccm_size. How do they finally decide the atom layers and length of vacuum layer. And how can I generate a slab a with fixed number of atoms and a fixed length of vacuum on a normal lattice vector, like 8 layers and a 20A vacuum layers, I just wang the c axis is the max c coordinate of atoms plus 20 on a normal lattice vector.
this is a very good question that I encountered as well. Pymatgen tries to give you a slab with more than
min_slab_size, which is a length in Angstrom, unless you also specify
in_unit_planes = True in the SlabGenerator input. If you do that, you will have a minimum number of Layers. However, the number of layers that pymatgen finds might not be the same number of layers that you would assume for your structure (e.g. because of somewhat corrugated layers), so the slab you get might be a lot thicker than you want it to be.
Another issue is that slabs will be returned as multiples of the oriented unit cell (OUC, you can see it after slab generation by typing
slab.oriented_unit_cell), so that alone might limit the options a lot if you have a lot of layers in your OUC.
symmetrize=True in the
get_slabs method additionally complicate things as layers get removed afterwards to give you symmetric surfaces.
On the other hand, the vacuum thickness should be pretty easy as long as you do not select
in_unit_planes = True and stay with Angstrom inputs. Otherwise also the vacuum layer will be scaled by the distance between unit planes in the OUC.
I would recommend to keep the input in Angstrom and then afterwards check the number of layers yourself and delete some if the slab got too big for your taste.
In general I think that the SlabGenerator is a bit more complex than one would assume from the input options alone. Maybe @firaty can check if what I told here is actually correct? He is more of an expert in this than I am.
This is something I’ve been working on and @mwo summarized the situation perfectly.
What I can add is that when you set
in_unit_planes = True and pass a
min_slab_size of let’s say N layers, pymatgen calculates the ratio
struct.lattice.d_hkl(miller) (let’s call this p) where
struct is the structure you pass to
SlabGenerator and this is treated as the number of layers in the
oriented_unit_cell. Then the
oriented_unit_cell is replicated N/p times (rounded up) in z-direction.
The issue arises because
d_hkl height of
oriented_unit_cell contains more than one layer of atoms in many structures I’ve tested so you end up with a slab with many more layers than what you expect.
For instance Si(111) oriented unit cell contains 6 layers and d_hkl portion of it still contains 2 layers, so you end up with at least twice the layers you asked for in
There’s a kind of a workaround I’ve found where you can check the number of layers in d_hkl portion of the oriented_unit_cell, and divide your desired number of layers by this number and set it to
min_slab_size to get a slab with number of layers closer to what you actually want. For Si(111), if I wanted 9 layers for example, I’d set
min_slab_size to 5.
The issue with this is that as @mwo also mentioned, the slabs generated are all multiples of
oriented_unit_cell which may contain many layers and for my Si(111) example it contains 6, so the number of layers of Si(111) slabs are all multiples of 6 which is not ideal for some applications I’d say.
Thanks for your replies @mwo and @firaty !
Understanding that the pymatgen use oriented_unit_cell to decide the number of layers in a slab structure is very helpful. If I understand it correctly, if a oriented_unit_cell have a 3 layers of atoms and a hieght of 6A, and I set the min_slab_size as 9A , it will return me a slab with 6 layers and 12A.
And the length of the vacuum looks like follow the same rule. I manually modify the c vector in slab.lattice to control the thickness of the vacuum layer