Skip to content

Commit d2df8d4

Browse files
authored
Merge pull request #190 from Exabyte-io/feature/SOF-7523
Feature/SOF-7523 GB 2D h-BN NB
2 parents 3dcd0e0 + bdc8d43 commit d2df8d4

File tree

1 file changed

+316
-0
lines changed

1 file changed

+316
-0
lines changed
Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"source": [
6+
"# A 2D grain boundary in Boron Nitride\n",
7+
"\n",
8+
"## 0. Introduction\n",
9+
"\n",
10+
"This notebook demonstrates how to generate a 2D grain boundary in Boron Nitride, following the example in the manuscript:\n",
11+
"\n",
12+
"> **Qiucheng Li, Xiaolong Zou, Mengxi Liu, Jingyu Sun, Yabo Gao, Yue Qi, Xiebo Zhou, Boris I. Yakobson, Yanfeng Zhang, and Zhongfan Liu**\n",
13+
"> \"Grain Boundary Structures and Electronic Properties of Hexagonal Boron Nitride on Cu(111)\"\n",
14+
"> *ACS Nano* **2015** 9 (6), 6308-6315\n",
15+
"> [DOI: 10.1021/acs.nanolett.5b01852](https://doi.org/10.1021/acs.nanolett.5b01852)\n",
16+
"\n",
17+
"Reproducing the material from Figure 2. c:\n",
18+
"\n",
19+
"<img src=\"https://i.imgur.com/NF79OUq.png\" alt=\"Grain Boundary in Boron Nitride\" width=\"400\"/>"
20+
],
21+
"metadata": {
22+
"collapsed": false
23+
},
24+
"id": "415ed707e27a6c8e"
25+
},
26+
{
27+
"cell_type": "markdown",
28+
"source": [
29+
"## 1. Prepare the Environment\n",
30+
"### 1.1. Set up the notebook\n",
31+
"Set the following flags to control the notebook behavior\n",
32+
"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",
33+
"`EDGE_INCLUSION_TOLERANCE` is a fine-tuning parameter that controls the inclusion of the edge atoms for both orientations in the gap.\n",
34+
"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",
35+
"<img src=\"https://i.imgur.com/QRgotXS.png\" alt=\"Edge Inclusion Tolerance\" width=\"400\"/>\n"
36+
],
37+
"metadata": {
38+
"collapsed": false
39+
},
40+
"id": "a080006df3785cc5"
41+
},
42+
{
43+
"cell_type": "code",
44+
"outputs": [],
45+
"source": [
46+
"# Material selection\n",
47+
"MATERIAL_NAME = \"Boron_Nitride\" # Name of the material to import from Standata\n",
48+
"\n",
49+
"# Grain boundary parameters\n",
50+
"TARGET_TWIST_ANGLE = 9.0 # in degrees\n",
51+
"BOUNDARY_GAP = 0.0 # Gap between two orientations in X direction, in Angstroms\n",
52+
"XY_SUPERCELL_MATRIX = [[1, 0], [0, 2]] # Supercell matrix to be applied to each of the orientations before matching\n",
53+
"\n",
54+
"# Search algorithm parameters\n",
55+
"MAX_REPETITION = None # Maximum supercell matrix element value\n",
56+
"ANGLE_TOLERANCE = 0.5 # in degrees\n",
57+
"RETURN_FIRST_MATCH = True # If True, returns first solution within tolerance\n",
58+
"\n",
59+
"# Distance tolerance for two atoms to be considered too close. \n",
60+
"# Used when merging two orientations to remove the atoms of the first one. \n",
61+
"# Should be less than the expected bond length\n",
62+
"DISTANCE_TOLERANCE = 1.43 # in Angstroms\n",
63+
"\n",
64+
"# How much to expand inclusion of the edge atoms for both orientations and fill in the gap region.\n",
65+
"# A fine-tuning parameter\n",
66+
"EDGE_INCLUSION_TOLERANCE = 0.0 # in Angstroms\n",
67+
"\n",
68+
"# Visualization parameters\n",
69+
"SHOW_INTERMEDIATE_STEPS = True\n",
70+
"CELL_REPETITIONS_FOR_VISUALIZATION = [3, 3, 1]"
71+
],
72+
"metadata": {
73+
"collapsed": false
74+
},
75+
"id": "338ee3c51155e086",
76+
"execution_count": null
77+
},
78+
{
79+
"cell_type": "markdown",
80+
"source": [
81+
"### 1.2. Install packages\n",
82+
"The step executes only in Pyodide environment. For other environments, the packages should be installed via `pip install`."
83+
],
84+
"metadata": {
85+
"collapsed": false
86+
},
87+
"id": "6463f9bbcd3be7c7"
88+
},
89+
{
90+
"cell_type": "code",
91+
"outputs": [],
92+
"source": [
93+
"import sys\n",
94+
"\n",
95+
"if sys.platform == \"emscripten\":\n",
96+
" import micropip\n",
97+
"\n",
98+
" await micropip.install('mat3ra-api-examples', deps=False)\n",
99+
" from utils.jupyterlite import install_packages\n",
100+
"\n",
101+
" await install_packages(\"specific_examples\")"
102+
],
103+
"metadata": {
104+
"collapsed": false
105+
},
106+
"id": "7e22d1f4da825575",
107+
"execution_count": null
108+
},
109+
{
110+
"cell_type": "markdown",
111+
"source": [
112+
"### 1.3. Load and preview input material"
113+
],
114+
"metadata": {
115+
"collapsed": false
116+
},
117+
"id": "4a1cfe15caa44c3e"
118+
},
119+
{
120+
"cell_type": "code",
121+
"outputs": [],
122+
"source": [
123+
"from mat3ra.standata.materials import Materials\n",
124+
"from mat3ra.made.material import Material\n",
125+
"\n",
126+
"material = Material(Materials.get_by_name_first_match(MATERIAL_NAME))"
127+
],
128+
"metadata": {
129+
"collapsed": false
130+
},
131+
"id": "a1635c31132962f6",
132+
"execution_count": null
133+
},
134+
{
135+
"cell_type": "markdown",
136+
"source": [
137+
"## 2. Prepare Material\n",
138+
"### 2.1. Select and visualize initial material"
139+
],
140+
"metadata": {
141+
"collapsed": false
142+
},
143+
"id": "32b3ad775543b06f"
144+
},
145+
{
146+
"cell_type": "code",
147+
"outputs": [],
148+
"source": [
149+
"from utils.visualize import visualize_materials\n",
150+
"\n",
151+
"if SHOW_INTERMEDIATE_STEPS:\n",
152+
" visualize_materials(material, repetitions=CELL_REPETITIONS_FOR_VISUALIZATION)"
153+
],
154+
"metadata": {
155+
"collapsed": false
156+
},
157+
"id": "61f0870d8104cd21",
158+
"execution_count": null
159+
},
160+
{
161+
"cell_type": "markdown",
162+
"source": [
163+
"## 3. Generate Surface Grain Boundary\n",
164+
"### 3.1. Set up grain boundary configuration and builder\n"
165+
],
166+
"metadata": {
167+
"collapsed": false
168+
},
169+
"id": "34d6c7a337f1e40b"
170+
},
171+
{
172+
"cell_type": "code",
173+
"outputs": [],
174+
"source": [
175+
"from mat3ra.made.tools.build.grain_boundary import (\n",
176+
" SurfaceGrainBoundaryConfiguration,\n",
177+
" SurfaceGrainBoundaryBuilderParameters,\n",
178+
" SurfaceGrainBoundaryBuilder\n",
179+
")\n",
180+
"\n",
181+
"config = SurfaceGrainBoundaryConfiguration(\n",
182+
" film=material,\n",
183+
" twist_angle=TARGET_TWIST_ANGLE,\n",
184+
" distance_z=BOUNDARY_GAP,\n",
185+
" gap=BOUNDARY_GAP,\n",
186+
" xy_supercell_matrix=XY_SUPERCELL_MATRIX\n",
187+
")\n",
188+
"\n",
189+
"params = SurfaceGrainBoundaryBuilderParameters(\n",
190+
" max_supercell_matrix_int=MAX_REPETITION,\n",
191+
" angle_tolerance=ANGLE_TOLERANCE,\n",
192+
" return_first_match=RETURN_FIRST_MATCH,\n",
193+
" edge_inclusion_tolerance=EDGE_INCLUSION_TOLERANCE,\n",
194+
" distance_tolerance=DISTANCE_TOLERANCE\n",
195+
")\n",
196+
"\n",
197+
"builder = SurfaceGrainBoundaryBuilder(build_parameters=params)"
198+
],
199+
"metadata": {
200+
"collapsed": false
201+
},
202+
"id": "33a2c8a9be436745",
203+
"execution_count": null
204+
},
205+
{
206+
"cell_type": "markdown",
207+
"source": [
208+
"### 3.2. Generate and analyze grain boundaries\n"
209+
],
210+
"metadata": {
211+
"collapsed": false
212+
},
213+
"id": "79e9378bf5e144d4"
214+
},
215+
{
216+
"cell_type": "code",
217+
"outputs": [],
218+
"source": [
219+
"from utils.plot import plot_twisted_interface_solutions\n",
220+
"\n",
221+
"grain_boundaries = builder.get_materials(config)\n",
222+
"\n",
223+
"print(f\"\\nFound {len(grain_boundaries)} possible structures\")\n",
224+
"for i, gb in enumerate(grain_boundaries):\n",
225+
" actual_angle = gb.metadata.get(\"actual_twist_angle\", \"unknown\")\n",
226+
" print(f\"\\nGrain Boundary {i + 1}:\")\n",
227+
" print(f\"Actual twist angle: {actual_angle}°\")\n",
228+
" print(f\"Number of atoms: {len(gb.basis.elements.ids)}\")\n",
229+
"\n",
230+
"if len(grain_boundaries) > 0:\n",
231+
" plot_twisted_interface_solutions(grain_boundaries)"
232+
],
233+
"metadata": {
234+
"collapsed": false
235+
},
236+
"id": "d7007fe825463e5a",
237+
"execution_count": null
238+
},
239+
{
240+
"cell_type": "markdown",
241+
"source": [
242+
"## 4. Preview the selected grain boundary\n",
243+
"By default, the first grain boundary is selected. You can change the selection by changing the `selected_structure` index."
244+
],
245+
"metadata": {
246+
"collapsed": false
247+
},
248+
"id": "8b2f0574a20089a5"
249+
},
250+
{
251+
"cell_type": "code",
252+
"outputs": [],
253+
"source": [
254+
"selected_structure = grain_boundaries[0]\n",
255+
"\n",
256+
"actual_angle = selected_structure.metadata.get(\"build\").get(\"configuration\").get(\"actual_twist_angle\")\n",
257+
"print(f\"Target angle: {TARGET_TWIST_ANGLE}°\")\n",
258+
"print(f\"Actual angle: {actual_angle}°\")\n",
259+
"print(f\"Number of atoms: {len(selected_structure.basis.elements.ids)}\")\n",
260+
"\n",
261+
"visualize_materials(selected_structure, repetitions=[1, 1, 1])\n",
262+
"visualize_materials(selected_structure, repetitions=[1, 1, 1], rotation=\"-90x\")"
263+
],
264+
"metadata": {
265+
"collapsed": false
266+
},
267+
"id": "7f558a8e9d417cef",
268+
"execution_count": null
269+
},
270+
{
271+
"cell_type": "markdown",
272+
"source": [
273+
"### 5. Pass data to the outside runtime\n"
274+
],
275+
"metadata": {
276+
"collapsed": false
277+
},
278+
"id": "afcc004c5878b56f"
279+
},
280+
{
281+
"cell_type": "code",
282+
"outputs": [],
283+
"source": [
284+
"from utils.jupyterlite import download_content_to_file\n",
285+
"\n",
286+
"download_content_to_file(selected_structure, \"grain_boundary_2d_boron_nitride.json\")"
287+
],
288+
"metadata": {
289+
"collapsed": false
290+
},
291+
"id": "20e46167358d63",
292+
"execution_count": null
293+
}
294+
],
295+
"metadata": {
296+
"kernelspec": {
297+
"display_name": "Python 3",
298+
"language": "python",
299+
"name": "python3"
300+
},
301+
"language_info": {
302+
"codemirror_mode": {
303+
"name": "ipython",
304+
"version": 2
305+
},
306+
"file_extension": ".py",
307+
"mimetype": "text/x-python",
308+
"name": "python",
309+
"nbconvert_exporter": "python",
310+
"pygments_lexer": "ipython2",
311+
"version": "2.7.6"
312+
}
313+
},
314+
"nbformat": 4,
315+
"nbformat_minor": 5
316+
}

0 commit comments

Comments
 (0)