How to get an orthogonal basis after applying Slabgenerator to an hex. basis structure ?

Hello everyone,

My aim is to generate pristine slabs of a trigonal structure (alpha quartz to be precise), which is described in an hexagonal basis (α=β=90° ≠ γ=120°) and to get those slabs in an orthogonal basis (α=β=γ=90°).
I’ve managed to get a slab structure with the slabgenerator with the code shown below. But I didn’t get the orthogonalization of the basis.
The generated slab structure remain in an hexagonal basis even thought I’ve set “lll_reduce” on True. Yet it is imperative for me to get those slabs in an orthogonal basis for the rest of my work.

Here is my code :
"
import pymatgen as mg

from pymatgen.core.surface import SlabGenerator, Lattice, Slab, Structure

lattice = Lattice.hexagonal(4.96584859, 5.46805563)
sio2lattice = Structure(lattice, [“Si”, “Si”, “Si”, “O”, “O”, “O”, “O”, “O”, “O”],
[[4.70071457539E-01, -1.66533453694E-16, -9.73500614738E-20],
[1.66533453694E-16, 4.70071457539E-01, -3.33333333333E-01],
[-4.70071457539E-01, -4.70071457539E-01, -4.70071457539E-01],
[4.11209584295E-01, 2.68339766324E-01, 1.16860800877E-01],
[-2.68339766324E-01, 1.42869817970E-01, -2.16472532457E-01],
[-1.42869817970E-01, -4.11209584295E-01, 4.50194134210E-01],
[1.42869817970E-01, -2.68339766324E-01, -1.16860800877E-01],
[-4.11209584295E-01, -1.42869817970E-01, 2.16472532457E-01],
[2.68339766324E-01, 4.11209584295E-01, -4.50194134210E-01] ])

slabgen = SlabGenerator(sio2lattice, (0, 0, 1), 20, 20, lll_reduce=True,
center_slab=False, in_unit_planes=True,
primitive=False, max_normal_search=None,
reorient_lattice=True)
print(slabgen.get_slab())
"
I’m new to PymatGen and I don’t get where my error come from.

I am very grateful for any help. Thank you very much.

For each slab, you can use the get_orthogonal_c_slab method (http://pymatgen.org/pymatgen.core.surface.html?highlight=orthogonal%20slab#pymatgen.core.surface.Slab.get_orthogonal_c_slab). In your code, after slabgen.get_slab, you can simply do:

slab = slabgen.get_slab()
ortho_slab = slab.get_orthogonal_c_slab()

Thank you for your answer,

With the get_orthogonal_c_slab I got the c vector normal to the slab plane as expected.

I’m also trying to orthogonalize within the surface plane. Is there an option to apply something similar to the Gram-Shmidt process?

thank you in advance

You can try LLL reducing the orthogonal slab. But generally, there is no way to guarantee that the surface vectors are orthogonal since those are determined by proper lattice translations.

Thank you,

I’ve tried it but it didn’t work
I have activated the lll_reduce parameter in the slabgenerator, with a slabplane that I know is orthogonalizable
(0 0 1). I have applied the Gram-Schmidt process manually to this surface plane to be sure that it is possible.
But the angle between a and b stayed at 120 ° after the process with the folowing code :

"
slabgen = SlabGenerator(sio2lattice, ([0, 0, 1]), 3, 3, lll_reduce=True,
center_slab=False, in_unit_planes=False,
primitive=False, max_normal_search=True,
reorient_lattice=True)
"
When I print the structure I still get :
angles: 90.000000 90.000000 120.000000

I’m not sure if the lll_reduction is running

Thank you in advance

I think that is already the best structure that is found.

Ok thank you,

So, In this case where the smallest basis in the hkl plane is hexagonal :
if I want an orthogonal basis in the (hkl) plane of my slab I should apply the Gram-Schmidt process (via scipy or numpy) to the XY plane of the output of the slabgenerator ?

The aim is to build supercells for AIMD at the interface on different slab planes, so I’ve got to orthogonalize in the 3 directions as much as possible.

Thank you in advance,

You can try that. But my experience is that the LLL reduction already reduces to as orthogonal as possible. You can of course make supercells which are more orthogonal, but that is much more expensive to compute.

Ok,

thank you very much for your answers,