ansys-pyensight-core 0.7.0__tar.gz → 0.7.2__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.
Potentially problematic release.
This version of ansys-pyensight-core might be problematic. Click here for more details.
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/PKG-INFO +1 -3
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/pyproject.toml +1 -3
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/listobj.py +1 -2
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/renderable.py +27 -10
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/session.py +12 -2
- ansys_pyensight_core-0.7.2/src/ansys/pyensight/core/utils/parts.py +900 -0
- ansys_pyensight_core-0.7.0/src/ansys/pyensight/core/utils/parts.py +0 -124
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/LICENSE +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/README.rst +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/__init__.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/deep_pixel_view.html +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/dockerlauncher.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/enscontext.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/enshell_grpc.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/ensight_grpc.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/ensobj.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/launch_ensight.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/launcher.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/locallauncher.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/py.typed +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/sgeo_poll.html +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/utils/__init__.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/utils/adr.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/utils/export.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/utils/query.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/utils/support.py +0 -0
- {ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/utils/views.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ansys-pyensight-core
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
4
4
|
Summary: A python wrapper for Ansys EnSight
|
|
5
5
|
Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
6
6
|
Maintainer-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
@@ -20,8 +20,6 @@ Requires-Dist: ansys-api-pyensight==0.3.2
|
|
|
20
20
|
Requires-Dist: requests>=2.28.2
|
|
21
21
|
Requires-Dist: docker>=6.1.0
|
|
22
22
|
Requires-Dist: urllib3<2
|
|
23
|
-
Requires-Dist: typing>=3.7.4.3
|
|
24
|
-
Requires-Dist: typing-extensions>=4.5.0
|
|
25
23
|
Requires-Dist: numpy>=1.21.0
|
|
26
24
|
Requires-Dist: Pillow>=9.3.0
|
|
27
25
|
Requires-Dist: build>=0.10.0 ; extra == "dev"
|
|
@@ -6,7 +6,7 @@ build-backend = "flit_core.buildapi"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "ansys-pyensight-core"
|
|
9
|
-
version = "0.7.
|
|
9
|
+
version = "0.7.2"
|
|
10
10
|
description = "A python wrapper for Ansys EnSight"
|
|
11
11
|
readme = "README.rst"
|
|
12
12
|
requires-python = ">=3.9,<4"
|
|
@@ -31,8 +31,6 @@ dependencies = [
|
|
|
31
31
|
"requests>=2.28.2",
|
|
32
32
|
"docker>=6.1.0",
|
|
33
33
|
"urllib3<2",
|
|
34
|
-
"typing>=3.7.4.3",
|
|
35
|
-
"typing-extensions>=4.5.0",
|
|
36
34
|
"numpy>=1.21.0",
|
|
37
35
|
"Pillow>=9.3.0"
|
|
38
36
|
]
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/listobj.py
RENAMED
|
@@ -5,10 +5,9 @@ Emulation of the EnSight ensobjlist class
|
|
|
5
5
|
"""
|
|
6
6
|
from collections.abc import Iterable
|
|
7
7
|
import fnmatch
|
|
8
|
-
from typing import Any, List, Optional, TypeVar, no_type_check, overload
|
|
8
|
+
from typing import Any, List, Optional, SupportsIndex, TypeVar, no_type_check, overload
|
|
9
9
|
|
|
10
10
|
from ansys.pyensight.core.ensobj import ENSOBJ
|
|
11
|
-
from typing_extensions import SupportsIndex
|
|
12
11
|
|
|
13
12
|
T = TypeVar("T")
|
|
14
13
|
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/renderable.py
RENAMED
|
@@ -525,15 +525,11 @@ class RenderableWebGL(Renderable):
|
|
|
525
525
|
|
|
526
526
|
|
|
527
527
|
class RenderableVNC(Renderable):
|
|
528
|
-
"""Generates
|
|
528
|
+
"""Generates an ansys-nexus-viewer component that can be used to connect to the EnSight VNC remote image renderer."""
|
|
529
529
|
|
|
530
530
|
def __init__(self, *args, **kwargs) -> None:
|
|
531
531
|
super().__init__(*args, **kwargs)
|
|
532
|
-
self.
|
|
533
|
-
"autoconnect": "true",
|
|
534
|
-
"host": self._session.html_hostname,
|
|
535
|
-
"port": self._session.ws_port,
|
|
536
|
-
}
|
|
532
|
+
self._generate_url()
|
|
537
533
|
self._rendertype = "remote"
|
|
538
534
|
self.update()
|
|
539
535
|
|
|
@@ -544,10 +540,31 @@ class RenderableVNC(Renderable):
|
|
|
544
540
|
iframe reference.
|
|
545
541
|
|
|
546
542
|
"""
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
543
|
+
optional_query = self._get_query_parameters_str()
|
|
544
|
+
|
|
545
|
+
html = f"<script src='/ansys/nexus/viewer-loader.js{optional_query}'></script>\n"
|
|
546
|
+
rest_uri = (
|
|
547
|
+
f"{self._http_protocol}://{self._session.html_hostname}:{self._session.html_port}"
|
|
548
|
+
)
|
|
549
|
+
ws_uri = f"{self._http_protocol}://{self._session.html_hostname}:{self._session.ws_port}"
|
|
550
|
+
|
|
551
|
+
query_args = ""
|
|
552
|
+
if self._using_proxy and optional_query:
|
|
553
|
+
query_args = f', "extra_query_args":"{optional_query[1:]}"'
|
|
554
|
+
|
|
555
|
+
attributes = ' renderer="envnc"'
|
|
556
|
+
attributes += ' ui="simple"'
|
|
557
|
+
attributes += ' active="true"'
|
|
558
|
+
attributes += (
|
|
559
|
+
" renderer_options='"
|
|
560
|
+
+ f'{{ "ws":"{ws_uri}", "http":"{rest_uri}", "security_token":"{self._session.secret_key}", "connect_to_running_ens":true {query_args} }}'
|
|
561
|
+
+ "'"
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
html += f"<ansys-nexus-viewer {attributes}></ansys-nexus-viewer>\n"
|
|
565
|
+
|
|
566
|
+
# refresh the remote HTML
|
|
567
|
+
self._save_remote_html_page(html)
|
|
551
568
|
super().update()
|
|
552
569
|
|
|
553
570
|
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/session.py
RENAMED
|
@@ -1510,6 +1510,13 @@ class Session:
|
|
|
1510
1510
|
tail = s.find(", cached:yes")
|
|
1511
1511
|
if tail == -1:
|
|
1512
1512
|
break
|
|
1513
|
+
# Subtype (PartType:, AnnotType:, ToolType:)
|
|
1514
|
+
subtype = None
|
|
1515
|
+
for name in ("PartType:", "AnnotType:", "ToolType:"):
|
|
1516
|
+
location = s.find(name)
|
|
1517
|
+
if (location != -1) and (location > id):
|
|
1518
|
+
subtype = int(s[location + len(name) :].split(",")[0])
|
|
1519
|
+
break
|
|
1513
1520
|
# isolate the block to replace
|
|
1514
1521
|
prefix = s[:start]
|
|
1515
1522
|
suffix = s[tail + tail_len :]
|
|
@@ -1526,8 +1533,11 @@ class Session:
|
|
|
1526
1533
|
else:
|
|
1527
1534
|
subclass_info = ""
|
|
1528
1535
|
if attr_id is not None:
|
|
1529
|
-
|
|
1530
|
-
|
|
1536
|
+
if subtype is not None:
|
|
1537
|
+
# the 2024 R2 interface includes the subtype
|
|
1538
|
+
subclass_info = f",attr_id={attr_id}, attr_value={subtype}"
|
|
1539
|
+
elif classname_lookup is not None:
|
|
1540
|
+
# if a "subclass" case and no subclass attrid value, ask for it...
|
|
1531
1541
|
remote_name = self.remote_obj(objid)
|
|
1532
1542
|
cmd = f"{remote_name}.getattr({attr_id})"
|
|
1533
1543
|
attr_value = self.cmd(cmd)
|
|
@@ -0,0 +1,900 @@
|
|
|
1
|
+
"""Parts module.
|
|
2
|
+
|
|
3
|
+
This module allows PyEnSight to control the parts in the EnSight session.
|
|
4
|
+
|
|
5
|
+
Example for selecting all 3D parts:
|
|
6
|
+
|
|
7
|
+
(PyEnSight)
|
|
8
|
+
>>> from ansys.pyensight.core import LocalLauncher
|
|
9
|
+
>>> session = LocalLauncher().start()
|
|
10
|
+
>>> parts = session.ensight.utils.parts
|
|
11
|
+
>>> parts.select_by_dimension(3)
|
|
12
|
+
|
|
13
|
+
(EnSight)
|
|
14
|
+
>>> from ensight.utils import parts
|
|
15
|
+
>>> parts.select_by_dimension(3)
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
from types import ModuleType
|
|
19
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
import ensight
|
|
23
|
+
from ensight.objs import ens_emitterobj, ensobjlist # type: ignore
|
|
24
|
+
except ImportError:
|
|
25
|
+
from ansys.api.pyensight.ens_emitterobj import ens_emitterobj
|
|
26
|
+
from ansys.pyensight.core.listobj import ensobjlist
|
|
27
|
+
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
try:
|
|
30
|
+
from ensight.objs import ENS_PART, ENS_VAR # type: ignore
|
|
31
|
+
except ImportError:
|
|
32
|
+
from ansys.api.pyensight import ensight_api
|
|
33
|
+
from ansys.api.pyensight.ens_part import ENS_PART
|
|
34
|
+
from ansys.api.pyensight.ens_var import ENS_VAR
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def convert_part(
|
|
38
|
+
_ensight: Union["ensight_api.ensight", "ensight"], part: Union[str, int, "ENS_PART"]
|
|
39
|
+
):
|
|
40
|
+
if isinstance(part, str):
|
|
41
|
+
return _ensight.objs.core.PARTS[part][0].PARTNUMBER
|
|
42
|
+
elif isinstance(part, int):
|
|
43
|
+
return part
|
|
44
|
+
elif hasattr(part, "PARTNUMBER"):
|
|
45
|
+
return part.PARTNUMBER
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def convert_variable(
|
|
49
|
+
_ensight: Union["ensight_api.ensight", "ensight"], var: Union[str, int, "ENS_VAR"]
|
|
50
|
+
):
|
|
51
|
+
if isinstance(var, str):
|
|
52
|
+
return _ensight.objs.core.VARIABLES[var][0].ID
|
|
53
|
+
elif isinstance(var, int):
|
|
54
|
+
return var
|
|
55
|
+
elif hasattr(var, "ID"):
|
|
56
|
+
return var.ID
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class Parts:
|
|
60
|
+
"""Controls the parts in the current EnSight ``Session`` instance."""
|
|
61
|
+
|
|
62
|
+
class _EnSEmitterPoint(ens_emitterobj):
|
|
63
|
+
def __init__(
|
|
64
|
+
self,
|
|
65
|
+
ensight: "ensight",
|
|
66
|
+
point1: Optional[List[float]] = [0, 0, 0],
|
|
67
|
+
):
|
|
68
|
+
if not isinstance(ensight, ModuleType):
|
|
69
|
+
raise RuntimeError(
|
|
70
|
+
"The class cannot be used directly in PyEnSight. It should not be used directly even in EnSight"
|
|
71
|
+
)
|
|
72
|
+
super().__init__(ensight.objs.EMIT_CURSOR)
|
|
73
|
+
self.ensight = ensight
|
|
74
|
+
self.ensight.view_transf.cursor(*point1)
|
|
75
|
+
self.CENTROID = point1
|
|
76
|
+
|
|
77
|
+
class _EnSEmitterGrid(ens_emitterobj):
|
|
78
|
+
def __init__(
|
|
79
|
+
self,
|
|
80
|
+
ensight: "ensight",
|
|
81
|
+
point1: Optional[List[float]] = [0, 0, 0],
|
|
82
|
+
point2: Optional[List[float]] = [0, 0, 0],
|
|
83
|
+
point3: Optional[List[float]] = [0, 0, 0],
|
|
84
|
+
point4: Optional[List[float]] = [0, 0, 0],
|
|
85
|
+
num_points_x: Optional[int] = 25,
|
|
86
|
+
num_points_y: Optional[int] = 25,
|
|
87
|
+
):
|
|
88
|
+
if not isinstance(ensight, ModuleType):
|
|
89
|
+
raise RuntimeError(
|
|
90
|
+
"The class cannot be used directly in PyEnSight. It should not be used directly even in EnSight"
|
|
91
|
+
)
|
|
92
|
+
super().__init__(ensight.objs.EMIT_PLANE)
|
|
93
|
+
self.ensight = ensight
|
|
94
|
+
self.ensight.view_transf.plane(1, *point1)
|
|
95
|
+
self.ensight.view_transf.plane(2, *point2)
|
|
96
|
+
self.ensight.view_transf.plane(3, *point3)
|
|
97
|
+
self.POINT1 = point1
|
|
98
|
+
self.POINT2 = point2
|
|
99
|
+
self.POINT3 = point3
|
|
100
|
+
self.POINT4 = point4
|
|
101
|
+
self.NUM_POINTS_X = num_points_x
|
|
102
|
+
self.NUM_POINTS_Y = num_points_y
|
|
103
|
+
|
|
104
|
+
class _EnSEmitterLine(ens_emitterobj):
|
|
105
|
+
def __init__(
|
|
106
|
+
self,
|
|
107
|
+
ensight: "ensight",
|
|
108
|
+
point1: Optional[List[float]] = [0, 0, 0],
|
|
109
|
+
point2: Optional[List[float]] = [0, 0, 0],
|
|
110
|
+
num_points: Optional[int] = 100,
|
|
111
|
+
):
|
|
112
|
+
if not isinstance(ensight, ModuleType):
|
|
113
|
+
raise RuntimeError(
|
|
114
|
+
"The class cannot be used directly in PyEnSight. It should not be used directly even in EnSight"
|
|
115
|
+
)
|
|
116
|
+
super().__init__(ensight.objs.EMIT_LINE)
|
|
117
|
+
self.ensight = ensight
|
|
118
|
+
self.ensight.view_transf.line(1, *point1)
|
|
119
|
+
self.ensight.view_transf.line(2, *point2)
|
|
120
|
+
self.POINT1 = point1
|
|
121
|
+
self.POINT2 = point2
|
|
122
|
+
self.NUM_POINTS = num_points
|
|
123
|
+
|
|
124
|
+
class _EnSEmitterPart(ens_emitterobj):
|
|
125
|
+
def __init__(
|
|
126
|
+
self,
|
|
127
|
+
ensight: "ensight",
|
|
128
|
+
part: Optional[Any] = None,
|
|
129
|
+
part_kind: Optional[Any] = 0,
|
|
130
|
+
num_points: Optional[int] = 100,
|
|
131
|
+
):
|
|
132
|
+
if not isinstance(ensight, ModuleType):
|
|
133
|
+
raise RuntimeError(
|
|
134
|
+
"The class cannot be used directly in PyEnSight. It should not be used directly even in EnSight"
|
|
135
|
+
)
|
|
136
|
+
super().__init__(ensight.objs.EMIT_PART)
|
|
137
|
+
self.ensight = ensight
|
|
138
|
+
if not part:
|
|
139
|
+
raise RuntimeError("part is a required input")
|
|
140
|
+
self.PART = convert_part(self.ensight, part)
|
|
141
|
+
self.NUM_POINTS = num_points
|
|
142
|
+
self.DISTRIB_TYPE = part_kind
|
|
143
|
+
|
|
144
|
+
def __init__(self, ensight: Union["ensight_api.ensight", "ensight"]):
|
|
145
|
+
self.ensight = ensight
|
|
146
|
+
|
|
147
|
+
def select_parts_by_dimension(self, dimension: int) -> ensobjlist["ENS_PART"]:
|
|
148
|
+
"""Select parts by the input dimension and return the parts found.
|
|
149
|
+
|
|
150
|
+
Parameters
|
|
151
|
+
----------
|
|
152
|
+
dimension : int
|
|
153
|
+
Dimension for selecting parts.
|
|
154
|
+
|
|
155
|
+
Returns
|
|
156
|
+
-------
|
|
157
|
+
ensobjlist["ENS_PART"]
|
|
158
|
+
found (ensobjlist): List of parts found.
|
|
159
|
+
|
|
160
|
+
"""
|
|
161
|
+
parts = self.ensight.objs.core.PARTS
|
|
162
|
+
parts.set_attr("SELECTED", False)
|
|
163
|
+
found = parts.find(True, f"HAS{dimension}DELEMENTS")
|
|
164
|
+
found.set_attr("SELECTED", True)
|
|
165
|
+
return found
|
|
166
|
+
|
|
167
|
+
def select_parts_invert(self) -> ensobjlist["ENS_PART"]:
|
|
168
|
+
"""Select parts currently not selected, deselecting the previously selected parts.
|
|
169
|
+
|
|
170
|
+
Returns
|
|
171
|
+
-------
|
|
172
|
+
ensobjlist["ENS_PART"]
|
|
173
|
+
Updated list of parts selected.
|
|
174
|
+
|
|
175
|
+
"""
|
|
176
|
+
self.ensight.part.select_invert()
|
|
177
|
+
parts = self.ensight.objs.core.PARTS
|
|
178
|
+
return parts.find(True, "SELECTED")
|
|
179
|
+
|
|
180
|
+
def select_parts_by_tag(
|
|
181
|
+
self,
|
|
182
|
+
tag: Optional[str] = None,
|
|
183
|
+
value: Optional[str] = None,
|
|
184
|
+
tagdict: Optional[Dict[str, str]] = None,
|
|
185
|
+
) -> ensobjlist["ENS_PART"]:
|
|
186
|
+
"""Select parts by the input dimension and return the parts found.
|
|
187
|
+
|
|
188
|
+
Parameters
|
|
189
|
+
----------
|
|
190
|
+
tag : str, optional
|
|
191
|
+
Tag for finding the parts.
|
|
192
|
+
value : str, optional
|
|
193
|
+
Value for finding the parts.
|
|
194
|
+
tagdict : dict, optional
|
|
195
|
+
Dictionary containing the key and value pairs for finding
|
|
196
|
+
the parts. Only the parts that have all the keys and corresponding
|
|
197
|
+
values are returned. If a value for this parameter is supplied, it
|
|
198
|
+
takes precedence over the valeus supplied for the ``tag`` and
|
|
199
|
+
``value`` parameters.
|
|
200
|
+
|
|
201
|
+
Returns
|
|
202
|
+
-------
|
|
203
|
+
ensobjlist["ENS_PART"]
|
|
204
|
+
List of parts found. If no arguments are given, all parts are returned.
|
|
205
|
+
|
|
206
|
+
"""
|
|
207
|
+
parts = self.ensight.objs.core.PARTS
|
|
208
|
+
metadata = {p: p.METADATA for p in parts}
|
|
209
|
+
found = ensobjlist()
|
|
210
|
+
if not tag and not value and not tagdict:
|
|
211
|
+
self.ensight.part.select_all()
|
|
212
|
+
return parts
|
|
213
|
+
if not tagdict:
|
|
214
|
+
if tag and value:
|
|
215
|
+
found = ensobjlist([p for p, met in metadata.items() if met.get(tag) == value])
|
|
216
|
+
elif value and not tag:
|
|
217
|
+
found = ensobjlist([p for p, met in metadata.items() if value in met.values()])
|
|
218
|
+
elif tag and not value:
|
|
219
|
+
found = ensobjlist([p for p, met in metadata.items() if tag in met.keys()])
|
|
220
|
+
else:
|
|
221
|
+
found = ensobjlist(
|
|
222
|
+
[
|
|
223
|
+
p
|
|
224
|
+
for p, met in metadata.items()
|
|
225
|
+
if all(met.get(k) == v for k, v in tagdict.items())
|
|
226
|
+
]
|
|
227
|
+
)
|
|
228
|
+
if found:
|
|
229
|
+
found.set_attr("SELECTED", True)
|
|
230
|
+
return found
|
|
231
|
+
|
|
232
|
+
_EMIT_POINT: int = 0
|
|
233
|
+
_EMIT_LINE: int = 1
|
|
234
|
+
_EMIT_PLANE: int = 2
|
|
235
|
+
_EMIT_PART: int = 3
|
|
236
|
+
PT_POS_TIME: str = "+"
|
|
237
|
+
PT_NEG_TIME: str = "-"
|
|
238
|
+
PT_POS_NEG_TIME: str = "+/-"
|
|
239
|
+
PART_EMIT_FROM_NODES: int = 0
|
|
240
|
+
PART_EMIT_FROM_AREA: int = 1
|
|
241
|
+
|
|
242
|
+
def _create_emitters(
|
|
243
|
+
self,
|
|
244
|
+
emitter_type: int,
|
|
245
|
+
points: Optional[List[List[float]]] = None,
|
|
246
|
+
point1: Optional[List[float]] = None,
|
|
247
|
+
point2: Optional[List[float]] = None,
|
|
248
|
+
point3: Optional[List[float]] = None,
|
|
249
|
+
parts: Optional[List["ENS_PART"]] = None,
|
|
250
|
+
part_distribution_type: Optional[int] = 0,
|
|
251
|
+
num_points: Optional[int] = 100,
|
|
252
|
+
num_points_x: Optional[int] = 25,
|
|
253
|
+
num_points_y: Optional[int] = 25,
|
|
254
|
+
) -> List[Any]:
|
|
255
|
+
"""Private routine to create emitter objects"""
|
|
256
|
+
new_emitters: List[Any] = []
|
|
257
|
+
if emitter_type == self._EMIT_POINT:
|
|
258
|
+
if not points:
|
|
259
|
+
raise RuntimeError("list of points needed if particle trace emitted from points")
|
|
260
|
+
for p in points:
|
|
261
|
+
if isinstance(self.ensight, ModuleType):
|
|
262
|
+
new_emitters.append(self._EnSEmitterPoint(self.ensight, point1=p))
|
|
263
|
+
else:
|
|
264
|
+
new_emitters.append(
|
|
265
|
+
f"ensight.utils.parts._EnSEmitterPoint(ensight, point1={p})"
|
|
266
|
+
)
|
|
267
|
+
elif emitter_type == self._EMIT_LINE:
|
|
268
|
+
if not any([point1, point2]):
|
|
269
|
+
raise RuntimeError("point1 and point2 needed if particle trace emitted from line")
|
|
270
|
+
if isinstance(self.ensight, ModuleType):
|
|
271
|
+
new_emitters.append(
|
|
272
|
+
self._EnSEmitterLine(
|
|
273
|
+
self.ensight, point1=point1, point2=point2, num_points=num_points
|
|
274
|
+
)
|
|
275
|
+
)
|
|
276
|
+
else:
|
|
277
|
+
new_emitters.append(
|
|
278
|
+
f"ensight.utils.parts._EnSEmitterLine(ensight, point1={point1}, point2={point2}, num_points={num_points})"
|
|
279
|
+
)
|
|
280
|
+
elif emitter_type == self._EMIT_PLANE:
|
|
281
|
+
if not any([point1, point2, point3]):
|
|
282
|
+
raise RuntimeError(
|
|
283
|
+
"point1, point2 and point3 needed if particle trace emitted from plane"
|
|
284
|
+
)
|
|
285
|
+
if isinstance(self.ensight, ModuleType):
|
|
286
|
+
new_emitters.append(
|
|
287
|
+
self._EnSEmitterGrid(
|
|
288
|
+
self.ensight,
|
|
289
|
+
point1=point1,
|
|
290
|
+
point2=point2,
|
|
291
|
+
point3=point3,
|
|
292
|
+
num_points_x=num_points_x,
|
|
293
|
+
num_points_y=num_points_y,
|
|
294
|
+
)
|
|
295
|
+
)
|
|
296
|
+
else:
|
|
297
|
+
new_emitters.append(
|
|
298
|
+
f"ensight.utils.parts._EnSEmitterGrid(ensight, point1={point1}, point2={point2}, point3={point3}, num_points_x={num_points_x}, num_points_y={num_points_y})"
|
|
299
|
+
)
|
|
300
|
+
elif emitter_type == self._EMIT_PART:
|
|
301
|
+
if not parts:
|
|
302
|
+
raise RuntimeError("part and num_points needed if particle trace emitted from part")
|
|
303
|
+
for p in parts:
|
|
304
|
+
if isinstance(self.ensight, ModuleType):
|
|
305
|
+
new_emitters.append(
|
|
306
|
+
self._EnSEmitterPart(
|
|
307
|
+
self.ensight,
|
|
308
|
+
part=p,
|
|
309
|
+
num_points=num_points,
|
|
310
|
+
part_kind=part_distribution_type,
|
|
311
|
+
)
|
|
312
|
+
)
|
|
313
|
+
else:
|
|
314
|
+
new_emitters.append(
|
|
315
|
+
f"ensight.utils.parts._EnSEmitterPart(ensight, part={convert_part(self.ensight ,p)}, num_points={num_points}, part_kind={part_distribution_type})"
|
|
316
|
+
)
|
|
317
|
+
else:
|
|
318
|
+
raise RuntimeError("No input provided to create the emitters for the particle trace")
|
|
319
|
+
return new_emitters
|
|
320
|
+
|
|
321
|
+
def _create_pathline_part(
|
|
322
|
+
self,
|
|
323
|
+
name: str,
|
|
324
|
+
variable: Union[str, int, "ENS_VAR"],
|
|
325
|
+
direction: str,
|
|
326
|
+
source_parts: List["ENS_PART"],
|
|
327
|
+
pathlines: Optional[bool] = False,
|
|
328
|
+
emit_time: Optional[float] = None,
|
|
329
|
+
total_time: Optional[float] = None,
|
|
330
|
+
delta_time: Optional[float] = None,
|
|
331
|
+
) -> Tuple["ENS_PART", "ENS_PART"]:
|
|
332
|
+
"""Private routine to create a pathline part object"""
|
|
333
|
+
direction_map = {
|
|
334
|
+
self.PT_POS_TIME: self.ensight.objs.enums.POS_TIME,
|
|
335
|
+
self.PT_NEG_TIME: self.ensight.objs.enums.NEG_TIME,
|
|
336
|
+
self.PT_POS_NEG_TIME: self.ensight.objs.enums.POS_NEG_TIME,
|
|
337
|
+
}
|
|
338
|
+
idx = self.ensight.objs.enums.PART_PARTICLE_TRACE
|
|
339
|
+
def_part = self.ensight.objs.core.DEFAULTPARTS[idx]
|
|
340
|
+
def_part.TYPE = self.ensight.objs.enums.STREAMLINE
|
|
341
|
+
if pathlines is True:
|
|
342
|
+
def_part.TYPE = self.ensight.objs.enums.PATHLINE
|
|
343
|
+
if total_time:
|
|
344
|
+
def_part.TOTALTIME = total_time
|
|
345
|
+
if delta_time:
|
|
346
|
+
def_part.DELTATIME = delta_time
|
|
347
|
+
if emit_time:
|
|
348
|
+
def_part.STARTTIME = emit_time
|
|
349
|
+
def_part.DESCRIPTION = name
|
|
350
|
+
def_part.VARIABLE = convert_variable(self.ensight, variable)
|
|
351
|
+
def_part.SURFACERESTRICTED = False
|
|
352
|
+
def_part.TRACEDIRECTION = direction_map.get(direction)
|
|
353
|
+
pathline_part = def_part.createpart(sources=source_parts, name=name)[0]
|
|
354
|
+
return pathline_part, def_part
|
|
355
|
+
|
|
356
|
+
def _add_emitters_to_pathline(
|
|
357
|
+
self, pathline_part: "ENS_PART", new_emitters: List[Any], palette: Optional[str] = None
|
|
358
|
+
) -> "ENS_PART":
|
|
359
|
+
"""Private utility to add emitters to an existing pathline part."""
|
|
360
|
+
if isinstance(self.ensight, ModuleType):
|
|
361
|
+
emitters = pathline_part.EMITTERS.copy()
|
|
362
|
+
emitters.extend(new_emitters)
|
|
363
|
+
pathline_part.EMITTERS = emitters
|
|
364
|
+
else:
|
|
365
|
+
self.ensight._session.cmd(
|
|
366
|
+
f"enscl.emitters=ensight.objs.wrap_id({pathline_part.objid}).EMITTERS.copy()",
|
|
367
|
+
do_eval=False,
|
|
368
|
+
)
|
|
369
|
+
text = "enscl.emitters.extend(["
|
|
370
|
+
for emitter in new_emitters:
|
|
371
|
+
text += emitter + ", "
|
|
372
|
+
text = text[:-2]
|
|
373
|
+
text += "])"
|
|
374
|
+
self.ensight._session.cmd(text, do_eval=False)
|
|
375
|
+
self.ensight._session.cmd(
|
|
376
|
+
f"ensight.objs.wrap_id({pathline_part.objid}).setattr('EMITTERS', enscl.emitters.copy())"
|
|
377
|
+
)
|
|
378
|
+
self.ensight._session.cmd("del enscl.emitters", do_eval=False)
|
|
379
|
+
if palette:
|
|
380
|
+
pathline_part.COLORBYPALETTE = palette
|
|
381
|
+
return pathline_part
|
|
382
|
+
|
|
383
|
+
def _cure_pathline_part(self, pathline_part: Union[str, int, "ENS_PART"]) -> "ENS_PART":
|
|
384
|
+
"""Private utility to cure an input pathline part and convert it to an ``ENS_PART`"""
|
|
385
|
+
if isinstance(pathline_part, (str, int)):
|
|
386
|
+
temp = self.ensight.objs.core.PARTS[pathline_part]
|
|
387
|
+
if not temp:
|
|
388
|
+
raise RuntimeError("pathline_part input is not a valid part")
|
|
389
|
+
pathline_part = temp[0]
|
|
390
|
+
return pathline_part
|
|
391
|
+
|
|
392
|
+
def _prepare_particle_creation(
|
|
393
|
+
self,
|
|
394
|
+
direction: Optional[str] = None,
|
|
395
|
+
source_parts: Optional[List[Union[str, int, "ENS_PART"]]] = None,
|
|
396
|
+
) -> Tuple[str, List["ENS_PART"]]:
|
|
397
|
+
"""Private utility to set the direction if not provided, and to cure the list of source parts."""
|
|
398
|
+
if not direction:
|
|
399
|
+
direction = self.PT_POS_TIME
|
|
400
|
+
if source_parts:
|
|
401
|
+
converted_source_parts = [convert_part(self.ensight, p) for p in source_parts]
|
|
402
|
+
if not source_parts:
|
|
403
|
+
converted_source_parts = self.ensight.objs.core.selection(name="ENS_PART")
|
|
404
|
+
if not converted_source_parts:
|
|
405
|
+
raise RuntimeError("No part selected for particle trace generation")
|
|
406
|
+
return direction, converted_source_parts
|
|
407
|
+
|
|
408
|
+
def create_particle_trace_from_points(
|
|
409
|
+
self,
|
|
410
|
+
name: str,
|
|
411
|
+
variable: Union[str, int, "ENS_VAR"],
|
|
412
|
+
points: List[List[float]],
|
|
413
|
+
direction: Optional[str] = None,
|
|
414
|
+
pathlines: Optional[bool] = False,
|
|
415
|
+
source_parts: Optional[List[Union[str, int, "ENS_PART"]]] = None,
|
|
416
|
+
emit_time: Optional[float] = None,
|
|
417
|
+
total_time: Optional[float] = None,
|
|
418
|
+
delta_time: Optional[float] = None,
|
|
419
|
+
) -> "ENS_PART":
|
|
420
|
+
"""
|
|
421
|
+
Create a particle trace part from a list o points.
|
|
422
|
+
Returns the ``ENS_PART`` generated.
|
|
423
|
+
|
|
424
|
+
Parameters:
|
|
425
|
+
-----------
|
|
426
|
+
|
|
427
|
+
name: str
|
|
428
|
+
The name of part to be generated
|
|
429
|
+
variable:
|
|
430
|
+
The variable to compute the particle traces with.
|
|
431
|
+
It can be the name, the ID or the ``ENS_VAR`` object. It must be a vector variable.
|
|
432
|
+
direction: str
|
|
433
|
+
The direction for the particle traces to be generated.
|
|
434
|
+
This table describes the options:
|
|
435
|
+
|
|
436
|
+
================== ==============================================
|
|
437
|
+
Name Query type
|
|
438
|
+
================== ==============================================
|
|
439
|
+
PT_POS_TIME Follow the vector direction
|
|
440
|
+
PT_NEG_TIME Go contrary to the vector direction
|
|
441
|
+
PT_POS_NEG_TIME Follow and go contrary to the vector direction
|
|
442
|
+
================== ==============================================
|
|
443
|
+
|
|
444
|
+
If not provided, it will default to ``PT_POS_TIME``
|
|
445
|
+
pathlines: bool
|
|
446
|
+
True if the particle traces need to be pathlines
|
|
447
|
+
points: list
|
|
448
|
+
List of coordinates for the seed points.
|
|
449
|
+
source_parts: list
|
|
450
|
+
A list of parts to create the particle trace in. For instance, in a CFD
|
|
451
|
+
simulation this might be the fluid zone.
|
|
452
|
+
If not provided, the function will try to look for the selected parts.
|
|
453
|
+
emit_time: float
|
|
454
|
+
The emission time to start the particle trace from. If not provided,
|
|
455
|
+
it will use the current time.
|
|
456
|
+
total_time: float
|
|
457
|
+
The total emission time. If not provided, EnSight will provide the end time
|
|
458
|
+
for a transient simulation, an internal best time for steady state simulations.
|
|
459
|
+
delta_time: float
|
|
460
|
+
The interval for the emissions. If not provided, EnSight will provide
|
|
461
|
+
a best estimate.
|
|
462
|
+
"""
|
|
463
|
+
emitter_type = self._EMIT_POINT
|
|
464
|
+
direction, converted_source_parts = self._prepare_particle_creation(
|
|
465
|
+
direction=direction, source_parts=source_parts
|
|
466
|
+
)
|
|
467
|
+
pathline_part, def_part = self._create_pathline_part(
|
|
468
|
+
name,
|
|
469
|
+
variable,
|
|
470
|
+
direction,
|
|
471
|
+
converted_source_parts,
|
|
472
|
+
pathlines=pathlines,
|
|
473
|
+
emit_time=emit_time,
|
|
474
|
+
delta_time=delta_time,
|
|
475
|
+
total_time=total_time,
|
|
476
|
+
)
|
|
477
|
+
new_emitters = self._create_emitters(emitter_type=emitter_type, points=points)
|
|
478
|
+
return self._add_emitters_to_pathline(
|
|
479
|
+
pathline_part, new_emitters=new_emitters, palette=def_part.VARIABLE.DESCRIPTION
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
def create_particle_trace_from_line(
|
|
483
|
+
self,
|
|
484
|
+
name: str,
|
|
485
|
+
variable: Union[str, int, "ENS_VAR"],
|
|
486
|
+
point1: List[float],
|
|
487
|
+
point2: List[float],
|
|
488
|
+
num_points: Optional[int] = 100,
|
|
489
|
+
direction: Optional[str] = None,
|
|
490
|
+
pathlines: Optional[bool] = False,
|
|
491
|
+
source_parts: Optional[List[Union[str, int, "ENS_PART"]]] = None,
|
|
492
|
+
emit_time: Optional[float] = None,
|
|
493
|
+
total_time: Optional[float] = None,
|
|
494
|
+
delta_time: Optional[float] = None,
|
|
495
|
+
) -> "ENS_PART":
|
|
496
|
+
"""
|
|
497
|
+
Create a particle trace part from a line.
|
|
498
|
+
Returns the ``ENS_PART`` generated.
|
|
499
|
+
|
|
500
|
+
Parameters:
|
|
501
|
+
-----------
|
|
502
|
+
|
|
503
|
+
name: str
|
|
504
|
+
The name of part to be generated
|
|
505
|
+
variable:
|
|
506
|
+
The variable to compute the particle traces with.
|
|
507
|
+
It can be the name, the ID or the ``ENS_VAR`` object. It must be a vector variable.
|
|
508
|
+
direction: str
|
|
509
|
+
The direction for the particle traces to be generated.
|
|
510
|
+
This table describes the options:
|
|
511
|
+
|
|
512
|
+
================== ==============================================
|
|
513
|
+
Name Query type
|
|
514
|
+
================== ==============================================
|
|
515
|
+
PT_POS_TIME Follow the vector direction
|
|
516
|
+
PT_NEG_TIME Go contrary to the vector direction
|
|
517
|
+
PT_POS_NEG_TIME Follow and go contrary to the vector direction
|
|
518
|
+
================== ==============================================
|
|
519
|
+
|
|
520
|
+
If not provided, it will default to ``PT_POS_TIME``
|
|
521
|
+
pathlines: bool
|
|
522
|
+
True if the particle traces need to be pathlines
|
|
523
|
+
point1: list
|
|
524
|
+
List of coordinates for point 1.
|
|
525
|
+
point2: list
|
|
526
|
+
List of coordinates for point 2.
|
|
527
|
+
source_parts: list
|
|
528
|
+
A list of parts to create the particle trace in. For instance, in a CFD
|
|
529
|
+
simulation this might be the fluid zone.
|
|
530
|
+
If not provided, the function will try to look for the selected parts.
|
|
531
|
+
num_points: int
|
|
532
|
+
The number of points to emit from. Defaults to 100.
|
|
533
|
+
emit_time: float
|
|
534
|
+
The emission time to start the particle trace from. If not provided,
|
|
535
|
+
it will use the current time.
|
|
536
|
+
total_time: float
|
|
537
|
+
The total emission time. If not provided, EnSight will provide the end time
|
|
538
|
+
for a transient simulation, an internal best time for steady state simulations.
|
|
539
|
+
delta_time: float
|
|
540
|
+
The interval for the emissions. If not provided, EnSight will provide
|
|
541
|
+
a best estimate.
|
|
542
|
+
"""
|
|
543
|
+
emitter_type = self._EMIT_LINE
|
|
544
|
+
direction, converted_source_parts = self._prepare_particle_creation(
|
|
545
|
+
direction=direction, source_parts=source_parts
|
|
546
|
+
)
|
|
547
|
+
pathline_part, def_part = self._create_pathline_part(
|
|
548
|
+
name,
|
|
549
|
+
variable,
|
|
550
|
+
direction,
|
|
551
|
+
converted_source_parts,
|
|
552
|
+
pathlines=pathlines,
|
|
553
|
+
emit_time=emit_time,
|
|
554
|
+
delta_time=delta_time,
|
|
555
|
+
total_time=total_time,
|
|
556
|
+
)
|
|
557
|
+
new_emitters = self._create_emitters(
|
|
558
|
+
emitter_type=emitter_type, point1=point1, point2=point2, num_points=num_points
|
|
559
|
+
)
|
|
560
|
+
return self._add_emitters_to_pathline(
|
|
561
|
+
pathline_part, new_emitters=new_emitters, palette=def_part.VARIABLE.DESCRIPTION
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
def create_particle_trace_from_plane(
|
|
565
|
+
self,
|
|
566
|
+
name: str,
|
|
567
|
+
variable: Union[str, int, "ENS_VAR"],
|
|
568
|
+
point1: List[float],
|
|
569
|
+
point2: List[float],
|
|
570
|
+
point3: List[float],
|
|
571
|
+
num_points_x: Optional[int] = 25,
|
|
572
|
+
num_points_y: Optional[int] = 25,
|
|
573
|
+
direction: Optional[str] = None,
|
|
574
|
+
pathlines: Optional[bool] = False,
|
|
575
|
+
source_parts: Optional[List[Union[str, int, "ENS_PART"]]] = None,
|
|
576
|
+
emit_time: Optional[float] = None,
|
|
577
|
+
total_time: Optional[float] = None,
|
|
578
|
+
delta_time: Optional[float] = None,
|
|
579
|
+
) -> "ENS_PART":
|
|
580
|
+
"""
|
|
581
|
+
Create a particle trace part from a plane.
|
|
582
|
+
Returns the ``ENS_PART`` generated.
|
|
583
|
+
|
|
584
|
+
Parameters:
|
|
585
|
+
-----------
|
|
586
|
+
|
|
587
|
+
name: str
|
|
588
|
+
The name of part to be generated
|
|
589
|
+
variable:
|
|
590
|
+
The variable to compute the particle traces with.
|
|
591
|
+
It can be the name, the ID or the ``ENS_VAR`` object. It must be a vector variable.
|
|
592
|
+
direction: str
|
|
593
|
+
The direction for the particle traces to be generated.
|
|
594
|
+
This table describes the options:
|
|
595
|
+
|
|
596
|
+
================== ==============================================
|
|
597
|
+
Name Query type
|
|
598
|
+
================== ==============================================
|
|
599
|
+
PT_POS_TIME Follow the vector direction
|
|
600
|
+
PT_NEG_TIME Go contrary to the vector direction
|
|
601
|
+
PT_POS_NEG_TIME Follow and go contrary to the vector direction
|
|
602
|
+
================== ==============================================
|
|
603
|
+
|
|
604
|
+
If not provided, it will default to ``PT_POS_TIME``
|
|
605
|
+
pathlines: bool
|
|
606
|
+
True if the particle traces need to be pathlines
|
|
607
|
+
point1: list
|
|
608
|
+
List of coordinates for point 1, being a corner of the plane.
|
|
609
|
+
point2: list
|
|
610
|
+
List of coordinates for point 2, being a corner of the plane.
|
|
611
|
+
point3: list
|
|
612
|
+
List of coordinates for point 3, being a corner of the plane.
|
|
613
|
+
source_parts: list
|
|
614
|
+
A list of parts to create the particle trace in. For instance, in a CFD
|
|
615
|
+
simulation this might be the fluid zone.
|
|
616
|
+
If not provided, the function will try to look for the selected parts.
|
|
617
|
+
num_points_x: int
|
|
618
|
+
The number of points on the ``X`` direction of the emission plane.
|
|
619
|
+
Defaults to 25.
|
|
620
|
+
num_points_y: int
|
|
621
|
+
The number of points on the ``Y`` direction of the emission plane.
|
|
622
|
+
Defaults to 25.
|
|
623
|
+
emit_time: float
|
|
624
|
+
The emission time to start the particle trace from. If not provided,
|
|
625
|
+
it will use the current time.
|
|
626
|
+
total_time: float
|
|
627
|
+
The total emission time. If not provided, EnSight will provide the end time
|
|
628
|
+
for a transient simulation, an internal best time for steady state simulations.
|
|
629
|
+
delta_time: float
|
|
630
|
+
The interval for the emissions. If not provided, EnSight will provide
|
|
631
|
+
a best estimate.
|
|
632
|
+
"""
|
|
633
|
+
emitter_type = self._EMIT_PLANE
|
|
634
|
+
direction, converted_source_parts = self._prepare_particle_creation(
|
|
635
|
+
direction=direction, source_parts=source_parts
|
|
636
|
+
)
|
|
637
|
+
pathline_part, def_part = self._create_pathline_part(
|
|
638
|
+
name,
|
|
639
|
+
variable,
|
|
640
|
+
direction,
|
|
641
|
+
converted_source_parts,
|
|
642
|
+
pathlines=pathlines,
|
|
643
|
+
emit_time=emit_time,
|
|
644
|
+
delta_time=delta_time,
|
|
645
|
+
total_time=total_time,
|
|
646
|
+
)
|
|
647
|
+
new_emitters = self._create_emitters(
|
|
648
|
+
emitter_type=emitter_type,
|
|
649
|
+
point1=point1,
|
|
650
|
+
point2=point2,
|
|
651
|
+
point3=point3,
|
|
652
|
+
num_points_x=num_points_x,
|
|
653
|
+
num_points_y=num_points_y,
|
|
654
|
+
)
|
|
655
|
+
return self._add_emitters_to_pathline(
|
|
656
|
+
pathline_part, new_emitters=new_emitters, palette=def_part.VARIABLE.DESCRIPTION
|
|
657
|
+
)
|
|
658
|
+
|
|
659
|
+
def create_particle_trace_from_parts(
|
|
660
|
+
self,
|
|
661
|
+
name: str,
|
|
662
|
+
variable: Union[str, int, "ENS_VAR"],
|
|
663
|
+
parts: List[Union[str, int, "ENS_PART"]],
|
|
664
|
+
part_distribution_type: Optional[int] = 0,
|
|
665
|
+
num_points: Optional[int] = 100,
|
|
666
|
+
direction: Optional[str] = None,
|
|
667
|
+
pathlines: Optional[bool] = False,
|
|
668
|
+
source_parts: Optional[List[Union[str, int, "ENS_PART"]]] = None,
|
|
669
|
+
emit_time: Optional[float] = None,
|
|
670
|
+
total_time: Optional[float] = None,
|
|
671
|
+
delta_time: Optional[float] = None,
|
|
672
|
+
) -> "ENS_PART":
|
|
673
|
+
"""
|
|
674
|
+
Create a particle trace part from a list of seed parts.
|
|
675
|
+
Returns the ``ENS_PART`` generated.
|
|
676
|
+
|
|
677
|
+
Parameters:
|
|
678
|
+
-----------
|
|
679
|
+
|
|
680
|
+
name: str
|
|
681
|
+
The name of part to be generated
|
|
682
|
+
variable:
|
|
683
|
+
The variable to compute the particle traces with.
|
|
684
|
+
It can be the name, the ID or the ``ENS_VAR`` object. It must be a vector variable.
|
|
685
|
+
direction: str
|
|
686
|
+
The direction for the particle traces to be generated.
|
|
687
|
+
This table describes the options:
|
|
688
|
+
|
|
689
|
+
================== ==============================================
|
|
690
|
+
Name Query type
|
|
691
|
+
================== ==============================================
|
|
692
|
+
PT_POS_TIME Follow the vector direction
|
|
693
|
+
PT_NEG_TIME Go contrary to the vector direction
|
|
694
|
+
PT_POS_NEG_TIME Follow and go contrary to the vector direction
|
|
695
|
+
================== ==============================================
|
|
696
|
+
|
|
697
|
+
If not provided, it will default to ``PT_POS_TIME``
|
|
698
|
+
pathlines: bool
|
|
699
|
+
True if the particle traces need to be pathlines
|
|
700
|
+
source_parts: list
|
|
701
|
+
A list of parts to create the particle trace in. For instance, in a CFD
|
|
702
|
+
simulation this might be the fluid zone.
|
|
703
|
+
If not provided, the function will try to look for the selected parts.
|
|
704
|
+
parts: list
|
|
705
|
+
A list of parts to emit the particle traces from.
|
|
706
|
+
They can be their names, their IDs or the respective ``ENS_PART`` objects.
|
|
707
|
+
part_distribution_type: int
|
|
708
|
+
The distribution of emitters in case of emission from a part.
|
|
709
|
+
This table describes the options:
|
|
710
|
+
|
|
711
|
+
==================== =================================================
|
|
712
|
+
Name Query type
|
|
713
|
+
==================== =================================================
|
|
714
|
+
PART_EMIT_FROM_NODES Emit from the nodes of the part
|
|
715
|
+
PART_EMIT_FROM_AREA Create an area of equidistant points for emission
|
|
716
|
+
================== =================================================
|
|
717
|
+
|
|
718
|
+
If not provided, it will default to ``PART_EMIT_FROM_NODES``
|
|
719
|
+
num_points: int
|
|
720
|
+
The number of points to emit from.
|
|
721
|
+
Defaults to 100.
|
|
722
|
+
emit_time: float
|
|
723
|
+
The emission time to start the particle trace from. If not provided,
|
|
724
|
+
it will use the current time.
|
|
725
|
+
total_time: float
|
|
726
|
+
The total emission time. If not provided, EnSight will provide the end time
|
|
727
|
+
for a transient simulation, an internal best time for steady state simulations.
|
|
728
|
+
delta_time: float
|
|
729
|
+
The interval for the emissions. If not provided, EnSight will provide
|
|
730
|
+
a best estimate.
|
|
731
|
+
"""
|
|
732
|
+
emitter_type = self._EMIT_PART
|
|
733
|
+
direction, converted_source_parts = self._prepare_particle_creation(
|
|
734
|
+
direction=direction, source_parts=source_parts
|
|
735
|
+
)
|
|
736
|
+
pathline_part, def_part = self._create_pathline_part(
|
|
737
|
+
name,
|
|
738
|
+
variable,
|
|
739
|
+
direction,
|
|
740
|
+
converted_source_parts,
|
|
741
|
+
pathlines=pathlines,
|
|
742
|
+
emit_time=emit_time,
|
|
743
|
+
delta_time=delta_time,
|
|
744
|
+
total_time=total_time,
|
|
745
|
+
)
|
|
746
|
+
new_parts = [convert_part(self.ensight, p) for p in parts]
|
|
747
|
+
new_emitters = self._create_emitters(
|
|
748
|
+
emitter_type=emitter_type,
|
|
749
|
+
parts=new_parts,
|
|
750
|
+
part_distribution_type=part_distribution_type,
|
|
751
|
+
num_points=num_points,
|
|
752
|
+
)
|
|
753
|
+
return self._add_emitters_to_pathline(
|
|
754
|
+
pathline_part, new_emitters=new_emitters, palette=def_part.VARIABLE.DESCRIPTION
|
|
755
|
+
)
|
|
756
|
+
|
|
757
|
+
def add_emitter_points_to_pathline_part(
|
|
758
|
+
self,
|
|
759
|
+
pathline_part: Union[str, int, "ENS_PART"],
|
|
760
|
+
points: List[List[float]],
|
|
761
|
+
) -> "ENS_PART":
|
|
762
|
+
"""
|
|
763
|
+
Add point emitters to an existing particle trace. The function will return the updated
|
|
764
|
+
``ENS_PART`` object.
|
|
765
|
+
|
|
766
|
+
Parameters:
|
|
767
|
+
-----------
|
|
768
|
+
|
|
769
|
+
pathline_part:
|
|
770
|
+
The particle trace part to be added emitters to.
|
|
771
|
+
Can be the name, the ID or the ``ENS_PART`` object
|
|
772
|
+
points: list
|
|
773
|
+
List of list containing the coordinates for the seed points.
|
|
774
|
+
"""
|
|
775
|
+
emitter_type = self._EMIT_POINT
|
|
776
|
+
pathline_part = self._cure_pathline_part(pathline_part)
|
|
777
|
+
new_emitters = self._create_emitters(emitter_type=emitter_type, points=points)
|
|
778
|
+
return self._add_emitters_to_pathline(pathline_part, new_emitters)
|
|
779
|
+
|
|
780
|
+
def add_emitter_line_to_pathline_part(
|
|
781
|
+
self,
|
|
782
|
+
pathline_part: Union[str, int, "ENS_PART"],
|
|
783
|
+
point1: List[float],
|
|
784
|
+
point2: List[float],
|
|
785
|
+
num_points: Optional[int] = 100,
|
|
786
|
+
):
|
|
787
|
+
"""
|
|
788
|
+
Add a line emitter to an existing particle trace. The function will return the updated
|
|
789
|
+
``ENS_PART`` object.
|
|
790
|
+
|
|
791
|
+
Parameters:
|
|
792
|
+
-----------
|
|
793
|
+
|
|
794
|
+
pathline_part:
|
|
795
|
+
The particle trace part to be added emitters to.
|
|
796
|
+
Can be the name, the ID or the ``ENS_PART`` object.
|
|
797
|
+
point1: list
|
|
798
|
+
The coordinates for point 1.
|
|
799
|
+
point2: list
|
|
800
|
+
The coordinates for point 2.
|
|
801
|
+
num_points: int
|
|
802
|
+
The number of seed points. Defaults to 100.
|
|
803
|
+
"""
|
|
804
|
+
emitter_type = self._EMIT_LINE
|
|
805
|
+
pathline_part = self._cure_pathline_part(pathline_part)
|
|
806
|
+
new_emitters = self._create_emitters(
|
|
807
|
+
emitter_type=emitter_type, point1=point1, point2=point2, num_points=num_points
|
|
808
|
+
)
|
|
809
|
+
return self._add_emitters_to_pathline(pathline_part, new_emitters)
|
|
810
|
+
|
|
811
|
+
def add_emitter_plane_to_pathline_part(
|
|
812
|
+
self,
|
|
813
|
+
pathline_part: Union[str, int, "ENS_PART"],
|
|
814
|
+
point1: List[float],
|
|
815
|
+
point2: List[float],
|
|
816
|
+
point3: List[float],
|
|
817
|
+
num_points_x: Optional[int] = 25,
|
|
818
|
+
num_points_y: Optional[int] = 25,
|
|
819
|
+
):
|
|
820
|
+
"""
|
|
821
|
+
Add a plane emitter to an existing particle trace. The function will return the updated
|
|
822
|
+
``ENS_PART`` object.
|
|
823
|
+
|
|
824
|
+
Parameters:
|
|
825
|
+
-----------
|
|
826
|
+
|
|
827
|
+
pathline_part:
|
|
828
|
+
The particle trace part to be added emitters to.
|
|
829
|
+
Can be the name, the ID or the ``ENS_PART`` object.
|
|
830
|
+
point1: list
|
|
831
|
+
The coordinates for point 1, being a corner of the plane.
|
|
832
|
+
point2: list
|
|
833
|
+
The coordinates for point 2, being a corner of the plane.
|
|
834
|
+
point3: list
|
|
835
|
+
The coordinates for point 3, being a corner of the plane.
|
|
836
|
+
num_points_x: int
|
|
837
|
+
The number of points on the ``X`` direction of the emission plane.
|
|
838
|
+
Defaults to 25.
|
|
839
|
+
num_points_y: int
|
|
840
|
+
The number of points on the ``Y`` direction of the emission plane.
|
|
841
|
+
Defaults to 25.
|
|
842
|
+
"""
|
|
843
|
+
emitter_type = self._EMIT_PLANE
|
|
844
|
+
pathline_part = self._cure_pathline_part(pathline_part)
|
|
845
|
+
new_emitters = self._create_emitters(
|
|
846
|
+
emitter_type=emitter_type,
|
|
847
|
+
point1=point1,
|
|
848
|
+
point2=point2,
|
|
849
|
+
point3=point3,
|
|
850
|
+
num_points_x=num_points_x,
|
|
851
|
+
num_points_y=num_points_y,
|
|
852
|
+
)
|
|
853
|
+
return self._add_emitters_to_pathline(pathline_part, new_emitters)
|
|
854
|
+
|
|
855
|
+
def add_emitter_parts_to_pathline_part(
|
|
856
|
+
self,
|
|
857
|
+
pathline_part: Union[str, int, "ENS_PART"],
|
|
858
|
+
parts: List[Union[str, int, "ENS_PART"]],
|
|
859
|
+
part_distribution_type: Optional[int] = 0,
|
|
860
|
+
num_points: Optional[int] = 100,
|
|
861
|
+
):
|
|
862
|
+
"""
|
|
863
|
+
Add a list of part emitters to an existing particle trace. The function will return the updated
|
|
864
|
+
``ENS_PART`` object.
|
|
865
|
+
|
|
866
|
+
Parameters:
|
|
867
|
+
-----------
|
|
868
|
+
|
|
869
|
+
pathline_part:
|
|
870
|
+
The particle trace part to be added emitters to.
|
|
871
|
+
Can be the name, the ID or the ``ENS_PART`` object.
|
|
872
|
+
parts: list
|
|
873
|
+
A list of parts to emit the particle traces from.
|
|
874
|
+
They can be their names, their IDs or the respective ``ENS_PART`` objects.
|
|
875
|
+
part_distribution_type: int
|
|
876
|
+
The distribution of emitters in case of emission from a part.
|
|
877
|
+
This table describes the options:
|
|
878
|
+
|
|
879
|
+
==================== =================================================
|
|
880
|
+
Name Query type
|
|
881
|
+
==================== =================================================
|
|
882
|
+
PART_EMIT_FROM_NODES Emit from the nodes of the part
|
|
883
|
+
PART_EMIT_FROM_AREA Create an area of equidistant points for emission
|
|
884
|
+
================== =================================================
|
|
885
|
+
|
|
886
|
+
If not provided, it will default to ``PART_EMIT_FROM_NODES``
|
|
887
|
+
num_points: int
|
|
888
|
+
The number of points to emit from.
|
|
889
|
+
Defaults to 100.
|
|
890
|
+
"""
|
|
891
|
+
emitter_type = self._EMIT_PART
|
|
892
|
+
pathline_part = self._cure_pathline_part(pathline_part)
|
|
893
|
+
new_parts = [convert_part(self.ensight, p) for p in parts]
|
|
894
|
+
new_emitters = self._create_emitters(
|
|
895
|
+
emitter_type=emitter_type,
|
|
896
|
+
parts=new_parts,
|
|
897
|
+
part_distribution_type=part_distribution_type,
|
|
898
|
+
num_points=num_points,
|
|
899
|
+
)
|
|
900
|
+
return self._add_emitters_to_pathline(pathline_part, new_emitters)
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
"""Parts module.
|
|
2
|
-
|
|
3
|
-
This module allows PyEnSight to control the parts in the EnSight session.
|
|
4
|
-
|
|
5
|
-
Example for selecting all 3D parts:
|
|
6
|
-
|
|
7
|
-
(PyEnSight)
|
|
8
|
-
>>> from ansys.pyensight.core import LocalLauncher
|
|
9
|
-
>>> session = LocalLauncher().start()
|
|
10
|
-
>>> parts = session.ensight.utils.parts
|
|
11
|
-
>>> parts.select_by_dimension(3)
|
|
12
|
-
|
|
13
|
-
(EnSight)
|
|
14
|
-
>>> from ensight.utils import parts
|
|
15
|
-
>>> parts.select_by_dimension(3)
|
|
16
|
-
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
from typing import TYPE_CHECKING, Dict, Optional, Union
|
|
20
|
-
|
|
21
|
-
try:
|
|
22
|
-
import ensight
|
|
23
|
-
from ensight.objs import ensobjlist # type: ignore
|
|
24
|
-
except ImportError:
|
|
25
|
-
from ansys.pyensight.core.listobj import ensobjlist
|
|
26
|
-
|
|
27
|
-
if TYPE_CHECKING:
|
|
28
|
-
try:
|
|
29
|
-
from ensight.objs import ENS_PART # type: ignore
|
|
30
|
-
except ImportError:
|
|
31
|
-
from ansys.api.pyensight import ensight_api
|
|
32
|
-
from ansys.api.pyensight.ens_part import ENS_PART
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class Parts:
|
|
36
|
-
"""Controls the parts in the current EnSight ``Session`` instance."""
|
|
37
|
-
|
|
38
|
-
def __init__(self, ensight: Union["ensight_api.ensight", "ensight"]):
|
|
39
|
-
self.ensight = ensight
|
|
40
|
-
|
|
41
|
-
def select_parts_by_dimension(self, dimension: int) -> ensobjlist["ENS_PART"]:
|
|
42
|
-
"""Select parts by the input dimension and return the parts found.
|
|
43
|
-
|
|
44
|
-
Parameters
|
|
45
|
-
----------
|
|
46
|
-
dimension : int
|
|
47
|
-
Dimension for selecting parts.
|
|
48
|
-
|
|
49
|
-
Returns
|
|
50
|
-
-------
|
|
51
|
-
ensobjlist["ENS_PART"]
|
|
52
|
-
found (ensobjlist): List of parts found.
|
|
53
|
-
|
|
54
|
-
"""
|
|
55
|
-
parts = self.ensight.objs.core.PARTS
|
|
56
|
-
parts.set_attr("SELECTED", False)
|
|
57
|
-
found = parts.find(True, f"HAS{dimension}DELEMENTS")
|
|
58
|
-
found.set_attr("SELECTED", True)
|
|
59
|
-
return found
|
|
60
|
-
|
|
61
|
-
def select_parts_invert(self) -> ensobjlist["ENS_PART"]:
|
|
62
|
-
"""Select parts currently not selected, deselecting the previously selected parts.
|
|
63
|
-
|
|
64
|
-
Returns
|
|
65
|
-
-------
|
|
66
|
-
ensobjlist["ENS_PART"]
|
|
67
|
-
Updated list of parts selected.
|
|
68
|
-
|
|
69
|
-
"""
|
|
70
|
-
self.ensight.part.select_invert()
|
|
71
|
-
parts = self.ensight.objs.core.PARTS
|
|
72
|
-
return parts.find(True, "SELECTED")
|
|
73
|
-
|
|
74
|
-
def select_parts_by_tag(
|
|
75
|
-
self,
|
|
76
|
-
tag: Optional[str] = None,
|
|
77
|
-
value: Optional[str] = None,
|
|
78
|
-
tagdict: Optional[Dict[str, str]] = None,
|
|
79
|
-
) -> ensobjlist["ENS_PART"]:
|
|
80
|
-
"""Select parts by the input dimension and return the parts found.
|
|
81
|
-
|
|
82
|
-
Parameters
|
|
83
|
-
----------
|
|
84
|
-
tag : str, optional
|
|
85
|
-
Tag for finding the parts.
|
|
86
|
-
value : str, optional
|
|
87
|
-
Value for finding the parts.
|
|
88
|
-
tagdict : dict, optional
|
|
89
|
-
Dictionary containing the key and value pairs for finding
|
|
90
|
-
the parts. Only the parts that have all the keys and corresponding
|
|
91
|
-
values are returned. If a value for this parameter is supplied, it
|
|
92
|
-
takes precedence over the valeus supplied for the ``tag`` and
|
|
93
|
-
``value`` parameters.
|
|
94
|
-
|
|
95
|
-
Returns
|
|
96
|
-
-------
|
|
97
|
-
ensobjlist["ENS_PART"]
|
|
98
|
-
List of parts found. If no arguments are given, all parts are returned.
|
|
99
|
-
|
|
100
|
-
"""
|
|
101
|
-
parts = self.ensight.objs.core.PARTS
|
|
102
|
-
metadata = {p: p.METADATA for p in parts}
|
|
103
|
-
found = ensobjlist()
|
|
104
|
-
if not tag and not value and not tagdict:
|
|
105
|
-
self.ensight.part.select_all()
|
|
106
|
-
return parts
|
|
107
|
-
if not tagdict:
|
|
108
|
-
if tag and value:
|
|
109
|
-
found = ensobjlist([p for p, met in metadata.items() if met.get(tag) == value])
|
|
110
|
-
elif value and not tag:
|
|
111
|
-
found = ensobjlist([p for p, met in metadata.items() if value in met.values()])
|
|
112
|
-
elif tag and not value:
|
|
113
|
-
found = ensobjlist([p for p, met in metadata.items() if tag in met.keys()])
|
|
114
|
-
else:
|
|
115
|
-
found = ensobjlist(
|
|
116
|
-
[
|
|
117
|
-
p
|
|
118
|
-
for p, met in metadata.items()
|
|
119
|
-
if all(met.get(k) == v for k, v in tagdict.items())
|
|
120
|
-
]
|
|
121
|
-
)
|
|
122
|
-
if found:
|
|
123
|
-
found.set_attr("SELECTED", True)
|
|
124
|
-
return found
|
|
File without changes
|
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/dockerlauncher.py
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/enscontext.py
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/enshell_grpc.py
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/ensight_grpc.py
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/ensobj.py
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/launch_ensight.py
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/launcher.py
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/locallauncher.py
RENAMED
|
File without changes
|
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/sgeo_poll.html
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/utils/__init__.py
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/utils/adr.py
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/utils/export.py
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/utils/query.py
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/utils/support.py
RENAMED
|
File without changes
|
{ansys_pyensight_core-0.7.0 → ansys_pyensight_core-0.7.2}/src/ansys/pyensight/core/utils/views.py
RENAMED
|
File without changes
|