pytecplot 1.5.2__py3-none-any.whl
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.
- pytecplot-1.5.2.dist-info/LICENSE.html +77 -0
- pytecplot-1.5.2.dist-info/METADATA +508 -0
- pytecplot-1.5.2.dist-info/RECORD +97 -0
- pytecplot-1.5.2.dist-info/WHEEL +5 -0
- pytecplot-1.5.2.dist-info/top_level.txt +1 -0
- tecplot/__init__.py +94 -0
- tecplot/annotation/__init__.py +7 -0
- tecplot/annotation/annotation.py +223 -0
- tecplot/annotation/geometry.py +369 -0
- tecplot/annotation/georeference.py +33 -0
- tecplot/annotation/image.py +185 -0
- tecplot/annotation/iter.py +105 -0
- tecplot/annotation/polyline.py +381 -0
- tecplot/annotation/text.py +744 -0
- tecplot/constant.py +401 -0
- tecplot/data/__init__.py +34 -0
- tecplot/data/array.py +645 -0
- tecplot/data/create.py +1 -0
- tecplot/data/dataset.py +1809 -0
- tecplot/data/extract.py +544 -0
- tecplot/data/face_neighbors.py +494 -0
- tecplot/data/facemap.py +814 -0
- tecplot/data/load.py +2075 -0
- tecplot/data/nodemap.py +577 -0
- tecplot/data/operate.py +928 -0
- tecplot/data/query.py +334 -0
- tecplot/data/save.py +343 -0
- tecplot/data/variable.py +280 -0
- tecplot/data/zone.py +841 -0
- tecplot/exception.py +201 -0
- tecplot/export/__init__.py +13 -0
- tecplot/export/animation.py +521 -0
- tecplot/export/export_setup.py +318 -0
- tecplot/export/image.py +577 -0
- tecplot/export/print_setup.py +218 -0
- tecplot/export/time_animation.py +607 -0
- tecplot/extension/__init__.py +14 -0
- tecplot/extension/ipython.py +68 -0
- tecplot/layout/__init__.py +20 -0
- tecplot/layout/frame.py +1285 -0
- tecplot/layout/layout.py +488 -0
- tecplot/layout/page.py +541 -0
- tecplot/legend/__init__.py +4 -0
- tecplot/legend/contour_legend.py +516 -0
- tecplot/legend/legend.py +141 -0
- tecplot/legend/line_legend.py +66 -0
- tecplot/legend/rgb_coloring_legend.py +291 -0
- tecplot/legend/scatter_legend.py +136 -0
- tecplot/macro.py +339 -0
- tecplot/plot/__init__.py +62 -0
- tecplot/plot/axes.py +881 -0
- tecplot/plot/axis.py +1350 -0
- tecplot/plot/blanking.py +584 -0
- tecplot/plot/contour.py +1302 -0
- tecplot/plot/effects.py +162 -0
- tecplot/plot/fieldmap.py +2159 -0
- tecplot/plot/grid.py +758 -0
- tecplot/plot/isosurface.py +1167 -0
- tecplot/plot/labels.py +338 -0
- tecplot/plot/linemap.py +1905 -0
- tecplot/plot/linking.py +489 -0
- tecplot/plot/plot.py +1791 -0
- tecplot/plot/rgb_coloring.py +281 -0
- tecplot/plot/scatter.py +396 -0
- tecplot/plot/slice.py +1544 -0
- tecplot/plot/streamtrace.py +1949 -0
- tecplot/plot/symbol.py +567 -0
- tecplot/plot/ticks.py +666 -0
- tecplot/plot/title.py +380 -0
- tecplot/plot/vector.py +679 -0
- tecplot/plot/view.py +868 -0
- tecplot/session/__init__.py +112 -0
- tecplot/session/aux_data.py +276 -0
- tecplot/session/config.py +92 -0
- tecplot/session/session.py +425 -0
- tecplot/session/state_changed.py +225 -0
- tecplot/session/style.py +504 -0
- tecplot/tecutil/__init__.py +16 -0
- tecplot/tecutil/arglist.py +230 -0
- tecplot/tecutil/captured_output.py +177 -0
- tecplot/tecutil/constant.py +1312 -0
- tecplot/tecutil/index_set.py +118 -0
- tecplot/tecutil/lock.py +36 -0
- tecplot/tecutil/message_pb2.py +39 -0
- tecplot/tecutil/preamble.py +54 -0
- tecplot/tecutil/stringlist.py +114 -0
- tecplot/tecutil/sv.py +1662 -0
- tecplot/tecutil/tecutil.py +12402 -0
- tecplot/tecutil/tecutil_client.py +627 -0
- tecplot/tecutil/tecutil_connector.py +937 -0
- tecplot/tecutil/tecutil_rpc.py +6845 -0
- tecplot/tecutil/util.py +332 -0
- tecplot/text/__init__.py +3 -0
- tecplot/text/font.py +224 -0
- tecplot/text/label_format.py +374 -0
- tecplot/text/textbox.py +106 -0
- tecplot/version.py +41 -0
tecplot/data/zone.py
ADDED
|
@@ -0,0 +1,841 @@
|
|
|
1
|
+
""".. _Zones:
|
|
2
|
+
|
|
3
|
+
Zones describe the size, shape, element (cell) geometry, connectivity and
|
|
4
|
+
solution time of arrays in a dataset. Zones created as "ordered," "classic
|
|
5
|
+
finite-element," or "polytopal finite-element" along with the number of nodes
|
|
6
|
+
and elements which can not be changed (without creating a new zone). Ordered
|
|
7
|
+
zones are always considered to be logically-rectangular grids of one, two or
|
|
8
|
+
three dimensions depending on the shape. Classic finite-element zones must use
|
|
9
|
+
a fixed-type element throughout. This means that each element has the same
|
|
10
|
+
number of faces and nodes. Polytopal zones can have a varying number of faces
|
|
11
|
+
and nodes for each element. The connectivity is implied in ordered zones and
|
|
12
|
+
explicitly provided by the user for finite-element zones.
|
|
13
|
+
|
|
14
|
+
In PyTecplot, there are three zone class objects: `OrderedZone`,
|
|
15
|
+
`ClassicFEZone` and `PolyFEZone`. The `OrderedZone` and `ClassicFEZone` classes
|
|
16
|
+
use the `FaceNeighbors` class to handle "global" face-neighbor connections from
|
|
17
|
+
one zone to another. The connectivity for the `ClassicFEZone` objects are
|
|
18
|
+
accessed through the `Nodemap` class. The `PolyFEZone` objects provide element
|
|
19
|
+
definition and connectivity access through the `Facemap` class.
|
|
20
|
+
"""
|
|
21
|
+
import logging
|
|
22
|
+
|
|
23
|
+
from functools import reduce
|
|
24
|
+
from textwrap import dedent
|
|
25
|
+
|
|
26
|
+
from ..tecutil import _tecutil, _tecutil_connector
|
|
27
|
+
from ..constant import *
|
|
28
|
+
from ..exception import *
|
|
29
|
+
from .. import session, layout, tecutil, version
|
|
30
|
+
from . import array, face_neighbors, facemap, nodemap
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
log = logging.getLogger(__name__)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@tecutil.lock_attributes
|
|
37
|
+
class Zone(object):
|
|
38
|
+
def __init__(self, uid, dataset):
|
|
39
|
+
self.uid = uid
|
|
40
|
+
self.dataset = dataset
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def _cache(self):
|
|
44
|
+
if _tecutil_connector.suspended:
|
|
45
|
+
_tecutil_connector._delete_caches.append(self._delete_cache)
|
|
46
|
+
return True
|
|
47
|
+
else:
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
def _delete_cache(self):
|
|
51
|
+
attrs = ['_index']
|
|
52
|
+
for attr in attrs:
|
|
53
|
+
try:
|
|
54
|
+
delattr(self, attr)
|
|
55
|
+
except AttributeError:
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
def __str__(self):
|
|
59
|
+
"""Brief string representation.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
`str`: Brief representation of this `Zone <data_access>`,
|
|
63
|
+
showing a list of associated `Variables <Variable>`.
|
|
64
|
+
|
|
65
|
+
Example::
|
|
66
|
+
|
|
67
|
+
>>> rect_zone = dataset.zone('Rectangular zone')
|
|
68
|
+
>>> print(rect_zone)
|
|
69
|
+
Zone: 'Rectangular zone'
|
|
70
|
+
Type: Ordered
|
|
71
|
+
Shape: (10, 10, 10)
|
|
72
|
+
"""
|
|
73
|
+
fmt = dedent('''\
|
|
74
|
+
Zone: '{}'
|
|
75
|
+
Type: {}
|
|
76
|
+
Shape: {}''')
|
|
77
|
+
return fmt.format(self.name, self.zone_type.name, self._shape)
|
|
78
|
+
|
|
79
|
+
def __repr__(self):
|
|
80
|
+
"""Executable string representation.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
`str`: Internal representation of this `Zone
|
|
84
|
+
<data_access>`.
|
|
85
|
+
|
|
86
|
+
The string returned can be executed to generate a clone of this
|
|
87
|
+
`Zone <data_access>` object::
|
|
88
|
+
|
|
89
|
+
>>> rectzone = dataset.zone('Rectangular zone')
|
|
90
|
+
>>> print(repr(rectzone))
|
|
91
|
+
Zone(uid=31, Dataset(uid=21, frame=Frame(uid=11, page=Page(uid=1)))
|
|
92
|
+
>>> exec('rectzone_clone = '+repr(rectzone))
|
|
93
|
+
>>> rectzone_clone
|
|
94
|
+
Zone(uid=31, Dataset(uid=21, frame=Frame(uid=11, page=Page(uid=1)))
|
|
95
|
+
>>> rectzone == rectzone_clone
|
|
96
|
+
True
|
|
97
|
+
"""
|
|
98
|
+
return 'Zone(uid={uid}, dataset={dataset})'.format(
|
|
99
|
+
uid=self.uid, dataset=repr(self.dataset))
|
|
100
|
+
|
|
101
|
+
def __eq__(self, other):
|
|
102
|
+
"""Checks for equality in the |Tecplot Engine|.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
`bool`: `True` if the unique ID numbers are the same for both
|
|
106
|
+
`Zones <data_access>`.
|
|
107
|
+
"""
|
|
108
|
+
return self.uid == other.uid
|
|
109
|
+
|
|
110
|
+
def __ne__(self, other):
|
|
111
|
+
return not (self == other)
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def aux_data(self):
|
|
115
|
+
"""Auxiliary data for this zone.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
`AuxData`
|
|
119
|
+
|
|
120
|
+
This is the auxiliary data attached to the zone. Such data is
|
|
121
|
+
written to the layout file by default and can be retrieved later.
|
|
122
|
+
Example usage::
|
|
123
|
+
|
|
124
|
+
>>> frame = tp.active_frame()
|
|
125
|
+
>>> aux = frame.dataset.zone('My Zone').aux_data
|
|
126
|
+
>>> aux['X_weighted_avg'] = '3.14159'
|
|
127
|
+
>>> print(aux['X_weighted_avg'])
|
|
128
|
+
3.14159
|
|
129
|
+
"""
|
|
130
|
+
return session.AuxData(self.dataset.frame, AuxDataObjectType.Zone,
|
|
131
|
+
self.index)
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def index(self):
|
|
135
|
+
"""`Index`: Zero-based position within the parent `Dataset <tecplot.data.Dataset>`.
|
|
136
|
+
|
|
137
|
+
This is the value used to obtain a specific zone if you have
|
|
138
|
+
duplicately named zones in the dataset::
|
|
139
|
+
|
|
140
|
+
>>> tp.new_layout()
|
|
141
|
+
>>> frame = tp.active_frame()
|
|
142
|
+
>>> dataset = frame.create_dataset('Dataset', ['x', 'y'])
|
|
143
|
+
>>> dataset.add_ordered_zone('Zone', (10,10,10))
|
|
144
|
+
>>> dataset.add_ordered_zone('Zone', (3,3,3))
|
|
145
|
+
>>> # getting zone by name always returns first match
|
|
146
|
+
>>> print(dataset.zone('Zone').index)
|
|
147
|
+
0
|
|
148
|
+
>>> # use index to get specific zone
|
|
149
|
+
>>> print(dataset.zone(1).dimensions)
|
|
150
|
+
(3, 3, 3)
|
|
151
|
+
"""
|
|
152
|
+
if self._cache:
|
|
153
|
+
if not hasattr(self, '_index'):
|
|
154
|
+
num = _tecutil.ZoneGetNumByUniqueID(self.uid)
|
|
155
|
+
self._index = tecutil.Index(num - 1)
|
|
156
|
+
return self._index
|
|
157
|
+
else:
|
|
158
|
+
return tecutil.Index(_tecutil.ZoneGetNumByUniqueID(self.uid) - 1)
|
|
159
|
+
|
|
160
|
+
@property
|
|
161
|
+
def strand(self):
|
|
162
|
+
"""`int`: The strand ID number.
|
|
163
|
+
|
|
164
|
+
Example usage::
|
|
165
|
+
|
|
166
|
+
>>> dataset.zone('My Zone').strand = 2
|
|
167
|
+
|
|
168
|
+
.. note:: **Possible side-effect when connected to Tecplot 360.**
|
|
169
|
+
|
|
170
|
+
Changing the solution times in the dataset or modifying the
|
|
171
|
+
active fieldmaps in a frame may trigger a change in the active
|
|
172
|
+
plot's solution time by the Tecplot 360 interface. This is done
|
|
173
|
+
to keep the GUI controls consistent. In batch mode, no such
|
|
174
|
+
side-effect will take place and the user must take care to set
|
|
175
|
+
the plot's solution time with the `plot.solution_time
|
|
176
|
+
<Cartesian3DFieldPlot.solution_time>` or
|
|
177
|
+
`plot.solution_timestep
|
|
178
|
+
<Cartesian3DFieldPlot.solution_timestep>` properties.
|
|
179
|
+
"""
|
|
180
|
+
return _tecutil.ZoneGetStrandIDByDataSetID(self.dataset.uid,
|
|
181
|
+
self.index + 1)
|
|
182
|
+
|
|
183
|
+
@strand.setter
|
|
184
|
+
@tecutil.lock()
|
|
185
|
+
def strand(self, value):
|
|
186
|
+
if __debug__:
|
|
187
|
+
if not isinstance(value, int):
|
|
188
|
+
raise TecplotTypeError('strand must be an integer.')
|
|
189
|
+
_tecutil.ZoneSetStrandIDByDataSetID(self.dataset.uid,
|
|
190
|
+
self.index + 1, int(value))
|
|
191
|
+
|
|
192
|
+
@property
|
|
193
|
+
def solution_time(self):
|
|
194
|
+
"""`float`: The solution time for this zone.
|
|
195
|
+
|
|
196
|
+
Example usage::
|
|
197
|
+
|
|
198
|
+
>>> dataset.zone('My Zone').solution_time = 3.14
|
|
199
|
+
|
|
200
|
+
.. note:: **Possible side-effect when connected to Tecplot 360.**
|
|
201
|
+
|
|
202
|
+
Changing the solution times in the dataset or modifying the
|
|
203
|
+
active fieldmaps in a frame may trigger a change in the active
|
|
204
|
+
plot's solution time by the Tecplot 360 interface. This is done
|
|
205
|
+
to keep the GUI controls consistent. In batch mode, no such
|
|
206
|
+
side-effect will take place and the user must take care to set
|
|
207
|
+
the plot's solution time with the `plot.solution_time
|
|
208
|
+
<Cartesian3DFieldPlot.solution_time>` or
|
|
209
|
+
`plot.solution_timestep
|
|
210
|
+
<Cartesian3DFieldPlot.solution_timestep>` properties.
|
|
211
|
+
"""
|
|
212
|
+
return _tecutil.ZoneGetSolutionTime(self.index + 1)
|
|
213
|
+
|
|
214
|
+
@solution_time.setter
|
|
215
|
+
@tecutil.lock()
|
|
216
|
+
def solution_time(self, value):
|
|
217
|
+
with self.dataset.frame.activated():
|
|
218
|
+
_tecutil.ZoneSetSolutionTime(self.index + 1, float(value))
|
|
219
|
+
|
|
220
|
+
@property
|
|
221
|
+
def zone_type(self):
|
|
222
|
+
return _tecutil.ZoneGetTypeByDataSetID(self.dataset.uid, self.index + 1)
|
|
223
|
+
|
|
224
|
+
@property
|
|
225
|
+
def name(self):
|
|
226
|
+
"""`str`: The name of the zone.
|
|
227
|
+
|
|
228
|
+
.. warning:: **Newlines in string identifiers may affect performance.**
|
|
229
|
+
|
|
230
|
+
When iterating over many items by name, such as must be done when
|
|
231
|
+
fetching an item via pattern matching, PyTecplot will optimize the
|
|
232
|
+
search only if there are no newline characters in the searched
|
|
233
|
+
items. Iterating over strings that contain newlines will be slower
|
|
234
|
+
and therefore, it is best to avoid using newlines in string
|
|
235
|
+
identifiers or names of objects such as `Zones <data_access>` or
|
|
236
|
+
`Variables <Variable>`.
|
|
237
|
+
|
|
238
|
+
Example usage::
|
|
239
|
+
|
|
240
|
+
>>> dataset.zone(0).name = 'Zone 0'
|
|
241
|
+
"""
|
|
242
|
+
res, zname = _tecutil.ZoneGetNameByDataSetID(self.dataset.uid,
|
|
243
|
+
self.index + 1)
|
|
244
|
+
if not res:
|
|
245
|
+
raise TecplotSystemError()
|
|
246
|
+
return zname
|
|
247
|
+
|
|
248
|
+
@name.setter
|
|
249
|
+
@tecutil.lock()
|
|
250
|
+
def name(self, name):
|
|
251
|
+
_tecutil.ZoneRenameByDataSetID(self.dataset.uid, self.index + 1, name)
|
|
252
|
+
|
|
253
|
+
@property
|
|
254
|
+
def num_variables(self):
|
|
255
|
+
"""`int`: Number of `Variables <Variable>` in the parent `Dataset <tecplot.data.Dataset>`.
|
|
256
|
+
|
|
257
|
+
Example usage, iterating over all variables by index::
|
|
258
|
+
|
|
259
|
+
>>> for i in range(dataset.num_variables):
|
|
260
|
+
... variable = dataset.variable(i)
|
|
261
|
+
"""
|
|
262
|
+
return self.dataset.num_variables
|
|
263
|
+
|
|
264
|
+
def values(self, pattern):
|
|
265
|
+
"""Returns an `Array` by index or string pattern.
|
|
266
|
+
|
|
267
|
+
Parameters:
|
|
268
|
+
pattern (`int`, `str` or `Variable`): Zero-based index,
|
|
269
|
+
`glob-style pattern <fnmatch.fnmatch>` in which case, the first
|
|
270
|
+
match is returned, or a `Variable` object.
|
|
271
|
+
|
|
272
|
+
.. note:: **Data operations can make use of Numpy when installed.**
|
|
273
|
+
|
|
274
|
+
When doing large data transfers into and out of Tecplot using
|
|
275
|
+
PyTecplot, it is recommended to install the Python array-processing
|
|
276
|
+
module `Numpy <https://scipy.org>`_. PyTecplot will automatically
|
|
277
|
+
use this to optimize data transfers which may result in significant
|
|
278
|
+
performance gains.
|
|
279
|
+
|
|
280
|
+
The `Variable.name` attribute is used to match the *pattern* to the
|
|
281
|
+
desired `Array` though this is not necessarily unique::
|
|
282
|
+
|
|
283
|
+
>>> ds = frame.dataset
|
|
284
|
+
>>> print(ds)
|
|
285
|
+
Dataset:
|
|
286
|
+
Zones: ['Rectangular zone']
|
|
287
|
+
Variables: ['x', 'y', 'z']
|
|
288
|
+
>>> zone = ds.zone('Rectangular zone')
|
|
289
|
+
>>> x = zone.values('x')
|
|
290
|
+
>>> x == zone.values(0)
|
|
291
|
+
True
|
|
292
|
+
|
|
293
|
+
.. warning:: **Zone and variable ordering may change between releases**
|
|
294
|
+
|
|
295
|
+
Due to possible changes in data loaders or data formats over time,
|
|
296
|
+
the ordering of zones and variables may be different between
|
|
297
|
+
versions of Tecplot 360. Therefore it is recommended to always
|
|
298
|
+
reference zones and variables **by name** instead of by index.
|
|
299
|
+
"""
|
|
300
|
+
if isinstance(pattern, (str, int)):
|
|
301
|
+
variable = self.dataset.variable(pattern)
|
|
302
|
+
else:
|
|
303
|
+
variable = pattern
|
|
304
|
+
return array.Array(self, variable)
|
|
305
|
+
|
|
306
|
+
def copy(self, share_variables=False):
|
|
307
|
+
"""Duplicate this `Zone <data_access>` in the parent `Dataset <tecplot.data.Dataset>`.
|
|
308
|
+
|
|
309
|
+
The name is also copied but can be changed after duplication.
|
|
310
|
+
|
|
311
|
+
Parameters:
|
|
312
|
+
share_variables (`bool` or `list` of `Variables <Variable>`):
|
|
313
|
+
Share all variables between the original and generated zones if
|
|
314
|
+
`True` or the list of Variables to be shared. Variable sharing
|
|
315
|
+
allows you to lower the use of physical memory (RAM). When
|
|
316
|
+
sharing a variable the memory used by the source zone is shared
|
|
317
|
+
with the copied zone. Alterations to the variable in one zone
|
|
318
|
+
will affect the other. See also `Dataset.branch_variables()`.
|
|
319
|
+
Default: `False`.
|
|
320
|
+
|
|
321
|
+
Returns:
|
|
322
|
+
`Zone <data_access>`: The newly created zone.
|
|
323
|
+
|
|
324
|
+
Example::
|
|
325
|
+
|
|
326
|
+
>>> new_zone = dataset.zone('My Zone').copy()
|
|
327
|
+
>>> print(new_zone.name)
|
|
328
|
+
My Zone
|
|
329
|
+
>>> new_zone.name = 'My Zone Copy'
|
|
330
|
+
>>> print(new_zone.name)
|
|
331
|
+
My Zone Copy
|
|
332
|
+
"""
|
|
333
|
+
return self.dataset.copy_zones(self, share_variables=share_variables)[0]
|
|
334
|
+
|
|
335
|
+
def mirror(self, mirror_variables):
|
|
336
|
+
"""Mirror this `Zone <data_access>`.
|
|
337
|
+
|
|
338
|
+
The name of the resulting zone will be "Mirror of zone *sourcezone*",
|
|
339
|
+
where *sourcezone* is the number of the zone from which the mirrored
|
|
340
|
+
zone was created. The variables in the newly created zones are shared
|
|
341
|
+
with their corresponding source zones, except for variables to be
|
|
342
|
+
mirrored as specified.
|
|
343
|
+
|
|
344
|
+
Parameters:
|
|
345
|
+
mirror_variables (`Variable` or `list` of `Variables <Variable>`):
|
|
346
|
+
Variables in the new zone to be multiplied by :math:`-1` after
|
|
347
|
+
the zone is copied. the variables may be `Variable` objects,
|
|
348
|
+
`str` names or `int` indices.
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
A zone of the same type as the source.
|
|
352
|
+
|
|
353
|
+
This example show how to mirror the first zone across the xy-plane in
|
|
354
|
+
3D::
|
|
355
|
+
|
|
356
|
+
>>> mirrored_zone = dataset.zone(0).mirror('Z')
|
|
357
|
+
"""
|
|
358
|
+
return next(self.dataset.mirror_zones(mirror_variables, self))
|
|
359
|
+
|
|
360
|
+
@property
|
|
361
|
+
def _shape(self):
|
|
362
|
+
return _tecutil.ZoneGetIJKByUniqueID(self.dataset.uid, self.index + 1)
|
|
363
|
+
|
|
364
|
+
@property
|
|
365
|
+
def num_faces(self):
|
|
366
|
+
"""`int`: Number of faces in this zone.
|
|
367
|
+
|
|
368
|
+
This is the same as the number of elements times the number of faces
|
|
369
|
+
per element. Example usage::
|
|
370
|
+
|
|
371
|
+
>>> print(dataset.zone('My Zone').num_faces)
|
|
372
|
+
1048576
|
|
373
|
+
"""
|
|
374
|
+
return self.num_elements * self.num_faces_per_element
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
class OrderedZone(Zone):
|
|
378
|
+
"""An ordered ``(i, j, k)`` zone within a `Dataset <tecplot.data.Dataset>`.
|
|
379
|
+
|
|
380
|
+
Ordered zones contain nodal or cell-centered arrays where the connectivity
|
|
381
|
+
is implied by the dimensions and ordering of the data.
|
|
382
|
+
|
|
383
|
+
`Zones <data_access>` can be identified (uniquely) by the index with their
|
|
384
|
+
parent `Dataset <tecplot.data.Dataset>` or (non-uniquely) by name. In general, a `Variable` must
|
|
385
|
+
be selected to access the underlying data array. This object is used by
|
|
386
|
+
fieldmaps and linemaps to apply style to specific zones. Here we obtain the
|
|
387
|
+
fieldmap associated with the zone named 'My Zone'::
|
|
388
|
+
|
|
389
|
+
>>> fmap = plot.fieldmap(dataset.zone('My Zone'))
|
|
390
|
+
"""
|
|
391
|
+
|
|
392
|
+
@property
|
|
393
|
+
def dimensions(self):
|
|
394
|
+
"""Nodal dimensions along ``(i, j, k)``.
|
|
395
|
+
|
|
396
|
+
Returns:
|
|
397
|
+
`tuple` of `integers <int>`: ``(i, j, k)`` for ordered data.
|
|
398
|
+
|
|
399
|
+
Example usage::
|
|
400
|
+
|
|
401
|
+
>>> print(zone.dimensions)
|
|
402
|
+
(128, 128, 128)
|
|
403
|
+
"""
|
|
404
|
+
return self._shape
|
|
405
|
+
|
|
406
|
+
@property
|
|
407
|
+
def rank(self):
|
|
408
|
+
"""`int`: Number of dimensions of the data array.
|
|
409
|
+
|
|
410
|
+
This will return the number of dimensions which contain more than one
|
|
411
|
+
value::
|
|
412
|
+
|
|
413
|
+
>>> zone = dataset.zone('My Zone')
|
|
414
|
+
>>> print(zone.dimensions)
|
|
415
|
+
(10, 10, 1)
|
|
416
|
+
>>> print(zone.rank)
|
|
417
|
+
2
|
|
418
|
+
"""
|
|
419
|
+
return sum(s > 1 for s in self.dimensions)
|
|
420
|
+
|
|
421
|
+
@property
|
|
422
|
+
def num_points(self):
|
|
423
|
+
"""`int`: Total number of nodes within this zone.
|
|
424
|
+
|
|
425
|
+
This is number of nodes within the zone and is equivalent to the
|
|
426
|
+
product of the values in `OrderedZone.dimensions`. Example usage::
|
|
427
|
+
|
|
428
|
+
>>> zone = dataset.zone('My Zone')
|
|
429
|
+
>>> print(zone.dimensions)
|
|
430
|
+
(128, 128, 128)
|
|
431
|
+
>>> print(zone.num_points)
|
|
432
|
+
2097152
|
|
433
|
+
"""
|
|
434
|
+
return reduce(lambda x, y: x * y, self.dimensions, 1)
|
|
435
|
+
|
|
436
|
+
@property
|
|
437
|
+
def num_elements(self):
|
|
438
|
+
"""`int`: Number of cells in this zone.
|
|
439
|
+
|
|
440
|
+
Example usage::
|
|
441
|
+
|
|
442
|
+
>>> zone = dataset.zone('My Zone')
|
|
443
|
+
>>> print(zone.dimensions)
|
|
444
|
+
(128, 128, 128)
|
|
445
|
+
>>> print(zone.num_elements)
|
|
446
|
+
2048383
|
|
447
|
+
"""
|
|
448
|
+
reduced_shape = list(filter(lambda x: x > 1, self.dimensions))
|
|
449
|
+
return reduce(lambda x, y: x * (y - 1), reduced_shape or [1], 1)
|
|
450
|
+
|
|
451
|
+
@property
|
|
452
|
+
def num_points_per_element(self):
|
|
453
|
+
"""`int`: Points per cell for ordered zones.
|
|
454
|
+
|
|
455
|
+
For ordered zones, this is :math:`2^{d}` where :math:`d` is the number
|
|
456
|
+
of dimensions greater than one:
|
|
457
|
+
|
|
458
|
+
==== =================
|
|
459
|
+
Rank Faces Per Element
|
|
460
|
+
==== =================
|
|
461
|
+
0 0
|
|
462
|
+
1 2
|
|
463
|
+
2 4
|
|
464
|
+
3 8
|
|
465
|
+
==== =================
|
|
466
|
+
|
|
467
|
+
Example usage::
|
|
468
|
+
|
|
469
|
+
>>> zone = dataset.zone('My Zone')
|
|
470
|
+
>>> print(zone.dimensions)
|
|
471
|
+
(10, 10, 1)
|
|
472
|
+
>>> print(zone.rank)
|
|
473
|
+
2
|
|
474
|
+
>>> print(zone.num_points_per_element)
|
|
475
|
+
4
|
|
476
|
+
"""
|
|
477
|
+
ndim = self.rank
|
|
478
|
+
return 2**ndim if ndim > 0 else 0
|
|
479
|
+
|
|
480
|
+
@property
|
|
481
|
+
def num_faces_per_element(self):
|
|
482
|
+
"""`int`: Number of faces per element in this ordered zone.
|
|
483
|
+
|
|
484
|
+
This is determined by the rank of the zone:
|
|
485
|
+
|
|
486
|
+
==== =================
|
|
487
|
+
Rank Faces Per Element
|
|
488
|
+
==== =================
|
|
489
|
+
0 0
|
|
490
|
+
1 1
|
|
491
|
+
2 4
|
|
492
|
+
3 6
|
|
493
|
+
==== =================
|
|
494
|
+
|
|
495
|
+
Example usage::
|
|
496
|
+
|
|
497
|
+
>>> zone = dataset.zone('My Zone')
|
|
498
|
+
>>> print(zone.dimensions)
|
|
499
|
+
(1, 10, 10)
|
|
500
|
+
>>> print(zone.rank)
|
|
501
|
+
2
|
|
502
|
+
>>> print(zone.num_faces_per_element)
|
|
503
|
+
4
|
|
504
|
+
"""
|
|
505
|
+
_fpe = {0: 0, 1: 1, 2: 4, 3: 6}
|
|
506
|
+
return _fpe[self.rank]
|
|
507
|
+
|
|
508
|
+
@tecutil.inherited_property(Zone)
|
|
509
|
+
def zone_type(self):
|
|
510
|
+
"""`ZoneType`: The `ZoneType` indicating structure of the data contained.
|
|
511
|
+
|
|
512
|
+
The specific type of zone this object represents::
|
|
513
|
+
|
|
514
|
+
>>> print(dataset.zone(0).zone_type)
|
|
515
|
+
ZoneType.Ordered
|
|
516
|
+
"""
|
|
517
|
+
|
|
518
|
+
@property
|
|
519
|
+
def face_neighbors(self):
|
|
520
|
+
"""`FaceNeighbors`: The face neighbor list for this ordered zone.
|
|
521
|
+
|
|
522
|
+
Example usage::
|
|
523
|
+
|
|
524
|
+
>>> zone = dataset.zone(0)
|
|
525
|
+
>>> print(zone.face_neighbors.mode)
|
|
526
|
+
FaceNeighborMode.LocalOneToOne
|
|
527
|
+
"""
|
|
528
|
+
return face_neighbors.FaceNeighbors(self)
|
|
529
|
+
|
|
530
|
+
def copy(self, share_variables=False, i_range=None, j_range=None,
|
|
531
|
+
k_range=None):
|
|
532
|
+
"""Duplicate this `Zone <data_access>` in the parent `Dataset <tecplot.data.Dataset>`.
|
|
533
|
+
|
|
534
|
+
The name is also copied but can be changed after duplication.
|
|
535
|
+
|
|
536
|
+
Parameters:
|
|
537
|
+
share_variables (`bool` or `list` of `Variables <Variable>`):
|
|
538
|
+
Share all variables between the original and generated zones if
|
|
539
|
+
`True` or the list of Variables to be shared. Variable sharing
|
|
540
|
+
allows you to lower the use of physical memory (RAM). When
|
|
541
|
+
sharing a variable the memory used by the source zone is shared
|
|
542
|
+
with the copied zone. Alterations to the variable in one zone
|
|
543
|
+
will affect the other. See also `Dataset.branch_variables()`.
|
|
544
|
+
Default: `False`.
|
|
545
|
+
i_range (`tuple` of `integers <int>`, optional):
|
|
546
|
+
Range (min, max, step) along the ``i`` dimension for ordered
|
|
547
|
+
data. Min and max are zero-based indicies where max is
|
|
548
|
+
inclusive. If step causes max to be skipped, max will be
|
|
549
|
+
included. If `None` (default), the entire range will be copied.
|
|
550
|
+
j_range (`tuple` of `integers <int>`, optional):
|
|
551
|
+
Range (min, max, step) along the ``j`` dimension for ordered
|
|
552
|
+
data. Min and max are zero-based indicies where max is
|
|
553
|
+
inclusive. If step causes max to be skipped, max will be
|
|
554
|
+
included. If `None` (default), the entire range will be copied.
|
|
555
|
+
k_range (`tuple` of `integers <int>`, optional):
|
|
556
|
+
Range (min, max, step) along the ``k`` dimension for ordered
|
|
557
|
+
data. Min and max are zero-based indicies where max is
|
|
558
|
+
inclusive. If step causes max to be skipped, max will be
|
|
559
|
+
included. If `None` (default), the entire range will be copied.
|
|
560
|
+
|
|
561
|
+
Returns:
|
|
562
|
+
`Zone <data_access>`: The newly created zone.
|
|
563
|
+
|
|
564
|
+
.. code-block:: python
|
|
565
|
+
|
|
566
|
+
import tecplot as tp
|
|
567
|
+
|
|
568
|
+
ds = tp.active_page().add_frame().create_dataset('D', ['x','y','z'])
|
|
569
|
+
z = ds.add_ordered_zone('Z1', (3,3,3))
|
|
570
|
+
zcopy = z.copy(i_range=(1, -1, 2))
|
|
571
|
+
"""
|
|
572
|
+
return self.dataset.copy_zones(self, share_variables=share_variables,
|
|
573
|
+
i_range=i_range, j_range=j_range,
|
|
574
|
+
k_range=k_range)[0]
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
class FEZone(Zone):
|
|
578
|
+
@property
|
|
579
|
+
def num_points(self):
|
|
580
|
+
"""`int`: Total number of nodes within this zone.
|
|
581
|
+
|
|
582
|
+
This is the total number of nodes in the zone. Example usage::
|
|
583
|
+
|
|
584
|
+
>>> print(dataset.zone('My Zone').num_points)
|
|
585
|
+
2048
|
|
586
|
+
"""
|
|
587
|
+
return self._shape[0]
|
|
588
|
+
|
|
589
|
+
@property
|
|
590
|
+
def num_elements(self):
|
|
591
|
+
"""`int`: Number of cells in this finite-element zone.
|
|
592
|
+
|
|
593
|
+
Example usage::
|
|
594
|
+
|
|
595
|
+
>>> print(dataset.zone('My Zone').num_elements)
|
|
596
|
+
1048576
|
|
597
|
+
"""
|
|
598
|
+
return self._shape[1]
|
|
599
|
+
|
|
600
|
+
@property
|
|
601
|
+
def shared_connectivity(self):
|
|
602
|
+
"""`list` of `Zones <data_access>`: `Zones <data_access>` sharing connectivity.
|
|
603
|
+
|
|
604
|
+
Example usage::
|
|
605
|
+
|
|
606
|
+
>>> dataset.zone('My Zone').copy()
|
|
607
|
+
>>> for zone in dataset.zone('My Zone').shared_connectivity:
|
|
608
|
+
... print(zone.index)
|
|
609
|
+
0
|
|
610
|
+
1
|
|
611
|
+
"""
|
|
612
|
+
indices = _tecutil.ConnectGetShareZoneSet(self.index + 1)
|
|
613
|
+
ret = [self.dataset.zone(i) for i in indices]
|
|
614
|
+
indices.dealloc()
|
|
615
|
+
return ret
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
class ClassicFEZone(FEZone):
|
|
619
|
+
"""A classic finite-element zone within a `Dataset <tecplot.data.Dataset>`.
|
|
620
|
+
|
|
621
|
+
Classic finite-element zones are arrays of nodes that are connected
|
|
622
|
+
explicitly into pre-defined geometric shapes called "elements." The
|
|
623
|
+
geometry is consistent across the whole zone so that the number of nodes
|
|
624
|
+
per element is constant.
|
|
625
|
+
|
|
626
|
+
`Zones <data_access>` can be identified (uniquely) by the index with their
|
|
627
|
+
parent `Dataset <tecplot.data.Dataset>` or (non-uniquely) by name. In general, a `Variable` must
|
|
628
|
+
be selected to access the underlying data array. This object is used by
|
|
629
|
+
fieldmaps and linemaps to apply style to specific zones. Here we obtain the
|
|
630
|
+
fieldmap associated with the zone named 'My Zone'::
|
|
631
|
+
|
|
632
|
+
>>> fmap = plot.fieldmap(dataset.zone('My Zone'))
|
|
633
|
+
"""
|
|
634
|
+
|
|
635
|
+
@property
|
|
636
|
+
def num_points_per_element(self):
|
|
637
|
+
"""`int`: Points per element for classic finite-element zones.
|
|
638
|
+
|
|
639
|
+
The number of points (also known as nodes) per finite-element is
|
|
640
|
+
determined from the ``zone_type`` parameter. The follow table shows the
|
|
641
|
+
number of points per element for the available zone types along with
|
|
642
|
+
the resulting shape of the nodemap based on the number of points
|
|
643
|
+
specified (:math:`N`):
|
|
644
|
+
|
|
645
|
+
============== ============== ========================
|
|
646
|
+
Zone Type Points/Element Nodemap Shape
|
|
647
|
+
============== ============== ========================
|
|
648
|
+
``FELineSeg`` 2 (:math:`N`, :math:`2 N`)
|
|
649
|
+
``FETriangle`` 3 (:math:`N`, :math:`3 N`)
|
|
650
|
+
``FEQuad`` 4 (:math:`N`, :math:`4 N`)
|
|
651
|
+
``FETetra`` 4 (:math:`N`, :math:`4 N`)
|
|
652
|
+
``FEBrick`` 8 (:math:`N`, :math:`8 N`)
|
|
653
|
+
============== ============== ========================
|
|
654
|
+
|
|
655
|
+
Example usage::
|
|
656
|
+
|
|
657
|
+
>>> zone = dataset.zone('My Zone')
|
|
658
|
+
>>> print(zone.zone_type)
|
|
659
|
+
ZoneType.FETriangle
|
|
660
|
+
>>> print(zone.num_points_per_element)
|
|
661
|
+
3
|
|
662
|
+
"""
|
|
663
|
+
return self.nodemap.num_points_per_element
|
|
664
|
+
|
|
665
|
+
@property
|
|
666
|
+
def nodemap(self):
|
|
667
|
+
"""`Nodemap`: The connectivity `Nodemap` for this classic finite-element zone.
|
|
668
|
+
|
|
669
|
+
Example usage::
|
|
670
|
+
|
|
671
|
+
>>> zone = dataset.zone(0)
|
|
672
|
+
>>> print(zone.nodemap.num_points_per_element)
|
|
673
|
+
4
|
|
674
|
+
"""
|
|
675
|
+
return nodemap.Nodemap(self)
|
|
676
|
+
|
|
677
|
+
@property
|
|
678
|
+
def face_neighbors(self):
|
|
679
|
+
"""`FaceNeighbors`: The face neighbor list for this finite-element zone.
|
|
680
|
+
|
|
681
|
+
Example usage::
|
|
682
|
+
|
|
683
|
+
>>> zone = dataset.zone(0)
|
|
684
|
+
>>> print(zone.face_neighbors.mode)
|
|
685
|
+
FaceNeighborMode.LocalOneToMany
|
|
686
|
+
"""
|
|
687
|
+
return face_neighbors.FaceNeighbors(self)
|
|
688
|
+
|
|
689
|
+
@tecutil.inherited_property(Zone)
|
|
690
|
+
def zone_type(self):
|
|
691
|
+
"""`ZoneType`: The `ZoneType` indicating structure of the data contained.
|
|
692
|
+
|
|
693
|
+
The specific type of zone this object represents::
|
|
694
|
+
|
|
695
|
+
>>> print(dataset.zone(0).zone_type)
|
|
696
|
+
ZoneType.FEBrick
|
|
697
|
+
"""
|
|
698
|
+
|
|
699
|
+
@property
|
|
700
|
+
def rank(self):
|
|
701
|
+
"""`int`: Number of dimensions of the data array.
|
|
702
|
+
|
|
703
|
+
This indicates the dimensionality of the data and is dependent on the
|
|
704
|
+
type of element this zone contains:
|
|
705
|
+
|
|
706
|
+
============== ====
|
|
707
|
+
Zone Type Rank
|
|
708
|
+
============== ====
|
|
709
|
+
``FELineSeg`` 1
|
|
710
|
+
``FETriangle`` 2
|
|
711
|
+
``FEQuad`` 2
|
|
712
|
+
``FETetra`` 3
|
|
713
|
+
``FEBrick`` 3
|
|
714
|
+
============== ====
|
|
715
|
+
|
|
716
|
+
Example usage::
|
|
717
|
+
|
|
718
|
+
>>> zone = dataset.zone('My Zone')
|
|
719
|
+
>>> print(zone.zone_type)
|
|
720
|
+
ZoneType.FEBrick
|
|
721
|
+
>>> print(zone.rank)
|
|
722
|
+
3
|
|
723
|
+
"""
|
|
724
|
+
_rank = {ZoneType.FELineSeg: 1,
|
|
725
|
+
ZoneType.FETriangle: 2,
|
|
726
|
+
ZoneType.FEQuad: 2,
|
|
727
|
+
ZoneType.FETetra: 3,
|
|
728
|
+
ZoneType.FEBrick: 3}
|
|
729
|
+
return _rank[self.zone_type]
|
|
730
|
+
|
|
731
|
+
@property
|
|
732
|
+
def num_faces_per_element(self):
|
|
733
|
+
"""`int`: Number of faces per element.
|
|
734
|
+
|
|
735
|
+
This is dependent on the type of element this zone contains:
|
|
736
|
+
|
|
737
|
+
============== =================
|
|
738
|
+
Zone Type Faces Per Element
|
|
739
|
+
============== =================
|
|
740
|
+
``FELineSeg`` 1
|
|
741
|
+
``FETriangle`` 3
|
|
742
|
+
``FEQuad`` 4
|
|
743
|
+
``FETetra`` 4
|
|
744
|
+
``FEBrick`` 6
|
|
745
|
+
============== =================
|
|
746
|
+
|
|
747
|
+
Example usage::
|
|
748
|
+
|
|
749
|
+
>>> print(dataset.zone('My Zone').num_faces_per_element)
|
|
750
|
+
4
|
|
751
|
+
"""
|
|
752
|
+
_fpe = {ZoneType.FELineSeg: 1,
|
|
753
|
+
ZoneType.FETriangle: 3,
|
|
754
|
+
ZoneType.FEQuad: 4,
|
|
755
|
+
ZoneType.FETetra: 4,
|
|
756
|
+
ZoneType.FEBrick: 6}
|
|
757
|
+
return _fpe[self.zone_type]
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
class PolyFEZone(FEZone):
|
|
761
|
+
"""A polygonal finite-element zone within a `Dataset <tecplot.data.Dataset>`.
|
|
762
|
+
|
|
763
|
+
A polygonal zone consists of arrays of nodes which are connected explicitly
|
|
764
|
+
into arbitrary and varying geometric elements. These elements are 2D or 3D
|
|
765
|
+
in nature and have a number of faces (connections between nodes) which hold
|
|
766
|
+
the concept of a left and right neighbor.
|
|
767
|
+
|
|
768
|
+
`Zones <data_access>` can be identified (uniquely) by the index with their
|
|
769
|
+
parent `Dataset <tecplot.data.Dataset>` or (non-uniquely) by name. In general, a `Variable` must
|
|
770
|
+
be selected to access the underlying data array. This object is used by
|
|
771
|
+
fieldmaps and linemaps to apply style to specific zones. Here we obtain the
|
|
772
|
+
fieldmap associated with the zone named 'My Zone'::
|
|
773
|
+
|
|
774
|
+
>>> fmap = plot.fieldmap(dataset.zone('My Zone'))
|
|
775
|
+
"""
|
|
776
|
+
|
|
777
|
+
@property
|
|
778
|
+
@tecutil.lock()
|
|
779
|
+
def num_faces(self):
|
|
780
|
+
"""`int`: Number of faces in this finite-element zone.
|
|
781
|
+
|
|
782
|
+
The number of faces may be ``0`` if unknown or facemap creation is
|
|
783
|
+
deferred. Example usage::
|
|
784
|
+
|
|
785
|
+
>>> print(dataset.zone('My Zone').num_faces)
|
|
786
|
+
1048576
|
|
787
|
+
"""
|
|
788
|
+
try:
|
|
789
|
+
with self.dataset.frame.activated():
|
|
790
|
+
_ = _tecutil.DataFaceMapGetReadableRef(self.index + 1)
|
|
791
|
+
except TecplotLogicError:
|
|
792
|
+
return 0
|
|
793
|
+
return self._shape[2]
|
|
794
|
+
|
|
795
|
+
@property
|
|
796
|
+
def rank(self):
|
|
797
|
+
"""`int`: Number of dimensions of the data array.
|
|
798
|
+
|
|
799
|
+
This indicates the dimensionality of the data and is dependent on the
|
|
800
|
+
type of element this zone contains:
|
|
801
|
+
|
|
802
|
+
================ ====
|
|
803
|
+
Zone Type Rank
|
|
804
|
+
================ ====
|
|
805
|
+
``FEPolygon`` 2
|
|
806
|
+
``FEPolyhedron`` 3
|
|
807
|
+
================ ====
|
|
808
|
+
|
|
809
|
+
Example usage::
|
|
810
|
+
|
|
811
|
+
>>> zone = dataset.zone('My Zone')
|
|
812
|
+
>>> print(zone.zone_type)
|
|
813
|
+
ZoneType.FEPolygon
|
|
814
|
+
>>> print(zone.rank)
|
|
815
|
+
2
|
|
816
|
+
"""
|
|
817
|
+
_rank = {ZoneType.FEPolygon: 2,
|
|
818
|
+
ZoneType.FEPolyhedron: 3}
|
|
819
|
+
return _rank[self.zone_type]
|
|
820
|
+
|
|
821
|
+
@property
|
|
822
|
+
def facemap(self):
|
|
823
|
+
"""`Facemap`: The connectivity `Facemap` for this polygonal finite-element zone.
|
|
824
|
+
|
|
825
|
+
Example usage::
|
|
826
|
+
|
|
827
|
+
>>> zone = dataset.zone(0)
|
|
828
|
+
>>> print(zone.facemap.num_faces)
|
|
829
|
+
4500
|
|
830
|
+
"""
|
|
831
|
+
return facemap.Facemap(self)
|
|
832
|
+
|
|
833
|
+
@tecutil.inherited_property(Zone)
|
|
834
|
+
def zone_type(self):
|
|
835
|
+
"""`ZoneType`: The `ZoneType` indicating structure of the data contained.
|
|
836
|
+
|
|
837
|
+
The specific type of zone this object represents::
|
|
838
|
+
|
|
839
|
+
>>> print(dataset.zone(0).zone_type)
|
|
840
|
+
ZoneType.FEPolygon
|
|
841
|
+
"""
|