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",
+ "
\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"
+ "
"
],
"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": {