tecio-python 0.2.1__py3-none-any.whl → 0.2.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.
- tecio/_containers.py +2 -2
- tecio/_io.py +46 -38
- tecio/_meta.py +4 -4
- tecio/cli/__init__.py +3 -3
- tecio/cli/tec2mat.py +21 -21
- tecio/cli/tecaux.py +322 -51
- tecio/cli/tecdump.py +4 -4
- tecio/cli/tecextract.py +6 -6
- tecio/cli/tecfix.py +4 -4
- tecio/cli/tecmerge.py +12 -12
- tecio/cli/teconvert.py +3 -3
- tecio/cli/tecscale.py +7 -7
- tecio/cli/tecslice.py +12 -12
- tecio/cli/tecstats.py +4 -4
- tecio/dat/__init__.py +1 -1
- tecio/dat/_read.py +17 -17
- tecio/dat/_write.py +22 -22
- tecio/libtecio.py +1 -1
- tecio/plt/_read.py +21 -21
- tecio/plt/_write.py +35 -35
- tecio/szl/_read.py +3 -3
- tecio/szl/_write.py +28 -28
- {tecio_python-0.2.1.dist-info → tecio_python-0.2.2.dist-info}/METADATA +1 -1
- tecio_python-0.2.2.dist-info/RECORD +33 -0
- {tecio_python-0.2.1.dist-info → tecio_python-0.2.2.dist-info}/licenses/NOTICE +2 -2
- tecio_python-0.2.1.dist-info/RECORD +0 -33
- {tecio_python-0.2.1.dist-info → tecio_python-0.2.2.dist-info}/WHEEL +0 -0
- {tecio_python-0.2.1.dist-info → tecio_python-0.2.2.dist-info}/entry_points.txt +0 -0
- {tecio_python-0.2.1.dist-info → tecio_python-0.2.2.dist-info}/licenses/LICENSE +0 -0
- {tecio_python-0.2.1.dist-info → tecio_python-0.2.2.dist-info}/top_level.txt +0 -0
tecio/cli/tecmerge.py
CHANGED
|
@@ -3,8 +3,8 @@ r"""Merge zones from multiple Tecplot data files into a single output file.
|
|
|
3
3
|
Post-processing workflows commonly produce results distributed across multiple files.
|
|
4
4
|
``tecmerge`` collects all zones from an arbitrary number of input files into a single
|
|
5
5
|
output, reconciling variable lists across sources by taking their union and writing any
|
|
6
|
-
variable absent from a given source as passive.
|
|
7
|
-
or via a quoted glob pattern and may be any mix of supported formats.
|
|
6
|
+
variable absent from a given source as passive. Input files may be specified explicitly
|
|
7
|
+
or via a quoted glob pattern and may be any mix of supported formats. When merging
|
|
8
8
|
time-step sequences, solution times and strand IDs can be assigned automatically from a
|
|
9
9
|
start time and either a fixed interval or an end time.
|
|
10
10
|
|
|
@@ -44,7 +44,7 @@ start time and either a fixed interval or an end time.
|
|
|
44
44
|
Solution time of the first input file. Used with ``--assign-time-strands``.
|
|
45
45
|
|
|
46
46
|
``-delta VALUE``
|
|
47
|
-
Constant time increment between successive input files.
|
|
47
|
+
Constant time increment between successive input files. Mutually exclusive with
|
|
48
48
|
``-end``.
|
|
49
49
|
|
|
50
50
|
``-end VALUE``
|
|
@@ -136,8 +136,8 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
136
136
|
nargs="+",
|
|
137
137
|
metavar="FILE",
|
|
138
138
|
help=(
|
|
139
|
-
"Input Tecplot files.
|
|
140
|
-
"pattern to prevent shell expansion).
|
|
139
|
+
"Input Tecplot files. Glob patterns are expanded (quote the "
|
|
140
|
+
"pattern to prevent shell expansion). Files are merged in the "
|
|
141
141
|
"order given / matched."
|
|
142
142
|
),
|
|
143
143
|
)
|
|
@@ -150,7 +150,7 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
150
150
|
required=True,
|
|
151
151
|
metavar="PATH",
|
|
152
152
|
help=(
|
|
153
|
-
"Output file path.
|
|
153
|
+
"Output file path. The extension controls the output format "
|
|
154
154
|
"(.szplt, .plt, .dat)."
|
|
155
155
|
),
|
|
156
156
|
)
|
|
@@ -166,7 +166,7 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
166
166
|
default=None,
|
|
167
167
|
metavar="STRING",
|
|
168
168
|
help=(
|
|
169
|
-
"Dataset title for the output file.
|
|
169
|
+
"Dataset title for the output file. Defaults to the title of "
|
|
170
170
|
"the first input file."
|
|
171
171
|
),
|
|
172
172
|
)
|
|
@@ -180,7 +180,7 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
180
180
|
dest="assign_ts",
|
|
181
181
|
help=(
|
|
182
182
|
"Assign evenly-spaced solution times and a strand ID to all "
|
|
183
|
-
"zones.
|
|
183
|
+
"zones. Each input file corresponds to one time step. "
|
|
184
184
|
"Requires -start and one of -delta or -end."
|
|
185
185
|
),
|
|
186
186
|
)
|
|
@@ -192,7 +192,7 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
192
192
|
help="Solution time of the first input file.",
|
|
193
193
|
)
|
|
194
194
|
# -delta and -end are mutually exclusive -- either specifies the spacing,
|
|
195
|
-
# the other specifies the endpoint.
|
|
195
|
+
# the other specifies the endpoint. Providing both over-constrains the
|
|
196
196
|
# problem and is therefore disallowed at the parser level.
|
|
197
197
|
step_group = ts.add_mutually_exclusive_group()
|
|
198
198
|
step_group.add_argument(
|
|
@@ -208,7 +208,7 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
208
208
|
default=None,
|
|
209
209
|
metavar="VALUE",
|
|
210
210
|
help=(
|
|
211
|
-
"Solution time of the last input file.
|
|
211
|
+
"Solution time of the last input file. The step is computed as "
|
|
212
212
|
"(end - start) / (N - 1) where N is the number of input files."
|
|
213
213
|
),
|
|
214
214
|
)
|
|
@@ -217,7 +217,7 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
217
217
|
type=int,
|
|
218
218
|
default=1,
|
|
219
219
|
metavar="ID",
|
|
220
|
-
help="Strand ID to assign to all zones.
|
|
220
|
+
help="Strand ID to assign to all zones. Default: 1.",
|
|
221
221
|
)
|
|
222
222
|
|
|
223
223
|
return parser.parse_args(argv)
|
|
@@ -310,7 +310,7 @@ def _write_zone(
|
|
|
310
310
|
) -> None:
|
|
311
311
|
"""Write one zone to *writer* using the reconciled variable list.
|
|
312
312
|
|
|
313
|
-
Variables present in *zone* are copied verbatim.
|
|
313
|
+
Variables present in *zone* are copied verbatim. Variables absent from
|
|
314
314
|
*zone* (``None`` entries in *local_index_map*) are written as passive.
|
|
315
315
|
|
|
316
316
|
Args:
|
tecio/cli/teconvert.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
r"""Convert between Tecplot data file formats.
|
|
2
2
|
|
|
3
3
|
The three Tecplot file formats, SZL binary (``.szplt``), PLT binary (``.plt``), and
|
|
4
|
-
ASCII DAT (``.dat``), are not always interchangeable in practice.
|
|
4
|
+
ASCII DAT (``.dat``), are not always interchangeable in practice. Tecplot itself
|
|
5
5
|
stores all data internally in binary form and provides license-free command-line
|
|
6
6
|
utilities (``preplot``, ``tec360 -convert``) for converting from lower-level formats
|
|
7
7
|
upward to SZL, but no supported path exists for the reverse without a active license.
|
|
@@ -182,7 +182,7 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
182
182
|
default=None,
|
|
183
183
|
metavar="PATH",
|
|
184
184
|
help=(
|
|
185
|
-
"Explicit output file path.
|
|
185
|
+
"Explicit output file path. Defaults to the input file stem with "
|
|
186
186
|
"the new extension in the same directory as the input."
|
|
187
187
|
),
|
|
188
188
|
)
|
|
@@ -198,7 +198,7 @@ def _copy_zones(reader: Any, writer: Any) -> None:
|
|
|
198
198
|
"""Stream all zones from *reader* into the open *writer*.
|
|
199
199
|
|
|
200
200
|
Each zone is reproduced at its original data type and value location.
|
|
201
|
-
Connectivity (node maps) is copied verbatim for FE zones.
|
|
201
|
+
Connectivity (node maps) is copied verbatim for FE zones. Zone-level
|
|
202
202
|
auxiliary data is forwarded as well.
|
|
203
203
|
|
|
204
204
|
Args:
|
tecio/cli/tecscale.py
CHANGED
|
@@ -3,7 +3,7 @@ r"""Scale and/or offset variable arrays in a Tecplot data file.
|
|
|
3
3
|
CFD solvers and experimental data sources frequently produce output in differing unit
|
|
4
4
|
systems, and converting between them (e.g.pressure in Pa to kPa, temperature in Kelvin
|
|
5
5
|
to Celsius or lengths in meters to feet) is a routine step before visualisation or
|
|
6
|
-
comparison.
|
|
6
|
+
comparison. Performing these transformations would otherwise require loading the file
|
|
7
7
|
in Tecplot or writing a dedicated script. ``tecscale`` applies the linear transformation
|
|
8
8
|
|
|
9
9
|
.. math::
|
|
@@ -11,7 +11,7 @@ in Tecplot or writing a dedicated script. ``tecscale`` applies the linear transf
|
|
|
11
11
|
v' = v \cdot s + b
|
|
12
12
|
|
|
13
13
|
to every value in a selected variable array, where :math:`s` is the scale factor and
|
|
14
|
-
:math:`b` is the additive offset.
|
|
14
|
+
:math:`b` is the additive offset. The transformation can be restricted to a single zone
|
|
15
15
|
and the output format is controlled by the output file extension, allowing unit
|
|
16
16
|
conversion and format conversion to be performed in a single step.
|
|
17
17
|
|
|
@@ -144,14 +144,14 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
144
144
|
type=float,
|
|
145
145
|
default=1.0,
|
|
146
146
|
metavar="FLOAT",
|
|
147
|
-
help="Multiplicative scale factor.
|
|
147
|
+
help="Multiplicative scale factor. Default: 1.0.",
|
|
148
148
|
)
|
|
149
149
|
parser.add_argument(
|
|
150
150
|
"-offset",
|
|
151
151
|
type=float,
|
|
152
152
|
default=0.0,
|
|
153
153
|
metavar="FLOAT",
|
|
154
|
-
help="Additive offset applied after scaling.
|
|
154
|
+
help="Additive offset applied after scaling. Default: 0.0.",
|
|
155
155
|
)
|
|
156
156
|
parser.add_argument(
|
|
157
157
|
"-zone",
|
|
@@ -159,7 +159,7 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
159
159
|
default=None,
|
|
160
160
|
metavar="INDEX",
|
|
161
161
|
help=(
|
|
162
|
-
"1-based zone index to apply the transformation to.
|
|
162
|
+
"1-based zone index to apply the transformation to. Default is all zones."
|
|
163
163
|
),
|
|
164
164
|
)
|
|
165
165
|
parser.add_argument(
|
|
@@ -169,7 +169,7 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
169
169
|
default=None,
|
|
170
170
|
metavar="PATH",
|
|
171
171
|
help=(
|
|
172
|
-
"Output file path.
|
|
172
|
+
"Output file path. The extension controls the output format. "
|
|
173
173
|
"Defaults to <stem>_scaled<ext> in the same directory."
|
|
174
174
|
),
|
|
175
175
|
)
|
|
@@ -225,7 +225,7 @@ def _resolve_variable(spec: str, var_names: list[str]) -> int | None:
|
|
|
225
225
|
return i
|
|
226
226
|
|
|
227
227
|
print(
|
|
228
|
-
f"Error: variable '{spec}' not found.
|
|
228
|
+
f"Error: variable '{spec}' not found. Available: {var_names}",
|
|
229
229
|
file=sys.stderr,
|
|
230
230
|
)
|
|
231
231
|
return None
|
tecio/cli/tecslice.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
r"""Slice a Tecplot data file along IJK indices and/or solution time.
|
|
2
2
|
|
|
3
3
|
Structured CFD datasets frequently contain more spatial resolution or time steps than
|
|
4
|
-
are necessary for a given analysis.
|
|
4
|
+
are necessary for a given analysis. Reducing the data to a relevant subset (like every
|
|
5
5
|
other grid point, a specific index range along one axis, or a window of solution times)
|
|
6
6
|
would otherwise require loading the full file in Tecplot or writing a dedicated script.
|
|
7
7
|
``tecslice`` applies these reductions directly to the file using a compact
|
|
@@ -212,7 +212,7 @@ def _parse_ijk_slice(value: str) -> IjkSliceSpec:
|
|
|
212
212
|
)
|
|
213
213
|
except ValueError as exc:
|
|
214
214
|
raise argparse.ArgumentTypeError(
|
|
215
|
-
f"Invalid IJK slice {value!r}: {exc}.
|
|
215
|
+
f"Invalid IJK slice {value!r}: {exc}. All components must be integers."
|
|
216
216
|
) from exc
|
|
217
217
|
|
|
218
218
|
|
|
@@ -313,7 +313,7 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
313
313
|
required=True,
|
|
314
314
|
metavar="PATH",
|
|
315
315
|
help=(
|
|
316
|
-
"Output file path.
|
|
316
|
+
"Output file path. The extension controls the output format "
|
|
317
317
|
"(.szplt, .plt, .dat)."
|
|
318
318
|
),
|
|
319
319
|
)
|
|
@@ -408,10 +408,10 @@ def _ijk_spec_to_slice(spec: IjkSliceSpec | None) -> slice:
|
|
|
408
408
|
# 1-based inclusive end -> Python exclusive stop.
|
|
409
409
|
#
|
|
410
410
|
# Positive step: 1-based end N -> py_stop N.
|
|
411
|
-
# arr[:N] (0-based) gives elements 0..N-1 = 1-based 1..N.
|
|
411
|
+
# arr[:N] (0-based) gives elements 0..N-1 = 1-based 1..N. Correct.
|
|
412
412
|
#
|
|
413
413
|
# Negative step: 1-based end N -> py_stop N-1.
|
|
414
|
-
# arr[s:N-1:-1] includes 0-based index N-1 = 1-based N.
|
|
414
|
+
# arr[s:N-1:-1] includes 0-based index N-1 = 1-based N. Correct.
|
|
415
415
|
# Special case: 1-based end=1 -> 0-based index 0 -> py_stop=None
|
|
416
416
|
# (arr[s:0:-1] would miss index 0; arr[s:None:-1] includes it).
|
|
417
417
|
if spec.end is not None:
|
|
@@ -445,7 +445,7 @@ def _build_time_filter(
|
|
|
445
445
|
) -> set[int]:
|
|
446
446
|
"""Return the set of 0-based zone indices to include in the output.
|
|
447
447
|
|
|
448
|
-
Zones with strand ID == 0 are always included.
|
|
448
|
+
Zones with strand ID == 0 are always included. For each eligible
|
|
449
449
|
strand the zones are sorted by solution time, the ``[start, end]``
|
|
450
450
|
window is applied (inclusive), then the ``skip`` stride is applied to
|
|
451
451
|
the windowed list.
|
|
@@ -514,7 +514,7 @@ def _build_protected_set(
|
|
|
514
514
|
|
|
515
515
|
A zone is "protected" if it is excluded by the time filter but is
|
|
516
516
|
referenced as a variable-sharing source by at least one zone that will
|
|
517
|
-
be written.
|
|
517
|
+
be written. Protected zones are written with all non-shared variables
|
|
518
518
|
set passive and their strand ID forced to 0 so they act as inert grid
|
|
519
519
|
anchors without contributing to the time series.
|
|
520
520
|
|
|
@@ -554,7 +554,7 @@ def _collect_zone_arrays(
|
|
|
554
554
|
|
|
555
555
|
Returns:
|
|
556
556
|
``(data, locs, passive_vars, var_sharing)`` where each list has
|
|
557
|
-
length ``num_vars``.
|
|
557
|
+
length ``num_vars``. Passive and shared entries have empty arrays.
|
|
558
558
|
|
|
559
559
|
"""
|
|
560
560
|
data: list[np.ndarray] = []
|
|
@@ -653,9 +653,9 @@ def _write_zone_protected(
|
|
|
653
653
|
"""Write a zone as a protected grid anchor.
|
|
654
654
|
|
|
655
655
|
All variables that are not already passive or shared are set passive so
|
|
656
|
-
that no solution data is carried into the output.
|
|
656
|
+
that no solution data is carried into the output. The strand ID is
|
|
657
657
|
forced to 0 so the zone is treated as stationary and does not appear in
|
|
658
|
-
any time-series animation.
|
|
658
|
+
any time-series animation. Sharing references are preserved verbatim so
|
|
659
659
|
that zones which share coordinates from this zone continue to work.
|
|
660
660
|
|
|
661
661
|
Args:
|
|
@@ -754,7 +754,7 @@ def _slice_and_write_ordered(
|
|
|
754
754
|
|
|
755
755
|
if var.value_location == ValueLocation.CELL_CENTERED:
|
|
756
756
|
# Cell array has shape (I-1, J-1, K-1).
|
|
757
|
-
# Cell c sits between nodes c and c+1.
|
|
757
|
+
# Cell c sits between nodes c and c+1. For a nodal selection
|
|
758
758
|
# with stride s, the fully-bounded cells are exactly the
|
|
759
759
|
# lower-node indices of each consecutive selected-node pair:
|
|
760
760
|
# positive step -> selected_nodes[:-1] (each is the lower node)
|
|
@@ -837,7 +837,7 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|
|
837
837
|
|
|
838
838
|
if not do_ijk and not do_time:
|
|
839
839
|
print(
|
|
840
|
-
"Warning: no slice flags provided.
|
|
840
|
+
"Warning: no slice flags provided. Output will be a verbatim copy.",
|
|
841
841
|
file=sys.stderr,
|
|
842
842
|
)
|
|
843
843
|
|
tecio/cli/tecstats.py
CHANGED
|
@@ -26,7 +26,7 @@ corrective operation.
|
|
|
26
26
|
are reported.
|
|
27
27
|
|
|
28
28
|
``-variable INDEX``
|
|
29
|
-
Restrict output to the variable at the given one-based index.
|
|
29
|
+
Restrict output to the variable at the given one-based index. If omitted, all
|
|
30
30
|
variables are reported.
|
|
31
31
|
|
|
32
32
|
``-csv``
|
|
@@ -154,14 +154,14 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
154
154
|
type=int,
|
|
155
155
|
default=None,
|
|
156
156
|
metavar="INDEX",
|
|
157
|
-
help="1-based zone index to report.
|
|
157
|
+
help="1-based zone index to report. Default is all zones.",
|
|
158
158
|
)
|
|
159
159
|
parser.add_argument(
|
|
160
160
|
"-variable",
|
|
161
161
|
type=int,
|
|
162
162
|
default=None,
|
|
163
163
|
metavar="INDEX",
|
|
164
|
-
help="1-based variable index to report.
|
|
164
|
+
help="1-based variable index to report. Default is all variables.",
|
|
165
165
|
)
|
|
166
166
|
parser.add_argument(
|
|
167
167
|
"-csv",
|
|
@@ -169,7 +169,7 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
|
|
|
169
169
|
default=False,
|
|
170
170
|
dest="write_csv",
|
|
171
171
|
help=(
|
|
172
|
-
"Write statistics to a CSV file.
|
|
172
|
+
"Write statistics to a CSV file. The filename is derived "
|
|
173
173
|
"automatically from the input file stem with a _stats suffix "
|
|
174
174
|
"always appended, preceded by optional _zone_N and _var_N "
|
|
175
175
|
"segments when -zone or -variable are active "
|
tecio/dat/__init__.py
CHANGED
|
@@ -6,7 +6,7 @@ files, but are useful for small datasets, debugging, and interoperability
|
|
|
6
6
|
with other tools.
|
|
7
7
|
|
|
8
8
|
This module provides :class:`Read` for parsing and :class:`Write` for
|
|
9
|
-
producing Tecplot 360 ASCII data files (``.dat`` / ``.tec``).
|
|
9
|
+
producing Tecplot 360 ASCII data files (``.dat`` / ``.tec``). Both
|
|
10
10
|
classes mirror the interfaces of :class:`szl.Read` / :class:`szl.Write`
|
|
11
11
|
and :class:`plt.Read` / :class:`plt.Write` so that downstream code can
|
|
12
12
|
switch between file formats by changing only the file extension passed to
|
tecio/dat/_read.py
CHANGED
|
@@ -3,7 +3,7 @@ r"""Tecplot ASCII DAT file reader API.
|
|
|
3
3
|
Supported ``DATAPACKING`` modes:
|
|
4
4
|
* ``BLOCK`` — one contiguous value block per variable (Tecplot default).
|
|
5
5
|
* ``POINT`` — one row of all variable values per node, followed by a separate
|
|
6
|
-
row-per-cell section for any cell-centred variables.
|
|
6
|
+
row-per-cell section for any cell-centred variables. This is the format most
|
|
7
7
|
commonly produced by third-party exporters and tools that treat the file like a
|
|
8
8
|
CSV with a header.
|
|
9
9
|
"""
|
|
@@ -213,9 +213,9 @@ def _next_token_is_value(text: str, i: int) -> bool:
|
|
|
213
213
|
"""Return ``True`` if the token at *i* is a value, not the next key.
|
|
214
214
|
|
|
215
215
|
Supports the legacy whitespace-separated ``KEY VALUE`` form in zone headers
|
|
216
|
-
(e.g. ``STRANDID 2``).
|
|
216
|
+
(e.g. ``STRANDID 2``). A token is treated as the *next key* — and therefore not a
|
|
217
217
|
value for the preceding key — when it is immediately followed (after optional
|
|
218
|
-
whitespace) by ``=``.
|
|
218
|
+
whitespace) by ``=``. A quoted token is always a value.
|
|
219
219
|
|
|
220
220
|
Example:
|
|
221
221
|
>>> _next_token_is_value("STRANDID 2", 9)
|
|
@@ -270,7 +270,7 @@ def _kv_split(text: str) -> dict[str, str]:
|
|
|
270
270
|
i += 1
|
|
271
271
|
continue
|
|
272
272
|
|
|
273
|
-
# Determine the separator between key and value.
|
|
273
|
+
# Determine the separator between key and value. The modern form is
|
|
274
274
|
# ``KEY = VALUE``; some legacy files (and ``preplot``) also accept a bare
|
|
275
275
|
# whitespace separator, e.g. ``STRANDID 2``.
|
|
276
276
|
while i < n and text[i] in " \t":
|
|
@@ -362,7 +362,7 @@ def _parse_legacy_element_type(text: str) -> ZoneType:
|
|
|
362
362
|
"""Parse a legacy ``ET=`` (element type) value into a :class:`ZoneType`.
|
|
363
363
|
|
|
364
364
|
Recognises the canonical Tecplot element names (``TRIANGLE``,
|
|
365
|
-
``QUADRILATERAL``, ``TETRAHEDRON``, ``BRICK``, ``LINESEG``).
|
|
365
|
+
``QUADRILATERAL``, ``TETRAHEDRON``, ``BRICK``, ``LINESEG``). A prefix-based
|
|
366
366
|
fallback provides a little tolerance for the minor spelling variants some
|
|
367
367
|
third-party exporters emit, keeping the reader as permissive as ``preplot``.
|
|
368
368
|
|
|
@@ -473,7 +473,7 @@ def _parse_varsharelist(text: str) -> dict[int, int]:
|
|
|
473
473
|
"([1-3,5]=2)" → {0: 2, 1: 2, 2: 2, 4: 2}
|
|
474
474
|
|
|
475
475
|
Note that the bracketed group may contain either a single integer or a
|
|
476
|
-
hyphen-separated range.
|
|
476
|
+
hyphen-separated range. Mixed forms such as ``[1-3,5]`` are also produced by some
|
|
477
477
|
writers.
|
|
478
478
|
|
|
479
479
|
Args:
|
|
@@ -751,7 +751,7 @@ class ReadVariable:
|
|
|
751
751
|
"""Return :class:`DataType` inferred from the stored NumPy dtype.
|
|
752
752
|
|
|
753
753
|
A shared variable reports the source zone's actual dtype, since its data array
|
|
754
|
-
is resolved from that zone (see :attr:`shared_zone`).
|
|
754
|
+
is resolved from that zone (see :attr:`shared_zone`). Only a passive variable
|
|
755
755
|
(which has no data array anywhere in the file) returns :attr:`DataType.FLOAT` as
|
|
756
756
|
a placeholder.
|
|
757
757
|
"""
|
|
@@ -846,7 +846,7 @@ class ReadZone:
|
|
|
846
846
|
Attributes:
|
|
847
847
|
datapacking: :class:`~tecio.libtecio.DataPacking` member reflecting the
|
|
848
848
|
``DATAPACKING`` keyword found in the zone header (``BLOCK`` or
|
|
849
|
-
``POINT``).
|
|
849
|
+
``POINT``). The data arrays are identical either way; this attribute
|
|
850
850
|
records how the values were laid out on disk.
|
|
851
851
|
shared_connectivity: 1-based source zone index if this zone's connectivity is
|
|
852
852
|
shared via ``CONNECTIVITYSHAREZONE``, else ``None``. :attr:`node_map`
|
|
@@ -921,7 +921,7 @@ class ReadZone:
|
|
|
921
921
|
def nodes_per_cell(self) -> int:
|
|
922
922
|
"""Nodes per cell based on zone type.
|
|
923
923
|
|
|
924
|
-
Uses the module-level ``_NODES_PER_ELEM`` table for simple FE types.
|
|
924
|
+
Uses the module-level ``_NODES_PER_ELEM`` table for simple FE types. For
|
|
925
925
|
ORDERED zones the count is inferred from the number of active dimensions (1-D →
|
|
926
926
|
2, 2-D → 4, 3-D → 8).
|
|
927
927
|
|
|
@@ -954,7 +954,7 @@ class ReadZone:
|
|
|
954
954
|
) -> npt.NDArray | None | tuple[npt.NDArray | None, ...]:
|
|
955
955
|
"""Return variable data array(s) for this zone.
|
|
956
956
|
|
|
957
|
-
A single key (0-based index or exact name) returns one array.
|
|
957
|
+
A single key (0-based index or exact name) returns one array. A list of exact
|
|
958
958
|
names returns a tuple of arrays in the order given, suitable for unpacking::
|
|
959
959
|
|
|
960
960
|
p = zone.get_array("p")
|
|
@@ -986,7 +986,7 @@ class ReadZone:
|
|
|
986
986
|
class Read:
|
|
987
987
|
"""Read a Tecplot ASCII DAT file into memory.
|
|
988
988
|
|
|
989
|
-
The entire file is parsed on construction.
|
|
989
|
+
The entire file is parsed on construction. All data is then available through the
|
|
990
990
|
same attributes and methods as :class:`szl.Read`.
|
|
991
991
|
|
|
992
992
|
Example:
|
|
@@ -1049,7 +1049,7 @@ class Read:
|
|
|
1049
1049
|
"""Context manager protocol for read-only file interfaces.
|
|
1050
1050
|
|
|
1051
1051
|
Read classes hold no open file handle between accesses, so there is nothing to
|
|
1052
|
-
release on exit.
|
|
1052
|
+
release on exit. Provided for API consistency with the Write classes and to
|
|
1053
1053
|
support the ``with tecio.open(...) as r:`` pattern.
|
|
1054
1054
|
"""
|
|
1055
1055
|
pass
|
|
@@ -1300,7 +1300,7 @@ class Read:
|
|
|
1300
1300
|
# (legacy). ``ET`` (element type) only ever appears on finite-element zones —
|
|
1301
1301
|
# ordered/structured data has no elements — so it merely names the element
|
|
1302
1302
|
# *shape* once a zone is already known to be FE, and is ignored on ordered
|
|
1303
|
-
# zones.
|
|
1303
|
+
# zones. Modern keywords win when present.
|
|
1304
1304
|
legacy_is_fe: bool | None = None
|
|
1305
1305
|
legacy_packing: DataPacking | None = None
|
|
1306
1306
|
if "F" in kv:
|
|
@@ -1310,11 +1310,11 @@ class Read:
|
|
|
1310
1310
|
zt_raw = kv["ZONETYPE"].rstrip(",").strip().lower()
|
|
1311
1311
|
zone_type = _STR_TO_ZONETYPE.get(zt_raw, ZoneType.ORDERED)
|
|
1312
1312
|
elif legacy_is_fe is False:
|
|
1313
|
-
# F=POINT/BLOCK: ordered zone.
|
|
1313
|
+
# F=POINT/BLOCK: ordered zone. A stray ET (if any) does not apply.
|
|
1314
1314
|
zone_type = ZoneType.ORDERED
|
|
1315
1315
|
elif legacy_is_fe or "ET" in kv:
|
|
1316
1316
|
# Finite-element zone: F=FEPOINT/FEBLOCK, or an ET keyword with no F
|
|
1317
|
-
# (some exporters omit F).
|
|
1317
|
+
# (some exporters omit F). The element shape comes from ET, which is
|
|
1318
1318
|
# then required.
|
|
1319
1319
|
if "ET" not in kv:
|
|
1320
1320
|
raise ValueError(
|
|
@@ -1584,9 +1584,9 @@ class Read:
|
|
|
1584
1584
|
|
|
1585
1585
|
The spec writes two interleaved sections:
|
|
1586
1586
|
|
|
1587
|
-
* **Nodal section** — ``num_nodes`` rows, one per node.
|
|
1587
|
+
* **Nodal section** — ``num_nodes`` rows, one per node. Each row contains
|
|
1588
1588
|
the values of all active nodal variables in dataset order.
|
|
1589
|
-
* **Cell-centered section** — ``num_cells`` rows, one per element.
|
|
1589
|
+
* **Cell-centered section** — ``num_cells`` rows, one per element. Each row
|
|
1590
1590
|
contains the values of all active CC variables in dataset order.
|
|
1591
1591
|
|
|
1592
1592
|
When all variables are nodal the cell-centered section is empty and is skipped
|
tecio/dat/_write.py
CHANGED
|
@@ -250,9 +250,9 @@ def _stage_point_rows(
|
|
|
250
250
|
) -> None:
|
|
251
251
|
"""Write *cols* as ``DATAPACKING=POINT`` rows into *buf*.
|
|
252
252
|
|
|
253
|
-
Each element of *cols* is the flat value array for one variable.
|
|
253
|
+
Each element of *cols* is the flat value array for one variable. One tab-separated
|
|
254
254
|
row is written per point (node or cell): all variable values for that point appear
|
|
255
|
-
on the same line.
|
|
255
|
+
on the same line. All column arrays must have the same length. Does nothing when
|
|
256
256
|
*cols* is empty.
|
|
257
257
|
|
|
258
258
|
Example:
|
|
@@ -288,12 +288,12 @@ class Write:
|
|
|
288
288
|
path:
|
|
289
289
|
Destination file path.
|
|
290
290
|
title:
|
|
291
|
-
Dataset title.
|
|
291
|
+
Dataset title. Defaults to ``"untitled"``.
|
|
292
292
|
variables:
|
|
293
293
|
Variable name list. ``None`` defers file creation until the first
|
|
294
294
|
zone-writing call (lazy open).
|
|
295
295
|
file_type:
|
|
296
|
-
:class:`FileType` enum.
|
|
296
|
+
:class:`FileType` enum. Defaults to :attr:`FileType.FULL`.
|
|
297
297
|
precision:
|
|
298
298
|
Uniform floating point precision for the whole file. :attr:`DataType.FLOAT`
|
|
299
299
|
(default; ``"single"``) or :attr:`DataType.DOUBLE` (``"double"``). Also
|
|
@@ -509,24 +509,24 @@ class Write:
|
|
|
509
509
|
Zone dimensions are inferred from the shape of the first NODAL array.
|
|
510
510
|
|
|
511
511
|
Args:
|
|
512
|
-
data: One NumPy array per dataset variable.
|
|
512
|
+
data: One NumPy array per dataset variable. Array shape is used
|
|
513
513
|
to infer ``imax``, ``jmax``, and ``kmax``; Fortran
|
|
514
|
-
(column-major) order is assumed.
|
|
514
|
+
(column-major) order is assumed. Pass ``None`` to write a
|
|
515
515
|
zone header only.
|
|
516
|
-
title: Zone title.
|
|
517
|
-
variables: Variable name list.
|
|
516
|
+
title: Zone title. Defaults to ``"IJK_Zone_{current_zone + 1}"``.
|
|
517
|
+
variables: Variable name list. Required on the first call when the
|
|
518
518
|
file has not been opened yet (lazy-open path); ignored once
|
|
519
519
|
the file is already initialised. Default to ``[V1, V2, V3,
|
|
520
520
|
...]`` if not provided in open or zone call.
|
|
521
|
-
value_locations: Per-variable :class:`~libtecio.ValueLocation`.
|
|
521
|
+
value_locations: Per-variable :class:`~libtecio.ValueLocation`. Defaults to
|
|
522
522
|
all ``NODAL``.
|
|
523
|
-
passive_vars: Per-variable passive flags.
|
|
523
|
+
passive_vars: Per-variable passive flags. Defaults to all active
|
|
524
524
|
(``False``).
|
|
525
|
-
var_sharing: Per-variable share-from zone index (1-based).
|
|
525
|
+
var_sharing: Per-variable share-from zone index (1-based). Defaults to
|
|
526
526
|
no sharing (all zeros).
|
|
527
|
-
solution_time: Solution time for transient data.
|
|
527
|
+
solution_time: Solution time for transient data. Use ``0.0`` for static
|
|
528
528
|
zones. Default to ``0.0`` if not defined.
|
|
529
|
-
strand_id: Strand ID for transient data.
|
|
529
|
+
strand_id: Strand ID for transient data. Use ``0`` for static
|
|
530
530
|
zones. Default to ``0`` (static) if not defined.
|
|
531
531
|
aux: Zone-level auxiliary data as ``{name: value}`` string
|
|
532
532
|
pairs.
|
|
@@ -795,12 +795,12 @@ class Write:
|
|
|
795
795
|
``FEPOLYGON`` and ``FEPOLYHEDRON`` raise :exc:`NotImplementedError`.
|
|
796
796
|
|
|
797
797
|
Args:
|
|
798
|
-
data: Sequence of 1-D arrays, one per dataset variable.
|
|
798
|
+
data: Sequence of 1-D arrays, one per dataset variable. NODAL
|
|
799
799
|
arrays must have length ``num_nodes``; CELL_CENTERED arrays
|
|
800
800
|
must have length ``num_cells``. ``num_nodes`` and
|
|
801
801
|
``num_cells`` are inferred from ``node_map`` (or from the
|
|
802
802
|
``con_sharing`` source zone when ``node_map`` is omitted).
|
|
803
|
-
zone_type: FE zone type from the ZoneType enum.
|
|
803
|
+
zone_type: FE zone type from the ZoneType enum. Must be one of the
|
|
804
804
|
types in ``_FE_SIMPLE``.
|
|
805
805
|
node_map: Integer array of shape ``(num_cells, nodes_per_cell)``
|
|
806
806
|
containing 1-based node indices. 32- or 64-bit write is
|
|
@@ -808,17 +808,17 @@ class Write:
|
|
|
808
808
|
Required unless ``con_sharing`` is set, in which case the
|
|
809
809
|
connectivity -- and the node/cell counts derived from it --
|
|
810
810
|
are inherited from the source zone instead.
|
|
811
|
-
title: Zone title string.
|
|
811
|
+
title: Zone title string. Defaults to ``"FE_Zone_{current_zone +
|
|
812
812
|
1}"`` if not provided.
|
|
813
|
-
variables: Variable name list.
|
|
814
|
-
been opened yet (lazy-open path).
|
|
813
|
+
variables: Variable name list. Required only when the file has not
|
|
814
|
+
been opened yet (lazy-open path). Ignored on subsequent
|
|
815
815
|
zones once the file is already initialised. Default to
|
|
816
816
|
``[V1, V2, V3, ...]`` if not provided in open or zone call.
|
|
817
|
-
value_locations: Per-variable ValueLocation.
|
|
818
|
-
passive_vars: Per-variable passive flags.
|
|
817
|
+
value_locations: Per-variable ValueLocation. Defaults to all NODAL.
|
|
818
|
+
passive_vars: Per-variable passive flags. Defaults to all active
|
|
819
819
|
(False).
|
|
820
|
-
var_sharing: Per-variable share from zone index.
|
|
821
|
-
sharing.
|
|
820
|
+
var_sharing: Per-variable share from zone index. Defaults to no
|
|
821
|
+
sharing. Cross-checked against ``node_map`` /
|
|
822
822
|
``con_sharing`` for a consistent node/cell count.
|
|
823
823
|
con_sharing: Optional zone index that the connectivity is shared from.
|
|
824
824
|
``None`` or ``0`` indicates no sharing (this zone owns its
|
tecio/libtecio.py
CHANGED
|
@@ -234,7 +234,7 @@ class DataPacking(Enum):
|
|
|
234
234
|
"""Zone data packing order for ASCII (``.dat``) files.
|
|
235
235
|
|
|
236
236
|
Controls whether data is laid out variable-by-variable or point-by-point
|
|
237
|
-
in the ASCII file.
|
|
237
|
+
in the ASCII file. The ``DATAPACKING`` keyword in a zone header takes one
|
|
238
238
|
of these two values.
|
|
239
239
|
|
|
240
240
|
.. list-table::
|