$extrastylesheet
plt_loader_read.C
Go to the documentation of this file.
00001 // Copyright (C) 2002-2007  Benjamin S. Kirk
00002 
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License, or (at your option) any later version.
00007 
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00016 
00017 
00018 // C++ includes
00019 #include <iostream>
00020 #include <fstream>
00021 #include <cstring>
00022 
00023 // Local includes
00024 #include "libmesh/utility.h"
00025 #include "libmesh/plt_loader.h"
00026 
00027 namespace libMesh
00028 {
00029 
00030 
00031 
00032 //-----------------------------------------------------------------------------
00033 // PltLoader reading members
00034 void PltLoader::read (const std::string& name)
00035 {
00036   std::ifstream in (name.c_str(), std::ios::in|std::ios::binary);
00037 
00038   if (!in.good())
00039     libmesh_error_msg("Error reading input file " << name);
00040 
00041 
00042   if (this->verbose())
00043     libMesh::out << std::endl
00044                  << "Reading input file " << name
00045                  << std::endl
00046                  << "-------------------------------------------------------------------------"
00047                  << std::endl;
00048 
00049   this->read_header (in);
00050   this->read_data   (in);
00051 
00052   if (this->verbose())
00053     libMesh::out << std::endl
00054                  << "-------------------------------------------------------------------------"
00055                  << std::endl;
00056 
00057 }
00058 
00059 
00060 
00061 void PltLoader::read_header (std::istream& in)
00062 {
00063   libmesh_assert (in.good());
00064 
00065   //----------------------------------------------------
00066   // Read the TECPLOT header
00067 
00068   // Read the version number
00069   {
00070     in.read (buf, 8);
00071 
00072     // Using erase for GCC 2.95.3
00073     this->version().erase();
00074 
00075     for (unsigned int i=0; i<8; i++)
00076       this->version() += buf[i];
00077 
00078     if (this->verbose())
00079       libMesh::out << "Tecplot Version: "
00080                    << this->version()
00081                    << std::endl;
00082   }
00083 
00084 
00085   //----------------------------------------------------
00086   // Read plt files written by older versions of Tecplot
00087   if (this->version().rfind("V7") < this->version().size())
00088     {
00089       if (this->verbose())
00090         libMesh::out << "Reading legacy .plt format (<= v9) ..."
00091                      << std::endl;
00092 
00093       // Read the value of 1 to determine byte ordering
00094       {
00095         int one = 0;
00096         in.read (buf, LIBMESH_SIZEOF_INT);
00097         std::memcpy  (&one, buf, LIBMESH_SIZEOF_INT);
00098 
00099         if (one != 1)
00100           {
00101             if (this->verbose())
00102               libMesh::out << "Tecplot data is Foreign!"
00103                            << std::endl;
00104             this->is_foreign() = true;
00105 
00106             // Make sure one reversed is one
00107             Utility::ReverseBytes rb(this->is_foreign());
00108             libmesh_assert_equal_to (rb(one), 1);
00109           }
00110       }
00111 
00112       // A byte-reverser in case the data is foreign
00113       Utility::ReverseBytes rb(this->is_foreign());
00114 
00115       // Read the title
00116       {
00117         int i=0;
00118 
00119         // Using erase for GCC 2.95.3
00120         this->title().erase();
00121 
00122         do
00123           {
00124             in.read (buf, LIBMESH_SIZEOF_INT);
00125             std::memcpy  (&i, buf, LIBMESH_SIZEOF_INT);
00126             rb(i);
00127 
00128             // Don't add trailing \0
00129             if (i)
00130               this->title() += static_cast<char>(i);
00131           }
00132         while (i);
00133       }
00134 
00135       // Read the number of variables in the data set
00136       {
00137         int nv;
00138         in.read (buf, LIBMESH_SIZEOF_INT);
00139         std::memcpy  (&nv, buf, LIBMESH_SIZEOF_INT);
00140         rb(nv);
00141 
00142         this->set_n_vars (nv);
00143       }
00144 
00145       // Read the variable names
00146       for (unsigned int v=0; v<this->n_vars(); v++)
00147         {
00148           int i=0;
00149 
00150           // Using erase for GCC 2.95.3
00151           this->var_name(v).erase();
00152 
00153           do
00154             {
00155               in.read (buf, LIBMESH_SIZEOF_INT);
00156               std::memcpy  (&i, buf, LIBMESH_SIZEOF_INT);
00157               rb(i);
00158 
00159               // Don't add trailing \0
00160               if (i)
00161                 this->var_name(v) += static_cast<char>(i);
00162             }
00163           while (i);
00164         }
00165 
00166 
00167 
00168       // Read zones from the header.
00169       // Continue reading until the end-of-header
00170       // marker (357.) is found.
00171       int nz=0;
00172       std::vector<std::string> zname;
00173       std::vector<int>         ztype, zimax, zjmax, zkmax;
00174 
00175       {
00176         float f=0.;
00177 
00178         do
00179           {
00180             // find the next Zone marker
00181             do
00182               {
00183                 f = 0.;
00184                 in.read (buf, LIBMESH_SIZEOF_FLOAT);
00185                 std::memcpy  (&f, buf, LIBMESH_SIZEOF_FLOAT);
00186                 rb(f);
00187               }
00188             while ((f != 299.) &&
00189                    (f != 357.) &&
00190                    in.good());
00191 
00192 
00193             // Did we overrun the file?
00194             if (!in.good())
00195               libmesh_error_msg("ERROR: Unexpected end-of-file!");
00196 
00197             // Found a Zone marker
00198             else if (f == 299.)
00199               {
00200                 // Incriment the Zone counter
00201                 nz++;
00202 
00203                 // Read the zone name
00204                 {
00205                   int i=0;
00206                   std::string name;
00207 
00208                   do
00209                     {
00210                       in.read (buf, LIBMESH_SIZEOF_INT);
00211                       std::memcpy  (&i, buf, LIBMESH_SIZEOF_INT);
00212                       rb(i);
00213 
00214                       // Don't add trailing \0
00215                       if (i)
00216                         name += static_cast<char>(i);
00217                     }
00218                   while (i);
00219 
00220                   zname.push_back(name);
00221                 }
00222 
00223                 // Read the zone format
00224                 {
00225                   int zt;
00226                   in.read (buf, LIBMESH_SIZEOF_INT);
00227                   std::memcpy  (&zt, buf, LIBMESH_SIZEOF_INT);
00228                   rb(zt);
00229 
00230                   ztype.push_back(zt);
00231                   //libMesh::out << "zone type=" << ztype.back() << std::endl;
00232                 }
00233 
00234                 // Read the zone color
00235                 {
00236                   int zc=0;
00237 
00238                   in.read (buf, LIBMESH_SIZEOF_INT);
00239                   std::memcpy  (&zc, buf, LIBMESH_SIZEOF_INT);
00240                   rb(zc);
00241 
00242                   //libMesh::out << "zone color=" << zc << std::endl;
00243                 }
00244 
00245                 // Read in the block dimensions
00246                 {
00247                   int
00248                     i_max=0,
00249                     j_max=0,
00250                     k_max=0;
00251 
00252                   in.read (buf, LIBMESH_SIZEOF_INT);
00253                   std::memcpy  (&i_max, buf, LIBMESH_SIZEOF_INT);
00254                   rb(i_max);
00255 
00256                   in.read (buf, LIBMESH_SIZEOF_INT);
00257                   std::memcpy  (&j_max, buf, LIBMESH_SIZEOF_INT);
00258                   rb(j_max);
00259 
00260                   in.read (buf, LIBMESH_SIZEOF_INT);
00261                   std::memcpy  (&k_max, buf, LIBMESH_SIZEOF_INT);
00262                   rb(k_max);
00263 
00264                   zimax.push_back (i_max);
00265                   zjmax.push_back (j_max);
00266                   zkmax.push_back (k_max);
00267                 }
00268               } // else if (f == 299.)
00269           }
00270         while ((f != 357.) && in.good());
00271       }
00272 
00273       // Set the header data
00274       this->set_n_zones (nz);
00275 
00276       for (unsigned int z=0; z<this->n_zones(); z++)
00277         {
00278           this->zone_type(z) = ztype[z];
00279           this->zone_name(z) = zname[z];
00280           this->imax(z)      = zimax[z];
00281           this->jmax(z)      = zjmax[z];
00282           this->kmax(z)      = zkmax[z];
00283         }
00284     }
00285 
00286 
00287   //----------------------------------------------------
00288   // Read plt files written by newer versions of Tecplot
00289   else if (this->version().rfind("V1") < this->version().size())
00290     {
00291       if (this->verbose())
00292         libMesh::out << "Reading new .plt format (>= v10)..."
00293                      << std::endl;
00294 
00295       // Read the value of 1 to determine byte ordering
00296       {
00297         int one = 0;
00298 
00299         in.read (buf, LIBMESH_SIZEOF_INT);
00300         std::memcpy  (&one, buf, LIBMESH_SIZEOF_INT);
00301 
00302         if (one != 1)
00303           {
00304             if (this->verbose())
00305               libMesh::err << "Tecplot data is Foreign!"
00306                            << std::endl;
00307             this->is_foreign() = true;
00308 
00309             // Make sure one reversed is one
00310             Utility::ReverseBytes rb(this->is_foreign());
00311             libmesh_assert_equal_to (rb(one), 1);
00312           }
00313       }
00314 
00315       // A byte-reverser in case the data is foreign
00316       Utility::ReverseBytes rb(this->is_foreign());
00317 
00318       // Read the title
00319       {
00320         int i=0;
00321 
00322         // Using erase() for GCC 2.95.3
00323         this->title().erase();
00324         do
00325           {
00326             in.read (buf, LIBMESH_SIZEOF_INT);
00327             std::memcpy  (&i, buf, LIBMESH_SIZEOF_INT);
00328             rb(i);
00329 
00330             // Don't add trailing \0
00331             if (i)
00332               this->title() += static_cast<char>(i);
00333           }
00334         while (i);
00335       }
00336 
00337       // Read the number of variables in the data set
00338       {
00339         int nv;
00340         in.read (buf, LIBMESH_SIZEOF_INT);
00341         std::memcpy  (&nv, buf, LIBMESH_SIZEOF_INT);
00342         rb(nv);
00343 
00344         this->set_n_vars (nv);
00345       }
00346 
00347       // Read the variable names
00348       for (unsigned int v=0; v<this->n_vars(); v++)
00349         {
00350           int i=0;
00351 
00352           // Using erase() for GCC 2.95.3
00353           this->var_name(v).erase();
00354 
00355           do
00356             {
00357               in.read (buf, LIBMESH_SIZEOF_INT);
00358               std::memcpy  (&i, buf, LIBMESH_SIZEOF_INT);
00359               rb(i);
00360 
00361               // Don't add trailing \0
00362               if (i)
00363                 this->var_name(v) += static_cast<char>(i);
00364             }
00365           while (i);
00366         }
00367 
00368 
00369 
00370       // Read zones from the header.
00371       // Continue reading until the end-of-header
00372       // marker (357.) is found.
00373       int nz=0;
00374       std::vector<std::string> zname;
00375       std::vector<int>         zpack, ztype, zimax, zjmax, zkmax;
00376 
00377       {
00378         float f=0.;
00379 
00380         do
00381           {
00382             // find the next Zone marker
00383             do
00384               {
00385                 f = 0.;
00386                 in.read (buf, LIBMESH_SIZEOF_FLOAT);
00387                 std::memcpy  (&f, buf, LIBMESH_SIZEOF_FLOAT);
00388                 rb(f);
00389               }
00390             while ((f != 299.) &&
00391                    (f != 357.) &&
00392                    in.good());
00393 
00394 
00395             // Did we overrun the file?
00396             if (!in.good())
00397               libmesh_error_msg("ERROR: Unexpected end-of-file!");
00398 
00399             // Found a Zone marker
00400             else if (f == 299.)
00401               {
00402                 // Incriment the Zone counter
00403                 nz++;
00404 
00405                 // Read the zone name
00406                 {
00407                   int i=0;
00408                   std::string name;
00409 
00410                   do
00411                     {
00412                       in.read (buf, LIBMESH_SIZEOF_INT);
00413                       std::memcpy  (&i, buf, LIBMESH_SIZEOF_INT);
00414                       rb(i);
00415 
00416                       // Don't add trailing \0
00417                       if (i)
00418                         name += static_cast<char>(i);
00419                     }
00420                   while (i);
00421 
00422                   zname.push_back(name);
00423                 }
00424 
00425                 // Read the zone color
00426                 {
00427                   int zc=0;
00428                   in.read (buf, LIBMESH_SIZEOF_INT);
00429                   std::memcpy  (&zc, buf, LIBMESH_SIZEOF_INT);
00430                   rb(zc);
00431                 }
00432 
00433                 // Read the zone format
00434                 {
00435                   int zt;
00436                   in.read (buf, LIBMESH_SIZEOF_INT);
00437                   std::memcpy  (&zt, buf, LIBMESH_SIZEOF_INT);
00438                   rb(zt);
00439 
00440                   ztype.push_back(zt);
00441                 }
00442 
00443                 // Read the data packing flag
00444                 {
00445                   int dp=0;
00446                   in.read (buf, LIBMESH_SIZEOF_INT);
00447                   std::memcpy (&dp, buf, LIBMESH_SIZEOF_INT);
00448                   rb(dp);
00449 
00450                   zpack.push_back (dp);
00451                 }
00452 
00453                 // Will we specify the variable location?
00454                 {
00455                   int svl=0;
00456                   int  vl=0;
00457                   in.read (buf, LIBMESH_SIZEOF_INT);
00458                   std::memcpy  (&svl, buf, LIBMESH_SIZEOF_INT);
00459                   rb(svl);
00460 
00461                   if (svl)
00462                     for (unsigned int v=0; v<this->n_vars(); v++)
00463                       {
00464                         in.read (buf, LIBMESH_SIZEOF_INT);
00465                         std::memcpy  (&vl, buf, LIBMESH_SIZEOF_INT);
00466                         rb(vl);
00467                         libmesh_assert_equal_to (vl, 0); // Only know about node-based data
00468                         // right now
00469                       }
00470 
00471                 }
00472 
00473                 // Get the number of user-defined face-neighbors
00474                 {
00475                   int fn=0;
00476                   in.read (buf, LIBMESH_SIZEOF_INT);
00477                   std::memcpy  (&fn, buf, LIBMESH_SIZEOF_INT);
00478                   rb(fn);
00479                 }
00480 
00481                 // Read in the block dimensions
00482                 {
00483                   if (ztype.back() != ORDERED)
00484                     {
00485                       int np=0, ne=0;
00486 
00487                       in.read (buf, LIBMESH_SIZEOF_INT);
00488                       std::memcpy  (&np, buf, LIBMESH_SIZEOF_INT);
00489                       rb(np);
00490 
00491                       in.read (buf, LIBMESH_SIZEOF_INT);
00492                       std::memcpy  (&ne, buf, LIBMESH_SIZEOF_INT);
00493                       rb(ne);
00494 
00495                       zimax.push_back (np);
00496                       zjmax.push_back (ne);
00497                       zjmax.push_back (0);
00498                     }
00499 
00500                   int
00501                     i_max=0,
00502                     j_max=0,
00503                     k_max=0;
00504 
00505                   in.read (buf, LIBMESH_SIZEOF_INT);
00506                   std::memcpy  (&i_max, buf, LIBMESH_SIZEOF_INT);
00507                   rb(i_max);
00508 
00509                   in.read (buf, LIBMESH_SIZEOF_INT);
00510                   std::memcpy  (&j_max, buf, LIBMESH_SIZEOF_INT);
00511                   rb(j_max);
00512 
00513                   in.read (buf, LIBMESH_SIZEOF_INT);
00514                   std::memcpy  (&k_max, buf, LIBMESH_SIZEOF_INT);
00515                   rb(k_max);
00516 
00517                   // These are only useful for orderd data.  Otherwise
00518                   // we grabbed the relevant values above.
00519                   if (ztype.back() != ORDERED)
00520                     {
00521                       zimax.push_back (i_max);
00522                       zjmax.push_back (j_max);
00523                       zkmax.push_back (k_max);
00524                     }
00525                 }
00526               } // else if (f == 299.)
00527           }
00528         while ((f != 357.) && in.good());
00529       }
00530 
00531       // Set the header data
00532       this->set_n_zones (nz);
00533 
00534       for (unsigned int z=0; z<this->n_zones(); z++)
00535         {
00536           this->zone_type(z) = ztype[z];
00537           this->zone_name(z) = zname[z];
00538           this->zone_pack(z) = zpack[z];
00539           this->imax(z)      = zimax[z];
00540           this->jmax(z)      = zjmax[z];
00541           this->kmax(z)      = zkmax[z];
00542         }
00543     }
00544 
00545 
00546 
00547   //----------------------------------------------------
00548   // Unrecognized Tecplot Version!
00549   else
00550     libmesh_error_msg("ERROR:  This plot file was written by an unrecognized version of Tecplot!:\n" << this->version());
00551 
00552 
00553 
00554 
00555 
00556 
00557 
00558 
00559   // Print the data to the screen.
00560   if (this->verbose())
00561     {
00562       libMesh::out << "Tecplot Header: "
00563                    << this->title() << std::endl;
00564 
00565       libMesh::out << "Variables: ";
00566       for (unsigned int v=0; v<this->n_vars(); v++)
00567         libMesh::out << "\"" << this->var_name (v) << "\"" << " ";
00568       libMesh::out << std::endl;
00569 
00570       libMesh::out << "Variable Types: ";
00571       for (unsigned int v=0; v<this->n_vars(); v++)
00572         libMesh::out << this->var_type (v) << " ";
00573       libMesh::out << std::endl;
00574 
00575       libMesh::out << "Zone Names: ";
00576       for (unsigned int z=0; z<this->n_zones(); z++)
00577         libMesh::out << "\"" << this->zone_name (z) << "\"" << " ";
00578       libMesh::out << std::endl;
00579 
00580       libMesh::out << "Zone Types: ";
00581       for (unsigned int z=0; z<this->n_zones(); z++)
00582         {
00583           libMesh::out << this->zone_type (z) << " ";
00584 
00585           if (this->zone_type (z) != ORDERED)
00586             libMesh::out << "(" << this->n_nodes(z) << "," << this->n_elem(z) << ") ";
00587         }
00588       libMesh::out << std::endl;
00589 
00590       libMesh::out << "Zone Dimensions: " << std::endl;
00591       for (unsigned int z=0; z<this->n_zones(); z++)
00592         libMesh::out << "  ("
00593                      << this->imax(z) << ","
00594                      << this->jmax(z) << ","
00595                      << this->kmax(z) << ")"
00596                      << std::endl;
00597     }
00598 }
00599 
00600 
00601 
00602 void PltLoader::read_data (std::istream& in)
00603 {
00604   libmesh_assert (in.good());
00605 
00606   // A byte-reverser in case the data is foreign
00607   Utility::ReverseBytes rb(this->is_foreign());
00608 
00609   //----------------------------------------------------
00610   // Read the TECPLOT data for each zone
00611   if (this->verbose())
00612     {
00613       libMesh::out << "Reading Zones";
00614       libMesh::out.flush();
00615     }
00616 
00617 
00618   for (unsigned int zone=0; zone<this->n_zones(); zone++)
00619     {
00620       if (this->verbose())
00621         {
00622           libMesh::out << ".";
00623           libMesh::out.flush();
00624         }
00625 
00626 
00627       //----------------------------------------------------
00628       // Read plt files written by older versions of Tecplot
00629       if (this->version().rfind("V7") < this->version().size())
00630         {
00631           float f = 0.;
00632 
00633           // Find the next Zone marker.
00634           do
00635             {
00636               f = 0.;
00637               in.read (buf, LIBMESH_SIZEOF_FLOAT);
00638               std::memcpy  (&f, buf, LIBMESH_SIZEOF_FLOAT);
00639               rb(f);
00640             }
00641           while ((f != 299.) && in.good());
00642 
00643           // Did we overrun the file?
00644           if (!in.good())
00645             libmesh_error_msg("ERROR: Unexpected end-of-file!");
00646 
00647           // Get the number of repeated vars.
00648           unsigned int n_rep_vars=0;
00649           std::vector<int> rep_vars;
00650 
00651           {
00652             in.read (buf, LIBMESH_SIZEOF_INT);
00653             std::memcpy  (&n_rep_vars, buf, LIBMESH_SIZEOF_INT);
00654             rb(n_rep_vars);
00655 
00656             rep_vars.resize (n_rep_vars);
00657 
00658             // Get the repeated variables number.
00659             for (unsigned int v=0; v<n_rep_vars; v++)
00660               {
00661                 libmesh_error_msg("ERROR:  I don't understand repeated variables yet!");
00662 
00663                 in.read (buf, LIBMESH_SIZEOF_INT);
00664                 std::memcpy  (&rep_vars[v], buf, LIBMESH_SIZEOF_INT);
00665                 rb(rep_vars[v]);
00666               }
00667           }
00668 
00669           // Get the variable data type
00670           //libMesh::out << "var_types=";
00671           for (unsigned int v=0; v<this->n_vars(); v++)
00672             {
00673               in.read (buf, LIBMESH_SIZEOF_INT);
00674               std::memcpy  (&this->var_type(v), buf, LIBMESH_SIZEOF_INT);
00675               rb(this->var_type(v));
00676 
00677               //libMesh::out << this->var_type(v) << " ";
00678             }
00679           //libMesh::out << std::endl;
00680 
00681 
00682 
00683           // Read the data.
00684           switch (this->zone_type(zone) )
00685             {
00686               // Block-based data.  Structured meshes.
00687             case BLOCK:
00688               {
00689                 this->read_block_data (in, zone);
00690                 break;
00691               }
00692 
00693               // Point-based data.  Structured meshes.
00694             case POINT:
00695               {
00696                 this->read_point_data (in, zone);
00697                 break;
00698               }
00699 
00700               // FE block data.  Unstructured meshes.
00701             case FEBLOCK:
00702               {
00703                 this->read_feblock_data (in, zone);
00704 
00705                 if (this->verbose())
00706 
00707                   libMesh::out << "Zone " << zone << ":" << std::endl
00708                                << "  nnodes   =" << this->imax(zone) << std::endl
00709                                << "  nelem    =" << this->jmax(zone) << std::endl
00710                                << "  elem_type=" << this->kmax(zone) << std::endl
00711                                << std::endl;
00712                 break;
00713               }
00714 
00715               // FE point data.  Unstructured meshes.
00716             case FEPOINT:
00717               {
00718                 this->read_fepoint_data (in, zone);
00719                 break;
00720               }
00721 
00722             default:
00723               libmesh_error_msg("ERROR: Unsupported Zone type: " << this->zone_type(zone));
00724             } // end switch on zone type
00725         }
00726 
00727 
00728       //----------------------------------------------------
00729       // Read plt files written by newer versions of Tecplot
00730       else if (this->version().rfind("V1") < this->version().size())
00731         {
00732           float f = 0.;
00733 
00734           // Find the next Zone marker.
00735           do
00736             {
00737               f = 0.;
00738               in.read (buf, LIBMESH_SIZEOF_FLOAT);
00739               std::memcpy  (&f, buf, LIBMESH_SIZEOF_FLOAT);
00740               rb(f);
00741             }
00742           while ((f != 299.) && in.good());
00743 
00744           // Did we overrun the file?
00745           if (!in.good())
00746             libmesh_error_msg("ERROR: Unexpected end-of-file!");
00747 
00748           // Get the variable data type
00749           for (unsigned int v=0; v<this->n_vars(); v++)
00750             {
00751               in.read (buf, LIBMESH_SIZEOF_INT);
00752               std::memcpy  (&this->var_type(v), buf, LIBMESH_SIZEOF_INT);
00753               rb(this->var_type(v));
00754 
00755               //libMesh::out << this->var_type(v) << " ";
00756             }
00757 
00758           // Get the variable sharing flag
00759           {
00760             int vs=0;
00761             int sv=0;
00762 
00763             in.read (buf, LIBMESH_SIZEOF_INT);
00764             std::memcpy  (&vs, buf, LIBMESH_SIZEOF_INT);
00765             rb(vs);
00766 
00767             if (vs)
00768               {
00769                 for (unsigned int v=0; v<this->n_vars(); v++)
00770                   {
00771                     in.read (buf, LIBMESH_SIZEOF_INT);
00772                     std::memcpy  (&sv, buf, LIBMESH_SIZEOF_INT);
00773                     rb(sv);
00774 
00775                     if (sv != -1)
00776                       libmesh_error_msg("ERROR:  I don't understand variable sharing!");
00777                   }
00778               }
00779           }
00780 
00781           // Get zone to share connectivity with
00782           {
00783             int sc=0;
00784             in.read (buf, LIBMESH_SIZEOF_INT);
00785             std::memcpy  (&sc, buf, LIBMESH_SIZEOF_INT);
00786             rb(sc);
00787 
00788             libmesh_assert_equal_to (sc, -1);
00789           }
00790 
00791 
00792           // Read the data.
00793           if (this->zone_type(zone) == ORDERED)
00794             {
00795               // Block-based data.  Structured meshes.
00796               if (this->zone_pack(zone) == 0)
00797                 this->read_block_data (in, zone);
00798 
00799               // Point-based data.  Structured meshes.
00800               else if (this->zone_pack(zone) == 1)
00801                 this->read_point_data (in, zone);
00802 
00803               else
00804                 libmesh_error_msg("Unrecognized zone_pack(zone) = " << this->zone_pack(zone));
00805             }
00806           else
00807             {
00808               // Block-based data.  Unstructured meshes.
00809               if (this->zone_pack(zone) == 0)
00810                 this->read_feblock_data (in, zone);
00811 
00812               // Point-based data.  Unstructured meshes.
00813               else if (this->zone_pack(zone) == 1)
00814                 this->read_fepoint_data (in, zone);
00815 
00816               else
00817                 libmesh_error_msg("Unrecognized zone_pack(zone) = " << this->zone_pack(zone));
00818             }
00819         }
00820 
00821 
00822 
00823       //----------------------------------------------------
00824       // Unrecognized Tecplot Version!
00825       else
00826         libmesh_error_msg("ERROR:  This plot file was written by an unrecognized version of Tecplot!:\n" << this->version());
00827 
00828     } // end loop on zones
00829 }
00830 
00831 
00832 
00833 void PltLoader::read_block_data (std::istream& in, const unsigned int zone)
00834 {
00835   libmesh_assert (in.good());
00836 
00837 
00838   // A byte-reverser in case the data is foreign
00839   Utility::ReverseBytes rb(this->is_foreign());
00840 
00841 
00842   for (unsigned int var=0; var<this->n_vars(); var++)
00843     {
00844 
00845       switch (this->var_type(var))
00846         {
00847 
00848           // Read a single-precision variable
00849         case FLOAT:
00850           {
00851             std::vector<float> & data = _data[zone][var];
00852 
00853             data.clear();
00854             data.resize (this->imax(zone)*
00855                          this->jmax(zone)*
00856                          this->kmax(zone));
00857 
00858             in.read ((char*) &data[0], LIBMESH_SIZEOF_FLOAT*data.size());
00859 
00860             for (unsigned int i=0; i<data.size(); i++)
00861               rb(data[i]);
00862 
00863             break;
00864           }
00865 
00866           // Read a double-precision variable
00867         case DOUBLE:
00868           {
00869             std::vector<double> ddata;
00870             std::vector<float> & data = _data[zone][var];
00871 
00872             data.clear();
00873             data.resize (this->imax(zone)*
00874                          this->jmax(zone)*
00875                          this->kmax(zone));
00876 
00877             ddata.resize (this->imax(zone)*
00878                           this->jmax(zone)*
00879                           this->kmax(zone));
00880 
00881             in.read ((char*) &ddata[0], LIBMESH_SIZEOF_DOUBLE*ddata.size());
00882 
00883             for (unsigned int i=0; i<data.size(); i++)
00884               data[i] = rb(ddata[i]);
00885 
00886             break;
00887           }
00888 
00889         default:
00890           libmesh_error_msg("ERROR: Unsupported data type: " << this->var_type(var));
00891         }
00892     }
00893 }
00894 
00895 
00896 
00897 void PltLoader::read_point_data (std::istream& in, const unsigned int zone)
00898 {
00899   libmesh_assert (in.good());
00900 
00901   // A byte-reverser in case the data is foreign
00902   Utility::ReverseBytes rb(this->is_foreign());
00903 
00904   // First allocate space
00905   for (unsigned int var=0; var<this->n_vars(); var++)
00906     {
00907       std::vector<float> & data = _data[zone][var];
00908 
00909       data.clear();
00910       data.reserve (this->imax(zone)*
00911                     this->jmax(zone)*
00912                     this->kmax(zone));
00913     }
00914 
00915 
00916   for (unsigned int k=0; k<this->kmax(zone); k++)
00917     for (unsigned int j=0; j<this->jmax(zone); j++)
00918       for (unsigned int i=0; i<this->imax(zone); i++)
00919         for (unsigned int var=0; var<this->n_vars(); var++)
00920           if (this->var_type(var) == FLOAT)
00921             {
00922               float f = 0.;
00923 
00924               libmesh_assert (in.good());
00925 
00926               in.read (buf, LIBMESH_SIZEOF_FLOAT);
00927               std::memcpy  (&f, buf, LIBMESH_SIZEOF_FLOAT);
00928               rb(f);
00929 
00930               _data[zone][var].push_back(f);
00931             }
00932           else if (this->var_type(var) == DOUBLE)
00933             {
00934               double d = 0.;
00935 
00936               libmesh_assert (in.good());
00937 
00938               in.read (buf, LIBMESH_SIZEOF_DOUBLE);
00939               std::memcpy  (&d, buf, LIBMESH_SIZEOF_DOUBLE);
00940               rb(d);
00941 
00942               _data[zone][var].push_back(d);
00943             }
00944           else
00945             libmesh_error_msg("ERROR: unsupported data type: " << this->var_type(var));
00946 }
00947 
00948 
00949 
00950 void PltLoader::read_feblock_data (std::istream& in, const unsigned int zone)
00951 {
00952   libmesh_assert (in.good());
00953 
00954   // A byte-reverser in case the data is foreign
00955   Utility::ReverseBytes rb(this->is_foreign());
00956 
00957   // Read the variable values at each node.
00958   for (unsigned int var=0; var<this->n_vars(); var++)
00959     {
00960       switch (this->var_type(var))
00961         {
00962 
00963           // Read a single-precision variable
00964         case FLOAT:
00965           {
00966             std::vector<float> & data = _data[zone][var];
00967 
00968             data.clear();
00969             data.resize (this->imax(zone));
00970 
00971             in.read ((char*) &data[0], LIBMESH_SIZEOF_FLOAT*data.size());
00972 
00973             for (unsigned int i=0; i<data.size(); i++)
00974               rb(data[i]);
00975 
00976             break;
00977           }
00978 
00979           // Read a double-precision variable
00980         case DOUBLE:
00981           {
00982             std::vector<double> ddata;
00983             std::vector<float> & data = _data[zone][var];
00984 
00985             data.clear();
00986             data.resize (this->imax(zone));
00987             ddata.resize (this->imax(zone));
00988 
00989             in.read ((char*) &ddata[0], LIBMESH_SIZEOF_DOUBLE*ddata.size());
00990 
00991             for (unsigned int i=0; i<data.size(); i++)
00992               data[i] = rb(ddata[i]);
00993 
00994             break;
00995           }
00996 
00997         default:
00998           libmesh_error_msg("ERROR: Unsupported data type: " << this->var_type(var));
00999         }
01000     }
01001 
01002   // Read the connectivity
01003   {
01004     // Get the connectivity repetition flag
01005     int rep=0;
01006     in.read ((char*) &rep, LIBMESH_SIZEOF_INT);
01007     rb(rep);
01008 
01009     if (rep == 1 && this->n_zones() > 1)
01010       libmesh_error_msg("ERROR:  Repeated connectivity not supported!");
01011 
01012     // Read the connectivity
01013     else
01014       {
01015         libmesh_assert_less (zone, _conn.size());
01016         libmesh_assert_less (this->kmax(zone), 4);
01017 
01018         _conn[zone].resize (this->jmax(zone)*NNodes[this->kmax(zone)]);
01019 
01020         in.read ((char*) &_conn[zone][0], LIBMESH_SIZEOF_INT*_conn[zone].size());
01021 
01022         for (unsigned int i=0; i<_conn[zone].size(); i++)
01023           rb(_conn[zone][i]);
01024       }
01025   }
01026 }
01027 
01028 
01029 
01030 void PltLoader::read_fepoint_data (std::istream& in, const unsigned int zone)
01031 {
01032   libmesh_assert (in.good());
01033 
01034   // A byte-reverser in case the data is foreign
01035   Utility::ReverseBytes rb(this->is_foreign());
01036 
01037   // First allocate space
01038   for (unsigned int var=0; var<this->n_vars(); var++)
01039     {
01040       std::vector<float> & data = _data[zone][var];
01041 
01042       data.clear();
01043       data.reserve (this->imax(zone));
01044     }
01045 
01046 
01047   for (unsigned int i=0; i<this->imax(zone); i++)
01048     for (unsigned int var=0; var<this->n_vars(); var++)
01049       if (this->var_type(var) == FLOAT)
01050         {
01051           float f = 0.;
01052 
01053           libmesh_assert (in.good());
01054 
01055           in.read (buf, LIBMESH_SIZEOF_FLOAT);
01056           std::memcpy  (&f, buf, LIBMESH_SIZEOF_FLOAT);
01057           rb(f);
01058 
01059           _data[zone][var].push_back(f);
01060         }
01061       else if (this->var_type(var) == DOUBLE)
01062         {
01063           double d = 0.;
01064 
01065           libmesh_assert (in.good());
01066 
01067           in.read (buf, LIBMESH_SIZEOF_DOUBLE);
01068           std::memcpy  (&d, buf, LIBMESH_SIZEOF_DOUBLE);
01069           rb(d);
01070 
01071           _data[zone][var].push_back(d);
01072         }
01073       else
01074         libmesh_error_msg("ERROR: unsupported data type: " << this->var_type(var));
01075 
01076   // Read the connectivity
01077   {
01078     // Get the connectivity repetition flag
01079     int rep=0;
01080 
01081     in.read ((char*) &rep, LIBMESH_SIZEOF_INT);
01082     rb(rep);
01083 
01084     if (rep == 1)
01085       libmesh_error_msg("ERROR:  Repeated connectivity not supported!");
01086 
01087     // Read the connectivity
01088     else
01089       {
01090         libmesh_assert_less (zone, _conn.size());
01091         libmesh_assert_less (this->kmax(zone), 4);
01092 
01093         _conn[zone].resize (this->jmax(zone)*NNodes[this->kmax(zone)]);
01094 
01095         in.read ((char*) &_conn[zone][0], LIBMESH_SIZEOF_INT*_conn[zone].size());
01096 
01097         for (unsigned int i=0; i<_conn[zone].size(); i++)
01098           rb(_conn[zone][i]);
01099       }
01100   }
01101 }
01102 
01103 } // namespace libMesh