Skip to content

Commit

Permalink
Merge pull request #166 from Exabyte-io/feature/SOF-7497
Browse files Browse the repository at this point in the history
feature/SOF-7497 feat: 2D material grain boundary NB
  • Loading branch information
VsevolodX authored Nov 21, 2024
2 parents 58b5c2d + f000eb5 commit b4bf01c
Show file tree
Hide file tree
Showing 2 changed files with 323 additions and 0 deletions.
1 change: 1 addition & 0 deletions other/materials_designer/Introduction.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"\n",
"### 3.3. Planar Defects\n",
"#### [3.3.1. Grain Boundary in a 3D Crystal](create_grain_boundary_crystal.ipynb)\n",
"#### [3.3.2. Grain Boundary in a 2D Material](create_grain_boundary_film.ipynb)\n",
"\n",
"\n",
"## 4. Passivation.\n",
Expand Down
322 changes: 322 additions & 0 deletions other/materials_designer/create_grain_boundary_film.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,322 @@
{
"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",
"<h2 style=\"color:green\">Usage</h2>\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",
"<img src=\"https://i.imgur.com/QRgotXS.png\" alt=\"Edge Inclusion Tolerance\" width=\"400\"/>\n"
],
"metadata": {
"collapsed": false
},
"id": "a080006df3785cc5"
},
{
"cell_type": "code",
"outputs": [],
"source": [
"# Material selection\n",
"MATERIAL_INDEX = 0 # Index in the list of materials\n",
"\n",
"# Grain boundary parameters\n",
"TARGET_TWIST_ANGLE = 17.9 # 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 = 6 # 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(\"\", \"../../config.yml\")"
],
"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 utils.jupyterlite import get_materials\n",
"\n",
"materials = get_materials(globals())"
],
"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",
"material = materials[MATERIAL_INDEX]\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
}

0 comments on commit b4bf01c

Please sign in to comment.