Skip to content

Commit fe60c46

Browse files
authored
Merge pull request #139 from Exabyte-io/feature/SOF-7398
feature/SOF 7398
2 parents ee1eacb + 20ebb48 commit fe60c46

File tree

4 files changed

+362
-2
lines changed

4 files changed

+362
-2
lines changed

other/materials_designer/Introduction.ipynb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
"\n",
3434
"This notebook lets user create a slab and place an adatom at specified location. [Click here to open the notebook](create_adatom_defect.ipynb).\n",
3535
"\n",
36+
"#### [1.6. Slab Perturbation](create_perturbation.ipynb)\n",
37+
"\n",
38+
"This notebook lets user add a perturbation to a slab by moving atoms according to a specified function. [Click here to open the notebook](create_perturbation.ipynb).\n",
39+
"\n",
3640
"### 2. Data Import\n",
3741
"\n",
3842
"#### [2.1. Materials import from files in ASE-supported formats](import_materials_from_files.ipynb)\n",
Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"source": [
6+
"# Create a Perturbation in a Material\n",
7+
"\n",
8+
"Create a perturbation in a material with a specified smooth function or a custom function described with [SymPy](https://docs.sympy.org/latest/tutorials/intro-tutorial/intro.html) expressions. \n",
9+
"\n",
10+
"<h2 style=\"color:green\">Usage</h2>\n",
11+
"\n",
12+
"1. Make sure to select Input Materials (in the outer runtime) before running the notebook.\n",
13+
"1. Set notebook parameters in cell 1.1. below (or use the default values).\n",
14+
"1. Set perturbation parameters in cell 2.1. (or use default).\n",
15+
"1. Click “Run” > “Run All” to run all cells. \n",
16+
"1. Wait for the run to complete (depending on the parameters can take a few min). \n",
17+
"1. Scroll down to view results. \n",
18+
"\n",
19+
"## Summary\n",
20+
"1. Prepare the Environment: Set up the notebook and install packages, preview the input materials\n",
21+
"1. Create the Perturbation: Add a smooth perturbation to the material\n",
22+
"2. Visualize the Perturbed Material\n",
23+
"\n",
24+
"## Notes\n",
25+
"\n",
26+
"1. For more information, see [Introduction](Introduction.ipynb)\n"
27+
],
28+
"metadata": {
29+
"collapsed": false
30+
},
31+
"id": "367a698b29e22bd7"
32+
},
33+
{
34+
"cell_type": "markdown",
35+
"source": [
36+
"## 1. Prepare the Environment\n",
37+
"### 1.1. Set up supercell parameters "
38+
],
39+
"metadata": {
40+
"collapsed": false
41+
},
42+
"id": "193a4e6a78fd5bd7"
43+
},
44+
{
45+
"cell_type": "code",
46+
"outputs": [],
47+
"source": [
48+
"SUPERCELL_MATRIX = [[5, 0, 0], [0, 5, 0], [0, 0, 1]] "
49+
],
50+
"metadata": {
51+
"collapsed": false
52+
},
53+
"id": "a40d7b697c413113",
54+
"execution_count": null
55+
},
56+
{
57+
"cell_type": "markdown",
58+
"source": [
59+
"### 1.2. Install Packages\n",
60+
"The step executes only in Pyodide environment. For other environments, the packages should be installed via `pip install` (see [README](../../README.ipynb))."
61+
],
62+
"metadata": {
63+
"collapsed": false
64+
},
65+
"id": "49c9f5022d50517e"
66+
},
67+
{
68+
"cell_type": "code",
69+
"outputs": [],
70+
"source": [
71+
"import sys\n",
72+
"\n",
73+
"if sys.platform == \"emscripten\":\n",
74+
" import micropip\n",
75+
" await micropip.install('mat3ra-api-examples', deps=False)\n",
76+
" from utils.jupyterlite import install_packages\n",
77+
" await install_packages(\"\", \"../../config.yml\")"
78+
],
79+
"metadata": {
80+
"collapsed": false
81+
},
82+
"id": "c6d9f8e57bef2f91",
83+
"execution_count": null
84+
},
85+
{
86+
"cell_type": "markdown",
87+
"source": [
88+
"### 1.3. Get input materials\n",
89+
"Materials are loaded with `get_data()`. The first material is assigned as substrate and the second as film."
90+
],
91+
"metadata": {
92+
"collapsed": false
93+
},
94+
"id": "edf02101e27a2742"
95+
},
96+
{
97+
"cell_type": "code",
98+
"outputs": [],
99+
"source": [
100+
"from mat3ra.made.material import Material\n",
101+
"from utils.jupyterlite import get_data\n",
102+
"\n",
103+
"# Get the list of input materials and load them into `materials_in` variable\n",
104+
"get_data(\"materials_in\", globals())\n",
105+
"materials = list(map(Material, globals()[\"materials_in\"]))"
106+
],
107+
"metadata": {
108+
"collapsed": false
109+
},
110+
"id": "e0c53233ce728cc1",
111+
"execution_count": null
112+
},
113+
{
114+
"cell_type": "markdown",
115+
"source": [
116+
"### 1.4. Create and preview Supercell"
117+
],
118+
"metadata": {
119+
"collapsed": false
120+
},
121+
"id": "cf29b7f6fe114d8f"
122+
},
123+
{
124+
"cell_type": "code",
125+
"outputs": [],
126+
"source": [
127+
"from utils.visualize import visualize_materials as visualize\n",
128+
"from mat3ra.made.tools.build.supercell import create_supercell\n",
129+
"\n",
130+
"unit_cell = materials[0]\n",
131+
"supercell = create_supercell(unit_cell, supercell_matrix=SUPERCELL_MATRIX)\n",
132+
"visualize(supercell, repetitions=[1, 1, 1], rotation=\"0x\")"
133+
],
134+
"metadata": {
135+
"collapsed": false
136+
},
137+
"id": "897ba7aa4e402d24",
138+
"execution_count": null
139+
},
140+
{
141+
"cell_type": "markdown",
142+
"source": [
143+
"## 2. Create the SineWave Perturbation\n",
144+
"### 2.1. Set sine wave perturbation parameters\n",
145+
"Use perturbation function imported from `mat3ra.made.tools.utils.perturbation` folder."
146+
],
147+
"metadata": {
148+
"collapsed": false
149+
},
150+
"id": "39a93c4635762a83"
151+
},
152+
{
153+
"cell_type": "code",
154+
"outputs": [],
155+
"source": [
156+
"from mat3ra.made.tools.build.perturbation import PerturbationConfiguration, SlabPerturbationBuilder\n",
157+
"from mat3ra.made.tools.utils.perturbation import SineWavePerturbationFunctionHolder\n",
158+
"\n",
159+
"amplitude = 0.05\n",
160+
"wavelength = 1\n",
161+
"phase = 0\n",
162+
"axis = \"y\"\n",
163+
"perturbation_function = SineWavePerturbationFunctionHolder(amplitude=amplitude, \n",
164+
" wavelength=wavelength, \n",
165+
" phase=phase,\n",
166+
" axis=axis)\n",
167+
"\n",
168+
"configuration = PerturbationConfiguration(material=supercell, \n",
169+
" perturbation_function_holder=perturbation_function,\n",
170+
" use_cartesian_coordinates=False)\n",
171+
"\n",
172+
"builder = SlabPerturbationBuilder()"
173+
],
174+
"metadata": {
175+
"collapsed": false
176+
},
177+
"id": "1991efeeebe39db4",
178+
"execution_count": null
179+
},
180+
{
181+
"cell_type": "markdown",
182+
"source": [
183+
"### 2.2. Apply perturbation to the material"
184+
],
185+
"metadata": {
186+
"collapsed": false
187+
},
188+
"id": "d296d7287618dc0b"
189+
},
190+
{
191+
"cell_type": "code",
192+
"outputs": [],
193+
"source": [
194+
"from mat3ra.made.tools.build.perturbation import create_perturbation\n",
195+
"\n",
196+
"material_with_perturbation = create_perturbation(configuration, builder)"
197+
],
198+
"metadata": {
199+
"collapsed": false
200+
},
201+
"id": "d77821f7d0b8c330",
202+
"execution_count": null
203+
},
204+
{
205+
"cell_type": "markdown",
206+
"source": [
207+
"### 2.3. Visualize the Material"
208+
],
209+
"metadata": {
210+
"collapsed": false
211+
},
212+
"id": "eecd561cd92fb18a"
213+
},
214+
{
215+
"cell_type": "code",
216+
"outputs": [],
217+
"source": [
218+
"from utils.visualize import visualize_materials as visualize\n",
219+
"\n",
220+
"visualize([{\"material\": supercell, \"title\": \"Original material\"},\n",
221+
" {\"material\": material_with_perturbation, \"title\": f\"Material with perturbation\"},\n",
222+
" {\"material\": material_with_perturbation, \"title\": f\"Material with perturbation\", \"rotation\": \"-90x\"},\n",
223+
"])"
224+
],
225+
"metadata": {
226+
"collapsed": false
227+
},
228+
"id": "1ee393a7f2ec3bc8",
229+
"execution_count": null
230+
},
231+
{
232+
"cell_type": "markdown",
233+
"source": [
234+
"## 3. Create a Custom Perturbation\n",
235+
"### 3.1. Set custom perturbation parameters\n",
236+
"Provide a SymPy expression for the perturbation function. The expression should be a function of `x`, `y` and `z` variables."
237+
],
238+
"metadata": {
239+
"collapsed": false
240+
},
241+
"id": "6d4adf0d580e0340"
242+
},
243+
{
244+
"cell_type": "code",
245+
"outputs": [],
246+
"source": [
247+
"import sympy as sp\n",
248+
"from mat3ra.made.tools.build.perturbation import CellMatchingDistancePreservingSlabPerturbationBuilder\n",
249+
"from mat3ra.made.tools.utils.perturbation import PerturbationFunctionHolder\n",
250+
"\n",
251+
"x,y = sp.symbols('x y')\n",
252+
"function = amplitude * sp.sin(2 * sp.pi * x / wavelength + phase) * sp.sin(2 * sp.pi * y / wavelength)\n",
253+
"\n",
254+
"custom_perturbation_function = PerturbationFunctionHolder(function=function, variables=[\"x\", \"y\"])\n",
255+
"configuration_custom = PerturbationConfiguration(material=supercell,\n",
256+
" perturbation_function_holder=custom_perturbation_function,\n",
257+
" use_cartesian_coordinates=False)\n",
258+
"distance_preserving_builder = CellMatchingDistancePreservingSlabPerturbationBuilder()"
259+
],
260+
"metadata": {
261+
"collapsed": false
262+
},
263+
"id": "8d90932312c418ee"
264+
},
265+
{
266+
"cell_type": "markdown",
267+
"source": [
268+
"### 3.2. Apply perturbation to the material"
269+
],
270+
"metadata": {
271+
"collapsed": false
272+
},
273+
"id": "7695d5d1df6be2e3"
274+
},
275+
{
276+
"cell_type": "code",
277+
"outputs": [],
278+
"source": [
279+
"material_with_custom_perturbation = create_perturbation(configuration_custom, distance_preserving_builder)"
280+
],
281+
"metadata": {
282+
"collapsed": false
283+
},
284+
"id": "69ccc90b8c5c1191"
285+
},
286+
{
287+
"cell_type": "markdown",
288+
"source": [
289+
"### 3.3. Visualize the Material"
290+
],
291+
"metadata": {
292+
"collapsed": false
293+
},
294+
"id": "10e7ca8950839991"
295+
},
296+
{
297+
"cell_type": "code",
298+
"outputs": [],
299+
"source": [
300+
"visualize([\n",
301+
" {\"material\": material_with_custom_perturbation, \"title\": f\"Material with custom perturbation\"},\n",
302+
" {\"material\": material_with_custom_perturbation, \"title\": f\"Material with custom perturbation\",\"rotation\": \"-90x\"}\n",
303+
"])"
304+
],
305+
"metadata": {
306+
"collapsed": false
307+
},
308+
"id": "cbfe0878a16f6c83"
309+
},
310+
{
311+
"cell_type": "markdown",
312+
"source": [
313+
"## 4. Pass data to the outside runtime"
314+
],
315+
"metadata": {
316+
"collapsed": false
317+
},
318+
"id": "9e0b241366592109"
319+
},
320+
{
321+
"cell_type": "code",
322+
"outputs": [],
323+
"source": [
324+
"from utils.jupyterlite import set_data\n",
325+
"\n",
326+
"set_data(\"materials\", [material_with_perturbation.to_json(), material_with_custom_perturbation.to_json()])"
327+
],
328+
"metadata": {
329+
"collapsed": false
330+
},
331+
"id": "29dfa0a329cca2fa",
332+
"execution_count": null
333+
}
334+
],
335+
"metadata": {
336+
"kernelspec": {
337+
"display_name": "Python 3",
338+
"language": "python",
339+
"name": "python3"
340+
},
341+
"language_info": {
342+
"codemirror_mode": {
343+
"name": "ipython",
344+
"version": 2
345+
},
346+
"file_extension": ".py",
347+
"mimetype": "text/x-python",
348+
"name": "python",
349+
"nbconvert_exporter": "python",
350+
"pygments_lexer": "ipython2",
351+
"version": "2.7.6"
352+
}
353+
},
354+
"nbformat": 4,
355+
"nbformat_minor": 5
356+
}

other/materials_designer/create_point_defect.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
{
9191
"cell_type": "markdown",
9292
"source": [
93-
"### 1.3. Get input material and \n",
93+
"### 1.3. Get input materials\n",
9494
"Materials are loaded with `get_data()`. The first material is assigned as substrate and the second as film."
9595
],
9696
"metadata": {

utils/visualize.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def get_material_image(material: Material, title: str, rotation="0x,0y,0z", repe
2929
# Create supercell for visualization
3030
supercell_matrix = [[repetitions[0], 0, 0], [0, repetitions[1], 0], [0, 0, repetitions[2]]]
3131
material_repeat = make_supercell(ase_atoms, supercell_matrix)
32-
text = f"{ase_atoms.symbols} - {title} - rotation: {rotation}"
32+
text = f"{ase_atoms.get_chemical_formula()} - {title} - rotation: {rotation}"
3333

3434
# Write image to a buffer to display in HTML
3535
buf = io.BytesIO()

0 commit comments

Comments
 (0)