tecplot_io.C
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 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 00019 00020 // C++ includes 00021 #include <fstream> 00022 #include <iomanip> 00023 #include <sstream> 00024 00025 // Local includes 00026 #include "libmesh/libmesh_config.h" 00027 #include "libmesh/libmesh_logging.h" 00028 #include "libmesh/tecplot_io.h" 00029 #include "libmesh/mesh_base.h" 00030 #include "libmesh/elem.h" 00031 #include "libmesh/parallel.h" 00032 00033 #ifdef LIBMESH_HAVE_TECPLOT_API 00034 extern "C" { 00035 # include <TECIO.h> 00036 } 00037 #endif 00038 00039 00040 namespace libMesh 00041 { 00042 00043 00044 //-------------------------------------------------------- 00045 // Macros for handling Tecplot API data 00046 00047 #ifdef LIBMESH_HAVE_TECPLOT_API 00048 00049 namespace 00050 { 00051 class TecplotMacros 00052 { 00053 public: 00054 TecplotMacros(const unsigned int n_nodes, 00055 const unsigned int n_vars, 00056 const unsigned int n_cells, 00057 const unsigned int n_vert); 00058 float & nd(const unsigned int i, const unsigned int j); 00059 int & cd(const unsigned int i, const unsigned int j); 00060 std::vector<float> nodalData; 00061 std::vector<int> connData; 00062 //float* nodalData; 00063 //int* connData; 00064 00065 void set_n_cells (const unsigned int nc); 00066 00067 const unsigned int n_nodes; 00068 const unsigned int n_vars; 00069 unsigned int n_cells; 00070 const unsigned int n_vert; 00071 }; 00072 } 00073 00074 00075 00076 inline 00077 TecplotMacros::TecplotMacros(const unsigned int nn, 00078 const unsigned int nvar, 00079 const unsigned int nc, 00080 const unsigned int nvrt) : 00081 n_nodes(nn), 00082 n_vars(nvar), 00083 n_cells(nc), 00084 n_vert(nvrt) 00085 { 00086 nodalData.resize(n_nodes*n_vars); 00087 connData.resize(n_cells*n_vert); 00088 } 00089 00090 00091 00092 inline 00093 float & TecplotMacros::nd(const unsigned int i, const unsigned int j) 00094 { 00095 return nodalData[(i)*(n_nodes) + (j)]; 00096 } 00097 00098 00099 00100 inline 00101 int & TecplotMacros::cd(const unsigned int i, const unsigned int j) 00102 { 00103 return connData[(i) + (j)*(n_vert)]; 00104 } 00105 00106 00107 inline 00108 void TecplotMacros::set_n_cells (const unsigned int nc) 00109 { 00110 n_cells = nc; 00111 connData.resize(n_cells*n_vert); 00112 } 00113 #endif 00114 //-------------------------------------------------------- 00115 00116 00117 00118 // ------------------------------------------------------------ 00119 // TecplotIO members 00120 TecplotIO::TecplotIO (const MeshBase& mesh_in, 00121 const bool binary_in, 00122 const double time_in, 00123 const int strand_offset_in) : 00124 MeshOutput<MeshBase> (mesh_in), 00125 _binary (binary_in), 00126 _time (time_in), 00127 _strand_offset (strand_offset_in), 00128 _zone_title ("zone") 00129 { 00130 // Gather a list of subdomain ids in the mesh. 00131 // We must do this now, while we have every 00132 // processor's attention 00133 // (some of the write methods only execute on processor 0). 00134 mesh_in.subdomain_ids (_subdomain_ids); 00135 } 00136 00137 00138 00139 void TecplotIO::write (const std::string& fname) 00140 { 00141 if (libMesh::processor_id() == 0) 00142 { 00143 if (this->binary()) 00144 this->write_binary (fname); 00145 else 00146 this->write_ascii (fname); 00147 } 00148 } 00149 00150 00151 00152 void TecplotIO::write_nodal_data (const std::string& fname, 00153 const std::vector<Number>& soln, 00154 const std::vector<std::string>& names) 00155 { 00156 START_LOG("write_nodal_data()", "TecplotIO"); 00157 00158 if (libMesh::processor_id() == 0) 00159 { 00160 if (this->binary()) 00161 this->write_binary (fname, &soln, &names); 00162 else 00163 this->write_ascii (fname, &soln, &names); 00164 } 00165 00166 STOP_LOG("write_nodal_data()", "TecplotIO"); 00167 } 00168 00169 00170 00171 void TecplotIO::write_ascii (const std::string& fname, 00172 const std::vector<Number>* v, 00173 const std::vector<std::string>* solution_names) 00174 { 00175 // Should only do this on processor 0! 00176 libmesh_assert_equal_to (libMesh::processor_id(), 0); 00177 00178 // Create an output stream 00179 std::ofstream out_stream(fname.c_str()); 00180 00181 // Make sure it opened correctly 00182 if (!out_stream.good()) 00183 libmesh_file_error(fname.c_str()); 00184 00185 // Get a constant reference to the mesh. 00186 const MeshBase& the_mesh = MeshOutput<MeshBase>::mesh(); 00187 00188 // Write header to stream 00189 { 00190 { 00191 // TODO: We used to print out the SVN revision here when we did keyword expansions... 00192 out_stream << "# For a description of the Tecplot format see the Tecplot User's guide.\n" 00193 << "#\n"; 00194 } 00195 00196 out_stream << "Variables=x,y,z"; 00197 00198 if (solution_names != NULL) 00199 for (unsigned int n=0; n<solution_names->size(); n++) 00200 { 00201 #ifdef LIBMESH_USE_REAL_NUMBERS 00202 00203 // Write variable names for real variables 00204 out_stream << "," << (*solution_names)[n]; 00205 00206 #else 00207 00208 // Write variable names for complex variables 00209 out_stream << "," << "r_" << (*solution_names)[n] 00210 << "," << "i_" << (*solution_names)[n] 00211 << "," << "a_" << (*solution_names)[n]; 00212 00213 #endif 00214 } 00215 00216 out_stream << '\n'; 00217 00218 out_stream << "Zone f=fepoint, n=" << the_mesh.n_nodes() << ", e=" << the_mesh.n_active_sub_elem(); 00219 00220 if (the_mesh.mesh_dimension() == 1) 00221 out_stream << ", et=lineseg"; 00222 else if (the_mesh.mesh_dimension() == 2) 00223 out_stream << ", et=quadrilateral"; 00224 else if (the_mesh.mesh_dimension() == 3) 00225 out_stream << ", et=brick"; 00226 else 00227 { 00228 // Dimension other than 1, 2, or 3? 00229 libmesh_error(); 00230 } 00231 00232 // Use default mesh color = black 00233 out_stream << ", c=black\n"; 00234 00235 } // finished writing header 00236 00237 for (unsigned int i=0; i<the_mesh.n_nodes(); i++) 00238 { 00239 // Print the point without a newline 00240 the_mesh.point(i).write_unformatted(out_stream, false); 00241 00242 if ((v != NULL) && (solution_names != NULL)) 00243 { 00244 const std::size_t n_vars = solution_names->size(); 00245 00246 00247 for (std::size_t c=0; c<n_vars; c++) 00248 { 00249 #ifdef LIBMESH_USE_REAL_NUMBERS 00250 // Write real data 00251 out_stream << std::setprecision(this->ascii_precision()) 00252 << (*v)[i*n_vars + c] << " "; 00253 00254 #else 00255 // Write complex data 00256 out_stream << std::setprecision(this->ascii_precision()) 00257 << (*v)[i*n_vars + c].real() << " " 00258 << (*v)[i*n_vars + c].imag() << " " 00259 << std::abs((*v)[i*n_vars + c]) << " "; 00260 00261 #endif 00262 } 00263 } 00264 00265 // Write a new line after the data for this node 00266 out_stream << '\n'; 00267 } 00268 00269 MeshBase::const_element_iterator it = the_mesh.active_elements_begin(); 00270 const MeshBase::const_element_iterator end = the_mesh.active_elements_end(); 00271 00272 for ( ; it != end; ++it) 00273 (*it)->write_connectivity(out_stream, TECPLOT); 00274 } 00275 00276 00277 00278 void TecplotIO::write_binary (const std::string& fname, 00279 const std::vector<Number>* vec, 00280 const std::vector<std::string>* solution_names) 00281 { 00282 //----------------------------------------------------------- 00283 // Call the ASCII output function if configure did not detect 00284 // the Tecplot binary API 00285 #ifndef LIBMESH_HAVE_TECPLOT_API 00286 00287 libMesh::err << "WARNING: Tecplot Binary files require the Tecplot API." << std::endl 00288 << "Continuing with ASCII output." 00289 << std::endl; 00290 00291 if (libMesh::processor_id() == 0) 00292 this->write_ascii (fname, vec, solution_names); 00293 return; 00294 00295 00296 00297 //------------------------------------------------------------ 00298 // New binary formats, time aware and whatnot 00299 #elif defined(LIBMESH_HAVE_TECPLOT_API_112) 00300 00301 // Get a constant reference to the mesh. 00302 const MeshBase& the_mesh = MeshOutput<MeshBase>::mesh(); 00303 00304 // Required variables 00305 std::string tecplot_variable_names; 00306 int 00307 ierr = 0, 00308 file_type = 0, // full 00309 is_double = 0, 00310 #ifdef DEBUG 00311 tec_debug = 1, 00312 #else 00313 tec_debug = 0, 00314 #endif 00315 cell_type = -1, 00316 nn_per_elem = -1; 00317 00318 switch (the_mesh.mesh_dimension()) 00319 { 00320 case 1: 00321 cell_type = 1; // FELINESEG 00322 nn_per_elem = 2; 00323 break; 00324 00325 case 2: 00326 cell_type = 3; // FEQUADRILATERAL 00327 nn_per_elem = 4; 00328 break; 00329 00330 case 3: 00331 cell_type = 5; // FEBRICK 00332 nn_per_elem = 8; 00333 break; 00334 00335 default: 00336 libmesh_error(); 00337 } 00338 00339 // Build a string containing all the variable names to pass to Tecplot 00340 { 00341 tecplot_variable_names += "x, y, z"; 00342 00343 if (solution_names != NULL) 00344 { 00345 for (unsigned int name=0; name<solution_names->size(); name++) 00346 { 00347 #ifdef LIBMESH_USE_REAL_NUMBERS 00348 00349 tecplot_variable_names += ", "; 00350 tecplot_variable_names += (*solution_names)[name]; 00351 00352 #else 00353 00354 tecplot_variable_names += ", "; 00355 tecplot_variable_names += "r_"; 00356 tecplot_variable_names += (*solution_names)[name]; 00357 tecplot_variable_names += ", "; 00358 tecplot_variable_names += "i_"; 00359 tecplot_variable_names += (*solution_names)[name]; 00360 tecplot_variable_names += ", "; 00361 tecplot_variable_names += "a_"; 00362 tecplot_variable_names += (*solution_names)[name]; 00363 00364 #endif 00365 } 00366 } 00367 } 00368 00369 // Instantiate a TecplotMacros interface. In 2D the most nodes per 00370 // face should be 4, in 3D it's 8. 00371 00372 00373 TecplotMacros tm(the_mesh.n_nodes(), 00374 #ifdef LIBMESH_USE_REAL_NUMBERS 00375 (3 + ((solution_names == NULL) ? 0 : solution_names->size())), 00376 #else 00377 (3 + 3*((solution_names == NULL) ? 0 : solution_names->size())), 00378 #endif 00379 the_mesh.n_active_sub_elem(), 00380 nn_per_elem 00381 ); 00382 00383 00384 // Copy the nodes and data to the TecplotMacros class. Note that we store 00385 // everything as a float here since the eye doesn't require a double to 00386 // understand what is going on 00387 for (unsigned int v=0; v<the_mesh.n_nodes(); v++) 00388 { 00389 tm.nd(0,v) = static_cast<float>(the_mesh.point(v)(0)); 00390 tm.nd(1,v) = static_cast<float>(the_mesh.point(v)(1)); 00391 tm.nd(2,v) = static_cast<float>(the_mesh.point(v)(2)); 00392 00393 if ((vec != NULL) && 00394 (solution_names != NULL)) 00395 { 00396 const unsigned int n_vars = solution_names->size(); 00397 00398 for (unsigned int c=0; c<n_vars; c++) 00399 { 00400 #ifdef LIBMESH_USE_REAL_NUMBERS 00401 00402 tm.nd((3+c),v) = static_cast<float>((*vec)[v*n_vars + c]); 00403 #else 00404 tm.nd((3+3*c),v) = static_cast<float>((*vec)[v*n_vars + c].real()); 00405 tm.nd((3+3*c+1),v) = static_cast<float>((*vec)[v*n_vars + c].imag()); 00406 tm.nd((3+3*c+2),v) = static_cast<float>(std::abs((*vec)[v*n_vars + c])); 00407 #endif 00408 } 00409 } 00410 } 00411 00412 00413 // Initialize the file 00414 ierr = TECINI112 (NULL, 00415 (char*) tecplot_variable_names.c_str(), 00416 (char*) fname.c_str(), 00417 (char*) ".", 00418 &file_type, 00419 &tec_debug, 00420 &is_double); 00421 00422 libmesh_assert_equal_to (ierr, 0); 00423 00424 // A zone for each subdomain 00425 bool firstzone=true; 00426 for (std::set<subdomain_id_type>::const_iterator sbd_it=_subdomain_ids.begin(); 00427 sbd_it!=_subdomain_ids.end(); ++sbd_it) 00428 { 00429 // Copy the connectivity for this subdomain 00430 { 00431 MeshBase::const_element_iterator it = the_mesh.active_subdomain_elements_begin (*sbd_it); 00432 const MeshBase::const_element_iterator end = the_mesh.active_subdomain_elements_end (*sbd_it); 00433 00434 unsigned int n_subcells_in_subdomain=0; 00435 00436 for (; it != end; ++it) 00437 n_subcells_in_subdomain += (*it)->n_sub_elem(); 00438 00439 // update the connectivty array to include only the elements in this subdomain 00440 tm.set_n_cells (n_subcells_in_subdomain); 00441 00442 unsigned int te = 0; 00443 00444 for (it = the_mesh.active_subdomain_elements_begin (*sbd_it); 00445 it != end; ++it) 00446 { 00447 std::vector<dof_id_type> conn; 00448 for (unsigned int se=0; se<(*it)->n_sub_elem(); se++) 00449 { 00450 (*it)->connectivity(se, TECPLOT, conn); 00451 00452 for (unsigned int node=0; node<conn.size(); node++) 00453 tm.cd(node,te) = conn[node]; 00454 00455 te++; 00456 } 00457 } 00458 } 00459 00460 00461 // Ready to call the Tecplot API for this subdomain 00462 { 00463 int 00464 num_nodes = static_cast<int>(the_mesh.n_nodes()), 00465 num_cells = static_cast<int>(tm.n_cells), 00466 num_faces = 0, 00467 i_cell_max = 0, 00468 j_cell_max = 0, 00469 k_cell_max = 0, 00470 strand_id = std::max(*sbd_it,static_cast<subdomain_id_type>(1)) + this->strand_offset(), 00471 parent_zone = 0, 00472 is_block = 1, 00473 num_face_connect = 0, 00474 face_neighbor_mode = 0, 00475 tot_num_face_nodes = 0, 00476 num_connect_boundary_faces = 0, 00477 tot_num_boundary_connect = 0, 00478 share_connect_from_zone=0; 00479 00480 std::vector<int> 00481 passive_var_list (tm.n_vars, 0), 00482 share_var_from_zone (tm.n_vars, 1); // We only write data for the first zone, all other 00483 // zones will share from this one. 00484 00485 // get the subdomain name from libMesh, if there is one. 00486 std::string subdomain_name = the_mesh.subdomain_name(*sbd_it); 00487 std::ostringstream zone_name; 00488 zone_name << this->zone_title(); 00489 00490 // We will title this 00491 // "{zone_title()}_{subdomain_name}", or 00492 // "{zone_title()}_{subdomain_id}", or 00493 // "{zone_title()}" 00494 if (subdomain_name.size()) 00495 { 00496 zone_name << "_"; 00497 zone_name << subdomain_name; 00498 } 00499 else if (_subdomain_ids.size() > 1) 00500 { 00501 zone_name << "_"; 00502 zone_name << *sbd_it; 00503 } 00504 00505 ierr = TECZNE112 ((char*) zone_name.str().c_str(), 00506 &cell_type, 00507 &num_nodes, 00508 &num_cells, 00509 &num_faces, 00510 &i_cell_max, 00511 &j_cell_max, 00512 &k_cell_max, 00513 &_time, 00514 &strand_id, 00515 &parent_zone, 00516 &is_block, 00517 &num_face_connect, 00518 &face_neighbor_mode, 00519 &tot_num_face_nodes, 00520 &num_connect_boundary_faces, 00521 &tot_num_boundary_connect, 00522 &passive_var_list[0], 00523 NULL, // = all are node centered 00524 (firstzone) ? NULL : &share_var_from_zone[0], 00525 &share_connect_from_zone); 00526 00527 libmesh_assert_equal_to (ierr, 0); 00528 00529 // Write *all* the data for the first zone, then share it with the others 00530 if (firstzone) 00531 { 00532 int total = 00533 #ifdef LIBMESH_USE_REAL_NUMBERS 00534 ((3 + ((solution_names == NULL) ? 0 : solution_names->size()))*num_nodes); 00535 #else 00536 ((3 + 3*((solution_names == NULL) ? 0 : solution_names->size()))*num_nodes); 00537 #endif 00538 00539 00540 ierr = TECDAT112 (&total, 00541 &tm.nodalData[0], 00542 &is_double); 00543 00544 libmesh_assert_equal_to (ierr, 0); 00545 } 00546 00547 // Write the connectivity 00548 ierr = TECNOD112 (&tm.connData[0]); 00549 00550 libmesh_assert_equal_to (ierr, 0); 00551 } 00552 00553 firstzone = false; 00554 } 00555 00556 // Done, close the file. 00557 ierr = TECEND112 (); 00558 00559 libmesh_assert_equal_to (ierr, 0); 00560 00561 00562 00563 00564 //------------------------------------------------------------ 00565 // Legacy binary format 00566 #else 00567 00568 // Get a constant reference to the mesh. 00569 const MeshBase& the_mesh = MeshOutput<MeshBase>::mesh(); 00570 00571 // Tecplot binary output only good for dim=2,3 00572 if (the_mesh.mesh_dimension() == 1) 00573 { 00574 this->write_ascii (fname, vec, solution_names); 00575 00576 return; 00577 } 00578 00579 // Required variables 00580 std::string tecplot_variable_names; 00581 int is_double = 0, 00582 tec_debug = 0, 00583 cell_type = ((the_mesh.mesh_dimension()==2) ? (1) : (3)); 00584 00585 // Build a string containing all the variable names to pass to Tecplot 00586 { 00587 tecplot_variable_names += "x, y, z"; 00588 00589 if (solution_names != NULL) 00590 { 00591 for (unsigned int name=0; name<solution_names->size(); name++) 00592 { 00593 #ifdef LIBMESH_USE_REAL_NUMBERS 00594 00595 tecplot_variable_names += ", "; 00596 tecplot_variable_names += (*solution_names)[name]; 00597 00598 #else 00599 00600 tecplot_variable_names += ", "; 00601 tecplot_variable_names += "r_"; 00602 tecplot_variable_names += (*solution_names)[name]; 00603 tecplot_variable_names += ", "; 00604 tecplot_variable_names += "i_"; 00605 tecplot_variable_names += (*solution_names)[name]; 00606 tecplot_variable_names += ", "; 00607 tecplot_variable_names += "a_"; 00608 tecplot_variable_names += (*solution_names)[name]; 00609 00610 #endif 00611 } 00612 } 00613 } 00614 00615 // Instantiate a TecplotMacros interface. In 2D the most nodes per 00616 // face should be 4, in 3D it's 8. 00617 00618 00619 TecplotMacros tm(the_mesh.n_nodes(), 00620 #ifdef LIBMESH_USE_REAL_NUMBERS 00621 (3 + ((solution_names == NULL) ? 0 : solution_names->size())), 00622 #else 00623 (3 + 3*((solution_names == NULL) ? 0 : solution_names->size())), 00624 #endif 00625 the_mesh.n_active_sub_elem(), 00626 ((the_mesh.mesh_dimension() == 2) ? 4 : 8) 00627 ); 00628 00629 00630 // Copy the nodes and data to the TecplotMacros class. Note that we store 00631 // everything as a float here since the eye doesn't require a double to 00632 // understand what is going on 00633 for (unsigned int v=0; v<the_mesh.n_nodes(); v++) 00634 { 00635 tm.nd(0,v) = static_cast<float>(the_mesh.point(v)(0)); 00636 tm.nd(1,v) = static_cast<float>(the_mesh.point(v)(1)); 00637 tm.nd(2,v) = static_cast<float>(the_mesh.point(v)(2)); 00638 00639 if ((vec != NULL) && 00640 (solution_names != NULL)) 00641 { 00642 const unsigned int n_vars = solution_names->size(); 00643 00644 for (unsigned int c=0; c<n_vars; c++) 00645 { 00646 #ifdef LIBMESH_USE_REAL_NUMBERS 00647 00648 tm.nd((3+c),v) = static_cast<float>((*vec)[v*n_vars + c]); 00649 #else 00650 tm.nd((3+3*c),v) = static_cast<float>((*vec)[v*n_vars + c].real()); 00651 tm.nd((3+3*c+1),v) = static_cast<float>((*vec)[v*n_vars + c].imag()); 00652 tm.nd((3+3*c+2),v) = static_cast<float>(std::abs((*vec)[v*n_vars + c])); 00653 #endif 00654 } 00655 } 00656 } 00657 00658 00659 // Copy the connectivity 00660 { 00661 unsigned int te = 0; 00662 00663 MeshBase::const_element_iterator it = the_mesh.active_elements_begin(); 00664 const MeshBase::const_element_iterator end = the_mesh.active_elements_end(); 00665 00666 for ( ; it != end; ++it) 00667 { 00668 std::vector<dof_id_type> conn; 00669 for (unsigned int se=0; se<(*it)->n_sub_elem(); se++) 00670 { 00671 (*it)->connectivity(se, TECPLOT, conn); 00672 00673 for (unsigned int node=0; node<conn.size(); node++) 00674 tm.cd(node,te) = conn[node]; 00675 00676 te++; 00677 } 00678 } 00679 } 00680 00681 00682 // Ready to call the Tecplot API 00683 { 00684 int ierr = 0, 00685 num_nodes = static_cast<int>(the_mesh.n_nodes()), 00686 num_cells = static_cast<int>(the_mesh.n_active_sub_elem()); 00687 00688 00689 ierr = TECINI (NULL, 00690 (char*) tecplot_variable_names.c_str(), 00691 (char*) fname.c_str(), 00692 (char*) ".", 00693 &tec_debug, 00694 &is_double); 00695 00696 libmesh_assert_equal_to (ierr, 0); 00697 00698 ierr = TECZNE (NULL, 00699 &num_nodes, 00700 &num_cells, 00701 &cell_type, 00702 (char*) "FEBLOCK", 00703 NULL); 00704 00705 libmesh_assert_equal_to (ierr, 0); 00706 00707 00708 int total = 00709 #ifdef LIBMESH_USE_REAL_NUMBERS 00710 ((3 + ((solution_names == NULL) ? 0 : solution_names->size()))*num_nodes); 00711 #else 00712 ((3 + 3*((solution_names == NULL) ? 0 : solution_names->size()))*num_nodes); 00713 #endif 00714 00715 00716 ierr = TECDAT (&total, 00717 &tm.nodalData[0], 00718 &is_double); 00719 00720 libmesh_assert_equal_to (ierr, 0); 00721 00722 ierr = TECNOD (&tm.connData[0]); 00723 00724 libmesh_assert_equal_to (ierr, 0); 00725 00726 ierr = TECEND (); 00727 00728 libmesh_assert_equal_to (ierr, 0); 00729 } 00730 00731 #endif 00732 } 00733 00734 } // namespace libMesh 00735
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:49 UTC
Hosted By: