ansys-pyensight-core 0.7.1__tar.gz → 0.7.3__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.

Files changed (27) hide show
  1. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/PKG-INFO +1 -1
  2. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/pyproject.toml +1 -1
  3. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/renderable.py +27 -10
  4. ansys_pyensight_core-0.7.3/src/ansys/pyensight/core/utils/parts.py +1035 -0
  5. ansys_pyensight_core-0.7.1/src/ansys/pyensight/core/utils/parts.py +0 -124
  6. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/LICENSE +0 -0
  7. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/README.rst +0 -0
  8. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/__init__.py +0 -0
  9. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/deep_pixel_view.html +0 -0
  10. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/dockerlauncher.py +0 -0
  11. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/enscontext.py +0 -0
  12. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/enshell_grpc.py +0 -0
  13. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/ensight_grpc.py +0 -0
  14. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/ensobj.py +0 -0
  15. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/launch_ensight.py +0 -0
  16. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/launcher.py +0 -0
  17. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/listobj.py +0 -0
  18. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/locallauncher.py +0 -0
  19. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/py.typed +0 -0
  20. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/session.py +0 -0
  21. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/sgeo_poll.html +0 -0
  22. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/utils/__init__.py +0 -0
  23. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/utils/adr.py +0 -0
  24. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/utils/export.py +0 -0
  25. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/utils/query.py +0 -0
  26. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/src/ansys/pyensight/core/utils/support.py +0 -0
  27. {ansys_pyensight_core-0.7.1 → ansys_pyensight_core-0.7.3}/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.1
3
+ Version: 0.7.3
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>
@@ -6,7 +6,7 @@ build-backend = "flit_core.buildapi"
6
6
 
7
7
  [project]
8
8
  name = "ansys-pyensight-core"
9
- version = "0.7.1"
9
+ version = "0.7.3"
10
10
  description = "A python wrapper for Ansys EnSight"
11
11
  readme = "README.rst"
12
12
  requires-python = ">=3.9,<4"
@@ -525,15 +525,11 @@ class RenderableWebGL(Renderable):
525
525
 
526
526
 
527
527
  class RenderableVNC(Renderable):
