From 1f9d44d2076097a36826345776238232749c1111 Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Sun, 29 Dec 2024 18:20:42 -0800 Subject: [PATCH 1/3] feat: add gb 2d nb --- .../grain_boundary_2d_boron_nitride.ipynb | 321 ++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 other/materials_designer/specific_examples/grain_boundary_2d_boron_nitride.ipynb diff --git a/other/materials_designer/specific_examples/grain_boundary_2d_boron_nitride.ipynb b/other/materials_designer/specific_examples/grain_boundary_2d_boron_nitride.ipynb new file mode 100644 index 00000000..014f99c1 --- /dev/null +++ b/other/materials_designer/specific_examples/grain_boundary_2d_boron_nitride.ipynb @@ -0,0 +1,321 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Create a 2D Surface Grain Boundary in a film\n", + "\n", + "Use commensurate lattice matching algorithm to create grain boundaries in 2D materials by finding appropriate twist angles between two orientations of the same material.\n", + "\n", + "

Usage

\n", + "\n", + "1. Make sure to select Input Material (in the outer runtime) before running the notebook.\n", + "1. Set notebook parameters in cell 1.1. below (or use the default values).\n", + "1. Click \"Run\" > \"Run All\" to run all cells.\n", + "1. Wait for the run to complete (depending on the parameters can take a few min).\n", + "1. Scroll down to view results.\n", + "\n", + "## Notes\n", + "\n", + "1. We perform commensurate lattice matching to find valid supercells that achieve the desired twist angle.\n", + "1. When the matching is finished, grain boundaries with angles close to the target are presented.\n", + "1. The algorithm searches for supercell matrices within specified size limits.\n", + "2. The two orientations are placed next to each other in the x-direction with a gap in between.\n", + "1. Atoms on the edge of the left orientation are handled to overlap with the right orientation in the interfacial region.\n", + "1. For more information, see the [Introduction](Introduction.ipynb) notebook.\n" + ], + "metadata": { + "collapsed": false + }, + "id": "415ed707e27a6c8e" + }, + { + "cell_type": "markdown", + "source": [ + "## 1. Prepare the Environment\n", + "### 1.1. Set up the notebook\n", + "Set the following flags to control the notebook behavior\n", + "For more information on the parameters and algorithm, refer to [Grain Boundary Builder Source](https://github.com/Exabyte-io/made/blob/35b9f318f5d667e0f5af023f3178bc4404317ab0/src/py/mat3ra/made/tools/build/grain_boundary/builders.py#L103)\n", + "`EDGE_INCLUSION_TOLERANCE` is a fine-tuning parameter that controls the inclusion of the edge atoms for both orientations in the gap.\n", + "For example of Graphene at 17.9 degrees: orange and green atoms are present with the value of 0.5 Angstroms, with value of 0, they will not be included.\n", + "\"Edge\n" + ], + "metadata": { + "collapsed": false + }, + "id": "a080006df3785cc5" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "# Material selection\n", + "MATERIAL_NAME = \"Boron_Nitride\" # Name of the material to import from Standata\n", + "\n", + "# Grain boundary parameters\n", + "TARGET_TWIST_ANGLE = 9.0 # in degrees\n", + "BOUNDARY_GAP = 2.0 # Gap between two orientations in X direction, in Angstroms\n", + "XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]] # Supercell matrix to be applied to each of the orientations before matching\n", + "\n", + "# Search algorithm parameters\n", + "MAX_REPETITION = None # Maximum supercell matrix element value\n", + "ANGLE_TOLERANCE = 2.5 # in degrees\n", + "RETURN_FIRST_MATCH = True # If True, returns first solution within tolerance\n", + "\n", + "# Distance tolerance for two atoms to be considered too close. \n", + "# Used when merging two orientations to remove the atoms of the first one. \n", + "# Should be less than the expected bond length\n", + "DISTANCE_TOLERANCE = 1.2 # in Angstroms\n", + "\n", + "# How much to expand inclusion of the edge atoms for both orientations and fill in the gap region.\n", + "# A fine-tuning parameter\n", + "EDGE_INCLUSION_TOLERANCE = 0.5 # in Angstroms\n", + "\n", + "# Visualization parameters\n", + "SHOW_INTERMEDIATE_STEPS = True\n", + "CELL_REPETITIONS_FOR_VISUALIZATION = [3, 3, 1]" + ], + "metadata": { + "collapsed": false + }, + "id": "338ee3c51155e086", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "### 1.2. Install packages\n", + "The step executes only in Pyodide environment. For other environments, the packages should be installed via `pip install`." + ], + "metadata": { + "collapsed": false + }, + "id": "6463f9bbcd3be7c7" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "import sys\n", + "\n", + "if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install('mat3ra-api-examples', deps=False)\n", + " from utils.jupyterlite import install_packages\n", + "\n", + " await install_packages(\"specific_examples\")" + ], + "metadata": { + "collapsed": false + }, + "id": "7e22d1f4da825575", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "### 1.3. Load and preview input material" + ], + "metadata": { + "collapsed": false + }, + "id": "4a1cfe15caa44c3e" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "from mat3ra.standata.materials import Materials\n", + "from mat3ra.made.material import Material\n", + "\n", + "material = Material(Materials.get_by_name_first_match(MATERIAL_NAME))" + ], + "metadata": { + "collapsed": false + }, + "id": "a1635c31132962f6", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "## 2. Prepare Material\n", + "### 2.1. Select and visualize initial material" + ], + "metadata": { + "collapsed": false + }, + "id": "32b3ad775543b06f" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "from utils.visualize import visualize_materials\n", + "\n", + "if SHOW_INTERMEDIATE_STEPS:\n", + " visualize_materials(material, repetitions=CELL_REPETITIONS_FOR_VISUALIZATION)" + ], + "metadata": { + "collapsed": false + }, + "id": "61f0870d8104cd21", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "## 3. Generate Surface Grain Boundary\n", + "### 3.1. Set up grain boundary configuration and builder\n" + ], + "metadata": { + "collapsed": false + }, + "id": "34d6c7a337f1e40b" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "from mat3ra.made.tools.build.grain_boundary import (\n", + " SurfaceGrainBoundaryConfiguration,\n", + " SurfaceGrainBoundaryBuilderParameters,\n", + " SurfaceGrainBoundaryBuilder\n", + ")\n", + "\n", + "config = SurfaceGrainBoundaryConfiguration(\n", + " film=material,\n", + " twist_angle=TARGET_TWIST_ANGLE,\n", + " distance_z=BOUNDARY_GAP,\n", + " gap=BOUNDARY_GAP,\n", + " xy_supercell_matrix=XY_SUPERCELL_MATRIX\n", + ")\n", + "\n", + "params = SurfaceGrainBoundaryBuilderParameters(\n", + " max_supercell_matrix_int=MAX_REPETITION,\n", + " angle_tolerance=ANGLE_TOLERANCE,\n", + " return_first_match=RETURN_FIRST_MATCH,\n", + " edge_inclusion_tolerance=EDGE_INCLUSION_TOLERANCE,\n", + " distance_tolerance=DISTANCE_TOLERANCE\n", + ")\n", + "\n", + "builder = SurfaceGrainBoundaryBuilder(build_parameters=params)" + ], + "metadata": { + "collapsed": false + }, + "id": "33a2c8a9be436745", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "### 3.2. Generate and analyze grain boundaries\n" + ], + "metadata": { + "collapsed": false + }, + "id": "79e9378bf5e144d4" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "from utils.plot import plot_twisted_interface_solutions\n", + "\n", + "grain_boundaries = builder.get_materials(config)\n", + "\n", + "print(f\"\\nFound {len(grain_boundaries)} possible structures\")\n", + "for i, gb in enumerate(grain_boundaries):\n", + " actual_angle = gb.metadata.get(\"actual_twist_angle\", \"unknown\")\n", + " print(f\"\\nGrain Boundary {i + 1}:\")\n", + " print(f\"Actual twist angle: {actual_angle}°\")\n", + " print(f\"Number of atoms: {len(gb.basis.elements.ids)}\")\n", + "\n", + "if len(grain_boundaries) > 0:\n", + " plot_twisted_interface_solutions(grain_boundaries)" + ], + "metadata": { + "collapsed": false + }, + "id": "d7007fe825463e5a", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "## 4. Preview the selected grain boundary\n", + "By default, the first grain boundary is selected. You can change the selection by changing the `selected_structure` index." + ], + "metadata": { + "collapsed": false + }, + "id": "8b2f0574a20089a5" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "selected_structure = grain_boundaries[0]\n", + "actual_angle = selected_structure.metadata.get(\"build\").get(\"configuration\").get(\"actual_twist_angle\")\n", + "print(f\"Target angle: {TARGET_TWIST_ANGLE}°\")\n", + "print(f\"Actual angle: {actual_angle}°\")\n", + "print(f\"Number of atoms: {len(selected_structure.basis.elements.ids)}\")\n", + "\n", + "visualize_materials(selected_structure, repetitions=[1, 1, 1])\n", + "visualize_materials(selected_structure, repetitions=[1, 1, 1], rotation=\"-90x\")" + ], + "metadata": { + "collapsed": false + }, + "id": "7f558a8e9d417cef", + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "### 5. Pass data to the outside runtime\n" + ], + "metadata": { + "collapsed": false + }, + "id": "afcc004c5878b56f" + }, + { + "cell_type": "code", + "outputs": [], + "source": [ + "from utils.jupyterlite import set_materials\n", + "\n", + "set_materials(selected_structure)" + ], + "metadata": { + "collapsed": false + }, + "id": "20e46167358d63", + "execution_count": null + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From e3dc9281a3c2daa01e863d219e0a839228d1edde Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Sun, 29 Dec 2024 19:41:32 -0800 Subject: [PATCH 2/3] update: working params for gb 2d nb --- .../grain_boundary_2d_boron_nitride.ipynb | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/other/materials_designer/specific_examples/grain_boundary_2d_boron_nitride.ipynb b/other/materials_designer/specific_examples/grain_boundary_2d_boron_nitride.ipynb index 014f99c1..da4ad3df 100644 --- a/other/materials_designer/specific_examples/grain_boundary_2d_boron_nitride.ipynb +++ b/other/materials_designer/specific_examples/grain_boundary_2d_boron_nitride.ipynb @@ -54,8 +54,8 @@ "\n", "# Grain boundary parameters\n", "TARGET_TWIST_ANGLE = 9.0 # in degrees\n", - "BOUNDARY_GAP = 2.0 # Gap between two orientations in X direction, in Angstroms\n", - "XY_SUPERCELL_MATRIX = [[1, 0], [0, 1]] # Supercell matrix to be applied to each of the orientations before matching\n", + "BOUNDARY_GAP = 0.0 # Gap between two orientations in X direction, in Angstroms\n", + "XY_SUPERCELL_MATRIX = [[1, 0], [0, 2]] # Supercell matrix to be applied to each of the orientations before matching\n", "\n", "# Search algorithm parameters\n", "MAX_REPETITION = None # Maximum supercell matrix element value\n", @@ -65,11 +65,11 @@ "# Distance tolerance for two atoms to be considered too close. \n", "# Used when merging two orientations to remove the atoms of the first one. \n", "# Should be less than the expected bond length\n", - "DISTANCE_TOLERANCE = 1.2 # in Angstroms\n", + "DISTANCE_TOLERANCE = 1.43 # in Angstroms\n", "\n", "# How much to expand inclusion of the edge atoms for both orientations and fill in the gap region.\n", "# A fine-tuning parameter\n", - "EDGE_INCLUSION_TOLERANCE = 0.5 # in Angstroms\n", + "EDGE_INCLUSION_TOLERANCE = 0 # in Angstroms\n", "\n", "# Visualization parameters\n", "SHOW_INTERMEDIATE_STEPS = True\n", @@ -257,12 +257,16 @@ "cell_type": "code", "outputs": [], "source": [ + "from mat3ra.made.tools.build.supercell import create_supercell\n", + "\n", "selected_structure = grain_boundaries[0]\n", "actual_angle = selected_structure.metadata.get(\"build\").get(\"configuration\").get(\"actual_twist_angle\")\n", "print(f\"Target angle: {TARGET_TWIST_ANGLE}°\")\n", "print(f\"Actual angle: {actual_angle}°\")\n", "print(f\"Number of atoms: {len(selected_structure.basis.elements.ids)}\")\n", "\n", + "selected_structure = create_supercell(selected_structure, [[0,-1,0],[1,0,0],[0,0,1]])\n", + "\n", "visualize_materials(selected_structure, repetitions=[1, 1, 1])\n", "visualize_materials(selected_structure, repetitions=[1, 1, 1], rotation=\"-90x\")" ], @@ -295,6 +299,16 @@ }, "id": "20e46167358d63", "execution_count": null + }, + { + "cell_type": "code", + "outputs": [], + "source": [], + "metadata": { + "collapsed": false + }, + "id": "f0841e1b8e705c44", + "execution_count": null } ], "metadata": { From bdc8d43d0c91a65b0af32d501ffc7bbbeda1cf9c Mon Sep 17 00:00:00 2001 From: VsevolodX <79542055+VsevolodX@users.noreply.github.com> Date: Sun, 29 Dec 2024 19:59:49 -0800 Subject: [PATCH 3/3] update: cleanups + description --- .../grain_boundary_2d_boron_nitride.ipynb | 47 ++++++------------- 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/other/materials_designer/specific_examples/grain_boundary_2d_boron_nitride.ipynb b/other/materials_designer/specific_examples/grain_boundary_2d_boron_nitride.ipynb index da4ad3df..7817958e 100644 --- a/other/materials_designer/specific_examples/grain_boundary_2d_boron_nitride.ipynb +++ b/other/materials_designer/specific_examples/grain_boundary_2d_boron_nitride.ipynb @@ -3,26 +3,20 @@ { "cell_type": "markdown", "source": [ - "# Create a 2D Surface Grain Boundary in a film\n", + "# A 2D grain boundary in Boron Nitride\n", "\n", - "Use commensurate lattice matching algorithm to create grain boundaries in 2D materials by finding appropriate twist angles between two orientations of the same material.\n", + "## 0. Introduction\n", "\n", - "

Usage

\n", + "This notebook demonstrates how to generate a 2D grain boundary in Boron Nitride, following the example in the manuscript:\n", "\n", - "1. Make sure to select Input Material (in the outer runtime) before running the notebook.\n", - "1. Set notebook parameters in cell 1.1. below (or use the default values).\n", - "1. Click \"Run\" > \"Run All\" to run all cells.\n", - "1. Wait for the run to complete (depending on the parameters can take a few min).\n", - "1. Scroll down to view results.\n", + "> **Qiucheng Li, Xiaolong Zou, Mengxi Liu, Jingyu Sun, Yabo Gao, Yue Qi, Xiebo Zhou, Boris I. Yakobson, Yanfeng Zhang, and Zhongfan Liu**\n", + "> \"Grain Boundary Structures and Electronic Properties of Hexagonal Boron Nitride on Cu(111)\"\n", + "> *ACS Nano* **2015** 9 (6), 6308-6315\n", + "> [DOI: 10.1021/acs.nanolett.5b01852](https://doi.org/10.1021/acs.nanolett.5b01852)\n", "\n", - "## Notes\n", + "Reproducing the material from Figure 2. c:\n", "\n", - "1. We perform commensurate lattice matching to find valid supercells that achieve the desired twist angle.\n", - "1. When the matching is finished, grain boundaries with angles close to the target are presented.\n", - "1. The algorithm searches for supercell matrices within specified size limits.\n", - "2. The two orientations are placed next to each other in the x-direction with a gap in between.\n", - "1. Atoms on the edge of the left orientation are handled to overlap with the right orientation in the interfacial region.\n", - "1. For more information, see the [Introduction](Introduction.ipynb) notebook.\n" + "\"Grain" ], "metadata": { "collapsed": false @@ -59,7 +53,7 @@ "\n", "# Search algorithm parameters\n", "MAX_REPETITION = None # Maximum supercell matrix element value\n", - "ANGLE_TOLERANCE = 2.5 # in degrees\n", + "ANGLE_TOLERANCE = 0.5 # in degrees\n", "RETURN_FIRST_MATCH = True # If True, returns first solution within tolerance\n", "\n", "# Distance tolerance for two atoms to be considered too close. \n", @@ -69,7 +63,7 @@ "\n", "# How much to expand inclusion of the edge atoms for both orientations and fill in the gap region.\n", "# A fine-tuning parameter\n", - "EDGE_INCLUSION_TOLERANCE = 0 # in Angstroms\n", + "EDGE_INCLUSION_TOLERANCE = 0.0 # in Angstroms\n", "\n", "# Visualization parameters\n", "SHOW_INTERMEDIATE_STEPS = True\n", @@ -257,16 +251,13 @@ "cell_type": "code", "outputs": [], "source": [ - "from mat3ra.made.tools.build.supercell import create_supercell\n", - "\n", "selected_structure = grain_boundaries[0]\n", + "\n", "actual_angle = selected_structure.metadata.get(\"build\").get(\"configuration\").get(\"actual_twist_angle\")\n", "print(f\"Target angle: {TARGET_TWIST_ANGLE}°\")\n", "print(f\"Actual angle: {actual_angle}°\")\n", "print(f\"Number of atoms: {len(selected_structure.basis.elements.ids)}\")\n", "\n", - "selected_structure = create_supercell(selected_structure, [[0,-1,0],[1,0,0],[0,0,1]])\n", - "\n", "visualize_materials(selected_structure, repetitions=[1, 1, 1])\n", "visualize_materials(selected_structure, repetitions=[1, 1, 1], rotation=\"-90x\")" ], @@ -290,25 +281,15 @@ "cell_type": "code", "outputs": [], "source": [ - "from utils.jupyterlite import set_materials\n", + "from utils.jupyterlite import download_content_to_file\n", "\n", - "set_materials(selected_structure)" + "download_content_to_file(selected_structure, \"grain_boundary_2d_boron_nitride.json\")" ], "metadata": { "collapsed": false }, "id": "20e46167358d63", "execution_count": null - }, - { - "cell_type": "code", - "outputs": [], - "source": [], - "metadata": { - "collapsed": false - }, - "id": "f0841e1b8e705c44", - "execution_count": null } ], "metadata": {