romankempt / hetbuilder

Builds 2D heterostructures via coincidence lattice theory.
MIT License
12 stars 7 forks source link

Direct Z-scheme heterojunction construction of C_2N/Mg(OH)_2 targed for photocatalytic water splitting. #9

Open hongyi-zhao opened 9 months ago

hongyi-zhao commented 9 months ago

This paper with the title "Direct Z-scheme construction of C_2N/Mg(OH)_2 heterojunction and first-principles investigation of photocatalytic water splitting" is one of the recent work done by my student, and I am one of the corresponding authors of the paper named Hongsheng Zhao.

Now, I wonder for the photocatalytic water-splitting purpose, how should I speed up the construction of the heterojunctions mentioned above with the help of hetbuilder?

Here, I attached our paper and the input files for constructing the heterostructure after structural optimization with VASP.

Any tips and comments will be helpful.

The-paper-and-POSCAR.zip

Regards, Zhao

romankempt commented 9 months ago

Depends on what you want to study with which method. Most probably, generate some starting interfaces with hetbuilder, optimize them using a low-level method to get a feeling for which one is the most stable, then further your investigation.

hongyi-zhao commented 9 months ago

Depends on what you want to study with which method.

Mainly DFT via vasp.

Most probably, generate some starting interfaces with hetbuilder,

I tried the following method and it produced the same supercell as the one I used in my paper:

# This is the Python script poscar_to_2d.py called below:
import sys
from ase.io import read, write

def create_2d_structure(input_filename, output_filename):
    # Read the structure from the specified input file
    structure = read(input_filename)

    # Increase the cell size along the z-axis to create a 2D structure
    structure.cell[2, 2] += 20  # Increase the cell size along the z-axis by 20 Å

    # Set periodic boundary conditions for a 2D material: True in x and y, False in z
    structure.pbc = [True, True, False]

    # Determine the format for output based on the file extension
    # This assumes that for VASP/POSCAR format, users might use .vasp or .poscar as the file extension
    output_format = 'vasp' if output_filename.lower().endswith(('.poscar', '.vasp')) else output_filename.split('.')[-1]

    # Save the modified structure as a file in the specified output format.
    write(output_filename, structure, format=output_format)

if __name__ == "__main__":
    if len(sys.argv) == 3:
        input_file = sys.argv[1]
        output_file = sys.argv[2]
        create_2d_structure(input_file, output_file)
    else:
        print("Usage: python script_name.py <input_filename> <output_filename>")
        sys.exit(1)

Then do the following:

$ python poscar_to_2d.py C2N/CONTCAR 2d_C2N.cif
$ python poscar_to_2d.py MgOH2/CONTCAR 2d_MgOH2.cif
$ hetbuilder build -t 0.05 2d_C2N.cif 2d_MgOH2.cif 

image

But if I use the following options, the same size supercell as above will show the $\theta = 18 ^\circ$:

$ hetbuilder build -t 0.2 2d_C2N.cif 2d_MgOH2.cif

image

romankempt commented 9 months ago

That can happen. For a small tolerance, the algorithm might find 4 matching lattice points at an angle of 18 degrees and then saves the structure. For a higher tolerance, it might only find it at 19 degrees. You simply have to keep in mind that a rotation of 1 degree barely moves the lattice points in the case of small unit cells.

hongyi-zhao commented 9 months ago

You're correct. I tried to compare them using xtalcomp and they are the same. The steps are as follows:

# Visualize and save the corresponding structures:
$ hetbuilder build -t 0.05 2d_C2N.cif 2d_MgOH2.cif
$ hetbuilder build -t 0.2 2d_C2N.cif 2d_MgOH2.cif
# Convert them to poscar format:
$ formats_convert.py C12H14Mg7N6O14_18.00_degree_0.in C12H14Mg7N6O14_18.00_degree_0.vasp
$ formats_convert.py C12H14Mg7N6O14_19.00_degree_0.in C12H14Mg7N6O14_19.00_degree_0.vasp

Then do the comparison by XtalComp using the above poscar files by pasting them here:

Result: Using a cartesian tolerance of 0.090000 and an angular tolerance of 0.010000...

The structures DO match! NOTE: The crystals may have been reduced to their primitive form by spglib functions before this transform was applied

Transformation matrix:

-------------------------------------------------- +0.99995 -0.00000 +0.00000 +2.38112 +0.00000 +0.99995 -0.00000 +2.74961 +0.00000 +0.00000 +1.00000 -31.07693 +0.00000 +0.00000 +0.00000 +1.00000

Input structures:

------------------------------------- ------------------------------------- First cell matrix (row vectors) Second cell matrix (row vectors)
8.33329 -0.08061 0.00000 8.33407 -0.00777 0.00000
-4.09666 7.25770 0.00000 -4.16013 7.22194 0.00000
0.00000 0.00000 127.70382 0.00000 0.00000 127.70382
------------------------------------- -------------------------------------
type: fractional coordinate type: fractional coordinate
------------------------------------- -------------------------------------
0: 0.15852 0.00000 0.19813 0: 0.15852 0.00000 0.19813
0: 0.15841 0.33833 0.19813 0: 0.15841 0.33833 0.19813
0: 0.48928 0.66918 0.19813 0: 0.48928 0.66918 0.19813
0: 0.82766 0.66914 0.19813 0: 0.82766 0.66914 0.19813
0: 0.48927 0.00000 0.19813 0: 0.48927 -0.00000 0.19813
0: 0.82766 0.33833 0.19813 0: 0.82766 0.33833 0.19813
1: 0.31692 0.33422 0.19813 1: 0.31692 0.33422 0.19813
1: 0.31693 0.16262 0.19813 1: 0.31693 0.16262 0.19813
1: 0.49341 0.51070 0.19813 1: 0.49341 0.51070 0.19813
1: 0.49344 0.16261 0.19813 1: 0.49344 0.16261 0.19813
1: 0.65189 0.82763 0.19813 1: 0.65189 0.82763 0.19813
1: 0.65187 0.00411 0.19813 1: 0.65187 0.00411 0.19813
1: 0.66506 0.33422 0.19813 1: 0.66506 0.33422 0.19813
1: 0.66504 0.51070 0.19813 1: 0.66504 0.51070 0.19813
1: 0.82352 0.82762 0.19813 1: 0.82352 0.82762 0.19813
1: 0.82349 0.17572 0.19813 1: 0.82349 0.17572 0.19813
1: 0.00001 0.00410 0.19813 1: 0.00001 0.00410 0.19813
1: -0.00000 0.17571 0.19813 1: -0.00000 0.17571 0.19813
2: 0.47619 0.38095 0.24335 2: 0.47619 0.38095 0.24335
3: 0.00000 0.00000 0.25118 3: 0.00000 0.00000 0.25118
3: 0.23810 0.19048 0.23552 3: 0.23810 0.19048 0.23552
4: 0.00000 0.00000 0.25846 4: 0.00000 0.00000 0.25846
4: 0.23810 0.19048 0.22825 4: 0.23810 0.19048 0.22825
5: 0.61905 0.09524 0.24335 5: 0.61905 0.09524 0.24335
5: 0.76190 0.80952 0.24335 5: 0.76190 0.80952 0.24335
5: 0.04762 0.23810 0.24335 5: 0.04762 0.23810 0.24335
5: 0.90476 0.52381 0.24335 5: 0.90476 0.52381 0.24335
5: 0.19048 0.95238 0.24335 5: 0.19048 0.95238 0.24335
5: 0.33333 0.66667 0.24335 5: 0.33333 0.66667 0.24335
6: 0.14286 0.71429 0.25118 6: 0.14286 0.71429 0.25118
6: 0.28571 0.42857 0.25118 6: 0.28571 0.42857 0.25118
6: 0.57143 0.85714 0.25118 6: 0.57143 0.85714 0.25118
6: 0.42857 0.14286 0.25118 6: 0.42857 0.14286 0.25118
6: 0.71429 0.57143 0.25118 6: 0.71429 0.57143 0.25118
6: 0.85714 0.28571 0.25118 6: 0.85714 0.28571 0.25118
6: 0.38095 0.90476 0.23552 6: 0.38095 0.90476 0.23552
6: 0.52381 0.61905 0.23552 6: 0.52381 0.61905 0.23552
6: 0.80952 0.04762 0.23552 6: 0.80952 0.04762 0.23552
6: 0.66667 0.33333 0.23552 6: 0.66667 0.33333 0.23552
6: 0.95238 0.76190 0.23552 6: 0.95238 0.76190 0.23552
6: 0.09524 0.47619 0.23552 6: 0.09524 0.47619 0.23552
7: 0.14286 0.71429 0.25846 7: 0.14286 0.71429 0.25846
7: 0.28571 0.42857 0.25846 7: 0.28571 0.42857 0.25846
7: 0.57143 0.85714 0.25846 7: 0.57143 0.85714 0.25846
7: 0.42857 0.14286 0.25846 7: 0.42857 0.14286 0.25846
7: 0.71429 0.57143 0.25846 7: 0.71429 0.57143 0.25846
7: 0.85714 0.28571 0.25846 7: 0.85714 0.28571 0.25846
7: 0.38095 0.90476 0.22825 7: 0.38095 0.90476 0.22825
7: 0.52381 0.61905 0.22825 7: 0.52381 0.61905 0.22825
7: 0.80952 0.04762 0.22825 7: 0.80952 0.04762 0.22825
7: 0.66667 0.33333 0.22825 7: 0.66667 0.33333 0.22825
7: 0.95238 0.76190 0.22825 7: 0.95238 0.76190 0.22825
7: 0.09524 0.47619 0.22825 7: 0.09524 0.47619 0.22825
------------------------------------- -------------------------------------