528
- """Generates a URL that can be used to connect to the EnSight VNC remote image renderer."""
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._query_params = {
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
- url = f"{self._http_protocol}://{self._session.html_hostname}:{self._session.html_port}"
548
- url += "/ansys/nexus/novnc/vnc_envision.html"
549
- url += self._get_query_parameters_str(self._query_params)
550
- self._url = url
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
 
@@ -0,0 +1,1035 @@
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
+ from ansys.api.pyensight import ensight_api
30
+ from ansys.api.pyensight.ens_part import ENS_PART
31
+ from ansys.api.pyensight.ens_part_particle_trace import ENS_PART_PARTICLE_TRACE
32
+ from ansys.api.pyensight.ens_var import ENS_VAR
33
+
34
+
35
+ def convert_part(
36
+ _ensight: Union["ensight_api.ensight", "ensight"], part: Union[str, int, "ENS_PART"]
37
+ ):
38
+ if isinstance(part, str):
39
+ return _ensight.objs.core.PARTS[part][0].PARTNUMBER
40
+ elif isinstance(part, int):
41
+ return part
42
+ elif hasattr(part, "PARTNUMBER"):
43
+ return part.PARTNUMBER
44
+
45
+
46
+ def convert_variable(
47
+ _ensight: Union["ensight_api.ensight", "ensight"], var: Union[str, int, "ENS_VAR"]
48
+ ):
49
+ if isinstance(var, str):
50
+ return _ensight.objs.core.VARIABLES[var][0].ID
51
+ elif isinstance(var, int):
52
+ return var
53
+ elif hasattr(var, "ID"):
54
+ return var.ID
55
+
56
+
57
+ class Parts:
58
+ """Controls the parts in the current EnSight ``Session`` instance."""
59
+
60
+ class _EnSEmitterPoint(ens_emitterobj):
61
+ def __init__(
62
+ self,
63
+ ensight: "ensight",
64
+ point1: Optional[List[float]] = [0, 0, 0],
65
+ ):
66
+ if not isinstance(ensight, ModuleType):
67
+ raise RuntimeError(
68
+ "The class cannot be used directly in PyEnSight. It should not be used directly even in EnSight"
69
+ )
70
+ super().__init__(ensight.objs.EMIT_CURSOR)
71
+ self.ensight = ensight
72
+ self.ensight.view_transf.cursor(*point1)
73
+ self.CENTROID = point1
74
+
75
+ class _EnSEmitterGrid(ens_emitterobj):
76
+ def __init__(
77
+ self,
78
+ ensight: "ensight",
79
+ point1: Optional[List[float]] = [0, 0, 0],
80
+ point2: Optional[List[float]] = [0, 0, 0],
81
+ point3: Optional[List[float]] = [0, 0, 0],
82
+ point4: Optional[List[float]] = [0, 0, 0],
83
+ num_points_x: Optional[int] = 25,
84
+ num_points_y: Optional[int] = 25,
85
+ ):
86
+ if not isinstance(ensight, ModuleType):
87
+ raise RuntimeError(
88
+ "The class cannot be used directly in PyEnSight. It should not be used directly even in EnSight"
89
+ )
90
+ super().__init__(ensight.objs.EMIT_PLANE)
91
+ self.ensight = ensight
92
+ self.ensight.view_transf.plane(1, *point1)
93
+ self.ensight.view_transf.plane(2, *point2)
94
+ self.ensight.view_transf.plane(3, *point3)
95
+ self.POINT1 = point1
96
+ self.POINT2 = point2
97
+ self.POINT3 = point3
98
+ self.POINT4 = point4
99
+ self.NUM_POINTS_X = num_points_x
100
+ self.NUM_POINTS_Y = num_points_y
101
+
102
+ class _EnSEmitterLine(ens_emitterobj):
103
+ def __init__(
104
+ self,
105
+ ensight: "ensight",
106
+ point1: Optional[List[float]] = [0, 0, 0],
107
+ point2: Optional[List[float]] = [0, 0, 0],
108
+ num_points: Optional[int] = 100,
109
+ ):
110
+ if not isinstance(ensight, ModuleType):
111
+ raise RuntimeError(
112
+ "The class cannot be used directly in PyEnSight. It should not be used directly even in EnSight"
113
+ )
114
+ super().__init__(ensight.objs.EMIT_LINE)
115
+ self.ensight = ensight
116
+ self.ensight.view_transf.line(1, *point1)
117
+ self.ensight.view_transf.line(2, *point2)
118
+ self.POINT1 = point1
119
+ self.POINT2 = point2
120
+ self.NUM_POINTS = num_points
121
+
122
+ class _EnSEmitterPart(ens_emitterobj):
123
+ def __init__(
124
+ self,
125
+ ensight: "ensight",
126
+ part: Optional[Any] = None,
127
+ part_kind: Optional[Any] = 0,
128
+ num_points: Optional[int] = 100,
129
+ ):
130
+ if not isinstance(ensight, ModuleType):
131
+ raise RuntimeError(
132
+ "The class cannot be used directly in PyEnSight. It should not be used directly even in EnSight"
133
+ )
134
+ super().__init__(ensight.objs.EMIT_PART)
135
+ self.ensight = ensight
136
+ if not part:
137
+ raise RuntimeError("part is a required input")
138
+ self.PART = convert_part(self.ensight, part)
139
+ self.NUM_POINTS = num_points
140
+ self.DISTRIB_TYPE = part_kind
141
+
142
+ def __init__(self, ensight: Union["ensight_api.ensight", "ensight"]):
143
+ self.ensight = ensight
144
+
145
+ def select_parts_by_dimension(self, dimension: int) -> ensobjlist["ENS_PART"]:
146
+ """Select parts by the input dimension and return the parts found.
147
+
148
+ Parameters
149
+ ----------
150
+ dimension : int
151
+ Dimension for selecting parts.
152
+
153
+ Returns
154
+ -------
155
+ ensobjlist["ENS_PART"]
156
+ found (ensobjlist): List of parts found.
157
+
158
+ """
159
+ parts = self.ensight.objs.core.PARTS
160
+ parts.set_attr("SELECTED", False)
161
+ found = parts.find(True, f"HAS{dimension}DELEMENTS")
162
+ found.set_attr("SELECTED", True)
163
+ return found
164
+
165
+ def select_parts_invert(self) -> ensobjlist["ENS_PART"]:
166
+ """Select parts currently not selected, deselecting the previously selected parts.
167
+
168
+ Returns
169
+ -------
170
+ ensobjlist["ENS_PART"]
171
+ Updated list of parts selected.
172
+
173
+ """
174
+ self.ensight.part.select_invert()
175
+ parts = self.ensight.objs.core.PARTS
176
+ return parts.find(True, "SELECTED")
177
+
178
+ def select_parts_by_tag(
179
+ self,
180
+ tag: Optional[str] = None,
181
+ value: Optional[str] = None,
182
+ tagdict: Optional[Dict[str, str]] = None,
183
+ ) -> ensobjlist["ENS_PART"]:
184
+ """Select parts by the input dimension and return the parts found.
185
+
186
+ Parameters
187
+ ----------
188
+ tag : str, optional
189
+ Tag for finding the parts.
190
+ value : str, optional
191
+ Value for finding the parts.
192
+ tagdict : dict, optional
193
+ Dictionary containing the key and value pairs for finding
194
+ the parts. Only the parts that have all the keys and corresponding
195
+ values are returned. If a value for this parameter is supplied, it
196
+ takes precedence over the valeus supplied for the ``tag`` and
197
+ ``value`` parameters.
198
+
199
+ Returns
200
+ -------
201
+ ensobjlist["ENS_PART"]
202
+ List of parts found. If no arguments are given, all parts are returned.
203
+
204
+ """
205
+ parts = self.ensight.objs.core.PARTS
206
+ metadata = {p: p.METADATA for p in parts}
207
+ found = ensobjlist()
208
+ if not tag and not value and not tagdict:
209
+ self.ensight.part.select_all()
210
+ return parts
211
+ if not tagdict:
212
+ if tag and value:
213
+ found = ensobjlist([p for p, met in metadata.items() if met.get(tag) == value])
214
+ elif value and not tag:
215
+ found = ensobjlist([p for p, met in metadata.items() if value in met.values()])
216
+ elif tag and not value:
217
+ found = ensobjlist([p for p, met in metadata.items() if tag in met.keys()])
218
+ else:
219
+ found = ensobjlist(
220
+ [
221
+ p
222
+ for p, met in metadata.items()
223
+ if all(met.get(k) == v for k, v in tagdict.items())
224
+ ]
225
+ )
226
+ if found:
227
+ found.set_attr("SELECTED", True)
228
+ return found
229
+
230
+ _EMIT_POINT: int = 0
231
+ _EMIT_LINE: int = 1
232
+ _EMIT_PLANE: int = 2
233
+ _EMIT_PART: int = 3
234
+ PT_POS_TIME: str = "+"
235
+ PT_NEG_TIME: str = "-"
236
+ PT_POS_NEG_TIME: str = "+/-"
237
+ PART_EMIT_FROM_NODES: int = 0
238
+ PART_EMIT_FROM_AREA: int = 1
239
+
240
+ def _create_emitters(
241
+ self,
242
+ emitter_type: int,
243
+ points: Optional[List[List[float]]] = None,
244
+ point1: Optional[List[float]] = None,
245
+ point2: Optional[List[float]] = None,
246
+ point3: Optional[List[float]] = None,
247
+ parts: Optional[List["ENS_PART"]] = None,
248
+ part_distribution_type: Optional[int] = 0,
249
+ num_points: Optional[int] = 100,
250
+ num_points_x: Optional[int] = 25,
251
+ num_points_y: Optional[int] = 25,
252
+ ) -> List[Any]:
253
+ """Private routine to create emitter objects"""
254
+ new_emitters: List[Any] = []
255
+ if emitter_type == self._EMIT_POINT:
256
+ if not points:
257
+ raise RuntimeError("list of points needed if particle trace emitted from points")
258
+ for p in points:
259
+ if isinstance(self.ensight, ModuleType):
260
+ new_emitters.append(self._EnSEmitterPoint(self.ensight, point1=p))
261
+ else:
262
+ new_emitters.append(
263
+ f"ensight.utils.parts._EnSEmitterPoint(ensight, point1={p})"
264
+ )
265
+ elif emitter_type == self._EMIT_LINE:
266
+ if not any([point1, point2]):
267
+ raise RuntimeError("point1 and point2 needed if particle trace emitted from line")
268
+ if isinstance(self.ensight, ModuleType):
269
+ new_emitters.append(
270
+ self._EnSEmitterLine(
271
+ self.ensight, point1=point1, point2=point2, num_points=num_points
272
+ )
273
+ )
274
+ else:
275
+ new_emitters.append(
276
+ f"ensight.utils.parts._EnSEmitterLine(ensight, point1={point1}, point2={point2}, num_points={num_points})"
277
+ )
278
+ elif emitter_type == self._EMIT_PLANE:
279
+ if not any([point1, point2, point3]):
280
+ raise RuntimeError(
281
+ "point1, point2 and point3 needed if particle trace emitted from plane"
282
+ )
283
+ if isinstance(self.ensight, ModuleType):
284
+ new_emitters.append(
285
+ self._EnSEmitterGrid(
286
+ self.ensight,
287
+ point1=point1,
288
+ point2=point2,
289
+ point3=point3,
290
+ num_points_x=num_points_x,
291
+ num_points_y=num_points_y,
292
+ )
293
+ )
294
+ else:
295
+ new_emitters.append(
296
+ f"ensight.utils.parts._EnSEmitterGrid(ensight, point1={point1}, point2={point2}, point3={point3}, num_points_x={num_points_x}, num_points_y={num_points_y})"
297
+ )
298
+ elif emitter_type == self._EMIT_PART:
299
+ if not parts:
300
+ raise RuntimeError("part and num_points needed if particle trace emitted from part")
301
+ for p in parts:
302
+ if isinstance(self.ensight, ModuleType):
303
+ new_emitters.append(
304
+ self._EnSEmitterPart(
305
+ self.ensight,
306
+ part=p,
307
+ num_points=num_points,
308
+ part_kind=part_distribution_type,
309
+ )
310
+ )
311
+ else:
312
+ new_emitters.append(
313
+ f"ensight.utils.parts._EnSEmitterPart(ensight, part={convert_part(self.ensight ,p)}, num_points={num_points}, part_kind={part_distribution_type})"
314
+ )
315
+ else:
316
+ raise RuntimeError("No input provided to create the emitters for the particle trace")
317
+ return new_emitters
318
+
319
+ def _create_particle_trace_part(
320
+ self,
321
+ name: str,
322
+ variable: Union[str, int, "ENS_VAR"],
323
+ direction: str,
324
+ source_parts: List["ENS_PART"],
325
+ pathlines: Optional[bool] = False,
326
+ emit_time: Optional[float] = None,
327
+ total_time: Optional[float] = None,
328
+ delta_time: Optional[float] = None,
329
+ surface_restrict: Optional[bool] = False,
330
+ ) -> "ENS_PART_PARTICLE_TRACE":
331
+ """Private routine to create a particle trace part object"""
332
+ current_timestep = None
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: "ENS_PART_PARTICLE_TRACE" = 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
+ current_timestep = self.ensight.objs.core.TIMESTEP
344
+ self.ensight.objs.core.TIMESTEP = self.ensight.objs.core.TIMESTEP_LIMITS[0]
345
+ if total_time:
346
+ def_part.TOTALTIME = total_time
347
+ if delta_time:
348
+ def_part.DELTATIME = delta_time
349
+ if emit_time:
350
+ def_part.STARTTIME = emit_time
351
+ def_part.DESCRIPTION = name
352
+ def_part.VARIABLE = convert_variable(self.ensight, variable)
353
+ def_part.SURFACERESTRICTED = False
354
+ def_part.TRACEDIRECTION = direction_map.get(direction)
355
+ if surface_restrict:
356
+ def_part.SURFACERESTRICTED = True
357
+ particle_trace_part: "ENS_PART_PARTICLE_TRACE" = def_part.createpart(
358
+ sources=source_parts, name=name
359
+ )[0]
360
+ if current_timestep:
361
+ self.ensight.objs.core.TIMESTEP = current_timestep
362
+ return particle_trace_part
363
+
364
+ def _add_emitters_to_particle_trace_part(
365
+ self,
366
+ particle_trace_part: "ENS_PART_PARTICLE_TRACE",
367
+ new_emitters: List[Any],
368
+ palette: Optional[str] = None,
369
+ clean: Optional[bool] = False,
370
+ ) -> "ENS_PART_PARTICLE_TRACE":
371
+ """Private utility to add emitters to an existing particle trace part."""
372
+ if isinstance(self.ensight, ModuleType):
373
+ if clean:
374
+ emitters = []
375
+ else:
376
+ emitters = particle_trace_part.EMITTERS.copy()
377
+ emitters.extend(new_emitters)
378
+ particle_trace_part.EMITTERS = emitters
379
+ else:
380
+ if clean:
381
+ self.ensight._session.cmd("enscl.emitters=[]", do_eval=False)
382
+ else:
383
+ self.ensight._session.cmd(
384
+ f"enscl.emitters=ensight.objs.wrap_id({particle_trace_part.objid}).EMITTERS.copy()",
385
+ do_eval=False,
386
+ )
387
+ text = "enscl.emitters.extend(["
388
+ for emitter in new_emitters:
389
+ text += emitter + ", "
390
+ text = text[:-2]
391
+ text += "])"
392
+ self.ensight._session.cmd(text, do_eval=False)
393
+ self.ensight._session.cmd(
394
+ f"ensight.objs.wrap_id({particle_trace_part.objid}).setattr('EMITTERS', enscl.emitters.copy())"
395
+ )
396
+ self.ensight._session.cmd("del enscl.emitters", do_eval=False)
397
+ if palette:
398
+ particle_trace_part.COLORBYPALETTE = palette
399
+ return particle_trace_part
400
+
401
+ def _cure_particle_trace_part(
402
+ self, particle_trace_part: Union[str, int, "ENS_PART_PARTICLE_TRACE"]
403
+ ) -> "ENS_PART_PARTICLE_TRACE":
404
+ """Private utility to cure an input particle trace part and convert it to an ``ENS_PART`"""
405
+ _particle_trace_part: "ENS_PART_PARTICLE_TRACE"
406
+ if isinstance(particle_trace_part, (str, int)):
407
+ temp = self.ensight.objs.core.PARTS[particle_trace_part]
408
+ if not temp:
409
+ raise RuntimeError("particle_trace_part input is not a valid part")
410
+ _particle_trace_part = temp[0]
411
+ else:
412
+ _particle_trace_part = particle_trace_part
413
+ return _particle_trace_part
414
+
415
+ def _prepare_particle_creation(
416
+ self,
417
+ direction: Optional[str] = None,
418
+ source_parts: Optional[List[Union[str, int, "ENS_PART"]]] = None,
419
+ ) -> Tuple[str, List["ENS_PART"]]:
420
+ """Private utility to set the direction if not provided, and to cure the list of source parts."""
421
+ if not direction:
422
+ direction = self.PT_POS_TIME
423
+ if source_parts:
424
+ converted_source_parts = [convert_part(self.ensight, p) for p in source_parts]
425
+ if not source_parts:
426
+ converted_source_parts = self.ensight.objs.core.selection(name="ENS_PART")
427
+ if not converted_source_parts:
428
+ raise RuntimeError("No part selected for particle trace generation")
429
+ return direction, converted_source_parts
430
+
431
+ def _find_palette(self, color_by: Optional[Union[str, int, "ENS_VAR"]] = None) -> Optional[str]:
432
+ """Private utility to find the description of the input color_by variable"""
433
+ palette: Optional[str] = None
434
+ if color_by:
435
+ _color_by_var: List["ENS_VAR"] = ensight.objs.core.VARIABLES[
436
+ convert_variable(self.ensight, color_by)
437
+ ]
438
+ if _color_by_var:
439
+ palette = _color_by_var[0].DESCRIPTION
440
+ else:
441
+ raise RuntimeError(
442
+ "The variable supplied to color the particle trace by does not exist"
443
+ )
444
+ return palette
445
+
446
+ def create_particle_trace_from_points(
447
+ self,
448
+ name: str,
449
+ variable: Union[str, int, "ENS_VAR"],
450
+ points: List[List[float]],
451
+ direction: Optional[str] = None,
452
+ pathlines: Optional[bool] = False,
453
+ source_parts: Optional[List[Union[str, int, "ENS_PART"]]] = None,
454
+ emit_time: Optional[float] = None,
455
+ total_time: Optional[float] = None,
456
+ delta_time: Optional[float] = None,
457
+ color_by: Optional[Union[str, int, "ENS_VAR"]] = None,
458
+ ) -> "ENS_PART_PARTICLE_TRACE":
459
+ """
460
+ Create a particle trace part from a list o points.
461
+ Returns the ``ENS_PART`` generated.
462
+
463
+ Parameters:
464
+ -----------
465
+
466
+ name: str
467
+ The name of part to be generated
468
+ variable:
469
+ The variable to compute the particle traces with.
470
+ It can be the name, the ID or the ``ENS_VAR`` object. It must be a vector variable.
471
+ direction: str
472
+ The direction for the particle traces to be generated.
473
+ This table describes the options:
474
+
475
+ ================== ==============================================
476
+ Name Query type
477
+ ================== ==============================================
478
+ PT_POS_TIME Follow the vector direction
479
+ PT_NEG_TIME Go contrary to the vector direction
480
+ PT_POS_NEG_TIME Follow and go contrary to the vector direction
481
+ ================== ==============================================
482
+
483
+ If not provided, it will default to ``PT_POS_TIME``
484
+ pathlines: bool
485
+ True if the particle traces need to be pathlines
486
+ points: list
487
+ List of coordinates for the seed points.
488
+ source_parts: list
489
+ A list of parts to create the particle trace in. For instance, in a CFD
490
+ simulation this might be the fluid zone.
491
+ If not provided, the function will try to look for the selected parts.
492
+ emit_time: float
493
+ The emission time to start the particle trace from. If not provided,
494
+ it will use the current time.
495
+ total_time: float
496
+ The total emission time. If not provided, EnSight will provide the end time
497
+ for a transient simulation, an internal best time for steady state simulations.
498
+ delta_time: float
499
+ The interval for the emissions. If not provided, EnSight will provide
500
+ a best estimate.
501
+ color_by
502
+ The optional variable to color the particle trace by.
503
+ It can be the name, the ID or the ``ENS_VAR`` object.
504
+
505
+ Examples
506
+ --------
507
+ >>> s = LocalLauncher().start()
508
+ >>> cas_file = s.download_pyansys_example("mixing_elbow.cas.h5","pyfluent/mixing_elbow")
509
+ >>> dat_file = s.download_pyansys_example("mixing_elbow.dat.h5","pyfluent/mixing_elbow")
510
+ >>> s.load_data(cas_file, result_file=dat_file)
511
+ >>> s.ensight.utils.parts.create_particle_trace_from_points("mytraces", "Velocity", points=[[-0.02,-0.123,0.01576],[0.109876,-0.123,0.0123]], source_parts=parts.select_parts_by_dimension(3))
512
+ """
513
+ emitter_type = self._EMIT_POINT
514
+ direction, converted_source_parts = self._prepare_particle_creation(
515
+ direction=direction, source_parts=source_parts
516
+ )
517
+ particle_trace_part = self._create_particle_trace_part(
518
+ name,
519
+ variable,
520
+ direction,
521
+ converted_source_parts,
522
+ pathlines=pathlines,
523
+ emit_time=emit_time,
524
+ delta_time=delta_time,
525
+ total_time=total_time,
526
+ )
527
+ new_emitters = self._create_emitters(emitter_type=emitter_type, points=points)
528
+ palette = self._find_palette(color_by=color_by)
529
+ return self._add_emitters_to_particle_trace_part(
530
+ particle_trace_part, new_emitters=new_emitters, palette=palette, clean=True
531
+ )
532
+
533
+ def create_particle_trace_from_line(
534
+ self,
535
+ name: str,
536
+ variable: Union[str, int, "ENS_VAR"],
537
+ point1: List[float],
538
+ point2: List[float],
539
+ num_points: Optional[int] = 100,
540
+ direction: Optional[str] = None,
541
+ pathlines: Optional[bool] = False,
542
+ source_parts: Optional[List[Union[str, int, "ENS_PART"]]] = None,
543
+ emit_time: Optional[float] = None,
544
+ total_time: Optional[float] = None,
545
+ delta_time: Optional[float] = None,
546
+ color_by: Optional[Union[str, int, "ENS_VAR"]] = None,
547
+ ) -> "ENS_PART_PARTICLE_TRACE":
548
+ """
549
+ Create a particle trace part from a line.
550
+ Returns the ``ENS_PART`` generated.
551
+
552
+ Parameters:
553
+ -----------
554
+
555
+ name: str
556
+ The name of part to be generated
557
+ variable:
558
+ The variable to compute the particle traces with.
559
+ It can be the name, the ID or the ``ENS_VAR`` object. It must be a vector variable.
560
+ direction: str
561
+ The direction for the particle traces to be generated.
562
+ This table describes the options:
563
+
564
+ ================== ==============================================
565
+ Name Query type
566
+ ================== ==============================================
567
+ PT_POS_TIME Follow the vector direction
568
+ PT_NEG_TIME Go contrary to the vector direction
569
+ PT_POS_NEG_TIME Follow and go contrary to the vector direction
570
+ ================== ==============================================
571
+
572
+ If not provided, it will default to ``PT_POS_TIME``
573
+ pathlines: bool
574
+ True if the particle traces need to be pathlines
575
+ point1: list
576
+ List of coordinates for point 1.
577
+ point2: list
578
+ List of coordinates for point 2.
579
+ source_parts: list
580
+ A list of parts to create the particle trace in. For instance, in a CFD
581
+ simulation this might be the fluid zone.
582
+ If not provided, the function will try to look for the selected parts.
583
+ num_points: int
584
+ The number of points to emit from. Defaults to 100.
585
+ emit_time: float
586
+ The emission time to start the particle trace from. If not provided,
587
+ it will use the current time.
588
+ total_time: float
589
+ The total emission time. If not provided, EnSight will provide the end time
590
+ for a transient simulation, an internal best time for steady state simulations.
591
+ delta_time: float
592
+ The interval for the emissions. If not provided, EnSight will provide
593
+ a best estimate.
594
+ color_by
595
+ The optional variable to color the particle trace by.
596
+ It can be the name, the ID or the ``ENS_VAR`` object.
597
+
598
+ Examples
599
+ --------
600
+ >>> s = LocalLauncher().start()
601
+ >>> cas_file = s.download_pyansys_example("mixing_elbow.cas.h5","pyfluent/mixing_elbow")
602
+ >>> dat_file = s.download_pyansys_example("mixing_elbow.dat.h5","pyfluent/mixing_elbow")
603
+ >>> s.load_data(cas_file, result_file=dat_file)
604
+ >>> parts = s.ensight.utils.parts
605
+ >>> parts.create_particle_trace_from_line("mytraces", "Velocity", point1=[-0.02,-0.123,0.01576], point2=[0.109876,-0.123,0.0123], num_points=10, source_parts=parts.select_parts_by_dimension(3))
606
+ """
607
+ emitter_type = self._EMIT_LINE
608
+ direction, converted_source_parts = self._prepare_particle_creation(
609
+ direction=direction, source_parts=source_parts
610
+ )
611
+ particle_trace_part = self._create_particle_trace_part(
612
+ name,
613
+ variable,
614
+ direction,
615
+ converted_source_parts,
616
+ pathlines=pathlines,
617
+ emit_time=emit_time,
618
+ delta_time=delta_time,
619
+ total_time=total_time,
620
+ )
621
+ new_emitters = self._create_emitters(
622
+ emitter_type=emitter_type, point1=point1, point2=point2, num_points=num_points
623
+ )
624
+ palette = self._find_palette(color_by=color_by)
625
+ return self._add_emitters_to_particle_trace_part(
626
+ particle_trace_part, new_emitters=new_emitters, palette=palette, clean=True
627
+ )
628
+
629
+ def create_particle_trace_from_plane(
630
+ self,
631
+ name: str,
632
+ variable: Union[str, int, "ENS_VAR"],
633
+ point1: List[float],
634
+ point2: List[float],
635
+ point3: List[float],
636
+ num_points_x: Optional[int] = 25,
637
+ num_points_y: Optional[int] = 25,
638
+ direction: Optional[str] = None,
639
+ pathlines: Optional[bool] = False,
640
+ source_parts: Optional[List[Union[str, int, "ENS_PART"]]] = None,
641
+ emit_time: Optional[float] = None,
642
+ total_time: Optional[float] = None,
643
+ delta_time: Optional[float] = None,
644
+ color_by: Optional[Union[str, int, "ENS_VAR"]] = None,
645
+ ) -> "ENS_PART_PARTICLE_TRACE":
646
+ """
647
+ Create a particle trace part from a plane.
648
+ Returns the ``ENS_PART`` generated.
649
+
650
+ Parameters:
651
+ -----------
652
+
653
+ name: str
654
+ The name of part to be generated
655
+ variable:
656
+ The variable to compute the particle traces with.
657
+ It can be the name, the ID or the ``ENS_VAR`` object. It must be a vector variable.
658
+ direction: str
659
+ The direction for the particle traces to be generated.
660
+ This table describes the options:
661
+
662
+ ================== ==============================================
663
+ Name Query type
664
+ ================== ==============================================
665
+ PT_POS_TIME Follow the vector direction
666
+ PT_NEG_TIME Go contrary to the vector direction
667
+ PT_POS_NEG_TIME Follow and go contrary to the vector direction
668
+ ================== ==============================================
669
+
670
+ If not provided, it will default to ``PT_POS_TIME``
671
+ pathlines: bool
672
+ True if the particle traces need to be pathlines
673
+ point1: list
674
+ List of coordinates for point 1, being a corner of the plane.
675
+ point2: list
676
+ List of coordinates for point 2, being a corner of the plane.
677
+ point3: list
678
+ List of coordinates for point 3, being a corner of the plane.
679
+ source_parts: list
680
+ A list of parts to create the particle trace in. For instance, in a CFD
681
+ simulation this might be the fluid zone.
682
+ If not provided, the function will try to look for the selected parts.
683
+ num_points_x: int
684
+ The number of points on the ``X`` direction of the emission plane.
685
+ Defaults to 25.
686
+ num_points_y: int
687
+ The number of points on the ``Y`` direction of the emission plane.
688
+ Defaults to 25.
689
+ emit_time: float
690
+ The emission time to start the particle trace from. If not provided,
691
+ it will use the current time.
692
+ total_time: float
693
+ The total emission time. If not provided, EnSight will provide the end time
694
+ for a transient simulation, an internal best time for steady state simulations.
695
+ delta_time: float
696
+ The interval for the emissions. If not provided, EnSight will provide
697
+ a best estimate.
698
+ color_by
699
+ The optional variable to color the particle trace by.
700
+ It can be the name, the ID or the ``ENS_VAR`` object.
701
+
702
+ Examples
703
+ --------
704
+ >>> s = LocalLauncher().start()
705
+ >>> cas_file = s.download_pyansys_example("mixing_elbow.cas.h5","pyfluent/mixing_elbow")
706
+ >>> dat_file = s.download_pyansys_example("mixing_elbow.dat.h5","pyfluent/mixing_elbow")
707
+ >>> s.load_data(cas_file, result_file=dat_file)
708
+ >>> parts = s.ensight.utils.parts
709
+ >>> parts.create_particle_trace_from_plane("mytraces", "Velocity", point1=[-0.02,-0.123,0.01576], point2=[0.109876,-0.123,0.0123], point3=[0.1, 0, 0.05] ,num_points_x=10, num_points_y=10, source_parts=parts.select_parts_by_dimension(3))
710
+ """
711
+ emitter_type = self._EMIT_PLANE
712
+ direction, converted_source_parts = self._prepare_particle_creation(
713
+ direction=direction, source_parts=source_parts
714
+ )
715
+ particle_trace_part = self._create_particle_trace_part(
716
+ name,
717
+ variable,
718
+ direction,
719
+ converted_source_parts,
720
+ pathlines=pathlines,
721
+ emit_time=emit_time,
722
+ delta_time=delta_time,
723
+ total_time=total_time,
724
+ )
725
+ new_emitters = self._create_emitters(
726
+ emitter_type=emitter_type,
727
+ point1=point1,
728
+ point2=point2,
729
+ point3=point3,
730
+ num_points_x=num_points_x,
731
+ num_points_y=num_points_y,
732
+ )
733
+ palette = self._find_palette(color_by=color_by)
734
+ return self._add_emitters_to_particle_trace_part(
735
+ particle_trace_part, new_emitters=new_emitters, palette=palette, clean=True
736
+ )
737
+
738
+ def create_particle_trace_from_parts(
739
+ self,
740
+ name: str,
741
+ variable: Union[str, int, "ENS_VAR"],
742
+ parts: List[Union[str, int, "ENS_PART"]],
743
+ part_distribution_type: Optional[int] = 0,
744
+ num_points: Optional[int] = 100,
745
+ direction: Optional[str] = None,
746
+ pathlines: Optional[bool] = False,
747
+ source_parts: Optional[List[Union[str, int, "ENS_PART"]]] = None,
748
+ emit_time: Optional[float] = None,
749
+ total_time: Optional[float] = None,
750
+ delta_time: Optional[float] = None,
751
+ color_by: Optional[Union[str, int, "ENS_VAR"]] = None,
752
+ surface_restrict: Optional[bool] = False,
753
+ ) -> "ENS_PART_PARTICLE_TRACE":
754
+ """
755
+ Create a particle trace part from a list of seed parts.
756
+ Returns the ``ENS_PART`` generated.
757
+
758
+ Parameters:
759
+ -----------
760
+
761
+ name: str
762
+ The name of part to be generated
763
+ variable:
764
+ The variable to compute the particle traces with.
765
+ It can be the name, the ID or the ``ENS_VAR`` object. It must be a vector variable.
766
+ direction: str
767
+ The direction for the particle traces to be generated.
768
+ This table describes the options:
769
+
770
+ ================== ==============================================
771
+ Name Query type
772
+ ================== ==============================================
773
+ PT_POS_TIME Follow the vector direction
774
+ PT_NEG_TIME Go contrary to the vector direction
775
+ PT_POS_NEG_TIME Follow and go contrary to the vector direction
776
+ ================== ==============================================
777
+
778
+ If not provided, it will default to ``PT_POS_TIME``
779
+ pathlines: bool
780
+ True if the particle traces need to be pathlines
781
+ source_parts: list
782
+ A list of parts to create the particle trace in. For instance, in a CFD
783
+ simulation this might be the fluid zone.
784
+ If not provided, the function will try to look for the selected parts.
785
+ parts: list
786
+ A list of parts to emit the particle traces from.
787
+ They can be their names, their IDs or the respective ``ENS_PART`` objects.
788
+ part_distribution_type: int
789
+ The distribution of emitters in case of emission from a part.
790
+ This table describes the options:
791
+
792
+ ==================== =================================================
793
+ Name Query type
794
+ ==================== =================================================
795
+ PART_EMIT_FROM_NODES Emit from the nodes of the part
796
+ PART_EMIT_FROM_AREA Create an area of equidistant points for emission
797
+ ================== =================================================
798
+
799
+ If not provided, it will default to ``PART_EMIT_FROM_NODES``
800
+ num_points: int
801
+ The number of points to emit from.
802
+ Defaults to 100.
803
+ emit_time: float
804
+ The emission time to start the particle trace from. If not provided,
805
+ it will use the current time.
806
+ total_time: float
807
+ The total emission time. If not provided, EnSight will provide the end time
808
+ for a transient simulation, an internal best time for steady state simulations.
809
+ delta_time: float
810
+ The interval for the emissions. If not provided, EnSight will provide
811
+ a best estimate.
812
+ color_by
813
+ The optional variable to color the particle trace by.
814
+ It can be the name, the ID or the ``ENS_VAR`` object.
815
+ surface_restrict: bool
816
+ True if the particle trace needs to be restricted to the input parts.
817
+ Defaults to False. The flag will be applied to any additional emitter
818
+ appended to the particle trace created.
819
+
820
+ Examples
821
+ --------
822
+ >>> s = LocalLauncher().start()
823
+ >>> cas_file = s.download_pyansys_example("mixing_elbow.cas.h5","pyfluent/mixing_elbow")
824
+ >>> dat_file = s.download_pyansys_example("mixing_elbow.dat.h5","pyfluent/mixing_elbow")
825
+ >>> s.load_data(cas_file, result_file=dat_file)
826
+ >>> parts = s.ensight.utils.parts
827
+ >>> parts.create_particle_trace_from_parts("mytraces", "Velocity", parts=["hot-inlet", "cold-inlet"], num_points=100 source_parts=parts.select_parts_by_dimension(3))
828
+ """
829
+ emitter_type = self._EMIT_PART
830
+ direction, converted_source_parts = self._prepare_particle_creation(
831
+ direction=direction, source_parts=source_parts
832
+ )
833
+ particle_trace_part = self._create_particle_trace_part(
834
+ name,
835
+ variable,
836
+ direction,
837
+ converted_source_parts,
838
+ pathlines=pathlines,
839
+ emit_time=emit_time,
840
+ delta_time=delta_time,
841
+ total_time=total_time,
842
+ surface_restrict=surface_restrict,
843
+ )
844
+ new_parts = [convert_part(self.ensight, p) for p in parts]
845
+ new_emitters = self._create_emitters(
846
+ emitter_type=emitter_type,
847
+ parts=new_parts,
848
+ part_distribution_type=part_distribution_type,
849
+ num_points=num_points,
850
+ )
851
+ palette = self._find_palette(color_by=color_by)
852
+ return self._add_emitters_to_particle_trace_part(
853
+ particle_trace_part, new_emitters=new_emitters, palette=palette, clean=True
854
+ )
855
+
856
+ def add_emitter_points_to_particle_trace_part(
857
+ self,
858
+ particle_trace_part: Union[str, int, "ENS_PART"],
859
+ points: List[List[float]],
860
+ ) -> "ENS_PART_PARTICLE_TRACE":
861
+ """
862
+ Add point emitters to an existing particle trace. The function will return the updated
863
+ ``ENS_PART`` object.
864
+
865
+ Parameters:
866
+ -----------
867
+
868
+ particle_trace_part:
869
+ The particle trace part to be added emitters to.
870
+ Can be the name, the ID or the ``ENS_PART`` object
871
+ points: list
872
+ List of list containing the coordinates for the seed points.
873
+
874
+ Examples
875
+ --------
876
+ >>> s = LocalLauncher().start()
877
+ >>> cas_file = s.download_pyansys_example("mixing_elbow.cas.h5","pyfluent/mixing_elbow")
878
+ >>> dat_file = s.download_pyansys_example("mixing_elbow.dat.h5","pyfluent/mixing_elbow")
879
+ >>> s.load_data(cas_file, result_file=dat_file)
880
+ >>> p = s.ensight.utils.parts.create_particle_trace_from_points("mytraces", "Velocity", points=[[-0.02, -0.123, 0.01576]], source_parts=parts.select_parts_by_dimension(3))
881
+ >>> p = s.ensight.utils.parts.add_emitter_points_to_particle_trace_part(p, points=[[0.109876, -0.123, 0.0123]])
882
+ """
883
+ emitter_type = self._EMIT_POINT
884
+ particle_trace_part = self._cure_particle_trace_part(particle_trace_part)
885
+ new_emitters = self._create_emitters(emitter_type=emitter_type, points=points)
886
+ return self._add_emitters_to_particle_trace_part(particle_trace_part, new_emitters)
887
+
888
+ def add_emitter_line_to_particle_trace_part(
889
+ self,
890
+ particle_trace_part: Union[str, int, "ENS_PART"],
891
+ point1: List[float],
892
+ point2: List[float],
893
+ num_points: Optional[int] = 100,
894
+ ) -> "ENS_PART_PARTICLE_TRACE":
895
+ """
896
+ Add a line emitter to an existing particle trace. The function will return the updated
897
+ ``ENS_PART`` object.
898
+
899
+ Parameters:
900
+ -----------
901
+
902
+ particle_trace_part:
903
+ The particle trace part to be added emitters to.
904
+ Can be the name, the ID or the ``ENS_PART`` object.
905
+ point1: list
906
+ The coordinates for point 1.
907
+ point2: list
908
+ The coordinates for point 2.
909
+ num_points: int
910
+ The number of seed points. Defaults to 100.
911
+
912
+ Examples
913
+ --------
914
+ >>> s = LocalLauncher().start()
915
+ >>> cas_file = s.download_pyansys_example("mixing_elbow.cas.h5","pyfluent/mixing_elbow")
916
+ >>> dat_file = s.download_pyansys_example("mixing_elbow.dat.h5","pyfluent/mixing_elbow")
917
+ >>> s.load_data(cas_file, result_file=dat_file)
918
+ >>> p = s.ensight.utils.parts.create_particle_trace_from_points("mytraces", "Velocity", points=[[-0.02,-0.123,0.01576]], source_parts=parts.select_parts_by_dimension(3))
919
+ >>> p = s.ensight.utils.parts.add_emitter_line_to_particle_trace_part(p, point1=[-0.02, -0.123, 0.01576], point2=[0.109876, -0.123, 0.0123], num_points=10)
920
+ """
921
+ emitter_type = self._EMIT_LINE
922
+ particle_trace_part = self._cure_particle_trace_part(particle_trace_part)
923
+ new_emitters = self._create_emitters(
924
+ emitter_type=emitter_type, point1=point1, point2=point2, num_points=num_points
925
+ )
926
+ return self._add_emitters_to_particle_trace_part(particle_trace_part, new_emitters)
927
+
928
+ def add_emitter_plane_to_particle_trace_part(
929
+ self,
930
+ particle_trace_part: Union[str, int, "ENS_PART"],
931
+ point1: List[float],
932
+ point2: List[float],
933
+ point3: List[float],
934
+ num_points_x: Optional[int] = 25,
935
+ num_points_y: Optional[int] = 25,
936
+ ) -> "ENS_PART_PARTICLE_TRACE":
937
+ """
938
+ Add a plane emitter to an existing particle trace. The function will return the updated
939
+ ``ENS_PART`` object.
940
+
941
+ Parameters:
942
+ -----------
943
+
944
+ particle_trace_part:
945
+ The particle trace part to be added emitters to.
946
+ Can be the name, the ID or the ``ENS_PART`` object.
947
+ point1: list
948
+ The coordinates for point 1, being a corner of the plane.
949
+ point2: list
950
+ The coordinates for point 2, being a corner of the plane.
951
+ point3: list
952
+ The coordinates for point 3, being a corner of the plane.
953
+ num_points_x: int
954
+ The number of points on the ``X`` direction of the emission plane.
955
+ Defaults to 25.
956
+ num_points_y: int
957
+ The number of points on the ``Y`` direction of the emission plane.
958
+ Defaults to 25.
959
+
960
+ Examples
961
+ --------
962
+ >>> s = LocalLauncher().start()
963
+ >>> cas_file = s.download_pyansys_example("mixing_elbow.cas.h5","pyfluent/mixing_elbow")
964
+ >>> dat_file = s.download_pyansys_example("mixing_elbow.dat.h5","pyfluent/mixing_elbow")
965
+ >>> s.load_data(cas_file, result_file=dat_file)
966
+ >>> p = s.ensight.utils.parts.create_particle_trace_from_points("mytraces", "Velocity", points=[[-0.02,-0.123,0.01576]], source_parts=parts.select_parts_by_dimension(3))
967
+ >>> p = s.ensight.utils.parts.add_emitter_plane_to_particle_trace_part(p, point1=[-0.02, -0.123, 0.01576], point2=[0.109876, -0.123, 0.0123], point3=[0.1, 0, 0.05], num_points_x=10, num_points_y=10)
968
+ """
969
+ emitter_type = self._EMIT_PLANE
970
+ particle_trace_part = self._cure_particle_trace_part(particle_trace_part)
971
+ new_emitters = self._create_emitters(
972
+ emitter_type=emitter_type,
973
+ point1=point1,
974
+ point2=point2,
975
+ point3=point3,
976
+ num_points_x=num_points_x,
977
+ num_points_y=num_points_y,
978
+ )
979
+ return self._add_emitters_to_particle_trace_part(particle_trace_part, new_emitters)
980
+
981
+ def add_emitter_parts_to_particle_trace_part(
982
+ self,
983
+ particle_trace_part: Union[str, int, "ENS_PART"],
984
+ parts: List[Union[str, int, "ENS_PART"]],
985
+ part_distribution_type: Optional[int] = 0,
986
+ num_points: Optional[int] = 100,
987
+ ) -> "ENS_PART_PARTICLE_TRACE":
988
+ """
989
+ Add a list of part emitters to an existing particle trace. The function will return the updated
990
+ ``ENS_PART`` object.
991
+
992
+ Parameters:
993
+ -----------
994
+
995
+ particle_trace_part:
996
+ The particle trace part to be added emitters to.
997
+ Can be the name, the ID or the ``ENS_PART`` object.
998
+ parts: list
999
+ A list of parts to emit the particle traces from.
1000
+ They can be their names, their IDs or the respective ``ENS_PART`` objects.
1001
+ part_distribution_type: int
1002
+ The distribution of emitters in case of emission from a part.
1003
+ This table describes the options:
1004
+
1005
+ ==================== =================================================
1006
+ Name Query type
1007
+ ==================== =================================================
1008
+ PART_EMIT_FROM_NODES Emit from the nodes of the part
1009
+ PART_EMIT_FROM_AREA Create an area of equidistant points for emission
1010
+ ================== =================================================
1011
+
1012
+ If not provided, it will default to ``PART_EMIT_FROM_NODES``
1013
+ num_points: int
1014
+ The number of points to emit from.
1015
+ Defaults to 100.
1016
+
1017
+ Examples
1018
+ --------
1019
+ >>> s = LocalLauncher().start()
1020
+ >>> cas_file = s.download_pyansys_example("mixing_elbow.cas.h5","pyfluent/mixing_elbow")
1021
+ >>> dat_file = s.download_pyansys_example("mixing_elbow.dat.h5","pyfluent/mixing_elbow")
1022
+ >>> s.load_data(cas_file, result_file=dat_file)
1023
+ >>> p = s.ensight.utils.parts.create_particle_trace_from_points("mytraces", "Velocity", points=[[-0.02, -0.123, 0.01576]], source_parts=parts.select_parts_by_dimension(3))
1024
+ >>> p = s.ensight.utils.parts.add_emitter_parts_to_particle_trace_part(p, parts=["cold-inlet", "hot-inlet"], num_points=25)
1025
+ """
1026
+ emitter_type = self._EMIT_PART
1027
+ particle_trace_part = self._cure_particle_trace_part(particle_trace_part)
1028
+ new_parts = [convert_part(self.ensight, p) for p in parts]
1029
+ new_emitters = self._create_emitters(
1030
+ emitter_type=emitter_type,
1031
+ parts=new_parts,
1032
+ part_distribution_type=part_distribution_type,
1033
+ num_points=num_points,
1034
+ )
1035
+ return self._add_emitters_to_particle_trace_part(particle_trace_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