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