tetgen_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 // C++ includes 00020 #include <fstream> 00021 00022 // Local includes 00023 #include "libmesh/tetgen_io.h" 00024 #include "libmesh/mesh_base.h" 00025 #include "libmesh/cell_tet4.h" 00026 #include "libmesh/cell_tet10.h" 00027 #include "libmesh/mesh_data.h" 00028 00029 namespace libMesh 00030 { 00031 00032 // ------------------------------------------------------------ 00033 // TetgenIO class members 00034 void TetGenIO::read (const std::string& name) 00035 { 00036 // This is a serial-only process for now; 00037 // the Mesh should be read on processor 0 and 00038 // broadcast later 00039 libmesh_assert_equal_to (libMesh::processor_id(), 0); 00040 00041 std::string name_node, name_ele, dummy; 00042 00043 // tetgen only works in 3D 00044 MeshInput<MeshBase>::mesh().set_mesh_dimension(3); 00045 00046 #if LIBMESH_DIM < 3 00047 libMesh::err << "Cannot open dimension 3 mesh file when configured without 3D support." << 00048 std::endl; 00049 libmesh_error(); 00050 #endif 00051 00052 // Check name for *.node or *.ele extension. 00053 // Set std::istream for node_stream and ele_stream. 00054 // 00055 if (name.rfind(".node") < name.size()) 00056 { 00057 name_node = name; 00058 dummy = name; 00059 std::size_t position = dummy.rfind(".node"); 00060 name_ele = dummy.replace(position, 5, ".ele"); 00061 } 00062 else if (name.rfind(".ele") < name.size()) 00063 { 00064 name_ele = name; 00065 dummy = name; 00066 std::size_t position = dummy.rfind(".ele"); 00067 name_node = dummy.replace(position, 4, ".node"); 00068 } 00069 else 00070 { 00071 libMesh::err << "ERROR: Unrecognized file name: " 00072 << name << std::endl; 00073 libmesh_error(); 00074 } 00075 00076 00077 00078 // Set the streams from which to read in 00079 std::ifstream node_stream (name_node.c_str()); 00080 std::ifstream ele_stream (name_ele.c_str()); 00081 00082 if ( !node_stream.good() || !ele_stream.good() ) 00083 { 00084 libMesh::err << "ERROR: One or both Input file(s) not good." << std::endl 00085 << "Error checking files " 00086 << name_node << " and " 00087 << name_ele << std::endl; 00088 libmesh_error(); 00089 } 00090 libMesh::out<< "TetGenIO found the tetgen files to read " <<std::endl; 00091 00092 // Skip the comment lines at the beginning 00093 this->skip_comment_lines (node_stream, '#'); 00094 this->skip_comment_lines (ele_stream, '#'); 00095 00096 // Read the nodes and elements from the streams 00097 this->read_nodes_and_elem (node_stream, ele_stream); 00098 libMesh::out<< "TetGenIO read in nodes and elements " <<std::endl; 00099 } 00100 00101 00102 00103 void TetGenIO::read_nodes_and_elem (std::istream& node_stream, 00104 std::istream& ele_stream) 00105 { 00106 _num_nodes = 0; 00107 _num_elements = 0; 00108 00109 // Read all the datasets. 00110 this->node_in (node_stream); 00111 this->element_in (ele_stream); 00112 00113 // Tell the MeshData object that we are finished 00114 // reading data. 00115 if (this->_mesh_data != NULL) 00116 this->_mesh_data->close_foreign_id_maps (); 00117 00118 // some more clean-up 00119 _assign_nodes.clear(); 00120 } 00121 00122 00123 00124 //---------------------------------------------------------------------- 00125 // Function to read in the node table. 00126 void TetGenIO::node_in (std::istream& node_stream) 00127 { 00128 // Check input buffer 00129 libmesh_assert (node_stream.good()); 00130 00131 // Get a reference to the mesh 00132 MeshBase& mesh = MeshInput<MeshBase>::mesh(); 00133 00134 unsigned int dimension=0, nAttributes=0, BoundaryMarkers=0; 00135 00136 node_stream >> _num_nodes // Read the number of nodes from the stream 00137 >> dimension // Read the dimension from the stream 00138 >> nAttributes // Read the number of attributes from stream 00139 >> BoundaryMarkers; // Read if or not boundary markers are included in *.node (0 or 1) 00140 00141 // Read the nodal coordinates from the node_stream (*.node file). 00142 unsigned int node_lab=0; 00143 Point xyz; 00144 Real dummy; 00145 00146 // If present, make room for node attributes to be stored. 00147 this->node_attributes.resize(nAttributes); 00148 for (unsigned i=0; i<nAttributes; ++i) 00149 this->node_attributes[i].resize(_num_nodes); 00150 00151 00152 for (unsigned int i=0; i<_num_nodes; i++) 00153 { 00154 // Check input buffer 00155 libmesh_assert (node_stream.good()); 00156 00157 node_stream >> node_lab // node number 00158 >> xyz(0) // x-coordinate value 00159 >> xyz(1) // y-coordinate value 00160 >> xyz(2); // z-coordinate value 00161 00162 // Read and store attributes from the stream. 00163 for (unsigned int j=0; j<nAttributes; j++) 00164 node_stream >> node_attributes[j][i]; 00165 00166 // Read (and discard) boundary marker if BoundaryMarker=1. 00167 // TODO: should we store this somehow? 00168 if (BoundaryMarkers == 1) 00169 node_stream >> dummy; 00170 00171 // Store the new position of the node under its label. 00172 //_assign_nodes.insert (std::make_pair(node_lab,i)); 00173 _assign_nodes[node_lab] = i; 00174 00175 // do this irrespective whether MeshData exists 00176 Node* newnode = mesh.add_point(xyz, i); 00177 00178 // Add node to the nodes vector & 00179 // tell the MeshData object the foreign node id. 00180 if (this->_mesh_data != NULL) 00181 this->_mesh_data->add_foreign_node_id (newnode, node_lab); 00182 } 00183 } 00184 00185 00186 00187 //---------------------------------------------------------------------- 00188 // Function to read in the element table. 00189 void TetGenIO::element_in (std::istream& ele_stream) 00190 { 00191 // Check input buffer 00192 libmesh_assert (ele_stream.good()); 00193 00194 // Get a reference to the mesh 00195 MeshBase& mesh = MeshInput<MeshBase>::mesh(); 00196 00197 // Read the elements from the ele_stream (*.ele file). 00198 unsigned int element_lab=0, n_nodes=0, nAttri=0; 00199 00200 ele_stream >> _num_elements // Read the number of tetrahedrons from the stream. 00201 >> n_nodes // Read the number of nodes per tetrahedron from the stream (defaults to 4). 00202 >> nAttri; // Read the number of attributes from stream. 00203 00204 // Vector that assigns element nodes to their correct position. 00205 // TetGen is normaly 0-based 00206 // (right now this is strictly not necessary since it is the identity map, 00207 // but in the future TetGen could change their numbering scheme.) 00208 static const unsigned int assign_elm_nodes[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 00209 00210 // If present, make room for element attributes to be stored. 00211 this->element_attributes.resize(nAttri); 00212 for (unsigned i=0; i<nAttri; ++i) 00213 this->element_attributes[i].resize(_num_elements); 00214 00215 for (dof_id_type i=0; i<_num_elements; i++) 00216 { 00217 libmesh_assert (ele_stream.good()); 00218 00219 // TetGen only supports Tet4 and Tet10 elements. 00220 Elem* elem; 00221 00222 if (n_nodes==4) 00223 elem = new Tet4; 00224 00225 else if (n_nodes==10) 00226 elem = new Tet10; 00227 00228 else 00229 { 00230 libMesh::err << "Elements with " << n_nodes 00231 << " nodes are not supported in the LibMesh tetgen module\n"; 00232 libmesh_error(); 00233 } 00234 elem->set_id(i); 00235 00236 mesh.add_elem (elem); 00237 00238 libmesh_assert(elem); 00239 libmesh_assert_equal_to (elem->n_nodes(), n_nodes); 00240 00241 // Read the element label 00242 ele_stream >> element_lab; 00243 00244 // Add the element to the mesh & 00245 // tell the MeshData object the foreign element id 00246 if (this->_mesh_data != NULL) 00247 this->_mesh_data->add_foreign_elem_id (elem, element_lab); 00248 00249 // Read node labels 00250 for (dof_id_type j=0; j<n_nodes; j++) 00251 { 00252 dof_id_type node_label; 00253 ele_stream >> node_label; 00254 00255 // Assign node to element 00256 elem->set_node(assign_elm_nodes[j]) = 00257 mesh.node_ptr(_assign_nodes[node_label]); 00258 } 00259 00260 // Read and store attributes from the stream. 00261 for (unsigned int j=0; j<nAttri; j++) 00262 ele_stream >> this->element_attributes[j][i]; 00263 } 00264 } 00265 00266 00271 void TetGenIO::write (const std::string& fname) 00272 { 00273 // libmesh_assert three dimensions (should be extended later) 00274 libmesh_assert_equal_to (MeshOutput<MeshBase>::mesh().mesh_dimension(), 3); 00275 00276 if (!(fname.rfind(".poly") < fname.size())) 00277 { 00278 libMesh::err << "ERROR: Unrecognized file name: " 00279 << fname << std::endl; 00280 libmesh_error(); 00281 } 00282 00283 // Open the output file stream 00284 std::ofstream out_stream (fname.c_str()); 00285 00286 // Make sure it opened correctly 00287 if (!out_stream.good()) 00288 libmesh_file_error(fname.c_str()); 00289 00290 // Get a reference to the mesh 00291 const MeshBase& mesh = MeshOutput<MeshBase>::mesh(); 00292 00293 // Begin interfacing with the .poly file 00294 { 00295 // header: 00296 out_stream << "# poly file output generated by libmesh\n" 00297 << mesh.n_nodes() << " 3 0 0\n"; 00298 00299 // write the nodes: 00300 for (dof_id_type v=0; v<mesh.n_nodes(); v++) 00301 out_stream << v << " " 00302 << mesh.point(v)(0) << " " 00303 << mesh.point(v)(1) << " " 00304 << mesh.point(v)(2) << "\n"; 00305 } 00306 00307 { 00308 // write the connectivity: 00309 out_stream << "# Facets:\n" 00310 << mesh.n_elem() << " 0\n"; 00311 00312 // const_active_elem_iterator it (mesh.elements_begin()); 00313 // const const_active_elem_iterator end(mesh.elements_end()); 00314 00315 MeshBase::const_element_iterator it = mesh.active_elements_begin(); 00316 const MeshBase::const_element_iterator end = mesh.active_elements_end(); 00317 00318 for ( ; it != end; ++it) 00319 out_stream << "1\n3 " // no. of facet polygons 00320 // << (*it)->n_nodes() << " " 00321 << (*it)->node(0) << " " 00322 << (*it)->node(1) << " " 00323 << (*it)->node(2) << "\n"; 00324 } 00325 00326 // end of the file 00327 out_stream << "0\n"; // no holes output! 00328 out_stream << "\n\n# end of file\n"; 00329 } 00330 00331 } // namespace libMesh 00332
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:49 UTC
Hosted By: