ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_MPHTXT_WRITER_HPP 00002 #define VIENNAGRID_MPHTXT_WRITER_HPP 00003 00004 /* ======================================================================= 00005 Copyright (c) 2011-2014, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 00009 ----------------- 00010 ViennaGrid - The Vienna Grid Library 00011 ----------------- 00012 00013 License: MIT (X11), see file LICENSE in the base directory 00014 ======================================================================= */ 00015 00016 #include <iostream> 00017 #include <sstream> 00018 #include <fstream> 00019 00020 #include "viennagrid/algorithm/centroid.hpp" 00021 #include "viennagrid/algorithm/boundary.hpp" 00022 #include "viennagrid/algorithm/geometry.hpp" 00023 00024 #include "viennagrid/mesh/coboundary_iteration.hpp" 00025 #include "viennagrid/mesh/neighbor_iteration.hpp" 00026 00033 namespace viennagrid 00034 { 00035 namespace io 00036 { 00037 00038 template<typename TriangleHandleT> 00039 struct triangle_information 00040 { 00041 triangle_information(TriangleHandleT const & handle_) : handle(handle_), up_index(0), down_index(0), contact_index(-1), segment_index(-1) {} 00042 00043 TriangleHandleT handle; 00044 00045 int up_index; 00046 int down_index; 00047 00048 int contact_index; 00049 int segment_index; 00050 }; 00051 00052 00053 00054 00055 00056 00057 00058 00059 00060 template<typename SegmentHandleT, typename AccessorType, typename TriangleHandleT, typename SegmentIDRangeType> 00061 void mark_planar_neighbors( SegmentHandleT const & segment, AccessorType & contact_index_accessor, 00062 TriangleHandleT const & triangle_handle, int contact_index, 00063 SegmentIDRangeType const & sids ) 00064 { 00065 typedef typename viennagrid::result_of::point<SegmentHandleT>::type PointType; 00066 typedef typename viennagrid::result_of::coord<SegmentHandleT>::type NumericType; 00067 typedef typename viennagrid::result_of::triangle<SegmentHandleT>::type TriangleType; 00068 PointType normal = viennagrid::normal_vector( viennagrid::dereference_handle(segment, triangle_handle) ); 00069 00070 typedef typename viennagrid::result_of::const_neighbor_range<SegmentHandleT, viennagrid::triangle_tag, viennagrid::vertex_tag>::type NeigborTriangleRangeType; 00071 typedef typename viennagrid::result_of::iterator<NeigborTriangleRangeType>::type NeigborTriangleIteratorType; 00072 00073 NeigborTriangleRangeType neighbor_triangles( segment, triangle_handle ); 00074 for (NeigborTriangleIteratorType ntit = neighbor_triangles.begin(); ntit != neighbor_triangles.end(); ++ntit ) 00075 { 00076 if (contact_index_accessor(*ntit) != -1) 00077 continue; 00078 00079 if (!viennagrid::is_boundary(segment, *ntit)) 00080 continue; 00081 00082 if (!sids.is_equal(viennagrid::segment_ids(segment.parent(), *ntit))) 00083 continue; 00084 00085 PointType neighbor_normal = viennagrid::normal_vector(*ntit); 00086 00087 NumericType dot = viennagrid::inner_prod( normal, neighbor_normal ); 00088 00089 if ( std::abs(dot) > (1.0-1e-6) * viennagrid::norm_2(normal) * viennagrid::norm_2(neighbor_normal) ) 00090 { 00091 contact_index_accessor(*ntit) = contact_index; 00092 mark_planar_neighbors( segment, contact_index_accessor, ntit.handle(), contact_index, sids ); 00093 } 00094 } 00095 } 00096 00097 00098 00099 00100 template<typename SegmentationT, typename AccessorType> 00101 void mark_segment_hull_contacts( SegmentationT const & segmentation, AccessorType & contact_index_accessor ) 00102 { 00103 typedef typename viennagrid::result_of::segment_handle<SegmentationT>::type SegmentHandleType; 00104 typedef typename viennagrid::result_of::const_triangle_range<SegmentationT>::type ConstTriangleRangeType; 00105 typedef typename viennagrid::result_of::iterator<ConstTriangleRangeType>::type ConstTriangleIteratorType; 00106 00107 ConstTriangleRangeType triangles(segmentation); 00108 for (ConstTriangleIteratorType tit = triangles.begin(); tit != triangles.end(); ++tit) 00109 contact_index_accessor(*tit) = -1; 00110 00111 00112 int current_contact_index = 0; 00113 for (typename SegmentationT::const_iterator sit = segmentation.begin(); sit != segmentation.end(); ++sit) 00114 { 00115 typedef typename viennagrid::result_of::const_triangle_range<SegmentHandleType>::type ConstTriangleOnSegmentRangeType; 00116 typedef typename viennagrid::result_of::iterator<ConstTriangleOnSegmentRangeType>::type ConstTriangleOnSegmentIteratorType; 00117 00118 SegmentHandleType const & segment = *sit; 00119 00120 ConstTriangleOnSegmentRangeType triangles_on_segment(segment); 00121 for (ConstTriangleOnSegmentIteratorType tsit = triangles_on_segment.begin(); tsit != triangles_on_segment.end(); ++tsit) 00122 { 00123 if ( viennagrid::is_boundary(segment, *tsit) && (contact_index_accessor(*tsit) == -1) ) 00124 { 00125 contact_index_accessor(*tsit) = current_contact_index; 00126 00127 typedef typename viennagrid::result_of::triangle<SegmentationT>::type TriangleType; 00128 typedef typename viennagrid::result_of::segment_id_range<SegmentationT, TriangleType>::type SegmentIDRangeType; 00129 00130 SegmentIDRangeType sids = viennagrid::segment_ids(segmentation, *tsit); 00131 00132 mark_planar_neighbors(segment, contact_index_accessor, tsit.handle(), 00133 current_contact_index, sids); 00134 00135 ++current_contact_index; 00136 } 00137 } 00138 } 00139 00140 // std::cout << "Number of contacts: " << current_contact_index << std::endl; 00141 } 00142 00143 00144 00149 class mphtxt_writer 00150 { 00151 public: 00152 00159 template <typename MeshT, typename SegmentationT> 00160 void operator()(MeshT const & mesh, SegmentationT const & segmentation, std::string const & filename) const 00161 { 00162 typedef typename viennagrid::result_of::point<MeshT>::type PointType; 00163 typedef typename viennagrid::result_of::vertex_id<MeshT>::type VertexIDType; 00164 typedef typename viennagrid::result_of::triangle_id<MeshT>::type TriangleIDType; 00165 00166 typedef typename viennagrid::result_of::triangle<MeshT>::type TriangleType; 00167 00168 00169 typedef typename viennagrid::result_of::const_vertex_range<MeshT>::type ConstVertexRangeType; 00170 typedef typename viennagrid::result_of::iterator<ConstVertexRangeType>::type ConstVertexIteratorType; 00171 00172 typedef typename viennagrid::result_of::const_triangle_range<MeshT>::type ConstTriangleRangeType; 00173 typedef typename viennagrid::result_of::iterator<ConstTriangleRangeType>::type ConstTriangleIteratorType; 00174 00175 typedef typename viennagrid::result_of::const_tetrahedron_range<MeshT>::type ConstTetrahedronRangeType; 00176 typedef typename viennagrid::result_of::iterator<ConstTetrahedronRangeType>::type ConstTetrahedronIteratorType; 00177 00178 00179 00180 std::stringstream ss; 00181 if(filename.substr( filename.rfind(".")+1 ) == "mphtxt") 00182 ss << filename; 00183 else 00184 ss << filename << ".mphtxt"; 00185 std::ofstream writer(ss.str().c_str()); 00186 00187 writer << "# Created by ViennaGrid mphtxt writer\n"; 00188 writer << "\n"; 00189 00190 writer << "# Major & minor version\n"; 00191 writer << "0 1\n"; 00192 writer << "1 # number of tags\n"; 00193 writer << "# Tags\n"; 00194 writer << "15 viennagrid_mesh\n"; 00195 writer << "1 # number of types\n"; 00196 writer << "# Types\n"; 00197 writer << "3 obj\n"; 00198 00199 writer << "\n"; 00200 writer << "# --------- Object 0 ----------\n"; 00201 writer << "\n"; 00202 00203 writer << "0 0 1\n"; 00204 writer << "4 Mesh # class\n"; 00205 writer << "2 # version\n"; 00206 writer << viennagrid::result_of::geometric_dimension<MeshT>::value << " # sdim\n"; 00207 writer << viennagrid::vertices(mesh).size() << " # number of mesh points\n"; 00208 writer << "0 # lowest mesh point index\n"; 00209 writer << "\n"; 00210 00211 writer << "# Mesh point coordinates\n"; 00212 ConstVertexRangeType vertices(mesh); 00213 std::map<VertexIDType, int> vertex_index_map; 00214 00215 std::size_t vertex_index = 0; 00216 for (ConstVertexIteratorType vit = vertices.begin(); vit != vertices.end(); ++vit, ++vertex_index) 00217 { 00218 vertex_index_map[ vit->id() ] = vertex_index; 00219 00220 writer.precision( std::numeric_limits<typename PointType::value_type>::digits10 ); 00221 PointType const & point = viennagrid::point(*vit); 00222 for (std::size_t i = 0; i < point.size(); ++i) 00223 writer << point[i] << " "; 00224 writer << "\n"; 00225 } 00226 writer << "\n"; 00227 00228 writer << "\n"; 00229 writer << "2 # number of element types\n"; 00230 00231 00232 writer << "\n"; 00233 writer << "3 tri\n"; 00234 writer << "3 # nodes per element\n"; 00235 writer << "\n"; 00236 00237 ConstTriangleRangeType triangles(mesh); 00238 00239 typedef typename viennagrid::result_of::const_triangle_handle<MeshT>::type ConstTriangleHandleType; 00240 typedef triangle_information<ConstTriangleHandleType> TriInfoType; 00241 00242 std::map<TriangleIDType, TriInfoType> used_triangles; 00243 typedef typename viennagrid::result_of::segment_handle<SegmentationT>::type SegmentHandleType; 00244 00245 for (typename SegmentationT::const_iterator sit = segmentation.begin(); sit != segmentation.end(); ++sit) 00246 { 00247 typedef typename viennagrid::result_of::const_triangle_range<SegmentHandleType>::type TriangleOnSegmentRangeType; 00248 typedef typename viennagrid::result_of::iterator<TriangleOnSegmentRangeType>::type TriangleOnSegmentIteratorType; 00249 00250 TriangleOnSegmentRangeType triangles(*sit); 00251 for (TriangleOnSegmentIteratorType tit = triangles.begin(); tit != triangles.end(); ++tit) 00252 { 00253 if ( viennagrid::is_boundary(*sit, *tit) ) 00254 { 00255 typename std::map<TriangleIDType, TriInfoType>::iterator utit = used_triangles.find( tit->id() ); 00256 if (utit == used_triangles.end()) 00257 utit = used_triangles.insert( std::make_pair(tit->id(), TriInfoType(tit.handle())) ).first; 00258 00259 PointType triangle_normal = viennagrid::normal_vector(*tit); 00260 PointType triangle_center = viennagrid::centroid(*tit); 00261 00262 typedef typename viennagrid::result_of::const_coboundary_range<SegmentHandleType, viennagrid::triangle_tag, viennagrid::tetrahedron_tag>::type CoboundaryTetrahedronRangeType; 00263 typedef typename viennagrid::result_of::iterator<CoboundaryTetrahedronRangeType>::type CoboundaryTetrahedronIteratorType; 00264 00265 CoboundaryTetrahedronRangeType coboundary_tetrahedrons(*sit, tit.handle()); 00266 if (coboundary_tetrahedrons.size() != 1) 00267 { 00268 std::cout << "FEHLER!!! there is more than one on co-boundary tetrahedron" << std::endl; 00269 } 00270 00271 PointType tetrahedron_center = viennagrid::centroid( coboundary_tetrahedrons[0] ); 00272 00273 bool orientation = viennagrid::inner_prod( triangle_center-tetrahedron_center, triangle_normal ) > 0; 00274 00275 if (orientation) 00276 { 00277 if (utit->second.up_index != 0) 00278 { 00279 std::cout << "FEHLER!!!" << std::endl; 00280 } 00281 00282 utit->second.up_index = sit->id()+1; 00283 } 00284 else 00285 { 00286 if (utit->second.down_index != 0) 00287 { 00288 std::cout << "FEHLER!!!" << std::endl; 00289 } 00290 00291 utit->second.down_index = sit->id()+1; 00292 } 00293 } 00294 } 00295 } 00296 00297 00298 std::vector<int> contact_index_array; 00299 typename viennagrid::result_of::field< std::vector<int>, TriangleType>::type contact_index_field(contact_index_array); 00300 00301 mark_segment_hull_contacts( segmentation, contact_index_field ); 00302 00303 00304 00305 00306 // writer << viennagrid::triangles(mesh).size() << " # number of triangles\n"; 00307 writer << used_triangles.size() << " # number of triangles\n"; 00308 writer << "\n"; 00309 00310 for (typename std::map<TriangleIDType, TriInfoType>::const_iterator utit = used_triangles.begin(); utit != used_triangles.end(); ++utit) 00311 { 00312 typedef typename viennagrid::result_of::triangle<MeshT>::type TriangleType; 00313 typedef typename viennagrid::result_of::const_vertex_range<TriangleType>::type VertexOnTriangleRangeType; 00314 typedef typename viennagrid::result_of::iterator<VertexOnTriangleRangeType>::type VertexOnTriangleIteratorType; 00315 00316 VertexOnTriangleRangeType vertices_on_triangle( viennagrid::dereference_handle(mesh, utit->second.handle) ); 00317 for (VertexOnTriangleIteratorType vtit = vertices_on_triangle.begin(); vtit != vertices_on_triangle.end(); ++vtit) 00318 { 00319 writer << vertex_index_map[ vtit->id() ] << " "; 00320 } 00321 writer << "\n"; 00322 } 00323 00324 writer << "\n"; 00325 writer << "3\n"; 00326 writer << "0\n"; 00327 00328 writer << used_triangles.size() << " # number of triangles\n"; 00329 for (typename std::map<TriangleIDType, TriInfoType>::const_iterator utit = used_triangles.begin(); utit != used_triangles.end(); ++utit) 00330 writer << contact_index_field( viennagrid::dereference_handle(mesh, utit->second.handle) ) << "\n"; 00331 00332 writer << "\n"; 00333 writer << used_triangles.size() << " # number of triangles\n"; 00334 writer << "\n"; 00335 for (typename std::map<TriangleIDType, TriInfoType>::const_iterator utit = used_triangles.begin(); utit != used_triangles.end(); ++utit) 00336 writer << utit->second.up_index << " " << utit->second.down_index << "\n"; 00337 00338 00339 00340 00341 00342 00343 writer << "\n"; 00344 writer << "3 tet\n"; 00345 writer << "4 # nodes per element\n"; 00346 writer << "\n"; 00347 writer << viennagrid::tetrahedra(mesh).size() << " # number of tetrahedron\n"; 00348 writer << "\n"; 00349 00350 ConstTetrahedronRangeType tetrahedrons(mesh); 00351 for (ConstTetrahedronIteratorType tit = tetrahedrons.begin(); tit != tetrahedrons.end(); ++tit) 00352 { 00353 typedef typename viennagrid::result_of::tetrahedron<MeshT>::type TetrahedronType; 00354 typedef typename viennagrid::result_of::const_vertex_range<TetrahedronType>::type VertexOnTetrahedronRangeType; 00355 typedef typename viennagrid::result_of::iterator<VertexOnTetrahedronRangeType>::type VertexOnTetrahedronIteratorType; 00356 00357 VertexOnTetrahedronRangeType vertices_on_tetrahedron(*tit); 00358 for (VertexOnTetrahedronIteratorType vtit = vertices_on_tetrahedron.begin(); vtit != vertices_on_tetrahedron.end(); ++vtit) 00359 { 00360 writer << vertex_index_map[ vtit->id() ] << " "; 00361 } 00362 writer << "\n"; 00363 } 00364 00365 writer << "\n"; 00366 writer << "4\n"; 00367 writer << "0\n"; 00368 // writer << viennagrid::tetrahedra(mesh).size() << " # number of tetrahedron\n"; 00369 writer << "\n"; 00370 writer << viennagrid::tetrahedra(mesh).size() << " # number of tetrahedron\n"; 00371 00372 // ConstTetrahedronRangeType tetrahedrons(mesh); 00373 for (ConstTetrahedronIteratorType tit = tetrahedrons.begin(); tit != tetrahedrons.end(); ++tit) 00374 { 00375 typedef typename viennagrid::result_of::tetrahedron<MeshT>::type TetrahedronType; 00376 typedef typename viennagrid::result_of::const_vertex_range<TetrahedronType>::type VertexOnTetrahedronRangeType; 00377 typedef typename viennagrid::result_of::iterator<VertexOnTetrahedronRangeType>::type VertexOnTetrahedronIteratorType; 00378 00379 typedef typename viennagrid::result_of::segment_id_range<SegmentationT, TetrahedronType>::type SegmentIDRange; 00380 00381 SegmentIDRange segment_ids = viennagrid::segment_ids( segmentation, *tit ); 00382 writer << *(segment_ids.begin())+1 << "\n"; 00383 } 00384 00385 writer << "\n"; 00386 writer << "0\n"; 00387 } 00388 00389 00390 00391 private: 00392 00393 }; 00394 00395 00396 00397 } 00398 } 00399 00400 00401 00402 #endif