$extrastylesheet
xdr_mgf.C
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 // C++ includes
00019 #include <iomanip>
00020 
00021 // Local includes
00022 #include "libmesh/xdr_mgf.h"
00023 
00024 namespace libMesh
00025 {
00026 
00027 // XdrMGF member functions
00028 XdrMGF::~XdrMGF()
00029 {
00030   this->fini();
00031 }
00032 
00033 
00034 
00035 void XdrMGF::fini()
00036 {
00037 
00038 #ifdef LIBMESH_HAVE_XDR
00039 
00040   if (mp_xdr_handle)
00041     {
00042       //libMesh::out << "Destroying XDR file handle." << std::endl;
00043       xdr_destroy(mp_xdr_handle);
00044     }
00045 
00046   //libMesh::out << "Deleting the file handle pointer." << std::endl;
00047   delete mp_xdr_handle;
00048 
00049   mp_xdr_handle = NULL;
00050 
00051 #endif
00052 
00053   if (mp_fp)
00054     {
00055       //libMesh::out << "Closing file." << std::endl;
00056       std::fflush(mp_fp);
00057       std::fclose(mp_fp);
00058     }
00059 
00060   mp_fp = NULL;
00061 }
00062 
00063 
00064 
00065 
00066 
00067 
00068 void XdrMGF::init (XdrMGF::XdrIO_TYPE t, const char* fn, const char*, int)
00069 {
00070   m_type=t;
00071 
00072   // Close old file if necessary
00073   if (mp_fp) this->fini();
00074 
00075 
00076   // Open file
00077   switch (m_type)
00078     {
00079 
00080 #ifdef LIBMESH_HAVE_XDR
00081 
00082     case (XdrMGF::ENCODE):
00083     case (XdrMGF::DECODE):
00084       {
00085         mp_fp = fopen (fn, (m_type == ENCODE) ? "w" : "r");
00086 
00087         // Make sure the file is ready for use
00088         if (!mp_fp)
00089           libmesh_error_msg("XDR Error: Accessing file: " << fn << " failed.");
00090 
00091         // Create the XDR handle
00092         mp_xdr_handle = new XDR;
00093         xdrstdio_create(mp_xdr_handle,
00094                         mp_fp,
00095                         ((m_type == ENCODE) ? XDR_ENCODE : XDR_DECODE));
00096 
00097         break;
00098       }
00099 
00100 #endif
00101 
00102     case (XdrMGF::R_ASCII):
00103       {
00104         mp_in.open(fn, std::ios::in);
00105 
00106         // Make sure it opened correctly
00107         if (!mp_in.good())
00108           libmesh_file_error(fn);
00109 
00110         break;
00111       }
00112 
00113     case (XdrMGF::W_ASCII):
00114       {
00115         mp_out.open(fn, std::ios::out);
00116 
00117         // Make sure it opened correctly
00118         if (!mp_out.good())
00119           libmesh_file_error(fn);
00120 
00121         break;
00122       }
00123 
00124     default:
00125       libmesh_error_msg("Unrecognized file access type!");
00126     }
00127 
00128 
00129 
00130 
00131 
00132   // Read/Write the file signature
00133   const int  bufLen = 12;
00134   char       buf[bufLen+1];
00135 
00136   switch (m_type)
00137     {
00138 
00139 #ifdef LIBMESH_HAVE_XDR
00140 
00141     case (XdrMGF::ENCODE):
00142       {
00143         char* p = &buf[0];
00144         const LegacyXdrIO::FileFormat orig = this->get_orig_flag();
00145 
00146         std::ostringstream name;
00147         if (orig == LegacyXdrIO::DEAL)
00148           name << "DEAL 003:003";
00149 
00150         else if (orig == LegacyXdrIO::MGF)
00151           name << "MGF  002:000";
00152 
00153         else if (orig == LegacyXdrIO::LIBM)
00154           name << "LIBM " << this->get_num_levels();
00155 
00156         else
00157           libmesh_error_msg("Unknown orig " << orig);
00158 
00159         // Fill the buffer
00160         std::sprintf(&buf[0], "%s", name.str().c_str());
00161 
00162         xdr_string(mp_xdr_handle, &p, bufLen);  // Writes binary signature
00163 
00164         break;
00165       }
00166 
00167     case (XdrMGF::DECODE):
00168       {
00169         char* p = &buf[0];
00170         xdr_string(mp_xdr_handle, &p, bufLen); // Reads binary signature
00171 
00172         // Set the number of levels used in the mesh
00173         this->tokenize_first_line(p);
00174 
00175         break;
00176       }
00177 
00178 #endif
00179 
00180     case (XdrMGF::W_ASCII):
00181       {
00182         const LegacyXdrIO::FileFormat orig = this->get_orig_flag();
00183 
00184         if (orig == LegacyXdrIO::DEAL)
00185           std::sprintf(&buf[0], "%s %03d:%03d", "DEAL", 3, 3);
00186 
00187         else if (orig == LegacyXdrIO::MGF)
00188           std::sprintf(&buf[0], "%s %03d:%03d", "MGF ", 2, 0);
00189 
00190         else if (orig == LegacyXdrIO::LIBM)
00191           std::sprintf(&buf[0], "%s %d", "LIBM", this->get_num_levels());
00192 
00193         mp_out << buf << '\n';
00194 
00195         break;
00196       }
00197 
00198     case (XdrMGF::R_ASCII):
00199       {
00200 
00201 #ifdef __HP_aCC
00202         // weirdly, _only_ here aCC
00203         // is not fond of mp_in.getline()
00204         // however, using mp_in.getline()
00205         // further below is ok...
00206         std::string buf_buf;
00207         std::getline (mp_in, buf_buf, '\n');
00208         libmesh_assert_less_equal (buf_buf.size(), bufLen);
00209 
00210         buf_buf.copy (buf, std::string::npos);
00211 #else
00212 
00213         // Here we first use getline() to grab the very
00214         // first line of the file into a char buffer.  Then
00215         // this line is tokenized to look for:
00216         // 1.) The name LIBM, which specifies the new Mesh style.
00217         // 2.) The number of levels in the Mesh which is being read.
00218         // Note that "buf" will be further processed below, here we
00219         // are just attempting to get the number of levels.
00220         mp_in.getline(buf, bufLen+1);
00221 
00222 #endif
00223 
00224         // Determine the number of levels in this mesh
00225         this->tokenize_first_line(buf);
00226 
00227         break;
00228       }
00229 
00230     default:
00231       libmesh_error_msg("Unknown m_type" << m_type);
00232     }
00233 
00234 
00235 
00236   // If you are reading or decoding, process the signature
00237   if ((m_type == R_ASCII) || (m_type == DECODE))
00238     {
00239       char name[5];
00240       std::strncpy(name, &buf[0], 4);
00241       name[4] = '\0';
00242 
00243       if (std::strcmp (name, "DEAL") == 0)
00244         {
00245           this->orig_flag = LegacyXdrIO::DEAL; // 0 is the DEAL identifier by definition
00246         }
00247       else if (std::strcmp (name, "MGF ") == 0)
00248         {
00249           this->orig_flag = LegacyXdrIO::MGF; // 1 is the MGF identifier by definition
00250         }
00251       else if (std::strcmp (name, "LIBM") == 0)
00252         {
00253           this->orig_flag = LegacyXdrIO::LIBM; // the New and Improved XDA
00254         }
00255 
00256       else
00257         libmesh_error_msg("ERROR: No originating software can be determined for header string '" << name);
00258     }
00259 
00260 }
00261 
00262 
00263 
00264 int XdrMGF::dataBlk(int* array, int numvar, int size)
00265 {
00266   int totalSize = numvar*size;
00267 
00268   switch (m_type)
00269     {
00270 
00271 #ifdef LIBMESH_HAVE_XDR
00272 
00273     case (XdrMGF::DECODE):
00274     case (XdrMGF::ENCODE):
00275       {
00276         xdr_vector(mp_xdr_handle,
00277                    (char *) &array[0],
00278                    totalSize,
00279                    sizeof(int),
00280                    (xdrproc_t) xdr_int);
00281         break;
00282       }
00283 
00284 #endif
00285 
00286     case (XdrMGF::W_ASCII):
00287       {
00288         for (int i=0; i<size; i++)
00289           {
00290             for (int j=0; j<numvar; j++)
00291               mp_out << array[i*numvar + j] << " ";
00292 
00293             mp_out << '\n';
00294           }
00295 
00296         mp_out.flush();
00297         break;
00298       }
00299 
00300     case (XdrMGF::R_ASCII):
00301       {
00302         libmesh_assert (mp_in.good());
00303 
00304         for (int i=0; i<size; i++)
00305           {
00306             for (int j=0; j<numvar; j++)
00307               {
00308                 mp_in >> array[i*numvar + j];
00309               }
00310 
00311             mp_in.ignore(); // Read newline
00312           }
00313 
00314         break;
00315       }
00316 
00317     default:
00318       // Unknown access type
00319       libmesh_error_msg("Unknown m_type" << m_type);
00320     }
00321 
00322   return totalSize;
00323 }
00324 
00325 
00326 
00327 int XdrMGF::dataBlk(Real* array, int numvar, int size)
00328 {
00329   int totalSize = numvar*size;
00330 
00331   // If this function is called by coord(),
00332   // numvar is the problem dimension, and
00333   // size is the number of nodes in the problem.
00334 
00335   //libMesh::out << "Total amount of data to be written: " << totalSize << std::endl;
00336 
00337   switch (m_type)
00338     {
00339 
00340 #ifdef LIBMESH_HAVE_XDR
00341 
00342     case (XdrMGF::DECODE):
00343     case (XdrMGF::ENCODE):
00344       {
00345         // FIXME - this is probably broken for Real == long double
00346         // RHS
00347         xdr_vector(mp_xdr_handle,
00348                    (char *) &array[0],
00349                    totalSize,
00350                    sizeof(Real),
00351                    (xdrproc_t) xdr_REAL);
00352       }
00353 
00354 #endif
00355 
00356     case (XdrMGF::W_ASCII):
00357       {
00358         // Save stream flags
00359         std::ios_base::fmtflags out_flags = mp_out.flags();
00360 
00361         // We will use scientific notation with a precision of 16
00362         // digits in the following output.  The desired precision and
00363         // format will automatically determine the width.
00364         mp_out << std::scientific
00365                << std::setprecision(16);
00366 
00367         for (int i=0; i<size; i++)
00368           {
00369             for (int j=0; j<numvar; j++)
00370               mp_out << array[i*numvar + j] << " \t";
00371 
00372             mp_out << '\n';
00373           }
00374 
00375         // Restore stream flags
00376         mp_out.flags(out_flags);
00377 
00378         mp_out.flush();
00379         break;
00380       }
00381 
00382     case (XdrMGF::R_ASCII):
00383       {
00384         libmesh_assert (mp_in.good());
00385 
00386         for (int i=0; i<size; i++)
00387           {
00388             libmesh_assert (mp_in.good());
00389 
00390             for (int j=0; j<numvar; j++)
00391               mp_in >> array[i*numvar + j];
00392 
00393             mp_in.ignore(); // Read newline
00394           }
00395 
00396         break;
00397       }
00398 
00399     default:
00400       // Unknown access type
00401       libmesh_error_msg("Unknown m_type" << m_type);
00402     }
00403 
00404   return totalSize;
00405 }
00406 
00407 } // namespace libMesh