Skip to content

Commit 8dc99ab

Browse files
authored
Merge pull request #191 from Exabyte-io/feature/SOF-7511
feature/SOF-7511 Graphene edge perturbation nb
2 parents 06642f7 + 7533baa commit 8dc99ab

File tree

1 file changed

+337
-0
lines changed

1 file changed

+337
-0
lines changed
Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"source": [
6+
"# Ripple perturbation of a graphene sheet.\n",
7+
"\n",
8+
"## 0. Introduction\n",
9+
"\n",
10+
"This notebook demonstrates how to recreate a material from the following manuscript:\n",
11+
"\n",
12+
"> Thompson-Flagg, R. C., Moura, M. J. B., & Marder, M.\n",
13+
"> Rippling of graphene. \n",
14+
"> EPL (Europhysics Letters), 85(4), 46002. 2009\n",
15+
"> [DOI: 10.1209/0295-5075/85/46002](https://doi.org/10.1209/0295-5075/85/46002)\n",
16+
"\n",
17+
"\n",
18+
"Recreating material from Fig. 1:\n",
19+
"\n",
20+
"<img src=\"https://i.imgur.com/p1Tvz5t.png\" alt=\"Rippling of graphene\" width=\"400\"/>\n"
21+
],
22+
"metadata": {
23+
"collapsed": false
24+
},
25+
"id": "367a698b29e22bd7"
26+
},
27+
{
28+
"cell_type": "markdown",
29+
"source": [
30+
"## 1. Prepare the Environment"
31+
],
32+
"metadata": {
33+
"collapsed": false
34+
},
35+
"id": "193a4e6a78fd5bd7"
36+
},
37+
{
38+
"cell_type": "markdown",
39+
"source": [
40+
"### 1.1. Install Packages\n",
41+
"The step executes only in Pyodide environment. For other environments, the packages should be installed via `pip install` (see [README](../../README.ipynb))."
42+
],
43+
"metadata": {
44+
"collapsed": false
45+
},
46+
"id": "f38b2711726e5859"
47+
},
48+
{
49+
"cell_type": "code",
50+
"outputs": [],
51+
"source": [
52+
"import sys\n",
53+
"\n",
54+
"if sys.platform == \"emscripten\":\n",
55+
" import micropip\n",
56+
"\n",
57+
" await micropip.install('mat3ra-api-examples', deps=False)\n",
58+
" from utils.jupyterlite import install_packages\n",
59+
"\n",
60+
" await install_packages(\"specific-examples\")"
61+
],
62+
"metadata": {
63+
"collapsed": false
64+
},
65+
"id": "7a6e28cfae1a7b46",
66+
"execution_count": null
67+
},
68+
{
69+
"cell_type": "markdown",
70+
"source": [
71+
"### 1.2. Set Nanoribbon and Perturbation Parameters"
72+
],
73+
"metadata": {
74+
"collapsed": false
75+
},
76+
"id": "11db992e02891067"
77+
},
78+
{
79+
"cell_type": "code",
80+
"outputs": [],
81+
"source": [
82+
"# Set whether to preserve geodesic distance and scale the cell accordingly to match PBC\n",
83+
"PRESERVE_GEODESIC_DISTANCE = False\n",
84+
"\n",
85+
"NANORIBBON_SIZE = 40 # in unit cells, lateral width and length of the nanoribbon\n",
86+
"VACUUM_SIZE = 10 # in unit cells, lateral width and length of the vacuum region\n",
87+
"\n",
88+
"# Set whether to use Cartesian coordinates for the perturbation function\n",
89+
"USE_CARTESIAN_COORDINATES = False\n",
90+
"MATERIAL_NAME = \"Graphene\""
91+
],
92+
"metadata": {
93+
"collapsed": false
94+
},
95+
"id": "a40d7b697c413113",
96+
"execution_count": null
97+
},
98+
{
99+
"cell_type": "markdown",
100+
"source": [
101+
"### 1.3. Define Custom Perturbation Function\n",
102+
"Provide a [SymPy](https://docs.sympy.org/latest/tutorials/intro-tutorial/intro.html) expression for the perturbation function. The expression should be a function of `x`, `y` and `z` variables."
103+
],
104+
"metadata": {
105+
"collapsed": false
106+
},
107+
"id": "e6a19c741406eafe"
108+
},
109+
{
110+
"cell_type": "code",
111+
"outputs": [],
112+
"source": [
113+
"import sympy as sp\n",
114+
"\n",
115+
"# Variables for the perturbation function (for SymPy)\n",
116+
"variable_names = [\"x\", \"y\", \"z\"]\n",
117+
"x, y, z = sp.symbols(variable_names)\n",
118+
"\n",
119+
"# Set the parameters for the perturbation function\n",
120+
"AMPLITUDE = 0.09 # Ripple amplitude\n",
121+
"WAVELENGTH = 0.2 # Wavelength of ripples\n",
122+
"EDGE_WIDTH = 0.25 # Width of edge effect\n",
123+
"PHASE_X = 0.0 # Phase shift for x direction\n",
124+
"PHASE_Y = sp.pi/2 # Phase shift for y direction\n",
125+
"\n",
126+
"# Create edge masks for both x and y using polynomial functions\n",
127+
"left_edge_x = sp.Max(0, (EDGE_WIDTH - x) / EDGE_WIDTH)\n",
128+
"right_edge_x = sp.Max(0, (x - (1 - EDGE_WIDTH)) / EDGE_WIDTH)\n",
129+
"left_edge_y = sp.Max(0, (EDGE_WIDTH - y) / EDGE_WIDTH)\n",
130+
"right_edge_y = sp.Max(0, (y - (1 - EDGE_WIDTH)) / EDGE_WIDTH)\n",
131+
"\n",
132+
"# Combine edge masks\n",
133+
"edge_mask_x = left_edge_x + right_edge_x\n",
134+
"edge_mask_y = left_edge_y + right_edge_y\n",
135+
"edge_mask = edge_mask_x + edge_mask_y\n",
136+
"\n",
137+
"# Wave pattern\n",
138+
"wave_pattern = (\n",
139+
" sp.sin(2 * sp.pi * x / WAVELENGTH + PHASE_X) * \n",
140+
" sp.sin(2 * sp.pi * y / WAVELENGTH + PHASE_Y)\n",
141+
")\n",
142+
"\n",
143+
"# Combine waves with edge mask\n",
144+
"custom_sympy_function = AMPLITUDE * wave_pattern * edge_mask"
145+
],
146+
"metadata": {
147+
"collapsed": false
148+
},
149+
"id": "203911c2413c7447",
150+
"execution_count": null
151+
},
152+
{
153+
"cell_type": "markdown",
154+
"source": [
155+
"### 1.4. Get input materials"
156+
],
157+
"metadata": {
158+
"collapsed": false
159+
},
160+
"id": "edf02101e27a2742"
161+
},
162+
{
163+
"cell_type": "code",
164+
"outputs": [],
165+
"source": [
166+
"from mat3ra.standata.materials import Materials\n",
167+
"from mat3ra.made.material import Material\n",
168+
"\n",
169+
"material = Material(Materials.get_by_name_first_match(MATERIAL_NAME))"
170+
],
171+
"metadata": {
172+
"collapsed": false
173+
},
174+
"id": "e0c53233ce728cc1",
175+
"execution_count": null
176+
},
177+
{
178+
"cell_type": "markdown",
179+
"source": [
180+
"### 1.5. Create and preview Nanoribbon"
181+
],
182+
"metadata": {
183+
"collapsed": false
184+
},
185+
"id": "cf29b7f6fe114d8f"
186+
},
187+
{
188+
"cell_type": "code",
189+
"outputs": [],
190+
"source": [
191+
"from mat3ra.made.tools.build.nanoribbon import create_nanoribbon, NanoribbonConfiguration\n",
192+
"from utils.visualize import visualize_materials as visualize\n",
193+
"\n",
194+
"config = NanoribbonConfiguration(material=material, width=NANORIBBON_SIZE, length=NANORIBBON_SIZE, vacuum_width=VACUUM_SIZE, vacuum_length=VACUUM_SIZE)\n",
195+
"\n",
196+
"supercell = create_nanoribbon(config)\n",
197+
"visualize(supercell, repetitions=[1, 1, 1], rotation=\"0x\")"
198+
],
199+
"metadata": {
200+
"collapsed": false
201+
},
202+
"id": "897ba7aa4e402d24",
203+
"execution_count": null
204+
},
205+
{
206+
"cell_type": "markdown",
207+
"source": [
208+
"## 2. Create a target material\n",
209+
"### 2.1. Set custom perturbation parameters\n"
210+
],
211+
"metadata": {
212+
"collapsed": false
213+
},
214+
"id": "6d4adf0d580e0340"
215+
},
216+
{
217+
"cell_type": "code",
218+
"outputs": [],
219+
"source": [
220+
"from mat3ra.made.tools.build.perturbation import CellMatchingDistancePreservingSlabPerturbationBuilder, \\\n",
221+
" PerturbationConfiguration, SlabPerturbationBuilder\n",
222+
"from mat3ra.made.tools.utils.perturbation import PerturbationFunctionHolder\n",
223+
"\n",
224+
"custom_perturbation_function = PerturbationFunctionHolder(function=custom_sympy_function,\n",
225+
" variables=variable_names)\n",
226+
"configuration_custom = PerturbationConfiguration(\n",
227+
" material=supercell,\n",
228+
" perturbation_function_holder=custom_perturbation_function,\n",
229+
" use_cartesian_coordinates=USE_CARTESIAN_COORDINATES)\n",
230+
"\n",
231+
"if PRESERVE_GEODESIC_DISTANCE:\n",
232+
" builder = CellMatchingDistancePreservingSlabPerturbationBuilder()\n",
233+
"else:\n",
234+
" builder = SlabPerturbationBuilder()"
235+
],
236+
"metadata": {
237+
"collapsed": false
238+
},
239+
"id": "8d90932312c418ee",
240+
"execution_count": null
241+
},
242+
{
243+
"cell_type": "markdown",
244+
"source": [
245+
"### 2.2. Apply perturbation to the material"
246+
],
247+
"metadata": {
248+
"collapsed": false
249+
},
250+
"id": "7695d5d1df6be2e3"
251+
},
252+
{
253+
"cell_type": "code",
254+
"outputs": [],
255+
"source": [
256+
"from mat3ra.made.tools.build.perturbation import create_perturbation\n",
257+
"\n",
258+
"material_with_custom_perturbation = create_perturbation(configuration=configuration_custom, builder=builder)"
259+
],
260+
"metadata": {
261+
"collapsed": false
262+
},
263+
"id": "69ccc90b8c5c1191",
264+
"execution_count": null
265+
},
266+
{
267+
"cell_type": "markdown",
268+
"source": [
269+
"### 3. Visualize the Material"
270+
],
271+
"metadata": {
272+
"collapsed": false
273+
},
274+
"id": "10e7ca8950839991"
275+
},
276+
{
277+
"cell_type": "code",
278+
"outputs": [],
279+
"source": [
280+
"visualize([\n",
281+
" {\"material\": material_with_custom_perturbation, \"title\": f\"Material with custom perturbation\"},\n",
282+
" {\"material\": material_with_custom_perturbation, \"title\": f\"Material with custom perturbation\", \"rotation\": \"-90x\"}\n",
283+
"])"
284+
],
285+
"metadata": {
286+
"collapsed": false
287+
},
288+
"id": "cbfe0878a16f6c83",
289+
"execution_count": null
290+
},
291+
{
292+
"cell_type": "markdown",
293+
"source": [
294+
"## 4. Pass data to the outside runtime"
295+
],
296+
"metadata": {
297+
"collapsed": false
298+
},
299+
"id": "9e0b241366592109"
300+
},
301+
{
302+
"cell_type": "code",
303+
"outputs": [],
304+
"source": [
305+
"from utils.jupyterlite import download_content_to_file\n",
306+
"\n",
307+
"download_content_to_file(material_with_custom_perturbation, f\"{MATERIAL_NAME}_edge_perturbation.json\")"
308+
],
309+
"metadata": {
310+
"collapsed": false
311+
},
312+
"id": "29dfa0a329cca2fa",
313+
"execution_count": null
314+
}
315+
],
316+
"metadata": {
317+
"kernelspec": {
318+
"display_name": "Python 3",
319+
"language": "python",
320+
"name": "python3"
321+
},
322+
"language_info": {
323+
"codemirror_mode": {
324+
"name": "ipython",
325+
"version": 2
326+
},
327+
"file_extension": ".py",
328+
"mimetype": "text/x-python",
329+
"name": "python",
330+
"nbconvert_exporter": "python",
331+
"pygments_lexer": "ipython2",
332+
"version": "2.7.6"
333+
}
334+
},
335+
"nbformat": 4,
336+
"nbformat_minor": 5
337+
}

0 commit comments

Comments
 (0)