$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 00019 00020 // C++ includes 00021 #include <fstream> 00022 00023 // Local includes 00024 #include "libmesh/mesh_data.h" 00025 #include "libmesh/mesh_base.h" 00026 #include "libmesh/xdr_cxx.h" 00027 #include "libmesh/elem.h" 00028 00029 namespace libMesh 00030 { 00031 00032 00033 //------------------------------------------------------ 00034 // MeshData functions 00035 void MeshData::read_xdr (const std::string& name, 00036 const XdrMODE mode) 00037 { 00077 // we should better be active or in compatibility mode 00078 libmesh_assert (_active || _compatibility_mode); 00079 00080 00081 // make sure the id maps are ready 00082 libmesh_assert (_node_id_map_closed); 00083 libmesh_assert (_elem_id_map_closed); 00084 00085 00089 this->clear(); 00090 00091 00092 Xdr io(name, mode); 00093 00094 00095 /* 00096 * all processors read the data in the same format, 00097 * but only the processor that owns the element stores 00098 * element-associated data. For nodes, i haven't come 00099 * up with such asmart idea, yet... :-P 00100 */ 00101 const unsigned int proc_id = _mesh.processor_id(); 00102 00103 00104 00110 { 00111 std::string desc = ""; 00112 io.data (desc); 00113 this->_data_descriptor = desc; 00114 } 00115 00116 00117 00123 { 00124 std::string vtype=""; 00125 io.data (vtype); 00126 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 00127 if (vtype != "COMPLEX") 00128 libmesh_error_msg("ERROR: File does not contain complex-valued data!"); 00129 00130 #elif LIBMESH_USE_REAL_NUMBERS 00131 if (vtype != "REAL") 00132 libmesh_error_msg("ERROR: File does not contain real-valued data!"); 00133 00134 #else 00135 /* 00136 * What number type is this? 00137 */ 00138 libmesh_error_msg("Must be using either real or complex numbers!"); 00139 #endif 00140 } 00141 00142 00143 00149 unsigned int n_node = 0; 00150 io.data (n_node); 00151 00152 00158 unsigned int n_elem = 0; 00159 io.data (n_elem); 00160 00161 #ifdef DEBUG 00162 std::size_t previous_values_size = 0; 00163 #endif 00164 00165 for (unsigned int n_cnt=0; n_cnt < n_node; n_cnt++) 00166 { 00173 unsigned int f_id = 0; 00174 io.data (f_id); 00175 00176 const Node* node = foreign_id_to_node(f_id); 00177 00178 00185 { 00186 std::vector<Number> values; 00187 io.data (values); 00188 00189 00190 #ifdef DEBUG 00191 /* 00192 * make sure the size of the values vectors 00193 * are identical for all nodes 00194 */ 00195 if (n_cnt == 0) 00196 previous_values_size = values.size(); 00197 else 00198 { 00199 if (previous_values_size != values.size()) 00200 libmesh_error_msg("ERROR: Size mismatch for n_cnt = " << n_cnt); 00201 } 00202 #endif 00203 00204 00208 _node_data.insert (std::make_pair(node, values)); 00209 } 00210 } 00211 00212 00213 00214 #ifdef DEBUG 00215 previous_values_size = 0; 00216 #endif 00217 00218 for (unsigned int n_cnt=0; n_cnt < n_elem; n_cnt++) 00219 { 00225 unsigned int f_id = 0; 00226 io.data (f_id); 00227 00228 const Elem* elem = foreign_id_to_elem(f_id); 00229 00230 00237 { 00238 std::vector<Number> values; 00239 io.data (values); 00240 00241 00242 #ifdef DEBUG 00243 /* 00244 * make sure the size of the values vectors 00245 * are identical for all elements 00246 */ 00247 if (n_cnt == 0) 00248 previous_values_size = values.size(); 00249 else 00250 { 00251 if (previous_values_size != values.size()) 00252 libmesh_error_msg("ERROR: Size mismatch for n_cnt = " << n_cnt); 00253 } 00254 #endif 00255 00256 00261 if (elem->processor_id() == proc_id) 00262 _elem_data.insert (std::make_pair(elem, values)); 00263 } 00264 } 00265 00266 00267 /* 00268 * finished reading. Now ready for use, provided 00269 * there was any data contained in the file. 00270 */ 00271 libmesh_assert ((this->_node_data.size() != 0) || (this->_elem_data.size() != 0)); 00272 00273 this->_node_data_closed = true; 00274 this->_elem_data_closed = true; 00275 } 00276 00277 00278 00279 00280 00281 00282 void MeshData::write_xdr (const std::string& name, 00283 const XdrMODE mode) 00284 { 00323 /* 00324 * make sure the id maps are ready 00325 * and that we have data to write 00326 */ 00327 libmesh_assert (_node_id_map_closed); 00328 libmesh_assert (_elem_id_map_closed); 00329 00330 libmesh_assert (_node_data_closed); 00331 libmesh_assert (_elem_data_closed); 00332 00333 00334 Xdr io(name, mode); 00335 00336 00337 // all processors write the data in the same format 00338 //const unsigned int proc_id = _mesh.processor_id(); 00339 00345 { 00346 std::string desc = this->_data_descriptor; 00347 io.data (desc, "# Data description"); 00348 } 00349 00350 00351 00357 { 00358 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 00359 std::string desc = "COMPLEX"; 00360 #elif LIBMESH_USE_REAL_NUMBERS 00361 std::string desc = "REAL"; 00362 #else 00363 better_you_choke_this... 00364 #endif 00365 io.data (desc, "# type of values"); 00366 } 00367 00368 00369 00375 { 00376 unsigned int n_node = 00377 cast_int<unsigned int>(this->_node_data.size()); 00378 io.data (n_node, "# No. of nodes for which data is stored"); 00379 } 00380 00381 00387 { 00388 unsigned int n_elem = 00389 cast_int<unsigned int>(this->_elem_data.size()); 00390 io.data (n_elem, "# No. of elements for which data is stored"); 00391 } 00392 00393 00394 00395 00396 std::map<const Node*, 00397 std::vector<Number> >::const_iterator nit = _node_data.begin (); 00398 00399 for (; nit != _node_data.end(); ++nit) 00400 { 00401 const Node* node = (*nit).first; 00402 00408 { 00409 unsigned int f_id = node_to_foreign_id (node); 00410 io.data (f_id, "# Foreign node id"); 00411 } 00412 00413 00419 { 00420 /* 00421 * since we are iterating over our @e own 00422 * map, this libmesh_assert should never break... 00423 */ 00424 libmesh_assert (this->has_data(node)); 00425 00426 const std::vector<Number>& values = this->get_data(node); 00427 00428 /* 00429 * copy the data to a local buf, since 00430 * the Xdr class needs write access, even 00431 * when only reading data 00432 */ 00433 std::vector<Number> buf = values; 00434 io.data (buf, "# Values"); 00435 } 00436 } 00437 00438 00439 00440 00441 00442 00443 00444 std::map<const Elem*, 00445 std::vector<Number> >::const_iterator eit = _elem_data.begin (); 00446 00447 for (; eit != _elem_data.end(); ++eit) 00448 { 00449 const Elem* elem = (*eit).first; 00450 00456 { 00457 unsigned int f_id = elem_to_foreign_id (elem); 00458 io.data (f_id, "# Foreign element id"); 00459 } 00460 00461 00467 { 00468 /* 00469 * since we are iterating over our @e own 00470 * map, this libmesh_assert should never break... 00471 */ 00472 libmesh_assert (this->has_data(elem)); 00473 00474 const std::vector<Number>& values = this->get_data(elem); 00475 00476 /* 00477 * copy the data to a local buf, since 00478 * the Xdr class needs write access, even 00479 * when only reading data 00480 */ 00481 std::vector<Number> buf = values; 00482 io.data (buf, "# Values"); 00483 } 00484 } 00485 } 00486 00487 } // namespace libMesh