$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 // C++ includes 00019 #include <fstream> 00020 #include <sstream> 00021 #include <map> 00022 00023 // Local includes 00024 #include "libmesh/elem.h" 00025 #include "libmesh/libmesh_logging.h" 00026 #include "libmesh/mesh_base.h" 00027 #include "libmesh/gnuplot_io.h" 00028 00029 namespace libMesh 00030 { 00031 00032 GnuPlotIO::GnuPlotIO(const MeshBase& mesh_in, 00033 const std::string& title, 00034 int mesh_properties) 00035 : 00036 MeshOutput<MeshBase> (mesh_in), 00037 _title(title) 00038 { 00039 _grid = (mesh_properties & GRID_ON); 00040 _png_output = (mesh_properties & PNG_OUTPUT); 00041 } 00042 00043 void GnuPlotIO::write(const std::string& fname) 00044 { 00045 this->write_solution(fname); 00046 } 00047 00048 void GnuPlotIO::write_nodal_data (const std::string& fname, 00049 const std::vector<Number>& soln, 00050 const std::vector<std::string>& names) 00051 { 00052 START_LOG("write_nodal_data()", "GnuPlotIO"); 00053 00054 this->write_solution(fname, &soln, &names); 00055 00056 STOP_LOG("write_nodal_data()", "GnuPlotIO"); 00057 } 00058 00059 00060 00061 00062 void GnuPlotIO::write_solution(const std::string& fname, 00063 const std::vector<Number>* soln, 00064 const std::vector<std::string>* names) 00065 { 00066 // Even when writing on a serialized ParallelMesh, we expect 00067 // non-proc-0 help with calls like n_active_elem 00068 // libmesh_assert_equal_to (this->mesh().processor_id(), 0); 00069 00070 const MeshBase& the_mesh = MeshOutput<MeshBase>::mesh(); 00071 00072 dof_id_type n_active_elem = the_mesh.n_active_elem(); 00073 00074 if (this->mesh().processor_id() == 0) 00075 { 00076 std::stringstream data_stream_name; 00077 data_stream_name << fname << "_data"; 00078 const std::string data_file_name = data_stream_name.str(); 00079 00080 // This class is designed only for use with 1D meshes 00081 libmesh_assert_equal_to (the_mesh.mesh_dimension(), 1); 00082 00083 // Make sure we have a solution to plot 00084 libmesh_assert ((names != NULL) && (soln != NULL)); 00085 00086 // Create an output stream for script file 00087 std::ofstream out_stream(fname.c_str()); 00088 00089 // Make sure it opened correctly 00090 if (!out_stream.good()) 00091 libmesh_file_error(fname.c_str()); 00092 00093 // The number of variables in the equation system 00094 const unsigned int n_vars = 00095 cast_int<unsigned int>(names->size()); 00096 00097 // Write header to stream 00098 out_stream << "# This file was generated by gnuplot_io.C\n" 00099 << "# Stores 1D solution data in GNUplot format\n" 00100 << "# Execute this by loading gnuplot and typing " 00101 << "\"call '" << fname << "'\"\n" 00102 << "reset\n" 00103 << "set title \"" << _title << "\"\n" 00104 << "set xlabel \"x\"\n" 00105 << "set xtics nomirror\n"; 00106 00107 // Loop over the elements to find the minimum and maximum x values, 00108 // and also to find the element boundaries to write out as xtics 00109 // if requested. 00110 Real x_min=0., x_max=0.; 00111 00112 // construct string for xtic positions at element edges 00113 std::stringstream xtics_stream; 00114 00115 MeshBase::const_element_iterator it = the_mesh.active_elements_begin(); 00116 const MeshBase::const_element_iterator end_it = 00117 the_mesh.active_elements_end(); 00118 00119 unsigned int count = 0; 00120 00121 for( ; it != end_it; ++it) 00122 { 00123 const Elem* el = *it; 00124 00125 // if el is the left edge of the mesh, print its left node position 00126 if(el->neighbor(0) == NULL) 00127 { 00128 x_min = (*(el->get_node(0)))(0); 00129 xtics_stream << "\"\" " << x_min << ", \\\n"; 00130 } 00131 if(el->neighbor(1) == NULL) 00132 { 00133 x_max = (*(el->get_node(1)))(0); 00134 } 00135 xtics_stream << "\"\" " << (*(el->get_node(1)))(0); 00136 00137 if(count+1 != n_active_elem) 00138 { 00139 xtics_stream << ", \\\n"; 00140 } 00141 count++; 00142 } 00143 00144 out_stream << "set xrange [" << x_min << ":" << x_max << "]\n"; 00145 00146 if(_grid) 00147 out_stream << "set x2tics (" << xtics_stream.str() << ")\nset grid noxtics noytics x2tics\n"; 00148 00149 if(_png_output) 00150 { 00151 out_stream << "set terminal png\n"; 00152 out_stream << "set output \"" << fname << ".png\"\n"; 00153 } 00154 00155 out_stream << "plot " 00156 << axes_limits 00157 << " \"" << data_file_name << "\" using 1:2 title \"" << (*names)[0] 00158 << "\" with lines"; 00159 if(n_vars > 1) 00160 { 00161 for(unsigned int i=1; i<n_vars; i++) 00162 { 00163 out_stream << ", \\\n\"" << data_file_name << "\" using 1:" << i+2 00164 << " title \"" << (*names)[i] << "\" with lines"; 00165 } 00166 } 00167 00168 out_stream.close(); 00169 00170 00171 // Create an output stream for data file 00172 std::ofstream data(data_file_name.c_str()); 00173 00174 if (!data.good()) 00175 libmesh_error_msg("ERROR: opening output data file " << data_file_name); 00176 00177 // get ordered nodal data using a map 00178 typedef std::pair<Real, std::vector<Number> > key_value_pair; 00179 typedef std::map<Real, std::vector<Number> > map_type; 00180 typedef map_type::iterator map_iterator; 00181 00182 map_type node_map; 00183 00184 00185 it = the_mesh.active_elements_begin(); 00186 00187 for ( ; it != end_it; ++it) 00188 { 00189 const Elem* elem = *it; 00190 00191 for(unsigned int i=0; i<elem->n_nodes(); i++) 00192 { 00193 std::vector<Number> values; 00194 00195 // Get the global id of the node 00196 dof_id_type global_id = elem->node(i); 00197 00198 for(unsigned int c=0; c<n_vars; c++) 00199 { 00200 values.push_back( (*soln)[global_id*n_vars + c] ); 00201 } 00202 00203 node_map[ the_mesh.point(global_id)(0) ] = values; 00204 } 00205 } 00206 00207 00208 map_iterator map_it = node_map.begin(); 00209 const map_iterator end_map_it = node_map.end(); 00210 00211 for( ; map_it != end_map_it; ++map_it) 00212 { 00213 key_value_pair kvp = *map_it; 00214 std::vector<Number> values = kvp.second; 00215 00216 data << kvp.first << "\t"; 00217 00218 for(unsigned int i=0; i<values.size(); i++) 00219 { 00220 data << values[i] << "\t"; 00221 } 00222 00223 data << "\n"; 00224 } 00225 00226 data.close(); 00227 } 00228 } 00229 00230 } // namespace libMesh