|
2 | 2 | "cells": [ |
3 | 3 | { |
4 | 4 | "cell_type": "code", |
5 | | - "execution_count": null, |
| 5 | + "execution_count": 43, |
6 | 6 | "metadata": {}, |
7 | | - "outputs": [], |
| 7 | + "outputs": [ |
| 8 | + { |
| 9 | + "name": "stdout", |
| 10 | + "output_type": "stream", |
| 11 | + "text": [ |
| 12 | + "Requirement already satisfied: jsonschema in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (4.22.0)\n", |
| 13 | + "Requirement already satisfied: networkx in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (3.3)\n", |
| 14 | + "Requirement already satisfied: numpy in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (1.26.4)\n", |
| 15 | + "Requirement already satisfied: scipy in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (1.14.0)\n", |
| 16 | + "Requirement already satisfied: pythreejs in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (2.4.2)\n", |
| 17 | + "Requirement already satisfied: attrs>=22.2.0 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from jsonschema) (23.2.0)\n", |
| 18 | + "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from jsonschema) (2023.12.1)\n", |
| 19 | + "Requirement already satisfied: referencing>=0.28.4 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from jsonschema) (0.35.1)\n", |
| 20 | + "Requirement already satisfied: rpds-py>=0.7.1 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from jsonschema) (0.18.1)\n", |
| 21 | + "Requirement already satisfied: ipywidgets>=7.2.1 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from pythreejs) (8.1.2)\n", |
| 22 | + "Requirement already satisfied: ipydatawidgets>=1.1.1 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from pythreejs) (4.3.5)\n", |
| 23 | + "Requirement already satisfied: traitlets in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from pythreejs) (5.14.2)\n", |
| 24 | + "Requirement already satisfied: traittypes>=0.2.0 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from ipydatawidgets>=1.1.1->pythreejs) (0.2.1)\n", |
| 25 | + "Requirement already satisfied: comm>=0.1.3 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from ipywidgets>=7.2.1->pythreejs) (0.2.2)\n", |
| 26 | + "Requirement already satisfied: ipython>=6.1.0 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from ipywidgets>=7.2.1->pythreejs) (8.18.0)\n", |
| 27 | + "Requirement already satisfied: widgetsnbextension~=4.0.10 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from ipywidgets>=7.2.1->pythreejs) (4.0.10)\n", |
| 28 | + "Requirement already satisfied: jupyterlab-widgets~=3.0.10 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from ipywidgets>=7.2.1->pythreejs) (3.0.10)\n", |
| 29 | + "Requirement already satisfied: decorator in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (5.1.1)\n", |
| 30 | + "Requirement already satisfied: jedi>=0.16 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (0.19.1)\n", |
| 31 | + "Requirement already satisfied: matplotlib-inline in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (0.1.7)\n", |
| 32 | + "Requirement already satisfied: prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (3.0.36)\n", |
| 33 | + "Requirement already satisfied: pygments>=2.4.0 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (2.17.2)\n", |
| 34 | + "Requirement already satisfied: stack-data in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (0.6.3)\n", |
| 35 | + "Requirement already satisfied: pexpect>4.3 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (4.9.0)\n", |
| 36 | + "Requirement already satisfied: parso<0.9.0,>=0.8.3 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from jedi>=0.16->ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (0.8.4)\n", |
| 37 | + "Requirement already satisfied: ptyprocess>=0.5 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from pexpect>4.3->ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (0.7.0)\n", |
| 38 | + "Requirement already satisfied: wcwidth in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30->ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (0.2.13)\n", |
| 39 | + "Requirement already satisfied: executing>=1.2.0 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from stack-data->ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (2.0.1)\n", |
| 40 | + "Requirement already satisfied: asttokens>=2.1.0 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from stack-data->ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (2.4.1)\n", |
| 41 | + "Requirement already satisfied: pure-eval in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from stack-data->ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (0.2.2)\n", |
| 42 | + "Requirement already satisfied: six>=1.12.0 in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (from asttokens>=2.1.0->stack-data->ipython>=6.1.0->ipywidgets>=7.2.1->pythreejs) (1.16.0)\n", |
| 43 | + "Note: you may need to restart the kernel to use updated packages.\n", |
| 44 | + "zsh:1: 2.8 not found\n", |
| 45 | + "Note: you may need to restart the kernel to use updated packages.\n", |
| 46 | + "Requirement already satisfied: compas_notebook in /Users/vanmelet/opt/miniconda3/envs/compas2/lib/python3.12/site-packages (0.5.0)\n", |
| 47 | + "Note: you may need to restart the kernel to use updated packages.\n", |
| 48 | + "zsh:1: 0.5.0 not found\n", |
| 49 | + "Note: you may need to restart the kernel to use updated packages.\n" |
| 50 | + ] |
| 51 | + } |
| 52 | + ], |
8 | 53 | "source": [ |
9 | 54 | "%pip install jsonschema networkx numpy scipy pythreejs\n", |
10 | | - "%pip install compas>=2.0.0 --no-deps\n", |
| 55 | + "%pip install compas>=2.8 --no-deps\n", |
11 | 56 | "%pip install compas_notebook --no-deps\n", |
12 | 57 | "%pip install compas_fd>=0.5.0 --no-deps" |
13 | 58 | ] |
|
19 | 64 | "# Getting Started with COMPAS FD" |
20 | 65 | ] |
21 | 66 | }, |
| 67 | + { |
| 68 | + "cell_type": "markdown", |
| 69 | + "metadata": {}, |
| 70 | + "source": [ |
| 71 | + "Create a mesh from a grid of vertices and faces in the XY plane." |
| 72 | + ] |
| 73 | + }, |
22 | 74 | { |
23 | 75 | "cell_type": "code", |
24 | | - "execution_count": null, |
| 76 | + "execution_count": 44, |
25 | 77 | "metadata": {}, |
26 | 78 | "outputs": [], |
27 | 79 | "source": [ |
28 | | - "from compas.colors import Color\n", |
29 | 80 | "from compas.datastructures import Mesh\n", |
30 | | - "from compas_fd.solvers import fd_numpy\n", |
31 | | - "from compas_notebook.viewer import Viewer" |
| 81 | + "\n", |
| 82 | + "mesh = Mesh.from_meshgrid(dx=10, nx=10)" |
| 83 | + ] |
| 84 | + }, |
| 85 | + { |
| 86 | + "cell_type": "markdown", |
| 87 | + "metadata": {}, |
| 88 | + "source": [ |
| 89 | + "Move two opposite mesh corners out of the XY plane." |
32 | 90 | ] |
33 | 91 | }, |
34 | 92 | { |
35 | 93 | "cell_type": "code", |
36 | | - "execution_count": null, |
| 94 | + "execution_count": 45, |
37 | 95 | "metadata": {}, |
38 | 96 | "outputs": [], |
39 | 97 | "source": [ |
40 | | - "mesh = Mesh.from_meshgrid(dx=10, nx=10)" |
| 98 | + "vertex = list(mesh.vertices_where(x=0, y=0))[0]\n", |
| 99 | + "mesh.vertex_attribute(vertex, name='z', value=7)\n", |
| 100 | + "\n", |
| 101 | + "vertex = list(mesh.vertices_where(x=10, y=10))[0]\n", |
| 102 | + "mesh.vertex_attribute(vertex, name='z', value=7)" |
| 103 | + ] |
| 104 | + }, |
| 105 | + { |
| 106 | + "cell_type": "markdown", |
| 107 | + "metadata": {}, |
| 108 | + "source": [ |
| 109 | + "Extract the vertex coordinates." |
| 110 | + ] |
| 111 | + }, |
| 112 | + { |
| 113 | + "cell_type": "code", |
| 114 | + "execution_count": 46, |
| 115 | + "metadata": {}, |
| 116 | + "outputs": [], |
| 117 | + "source": [ |
| 118 | + "vertices = mesh.vertices_attributes(\"xyz\")" |
| 119 | + ] |
| 120 | + }, |
| 121 | + { |
| 122 | + "cell_type": "markdown", |
| 123 | + "metadata": {}, |
| 124 | + "source": [ |
| 125 | + "Identify the corners as fixed points, which will be able to provide reaction forces." |
| 126 | + ] |
| 127 | + }, |
| 128 | + { |
| 129 | + "cell_type": "code", |
| 130 | + "execution_count": 47, |
| 131 | + "metadata": {}, |
| 132 | + "outputs": [], |
| 133 | + "source": [ |
| 134 | + "fixed = list(mesh.vertices_where(vertex_degree=2))" |
| 135 | + ] |
| 136 | + }, |
| 137 | + { |
| 138 | + "cell_type": "markdown", |
| 139 | + "metadata": {}, |
| 140 | + "source": [ |
| 141 | + "Create a list of \"zero\" loads." |
41 | 142 | ] |
42 | 143 | }, |
43 | 144 | { |
44 | 145 | "cell_type": "code", |
45 | | - "execution_count": null, |
| 146 | + "execution_count": 48, |
46 | 147 | "metadata": {}, |
47 | 148 | "outputs": [], |
48 | 149 | "source": [ |
49 | | - "vertices = mesh.vertices_attributes(\"xyz\")\n", |
50 | | - "fixed = list(mesh.vertices_where(vertex_degree=2))\n", |
51 | | - "edges = list(mesh.edges())\n", |
52 | 150 | "loads = [[0, 0, 0] for _ in range(len(vertices))]" |
53 | 151 | ] |
54 | 152 | }, |
| 153 | + { |
| 154 | + "cell_type": "markdown", |
| 155 | + "metadata": {}, |
| 156 | + "source": [ |
| 157 | + "Create a list of edges, with each edge defined as a pair of vertex indices." |
| 158 | + ] |
| 159 | + }, |
| 160 | + { |
| 161 | + "cell_type": "code", |
| 162 | + "execution_count": 49, |
| 163 | + "metadata": {}, |
| 164 | + "outputs": [], |
| 165 | + "source": [ |
| 166 | + "edges = list(mesh.edges())" |
| 167 | + ] |
| 168 | + }, |
| 169 | + { |
| 170 | + "cell_type": "markdown", |
| 171 | + "metadata": {}, |
| 172 | + "source": [ |
| 173 | + "Assign force densities to the edges.\n", |
| 174 | + "Use `q=10.0` for edges on the boundary, and `q=1.0` everywhere else." |
| 175 | + ] |
| 176 | + }, |
55 | 177 | { |
56 | 178 | "cell_type": "code", |
57 | | - "execution_count": null, |
| 179 | + "execution_count": 50, |
58 | 180 | "metadata": {}, |
59 | 181 | "outputs": [], |
60 | 182 | "source": [ |
|
66 | 188 | " q.append(1.0)" |
67 | 189 | ] |
68 | 190 | }, |
| 191 | + { |
| 192 | + "cell_type": "markdown", |
| 193 | + "metadata": {}, |
| 194 | + "source": [ |
| 195 | + "Compute equilibrium with the base force density solver of `compas_fd`.\n", |
| 196 | + "The result is stored in a `Result` data class." |
| 197 | + ] |
| 198 | + }, |
69 | 199 | { |
70 | 200 | "cell_type": "code", |
71 | | - "execution_count": null, |
| 201 | + "execution_count": 51, |
72 | 202 | "metadata": {}, |
73 | 203 | "outputs": [], |
74 | 204 | "source": [ |
| 205 | + "from compas_fd.solvers import fd_numpy\n", |
| 206 | + "\n", |
75 | 207 | "result = fd_numpy(\n", |
76 | 208 | " vertices=vertices,\n", |
77 | 209 | " fixed=fixed,\n", |
|
81 | 213 | ")" |
82 | 214 | ] |
83 | 215 | }, |
| 216 | + { |
| 217 | + "cell_type": "markdown", |
| 218 | + "metadata": {}, |
| 219 | + "source": [ |
| 220 | + "Update the original mesh geometry using the vertex coordinates stored in the result." |
| 221 | + ] |
| 222 | + }, |
84 | 223 | { |
85 | 224 | "cell_type": "code", |
86 | | - "execution_count": null, |
| 225 | + "execution_count": 52, |
87 | 226 | "metadata": {}, |
88 | 227 | "outputs": [], |
89 | 228 | "source": [ |
|
93 | 232 | " attr[\"z\"] = result.vertices[vertex, 2]" |
94 | 233 | ] |
95 | 234 | }, |
| 235 | + { |
| 236 | + "cell_type": "markdown", |
| 237 | + "metadata": {}, |
| 238 | + "source": [ |
| 239 | + "Visualize the equilibrium geometry and mark the fixed nodes." |
| 240 | + ] |
| 241 | + }, |
96 | 242 | { |
97 | 243 | "cell_type": "code", |
98 | | - "execution_count": null, |
| 244 | + "execution_count": 59, |
99 | 245 | "metadata": {}, |
100 | | - "outputs": [], |
| 246 | + "outputs": [ |
| 247 | + { |
| 248 | + "data": { |
| 249 | + "application/vnd.jupyter.widget-view+json": { |
| 250 | + "model_id": "99feb14271324048884600a33ef5ad0a", |
| 251 | + "version_major": 2, |
| 252 | + "version_minor": 0 |
| 253 | + }, |
| 254 | + "text/plain": [ |
| 255 | + "VBox(children=(HBox(children=(Button(icon='search-plus', layout=Layout(height='32px', width='48px'), style=But…" |
| 256 | + ] |
| 257 | + }, |
| 258 | + "metadata": {}, |
| 259 | + "output_type": "display_data" |
| 260 | + } |
| 261 | + ], |
101 | 262 | "source": [ |
102 | | - "viewer = Viewer()\n", |
103 | | - "viewer.scene.add(mesh, color=Color.from_hex('#cccccc'))\n", |
| 263 | + "from compas.colors import Color\n", |
| 264 | + "from compas_notebook import Viewer\n", |
| 265 | + "from compas_notebook.config import Config\n", |
| 266 | + "\n", |
| 267 | + "config = Config()\n", |
| 268 | + "config.view.camera.position = [15, -10, 3]\n", |
| 269 | + "config.view.camera.target = [5, 5, 3]\n", |
| 270 | + "config.view.camera.fov = 35\n", |
| 271 | + "\n", |
| 272 | + "viewer = Viewer(config=config)\n", |
| 273 | + "\n", |
| 274 | + "viewer.scene.add(mesh, color=Color.from_hex('#cccccc'), show_edges=True)\n", |
| 275 | + "\n", |
104 | 276 | "for vertex in fixed:\n", |
105 | 277 | " viewer.scene.add(mesh.vertex_point(vertex), color=Color.red())\n", |
106 | | - "viewer.show()" |
| 278 | + "\n", |
| 279 | + "viewer.show()\n", |
| 280 | + "\n", |
| 281 | + "# this is a temp hack until notebook is fixed\n", |
| 282 | + "viewer.camera3.position = [15, -10, 3]\n", |
| 283 | + "viewer.camera3.lookAt([5, 5, 3])\n", |
| 284 | + "viewer.controls3.target = [5, 5, 3]\n" |
107 | 285 | ] |
108 | 286 | } |
109 | 287 | ], |
110 | 288 | "metadata": { |
| 289 | + "kernelspec": { |
| 290 | + "display_name": "compas2", |
| 291 | + "language": "python", |
| 292 | + "name": "python3" |
| 293 | + }, |
111 | 294 | "language_info": { |
112 | | - "name": "python" |
| 295 | + "codemirror_mode": { |
| 296 | + "name": "ipython", |
| 297 | + "version": 3 |
| 298 | + }, |
| 299 | + "file_extension": ".py", |
| 300 | + "mimetype": "text/x-python", |
| 301 | + "name": "python", |
| 302 | + "nbconvert_exporter": "python", |
| 303 | + "pygments_lexer": "ipython3", |
| 304 | + "version": "3.12.1" |
113 | 305 | } |
114 | 306 | }, |
115 | 307 | "nbformat": 4, |
|
0 commit comments