mphkit 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mphkit-0.1.0 → mphkit-0.2.0}/PKG-INFO +44 -25
- {mphkit-0.1.0 → mphkit-0.2.0}/README.md +42 -24
- {mphkit-0.1.0 → mphkit-0.2.0}/pyproject.toml +6 -2
- {mphkit-0.1.0 → mphkit-0.2.0}/pyproject.toml.orig +6 -2
- mphkit-0.2.0/src/mphkit/__init__.py +117 -0
- {mphkit-0.1.0 → mphkit-0.2.0}/src/mphkit/_comsol.py +178 -35
- {mphkit-0.1.0 → mphkit-0.2.0}/src/mphkit/_expr.py +5 -2
- mphkit-0.2.0/src/mphkit/_hints.py +274 -0
- mphkit-0.2.0/src/mphkit/_image.py +208 -0
- mphkit-0.2.0/src/mphkit/_measure.py +185 -0
- {mphkit-0.1.0 → mphkit-0.2.0}/src/mphkit/_props.py +13 -11
- {mphkit-0.1.0 → mphkit-0.2.0}/src/mphkit/_sel.py +247 -67
- {mphkit-0.1.0 → mphkit-0.2.0}/src/mphkit/geometry.py +109 -50
- {mphkit-0.1.0 → mphkit-0.2.0}/src/mphkit/sel.py +20 -12
- mphkit-0.1.0/src/mphkit/__init__.py +0 -23
- mphkit-0.1.0/src/mphkit/_measure.py +0 -102
- {mphkit-0.1.0 → mphkit-0.2.0}/LICENSE +0 -0
- {mphkit-0.1.0 → mphkit-0.2.0}/src/mphkit/errors.py +0 -0
- {mphkit-0.1.0 → mphkit-0.2.0}/src/mphkit/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mphkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Helpers on top of MPh for building COMSOL geometries and geometry-based selections in Python.
|
|
5
5
|
Keywords: comsol,mph,multiphysics,geometry,selection,simulation,fem
|
|
6
6
|
Author: elgar328
|
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
20
|
Classifier: Topic :: Scientific/Engineering
|
|
20
21
|
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
21
22
|
Classifier: Typing :: Typed
|
|
@@ -30,14 +31,19 @@ Description-Content-Type: text/markdown
|
|
|
30
31
|
|
|
31
32
|
# mphkit
|
|
32
33
|
|
|
34
|
+
[](https://pypi.org/project/mphkit/)
|
|
35
|
+
[](https://pypi.org/project/mphkit/)
|
|
36
|
+
[](https://github.com/elgar328/mphkit/blob/main/LICENSE)
|
|
37
|
+
[](https://www.comsol.com/)
|
|
38
|
+
|
|
33
39
|
Helpers on top of [MPh](https://github.com/MPh-py/MPh) for building COMSOL
|
|
34
40
|
geometries and geometry-based selections in Python. Select boundaries by
|
|
35
41
|
location instead of by entity number, so selections keep working when the
|
|
36
42
|
geometry changes.
|
|
37
43
|
|
|
38
44
|
> [!WARNING]
|
|
39
|
-
> **Early stage.**
|
|
40
|
-
>
|
|
45
|
+
> **Early stage.** The API may change at any time, without deprecation
|
|
46
|
+
> warnings.
|
|
41
47
|
|
|
42
48
|
Not affiliated with COMSOL AB.
|
|
43
49
|
|
|
@@ -60,13 +66,18 @@ bottom = mk.sel.box(geom, 'boundary', z=0) # faces on the plane z = 0
|
|
|
60
66
|
|
|
61
67
|
# plain MPh from here on
|
|
62
68
|
physics = (model/'physics').create('HeatTransfer', geom)
|
|
63
|
-
physics.create('TemperatureBoundary', 2).select(bottom)
|
|
69
|
+
physics.create('TemperatureBoundary', 2).select(bottom) # 2: boundaries in 3D
|
|
64
70
|
model.save('demo.mph')
|
|
65
71
|
```
|
|
66
72
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
plain MPh (or the
|
|
73
|
+
Helpers take MPh `Node`s (`mk.geometry` the model, `mk.set` also Java
|
|
74
|
+
objects), and those that create something return one, so mphkit and MPh
|
|
75
|
+
mix freely. Physics, mesh, study and results stay plain MPh (or the
|
|
76
|
+
COMSOL Java API through `node.java`).
|
|
77
|
+
|
|
78
|
+
`help(mphkit)` sums up the workflow, the rules and the common pitfalls,
|
|
79
|
+
and each helper has its own `help()`. Point an AI assistant to
|
|
80
|
+
`help(mphkit)` first.
|
|
70
81
|
|
|
71
82
|
## Requirements
|
|
72
83
|
|
|
@@ -77,10 +88,10 @@ plain MPh (or the COMSOL Java API through `node.java`).
|
|
|
77
88
|
for CAD import (CAD Import Module, Design Module or a LiveLink).
|
|
78
89
|
Everything else needs COMSOL only.
|
|
79
90
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
91
|
+
mphkit is developed and tested with COMSOL 6.4 and MPh 1.4. Feature types,
|
|
92
|
+
property names and selection behavior can differ between COMSOL versions,
|
|
93
|
+
so other versions may need adjustments; reports are welcome. Checked on
|
|
94
|
+
macOS and Windows; it should run wherever MPh runs.
|
|
84
95
|
|
|
85
96
|
## Installation
|
|
86
97
|
|
|
@@ -102,7 +113,7 @@ mk.block(geom, (10, 10, 5)); mk.cylinder(geom, r, h, pos); mk.sphere(geom, r)
|
|
|
102
113
|
mk.union(geom, [a, b]); mk.difference(geom, a, [b]); mk.intersection(geom, [a, b])
|
|
103
114
|
mk.move(geom, part, (10, 0, 0)); mk.rotate(geom, part, 90, axis='z')
|
|
104
115
|
mk.mirror(geom, part, (1, 0, 0)); mk.array(geom, part, size=(5, 5, 1), displ=(10, 10, 0))
|
|
105
|
-
mk.fillet(geom,
|
|
116
|
+
mk.fillet(geom, part, 0.5); mk.chamfer(geom, part, 0.5) # all edges, or a selection
|
|
106
117
|
mk.partition(geom, part, tool); mk.delete(geom, part)
|
|
107
118
|
plane = mk.workplane(geom, quickz=0)
|
|
108
119
|
mk.circle(plane, 2); mk.extrude(geom, plane, 5); mk.revolve(geom, plane)
|
|
@@ -125,16 +136,27 @@ mk.cylinder(geom, 1, 5, pos, contributeto=holes) # collect from several feature
|
|
|
125
136
|
`where='geometry'` makes a selection inside the geometry sequence instead,
|
|
126
137
|
for use as input of a later operation, e.g. `mk.sel.box(geom, 'object',
|
|
127
138
|
x=(20, 40), where='geometry')` to pick whole objects for `mk.delete`. In a
|
|
128
|
-
work plane, selections pick single corners or edges
|
|
129
|
-
`mk.fillet(plane, mk.sel.box(plane, 'point', x=1, y=1), 0.3)`.
|
|
139
|
+
work plane, selections can pick single corners or edges, e.g. to fillet
|
|
140
|
+
one corner: `mk.fillet(plane, mk.sel.box(plane, 'point', x=1, y=1), 0.3)`.
|
|
130
141
|
|
|
131
|
-
Queries
|
|
142
|
+
Queries on the plate from the Example section return plain Python values
|
|
143
|
+
and leave nothing in the model:
|
|
132
144
|
|
|
133
145
|
```python
|
|
134
146
|
mk.sel.entities(geom, bottom) # [3]
|
|
135
|
-
mk.sel.find(geom, '
|
|
136
|
-
mk.measure(geom, 'domain') # volume
|
|
137
|
-
mk.bounding_box(geom, 'boundary', 3) # {'x': (0,
|
|
147
|
+
mk.sel.find(geom, 'boundary', x=0) # [1]: the face at x = 0
|
|
148
|
+
mk.measure(geom, 'domain') # 99216.5: volume, approximate where curved
|
|
149
|
+
mk.bounding_box(geom, 'boundary', 3) # {'x': (0.0, 100.0), 'y': ..., 'z': (0.0, 0.0)}
|
|
150
|
+
mk.summary(geom) # counts, voids, bounding box, unit
|
|
151
|
+
mk.sel.neighbors(geom, 'domain', boundary=3) # [1]: the domain beside it
|
|
152
|
+
mk.coordinates(geom, 'boundary', 3) # {1: (0.0, 0.0, 0.0), 3: (0.0, 100.0, 0.0), ...}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Pictures, written to a file:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
mk.image(geom, 'geom.png') # the geometry
|
|
159
|
+
mk.image(geom, 'selection.png', selection, labels=True) # with numbers
|
|
138
160
|
```
|
|
139
161
|
|
|
140
162
|
And a few helpers outside geometry:
|
|
@@ -144,21 +166,18 @@ mk.coordinate_system(geom, 'PML', selection=layer) # e.g. perfectly matched la
|
|
|
144
166
|
mk.set(mesh_size, hmax=0.5, hgrad=2) # any node or Java object; converts ints and lists
|
|
145
167
|
```
|
|
146
168
|
|
|
147
|
-
Arguments are COMSOL property names, so the COMSOL documentation of each
|
|
148
|
-
feature applies. The docstrings describe each helper in detail.
|
|
149
|
-
|
|
150
169
|
[`examples/plate_with_holes.py`](https://github.com/elgar328/mphkit/blob/main/examples/plate_with_holes.py)
|
|
151
170
|
is a complete script, from geometry to solved results: heat conduction in
|
|
152
|
-
a plate with a row of cooling holes, for
|
|
171
|
+
a plate with a row of cooling holes, for one or more holes.
|
|
153
172
|
|
|
154
173
|
## Limitations
|
|
155
174
|
|
|
156
|
-
- mphkit covers geometry and selections
|
|
175
|
+
- mphkit covers geometry and selections. Physics, mesh, studies and
|
|
157
176
|
results are left to MPh.
|
|
158
177
|
- No named helpers yet for geometry parts (`PartInstance`), sweeps, cones
|
|
159
178
|
and the other remaining primitives, virtual operations or repair. They
|
|
160
|
-
work through `mk.feature(geom, 'Sweep', ...)
|
|
161
|
-
|
|
179
|
+
work through `mk.feature(geom, 'Sweep', ...)`, which handles arguments
|
|
180
|
+
like the named helpers (expressions, lists, nodes as inputs).
|
|
162
181
|
|
|
163
182
|
## Development
|
|
164
183
|
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
# mphkit
|
|
2
2
|
|
|
3
|
+
[](https://pypi.org/project/mphkit/)
|
|
4
|
+
[](https://pypi.org/project/mphkit/)
|
|
5
|
+
[](https://github.com/elgar328/mphkit/blob/main/LICENSE)
|
|
6
|
+
[](https://www.comsol.com/)
|
|
7
|
+
|
|
3
8
|
Helpers on top of [MPh](https://github.com/MPh-py/MPh) for building COMSOL
|
|
4
9
|
geometries and geometry-based selections in Python. Select boundaries by
|
|
5
10
|
location instead of by entity number, so selections keep working when the
|
|
6
11
|
geometry changes.
|
|
7
12
|
|
|
8
13
|
> [!WARNING]
|
|
9
|
-
> **Early stage.**
|
|
10
|
-
>
|
|
14
|
+
> **Early stage.** The API may change at any time, without deprecation
|
|
15
|
+
> warnings.
|
|
11
16
|
|
|
12
17
|
Not affiliated with COMSOL AB.
|
|
13
18
|
|
|
@@ -30,13 +35,18 @@ bottom = mk.sel.box(geom, 'boundary', z=0) # faces on the plane z = 0
|
|
|
30
35
|
|
|
31
36
|
# plain MPh from here on
|
|
32
37
|
physics = (model/'physics').create('HeatTransfer', geom)
|
|
33
|
-
physics.create('TemperatureBoundary', 2).select(bottom)
|
|
38
|
+
physics.create('TemperatureBoundary', 2).select(bottom) # 2: boundaries in 3D
|
|
34
39
|
model.save('demo.mph')
|
|
35
40
|
```
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
plain MPh (or the
|
|
42
|
+
Helpers take MPh `Node`s (`mk.geometry` the model, `mk.set` also Java
|
|
43
|
+
objects), and those that create something return one, so mphkit and MPh
|
|
44
|
+
mix freely. Physics, mesh, study and results stay plain MPh (or the
|
|
45
|
+
COMSOL Java API through `node.java`).
|
|
46
|
+
|
|
47
|
+
`help(mphkit)` sums up the workflow, the rules and the common pitfalls,
|
|
48
|
+
and each helper has its own `help()`. Point an AI assistant to
|
|
49
|
+
`help(mphkit)` first.
|
|
40
50
|
|
|
41
51
|
## Requirements
|
|
42
52
|
|
|
@@ -47,10 +57,10 @@ plain MPh (or the COMSOL Java API through `node.java`).
|
|
|
47
57
|
for CAD import (CAD Import Module, Design Module or a LiveLink).
|
|
48
58
|
Everything else needs COMSOL only.
|
|
49
59
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
60
|
+
mphkit is developed and tested with COMSOL 6.4 and MPh 1.4. Feature types,
|
|
61
|
+
property names and selection behavior can differ between COMSOL versions,
|
|
62
|
+
so other versions may need adjustments; reports are welcome. Checked on
|
|
63
|
+
macOS and Windows; it should run wherever MPh runs.
|
|
54
64
|
|
|
55
65
|
## Installation
|
|
56
66
|
|
|
@@ -72,7 +82,7 @@ mk.block(geom, (10, 10, 5)); mk.cylinder(geom, r, h, pos); mk.sphere(geom, r)
|
|
|
72
82
|
mk.union(geom, [a, b]); mk.difference(geom, a, [b]); mk.intersection(geom, [a, b])
|
|
73
83
|
mk.move(geom, part, (10, 0, 0)); mk.rotate(geom, part, 90, axis='z')
|
|
74
84
|
mk.mirror(geom, part, (1, 0, 0)); mk.array(geom, part, size=(5, 5, 1), displ=(10, 10, 0))
|
|
75
|
-
mk.fillet(geom,
|
|
85
|
+
mk.fillet(geom, part, 0.5); mk.chamfer(geom, part, 0.5) # all edges, or a selection
|
|
76
86
|
mk.partition(geom, part, tool); mk.delete(geom, part)
|
|
77
87
|
plane = mk.workplane(geom, quickz=0)
|
|
78
88
|
mk.circle(plane, 2); mk.extrude(geom, plane, 5); mk.revolve(geom, plane)
|
|
@@ -95,16 +105,27 @@ mk.cylinder(geom, 1, 5, pos, contributeto=holes) # collect from several feature
|
|
|
95
105
|
`where='geometry'` makes a selection inside the geometry sequence instead,
|
|
96
106
|
for use as input of a later operation, e.g. `mk.sel.box(geom, 'object',
|
|
97
107
|
x=(20, 40), where='geometry')` to pick whole objects for `mk.delete`. In a
|
|
98
|
-
work plane, selections pick single corners or edges
|
|
99
|
-
`mk.fillet(plane, mk.sel.box(plane, 'point', x=1, y=1), 0.3)`.
|
|
108
|
+
work plane, selections can pick single corners or edges, e.g. to fillet
|
|
109
|
+
one corner: `mk.fillet(plane, mk.sel.box(plane, 'point', x=1, y=1), 0.3)`.
|
|
100
110
|
|
|
101
|
-
Queries
|
|
111
|
+
Queries on the plate from the Example section return plain Python values
|
|
112
|
+
and leave nothing in the model:
|
|
102
113
|
|
|
103
114
|
```python
|
|
104
115
|
mk.sel.entities(geom, bottom) # [3]
|
|
105
|
-
mk.sel.find(geom, '
|
|
106
|
-
mk.measure(geom, 'domain') # volume
|
|
107
|
-
mk.bounding_box(geom, 'boundary', 3) # {'x': (0,
|
|
116
|
+
mk.sel.find(geom, 'boundary', x=0) # [1]: the face at x = 0
|
|
117
|
+
mk.measure(geom, 'domain') # 99216.5: volume, approximate where curved
|
|
118
|
+
mk.bounding_box(geom, 'boundary', 3) # {'x': (0.0, 100.0), 'y': ..., 'z': (0.0, 0.0)}
|
|
119
|
+
mk.summary(geom) # counts, voids, bounding box, unit
|
|
120
|
+
mk.sel.neighbors(geom, 'domain', boundary=3) # [1]: the domain beside it
|
|
121
|
+
mk.coordinates(geom, 'boundary', 3) # {1: (0.0, 0.0, 0.0), 3: (0.0, 100.0, 0.0), ...}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Pictures, written to a file:
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
mk.image(geom, 'geom.png') # the geometry
|
|
128
|
+
mk.image(geom, 'selection.png', selection, labels=True) # with numbers
|
|
108
129
|
```
|
|
109
130
|
|
|
110
131
|
And a few helpers outside geometry:
|
|
@@ -114,21 +135,18 @@ mk.coordinate_system(geom, 'PML', selection=layer) # e.g. perfectly matched la
|
|
|
114
135
|
mk.set(mesh_size, hmax=0.5, hgrad=2) # any node or Java object; converts ints and lists
|
|
115
136
|
```
|
|
116
137
|
|
|
117
|
-
Arguments are COMSOL property names, so the COMSOL documentation of each
|
|
118
|
-
feature applies. The docstrings describe each helper in detail.
|
|
119
|
-
|
|
120
138
|
[`examples/plate_with_holes.py`](https://github.com/elgar328/mphkit/blob/main/examples/plate_with_holes.py)
|
|
121
139
|
is a complete script, from geometry to solved results: heat conduction in
|
|
122
|
-
a plate with a row of cooling holes, for
|
|
140
|
+
a plate with a row of cooling holes, for one or more holes.
|
|
123
141
|
|
|
124
142
|
## Limitations
|
|
125
143
|
|
|
126
|
-
- mphkit covers geometry and selections
|
|
144
|
+
- mphkit covers geometry and selections. Physics, mesh, studies and
|
|
127
145
|
results are left to MPh.
|
|
128
146
|
- No named helpers yet for geometry parts (`PartInstance`), sweeps, cones
|
|
129
147
|
and the other remaining primitives, virtual operations or repair. They
|
|
130
|
-
work through `mk.feature(geom, 'Sweep', ...)
|
|
131
|
-
|
|
148
|
+
work through `mk.feature(geom, 'Sweep', ...)`, which handles arguments
|
|
149
|
+
like the named helpers (expressions, lists, nodes as inputs).
|
|
132
150
|
|
|
133
151
|
## Development
|
|
134
152
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mphkit"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.0"
|
|
4
4
|
description = "Helpers on top of MPh for building COMSOL geometries and geometry-based selections in Python."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -30,6 +30,7 @@ classifiers = [
|
|
|
30
30
|
"Programming Language :: Python :: 3.11",
|
|
31
31
|
"Programming Language :: Python :: 3.12",
|
|
32
32
|
"Programming Language :: Python :: 3.13",
|
|
33
|
+
"Programming Language :: Python :: 3.14",
|
|
33
34
|
"Topic :: Scientific/Engineering",
|
|
34
35
|
"Topic :: Scientific/Engineering :: Physics",
|
|
35
36
|
"Typing :: Typed",
|
|
@@ -45,7 +46,10 @@ Changelog = "https://github.com/elgar328/mphkit/blob/main/CHANGELOG.md"
|
|
|
45
46
|
Issues = "https://github.com/elgar328/mphkit/issues"
|
|
46
47
|
|
|
47
48
|
[dependency-groups]
|
|
48
|
-
dev = [
|
|
49
|
+
dev = [
|
|
50
|
+
"mypy>=2.3.1",
|
|
51
|
+
"pytest>=8",
|
|
52
|
+
]
|
|
49
53
|
|
|
50
54
|
[build-system]
|
|
51
55
|
requires = ["uv_build>=0.9.9,<0.13"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mphkit"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.0"
|
|
4
4
|
description = "Helpers on top of MPh for building COMSOL geometries and geometry-based selections in Python."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "elgar328" }]
|
|
@@ -21,6 +21,7 @@ classifiers = [
|
|
|
21
21
|
"Programming Language :: Python :: 3.11",
|
|
22
22
|
"Programming Language :: Python :: 3.12",
|
|
23
23
|
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Programming Language :: Python :: 3.14",
|
|
24
25
|
"Topic :: Scientific/Engineering",
|
|
25
26
|
"Topic :: Scientific/Engineering :: Physics",
|
|
26
27
|
"Typing :: Typed",
|
|
@@ -33,7 +34,10 @@ Changelog = "https://github.com/elgar328/mphkit/blob/main/CHANGELOG.md"
|
|
|
33
34
|
Issues = "https://github.com/elgar328/mphkit/issues"
|
|
34
35
|
|
|
35
36
|
[dependency-groups]
|
|
36
|
-
dev = [
|
|
37
|
+
dev = [
|
|
38
|
+
"mypy>=2.3.1",
|
|
39
|
+
"pytest>=8",
|
|
40
|
+
]
|
|
37
41
|
|
|
38
42
|
[build-system]
|
|
39
43
|
requires = ["uv_build>=0.9.9,<0.13"]
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Helpers on top of MPh for building COMSOL geometries and selections.
|
|
3
|
+
|
|
4
|
+
mphkit builds geometry and named selections; physics, mesh, studies and
|
|
5
|
+
results stay plain MPh (or the COMSOL Java API through `node.java`).
|
|
6
|
+
Helpers take MPh nodes (`mk.geometry` the model, `mk.set` also Java
|
|
7
|
+
objects), and those that create something return one.
|
|
8
|
+
|
|
9
|
+
import mph
|
|
10
|
+
import mphkit as mk
|
|
11
|
+
|
|
12
|
+
client = mph.start()
|
|
13
|
+
model = client.create('demo')
|
|
14
|
+
geom = mk.geometry(model, 3, length_unit='mm')
|
|
15
|
+
plate = mk.block(geom, (100, 100, 10))
|
|
16
|
+
hole = mk.cylinder(geom, 5, 10, (50, 50, 0))
|
|
17
|
+
mk.difference(geom, plate, [hole])
|
|
18
|
+
model.build(geom)
|
|
19
|
+
bottom = mk.sel.box(geom, 'boundary', z=0) # select by location
|
|
20
|
+
physics = (model/'physics').create('HeatTransfer', geom)
|
|
21
|
+
# 2: boundaries in 3D
|
|
22
|
+
physics.create('TemperatureBoundary', 2).select(bottom)
|
|
23
|
+
|
|
24
|
+
Rules:
|
|
25
|
+
|
|
26
|
+
- Select entities by location with `mk.sel` (box, ball, cylinder, disk,
|
|
27
|
+
adjacent, set operations), never by entity number: numbers change with
|
|
28
|
+
the geometry, selections are re-evaluated by COMSOL.
|
|
29
|
+
- Besides locations, `mk.sel.result` selects what a feature left in the
|
|
30
|
+
geometry and `mk.sel.cumulative` collects groups across operations
|
|
31
|
+
(features join with `contributeto=`).
|
|
32
|
+
- Entity kinds are COMSOL's: 'domain' (volumes in 3D, areas in 2D),
|
|
33
|
+
'boundary' (faces in 3D, edges in 2D, where 'edge' means the same),
|
|
34
|
+
'edge', 'point' (vertices). Physics features take the level as a
|
|
35
|
+
number: 3 for domains and 2 for boundaries in 3D, 2 and 1 in 2D.
|
|
36
|
+
- Objects that touch or overlap stay separate domains, even after
|
|
37
|
+
`mk.union`; merge them with `mk.union(geom, [a, b], intbnd=False)`,
|
|
38
|
+
which also removes layers and partition cuts of its inputs. A full
|
|
39
|
+
`mk.revolve` (no `angle`) keeps its cross-section as an interior face
|
|
40
|
+
unless `origfaces=False`.
|
|
41
|
+
- Extra keyword arguments are COMSOL property names (`intbnd`, `keep`,
|
|
42
|
+
`layername`, `base`, ...); an unknown name raises an error that often
|
|
43
|
+
suggests the right one.
|
|
44
|
+
- Sizes, positions, angles and counts may be numbers or COMSOL expressions
|
|
45
|
+
with parameters and units, e.g. `'L-2*t'` or `'5[mm]'`; define
|
|
46
|
+
parameters with `model.parameter('t', '0.3[mm]')`.
|
|
47
|
+
- Sizes and coordinates are in the geometry's length unit.
|
|
48
|
+
- Build the geometry (`model.build(geom)`) before querying it, and again
|
|
49
|
+
after adding a `where='geometry'` selection.
|
|
50
|
+
|
|
51
|
+
Check the result from code:
|
|
52
|
+
|
|
53
|
+
- `mk.sel.entities(geom, selection)`: entity numbers of a selection
|
|
54
|
+
- `mk.sel.find(geom, 'domain', x=...)`: entity numbers inside a box
|
|
55
|
+
- `mk.measure(geom, 'domain')`: volume, area or length
|
|
56
|
+
- `mk.bounding_box(geom, 'boundary', 3)`: extents
|
|
57
|
+
- `mk.summary(geom)`: counts, voids, size
|
|
58
|
+
- `mk.sel.neighbors(geom, 'domain', boundary=3)`: adjacent entities
|
|
59
|
+
- `mk.coordinates(geom, 'boundary', 3)`: vertex coordinates
|
|
60
|
+
- `mk.image(geom, 'geom.png')`: a picture of the geometry
|
|
61
|
+
- `mk.image(geom, 'selection.png', selection, labels=True)`: a selection
|
|
62
|
+
highlighted, with entity numbers
|
|
63
|
+
|
|
64
|
+
Curved entities are measured approximately (see `help(mk.measure)`).
|
|
65
|
+
`mk.measure` and `mk.bounding_box` use single precision, about seven
|
|
66
|
+
digits of the coordinates (`mk.bounding_box` of points excepted);
|
|
67
|
+
`mk.coordinates` and `mk.summary` use double precision. Compare with a
|
|
68
|
+
tolerance either way.
|
|
69
|
+
|
|
70
|
+
Selection tips: `mk.sel.result(geom, feature, 'boundary')` gives the faces
|
|
71
|
+
that an object and its copies leave in the geometry, curved ones
|
|
72
|
+
included, and the faces it cuts into other objects, e.g. the spherical
|
|
73
|
+
faces a subtracted sphere leaves in a block. Curved surfaces are split
|
|
74
|
+
into several faces: the side of a cylinder or cone, the wall of a hole or
|
|
75
|
+
of an extruded circle into four, a sphere into eight. For the side of a
|
|
76
|
+
cylinder that no other object cut, use a thin shell:
|
|
77
|
+
`mk.sel.cylinder(geom, 'boundary', pos, r, rin=0.99*r, bottom=0, top=h,
|
|
78
|
+
name='side')` (`rin` needs about 1 % room, see
|
|
79
|
+
`help(mk.sel.cylinder)`; a name avoids a clash with the cylinder's own
|
|
80
|
+
label).
|
|
81
|
+
|
|
82
|
+
More: `help(mk.sel)` for selections (also in work planes), `help(mk.block)`
|
|
83
|
+
etc. for each helper, `mk.feature(geom, 'Type', ...)` for any other
|
|
84
|
+
geometry feature, `mk.set(node_or_java, **properties)` to set properties
|
|
85
|
+
of anything else (mesh, study, material, probe), and `node.java` for the
|
|
86
|
+
rest of the COMSOL API.
|
|
87
|
+
"""
|
|
88
|
+
import sys as _sys
|
|
89
|
+
|
|
90
|
+
from . import sel
|
|
91
|
+
from ._hints import HintModule as _HintModule
|
|
92
|
+
from ._image import image
|
|
93
|
+
from ._measure import bounding_box, coordinates, measure, summary
|
|
94
|
+
from ._props import set_ as set # not in __all__: keeps builtin set
|
|
95
|
+
from .errors import LicenseError
|
|
96
|
+
from .geometry import (array, block, chamfer, circle, component_of,
|
|
97
|
+
coordinate_system, cylinder, delete, difference,
|
|
98
|
+
extrude, feature, fillet, geometry, import_,
|
|
99
|
+
intersection, interval, line_segment, mirror, move,
|
|
100
|
+
partition, point, polygon, rectangle, revolve,
|
|
101
|
+
rigid_transform, rotate, sphere, square, union,
|
|
102
|
+
workplane)
|
|
103
|
+
|
|
104
|
+
__version__ = '0.2.0'
|
|
105
|
+
|
|
106
|
+
__all__ = ['LicenseError', 'array', 'block', 'bounding_box', 'chamfer',
|
|
107
|
+
'circle', 'component_of', 'coordinate_system', 'coordinates',
|
|
108
|
+
'cylinder', 'delete', 'difference', 'extrude', 'feature',
|
|
109
|
+
'fillet', 'geometry', 'image', 'import_', 'intersection',
|
|
110
|
+
'interval', 'line_segment', 'measure', 'mirror', 'move',
|
|
111
|
+
'partition', 'point', 'polygon', 'rectangle', 'revolve',
|
|
112
|
+
'rigid_transform', 'rotate', 'sel', 'sphere', 'square', 'summary',
|
|
113
|
+
'union', 'workplane']
|
|
114
|
+
|
|
115
|
+
# Unknown names raise errors that name the right helper (see _hints).
|
|
116
|
+
_sys.modules[__name__].__class__ = _HintModule
|
|
117
|
+
del _sys, _HintModule
|