Open hongyi-zhao opened 7 months ago
Since your structure is a molecular crystal I would suggest using the MolecularSurfaceGenerator
class that we have. Please try the following and you should see that it generates two surface terminations. The benefit of the MolecularSurfaceGenerator
is that it will ensure that your surface terminations do not include any broken molecules.
from typing import List
from pymatgen.io.cif import CifWriter
from pymatgen.core.structure import Structure
from OgreInterface.generate import MolecularSurfaceGenerator
from OgreInterface.surfaces import MolecularSurface
subs: List[MolecularSurface] = MolecularSurfaceGenerator.from_file(
filename="C_2N_mp-2718.cif",
miller_index=[1, 0, 0],
layers=3,
vacuum=15.0,
)
for i, sub in enumerate(subs):
# sub is a MolecularSurface
# If you want POSCAR's you can do this
sub.write_file(f"POSCAR_{i:02d}")
# If you want anything else you can gen the pymatgen Structure doing the
# following and write it to whatever file you want
sub_structure: Structure = sub.get_surface()
CifWriter(struct=sub_structure).write_file(f"slab_{i:02d}.cif")
Thank you for your reply and comments. But I still have the following questions:
Here is the corresponding file in vasp POSCAR format: C2N-CONTCAR.zip
I'm not sure how to prepare it with this package from the $C_2N$ molecular crystal mentioned above.
You can remove layer using the remove_layers
function of the Surface/MolecularSurface. See the following code below:
from OgreInterface.generate import MolecularSurfaceGenerator, SurfaceGenerator
from OgreInterface.surfaces import MolecularSurface
from pymatgen.io.cif import CifWriter
from pymatgen.core.structure import Structure
subs = MolecularSurfaceGenerator.from_file(
filename="C_2N_mp-2718.cif",
miller_index=[1, 0, 0],
layers=1,
vacuum=15.0,
)
for i, sub in enumerate(subs):
# remove molecular layers
sub.remove_layers(
num_layers=1,
atomic_layers=True,
top=False,
)
# sub is a MolecularSurface
# If you want POSCAR's you can do this
sub.write_file(f"POSCAR_{i:02d}")
# If you want anything else you can gen the pymatgen Structure doing the
# following and write it to whatever file you want
sub_structure: Structure = sub.get_surface()
CifWriter(struct=sub_structure).write_file(f"slab_{i:02d}.cif")
This doesn't seem to be exactly what I need to achieve. Specifically, I want to cut a specific slab with a given thickness out of a particular crystal material, for example, this one:
In this case, how can I cut out a slab with a thickness of 1/4 * c
on (100) plane with your package?
The best thing to do in this case is to generate one layer of the slab (one unit cell thickness) and remove the required number of atomic layers using the remove_layers function until you get the monolayer that you want. That is the easiest way to do fractional thickness in the current state of the package.
Yes, something like the following does the trick:
# Import the SurfaceGenerator class
from OgreInterface.generate import SurfaceGenerator
# Create a surface generator instance from a CIF file
subs = SurfaceGenerator.from_file(
"GaTe.cif",
miller_index=[0, 0, 1], # Specify the Miller index for the surface
layers=1, # Number of layers in the generated surface
vacuum=15 # Vacuum spacing around the surface
# refine_structure=False # Don't refine the initial structure; uncomment if needed
)
# Print the number of generated surfaces
print(len(subs))
# Select the first generated surface
sub = subs._slabs[0]
# Remove layers from the selected surface
sub.remove_layers(num_layers=3, top=False) # Remove 3 layers from the bottom side
# Write the modified surface to a file with the `c`-axis orthogonal to the `ab` plane
sub.write_file("poscar", orthogonal=True)
But I also noticed the following info:
In [27]: ?sub.remove_layers Signature: sub.remove_layers( num_layers: int, atomic_layers: bool = True, top: bool = False, ) -> None Docstring: Removes atomic layers from a specified side of the surface. Using this function will ruin the pseudo-hydrogen passivation for the side that has layers removed, so it would be prefered to just select a different termination from the list of Surfaces generated using the SurfaceGenerator instead of manually removing layers to get the termination you want.
Examples: Removing 3 layers from the top of a surface:
surface.remove_layers(num_layers=3, top=True)
Args: num_layers: Number of atomic layers to remove top: Determines of the layers are removed from the top of the slab or the bottom if False atol: Tolarence for grouping the layers, if None, it is automatically determined and usually performs well File: ~/Public/repo/github.com/DerekDardzinski/OgreInterface.git/OgreInterface/surfaces/base_surface.py Type: method
So, my question is: how to fix the "Using this function will ruin the pseudo-hydrogen passivation for the side that has layers removed" problem after I've created the fractional thickness layer?
The following operation got stuck forever:
Attached is the test cif file, please check.
C_2N_mp-2718.zip
Regards, Zhao