Comparisons performed since June 6th, 2011: 19275

Attached are all the files used in the above tests.

compare-with-xtalcomp.zip

hongyi-zhao commented 9 months ago

I'm not sure if the following method is also suitable for doing the above work:

$ cat pymatgen_compare_structures.py 
import sys
from ase.io import read
from pymatgen.io.ase import AseAtomsAdaptor
from pymatgen.analysis.structure_matcher import StructureMatcher

def compare_structures(path1, path2):
    # Read the constructure
    structure1 = read(path1)
    structure2 = read(path2)

    # Convert ASE to Pymatgen structure
    s1 = AseAtomsAdaptor.get_structure(structure1)
    s2 = AseAtomsAdaptor.get_structure(structure2)

    # Initialize the StructureMatcher
    matcher = StructureMatcher()

    # Compare the structures
    are_similar = matcher.fit(s1, s2)

    print("Do the structures have the same underlying structure?", are_similar)

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Usage: script.py path_to_structure1 path_to_structure2")
    else:
        path1, path2 = sys.argv[1], sys.argv[2]
        compare_structures(path1, path2)

$ python pymatgen_compare_structures.py C12H14Mg7N6O14_18.00_degree_0.in C12H14Mg7N6O14_19.00_degree_0.in
Do the structures have the same underlying structure? True
hongyi-zhao commented 9 months ago

My some additional confusion/questions on the structure file generated by this package:

Take the following file as an example:

$ cat C12H14Mg7N6O14_19.00_degree_0.in 
#===============================================================================
# Created using the Atomic Simulation Environment (ASE)

# Thu Feb  1 10:44:50 2024

