ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/io/mphtxt_writer.hpp
Go to the documentation of this file.
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