|
48 | 48 | },
|
49 | 49 | {
|
50 | 50 | "cell_type": "code",
|
51 |
| - "outputs": [], |
52 | 51 | "source": [
|
53 | 52 | "import sys\n",
|
54 | 53 | "\n",
|
|
58 | 57 | " await micropip.install('mat3ra-api-examples', deps=False)\n",
|
59 | 58 | " from utils.jupyterlite import install_packages\n",
|
60 | 59 | "\n",
|
61 |
| - " await install_packages(\"create_cluster_custom_shape.ipynb\")" |
| 60 | + " await install_packages(\"\")" |
62 | 61 | ],
|
63 | 62 | "metadata": {
|
64 | 63 | "collapsed": false
|
65 | 64 | },
|
66 | 65 | "id": "d9e6be14343d00a1",
|
| 66 | + "outputs": [], |
67 | 67 | "execution_count": null
|
68 | 68 | },
|
69 | 69 | {
|
|
78 | 78 | },
|
79 | 79 | {
|
80 | 80 | "cell_type": "code",
|
81 |
| - "outputs": [], |
82 | 81 | "source": [
|
83 | 82 | "RADIUS = 0.3 # in crystal units\n",
|
84 | 83 | "VACUUM = 10.0 # in Angstroms on each side\n",
|
|
90 | 89 | "collapsed": false
|
91 | 90 | },
|
92 | 91 | "id": "9d8b1890b34d850a",
|
| 92 | + "outputs": [], |
93 | 93 | "execution_count": null
|
94 | 94 | },
|
95 | 95 | {
|
|
104 | 104 | },
|
105 | 105 | {
|
106 | 106 | "cell_type": "code",
|
107 |
| - "outputs": [], |
108 | 107 | "source": [
|
109 | 108 | "import numpy as np\n",
|
| 109 | + "from scipy.spatial import ConvexHull\n", |
110 | 110 | "from typing import List\n",
|
111 |
| - "from icosphere import icosphere\n", |
112 | 111 | "from mat3ra.made.tools.utils.coordinate import CoordinateCondition\n",
|
113 | 112 | "\n",
|
114 | 113 | "\n",
|
115 |
| - "# Example of a custom coordinate condition (icosahedron). Adapt coordinate conditions to your needs.\n", |
116 | 114 | "class CustomCoordinateCondition(CoordinateCondition):\n",
|
117 |
| - " \"\"\"Creates an icosahedron shape using the icosphere module\"\"\"\n", |
| 115 | + " \"\"\"Creates a regular polyhedron shape using SciPy's ConvexHull\"\"\"\n", |
118 | 116 | " 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 | 117 | " center: List[float] = [0.5, 0.5, 0.5]\n",
|
123 | 118 | "\n",
|
| 119 | + " @property\n", |
| 120 | + " def _hull_planes(self):\n", |
| 121 | + " t = (1 + np.sqrt(5)) / 2\n", |
| 122 | + " vertices = np.array([\n", |
| 123 | + " [-1, t, 0], [1, t, 0], [-1, -t, 0], [1, -t, 0],\n", |
| 124 | + " [0, -1, t], [0, 1, t], [0, -1, -t], [0, 1, -t],\n", |
| 125 | + " [t, 0, -1], [t, 0, 1], [-t, 0, -1], [-t, 0, 1]\n", |
| 126 | + " ]) * self.radius / np.sqrt(1 + t*t)\n", |
| 127 | + " return ConvexHull(vertices).equations\n", |
| 128 | + "\n", |
124 | 129 | " 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", |
| 130 | + " \"\"\"Returns True if point is inside the polyhedron\"\"\"\n", |
| 131 | + " point = np.array(coordinate) - self.center\n", |
| 132 | + " return all(np.dot(plane[:3], point) + plane[3] <= 0\n", |
| 133 | + " for plane in self._hull_planes)\n", |
| 134 | + "\n", |
135 | 135 | " \n",
|
136 | 136 | "condition = CustomCoordinateCondition(radius=RADIUS).condition"
|
137 | 137 | ],
|
138 | 138 | "metadata": {
|
139 | 139 | "collapsed": false
|
140 | 140 | },
|
141 | 141 | "id": "8e382d5ab459e2d",
|
| 142 | + "outputs": [], |
142 | 143 | "execution_count": null
|
143 | 144 | },
|
144 | 145 | {
|
|
153 | 154 | },
|
154 | 155 | {
|
155 | 156 | "cell_type": "code",
|
156 |
| - "outputs": [], |
157 | 157 | "source": [
|
158 | 158 | "from utils.jupyterlite import get_materials\n",
|
159 | 159 | "\n",
|
|
163 | 163 | "collapsed": false
|
164 | 164 | },
|
165 | 165 | "id": "be38fdda1984c654",
|
| 166 | + "outputs": [], |
166 | 167 | "execution_count": null
|
167 | 168 | },
|
168 | 169 | {
|
|
178 | 179 | },
|
179 | 180 | {
|
180 | 181 | "cell_type": "code",
|
181 |
| - "outputs": [], |
182 | 182 | "source": [
|
183 |
| - "from mat3ra.made.tools.build.nanoparticle import ASEBasedNanoparticleConfiguration\n", |
184 |
| - "from mat3ra.made.tools.build.nanoparticle.enums import ASENanoparticleShapesEnum\n", |
185 |
| - "\n", |
| 183 | + "from mat3ra.made.tools.build.nanoparticle import SlabBasedNanoparticleConfiguration\n", |
186 | 184 | "\n",
|
187 |
| - "config = ASEBasedNanoparticleConfiguration(\n", |
| 185 | + "config = SlabBasedNanoparticleConfiguration(\n", |
188 | 186 | " material=materials[0],\n",
|
| 187 | + " condition_builder=condition,\n", |
189 | 188 | " supercell_size=SUPERCELL_SIZE,\n",
|
190 |
| - " vacuum=VACUUM,\n", |
191 |
| - " z_orientation=Z_ORIENTATION,\n", |
192 |
| - " coordinate_condition=condition\n", |
193 |
| - ")\n" |
| 189 | + ")" |
194 | 190 | ],
|
195 | 191 | "metadata": {
|
196 | 192 | "collapsed": false
|
197 | 193 | },
|
198 |
| - "id": "8fbe260fa14db47a" |
| 194 | + "id": "8fbe260fa14db47a", |
| 195 | + "outputs": [], |
| 196 | + "execution_count": null |
199 | 197 | },
|
200 | 198 | {
|
201 | 199 | "cell_type": "markdown",
|
|
209 | 207 | },
|
210 | 208 | {
|
211 | 209 | "cell_type": "code",
|
212 |
| - "outputs": [], |
213 | 210 | "source": [
|
214 |
| - "from mat3ra.made.tools.build.nanoparticle import ASEBasedNanoparticleBuilder" |
| 211 | + "from mat3ra.made.tools.build.nanoparticle import create_nanoparticle\n", |
| 212 | + "\n", |
| 213 | + "cluster = create_nanoparticle(config)" |
215 | 214 | ],
|
216 | 215 | "metadata": {
|
217 | 216 | "collapsed": false
|
218 | 217 | },
|
219 | 218 | "id": "a990fa35742d7269",
|
| 219 | + "outputs": [], |
220 | 220 | "execution_count": null
|
221 | 221 | },
|
222 | 222 | {
|
|
231 | 231 | },
|
232 | 232 | {
|
233 | 233 | "cell_type": "code",
|
234 |
| - "outputs": [], |
235 | 234 | "source": [
|
236 | 235 | "from mat3ra.made.lattice import Lattice\n",
|
237 | 236 | "\n",
|
|
245 | 244 | "collapsed": false
|
246 | 245 | },
|
247 | 246 | "id": "4f78c4743b370c3b",
|
| 247 | + "outputs": [], |
248 | 248 | "execution_count": null
|
249 | 249 | },
|
250 | 250 | {
|
|
259 | 259 | },
|
260 | 260 | {
|
261 | 261 | "cell_type": "code",
|
262 |
| - "outputs": [], |
263 | 262 | "source": [
|
264 |
| - "visualize([{\"material\": slab, \"title\": \"Original material\"},\n", |
265 |
| - " {\"material\": cluster, \"title\": f\"Cluster\"}])\n", |
266 |
| - "\n", |
267 |
| - "visualize([{\"material\": slab, \"title\": \"Original material\"},\n", |
268 |
| - " {\"material\": cluster, \"title\": f\"Cluster\"}], rotation=\"-90x\")" |
| 263 | + "from utils.visualize import visualize_materials as visualize\n", |
| 264 | + "visualize([{\"material\": cluster, \"title\": f\"Cluster\"},\n", |
| 265 | + " {\"material\": cluster, \"title\": f\"Cluster\", \"rotation\": \"-90x\"}])" |
269 | 266 | ],
|
270 | 267 | "metadata": {
|
271 | 268 | "collapsed": false
|
272 | 269 | },
|
273 | 270 | "id": "509b18661a069e42",
|
| 271 | + "outputs": [], |
274 | 272 | "execution_count": null
|
275 | 273 | },
|
276 | 274 | {
|
|
285 | 283 | },
|
286 | 284 | {
|
287 | 285 | "cell_type": "code",
|
288 |
| - "outputs": [], |
289 | 286 | "source": [
|
290 | 287 | "from utils.jupyterlite import set_materials\n",
|
291 | 288 | "\n",
|
|
296 | 293 | "collapsed": false
|
297 | 294 | },
|
298 | 295 | "id": "61daa5afcbc078a9",
|
| 296 | + "outputs": [], |
299 | 297 | "execution_count": null
|
300 | 298 | }
|
301 | 299 | ],
|
|
0 commit comments