# Additional information:
#  C12H14Mg7N6O14
#  M = [1 0 // 0 1]
#  N = [3 -1 // -2 3]
#  angle = 19.0000 [degree]
#  stress = 0.0029 [%]
#  strain = 2.7032 [%]
#=======================================================
lattice_vector 8.3340652386876179 -0.0077660973470854 0.0000000000000000 
lattice_vector -4.1601259676547908 7.2219414975643001 0.0000000000000000 
lattice_vector 0.0000000000000000 0.0000000000000000 107.7038200577331253 
atom 1.3210815974721342 -0.0012257018622099 25.3021862852645221 N
atom -0.0872586025426797 2.4421505519315967 25.3021862852645221 N
atom 1.2937622189570579 4.8290049778868243 25.3021862852645221 N
atom 4.1140101458814202 4.8260902284257874 25.3021862852645221 N
atom 4.0775971491544247 -0.0037997082450866 25.3021862852645221 N
atom 5.4902916707470135 2.4369470723141426 25.3021862852645221 N
atom 1.2508436407331598 2.4112921223995096 25.3021862852645221 C
atom 1.9647987697004075 1.1719540242837005 25.3021862852645221 C
atom 1.9875278194526294 3.6844482819013908 25.3021862852645221 C
atom 3.4359310217087109 1.1704965768816242 25.3021862852645221 C
atom 1.9898598897833222 5.9720218502522151 25.3021862852645221 C
atom 5.4156497071681517 0.0246038367979405 25.3021862852645221 C
atom 4.1522391000607364 2.4085454801279549 25.3021862852645221 C
atom 3.4179113187914654 3.6830712141113180 25.3021862852645221 C
atom 3.4202425810508141 5.9706473311488848 25.3021862852645221 C
atom 6.1319586188674249 1.2626518165768608 25.3021862852645221 C
atom -0.0170190039300733 0.0296317945771006 25.3021862852645221 C
atom -0.7309765976555073 1.2689688402230452 25.3021862852645221 C
atom 2.3837924953789562 2.7475176877487519 31.0769333962615733 Mg
atom 0.0000000000000000 0.0000000000000000 32.0771991013232878 O
atom 1.1918961764800668 1.3737589057278894 30.0766676912000044 O
atom 0.0000000000000000 0.0000000000000000 33.0060063429976509 H
atom 1.1918961764800668 1.3737589057278894 29.1478604495256413 H
atom 4.7629806630928426 0.6829963888236524 31.0769333962615733 Mg
atom 2.9820428631519356 5.8404165874628573 31.0769333962615733 Mg
atom -0.5936460401079101 1.7191400869597471 31.0769333962615733 Mg
atom 5.3612310308658238 3.7758952885377592 31.0769333962615733 Mg
atom -2.3745838400488135 6.8765602855989494 31.0769333962615733 Mg
atom 0.0046043276650762 4.8120389866738495 31.0769333962615733 Mg
atom -1.7809377999409048 5.1574201986392021 32.0771991013232878 O
atom 0.5982503677729818 3.0928988997141054 32.0771991013232878 O
atom 1.1965007355459636 6.1857977994282107 32.0771991013232878 O
atom 2.9774385354868667 1.0283776007890066 32.0771991013232878 O
atom 3.5756889032598491 4.1212765005031127 32.0771991013232878 O
atom 5.9548770709737333 2.0567552015780133 32.0771991013232878 O
atom -0.5890416234608377 6.5311791043670908 30.0766676912000044 O
atom 1.7901465442530464 4.4666578054419928 30.0766676912000044 O
atom 6.5485228796808208 0.3376152075917973 30.0766676912000044 O
atom 4.1693347119669344 2.4021365065168960 30.0766676912000044 O
atom 4.7675850797399155 5.4950354062310014 30.0766676912000044 O
atom -1.1872919912338196 3.4382802046529877 30.0766676912000044 O
atom -1.7809377999409048 5.1574201986392021 33.0060063429976509 H
atom 0.5982503677729818 3.0928988997141054 33.0060063429976509 H
atom 1.1965007355459636 6.1857977994282107 33.0060063429976509 H
atom 2.9774385354868667 1.0283776007890066 33.0060063429976509 H
atom 3.5756889032598491 4.1212765005031127 33.0060063429976509 H
atom 5.9548770709737333 2.0567552015780133 33.0060063429976509 H
atom -0.5890416234608377 6.5311791043670908 29.1478604495256413 H
atom 1.7901465442530464 4.4666578054419928 29.1478604495256413 H
atom 6.5485228796808208 0.3376152075917973 29.1478604495256413 H
atom 4.1693347119669344 2.4021365065168960 29.1478604495256413 H
atom 4.7675850797399155 5.4950354062310014 29.1478604495256413 H
atom -1.1872919912338196 3.4382802046529877 29.1478604495256413 H
  1. How to accurately understand the meaning of the following symbols?
    #  M = [1 0 // 0 1]
    #  N = [3 -1 // -2 3]
  2. About the stress and strain:
    #  stress = 0.0029 [%]
    #  strain = 2.7032 [%]

    stress = 0.0029 [%]: Stress is usually not expressed as a percentage, but rather as a unit of force that should be applied; Therefore, I do not understand what is meant by this description here.

strain = 2.7032 [%]: This is a quantity typically expressed as a percentage, representing the relative change in the length of the material. However, for the 2D lattice studied here, we have two lattice vectors. So, which lattice vector is this strain referring to, or is there a further, more specific description standard?

romankempt commented 9 months ago

Hetbuilder uses XtalComp under the hood.

Regarding N/M: These are the supercell matrices to generate the super cell from the primitive unit which you put into the program. Please see the docs if there is some confusion.

Stress/strain are somewhat arbitrary terms in this context. Hetbuilder calculates no forces, only new lattices and tries to estimate how much the lattice and structure changes compared to the input lattice and structure. The change of the lattice is called stress, some average over the components of the transformation matrix that describes how much the individual lattice vectors have to change. The problem is that the relative change of lattice vectors becomes smaller for increasingly large unit cells, but the absolute change can still be quite large.

That's why I introduced the bond length strain at some point to more accurately reflect how much the atomic motif has to change in the new unit cell. This measure is fairly independent of the supercell size. The sum of both, which is just an arbitrary value, is called deformation. It is just meant as an indicator how much one has to deform the input structures to match the heterostructure.

hongyi-zhao commented 9 months ago

Hetbuilder uses XtalComp under the hood.

  1. As I've represented, pymatgen also can do the job.

  2. I created a PR, which let XtalComp use the latest version of spglib from its GitHub repository directly.

Regarding N/M: These are the supercell matrices to generate the super cell from the primitive unit which you put into the program. Please see the docs if there is some confusion.

I have reread the document and found the corresponding description here, as shown below:

image

Stress/strain are somewhat arbitrary terms in this context. [...] The sum of both, which is just an arbitrary value, is called deformation. [...] It is just meant as an indicator how much one has to deform the input structures to match the heterostructure.

Thank you for your valuable comments and explanations. So, if I want to use these physical properties in academic papers, such as stress, strain, and lattice mismatch, I must obtain the corresponding data based on subsequent calculations.