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

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

Go to the documentation of this file.
00001 #ifndef VIENNAGRID_ALGORITHM_BOUNDARY_HPP
00002 #define VIENNAGRID_ALGORITHM_BOUNDARY_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/domain.hpp"
00024 #include "viennagrid/detail/element_iterators.hpp"
00025 #include "viennagrid/detail/domain_iterators.hpp"
00026 
00031 namespace viennagrid
00032 {
00034   template <typename T>
00035   class boundary_key
00036   {
00037     typedef typename T::ERROR_BOUNDARY_KEY_MUST_BE_USED_WITH_NCELL_OR_DOMAIN_OR_SEGMENT   error_type;
00038   };
00039   
00041   template <typename ConfigType, typename ElementTag>
00042   class boundary_key<element_t<ConfigType, ElementTag> >
00043   {
00044       typedef element_t<ConfigType, ElementTag>  element_type;
00045     
00046     public:
00047       boundary_key(element_type const & e) : e_(&e) {}
00048       
00050       bool operator<(boundary_key const & other) const
00051       {
00052         return e_ < other.e_;
00053       }
00054     private:
00055       element_type const * e_;
00056   };
00057   
00059   template <typename ConfigType>
00060   class boundary_key< segment_t<ConfigType> >
00061   {
00062     public:
00063       boundary_key(std::size_t seg_id) : seg_id_(seg_id) {}
00064       
00066       bool operator<(boundary_key const & other) const
00067       {
00068         return seg_id_ < other.seg_id_;
00069       }
00070     private:
00071       std::size_t seg_id_;
00072   };
00073   
00075   template <typename ConfigType>
00076   class boundary_key< domain_t<ConfigType> > {};
00077   
00078 }
00079 
00080 // Configure ViennaData to use a type-based dispatch on the domain
00081 
00083 namespace viennadata
00084 {
00086   namespace config
00087   {
00088     template <typename ConfigType>
00089     struct key_dispatch<viennagrid::boundary_key< viennagrid::domain_t<ConfigType> > >
00090     {
00091       typedef type_key_dispatch_tag    tag;
00092     };
00093   }
00094 }
00095   
00096 namespace viennagrid
00097 {
00098 
00103   template <long dim>
00104   struct boundary_setter
00105   {
00107     template <typename FacetType, typename KeyType>
00108     static void apply(FacetType const & facet, KeyType const & key, full_handling_tag)
00109     {
00110       typedef typename FacetType::config_type        ConfigType;
00111       typedef typename ConfigType::cell_tag          CellTag;
00112       
00113       typedef typename viennagrid::result_of::const_ncell_range<FacetType, dim>::type    ElementOnFacetRange;
00114       typedef typename result_of::iterator<ElementOnFacetRange>::type                    ElementOnFacetIterator;
00115 
00116       ElementOnFacetRange eof_container = ncells<dim>(facet);
00117       for (ElementOnFacetIterator eofit = eof_container.begin();
00118             eofit != eof_container.end();
00119             ++eofit)
00120       {
00121         viennadata::access<KeyType, bool>(key)(*eofit) = true;
00122       }
00123 
00124       //proceed to lower level:
00125       boundary_setter<dim - 1>::apply(facet,
00126                                                  key,
00127                                                  typename viennagrid::result_of::bndcell_handling<ConfigType, CellTag, dim-1>::type()
00128                                                 );
00129     }
00130     
00132     template <typename FacetType, typename KeyType>
00133     static void apply(FacetType const & facet, KeyType const & key, no_handling_tag)
00134     {
00135       typedef typename FacetType::config_type        ConfigType;
00136       typedef typename ConfigType::cell_tag          CellTag;
00137       
00138       //no elements handled at this level, thus proceed to lower level:
00139       boundary_setter<dim - 1>::apply(facet,
00140                                                  key,
00141                                                  typename viennagrid::result_of::bndcell_handling<ConfigType, CellTag, dim-1>::type()
00142                                                 );
00143     }
00144     
00145   };
00146 
00147   //end recursion of topolevel = -1
00149   template <>
00150   struct boundary_setter< -1 >
00151   {
00152     template <typename FacetType, typename KeyType, typename HandlingTag>
00153     static void apply(FacetType const & facet, KeyType const & key, HandlingTag)
00154     {
00155     }
00156   };
00157 
00159   template <typename DomainSegmentType, typename KeyType>
00160   void detect_boundary_impl(DomainSegmentType const & seg, KeyType const & key, no_handling_tag)
00161   {
00162     typedef typename DomainSegmentType::ERROR_CANNOT_DETECT_BOUNDARY_BECAUSE_FACETS_ARE_DISABLED        error_type;
00163   }
00164 
00166   template <typename DomainSegmentType, typename KeyType>
00167   void detect_boundary_impl(DomainSegmentType const & seg, KeyType const & key, full_handling_tag)
00168   {
00169     typedef typename DomainSegmentType::config_type                            ConfigType;
00170     typedef typename ConfigType::cell_tag                                      CellTag;
00171     typedef typename viennagrid::result_of::ncell<ConfigType, CellTag::dim-1>::type   FacetType;
00172     typedef typename viennagrid::result_of::ncell<ConfigType, CellTag::dim>::type     CellType;
00173 
00174     typedef typename viennagrid::result_of::const_ncell_range<DomainSegmentType, CellTag::dim-1>::type      FacetRange;
00175     typedef typename viennagrid::result_of::iterator<FacetRange>::type                                           FacetIterator;
00176       
00177     typedef typename viennagrid::result_of::const_ncell_range<DomainSegmentType, CellTag::dim>::type        CellRange;
00178     typedef typename viennagrid::result_of::iterator<CellRange>::type                                            CellIterator;
00179 
00180     typedef typename viennagrid::result_of::const_ncell_range<CellType, CellTag::dim-1>::type     FacetOnCellRange;
00181     typedef typename viennagrid::result_of::iterator<FacetOnCellRange>::type                           FacetOnCellIterator;
00182 
00183     //iterate over all cells, over facets there and tag them:
00184     CellRange cells = viennagrid::ncells<CellTag::dim>(seg);
00185     for (CellIterator cit = cells.begin();
00186           cit != cells.end();
00187           ++cit)
00188     {
00189       FacetOnCellRange facets_on_cell = ncells<CellTag::dim-1>(*cit);
00190       for (FacetOnCellIterator focit = facets_on_cell.begin();
00191             focit != facets_on_cell.end();
00192             ++focit)
00193       {
00194         bool * data_ptr = viennadata::find<KeyType, bool>(key)(*focit);
00195         if (data_ptr == NULL)  //Facet has not yet been tagged
00196         {
00197           viennadata::access<KeyType, bool>(key)(*focit) = true;
00198         }
00199         else
00200         {
00201           if (*data_ptr == false)          //mind densely stored data
00202             *data_ptr = true;
00203           else          
00204             viennadata::erase<KeyType, bool>(key)(*focit);
00205         }        
00206       }
00207     }
00208     
00209     //iterate over all facets again and tag all lower level topological elements on facets that belong to the boundary:
00210     FacetRange facets = viennagrid::ncells<CellTag::dim-1>(seg);
00211     for (FacetIterator fit = facets.begin();
00212           fit != facets.end();
00213           ++fit)
00214     {
00215       if (viennadata::find<KeyType, bool>(key)(*fit) != NULL)
00216       {
00217         if (viennadata::access<KeyType, bool>(key)(*fit) == true)
00218           boundary_setter<CellTag::dim-2>::apply(*fit,
00219                                                             key,
00220                                                             typename viennagrid::result_of::bndcell_handling<ConfigType, CellTag, CellTag::dim-2>::type()
00221                                                            );
00222       }
00223     }
00224   }
00225 
00226 
00227 
00235   template <typename DomainSegmentType, typename KeyType>
00236   void detect_boundary(DomainSegmentType const & segment, KeyType const & key)
00237   {
00238     typedef typename DomainSegmentType::config_type            ConfigType;
00239     typedef typename ConfigType::cell_tag                   CellTag;
00240     typedef typename result_of::domain<ConfigType>::type                        DomainType;
00241     typedef typename result_of::bndcell_handling<ConfigType, DomainType,
00242                                                     CellTag::dim-1>::type  HandlingTag;
00243     
00244     if (viennadata::access<KeyType, bool>(key)(segment) == false)
00245     {
00246       detect_boundary_impl(segment, key, HandlingTag());
00247       viennadata::access<KeyType, bool>(key)(segment) = true;
00248     }
00249   }
00250 
00251 
00257   template <typename ConfigType, typename ElementTag>
00258   bool is_boundary(element_t<ConfigType, ElementTag> const & el,
00259                    domain_t<ConfigType> const & domain)
00260   {
00261     typedef boundary_key<domain_t<ConfigType> >    BoundaryKey;
00262     
00263     detect_boundary(domain, BoundaryKey());
00264     if (viennadata::find<BoundaryKey, bool>()(el) != NULL)
00265     {
00266       return viennadata::access<BoundaryKey, bool>()(el);
00267     }
00268     return false;
00269   }
00270 
00276   template <typename ConfigType, typename ElementTag>
00277   bool is_boundary(element_t<ConfigType, ElementTag> const & el,
00278                    segment_t<ConfigType> const & segment)
00279   {
00280     typedef boundary_key<segment_t<ConfigType> >    BoundaryKey;
00281     
00282     BoundaryKey key(segment.id());
00283     detect_boundary(segment, key);
00284     
00285     if (viennadata::find<BoundaryKey, bool>(key)(el) != NULL)
00286     {
00287       return viennadata::access<BoundaryKey, bool>(key)(el);
00288     }
00289     return false;
00290   }
00291 
00292 }
00293 
00294 #endif

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