Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 :
4 : // This library is free software; you can redistribute it and/or
5 : // modify it under the terms of the GNU Lesser General Public
6 : // License as published by the Free Software Foundation; either
7 : // version 2.1 of the License, or (at your option) any later version.
8 :
9 : // This library is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : // Lesser General Public License for more details.
13 :
14 : // You should have received a copy of the GNU Lesser General Public
15 : // License along with this library; if not, write to the Free Software
16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 :
18 :
19 :
20 : #ifndef LIBMESH_PLT_LOADER_H
21 : #define LIBMESH_PLT_LOADER_H
22 :
23 : // Local includes
24 : #include "libmesh/libmesh_common.h"
25 :
26 : // C++ includes
27 : #include <string>
28 : #include <vector>
29 :
30 : namespace libMesh
31 : {
32 :
33 :
34 :
35 : /**
36 : * This class will read a binary \p .plt file. These types of files
37 : * are for use with Amtec's <a href="http://www.tecplot.com">Tecplot</a>
38 : * visualization package.
39 : *
40 : * \author Benjamin S. Kirk
41 : * \date 2004
42 : */
43 : class PltLoader
44 : {
45 : public:
46 :
47 : /**
48 : * Constructor. Initializes data.
49 : */
50 : PltLoader (const bool v=false);
51 :
52 : /**
53 : * Constructor. Reads the file specified by \p name.
54 : */
55 : PltLoader (const std::string & name, const bool v=false);
56 :
57 : /**
58 : * Destructor.
59 : */
60 : ~PltLoader ();
61 :
62 : /**
63 : * Clear all data and return to a pristine state.
64 : */
65 : void clear ();
66 :
67 : /**
68 : * \returns The verbosity.
69 : */
70 0 : bool verbose () const { return _verbose; }
71 :
72 : /**
73 : * Reads the .plt file specified by \p name.
74 : */
75 : void read (const std::string & name);
76 :
77 : /**
78 : * Writes an ASCII Tecplot file. The optional parameter \p version
79 : * specifies the version format to write.
80 : */
81 : void write_dat (const std::string & name,
82 : const unsigned int version=10) const;
83 :
84 : // BSK - this functionality requires FORTRAN subroutine calls,
85 : // and there is no need to "dirty up" \p libMesh with FORTRAN
86 : // just to enable these methods.
87 : // /**
88 : // * Writes a plot3d files. The grid will be in basename.g and
89 : // * the solution will be in basename.q. It is assumed that the
90 : // * first three variables from the .plt file are the (x,y,z)
91 : // * locations of the grid points. The optional parameter \p reverse
92 : // * specifies if the output file will have reversed byte ordering.
93 : // */
94 : // void write_plot3d (const std::string & basename,
95 : // const bool reverse=false,
96 : // const bool gridonly=false) const;
97 :
98 : // /**
99 : // * Writes a Cart3D .tri component file. The number of components
100 : // * will be the number of zones in the .plt file.
101 : // */
102 : // void write_tri (const std::string & name,
103 : // const bool reverse=false,
104 : // const bool gridonly=false) const;
105 :
106 :
107 :
108 : //--------------------------------------------------------------
109 : // Data access
110 :
111 :
112 :
113 : /**
114 : * Enum defining the zone type in the Tecplot binary file,
115 : * for use with the old .plt format.
116 : */
117 : enum OldZoneType { BLOCK=0,
118 : POINT,
119 : FEBLOCK,
120 : FEPOINT };
121 :
122 : /**
123 : * Enum defining the zone type in the Tecplot binary file,
124 : * for use with the new .plt format.
125 : */
126 : enum NewZoneType { ORDERED=0,
127 : FELINESEG,
128 : FETRIANGLE,
129 : FEQUADRILATERAL,
130 : FETETRAHEDRON,
131 : FEBRICK };
132 :
133 : /**
134 : * Enum defining the data type of each variable.
135 : */
136 : enum DataType { FLOAT=1,
137 : DOUBLE,
138 : LONGINT,
139 : SHORTINT,
140 : BYTE,
141 : BIT};
142 :
143 : /**
144 : * Enum defining the finite element types
145 : */
146 : enum FEType { TRI=0,
147 : QUAD,
148 : TET,
149 : HEX };
150 :
151 :
152 :
153 : //--------------------------------------------------------------
154 : // Public Data Access
155 :
156 :
157 :
158 : /**
159 : * \returns The Tecplot version number string. This identifies the
160 : * version of Tecplot (or preplot) that wrote the binary file. Currently,
161 : * PltLoader understands versions "#!TDV7X " and "#!TDV1XX"
162 : */
163 : const std::string & version () const { return _version; }
164 :
165 : /**
166 : * \returns \p true if the binary type of the file is different than the
167 : * machine that is reading it. If this is the case we must perform an
168 : * endian-swap on all input data.
169 : */
170 : bool is_foreign () const { return _is_foreign; }
171 :
172 : /**
173 : * \returns The data set title
174 : */
175 0 : const std::string & title () const { return _title; }
176 :
177 : /**
178 : * \returns The number of variables in the data set.
179 : */
180 0 : unsigned int n_vars () const { return _n_vars; }
181 :
182 : /**
183 : * \returns The name of variable \p v.
184 : */
185 : const std::string & var_name (const unsigned int v) const;
186 :
187 : /**
188 : * \returns The type of variable \p v
189 : */
190 : unsigned int var_type (const unsigned int v) const;
191 :
192 : /**
193 : * \returns The number of zones.
194 : */
195 0 : unsigned int n_zones () const { return _n_zones; }
196 :
197 : /**
198 : * \returns The type of zone \p z
199 : */
200 : unsigned int zone_type (const unsigned int z) const;
201 :
202 : /**
203 : * \returns The name of zone \p z.
204 : */
205 : const std::string & zone_name (const unsigned int z) const;
206 :
207 : /**
208 : * \returns The data packing flag for zone \p z.
209 : */
210 : unsigned int zone_pack (const unsigned int z) const;
211 :
212 : /**
213 : * \returns \p imax for zone \p z.
214 : */
215 : unsigned int imax (const unsigned int z) const;
216 :
217 : /**
218 : * \returns \p jmax for zone \p z.
219 : */
220 : unsigned int jmax (const unsigned int z) const;
221 :
222 : /**
223 : * \returns \p kmax for zone \p z.
224 : */
225 : unsigned int kmax (const unsigned int z) const;
226 :
227 : /**
228 : * \returns The number of nodes in the mesh (for unstructured meshes).
229 : */
230 : unsigned int n_nodes (const unsigned int z) const;
231 :
232 : /**
233 : * \returns The number of elements in the mesh (for unstructured meshes).
234 : */
235 : unsigned int n_elem (const unsigned int z) const;
236 :
237 : /**
238 : * \returns The element type for the \p zth zone (for unstructured meshes).
239 : */
240 : FEType elem_type (const unsigned int z) const;
241 :
242 : /**
243 : * \returns A reference to the data read from the file
244 : */
245 : const std::vector<std::vector<std::vector<float>>> & get_data () const;
246 :
247 : /**
248 : * Enum defining the number of nodes for each element type.
249 : */
250 : static const unsigned int NNodes[4];
251 :
252 :
253 : private:
254 :
255 :
256 : /**
257 : * Read the header of the binary file.
258 : */
259 : void read_header (std::istream & in);
260 :
261 : /**
262 : * Read data from the binary file.
263 : */
264 : void read_data (std::istream & in);
265 :
266 : /**
267 : * Read data for the zth zone in BLOCK structured format.
268 : */
269 : void read_block_data (std::istream & in, const unsigned int zn);
270 :
271 : /**
272 : * Read data for the zth zone in POINT structured format.
273 : */
274 : void read_point_data (std::istream & in, const unsigned int zn);
275 :
276 : /**
277 : * Read data for the zth zone in FEBLOCK unstructured format.
278 : */
279 : void read_feblock_data (std::istream & in, const unsigned int zn);
280 :
281 : /**
282 : * Read data for the zth zone in FEPOINT unstructured format.
283 : */
284 : void read_fepoint_data (std::istream & in, const unsigned int zn);
285 :
286 :
287 : //--------------------------------------------------------------
288 : // Private Data Access
289 :
290 :
291 :
292 : /**
293 : * \returns The Tecplot version number string.
294 : */
295 0 : std::string & version () { return _version; }
296 :
297 : /**
298 : * \returns \p true if the binary type of the file is different than the
299 : * machine that is reading it. If this is the case we must perform an
300 : * endian-swap on all input data.
301 : */
302 0 : bool & is_foreign () { return _is_foreign; }
303 :
304 : /**
305 : * \returns The data set title
306 : */
307 0 : std::string & title () { return _title; }
308 :
309 : /**
310 : * \returns The number of variables in the data set.
311 : */
312 : void set_n_vars (const unsigned int nv);
313 :
314 : /**
315 : * \returns The name of variable \p v.
316 : */
317 : std::string & var_name (const unsigned int v);
318 :
319 : /**
320 : * \returns The type of variable \p v
321 : */
322 : unsigned int & var_type (const unsigned int v);
323 :
324 : /**
325 : * \returns The number of zones.
326 : */
327 : void set_n_zones (const unsigned int nz);
328 :
329 : /**
330 : * \returns The type of zone \p z
331 : */
332 : unsigned int & zone_type (const unsigned int z);
333 :
334 : /**
335 : * \returns The name of zone \p z.
336 : */
337 : std::string & zone_name (const unsigned int z);
338 :
339 : /**
340 : * \returns The data pack flag for zone \p z.
341 : */
342 : unsigned int & zone_pack (const unsigned int z);
343 :
344 : /**
345 : * \returns \p imax for zone \p z.
346 : */
347 : unsigned int & imax (const unsigned int z);
348 :
349 : /**
350 : * \returns \p jmax for zone \p z.
351 : */
352 : unsigned int & jmax (const unsigned int z);
353 :
354 : /**
355 : * \returns \p kmax for zone \p z.
356 : */
357 : unsigned int & kmax (const unsigned int z);
358 :
359 :
360 : //--------------------------------------------------------------
361 : // Private Data
362 :
363 :
364 : /**
365 : * Verbosity
366 : */
367 : const bool _verbose;
368 :
369 : /**
370 : * The Tecplot Version number string.
371 : */
372 : std::string _version;
373 :
374 : /**
375 : * Is the data foreign?
376 : */
377 : bool _is_foreign;
378 :
379 : /**
380 : * The Tecplot data set title.
381 : */
382 : std::string _title;
383 :
384 : /**
385 : * The number of variables in the data set.
386 : */
387 : unsigned int _n_vars;
388 :
389 : /**
390 : * The name for each variable.
391 : */
392 : std::vector<std::string> _var_names;
393 :
394 : /**
395 : * The type of each variable. Must be one of the
396 : * enumerated \p DataType types.
397 : */
398 : std::vector<unsigned int> _var_types;
399 :
400 : /**
401 : * The number of zones.
402 : */
403 : unsigned int _n_zones;
404 :
405 : /**
406 : * The type of each zone.
407 : */
408 : std::vector<unsigned int> _zone_types;
409 :
410 : /**
411 : * The name of each zone.
412 : */
413 : std::vector<std::string> _zone_names;
414 :
415 : /**
416 : * The data packing for each zone (new version only)
417 : */
418 : std::vector<unsigned int> _zone_pack;
419 :
420 : /**
421 : * The (imax,jmax,kmax) value for each zone.
422 : */
423 : std::vector<unsigned int> _imax;
424 : std::vector<unsigned int> _jmax;
425 : std::vector<unsigned int> _kmax;
426 :
427 : /**
428 : * Vector to hold the data.
429 : */
430 : std::vector<std::vector<std::vector<float>>> _data;
431 :
432 : /**
433 : * Vectors to hold the connectivity for each zone
434 : * (only for unstructured files).
435 : */
436 : std::vector<std::vector<int>> _conn;
437 :
438 : /**
439 : * Scratch data & relevant sizes.
440 : */
441 : mutable char buf[512];
442 : };
443 :
444 :
445 :
446 : //---------------------------------------------------------
447 : // PltLoader inline members
448 : inline
449 : PltLoader::PltLoader (const bool v) :
450 : _verbose (v),
451 : _is_foreign (false),
452 : _n_vars (0),
453 : _n_zones (0)
454 : {
455 : }
456 :
457 :
458 :
459 : inline
460 : PltLoader::PltLoader (const std::string & name, const bool v) :
461 : _verbose (v),
462 : _is_foreign (false),
463 : _n_vars (0),
464 : _n_zones (0)
465 : {
466 : this->read (name);
467 : }
468 :
469 :
470 :
471 : inline
472 : PltLoader::~PltLoader()
473 : {
474 : }
475 :
476 :
477 :
478 : inline
479 0 : const std::string & PltLoader::var_name (const unsigned int v) const
480 : {
481 0 : libmesh_assert_less (v, this->n_vars());
482 0 : libmesh_assert_less (v, _var_names.size());
483 0 : libmesh_assert_equal_to (this->n_vars(), _var_names.size());
484 :
485 0 : return _var_names[v];
486 : }
487 :
488 :
489 :
490 : inline
491 0 : std::string & PltLoader::var_name (const unsigned int v)
492 : {
493 0 : libmesh_assert_less (v, this->n_vars());
494 0 : libmesh_assert_less (v, _var_names.size());
495 0 : libmesh_assert_equal_to (this->n_vars(), _var_names.size());
496 :
497 0 : return _var_names[v];
498 : }
499 :
500 :
501 :
502 : inline
503 : unsigned int PltLoader::var_type (const unsigned int v) const
504 : {
505 : libmesh_assert_less (v, this->n_vars());
506 : libmesh_assert_less (v, _var_types.size());
507 : libmesh_assert_equal_to (this->n_vars(), _var_types.size());
508 :
509 : return _var_types[v];
510 : }
511 :
512 :
513 :
514 : inline
515 0 : unsigned int & PltLoader::var_type (const unsigned int v)
516 : {
517 0 : libmesh_assert_less (v, this->n_vars());
518 0 : libmesh_assert_less (v, _var_types.size());
519 0 : libmesh_assert_equal_to (this->n_vars(), _var_types.size());
520 :
521 0 : return _var_types[v];
522 : }
523 :
524 :
525 :
526 : inline
527 0 : unsigned int PltLoader::zone_type (const unsigned int z) const
528 : {
529 0 : libmesh_assert_less (z, this->n_zones());
530 0 : libmesh_assert_less (z, _zone_types.size());
531 0 : libmesh_assert_equal_to (this->n_zones(), _zone_types.size());
532 :
533 0 : return _zone_types[z];
534 : }
535 :
536 :
537 :
538 : inline
539 0 : unsigned int & PltLoader::zone_type (const unsigned int z)
540 : {
541 0 : libmesh_assert_less (z, this->n_zones());
542 0 : libmesh_assert_less (z, _zone_types.size());
543 0 : libmesh_assert_equal_to (this->n_zones(), _zone_types.size());
544 :
545 0 : return _zone_types[z];
546 : }
547 :
548 :
549 :
550 : inline
551 0 : const std::string & PltLoader::zone_name (const unsigned int z) const
552 : {
553 0 : libmesh_assert_less (z, this->n_zones());
554 0 : libmesh_assert_less (z, _zone_names.size());
555 0 : libmesh_assert_equal_to (this->n_zones(), _zone_names.size());
556 :
557 0 : return _zone_names[z];
558 : }
559 :
560 :
561 :
562 : inline
563 0 : std::string & PltLoader::zone_name (const unsigned int z)
564 : {
565 0 : libmesh_assert_less (z, this->n_zones());
566 0 : libmesh_assert_less (z, _zone_names.size());
567 0 : libmesh_assert_equal_to (this->n_zones(), _zone_names.size());
568 :
569 0 : return _zone_names[z];
570 : }
571 :
572 :
573 :
574 : inline
575 : unsigned int PltLoader::zone_pack (const unsigned int z) const
576 : {
577 : libmesh_assert_less (z, this->n_zones());
578 : libmesh_assert_less (z, _zone_pack.size());
579 : libmesh_assert_equal_to (this->n_zones(), _zone_pack.size());
580 :
581 : return _zone_pack[z];
582 : }
583 :
584 :
585 :
586 : inline
587 0 : unsigned int & PltLoader::zone_pack (const unsigned int z)
588 : {
589 0 : libmesh_assert_less (z, this->n_zones());
590 0 : libmesh_assert_less (z, _zone_pack.size());
591 0 : libmesh_assert_equal_to (this->n_zones(), _zone_pack.size());
592 :
593 0 : return _zone_pack[z];
594 : }
595 :
596 :
597 :
598 : inline
599 0 : unsigned int PltLoader::imax (const unsigned int z) const
600 : {
601 0 : libmesh_assert_less (z, this->n_zones());
602 0 : libmesh_assert_equal_to (_imax.size(), this->n_zones());
603 :
604 0 : return _imax[z];
605 : }
606 :
607 :
608 :
609 : inline
610 0 : unsigned int & PltLoader::imax (const unsigned int z)
611 : {
612 0 : libmesh_assert_less (z, this->n_zones());
613 0 : libmesh_assert_equal_to (_imax.size(), this->n_zones());
614 :
615 0 : return _imax[z];
616 : }
617 :
618 :
619 :
620 : inline
621 0 : unsigned int PltLoader::jmax (const unsigned int z) const
622 : {
623 0 : libmesh_assert_less (z, this->n_zones());
624 0 : libmesh_assert_equal_to (_jmax.size(), this->n_zones());
625 :
626 0 : return _jmax[z];
627 : }
628 :
629 :
630 :
631 : inline
632 0 : unsigned int & PltLoader::jmax (const unsigned int z)
633 : {
634 0 : libmesh_assert_less (z, this->n_zones());
635 0 : libmesh_assert_equal_to (_jmax.size(), this->n_zones());
636 :
637 0 : return _jmax[z];
638 : }
639 :
640 :
641 :
642 : inline
643 0 : unsigned int PltLoader::kmax (const unsigned int z) const
644 : {
645 0 : libmesh_assert_less (z, this->n_zones());
646 0 : libmesh_assert_equal_to (_kmax.size(), this->n_zones());
647 :
648 0 : return _kmax[z];
649 : }
650 :
651 :
652 :
653 : inline
654 0 : unsigned int & PltLoader::kmax (const unsigned int z)
655 : {
656 0 : libmesh_assert_less (z, this->n_zones());
657 0 : libmesh_assert_equal_to (_kmax.size(), this->n_zones());
658 :
659 0 : return _kmax[z];
660 : }
661 :
662 :
663 :
664 : inline
665 0 : unsigned int PltLoader::n_nodes (const unsigned int z) const
666 : {
667 0 : libmesh_assert_less (z, this->n_zones());
668 :
669 : // Only for unstructured zones!
670 0 : libmesh_assert_greater (this->zone_type(z), 1);
671 :
672 0 : return this->imax(z);
673 : }
674 :
675 :
676 :
677 : inline
678 0 : unsigned int PltLoader::n_elem (const unsigned int z) const
679 : {
680 0 : libmesh_assert_less (z, this->n_zones());
681 :
682 : // Only for unstructured zones!
683 0 : libmesh_assert_greater (this->zone_type(z), 1);
684 :
685 0 : return this->jmax(z);
686 : }
687 :
688 :
689 :
690 : inline
691 : PltLoader::FEType PltLoader::elem_type (const unsigned int z) const
692 : {
693 : libmesh_assert_less (z, this->n_zones());
694 :
695 : // Only for unstructured zones!
696 : libmesh_assert_greater (this->zone_type(z), 1);
697 :
698 : return static_cast<FEType>(this->kmax(z));
699 : }
700 :
701 :
702 : inline
703 : const std::vector<std::vector<std::vector<float>>> &
704 : PltLoader::get_data () const
705 : {
706 : return _data;
707 : }
708 :
709 :
710 :
711 :
712 : } // namespace libMesh
713 :
714 :
715 : #endif // LIBMESH_PLT_LOADER_H
|