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