DerekDardzinski / OgreInterface

Package for creating and optimizing lattice matched and domain matched epitaxial interfaces.
Other
0 stars 4 forks source link

`SurfaceGenerator` got stuck with C_2N_mp-2718.cif #6

Open hongyi-zhao opened 7 months ago

hongyi-zhao commented 7 months ago

The following operation got stuck forever:

In [1]: from OgreInterface.generate import SurfaceGenerator

In [2]: substrate="C_2N_mp-2718.cif"

In [3]: subs = SurfaceGenerator.from_file(
   ...:     substrate,
   ...:     miller_index=[1, 0, 0],
   ...:     layers=1,
   ...:     vacuum=15,
   ...: )

Attached is the test cif file, please check.

C_2N_mp-2718.zip

Regards, Zhao

DerekDardzinski commented 6 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")
hongyi-zhao commented 6 months ago

Thank you for your reply and comments. But I still have the following questions:

  1. Can we let the package recognize molecular/ionic/atomic crystals automatically and do the corresponding manipulations accordingly?
  2. I want to cleave out the $C_2N$ mono-layer used in our paper, as shown below:

image

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.

DerekDardzinski commented 6 months ago

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")
hongyi-zhao commented 6 months ago

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:

image

In this case, how can I cut out a slab with a thickness of 1/4 * c on (100) plane with your package?

DerekDardzinski commented 6 months ago

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.

hongyi-zhao commented 6 months ago

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?