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