materialsproject / pymatgen

Python Materials Genomics (pymatgen) is a robust materials analysis code that defines classes for structures and molecules with support for many electronic structure codes. It powers the Materials Project.
https://pymatgen.org
Other
1.5k stars 862 forks source link

Documentation: Slab surface normal explanation seems fishy to me #1237

Closed smheidrich closed 6 years ago

smheidrich commented 6 years ago

System

Summary

In the documentation for the pymatgen.core.surface.Slab class, it says:

Note that all Slabs have the surface normal oriented in the c-direction. This means the lattice vectors a and b are in the surface plane and the c vector is out of the surface plane (though not necessary perpendicular to the surface.)

Do I have a knot in my brain or does that make no sense? If the surface normal is really oriented in the c-direction, then the c-vector is necessarily perpendicular to the surface, isn't it? So either the first or the second sentence is wrong. From the tests below, it seems to me that (at least in this case with these settings) the first sentence doesn't hold.

Example code

This demonstrates that the slab normal doesn't necessarily point in the direction of the c lattice vector, but it does seem to always point in the direction perpendicular to the a and b lattice vectors:

import numpy as np
from pkg_resources import resource_filename
from pymatgen.io.vasp.inputs import Poscar
from pymatgen.core.surface import generate_all_slabs

# works only if you installed from the git repository in editable mode; if not,
# just plug in the path to the test file manually
pc_path = resource_filename("pymatgen", "../test_files/POSCAR.Al12O18")
pc = Poscar.from_file(pc_path)
structure = pc.structure

print("***** ORIGINAL LATTICE: *****")
print(structure.lattice)

# generate slabs with more or less default settings:
print("Generating slabs; this might take a while...")
slabs = generate_all_slabs(structure=structure, max_index=2, min_slab_size=5.0,
  min_vacuum_size=5.0)
print("")

print("***** SLABS: *****")
for slab in slabs:
  print("Lattice:")
  print(slab.lattice)
  print("Slab normal: {}".format(slab.normal))
  ab_normal = np.cross(slab.lattice.matrix[0], slab.lattice.matrix[1])
  ab_normal /= np.linalg.norm(ab_normal)
  print("(a,b)-normal: {}".format(ab_normal))
  print("")

Output

***** ORIGINAL LATTICE: *****
2.397450 -4.152505 0.000000
2.397450 4.152505 0.000000
0.000000 0.000000 13.099500
Generating slabs; this might take a while...

***** SLABS: *****
Lattice:
4.152505 0.000000 -7.192350
-0.000000 13.099500 -4.794900
0.000000 0.000000 28.769399
Slab normal: [0.8518758  0.18002818 0.49183075]
(a,b)-normal: [0.8518758  0.18002818 0.49183075]

...

Suggested solution

From the tests in the example code above, I would say that the first sentence should instead read:

Note that all Slabs have the surface normal oriented perpendicular to the a and b lattice vectors.

Or, perhaps even simpler:

Note that all Slab surfaces are oriented parallel to the plane spanned by the a and b lattice vectors.

But maybe that's just down to the specific settings I used, or maybe I made a mistake or misunderstood something?

Files

POSCAR.Al12O18, which ships with pymatgen (in the test_files folder).

shyuep commented 6 years ago

The documentation is correct as is. When you generate a slab, the c vector is out of the a-b plane, which is defined to be parallel to the plane of interest. It does not mean that c is perpendicular to the a-b plane. It will be perpendicular for certain planes, e.g., the (100) plane of the cubic structure or (001) of the hexagonal, tetragonal structures, etc. But it is not true for any general triclinic structure. Pls consult the publication linked to this piece of code for a detailed explanation why c is not always parallel to a and b.

montoyjh commented 6 years ago

I think @smheidrich has a point here, they're highlighting this statement in the documentation specifically:

Note that all Slabs have the surface normal oriented in the c-direction.

I interpret this as "the surface normal should be parallel to the c-vector in all cases." As you both are pointing out, this is untrue in general. @smheidrich why don't you try making a small edit and submitting a PR?

smheidrich commented 6 years ago

@montoyjh Thanks, done.

@shyuep I agree with everything in your post (except for the first sentence of course), I just don't see how the statement that @montoyjh cited can be compatible with it. Or do we mean different things by a, b and c perhaps? I thought they were referring to the lattice vectors of the returned slab structure. Very sorry for wasting your time if it turns out I'm wrong.

shyuep commented 6 years ago

Thanks. Sorry I misread what you wrote earlier. I have merged the PR.

smheidrich commented 6 years ago

No problem, thanks for merging! :+1: