Skip to content

Commit 54cc0f0

Browse files
committed
Merge branch 'dev' into feature/SOF-7493
2 parents 02a4b55 + 79e7644 commit 54cc0f0

13 files changed

+2313
-24
lines changed

config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,11 @@ notebooks:
6464
packages_pyodide:
6565
- mat3ra-esse
6666
- mat3ra-made
67+
- name: create_cluster_custom_shape.ipynb
68+
packages_common:
69+
- icosphere
70+
packages_python:
71+
packages_pyodide:
72+
- name: specific_examples
73+
packages_common:
74+
- mat3ra-standata

other/materials_designer/Introduction.ipynb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,20 @@
2323
"\n",
2424
"### 1.3. 1D Structures.\n",
2525
"#### [1.3.1. Nanoribbons. Create nanoribbons from 2D materials.](create_nanoribbon.ipynb)\n",
26+
"#### [1.3.2. Nanowires. Create a nanowire from a bulk material.](create_nanowire.ipynb)\n",
27+
"#### [1.3.3. Nanowires with custom shape. Create a nanowire with a custom cross-section.](create_nanowire_custom_shape.ipynb)\n",
2628
"\n",
2729
"### 1.4. 0D Structures.\n",
28-
"#### [1.4.1. Spherical. Create clusters or spherical structures.](create_cluster_sphere.ipynb)\n",
30+
"#### [1.4.1. Spherical Cluster. Create a spherical cluster from a bulk material.](create_cluster_sphere.ipynb)\n",
31+
"#### [1.4.2. Custom Shape Cluster. Create a cluster with a custom shape.](create_cluster_custom_shape.ipynb)\n",
32+
"#### [1.4.3. Box-cutout. Create a slab with a box cutout](create_cutout_box.ipynb)\n",
33+
"#### [1.4.4. Custom Shape Cutout. Create a slab with a custom shape cutout.](create_cutout_custom_shape.ipynb)\n",
2934
"\n",
3035
"\n",
3136
"## 2. Multi-Material Structures.\n",
3237
"\n",
3338
"### 2.1. Interfaces\n",
34-
"#### [2.1.1. Interface with Zur and McGill Superlattice (ZSL) straing matching](create_interface_with_min_strain_zsl.ipynb)\n",
39+
"#### [2.1.1. Interface with Zur and McGill Superlattice (ZSL) strain matching](create_interface_with_min_strain_zsl.ipynb)\n",
3540
"\n",
3641
"#### [2.1.3. Interface without strain matching](create_interface_with_no_strain_matching.ipynb)\n",
3742
"\n",
Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"source": [
6+
"# Create a cluster of custom shape from a bulk material\n",
7+
"\n",
8+
"Create a cluster with shape provided by condition on coordinates and crystal orientation along the z-axis from a bulk material.\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. Click “Run” > “Run All” to run all cells. \n",
15+
"1. Scroll down to view results. \n",
16+
"\n",
17+
"\n",
18+
"## Notes\n",
19+
"\n",
20+
"1. For more information, see [Introduction](Introduction.ipynb)\n",
21+
"<!-- # TODO: use a hashtag-based anchor link to interface creation documention above -->\n"
22+
],
23+
"metadata": {
24+
"collapsed": false
25+
},
26+
"id": "f2e1e795020d7b3f"
27+
},
28+
{
29+
"cell_type": "markdown",
30+
"source": [
31+
"## 1. Prepare the Environment\n"
32+
],
33+
"metadata": {
34+
"collapsed": false
35+
},
36+
"id": "5e43ff288847b784"
37+
},
38+
{
39+
"cell_type": "markdown",
40+
"source": [
41+
"### 1.1. Install Packages\n",
42+
"The step executes only in Pyodide environment. For other environments, the packages should be installed via `pip install` (see [README](../../README.ipynb))."
43+
],
44+
"metadata": {
45+
"collapsed": false
46+
},
47+
"id": "9adf37a8d2620dc4"
48+
},
49+
{
50+
"cell_type": "code",
51+
"outputs": [],
52+
"source": [
53+
"import sys\n",
54+
"\n",
55+
"if sys.platform == \"emscripten\":\n",
56+
" import micropip\n",
57+
"\n",
58+
" await micropip.install('mat3ra-api-examples', deps=False)\n",
59+
" from utils.jupyterlite import install_packages\n",
60+
"\n",
61+
" await install_packages(\"create_cluster_custom_shape.ipynb\", \"../../config.yml\")"
62+
],
63+
"metadata": {
64+
"collapsed": false
65+
},
66+
"id": "d9e6be14343d00a1",
67+
"execution_count": null
68+
},
69+
{
70+
"cell_type": "markdown",
71+
"source": [
72+
"### 1.2. Set up cluster parameters"
73+
],
74+
"metadata": {
75+
"collapsed": false
76+
},
77+
"id": "26066db067a41c93"
78+
},
79+
{
80+
"cell_type": "code",
81+
"outputs": [],
82+
"source": [
83+
"RADIUS = 0.3 # in crystal units\n",
84+
"VACUUM = 10.0 # in Angstroms on each side\n",
85+
"SUPERCELL_SIZE = 10 # in crystal units\n",
86+
"Z_ORIENTATION = (0, 0, 1) # Miller indices of the slab orientation along the z-axis for the cluster\n",
87+
"NAME = \"Icosahedron\" # Name of the cluster"
88+
],
89+
"metadata": {
90+
"collapsed": false
91+
},
92+
"id": "9d8b1890b34d850a",
93+
"execution_count": null
94+
},
95+
{
96+
"cell_type": "markdown",
97+
"source": [
98+
"### 1.3. Set coordinates condition"
99+
],
100+
"metadata": {
101+
"collapsed": false
102+
},
103+
"id": "3aae932e71fa71a9"
104+
},
105+
{
106+
"cell_type": "code",
107+
"outputs": [],
108+
"source": [
109+
"import numpy as np\n",
110+
"from typing import List\n",
111+
"from icosphere import icosphere\n",
112+
"from mat3ra.made.tools.utils.coordinate import CoordinateCondition\n",
113+
"\n",
114+
"\n",
115+
"# Example of a custom coordinate condition (icosahedron). Adapt coordinate conditions to your needs.\n",
116+
"class CustomCoordinateCondition(CoordinateCondition):\n",
117+
" \"\"\"Creates an icosahedron shape using the icosphere module\"\"\"\n",
118+
" radius: float = 1\n",
119+
" frequency: int = 1\n",
120+
" vertices: List[List[float]] = icosphere(1)[0]\n",
121+
" faces: List[List[int]] = icosphere(1)[1]\n",
122+
" center: List[float] = [0.5, 0.5, 0.5]\n",
123+
"\n",
124+
" def condition(self, coordinate: List[float]) -> bool:\n",
125+
" \"\"\"Returns True if point is inside icosahedron\"\"\"\n",
126+
" coordinate = np.array(coordinate) - self.center\n",
127+
" for face in self.faces:\n",
128+
" a, b, c = face\n",
129+
" normal = np.cross(self.vertices[b] - self.vertices[a], self.vertices[c] - self.vertices[a])\n",
130+
" normal = normal / np.linalg.norm(normal)\n",
131+
" if np.dot(normal, coordinate) > self.radius:\n",
132+
" return False\n",
133+
" return True\n",
134+
" \n",
135+
"condition = CustomCoordinateCondition(radius=RADIUS).condition"
136+
],
137+
"metadata": {
138+
"collapsed": false
139+
},
140+
"id": "8e382d5ab459e2d",
141+
"execution_count": null
142+
},
143+
{
144+
"cell_type": "markdown",
145+
"source": [
146+
"### 1.3. Get input material"
147+
],
148+
"metadata": {
149+
"collapsed": false
150+
},
151+
"id": "919ad7af8dceeedd"
152+
},
153+
{
154+
"cell_type": "code",
155+
"outputs": [],
156+
"source": [
157+
"from utils.jupyterlite import get_materials\n",
158+
"\n",
159+
"materials = get_materials(globals())"
160+
],
161+
"metadata": {
162+
"collapsed": false
163+
},
164+
"id": "be38fdda1984c654",
165+
"execution_count": null
166+
},
167+
{
168+
"cell_type": "markdown",
169+
"source": [
170+
"### 1.4. Create a slab of sufficient size"
171+
],
172+
"metadata": {
173+
"collapsed": false
174+
},
175+
"id": "a132fe0ef8bbf0d0"
176+
},
177+
{
178+
"cell_type": "code",
179+
"outputs": [],
180+
"source": [
181+
"from mat3ra.made.tools.build.supercell import create_supercell\n",
182+
"from mat3ra.made.tools.build.slab import create_slab, SlabConfiguration\n",
183+
"from utils.visualize import visualize_materials as visualize\n",
184+
"\n",
185+
"slab_config = SlabConfiguration(\n",
186+
" bulk=materials[0],\n",
187+
" miller_indices=Z_ORIENTATION,\n",
188+
" thickness=SUPERCELL_SIZE,\n",
189+
" vacuum=0,\n",
190+
" use_orthogonal_z=True,\n",
191+
" xy_supercell_matrix=[[SUPERCELL_SIZE, 0], [0, SUPERCELL_SIZE]],\n",
192+
")\n",
193+
"\n",
194+
"slab = create_slab(slab_config)\n",
195+
"\n",
196+
"visualize([{\"material\": slab, \"title\": \"Original material\"}])\n",
197+
"visualize([{\"material\": slab, \"title\": \"Original material\"}], rotation=\"-90x\")"
198+
],
199+
"metadata": {
200+
"collapsed": false
201+
},
202+
"id": "7fcb1e02e84c5f35",
203+
"execution_count": null
204+
},
205+
{
206+
"cell_type": "markdown",
207+
"source": [
208+
"## 2. Create the Target Material\n",
209+
"### 2.1. Create spherical cluster\n"
210+
],
211+
"metadata": {
212+
"collapsed": false
213+
},
214+
"id": "690241d87e7bbbe0"
215+
},
216+
{
217+
"cell_type": "code",
218+
"outputs": [],
219+
"source": [
220+
"from mat3ra.made.tools.modify import add_vacuum, add_vacuum_sides, filter_by_condition_on_coordinates\n",
221+
"\n",
222+
"cluster = filter_by_condition_on_coordinates(slab, condition)\n",
223+
"cluster = add_vacuum(cluster, VACUUM, to_bottom=True, on_top=True)\n",
224+
"cluster = add_vacuum_sides(cluster, VACUUM, on_x=True, on_y=True)"
225+
],
226+
"metadata": {
227+
"collapsed": false
228+
},
229+
"id": "a990fa35742d7269",
230+
"execution_count": null
231+
},
232+
{
233+
"cell_type": "markdown",
234+
"source": [
235+
"### 2.2. Set lattice to Cubic"
236+
],
237+
"metadata": {
238+
"collapsed": false
239+
},
240+
"id": "a01018588e6e55fc"
241+
},
242+
{
243+
"cell_type": "code",
244+
"outputs": [],
245+
"source": [
246+
"from mat3ra.made.lattice import Lattice\n",
247+
"\n",
248+
"current_vector_1, current_vector_2, current_vector_3 = cluster.lattice.vectors\n",
249+
"cubic_vector_1 = [current_vector_1[0], 0, 0]\n",
250+
"cubic_vector_2 = [0, current_vector_2[1], 0]\n",
251+
"cubic_vector_3 = [0, 0, current_vector_3[2]]\n",
252+
"cluster.lattice = Lattice.from_vectors_array([cubic_vector_1, cubic_vector_2, cubic_vector_3], type=\"CUB\")"
253+
],
254+
"metadata": {
255+
"collapsed": false
256+
},
257+
"id": "4f78c4743b370c3b",
258+
"execution_count": null
259+
},
260+
{
261+
"cell_type": "markdown",
262+
"source": [
263+
"## 3. Visualize the Result(s)"
264+
],
265+
"metadata": {
266+
"collapsed": false
267+
},
268+
"id": "462549d016073446"
269+
},
270+
{
271+
"cell_type": "code",
272+
"outputs": [],
273+
"source": [
274+
"visualize([{\"material\": slab, \"title\": \"Original material\"},\n",
275+
" {\"material\": cluster, \"title\": f\"Cluster\"}])\n",
276+
"\n",
277+
"visualize([{\"material\": slab, \"title\": \"Original material\"},\n",
278+
" {\"material\": cluster, \"title\": f\"Cluster\"}], rotation=\"-90x\")"
279+
],
280+
"metadata": {
281+
"collapsed": false
282+
},
283+
"id": "509b18661a069e42",
284+
"execution_count": null
285+
},
286+
{
287+
"cell_type": "markdown",
288+
"source": [
289+
"## 4. Pass data to the outside runtime"
290+
],
291+
"metadata": {
292+
"collapsed": false
293+
},
294+
"id": "d381df29a6bbdd82"
295+
},
296+
{
297+
"cell_type": "code",
298+
"outputs": [],
299+
"source": [
300+
"from utils.jupyterlite import set_materials\n",
301+
"\n",
302+
"cluster.name = f\"{materials[0].name} {NAME}\"\n",
303+
"set_materials(cluster)"
304+
],
305+
"metadata": {
306+
"collapsed": false
307+
},
308+
"id": "61daa5afcbc078a9",
309+
"execution_count": null
310+
}
311+
],
312+
"metadata": {
313+
"kernelspec": {
314+
"display_name": "Python 3",
315+
"language": "python",
316+
"name": "python3"
317+
},
318+
"language_info": {
319+
"codemirror_mode": {
320+
"name": "ipython",
321+
"version": 2
322+
},
323+
"file_extension": ".py",
324+
"mimetype": "text/x-python",
325+
"name": "python",
326+
"nbconvert_exporter": "python",
327+
"pygments_lexer": "ipython2",
328+
"version": "2.7.6"
329+
}
330+
},
331+
"nbformat": 4,
332+
"nbformat_minor": 5
333+
}

0 commit comments

Comments
 (0)