$extrastylesheet
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