$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 #include "libmesh/checkpoint_io.h" 00019 00020 // C++ includes 00021 #include <iostream> 00022 #include <iomanip> 00023 #include <cstdio> 00024 #include <vector> 00025 #include <string> 00026 #include <fstream> 00027 #include <sstream> // for ostringstream 00028 00029 // Local includes 00030 #include "libmesh/xdr_io.h" 00031 #include "libmesh/legacy_xdr_io.h" 00032 #include "libmesh/xdr_cxx.h" 00033 #include "libmesh/enum_xdr_mode.h" 00034 #include "libmesh/mesh_base.h" 00035 #include "libmesh/node.h" 00036 #include "libmesh/elem.h" 00037 #include "libmesh/boundary_info.h" 00038 #include "libmesh/parallel.h" 00039 #include "libmesh/mesh_tools.h" 00040 #include "libmesh/partitioner.h" 00041 #include "libmesh/libmesh_logging.h" 00042 #include "libmesh/mesh_communication.h" 00043 #include "libmesh/parallel_mesh.h" 00044 00045 namespace libMesh 00046 { 00047 00048 // ------------------------------------------------------------ 00049 // CheckpointIO members 00050 CheckpointIO::CheckpointIO (MeshBase& mesh, const bool binary_in) : 00051 MeshInput<MeshBase> (mesh,/* is_parallel_format = */ true), 00052 MeshOutput<MeshBase>(mesh,/* is_parallel_format = */ true), 00053 ParallelObject (mesh), 00054 _binary (binary_in), 00055 _version ("checkpoint-1.0") 00056 { 00057 } 00058 00059 00060 00061 CheckpointIO::CheckpointIO (const MeshBase& mesh, const bool binary_in) : 00062 MeshOutput<MeshBase>(mesh,/* is_parallel_format = */ true), 00063 ParallelObject (mesh), 00064 _binary (binary_in) 00065 { 00066 } 00067 00068 00069 00070 CheckpointIO::~CheckpointIO () 00071 { 00072 } 00073 00074 00075 00076 00077 void CheckpointIO::write (const std::string& name) 00078 { 00079 START_LOG("write()","CheckpointIO"); 00080 00081 // convenient reference to our mesh 00082 const MeshBase &mesh = MeshOutput<MeshBase>::mesh(); 00083 00084 // Try to dynamic cast the mesh to see if it's a ParallelMesh object 00085 // Note: Just using is_serial() is not good enough because the Mesh won't 00086 // have been prepared yet when is when that flag gets set to false... sigh. 00087 bool parallel_mesh = dynamic_cast<const ParallelMesh*>(&mesh); 00088 00089 // If this is a serial mesh then we're only going to write it on processor 0 00090 if(parallel_mesh || this->processor_id() == 0) 00091 { 00092 std::ostringstream file_name_stream; 00093 00094 file_name_stream << name; 00095 00096 if(parallel_mesh) 00097 file_name_stream << "-" << this->processor_id(); 00098 00099 Xdr io (file_name_stream.str(), this->binary() ? ENCODE : WRITE); 00100 00101 // write the version 00102 io.data(_version, "# version"); 00103 00104 // Write out whether or not this is a serial mesh (helps with error checking on read) 00105 { 00106 unsigned int parallel = parallel_mesh; 00107 io.data(parallel, "# parallel"); 00108 } 00109 00110 // If we're writing out a parallel mesh then we need to write the number of processors 00111 // so we can check it upon reading the file 00112 if(parallel_mesh) 00113 { 00114 largest_id_type n_procs = this->n_processors(); 00115 io.data(n_procs, "# n_procs"); 00116 } 00117 00118 // write subdomain names 00119 this->write_subdomain_names(io); 00120 00121 // write the nodal locations 00122 this->write_nodes (io); 00123 00124 // write connectivity 00125 this->write_connectivity (io); 00126 00127 // write the boundary condition information 00128 this->write_bcs (io); 00129 00130 // write the nodeset information 00131 this->write_nodesets (io); 00132 00133 // pause all processes until the writing ends -- this will 00134 // protect for the pathological case where a write is 00135 // followed immediately by a read. The write must be 00136 // guaranteed to complete first. 00137 io.close(); 00138 } 00139 00140 this->comm().barrier(); 00141 00142 STOP_LOG("write()","CheckpointIO"); 00143 } 00144 00145 00146 00147 void CheckpointIO::write_subdomain_names(Xdr &io) const 00148 { 00149 { 00150 const MeshBase &mesh = MeshOutput<MeshBase>::mesh(); 00151 00152 const std::map<subdomain_id_type, std::string> & subdomain_map = mesh.get_subdomain_name_map(); 00153 00154 std::vector<header_id_type> subdomain_ids; subdomain_ids.reserve(subdomain_map.size()); 00155 std::vector<std::string> subdomain_names; subdomain_names.reserve(subdomain_map.size()); 00156 00157 // We need to loop over the map and make sure that there aren't any invalid entries. Since we 00158 // return writable references in mesh_base, it's possible for the user to leave some entity names 00159 // blank. We can't write those to the XDA file. 00160 header_id_type n_subdomain_names = 0; 00161 std::map<subdomain_id_type, std::string>::const_iterator it_end = subdomain_map.end(); 00162 for (std::map<subdomain_id_type, std::string>::const_iterator it = subdomain_map.begin(); it != it_end; ++it) 00163 { 00164 if (!it->second.empty()) 00165 { 00166 n_subdomain_names++; 00167 subdomain_ids.push_back(it->first); 00168 subdomain_names.push_back(it->second); 00169 } 00170 } 00171 00172 io.data(n_subdomain_names, "# subdomain id to name map"); 00173 // Write out the ids and names in two vectors 00174 if (n_subdomain_names) 00175 { 00176 io.data(subdomain_ids); 00177 io.data(subdomain_names); 00178 } 00179 } 00180 } 00181 00182 00183 00184 void CheckpointIO::write_nodes (Xdr &io) const 00185 { 00186 // convenient reference to our mesh 00187 const MeshBase &mesh = MeshOutput<MeshBase>::mesh(); 00188 00189 MeshBase::const_node_iterator 00190 it = mesh.nodes_begin(), 00191 end = mesh.nodes_end(); 00192 00193 unsigned int n_nodes_here = MeshTools::n_nodes(it, end); 00194 00195 io.data(n_nodes_here, "# n_nodes on proc"); 00196 00197 it = mesh.nodes_begin(); 00198 00199 // Will hold the node id and pid 00200 std::vector<largest_id_type> id_pid(2); 00201 00202 // For the coordinates 00203 std::vector<Real> coords(LIBMESH_DIM); 00204 00205 for(; it != end; ++it) 00206 { 00207 Node & node = *(*it); 00208 00209 id_pid[0] = node.id(); 00210 id_pid[1] = node.processor_id(); 00211 00212 io.data_stream(&id_pid[0], 2, 2); 00213 00214 #ifdef LIBMESH_ENABLE_UNIQUE_ID 00215 largest_id_type unique_id = node.unique_id(); 00216 00217 io.data(unique_id, "# unique id"); 00218 #endif 00219 00220 coords[0] = node(0); 00221 00222 #if LIBMESH_DIM > 1 00223 coords[1] = node(1); 00224 #endif 00225 00226 #if LIBMESH_DIM > 2 00227 coords[2] = node(2); 00228 #endif 00229 00230 io.data_stream(&coords[0], LIBMESH_DIM, 3); 00231 } 00232 } 00233 00234 00235 00236 void CheckpointIO::write_connectivity (Xdr &io) const 00237 { 00238 libmesh_assert (io.writing()); 00239 00240 // convenient reference to our mesh 00241 const MeshBase &mesh = MeshOutput<MeshBase>::mesh(); 00242 00243 // We will only write active elements and their parents. 00244 unsigned int n_active_levels = n_active_levels_on_processor(mesh); 00245 00246 std::vector<xdr_id_type> n_elem_at_level(n_active_levels); 00247 00248 // Find the number of elements at each level 00249 for (unsigned int level=0; level<n_active_levels; level++) 00250 { 00251 MeshBase::const_element_iterator it = mesh.level_elements_begin(level); 00252 MeshBase::const_element_iterator end = mesh.level_elements_end(level); 00253 00254 n_elem_at_level[level] = MeshTools::n_elem(it, end); 00255 } 00256 00257 io.data(n_active_levels, "# n_active_levels"); 00258 00259 for(unsigned int level=0; level < n_active_levels; level++) 00260 { 00261 std::ostringstream comment; 00262 comment << "# n_elem at level "; 00263 comment << level ; 00264 io.data (n_elem_at_level[level], comment.str().c_str()); 00265 00266 MeshBase::const_element_iterator it = mesh.level_elements_begin(level); 00267 MeshBase::const_element_iterator end = mesh.level_elements_end(level); 00268 for (; it != end; ++it) 00269 { 00270 Elem & elem = *(*it); 00271 00272 unsigned int n_nodes = elem.n_nodes(); 00273 00274 // id type pid subdomain_id parent_id 00275 std::vector<largest_id_type> elem_data(5); 00276 00277 elem_data[0] = elem.id(); 00278 elem_data[1] = elem.type(); 00279 elem_data[2] = elem.processor_id(); 00280 elem_data[3] = elem.subdomain_id(); 00281 00282 if(elem.parent() != NULL) 00283 elem_data[4] = elem.parent()->id(); 00284 else 00285 elem_data[4] = DofObject::invalid_processor_id; 00286 00287 std::vector<largest_id_type> conn_data(n_nodes); 00288 00289 for(unsigned int i=0; i<n_nodes; i++) 00290 conn_data[i] = elem.node(i); 00291 00292 io.data_stream(&elem_data[0], 00293 cast_int<unsigned int>(elem_data.size()), 00294 cast_int<unsigned int>(elem_data.size())); 00295 00296 #ifdef LIBMESH_ENABLE_UNIQUE_ID 00297 largest_id_type unique_id = elem.unique_id(); 00298 00299 io.data(unique_id, "# unique id"); 00300 #endif 00301 00302 #ifdef LIBMESH_ENABLE_AMR 00303 unsigned int p_level = elem.p_level(); 00304 00305 io.data(p_level, "# p_level"); 00306 #endif 00307 00308 io.data_stream(&conn_data[0], 00309 cast_int<unsigned int>(conn_data.size()), 00310 cast_int<unsigned int>(conn_data.size())); 00311 } 00312 } 00313 } 00314 00315 00316 00317 void CheckpointIO::write_bcs (Xdr &io) const 00318 { 00319 libmesh_assert (io.writing()); 00320 00321 // convenient reference to our mesh 00322 const MeshBase &mesh = MeshOutput<MeshBase>::mesh(); 00323 00324 // and our boundary info object 00325 const BoundaryInfo &boundary_info = mesh.get_boundary_info(); 00326 00327 // Version 0.9.2+ introduces entity names 00328 write_bc_names(io, boundary_info, true); // sideset names 00329 write_bc_names(io, boundary_info, false); // nodeset names 00330 00331 std::vector<dof_id_type> element_id_list; 00332 std::vector<unsigned short int> side_list; 00333 std::vector<boundary_id_type> bc_id_list; 00334 00335 boundary_info.build_side_list(element_id_list, side_list, bc_id_list); 00336 00337 io.data(element_id_list, "# element ids for bcs"); 00338 io.data(side_list, "# sides of elements for bcs"); 00339 io.data(bc_id_list, "# bc ids"); 00340 } 00341 00342 00343 00344 void CheckpointIO::write_nodesets (Xdr &io) const 00345 { 00346 libmesh_assert (io.writing()); 00347 00348 // convenient reference to our mesh 00349 const MeshBase &mesh = MeshOutput<MeshBase>::mesh(); 00350 00351 // and our boundary info object 00352 const BoundaryInfo &boundary_info = mesh.get_boundary_info(); 00353 00354 std::vector<dof_id_type> node_id_list; 00355 std::vector<boundary_id_type> bc_id_list; 00356 00357 boundary_info.build_node_list(node_id_list, bc_id_list); 00358 00359 io.data(node_id_list, "# node id list"); 00360 io.data(bc_id_list, "# nodeset bc id list"); 00361 } 00362 00363 00364 00365 void CheckpointIO::write_bc_names (Xdr &io, const BoundaryInfo & info, bool is_sideset) const 00366 { 00367 const std::map<boundary_id_type, std::string> & boundary_map = is_sideset ? 00368 info.get_sideset_name_map() : info.get_nodeset_name_map(); 00369 00370 std::vector<boundary_id_type> boundary_ids; boundary_ids.reserve(boundary_map.size()); 00371 std::vector<std::string> boundary_names; boundary_names.reserve(boundary_map.size()); 00372 00373 // We need to loop over the map and make sure that there aren't any invalid entries. Since we 00374 // return writable references in boundary_info, it's possible for the user to leave some entity names 00375 // blank. We can't write those to the XDA file. 00376 header_id_type n_boundary_names = 0; 00377 std::map<boundary_id_type, std::string>::const_iterator it_end = boundary_map.end(); 00378 for (std::map<boundary_id_type, std::string>::const_iterator it = boundary_map.begin(); it != it_end; ++it) 00379 { 00380 if (!it->second.empty()) 00381 { 00382 n_boundary_names++; 00383 boundary_ids.push_back(it->first); 00384 boundary_names.push_back(it->second); 00385 } 00386 } 00387 00388 if (is_sideset) 00389 io.data(n_boundary_names, "# sideset id to name map"); 00390 else 00391 io.data(n_boundary_names, "# nodeset id to name map"); 00392 // Write out the ids and names in two vectors 00393 if (n_boundary_names) 00394 { 00395 io.data(boundary_ids); 00396 io.data(boundary_names); 00397 } 00398 } 00399 00400 00401 00402 void CheckpointIO::read (const std::string& name) 00403 { 00404 START_LOG("read()","CheckpointIO"); 00405 00406 MeshBase &mesh = MeshInput<MeshBase>::mesh(); 00407 00408 // Try to dynamic cast the mesh to see if it's a ParallelMesh object 00409 // Note: Just using is_serial() is not good enough because the Mesh won't 00410 // have been prepared yet when is when that flag gets set to false... sigh. 00411 bool parallel_mesh = dynamic_cast<ParallelMesh*>(&mesh); 00412 00413 // If this is a serial mesh then we're going to only read it on processor 0 and broadcast it 00414 if(parallel_mesh || this->processor_id() == 0) 00415 { 00416 std::ostringstream file_name_stream; 00417 00418 file_name_stream << name; 00419 00420 if(parallel_mesh) 00421 file_name_stream << "-" << this->processor_id(); 00422 00423 { 00424 std::ifstream in (file_name_stream.str().c_str()); 00425 00426 if (!in.good()) 00427 libmesh_error_msg("ERROR: cannot locate specified file:\n\t" << file_name_stream.str()); 00428 } 00429 00430 Xdr io (file_name_stream.str(), this->binary() ? DECODE : READ); 00431 00432 // read the version 00433 io.data (_version); 00434 00435 // Check if the mesh we're reading is the same as the one that was written 00436 { 00437 unsigned int parallel; 00438 io.data(parallel, "# parallel"); 00439 00440 if(static_cast<unsigned int>(parallel_mesh) != parallel) 00441 libmesh_error_msg("Attempted to utilize a checkpoint file with an incompatible mesh distribution!"); 00442 } 00443 00444 // If this is a parallel mesh then we need to check to ensure we're reading this on the same number of procs 00445 if(parallel_mesh) 00446 { 00447 largest_id_type n_procs; 00448 io.data(n_procs, "# n_procs"); 00449 00450 if(n_procs != this->n_processors()) 00451 libmesh_error_msg("Attempted to utilize a checkpoint file on " << this->n_processors() << " processors but it was written using " << n_procs << "!!"); 00452 } 00453 00454 // read subdomain names 00455 this->read_subdomain_names(io); 00456 00457 // read the nodal locations 00458 this->read_nodes (io); 00459 00460 // read connectivity 00461 this->read_connectivity (io); 00462 00463 // read the boundary conditions 00464 this->read_bcs (io); 00465 00466 // read the nodesets 00467 this->read_nodesets (io); 00468 00469 io.close(); 00470 } 00471 00472 // If the mesh is serial then we only read it on processor 0 so we need to broadcast it 00473 if(!parallel_mesh) 00474 MeshCommunication().broadcast(mesh); 00475 00476 STOP_LOG("read()","CheckpointIO"); 00477 } 00478 00479 00480 00481 void CheckpointIO::read_subdomain_names(Xdr &io) 00482 { 00483 MeshBase &mesh = MeshInput<MeshBase>::mesh(); 00484 00485 std::map<subdomain_id_type, std::string> & subdomain_map = 00486 mesh.set_subdomain_name_map(); 00487 00488 std::vector<header_id_type> subdomain_ids; 00489 subdomain_ids.reserve(subdomain_map.size()); 00490 00491 std::vector<std::string> subdomain_names; 00492 subdomain_names.reserve(subdomain_map.size()); 00493 00494 header_id_type n_subdomain_names = 0; 00495 io.data(n_subdomain_names, "# subdomain id to name map"); 00496 00497 if(n_subdomain_names) 00498 { 00499 io.data(subdomain_ids); 00500 io.data(subdomain_names); 00501 00502 for(unsigned int i=0; i<subdomain_ids.size(); i++) 00503 subdomain_map[cast_int<subdomain_id_type>(subdomain_ids[i])] = 00504 subdomain_names[i]; 00505 } 00506 } 00507 00508 00509 00510 void CheckpointIO::read_nodes (Xdr &io) 00511 { 00512 // convenient reference to our mesh 00513 MeshBase &mesh = MeshInput<MeshBase>::mesh(); 00514 00515 unsigned int n_nodes_here; 00516 io.data(n_nodes_here, "# n_nodes on proc"); 00517 00518 // Will hold the node id and pid 00519 std::vector<largest_id_type> id_pid(2); 00520 00521 // For the coordinates 00522 std::vector<Real> coords(LIBMESH_DIM); 00523 00524 for(unsigned int i=0; i<n_nodes_here; i++) 00525 { 00526 io.data_stream(&id_pid[0], 2, 2); 00527 00528 #ifdef LIBMESH_ENABLE_UNIQUE_ID 00529 largest_id_type unique_id = 0; 00530 io.data(unique_id, "# unique id"); 00531 #endif 00532 00533 io.data_stream(&coords[0], LIBMESH_DIM, LIBMESH_DIM); 00534 00535 Point p; 00536 p(0) = coords[0]; 00537 00538 #if LIBMESH_DIM > 1 00539 p(1) = coords[1]; 00540 #endif 00541 00542 #if LIBMESH_DIM > 2 00543 p(2) = coords[2]; 00544 #endif 00545 00546 #ifdef LIBMESH_ENABLE_UNIQUE_ID 00547 Node * node = 00548 #endif 00549 mesh.add_point(p, cast_int<dof_id_type>(id_pid[0]), 00550 cast_int<processor_id_type>(id_pid[1])); 00551 00552 #ifdef LIBMESH_ENABLE_UNIQUE_ID 00553 node->set_unique_id() = unique_id; 00554 #endif 00555 } 00556 } 00557 00558 00559 00560 void CheckpointIO::read_connectivity (Xdr &io) 00561 { 00562 // convenient reference to our mesh 00563 MeshBase &mesh = MeshInput<MeshBase>::mesh(); 00564 00565 unsigned int n_active_levels; 00566 io.data(n_active_levels, "# n_active_levels"); 00567 00568 // Keep track of the highest dimensional element we've added to the mesh 00569 unsigned int highest_elem_dim = 1; 00570 00571 for(unsigned int level=0; level < n_active_levels; level++) 00572 { 00573 xdr_id_type n_elem_at_level = 0; 00574 io.data (n_elem_at_level, ""); 00575 00576 for (unsigned int i=0; i<n_elem_at_level; i++) 00577 { 00578 // id type pid subdomain_id parent_id 00579 std::vector<largest_id_type> elem_data(5); 00580 io.data_stream 00581 (&elem_data[0], cast_int<unsigned int>(elem_data.size()), 00582 cast_int<unsigned int>(elem_data.size())); 00583 00584 #ifdef LIBMESH_ENABLE_UNIQUE_ID 00585 largest_id_type unique_id = 0; 00586 io.data(unique_id, "# unique id"); 00587 #endif 00588 00589 #ifdef LIBMESH_ENABLE_AMR 00590 unsigned int p_level = 0; 00591 00592 io.data(p_level, "# p_level"); 00593 #endif 00594 00595 unsigned int n_nodes = Elem::type_to_n_nodes_map[elem_data[1]]; 00596 00597 // Snag the node ids this element was connected to 00598 std::vector<largest_id_type> conn_data(n_nodes); 00599 io.data_stream 00600 (&conn_data[0], cast_int<unsigned int>(conn_data.size()), 00601 cast_int<unsigned int>(conn_data.size())); 00602 00603 const dof_id_type id = 00604 cast_int<dof_id_type> (elem_data[0]); 00605 const ElemType elem_type = 00606 static_cast<ElemType> (elem_data[1]); 00607 const processor_id_type proc_id = 00608 cast_int<processor_id_type>(elem_data[2]); 00609 const subdomain_id_type subdomain_id = 00610 cast_int<subdomain_id_type>(elem_data[3]); 00611 const dof_id_type parent_id = 00612 cast_int<dof_id_type> (elem_data[4]); 00613 00614 Elem * parent = (parent_id == DofObject::invalid_processor_id) ? NULL : mesh.elem(parent_id); 00615 00616 // Create the element 00617 Elem * elem = Elem::build(elem_type, parent).release(); 00618 00619 #ifdef LIBMESH_ENABLE_UNIQUE_ID 00620 elem->set_unique_id() = unique_id; 00621 #endif 00622 00623 if(elem->dim() > highest_elem_dim) 00624 highest_elem_dim = elem->dim(); 00625 00626 elem->set_id() = id; 00627 elem->processor_id() = proc_id; 00628 elem->subdomain_id() = subdomain_id; 00629 00630 #ifdef LIBMESH_ENABLE_AMR 00631 elem->hack_p_level(p_level); 00632 00633 // Set parent connections 00634 if(parent) 00635 { 00636 parent->add_child(elem); 00637 parent->set_refinement_flag (Elem::INACTIVE); 00638 elem->set_refinement_flag (Elem::JUST_REFINED); 00639 } 00640 #endif 00641 00642 libmesh_assert(elem->n_nodes() == conn_data.size()); 00643 00644 // Connect all the nodes to this element 00645 for (unsigned int n=0; n<conn_data.size(); n++) 00646 elem->set_node(n) = 00647 mesh.node_ptr(cast_int<dof_id_type>(conn_data[n])); 00648 00649 mesh.add_elem(elem); 00650 } 00651 } 00652 00653 mesh.set_mesh_dimension(cast_int<unsigned char>(highest_elem_dim)); 00654 } 00655 00656 00657 00658 void CheckpointIO::read_bcs (Xdr &io) 00659 { 00660 // convenient reference to our mesh 00661 MeshBase &mesh = MeshInput<MeshBase>::mesh(); 00662 00663 // and our boundary info object 00664 BoundaryInfo &boundary_info = mesh.get_boundary_info(); 00665 00666 // Version 0.9.2+ introduces entity names 00667 read_bc_names(io, boundary_info, true); // sideset names 00668 read_bc_names(io, boundary_info, false); // nodeset names 00669 00670 std::vector<dof_id_type> element_id_list; 00671 std::vector<unsigned short int> side_list; 00672 std::vector<boundary_id_type> bc_id_list; 00673 00674 io.data(element_id_list, "# element ids for bcs"); 00675 io.data(side_list, "# sides of elements for bcs"); 00676 io.data(bc_id_list, "# bc ids"); 00677 00678 for(unsigned int i=0; i<element_id_list.size(); i++) 00679 boundary_info.add_side(element_id_list[i], side_list[i], bc_id_list[i]); 00680 } 00681 00682 00683 00684 void CheckpointIO::read_nodesets (Xdr &io) 00685 { 00686 // convenient reference to our mesh 00687 MeshBase &mesh = MeshInput<MeshBase>::mesh(); 00688 00689 // and our boundary info object 00690 BoundaryInfo &boundary_info = mesh.get_boundary_info(); 00691 00692 std::vector<dof_id_type> node_id_list; 00693 std::vector<boundary_id_type> bc_id_list; 00694 00695 io.data(node_id_list, "# node id list"); 00696 io.data(bc_id_list, "# nodeset bc id list"); 00697 00698 for(unsigned int i=0; i<node_id_list.size(); i++) 00699 boundary_info.add_node(node_id_list[i], bc_id_list[i]); 00700 } 00701 00702 00703 00704 void CheckpointIO::read_bc_names(Xdr &io, BoundaryInfo & info, bool is_sideset) 00705 { 00706 std::map<boundary_id_type, std::string> & boundary_map = is_sideset ? 00707 info.set_sideset_name_map() : info.set_nodeset_name_map(); 00708 00709 std::vector<boundary_id_type> boundary_ids; 00710 std::vector<std::string> boundary_names; 00711 00712 header_id_type n_boundary_names = 0; 00713 00714 if (is_sideset) 00715 io.data(n_boundary_names, "# sideset id to name map"); 00716 else 00717 io.data(n_boundary_names, "# nodeset id to name map"); 00718 00719 if (n_boundary_names) 00720 { 00721 io.data(boundary_ids); 00722 io.data(boundary_names); 00723 } 00724 00725 // Add them back into the map 00726 for(unsigned int i=0; i<boundary_ids.size(); i++) 00727 boundary_map[boundary_ids[i]] = boundary_names[i]; 00728 } 00729 00730 00731 unsigned int CheckpointIO::n_active_levels_on_processor(const MeshBase &mesh) const 00732 { 00733 unsigned int max_level = 0; 00734 00735 MeshBase::const_element_iterator el = mesh.active_elements_begin(); 00736 const MeshBase::const_element_iterator end_el = mesh.active_elements_end(); 00737 00738 for( ; el != end_el; ++el) 00739 max_level = std::max((*el)->level(), max_level); 00740 00741 return max_level + 1; 00742 } 00743 00744 } // namespace libMesh