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