$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 // Local includes 00020 #include "libmesh/equation_systems.h" 00021 #include "libmesh/mesh_output.h" 00022 #include "libmesh/parallel.h" 00023 #include "libmesh/parallel_mesh.h" 00024 #include "libmesh/unstructured_mesh.h" 00025 00026 namespace libMesh 00027 { 00028 00029 template <class MT> 00030 void MeshOutput<MT>::write_equation_systems (const std::string& fname, 00031 const EquationSystems& es, 00032 const std::set<std::string>* system_names) 00033 { 00034 START_LOG("write_equation_systems()", "MeshOutput"); 00035 00036 // We may need to gather and/or renumber a ParallelMesh to output 00037 // it, making that const qualifier in our constructor a dirty lie 00038 MT& my_mesh = const_cast<MT&>(*_obj); 00039 00040 // If we're asked to write data that's associated with a different 00041 // mesh, output files full of garbage are the result. 00042 libmesh_assert_equal_to(&es.get_mesh(), _obj); 00043 00044 // A non-renumbered mesh may not have a contiguous numbering, and 00045 // that needs to be fixed before we can build a solution vector. 00046 if (my_mesh.max_elem_id() != my_mesh.n_elem() || 00047 my_mesh.max_node_id() != my_mesh.n_nodes()) 00048 { 00049 // If we were allowed to renumber then we should have already 00050 // been properly renumbered... 00051 libmesh_assert(!my_mesh.allow_renumbering()); 00052 00053 libmesh_do_once(libMesh::out << 00054 "Warning: This MeshOutput subclass only supports meshes which are contiguously renumbered!" 00055 << std::endl;); 00056 00057 my_mesh.allow_renumbering(true); 00058 00059 my_mesh.renumber_nodes_and_elements(); 00060 00061 // Not sure what good going back to false will do here, the 00062 // renumbering horses have already left the barn... 00063 my_mesh.allow_renumbering(false); 00064 } 00065 00066 MeshSerializer serialize(const_cast<MT&>(*_obj), !_is_parallel_format); 00067 00068 // Build the nodal solution values & get the variable 00069 // names from the EquationSystems object 00070 std::vector<Number> soln; 00071 std::vector<std::string> names; 00072 00073 this->_build_variable_names_and_solution_vector(es, soln, names, system_names); 00074 //es.build_variable_names (names); 00075 //es.build_solution_vector (soln); 00076 00077 this->write_nodal_data (fname, soln, names); 00078 00079 STOP_LOG("write_equation_systems()", "MeshOutput"); 00080 } 00081 00082 00083 00084 template <class MT> 00085 void MeshOutput<MT>:: 00086 _build_variable_names_and_solution_vector (const EquationSystems& es, 00087 std::vector<Number>& soln, 00088 std::vector<std::string>& names, 00089 const std::set<std::string>* system_names) 00090 { 00091 if(!_is_parallel_format) 00092 { 00093 // We need a serial mesh for MeshOutput for now 00094 const_cast<EquationSystems&>(es).allgather(); 00095 } 00096 00097 es.build_variable_names (names, NULL, system_names); 00098 es.build_solution_vector (soln, system_names); 00099 00100 // For now, if we're doing a parallel format we're going to broadcast the vector from processor 0 00101 // to all of the processors to mimic what build_solution_vector used to do. 00102 // this is TERRIBLE and WASTEFUL but it's only temporary until we redesign the output of build_solution_vector 00103 // and the inputs to the I/O... both of which should actually be NumericVectors.... 00104 if(_is_parallel_format) 00105 { 00106 size_t size = soln.size(); 00107 _obj->comm().broadcast(size); 00108 00109 if(_obj->comm().rank()) 00110 soln.resize(size); 00111 00112 _obj->comm().broadcast(soln); 00113 } 00114 } 00115 00116 00117 00118 // Instantiate for our Mesh types. If this becomes too cumbersome later, 00119 // move any functions in this file to the header file instead. 00120 template class MeshOutput<MeshBase>; 00121 template class MeshOutput<UnstructuredMesh>; 00122 template class MeshOutput<ParallelMesh>; 00123 00124 } // namespace libMesh