Skip to content

Commit 765acf4

Browse files
authored
Merge pull request #224 from Exabyte-io/feature/2-example-notebooks
update: add etched cell + heterostack to specific examples
2 parents 018813b + fc9c74c commit 765acf4

File tree

3 files changed

+508
-131
lines changed

3 files changed

+508
-131
lines changed

.github/workflows/cicd.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ concurrency:
88

99
jobs:
1010
run-linter:
11-
runs-on: ubuntu-20.04
11+
runs-on: ubuntu-24.04
1212
strategy:
1313
matrix:
1414
python-version: ["3.10.13"]
@@ -55,7 +55,7 @@ jobs:
5555

5656
# TODO: Add back when when fixed.
5757
# build-and-deploy-docs:
58-
# runs-on: ubuntu-20.04
58+
# runs-on: ubuntu-24.04
5959
# strategy:
6060
# matrix:
6161
# python-version: ["3.8.6"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"source": [
6+
"# Create a custom-shape cutout (Si)\n",
7+
"\n",
8+
"Create a slab with a complex cutout pattern.\n",
9+
"By default, this notebook generates a structure of etching pattern:\n",
10+
"- Two vertical side walls\n",
11+
"- Two parallel channels at the top\n",
12+
"- A deeper central cavity\n",
13+
"\n",
14+
"<h2 style=\"color:green\">Usage</h2>\n",
15+
"\n",
16+
"1. Make sure to select Input Material (in the outer runtime) before running the notebook.\n",
17+
"2. Set structural parameters in cell 1.2 below\n",
18+
"4. Click \"Run\" > \"Run All\" to create the structure\n",
19+
"5. Scroll down to view the resulting structure from multiple angles\n",
20+
"\n",
21+
"## Resulting structure:\n",
22+
"<img src=\"https://objects.mat3ra.com/images/notebooks/cutout_custom_shape_silicon.png\" width=\"400\">"
23+
],
24+
"metadata": {
25+
"collapsed": false
26+
},
27+
"id": "f2e1e795020d7b3f"
28+
},
29+
{
30+
"cell_type": "markdown",
31+
"source": [
32+
"## 1. Prepare the Environment\n",
33+
"### 1.1. Install Packages\n",
34+
"The step executes only in Pyodide environment. For other environments, the packages should be installed via `pip install` (see [README](../../README.ipynb))."
35+
],
36+
"metadata": {
37+
"collapsed": false
38+
},
39+
"id": "98aa134f51746218"
40+
},
41+
{
42+
"cell_type": "code",
43+
"source": [
44+
"import sys\n",
45+
"\n",
46+
"if sys.platform == \"emscripten\":\n",
47+
" import micropip\n",
48+
"\n",
49+
" await micropip.install('mat3ra-api-examples', deps=False)\n",
50+
" await micropip.install('mat3ra-utils')\n",
51+
" from mat3ra.utils.jupyterlite.packages import install_packages\n",
52+
"\n",
53+
" await install_packages(\"specific_examples\")"
54+
],
55+
"metadata": {
56+
"collapsed": false
57+
},
58+
"id": "280f9794a876678b",
59+
"outputs": [],
60+
"execution_count": null
61+
},
62+
{
63+
"cell_type": "markdown",
64+
"source": [
65+
"### 1.2. Set up structure parameters "
66+
],
67+
"metadata": {
68+
"collapsed": false
69+
},
70+
"id": "b3d4d3ea7b589f89"
71+
},
72+
{
73+
"cell_type": "code",
74+
"source": [
75+
"# Slab parameters\n",
76+
"MILLER_INDICES = (0, 0, 1)\n",
77+
"THICKNESS = 6 # unit cell layers\n",
78+
"VACUUM = 10.0 # Angstrom\n",
79+
"XY_SUPERCELL_MATRIX = [[10, 0], [0, 10]]\n",
80+
"\n",
81+
"# Custom shape parameters in crystal units of the slab\n",
82+
"LEFT_WALL_POSITION = 0.2\n",
83+
"RIGHT_WALL_POSITION = 0.8\n",
84+
"LEFT_CHANNEL_POSITION = 0.25\n",
85+
"RIGHT_CHANNEL_POSITION = 0.75\n",
86+
"CHANNEL_TOP_Z = 0.8\n",
87+
"CAVITY_TOP_Z = 0.5\n",
88+
"\n",
89+
"NAME = \"Custom Shape - Etching Pattern\""
90+
],
91+
"metadata": {
92+
"collapsed": false
93+
},
94+
"id": "5177e239254e3601",
95+
"outputs": [],
96+
"execution_count": null
97+
},
98+
{
99+
"cell_type": "markdown",
100+
"source": [
101+
"### 1.3. Create a condition on coordinates\n"
102+
],
103+
"metadata": {
104+
"collapsed": false
105+
},
106+
"id": "361c291aaf3feb2a"
107+
},
108+
{
109+
"cell_type": "code",
110+
"source": [
111+
"from typing import List\n",
112+
"\n",
113+
"from mat3ra.made.tools.utils.coordinate import CoordinateCondition\n",
114+
"\n",
115+
"\n",
116+
"# Example of a custom coordinate condition. Adapt coordinate conditions to your needs.\n",
117+
"class CustomCoordinateCondition(CoordinateCondition):\n",
118+
" \"\"\"\n",
119+
" Defines an etched pattern structure with side walls, channels, and a central cavity.\n",
120+
" All dimensions are specified as fractions of the total size (0.0 to 1.0).\n",
121+
" \"\"\"\n",
122+
" left_wall_position: float = 0.2\n",
123+
" right_wall_position: float = 0.8\n",
124+
" left_channel_position: float = 0.25\n",
125+
" right_channel_position: float = 0.75\n",
126+
" channel_top_z: float = 0.8\n",
127+
" cavity_top_z: float = 0.5\n",
128+
"\n",
129+
" def condition(self, coordinate: List[float]) -> bool:\n",
130+
" \"\"\"\n",
131+
" Determines which atoms to filter based on the coordinate.\n",
132+
" Returns True for positions where atoms should be removed.\n",
133+
" \n",
134+
" The structure consists of:\n",
135+
" 1. Side walls: Two vertical walls running along the y-axis\n",
136+
" 2. Channels: Two trenches at the top running along the x-axis\n",
137+
" 3. Cavity: A deeper central region between the channels\n",
138+
" \"\"\"\n",
139+
" x, y, z = coordinate\n",
140+
"\n",
141+
" # Define the structural elements\n",
142+
" is_in_left_wall = x <= self.left_wall_position\n",
143+
" is_in_right_wall = x >= self.right_wall_position\n",
144+
"\n",
145+
" is_in_left_channel = y <= self.left_channel_position\n",
146+
" is_in_right_channel = y >= self.right_channel_position\n",
147+
"\n",
148+
" is_in_channel = (\n",
149+
" z < self.channel_top_z and\n",
150+
" (is_in_left_channel or is_in_right_channel)\n",
151+
" )\n",
152+
"\n",
153+
" is_below_cavity = (\n",
154+
" z < self.cavity_top_z and # Cavity depth\n",
155+
" self.left_wall_position < x < self.right_wall_position and # Between walls\n",
156+
" not is_in_left_channel and not is_in_right_channel # Between channels\n",
157+
" )\n",
158+
"\n",
159+
" return (\n",
160+
" is_in_left_wall or\n",
161+
" is_in_right_wall or\n",
162+
" is_in_channel or\n",
163+
" is_below_cavity\n",
164+
" )\n",
165+
"\n",
166+
"\n",
167+
"condition = CustomCoordinateCondition(\n",
168+
" left_wall_position=LEFT_WALL_POSITION,\n",
169+
" right_wall_position=RIGHT_WALL_POSITION,\n",
170+
" left_channel_position=LEFT_CHANNEL_POSITION,\n",
171+
" right_channel_position=RIGHT_CHANNEL_POSITION,\n",
172+
" channel_depth=CHANNEL_TOP_Z,\n",
173+
" cavity_depth=CAVITY_TOP_Z,\n",
174+
").condition"
175+
],
176+
"metadata": {
177+
"collapsed": false
178+
},
179+
"id": "56c8227695643174",
180+
"outputs": [],
181+
"execution_count": null
182+
},
183+
{
184+
"cell_type": "markdown",
185+
"source": [
186+
"### 1.3. Get input materials"
187+
],
188+
"metadata": {
189+
"collapsed": false
190+
},
191+
"id": "91724db55eddad60"
192+
},
193+
{
194+
"cell_type": "code",
195+
"source": [
196+
"from mat3ra.standata.materials import Materials\n",
197+
"from mat3ra.made.material import Material\n",
198+
"\n",
199+
"material_json = Materials.get_by_name_first_match(\"Si\")\n",
200+
"material = Material.create(material_json)"
201+
],
202+
"metadata": {
203+
"collapsed": false
204+
},
205+
"id": "ceebf2a5229da67c",
206+
"outputs": [],
207+
"execution_count": null
208+
},
209+
{
210+
"cell_type": "markdown",
211+
"source": [
212+
"### 1.4. Preview the material"
213+
],
214+
"metadata": {
215+
"collapsed": false
216+
},
217+
"id": "13964644436b4156"
218+
},
219+
{
220+
"cell_type": "code",
221+
"source": [
222+
"from utils.visualize import visualize_materials as visualize\n",
223+
"\n",
224+
"visualize(material, repetitions=[1, 1, 1], rotation=\"0x\")\n",
225+
"visualize(material, repetitions=[1, 1, 1], rotation=\"-90x\")"
226+
],
227+
"metadata": {
228+
"collapsed": false
229+
},
230+
"id": "45f0c424ece00186",
231+
"outputs": [],
232+
"execution_count": null
233+
},
234+
{
235+
"cell_type": "markdown",
236+
"source": [
237+
"## 2. Create target material\n",
238+
"### 2.1. Create a slab and apply the cutout condition"
239+
],
240+
"metadata": {
241+
"collapsed": false
242+
},
243+
"id": "615800437b2ef7a"
244+
},
245+
{
246+
"metadata": {},
247+
"cell_type": "code",
248+
"source": [
249+
"from mat3ra.made.tools.modify import filter_by_condition_on_coordinates, add_vacuum\n",
250+
"from mat3ra.made.tools.build.slab import create_slab, SlabConfiguration\n",
251+
"\n",
252+
"slab_config = SlabConfiguration(\n",
253+
" bulk=material,\n",
254+
" miller_indices=MILLER_INDICES,\n",
255+
" thickness=THICKNESS,\n",
256+
" vacuum=0,\n",
257+
" xy_supercell_matrix=XY_SUPERCELL_MATRIX,\n",
258+
" use_orthogonal_z=True,\n",
259+
" use_conventional_cell=True,\n",
260+
")\n",
261+
"\n",
262+
"slab_unit_cell = create_slab(slab_config)\n",
263+
"visualize(slab_unit_cell, viewer=\"wave\", title=\"Slab Unit Cell\")"
264+
],
265+
"id": "8938220048670941",
266+
"outputs": [],
267+
"execution_count": null
268+
},
269+
{
270+
"metadata": {},
271+
"cell_type": "markdown",
272+
"source": "### 2.2. Apply the cutout condition and add vacuum",
273+
"id": "b52118b5a4fb494c"
274+
},
275+
{
276+
"metadata": {},
277+
"cell_type": "code",
278+
"source": [
279+
"resulting_material = filter_by_condition_on_coordinates(slab_unit_cell, condition)\n",
280+
"resulting_material = add_vacuum(resulting_material, VACUUM)"
281+
],
282+
"id": "e1a13d9490a4d5ca",
283+
"outputs": [],
284+
"execution_count": null
285+
},
286+
{
287+
"cell_type": "markdown",
288+
"source": [
289+
"## 3. Visualize the result"
290+
],
291+
"metadata": {
292+
"collapsed": false
293+
},
294+
"id": "57cc38ec0df3c1f7"
295+
},
296+
{
297+
"metadata": {},
298+
"cell_type": "code",
299+
"source": [
300+
"visualize(resulting_material, title=\"Resulting Material\", rotation=\"-90x\")\n",
301+
"visualize(resulting_material, viewer=\"wave\")"
302+
],
303+
"id": "20f499a8dd2362e0",
304+
"outputs": [],
305+
"execution_count": null
306+
},
307+
{
308+
"cell_type": "markdown",
309+
"source": [
310+
"# 4. Pass material to the outside runtime"
311+
],
312+
"metadata": {
313+
"collapsed": false
314+
},
315+
"id": "c67e6f5363e80942"
316+
},
317+
{
318+
"cell_type": "code",
319+
"source": [
320+
"from utils.jupyterlite import set_materials\n",
321+
"\n",
322+
"resulting_material.name = NAME\n",
323+
"set_materials(resulting_material)"
324+
],
325+
"metadata": {
326+
"collapsed": false
327+
},
328+
"id": "cbee60d4b936e5cb",
329+
"outputs": [],
330+
"execution_count": null
331+
}
332+
],
333+
"metadata": {
334+
"kernelspec": {
335+
"display_name": "Python 3",
336+
"language": "python",
337+
"name": "python3"
338+
},
339+
"language_info": {
340+
"codemirror_mode": {
341+
"name": "ipython",
342+
"version": 2
343+
},
344+
"file_extension": ".py",
345+
"mimetype": "text/x-python",
346+
"name": "python",
347+
"nbconvert_exporter": "python",
348+
"pygments_lexer": "ipython2",
349+
"version": "2.7.6"
350+
}
351+
},
352+
"nbformat": 4,
353+
"nbformat_minor": 5
354+
}

0 commit comments

Comments
 (0)