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 : // C++ includes
20 : #include <iostream>
21 : #include <fstream>
22 : #include <cstring>
23 :
24 : // Local includes
25 : #include "libmesh/utility.h"
26 : #include "libmesh/plt_loader.h"
27 :
28 : namespace libMesh
29 : {
30 :
31 :
32 :
33 : //-----------------------------------------------------------------------------
34 : // PltLoader reading members
35 0 : void PltLoader::read (const std::string & name)
36 : {
37 0 : std::ifstream in (name.c_str(), std::ios::in|std::ios::binary);
38 :
39 0 : libmesh_error_msg_if(!in.good(), "Error reading input file " << name);
40 :
41 0 : if (this->verbose())
42 0 : libMesh::out << std::endl
43 0 : << "Reading input file " << name
44 0 : << std::endl
45 0 : << "-------------------------------------------------------------------------"
46 0 : << std::endl;
47 :
48 0 : this->read_header (in);
49 0 : this->read_data (in);
50 :
51 0 : if (this->verbose())
52 0 : libMesh::out << std::endl
53 0 : << "-------------------------------------------------------------------------"
54 0 : << std::endl;
55 :
56 0 : }
57 :
58 :
59 :
60 0 : void PltLoader::read_header (std::istream & in)
61 : {
62 0 : libmesh_assert (in.good());
63 :
64 : //----------------------------------------------------
65 : // Read the TECPLOT header
66 :
67 : // Read the version number
68 : {
69 0 : in.read (buf, 8);
70 :
71 0 : this->version().clear();
72 :
73 0 : for (unsigned int i=0; i<8; i++)
74 0 : this->version() += buf[i];
75 :
76 0 : if (this->verbose())
77 0 : libMesh::out << "Tecplot Version: "
78 0 : << this->version()
79 0 : << std::endl;
80 : }
81 :
82 :
83 : //----------------------------------------------------
84 : // Read plt files written by older versions of Tecplot
85 0 : if (Utility::contains(this->version(), "V7"))
86 : {
87 0 : if (this->verbose())
88 0 : libMesh::out << "Reading legacy .plt format (<= v9) ..."
89 0 : << std::endl;
90 :
91 : // Read the value of 1 to determine byte ordering
92 : {
93 0 : int one = 0;
94 0 : in.read (buf, LIBMESH_SIZEOF_INT);
95 0 : std::memcpy (&one, buf, LIBMESH_SIZEOF_INT);
96 :
97 0 : if (one != 1)
98 : {
99 0 : if (this->verbose())
100 0 : libMesh::out << "Tecplot data is Foreign!"
101 0 : << std::endl;
102 0 : this->is_foreign() = true;
103 :
104 : // Make sure one reversed is one
105 0 : Utility::ReverseBytes rb(this->is_foreign());
106 0 : libmesh_assert_equal_to (rb(one), 1);
107 : }
108 : }
109 :
110 : // A byte-reverser in case the data is foreign
111 0 : Utility::ReverseBytes rb(this->is_foreign());
112 :
113 : // Read the title
114 : {
115 0 : int i=0;
116 :
117 0 : this->title().clear();
118 :
119 0 : do
120 : {
121 0 : in.read (buf, LIBMESH_SIZEOF_INT);
122 0 : std::memcpy (&i, buf, LIBMESH_SIZEOF_INT);
123 0 : rb(i);
124 :
125 : // Don't add trailing \0
126 0 : if (i)
127 0 : this->title() += static_cast<char>(i);
128 : }
129 0 : while (i);
130 : }
131 :
132 : // Read the number of variables in the data set
133 : {
134 : int nv;
135 0 : in.read (buf, LIBMESH_SIZEOF_INT);
136 0 : std::memcpy (&nv, buf, LIBMESH_SIZEOF_INT);
137 0 : rb(nv);
138 :
139 0 : this->set_n_vars (nv);
140 : }
141 :
142 : // Read the variable names
143 0 : for (unsigned int v=0; v<this->n_vars(); v++)
144 : {
145 0 : int i=0;
146 :
147 0 : this->var_name(v).clear();
148 :
149 0 : do
150 : {
151 0 : in.read (buf, LIBMESH_SIZEOF_INT);
152 0 : std::memcpy (&i, buf, LIBMESH_SIZEOF_INT);
153 0 : rb(i);
154 :
155 : // Don't add trailing \0
156 0 : if (i)
157 0 : this->var_name(v) += static_cast<char>(i);
158 : }
159 0 : while (i);
160 : }
161 :
162 :
163 :
164 : // Read zones from the header.
165 : // Continue reading until the end-of-header
166 : // marker (357.) is found.
167 0 : int nz=0;
168 0 : std::vector<std::string> zname;
169 0 : std::vector<int> ztype, zimax, zjmax, zkmax;
170 :
171 : {
172 0 : float f=0.;
173 :
174 0 : do
175 : {
176 : // find the next Zone marker
177 0 : do
178 : {
179 0 : f = 0.;
180 0 : in.read (buf, LIBMESH_SIZEOF_FLOAT);
181 0 : std::memcpy (&f, buf, LIBMESH_SIZEOF_FLOAT);
182 0 : rb(f);
183 : }
184 0 : while ((f != 299.) &&
185 0 : (f != 357.) &&
186 0 : in.good());
187 :
188 :
189 : // Did we overrun the file?
190 0 : libmesh_error_msg_if(!in.good(), "ERROR: Unexpected end-of-file!");
191 :
192 : // Found a Zone marker
193 0 : if (f == 299.)
194 : {
195 : // Increment the Zone counter
196 0 : nz++;
197 :
198 : // Read the zone name
199 : {
200 0 : int i=0;
201 0 : std::string name;
202 :
203 0 : do
204 : {
205 0 : in.read (buf, LIBMESH_SIZEOF_INT);
206 0 : std::memcpy (&i, buf, LIBMESH_SIZEOF_INT);
207 0 : rb(i);
208 :
209 : // Don't add trailing \0
210 0 : if (i)
211 0 : name += static_cast<char>(i);
212 : }
213 0 : while (i);
214 :
215 0 : zname.push_back(name);
216 : }
217 :
218 : // Read the zone format
219 : {
220 : int zt;
221 0 : in.read (buf, LIBMESH_SIZEOF_INT);
222 0 : std::memcpy (&zt, buf, LIBMESH_SIZEOF_INT);
223 0 : rb(zt);
224 :
225 0 : ztype.push_back(zt);
226 : //libMesh::out << "zone type=" << ztype.back() << std::endl;
227 : }
228 :
229 : // Read the zone color
230 : {
231 0 : int zc=0;
232 :
233 0 : in.read (buf, LIBMESH_SIZEOF_INT);
234 0 : std::memcpy (&zc, buf, LIBMESH_SIZEOF_INT);
235 0 : rb(zc);
236 :
237 : //libMesh::out << "zone color=" << zc << std::endl;
238 : }
239 :
240 : // Read in the block dimensions
241 : {
242 : int
243 0 : i_max=0,
244 0 : j_max=0,
245 0 : k_max=0;
246 :
247 0 : in.read (buf, LIBMESH_SIZEOF_INT);
248 0 : std::memcpy (&i_max, buf, LIBMESH_SIZEOF_INT);
249 0 : rb(i_max);
250 :
251 0 : in.read (buf, LIBMESH_SIZEOF_INT);
252 0 : std::memcpy (&j_max, buf, LIBMESH_SIZEOF_INT);
253 0 : rb(j_max);
254 :
255 0 : in.read (buf, LIBMESH_SIZEOF_INT);
256 0 : std::memcpy (&k_max, buf, LIBMESH_SIZEOF_INT);
257 0 : rb(k_max);
258 :
259 0 : zimax.push_back (i_max);
260 0 : zjmax.push_back (j_max);
261 0 : zkmax.push_back (k_max);
262 : }
263 : } // else if (f == 299.)
264 : }
265 0 : while ((f != 357.) && in.good());
266 : }
267 :
268 : // Set the header data
269 0 : this->set_n_zones (nz);
270 :
271 0 : for (unsigned int z=0; z<this->n_zones(); z++)
272 : {
273 0 : this->zone_type(z) = ztype[z];
274 0 : this->zone_name(z) = zname[z];
275 0 : this->imax(z) = zimax[z];
276 0 : this->jmax(z) = zjmax[z];
277 0 : this->kmax(z) = zkmax[z];
278 : }
279 0 : }
280 :
281 :
282 : //----------------------------------------------------
283 : // Read plt files written by newer versions of Tecplot
284 0 : else if (Utility::contains(this->version(), "V1"))
285 : {
286 0 : if (this->verbose())
287 0 : libMesh::out << "Reading new .plt format (>= v10)..."
288 0 : << std::endl;
289 :
290 : // Read the value of 1 to determine byte ordering
291 : {
292 0 : int one = 0;
293 :
294 0 : in.read (buf, LIBMESH_SIZEOF_INT);
295 0 : std::memcpy (&one, buf, LIBMESH_SIZEOF_INT);
296 :
297 0 : if (one != 1)
298 : {
299 0 : if (this->verbose())
300 0 : libMesh::err << "Tecplot data is Foreign!"
301 0 : << std::endl;
302 0 : this->is_foreign() = true;
303 :
304 : // Make sure one reversed is one
305 0 : Utility::ReverseBytes rb(this->is_foreign());
306 0 : libmesh_assert_equal_to (rb(one), 1);
307 : }
308 : }
309 :
310 : // A byte-reverser in case the data is foreign
311 0 : Utility::ReverseBytes rb(this->is_foreign());
312 :
313 : // Read the title
314 : {
315 0 : int i=0;
316 :
317 0 : this->title().clear();
318 0 : do
319 : {
320 0 : in.read (buf, LIBMESH_SIZEOF_INT);
321 0 : std::memcpy (&i, buf, LIBMESH_SIZEOF_INT);
322 0 : rb(i);
323 :
324 : // Don't add trailing \0
325 0 : if (i)
326 0 : this->title() += static_cast<char>(i);
327 : }
328 0 : while (i);
329 : }
330 :
331 : // Read the number of variables in the data set
332 : {
333 : int nv;
334 0 : in.read (buf, LIBMESH_SIZEOF_INT);
335 0 : std::memcpy (&nv, buf, LIBMESH_SIZEOF_INT);
336 0 : rb(nv);
337 :
338 0 : this->set_n_vars (nv);
339 : }
340 :
341 : // Read the variable names
342 0 : for (unsigned int v=0; v<this->n_vars(); v++)
343 : {
344 0 : int i=0;
345 :
346 0 : this->var_name(v).clear();
347 :
348 0 : do
349 : {
350 0 : in.read (buf, LIBMESH_SIZEOF_INT);
351 0 : std::memcpy (&i, buf, LIBMESH_SIZEOF_INT);
352 0 : rb(i);
353 :
354 : // Don't add trailing \0
355 0 : if (i)
356 0 : this->var_name(v) += static_cast<char>(i);
357 : }
358 0 : while (i);
359 : }
360 :
361 :
362 :
363 : // Read zones from the header.
364 : // Continue reading until the end-of-header
365 : // marker (357.) is found.
366 0 : int nz=0;
367 0 : std::vector<std::string> zname;
368 0 : std::vector<int> zpack, ztype, zimax, zjmax, zkmax;
369 :
370 : {
371 0 : float f=0.;
372 :
373 0 : do
374 : {
375 : // find the next Zone marker
376 0 : do
377 : {
378 0 : f = 0.;
379 0 : in.read (buf, LIBMESH_SIZEOF_FLOAT);
380 0 : std::memcpy (&f, buf, LIBMESH_SIZEOF_FLOAT);
381 0 : rb(f);
382 : }
383 0 : while ((f != 299.) &&
384 0 : (f != 357.) &&
385 0 : in.good());
386 :
387 : // Did we overrun the file?
388 0 : libmesh_error_msg_if(!in.good(), "ERROR: Unexpected end-of-file!");
389 :
390 : // Found a Zone marker
391 0 : if (f == 299.)
392 : {
393 : // Increment the Zone counter
394 0 : nz++;
395 :
396 : // Read the zone name
397 : {
398 0 : int i=0;
399 0 : std::string name;
400 :
401 0 : do
402 : {
403 0 : in.read (buf, LIBMESH_SIZEOF_INT);
404 0 : std::memcpy (&i, buf, LIBMESH_SIZEOF_INT);
405 0 : rb(i);
406 :
407 : // Don't add trailing \0
408 0 : if (i)
409 0 : name += static_cast<char>(i);
410 : }
411 0 : while (i);
412 :
413 0 : zname.push_back(name);
414 : }
415 :
416 : // Read the zone color
417 : {
418 0 : int zc=0;
419 0 : in.read (buf, LIBMESH_SIZEOF_INT);
420 0 : std::memcpy (&zc, buf, LIBMESH_SIZEOF_INT);
421 0 : rb(zc);
422 : }
423 :
424 : // Read the zone format
425 : {
426 : int zt;
427 0 : in.read (buf, LIBMESH_SIZEOF_INT);
428 0 : std::memcpy (&zt, buf, LIBMESH_SIZEOF_INT);
429 0 : rb(zt);
430 :
431 0 : ztype.push_back(zt);
432 : }
433 :
434 : // Read the data packing flag
435 : {
436 0 : int dp=0;
437 0 : in.read (buf, LIBMESH_SIZEOF_INT);
438 0 : std::memcpy (&dp, buf, LIBMESH_SIZEOF_INT);
439 0 : rb(dp);
440 :
441 0 : zpack.push_back (dp);
442 : }
443 :
444 : // Will we specify the variable location?
445 : {
446 0 : int svl=0;
447 0 : int vl=0;
448 0 : in.read (buf, LIBMESH_SIZEOF_INT);
449 0 : std::memcpy (&svl, buf, LIBMESH_SIZEOF_INT);
450 0 : rb(svl);
451 :
452 0 : if (svl)
453 0 : for (unsigned int v=0; v<this->n_vars(); v++)
454 : {
455 0 : in.read (buf, LIBMESH_SIZEOF_INT);
456 0 : std::memcpy (&vl, buf, LIBMESH_SIZEOF_INT);
457 0 : rb(vl);
458 0 : libmesh_assert_equal_to (vl, 0); // Only know about node-based data
459 : // right now
460 : }
461 :
462 : }
463 :
464 : // Get the number of user-defined face-neighbors
465 : {
466 0 : int fn=0;
467 0 : in.read (buf, LIBMESH_SIZEOF_INT);
468 0 : std::memcpy (&fn, buf, LIBMESH_SIZEOF_INT);
469 0 : rb(fn);
470 : }
471 :
472 : // Read in the block dimensions
473 : {
474 0 : if (ztype.back() != ORDERED)
475 : {
476 0 : int np=0, ne=0;
477 :
478 0 : in.read (buf, LIBMESH_SIZEOF_INT);
479 0 : std::memcpy (&np, buf, LIBMESH_SIZEOF_INT);
480 0 : rb(np);
481 :
482 0 : in.read (buf, LIBMESH_SIZEOF_INT);
483 0 : std::memcpy (&ne, buf, LIBMESH_SIZEOF_INT);
484 0 : rb(ne);
485 :
486 0 : zimax.push_back (np);
487 0 : zjmax.push_back (ne);
488 0 : zjmax.push_back (0);
489 : }
490 :
491 : int
492 0 : i_max=0,
493 0 : j_max=0,
494 0 : k_max=0;
495 :
496 0 : in.read (buf, LIBMESH_SIZEOF_INT);
497 0 : std::memcpy (&i_max, buf, LIBMESH_SIZEOF_INT);
498 0 : rb(i_max);
499 :
500 0 : in.read (buf, LIBMESH_SIZEOF_INT);
501 0 : std::memcpy (&j_max, buf, LIBMESH_SIZEOF_INT);
502 0 : rb(j_max);
503 :
504 0 : in.read (buf, LIBMESH_SIZEOF_INT);
505 0 : std::memcpy (&k_max, buf, LIBMESH_SIZEOF_INT);
506 0 : rb(k_max);
507 :
508 : // These are only useful for ordered data. Otherwise
509 : // we grabbed the relevant values above.
510 0 : if (ztype.back() != ORDERED)
511 : {
512 0 : zimax.push_back (i_max);
513 0 : zjmax.push_back (j_max);
514 0 : zkmax.push_back (k_max);
515 : }
516 : }
517 : } // else if (f == 299.)
518 : }
519 0 : while ((f != 357.) && in.good());
520 : }
521 :
522 : // Set the header data
523 0 : this->set_n_zones (nz);
524 :
525 0 : for (unsigned int z=0; z<this->n_zones(); z++)
526 : {
527 0 : this->zone_type(z) = ztype[z];
528 0 : this->zone_name(z) = zname[z];
529 0 : this->zone_pack(z) = zpack[z];
530 0 : this->imax(z) = zimax[z];
531 0 : this->jmax(z) = zjmax[z];
532 0 : this->kmax(z) = zkmax[z];
533 : }
534 0 : }
535 :
536 :
537 :
538 : //----------------------------------------------------
539 : // Unrecognized Tecplot Version!
540 : else
541 0 : libmesh_error_msg("ERROR: This plot file was written by an unrecognized version of Tecplot!:\n" << this->version());
542 :
543 :
544 :
545 :
546 :
547 :
548 :
549 :
550 : // Print the data to the screen.
551 0 : if (this->verbose())
552 : {
553 0 : libMesh::out << "Tecplot Header: "
554 0 : << this->title() << std::endl;
555 :
556 0 : libMesh::out << "Variables: ";
557 0 : for (unsigned int v=0; v<this->n_vars(); v++)
558 0 : libMesh::out << "\"" << this->var_name (v) << "\"" << " ";
559 0 : libMesh::out << std::endl;
560 :
561 0 : libMesh::out << "Variable Types: ";
562 0 : for (unsigned int v=0; v<this->n_vars(); v++)
563 0 : libMesh::out << this->var_type (v) << " ";
564 0 : libMesh::out << std::endl;
565 :
566 0 : libMesh::out << "Zone Names: ";
567 0 : for (unsigned int z=0; z<this->n_zones(); z++)
568 0 : libMesh::out << "\"" << this->zone_name (z) << "\"" << " ";
569 0 : libMesh::out << std::endl;
570 :
571 0 : libMesh::out << "Zone Types: ";
572 0 : for (unsigned int z=0; z<this->n_zones(); z++)
573 : {
574 0 : libMesh::out << this->zone_type (z) << " ";
575 :
576 0 : if (this->zone_type (z) != ORDERED)
577 0 : libMesh::out << "(" << this->n_nodes(z) << "," << this->n_elem(z) << ") ";
578 : }
579 0 : libMesh::out << std::endl;
580 :
581 0 : libMesh::out << "Zone Dimensions: " << std::endl;
582 0 : for (unsigned int z=0; z<this->n_zones(); z++)
583 0 : libMesh::out << " ("
584 0 : << this->imax(z) << ","
585 0 : << this->jmax(z) << ","
586 0 : << this->kmax(z) << ")"
587 0 : << std::endl;
588 : }
589 0 : }
590 :
591 :
592 :
593 0 : void PltLoader::read_data (std::istream & in)
594 : {
595 0 : libmesh_assert (in.good());
596 :
597 : // A byte-reverser in case the data is foreign
598 0 : Utility::ReverseBytes rb(this->is_foreign());
599 :
600 : //----------------------------------------------------
601 : // Read the TECPLOT data for each zone
602 0 : if (this->verbose())
603 : {
604 0 : libMesh::out << "Reading Zones";
605 0 : libMesh::out.flush();
606 : }
607 :
608 :
609 0 : for (unsigned int zone=0; zone<this->n_zones(); zone++)
610 : {
611 0 : if (this->verbose())
612 : {
613 0 : libMesh::out << ".";
614 0 : libMesh::out.flush();
615 : }
616 :
617 :
618 : //----------------------------------------------------
619 : // Read plt files written by older versions of Tecplot
620 0 : if (Utility::contains(this->version(), "V7"))
621 : {
622 0 : float f = 0.;
623 :
624 : // Find the next Zone marker.
625 0 : do
626 : {
627 0 : f = 0.;
628 0 : in.read (buf, LIBMESH_SIZEOF_FLOAT);
629 0 : std::memcpy (&f, buf, LIBMESH_SIZEOF_FLOAT);
630 0 : rb(f);
631 : }
632 0 : while ((f != 299.) && in.good());
633 :
634 : // Did we overrun the file?
635 0 : libmesh_error_msg_if(!in.good(), "ERROR: Unexpected end-of-file!");
636 :
637 : // Get the number of repeated vars.
638 0 : unsigned int n_rep_vars=0;
639 0 : std::vector<int> rep_vars;
640 :
641 : {
642 0 : in.read (buf, LIBMESH_SIZEOF_INT);
643 0 : std::memcpy (&n_rep_vars, buf, LIBMESH_SIZEOF_INT);
644 0 : rb(n_rep_vars);
645 :
646 0 : rep_vars.resize (n_rep_vars);
647 :
648 : // Get the repeated variables number.
649 0 : for (unsigned int v=0; v<n_rep_vars; v++)
650 : {
651 0 : libmesh_error_msg("ERROR: I don't understand repeated variables yet!");
652 :
653 : in.read (buf, LIBMESH_SIZEOF_INT);
654 : std::memcpy (&rep_vars[v], buf, LIBMESH_SIZEOF_INT);
655 : rb(rep_vars[v]);
656 : }
657 : }
658 :
659 : // Get the variable data type
660 : //libMesh::out << "var_types=";
661 0 : for (unsigned int v=0; v<this->n_vars(); v++)
662 : {
663 0 : in.read (buf, LIBMESH_SIZEOF_INT);
664 0 : std::memcpy (&this->var_type(v), buf, LIBMESH_SIZEOF_INT);
665 0 : rb(this->var_type(v));
666 :
667 : //libMesh::out << this->var_type(v) << " ";
668 : }
669 : //libMesh::out << std::endl;
670 :
671 :
672 :
673 : // Read the data.
674 0 : switch (this->zone_type(zone) )
675 : {
676 : // Block-based data. Structured meshes.
677 0 : case BLOCK:
678 : {
679 0 : this->read_block_data (in, zone);
680 0 : break;
681 : }
682 :
683 : // Point-based data. Structured meshes.
684 0 : case POINT:
685 : {
686 0 : this->read_point_data (in, zone);
687 0 : break;
688 : }
689 :
690 : // FE block data. Unstructured meshes.
691 0 : case FEBLOCK:
692 : {
693 0 : this->read_feblock_data (in, zone);
694 :
695 0 : if (this->verbose())
696 :
697 0 : libMesh::out << "Zone " << zone << ":" << std::endl
698 0 : << " nnodes =" << this->imax(zone) << std::endl
699 0 : << " nelem =" << this->jmax(zone) << std::endl
700 0 : << " elem_type=" << this->kmax(zone) << std::endl
701 0 : << std::endl;
702 0 : break;
703 : }
704 :
705 : // FE point data. Unstructured meshes.
706 0 : case FEPOINT:
707 : {
708 0 : this->read_fepoint_data (in, zone);
709 0 : break;
710 : }
711 :
712 0 : default:
713 0 : libmesh_error_msg("ERROR: Unsupported Zone type: " << this->zone_type(zone));
714 : } // end switch on zone type
715 : }
716 :
717 :
718 : //----------------------------------------------------
719 : // Read plt files written by newer versions of Tecplot
720 0 : else if (Utility::contains(this->version(), "V1"))
721 : {
722 0 : float f = 0.;
723 :
724 : // Find the next Zone marker.
725 0 : do
726 : {
727 0 : f = 0.;
728 0 : in.read (buf, LIBMESH_SIZEOF_FLOAT);
729 0 : std::memcpy (&f, buf, LIBMESH_SIZEOF_FLOAT);
730 0 : rb(f);
731 : }
732 0 : while ((f != 299.) && in.good());
733 :
734 : // Did we overrun the file?
735 0 : libmesh_error_msg_if(!in.good(), "ERROR: Unexpected end-of-file!");
736 :
737 : // Get the variable data type
738 0 : for (unsigned int v=0; v<this->n_vars(); v++)
739 : {
740 0 : in.read (buf, LIBMESH_SIZEOF_INT);
741 0 : std::memcpy (&this->var_type(v), buf, LIBMESH_SIZEOF_INT);
742 0 : rb(this->var_type(v));
743 :
744 : //libMesh::out << this->var_type(v) << " ";
745 : }
746 :
747 : // Get the variable sharing flag
748 : {
749 0 : int vs=0;
750 0 : int sv=0;
751 :
752 0 : in.read (buf, LIBMESH_SIZEOF_INT);
753 0 : std::memcpy (&vs, buf, LIBMESH_SIZEOF_INT);
754 0 : rb(vs);
755 :
756 0 : if (vs)
757 : {
758 0 : for (unsigned int v=0; v<this->n_vars(); v++)
759 : {
760 0 : in.read (buf, LIBMESH_SIZEOF_INT);
761 0 : std::memcpy (&sv, buf, LIBMESH_SIZEOF_INT);
762 0 : rb(sv);
763 :
764 0 : libmesh_error_msg_if(sv != -1, "ERROR: I don't understand variable sharing!");
765 : }
766 : }
767 : }
768 :
769 : // Get zone to share connectivity with
770 : {
771 0 : int sc=0;
772 0 : in.read (buf, LIBMESH_SIZEOF_INT);
773 0 : std::memcpy (&sc, buf, LIBMESH_SIZEOF_INT);
774 0 : rb(sc);
775 :
776 0 : libmesh_assert_equal_to (sc, -1);
777 : }
778 :
779 :
780 : // Read the data.
781 0 : if (this->zone_type(zone) == ORDERED)
782 : {
783 : // Block-based data. Structured meshes.
784 0 : if (this->zone_pack(zone) == 0)
785 0 : this->read_block_data (in, zone);
786 :
787 : // Point-based data. Structured meshes.
788 0 : else if (this->zone_pack(zone) == 1)
789 0 : this->read_point_data (in, zone);
790 :
791 : else
792 0 : libmesh_error_msg("Unrecognized zone_pack(zone) = " << this->zone_pack(zone));
793 : }
794 : else
795 : {
796 : // Block-based data. Unstructured meshes.
797 0 : if (this->zone_pack(zone) == 0)
798 0 : this->read_feblock_data (in, zone);
799 :
800 : // Point-based data. Unstructured meshes.
801 0 : else if (this->zone_pack(zone) == 1)
802 0 : this->read_fepoint_data (in, zone);
803 :
804 : else
805 0 : libmesh_error_msg("Unrecognized zone_pack(zone) = " << this->zone_pack(zone));
806 : }
807 : }
808 :
809 :
810 :
811 : //----------------------------------------------------
812 : // Unrecognized Tecplot Version!
813 : else
814 0 : libmesh_error_msg("ERROR: This plot file was written by an unrecognized version of Tecplot!:\n" << this->version());
815 :
816 : } // end loop on zones
817 0 : }
818 :
819 :
820 :
821 0 : void PltLoader::read_block_data (std::istream & in, const unsigned int zone)
822 : {
823 0 : libmesh_assert (in.good());
824 :
825 :
826 : // A byte-reverser in case the data is foreign
827 0 : Utility::ReverseBytes rb(this->is_foreign());
828 :
829 :
830 0 : for (unsigned int var=0; var<this->n_vars(); var++)
831 : {
832 :
833 0 : switch (this->var_type(var))
834 : {
835 :
836 : // Read a single-precision variable
837 0 : case FLOAT:
838 : {
839 0 : std::vector<float> & data = _data[zone][var];
840 :
841 0 : data.clear();
842 0 : data.resize (this->imax(zone)*
843 0 : this->jmax(zone)*
844 0 : this->kmax(zone));
845 :
846 0 : in.read (reinterpret_cast<char *>(data.data()), LIBMESH_SIZEOF_FLOAT*data.size());
847 :
848 0 : for (std::size_t i=0; i<data.size(); i++)
849 0 : rb(data[i]);
850 :
851 0 : break;
852 : }
853 :
854 : // Read a double-precision variable
855 0 : case DOUBLE:
856 : {
857 0 : std::vector<double> ddata;
858 0 : std::vector<float> & data = _data[zone][var];
859 :
860 0 : data.clear();
861 0 : data.resize (this->imax(zone)*
862 0 : this->jmax(zone)*
863 0 : this->kmax(zone));
864 :
865 0 : ddata.resize (this->imax(zone)*
866 0 : this->jmax(zone)*
867 0 : this->kmax(zone));
868 :
869 0 : in.read (reinterpret_cast<char *>(ddata.data()), LIBMESH_SIZEOF_DOUBLE*ddata.size());
870 :
871 0 : for (std::size_t i=0; i<data.size(); i++)
872 0 : data[i] = float(rb(ddata[i]));
873 :
874 0 : break;
875 : }
876 :
877 0 : default:
878 0 : libmesh_error_msg("ERROR: Unsupported data type: " << this->var_type(var));
879 : }
880 : }
881 0 : }
882 :
883 :
884 :
885 0 : void PltLoader::read_point_data (std::istream & in, const unsigned int zone)
886 : {
887 0 : libmesh_assert (in.good());
888 :
889 : // A byte-reverser in case the data is foreign
890 0 : Utility::ReverseBytes rb(this->is_foreign());
891 :
892 : // First allocate space
893 0 : for (unsigned int var=0; var<this->n_vars(); var++)
894 : {
895 0 : std::vector<float> & data = _data[zone][var];
896 :
897 0 : data.clear();
898 0 : data.reserve (this->imax(zone)*
899 0 : this->jmax(zone)*
900 0 : this->kmax(zone));
901 : }
902 :
903 :
904 0 : for (unsigned int k=0; k<this->kmax(zone); k++)
905 0 : for (unsigned int j=0; j<this->jmax(zone); j++)
906 0 : for (unsigned int i=0; i<this->imax(zone); i++)
907 0 : for (unsigned int var=0; var<this->n_vars(); var++)
908 0 : if (this->var_type(var) == FLOAT)
909 : {
910 0 : float f = 0.;
911 :
912 0 : libmesh_assert (in.good());
913 :
914 0 : in.read (buf, LIBMESH_SIZEOF_FLOAT);
915 0 : std::memcpy (&f, buf, LIBMESH_SIZEOF_FLOAT);
916 0 : rb(f);
917 :
918 0 : _data[zone][var].push_back(f);
919 : }
920 0 : else if (this->var_type(var) == DOUBLE)
921 : {
922 0 : double d = 0.;
923 :
924 0 : libmesh_assert (in.good());
925 :
926 0 : in.read (buf, LIBMESH_SIZEOF_DOUBLE);
927 0 : std::memcpy (&d, buf, LIBMESH_SIZEOF_DOUBLE);
928 0 : rb(d);
929 :
930 0 : _data[zone][var].push_back(float(d));
931 : }
932 : else
933 0 : libmesh_error_msg("ERROR: unsupported data type: " << this->var_type(var));
934 0 : }
935 :
936 :
937 :
938 0 : void PltLoader::read_feblock_data (std::istream & in, const unsigned int zone)
939 : {
940 0 : libmesh_assert (in.good());
941 :
942 : // A byte-reverser in case the data is foreign
943 0 : Utility::ReverseBytes rb(this->is_foreign());
944 :
945 : // Read the variable values at each node.
946 0 : for (unsigned int var=0; var<this->n_vars(); var++)
947 : {
948 0 : switch (this->var_type(var))
949 : {
950 :
951 : // Read a single-precision variable
952 0 : case FLOAT:
953 : {
954 0 : std::vector<float> & data = _data[zone][var];
955 :
956 0 : data.clear();
957 0 : data.resize (this->imax(zone));
958 :
959 0 : in.read (reinterpret_cast<char *>(data.data()), LIBMESH_SIZEOF_FLOAT*data.size());
960 :
961 0 : for (std::size_t i=0; i<data.size(); i++)
962 0 : rb(data[i]);
963 :
964 0 : break;
965 : }
966 :
967 : // Read a double-precision variable
968 0 : case DOUBLE:
969 : {
970 0 : std::vector<double> ddata;
971 0 : std::vector<float> & data = _data[zone][var];
972 :
973 0 : data.clear();
974 0 : data.resize (this->imax(zone));
975 0 : ddata.resize (this->imax(zone));
976 :
977 0 : in.read (reinterpret_cast<char *>(ddata.data()), LIBMESH_SIZEOF_DOUBLE*ddata.size());
978 :
979 0 : for (std::size_t i=0; i<data.size(); i++)
980 0 : data[i] = float(rb(ddata[i]));
981 :
982 0 : break;
983 : }
984 :
985 0 : default:
986 0 : libmesh_error_msg("ERROR: Unsupported data type: " << this->var_type(var));
987 : }
988 : }
989 :
990 : // Read the connectivity
991 : {
992 : // Get the connectivity repetition flag
993 0 : int rep=0;
994 0 : in.read ((char *) &rep, LIBMESH_SIZEOF_INT);
995 0 : rb(rep);
996 :
997 0 : libmesh_error_msg_if(rep == 1 && this->n_zones() > 1, "ERROR: Repeated connectivity not supported!");
998 :
999 : // Read the connectivity
1000 0 : libmesh_assert_less (zone, _conn.size());
1001 0 : libmesh_assert_less (this->kmax(zone), 4);
1002 :
1003 0 : _conn[zone].resize (this->jmax(zone)*NNodes[this->kmax(zone)]);
1004 :
1005 0 : in.read (reinterpret_cast<char *>(_conn[zone].data()), LIBMESH_SIZEOF_INT*_conn[zone].size());
1006 :
1007 0 : for (std::size_t i=0; i<_conn[zone].size(); i++)
1008 0 : rb(_conn[zone][i]);
1009 : }
1010 0 : }
1011 :
1012 :
1013 :
1014 0 : void PltLoader::read_fepoint_data (std::istream & in, const unsigned int zone)
1015 : {
1016 0 : libmesh_assert (in.good());
1017 :
1018 : // A byte-reverser in case the data is foreign
1019 0 : Utility::ReverseBytes rb(this->is_foreign());
1020 :
1021 : // First allocate space
1022 0 : for (unsigned int var=0; var<this->n_vars(); var++)
1023 : {
1024 0 : std::vector<float> & data = _data[zone][var];
1025 :
1026 0 : data.clear();
1027 0 : data.reserve (this->imax(zone));
1028 : }
1029 :
1030 :
1031 0 : for (unsigned int i=0; i<this->imax(zone); i++)
1032 0 : for (unsigned int var=0; var<this->n_vars(); var++)
1033 0 : if (this->var_type(var) == FLOAT)
1034 : {
1035 0 : float f = 0.;
1036 :
1037 0 : libmesh_assert (in.good());
1038 :
1039 0 : in.read (buf, LIBMESH_SIZEOF_FLOAT);
1040 0 : std::memcpy (&f, buf, LIBMESH_SIZEOF_FLOAT);
1041 0 : rb(f);
1042 :
1043 0 : _data[zone][var].push_back(f);
1044 : }
1045 0 : else if (this->var_type(var) == DOUBLE)
1046 : {
1047 0 : double d = 0.;
1048 :
1049 0 : libmesh_assert (in.good());
1050 :
1051 0 : in.read (buf, LIBMESH_SIZEOF_DOUBLE);
1052 0 : std::memcpy (&d, buf, LIBMESH_SIZEOF_DOUBLE);
1053 0 : rb(d);
1054 :
1055 0 : _data[zone][var].push_back(float(d));
1056 : }
1057 : else
1058 0 : libmesh_error_msg("ERROR: unsupported data type: " << this->var_type(var));
1059 :
1060 : // Read the connectivity
1061 : {
1062 : // Get the connectivity repetition flag
1063 0 : int rep=0;
1064 :
1065 0 : in.read ((char *) &rep, LIBMESH_SIZEOF_INT);
1066 0 : rb(rep);
1067 :
1068 0 : libmesh_error_msg_if(rep == 1, "ERROR: Repeated connectivity not supported!");
1069 :
1070 : // Read the connectivity
1071 0 : libmesh_assert_less (zone, _conn.size());
1072 0 : libmesh_assert_less (this->kmax(zone), 4);
1073 :
1074 0 : _conn[zone].resize (this->jmax(zone)*NNodes[this->kmax(zone)]);
1075 :
1076 0 : in.read (reinterpret_cast<char *>(_conn[zone].data()), LIBMESH_SIZEOF_INT*_conn[zone].size());
1077 :
1078 0 : for (std::size_t i=0; i<_conn[zone].size(); i++)
1079 0 : rb(_conn[zone][i]);
1080 : }
1081 0 : }
1082 :
1083 : } // namespace libMesh
|