$extrastylesheet
plt_loader_write.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 
00019 // C++ includes
00020 #include <fstream>
00021 
00022 // Local includes
00023 #include "libmesh/plt_loader.h"
00024 
00025 namespace libMesh
00026 {
00027 
00028 
00029 
00030 // extern "C" {
00031 
00032 //   void open_   (const int*, const char*, int*);
00033 //   void idata_  (const int*, int*, int*);
00034 //   void fdata_  (const int*, float*, int*);
00035 //   void ddata_  (const int*, double*, int*);
00036 //   void close_  (const int*);
00037 // }
00038 
00039 
00040 
00041 //-----------------------------------------------------------------------------
00042 // PltLoader write members
00043 // void PltLoader::write_plot3d (const std::string& basename,
00044 //       const bool reverse,
00045 //       const bool gridonly) const
00046 // {
00047 //   const std::string gname = basename + ".g";
00048 //   const std::string qname = basename + ".q";
00049 
00050 //   // FORTAN file unit numbers
00051 //   const int gunit = 25;
00052 //   const int qunit = 26;
00053 
00054 //   // Tell the user what files we are creating
00055 //   if (this->verbose())
00056 //     {
00057 //       libMesh::out << "Plot3D output will be written to " << gname;
00058 
00059 //       if (!gridonly)
00060 // libMesh::out << " and " << qname;
00061 
00062 //       libMesh::out << std::endl;
00063 //     }
00064 
00065 
00066 //   // Open the FORTRAN unformatted file
00067 //   {
00068 //     libmesh_assert_equal_to (gname.size(), qname.size());
00069 //     int len = gname.size();
00070 
00071 //     open_ (&gunit, gname.c_str(), &len);
00072 
00073 //     if (!gridonly)
00074 //       open_ (&qunit, qname.c_str(), &len);
00075 //   }
00076 
00077 //   // Write the headers
00078 //   {
00079 //     std::vector<int> ints;
00080 //     ints.reserve (3*this->n_zones());
00081 
00082 //     for (unsigned int zn=0; zn<this->n_zones(); zn++)
00083 //       {
00084 // ints.push_back(this->imax(zn));
00085 // ints.push_back(this->jmax(zn));
00086 // ints.push_back(this->kmax(zn));
00087 //       }
00088 
00089 //     int nb  = this->n_zones();
00090 //     int one = 1;
00091 //     int len = ints.size();
00092 
00093 //     libmesh_assert_equal_to (static_cast<unsigned int>(len), 3*this->n_zones());
00094 
00095 //     idata_ (&gunit, &nb, &one);
00096 //     idata_ (&gunit, &ints[0], &len);
00097 
00098 //     if (!gridonly)
00099 //       {
00100 // idata_ (&qunit, &nb, &one);
00101 // idata_ (&qunit, &ints[0], &len);
00102 //       }
00103 //   }
00104 
00105 
00106 //   // Variables to write to plot3D file
00107 //   std::vector<unsigned int> write_vars;
00108 //   write_vars.reserve (5);
00109 
00110 //   std::fill (write_vars.begin(), write_vars.end(), 0);
00111 
00112 
00113 //   //------------------------------------------------------------------------
00114 //   // Ask the user which variables to write
00115 //   if (!gridonly)
00116 //     {
00117 //       libMesh::out << "Variables:" << std::endl;
00118 
00119 //       for (unsigned int v=0; v<this->n_vars(); v++)
00120 // libMesh::out << " " << v << ") \"" << this->var_name(v) << "\""
00121 //   << std::endl;
00122 //       libMesh::out << std::endl;
00123 
00124 //       int n_write_vars = 0;
00125 
00126 //       while (true)
00127 // {
00128 //   libMesh::out << "How many variables to write to the Plot3D file? 1<=n<=" << this->n_vars()
00129 //     << " "
00130 //     << std::endl
00131 //     << "(-1 writes them all): ";
00132 
00133 //   std::cin >> n_write_vars;
00134 
00135 //   if (n_write_vars == -1)
00136 //     break;
00137 
00138 //   if ((n_write_vars >= 1) &&
00139 //       (n_write_vars <= static_cast<int>(this->n_vars())))
00140 //     break;
00141 // };
00142 
00143 
00144 //       // The user wants all the variables
00145 //       if ((n_write_vars == -1) ||
00146 //   (n_write_vars == static_cast<int>(this->n_vars())))
00147 // {
00148 //   for (unsigned int wv=0; wv<this->n_vars(); wv++)
00149 //     write_vars.push_back (wv);
00150 // }
00151 
00152 //       // The user wants a subset of the variables
00153 //       else
00154 // {
00155 //   libmesh_assert_greater_equal (n_write_vars, 1);
00156 //   libmesh_assert_less (n_write_vars, static_cast<int>(this->n_vars()));
00157 
00158 //   libMesh::out << "Select the " << n_write_vars << " variables to write to the Plot3D file: "
00159 //     << std::endl;
00160 
00161 //   for (int wv=0; wv<n_write_vars; wv++)
00162 //     {
00163 //       int num=0;
00164 
00165 //       std::cin >> num;
00166 
00167 //       libmesh_assert_less (num, static_cast<int>(this->n_vars()));
00168 
00169 //       write_vars.push_back (num);
00170 //     }
00171 // }
00172 
00173 //       libMesh::out << std::endl;
00174 //     } // if (!gridonly)
00175 
00176 
00177 
00178 //   //------------------------------------------------------------------------
00179 //   // Write the coordinates & data for each block
00180 //   for (unsigned int zn=0; zn<this->n_zones(); zn++)
00181 //     {
00182 //       // Write the coordinates
00183 //       {
00184 // std::vector<float> coords;   // the nodal coordinates
00185 // coords.reserve (3*this->imax(zn)*this->jmax(zn)*this->kmax(zn));
00186 
00187 // for (unsigned int v=0; v<3; v++)
00188 //   {
00189 //     unsigned int l=0;
00190 
00191 //     for (unsigned int k=0; k<this->kmax(zn); k++)
00192 //       for (unsigned int j=0; j<this->jmax(zn); j++)
00193 // for (unsigned int i=0; i<this->imax(zn); i++)
00194 //   {
00195 //     libmesh_assert_less (l, _data[zn][v].size());
00196 //     coords.push_back (_data[zn][v][l++]);
00197 //   }
00198 //   }
00199 
00200 // // Write to the grid file
00201 // {
00202 //   int len = coords.size();
00203 //   libmesh_assert_equal_to (static_cast<unsigned int>(len),
00204 //   3*this->imax(zn)*this->jmax(zn)*this->kmax(zn));
00205 
00206 //   fdata_ (&gunit, &coords[0], &len);
00207 // }
00208 //       }
00209 
00210 
00211 //       //------------------------------------------------------------------------
00212 //       // Write the data
00213 //       if (!gridonly)
00214 // {
00215 //   std::vector<float> data;     // arbitrary data
00216 //   std::vector<float> conds(4); // plot3D conditions [FSMACH, ALPHA, RE, TIME]
00217 //   data.reserve (write_vars.size()*this->imax(zn)*this->jmax(zn)*this->kmax(zn));
00218 //   std::fill    (conds.begin(), conds.end(), 0.);
00219 
00220 //   if (zn == 0)
00221 //     libMesh::out << "  Writing ";
00222 
00223 //   for (unsigned int i=0; i<write_vars.size(); i++)
00224 //     {
00225 //       // Number of the variable to write
00226 //       const unsigned int v = write_vars[i];
00227 
00228 //       libmesh_assert_less (v, this->n_vars());
00229 
00230 //       // Tell the user what variable we are writing, but only
00231 //       // once per file.
00232 //       if (zn == 0)
00233 // libMesh::out << "\"" << this->var_name(v) << "\" ";
00234 
00235 //       unsigned int l=0;
00236 
00237 //       for (unsigned int k=0; k<this->kmax(zn); k++)
00238 // for (unsigned int j=0; j<this->jmax(zn); j++)
00239 //   for (unsigned int i=0; i<this->imax(zn); i++)
00240 //     {
00241 //       libmesh_assert_less (l, _data[zn][v].size());
00242 //       data.push_back ((v < this->n_vars()) ?
00243 //       _data[zn][v][l++] : 0.);
00244 //     }
00245 //     }
00246 
00247 //   if (zn == 0)
00248 //     libMesh::out << "to " << qname << std::endl;
00249 
00250 //   // Write to the solution file
00251 //   {
00252 //     int len = conds.size();
00253 
00254 //     fdata_ (&qunit, &conds[0], &len);
00255 //   }
00256 
00257 //   // Write to the solution file
00258 //   {
00259 //     int len = data.size();
00260 //     libmesh_assert_equal_to (static_cast<unsigned int>(len),
00261 //     write_vars.size()*this->imax(zn)*this->jmax(zn)*this->kmax(zn));
00262 
00263 //     fdata_ (&qunit, &data[0], &len);
00264 //   }
00265 // }
00266 //     }
00267 
00268 //   // Close the FORTAN files
00269 //   close_ (&gunit);
00270 
00271 //   if (!gridonly)
00272 //     close_ (&qunit);
00273 
00274 //   // Possibly reverse the orders
00275 //   if (reverse)
00276 //     {
00277 //       if (this->verbose())
00278 // libMesh::out << "Reversing byte-ordering for output files."
00279 //   << std::endl;
00280 
00281 //       Utility::reverse_endian (gname);
00282 
00283 //       if (!gridonly)
00284 // Utility::reverse_endian (qname);
00285 //     }
00286 // }
00287 
00288 
00289 
00290 // void PltLoader::write_tri (const std::string& name,
00291 //    const bool reverse,
00292 //    const bool gridonly) const
00293 //   {
00294 //   // Check out
00295 //   // http://people.nas.nasa.gov/~aftosmis/cart3d/cart3dTriangulations.html
00296 //   // for the .tri, .triq format
00297 
00298 //   // FORTRAN file unit numbers
00299 //   const int gunit = 25;
00300 
00301 //   if (this->verbose())
00302 //     {
00303 //       libMesh::out << "Writing unformatted .tri file " << name
00304 // << std::endl;
00305 
00306 //       if (gridonly)
00307 // libMesh::out << "Only writing the grid to " << name
00308 //   << std::endl;
00309 //     }
00310 
00311 
00312 //   // Open the FORTRAN unformatted file
00313 //   {
00314 //     int len = name.size();
00315 
00316 //     open_ (&gunit, name.c_str(), &len);
00317 //   }
00318 
00319 
00320 //   // Write the header
00321 //   unsigned int n_nodes =0;
00322 //   unsigned int n_tri   =0;
00323 //   unsigned int n_scalar=this->n_vars()-3;
00324 
00325 //   {
00326 //     std::vector<int> ints;
00327 
00328 //     for (unsigned int zone=0; zone<this->n_zones(); zone++)
00329 //       {
00330 // libmesh_assert_equal_to (this->elem_type(zone), TRI);
00331 // n_nodes += this->n_nodes(zone);
00332 // n_tri   += this->n_elem(zone);
00333 //       }
00334 
00335 //     ints.push_back (n_nodes);
00336 //     ints.push_back (n_tri);
00337 
00338 //     if (!gridonly)
00339 //       if (this->n_vars() > 3)
00340 // ints.push_back(n_scalar);
00341 
00342 //     int len = ints.size();
00343 //     idata_ (&gunit, &ints[0], &len);
00344 //   }
00345 
00346 //   // Write the nodal values.
00347 //   {
00348 //     std::vector<float> coords;
00349 //     coords.reserve (3*n_nodes);
00350 
00351 //     for (unsigned int zone=0; zone<this->n_zones(); zone++)
00352 //       for (unsigned int n=0; n<this->n_nodes(zone); n++)
00353 // {
00354 //   coords.push_back (_data[zone][0][n]);
00355 //   coords.push_back (_data[zone][1][n]);
00356 //   coords.push_back (_data[zone][2][n]);
00357 // }
00358 //     // Got all the nodes for all the zones
00359 
00360 
00361 //     int len = coords.size();
00362 //     fdata_ (&gunit, &coords[0], &len);
00363 //   }
00364 
00365 //   // Write the connectivity
00366 //   {
00367 //     std::vector<int> conn;
00368 //     conn.reserve (3*n_tri);
00369 
00370 //     for (unsigned int zone=0; zone<this->n_zones(); zone++)
00371 //       {
00372 // // The connectivity for this zone
00373 // const std::vector<int> & zconn = _conn[zone];
00374 
00375 // libmesh_assert (!zconn.empty());
00376 
00377 // // Append the connectivity for this zone to the connectivity
00378 // // array
00379 // conn.insert (conn.end(), zconn.begin(), zconn.end());
00380 //       }
00381 
00382 //     int len = conn.size();
00383 //     libmesh_assert_equal_to (static_cast<unsigned int>(len), 3*n_tri);
00384 //     idata_ (&gunit, &conn[0], &len);
00385 //   }
00386 
00387 
00388 //   // Write the component index for each triangle
00389 //   {
00390 //     std::vector<int> comp;
00391 //     comp.reserve (n_tri);
00392 
00393 //     for (unsigned int zone=0; zone<this->n_zones(); zone++)
00394 //       comp.insert (comp.end(), this->n_elem(zone), zone+1);
00395 
00396 //     int len = comp.size();
00397 //     libmesh_assert_equal_to (static_cast<unsigned int>(len), n_tri);
00398 //     idata_ (&gunit, &comp[0], &len);
00399 //   }
00400 
00401 
00402 //   // Possibly write additional values for each node
00403 //   if (!gridonly)
00404 //     if (this->n_vars() > 3)
00405 //       {
00406 // if (this->verbose())
00407 //   {
00408 //     libMesh::out << "Writing variables ";
00409 
00410 //     for (unsigned int v=3; v<this->n_vars(); v++)
00411 //       libMesh::out << "\"" << this->var_name(v) << "\" ";
00412 
00413 //     libMesh::out << "to the output file " << name
00414 //       << std::endl;
00415 //   }
00416 
00417 // std::vector<float> data;
00418 
00419 // data.reserve (n_nodes*(this->n_vars()-3));
00420 
00421 // for (unsigned int zone=0; zone<this->n_zones(); zone++)
00422 //   for (unsigned int n=0; n<this->n_nodes(zone); n++)
00423 //     for (unsigned int v=3; v<this->n_vars(); v++)
00424 //       data.push_back (_data[zone][v][n]);
00425 
00426 // int len = data.size();
00427 // libmesh_assert_equal_to (static_cast<unsigned int>(len),
00428 // n_nodes*(this->n_vars()-3));
00429 // fdata_ (&gunit, &data[0], &len);
00430 //       }
00431 
00432 
00433 //   // Close the FORTRAN file
00434 //   close_ (&gunit);
00435 
00436 
00437 //   // Possibly reverse the orders
00438 //   if (reverse)
00439 //     {
00440 //       if (this->verbose())
00441 // libMesh::out << "Reversing byte-ordering for output files."
00442 //   << std::endl;
00443 
00444 //       Utility::reverse_endian (name);
00445 //     }
00446 // }
00447 
00448 
00449 
00450 void PltLoader::write_dat (const std::string& name,
00451                            const unsigned int version_in) const
00452 {
00453   std::ofstream out_stream (name.c_str());
00454 
00455   out_stream << "TITLE=\""
00456              << this->title()
00457              << "\""
00458              << '\n';
00459 
00460   out_stream << "VARIABLES = ";
00461 
00462   for (unsigned int v=0; v<this->n_vars(); v++)
00463     out_stream << "\"" << this->var_name(v) << "\"\n";
00464 
00465   for (unsigned int z=0; z<this->n_zones(); z++)
00466     {
00467       out_stream << "ZONE T=\"" << this->zone_name(z) << "\"\n";
00468       out_stream << " I="  << this->imax(z)
00469                  << ", J=" << this->jmax(z)
00470                  << ", K=" << this->kmax(z);
00471 
00472       // Write BLOCK data for this zone
00473       if (this->zone_type(z) == BLOCK)
00474         {
00475           if (version_in < 10)
00476             {
00477               out_stream << ", F=BLOCK\n";
00478             }
00479           else
00480             {
00481               out_stream << ", ZONETYPE=Ordered\n"
00482                          << "DATAPACKING=BLOCK\n";
00483             }
00484 
00485           out_stream << "DT=(";
00486           for (unsigned int v=0; v<this->n_vars(); v++)
00487             out_stream << "SINGLE ";
00488           out_stream << ")\n";
00489 
00490           out_stream.precision(9);
00491 
00492           for (unsigned int v=0; v<this->n_vars(); v++)
00493             {
00494               unsigned int l=0;
00495 
00496               for (unsigned int k=0; k<this->kmax(z); k++)
00497                 for (unsigned int j=0; j<this->jmax(z); j++)
00498                   for (unsigned int i=0; i<this->imax(z); i++)
00499                     {
00500                       // GCC 2.95.3 has scientific in the ios class instead
00501                       // of in namespace std::
00502 #ifndef LIBMESH_BROKEN_IOSTREAM
00503                       out_stream << std::scientific
00504                                  << _data[z][v][l++] << " ";
00505 #else
00506                       out_stream << std::ios::scientific
00507                                  << _data[z][v][l++] << " ";
00508 #endif
00509                       // Throw in a newline every 5 entries to
00510                       // avoid really long lines.
00511                       if (l%5 == 0)
00512                         out_stream << '\n';
00513                     }
00514 
00515               if (l%5 != 0)
00516                 out_stream << '\n';
00517             }
00518         } // end if (this->zone_type(z) == BLOCK)
00519 
00520       // Write POINT data for this zone
00521       else if (this->zone_type(z) == POINT)
00522         {
00523           if (version_in < 10)
00524             {
00525               out_stream << ", F=POINT\n";
00526             }
00527           else
00528             {
00529               out_stream << ", ZONETYPE=Ordered\n"
00530                          << "DATAPACKING=POINT\n";
00531             }
00532 
00533           out_stream << "DT=(";
00534           for (unsigned int v=0; v<this->n_vars(); v++)
00535             out_stream << "SINGLE ";
00536           out_stream << ")\n";
00537 
00538           out_stream.precision(9);
00539 
00540           {
00541             unsigned int l=0;
00542 
00543             for (unsigned int k=0; k<this->kmax(z); k++)
00544               for (unsigned int j=0; j<this->jmax(z); j++)
00545                 for (unsigned int i=0; i<this->imax(z); i++)
00546                   {
00547                     for (unsigned int v=0; v<this->n_vars(); v++)
00548 
00549                       // GCC 2.95.3 has scientific in the ios class instead
00550                       // of in namespace std::
00551 #ifndef LIBMESH_BROKEN_IOSTREAM
00552                       out_stream << std::scientific
00553                                  << _data[z][v][l] << " ";
00554 #else
00555                     out_stream << std::ios::scientific
00556                                << _data[z][v][l] << " ";
00557 #endif
00558                     out_stream << '\n';
00559 
00560                     l++;
00561                   }
00562           }
00563         } // end else if (this->zone_type(z) == POINT)
00564 
00565       // Otherwise, unrecognized zone type
00566       else
00567         libmesh_error_msg("Unrecognized zone type: this->zone_type(z)==" << this->zone_type(z));
00568     }
00569 }
00570 
00571 } // namespace libMesh