• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

/export/development/ViennaGrid/release/ViennaGrid-1.0.0/viennagrid/algorithm/interface.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAGRID_ALGORITHM_INTERFACE_HPP
00002 #define VIENNAGRID_ALGORITHM_INTERFACE_HPP
00003 
00004 /* =======================================================================
00005    Copyright (c) 2011, Institute for Microelectronics,
00006                        Institute for Analysis and Scientific Computing,
00007                        TU Wien.
00008 
00009                             -----------------
00010                      ViennaGrid - The Vienna Grid Library
00011                             -----------------
00012 
00013    Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
00014                  Josef Weinbub                    weinbub@iue.tuwien.ac.at
00015                
00016    (A list of additional contributors can be found in the PDF manual)
00017 
00018    License:      MIT (X11), see file LICENSE in the base directory
00019 ======================================================================= */
00020 
00021 #include <vector>
00022 #include "viennagrid/forwards.h"
00023 #include "viennagrid/detail/element_iterators.hpp"
00024 #include "viennagrid/detail/domain_iterators.hpp"
00025 #include "viennagrid/algorithm/norm.hpp"
00026 #include "viennagrid/algorithm/centroid.hpp"
00027 #include "viennagrid/algorithm/boundary.hpp"
00028 
00034 namespace viennagrid
00035 {
00037   class interface_key
00038   {
00039     public:
00040       interface_key(std::size_t id1, std::size_t id2) : id_(id1, id2) {}
00041       
00043       bool operator<(interface_key const & other) const
00044       {
00045         return id_ < other.id_;
00046       }
00047       
00048     private:
00049       std::pair<std::size_t, std::size_t> id_;
00050   };
00051 
00052 
00054   template <long dim>
00055   struct interface_setter
00056   {
00057     template <typename FacetType, typename KeyType>
00058     static void apply(FacetType const & facet, KeyType const & key, full_handling_tag)
00059     {
00060       typedef typename FacetType::config_type        ConfigType;
00061       typedef typename ConfigType::cell_tag          CellTag;
00062       
00063       typedef typename viennagrid::result_of::const_ncell_range<FacetType, dim>::type    ElementOnFacetRange;
00064       typedef typename result_of::iterator<ElementOnFacetRange>::type                    ElementOnFacetIterator;
00065 
00066       ElementOnFacetRange eof_container = ncells<dim>(facet);
00067       for (ElementOnFacetIterator eofit = eof_container.begin();
00068             eofit != eof_container.end();
00069             ++eofit)
00070       {
00071         viennadata::access<KeyType, bool>(key)(*eofit) = true;
00072       }
00073 
00074       //proceed to lower level:
00075       interface_setter<dim-1>::apply(facet,
00076                                                 key,
00077                                                 typename viennagrid::result_of::bndcell_handling<ConfigType, CellTag, dim-1>::type());
00078     }
00079     
00080     template <typename FacetType, typename KeyType>
00081     static void apply(FacetType const & facet, KeyType const & key, no_handling_tag)
00082     {
00083       typedef typename FacetType::config_type        ConfigType;
00084       typedef typename ConfigType::cell_tag          CellTag;
00085       
00086       //proceed to lower level:
00087       interface_setter<dim-1>::apply(facet,
00088                                                 key,
00089                                                 typename viennagrid::result_of::bndcell_handling<ConfigType, CellTag, dim-1>::type());
00090     }
00091     
00092   };
00093 
00094   //end recursion of topological dimension = -1
00096   template <>
00097   struct interface_setter< -1 >
00098   {
00099     template <typename FacetType, typename KeyType, typename HandlingTag>
00100     static void apply(FacetType const & facet, KeyType const & key, HandlingTag) {}
00101   };
00102 
00104   template <typename SegmentType, typename KeyType>
00105   void detect_interface_impl(SegmentType const & seg1,
00106                              SegmentType const & seg2,
00107                              KeyType const & key,
00108                              no_handling_tag)
00109   {
00110     typedef typename SegmentType::ERROR_CANNOT_DETECT_INTERFACE_BECAUSE_FACETS_ARE_DISABLED        error_type;
00111   }
00112 
00119   template <typename SegmentType, typename KeyType>
00120   void detect_interface_impl(SegmentType const & seg1,
00121                              SegmentType const & seg2,
00122                              KeyType const & key,
00123                              full_handling_tag)
00124   {
00125     typedef typename SegmentType::config_type                                  ConfigType;
00126     typedef typename ConfigType::cell_tag                                      CellTag;
00127     typedef typename viennagrid::result_of::point<ConfigType>::type                              PointType;
00128     typedef typename viennagrid::result_of::ncell<ConfigType, CellTag::dim-1>::type   FacetType;
00129     typedef typename viennagrid::result_of::ncell<ConfigType, CellTag::dim>::type     CellType;
00130 
00131     typedef typename viennagrid::result_of::const_ncell_range<SegmentType, CellTag::dim-1>::type      FacetRange;
00132     typedef typename viennagrid::result_of::iterator<FacetRange>::type                                           FacetIterator;
00133     
00134     typedef typename ConfigType::numeric_type         numeric_type;
00135 
00136     std::set<FacetType const *>  facets_ptrs_seg1;
00137     
00138     //
00139     // Step 1: Write facets of segment 1 to a map:
00140     //
00141     FacetRange facets_seg1 = viennagrid::ncells<CellTag::dim-1>(seg1);
00142     for (FacetIterator fit = facets_seg1.begin();
00143           fit != facets_seg1.end();
00144           ++fit)
00145     {
00146       if (is_boundary(*fit, seg1))
00147         facets_ptrs_seg1.insert( &(*fit) );
00148     }
00149     
00150     //
00151     // Step 2: Compare facet in segment 2 with those stored in the map
00152     //
00153     FacetRange facets_seg2 = viennagrid::ncells<CellTag::dim-1>(seg2);
00154     for (FacetIterator fit = facets_seg2.begin();
00155           fit != facets_seg2.end();
00156           ++fit)
00157     {
00158       if (facets_ptrs_seg1.find( &(*fit) ) != facets_ptrs_seg1.end())
00159         viennadata::access<KeyType, bool>(key)(*fit) = true;
00160     }
00161     
00162     //
00163     // Step 3: Iterate over all facets again and tag all lower level topological elements on facets that belong to the boundary:
00164     //
00165     for (FacetIterator fit = facets_seg1.begin();
00166           fit != facets_seg1.end();
00167           ++fit)
00168     {
00169       if (viennadata::find<KeyType, bool>(key)(*fit) != NULL)
00170       {
00171         if (viennadata::access<KeyType, bool>(key)(*fit) == true)
00172           interface_setter<CellTag::dim-2>::apply(*fit,
00173                                                              key,
00174                                                              typename viennagrid::result_of::bndcell_handling<ConfigType, CellTag, CellTag::dim-2>::type()
00175                                                             );
00176       }
00177     }
00178   }
00179 
00180 
00181 
00188   template <typename SegmentType, typename KeyType>
00189   void detect_interface(SegmentType const & seg1,
00190                         SegmentType const & seg2,
00191                         KeyType const & key)
00192   {
00193     typedef typename SegmentType::config_type               ConfigType;
00194     typedef typename ConfigType::cell_tag                   CellTag;
00195     typedef typename result_of::bndcell_handling<ConfigType, CellTag,
00196                                                     CellTag::dim-1>::type  HandlingTag;
00197     
00198     if (viennadata::access<KeyType, bool>(key)(seg1) == false)
00199     {
00200       detect_interface_impl(seg1, seg2, key, HandlingTag());
00201       viennadata::access<KeyType, bool>(key)(seg1) = true;
00202       viennadata::access<KeyType, bool>(key)(seg2) = true;
00203     }
00204   }
00205 
00212   template <typename ConfigType, typename ElementTag>
00213   bool is_interface(element_t<ConfigType, ElementTag> const & el,
00214                     segment_t<ConfigType> const & seg1,
00215                     segment_t<ConfigType> const & seg2)
00216   {
00217     typedef interface_key    InterfaceKey;
00218     
00219     std::size_t seg_id_lower = std::min(seg1.id(), seg2.id());
00220     std::size_t seg_id_higher = std::max(seg1.id(), seg2.id());
00221     
00222     InterfaceKey key(seg_id_lower, seg_id_higher);
00223     detect_interface(seg1, seg2, key);
00224     
00225     if (viennadata::find<InterfaceKey, bool>(key)(el) != NULL)
00226       return viennadata::access<InterfaceKey, bool>(key)(el);
00227 
00228     return false;
00229   }
00230 
00231 }
00232 
00233 #endif

Generated on Wed Sep 14 2011 19:21:30 for ViennaGrid by  doxygen 1.7.1