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

/export/development/ViennaGrid/release/ViennaGrid-1.0.0/viennagrid/detail/segment_layers.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAGRID_DETAIL_SEGMENT_LAYERS_HPP
00002 #define VIENNAGRID_DETAIL_SEGMENT_LAYERS_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 
00022 #include <map>
00023 #include <set>
00024 #include <deque>
00025 
00026 #include "viennagrid/forwards.h"
00027 #include "viennagrid/element.hpp"
00028 #include "viennagrid/detail/element_key.hpp"
00029 
00034 namespace viennagrid
00035 {
00036 
00038   
00039   namespace detail
00040   {
00042     struct id_ptr_compare
00043     {
00044       template <typename ElementType>
00045       bool operator()(ElementType * e1, ElementType * e2) const
00046       {
00047         return e1->id() < e2->id();
00048       }
00049     };
00050     
00052     template <typename Conf>
00053     class segment_domain_holder
00054     {
00055         typedef viennagrid::domain_t<Conf>                         domain_type;
00056       public:
00057         void domain(domain_type & d) { domain_ = &d; }
00058 
00059         domain_type & domain() { return * domain_; }
00060         domain_type const & domain() const { return * domain_; }
00061 
00062         std::size_t id() const 
00063         {
00064           for (std::size_t i=0; i<domain_->segments().size(); ++i)
00065           {
00066             if (this == &(domain_->segments()[i]))
00067               return i;
00068           }
00069           
00070           assert(false && "Segment ID cannot be found!");
00071           return domain_->segments().size();
00072         }
00073         
00074       protected:
00075         domain_type * domain_;
00076     };
00077     
00078     template <typename Config,
00079               long dim>
00080     class segment_layers_full;
00081 
00082     template <typename Config,
00083               long dim>
00084     class segment_layers_empty;
00085     
00087     template <typename Config,
00088               long dim,
00089               typename handling_tag = typename result_of::bndcell_handling<Config, segment_t<Config>, dim>::type
00090               >
00091     struct next_segment_layer_selector
00092     {
00093       typedef segment_layers_full<Config, dim>    type;
00094     };
00095     
00096     template <typename Config, long dim>
00097     struct next_segment_layer_selector<Config, dim, no_handling_tag>
00098     {
00099       typedef segment_layers_empty<Config, dim>   type;
00100     };
00101     
00102     template <typename Config, typename handling_tag>
00103     struct next_segment_layer_selector<Config, 0, handling_tag>
00104     {
00105       typedef segment_layers_full<Config, 0>    type;
00106     };
00107     
00108     
00110     template <typename Config,
00111               long dim>
00112     class segment_layers_full : //public segment_layers<Config, 0, handling_tag>
00113                           public next_segment_layer_selector<Config, dim-1>::type
00114                           //public segment_domain_holder<Config>
00115     {
00116         typedef typename Config::cell_tag                                      CellTag;
00117         typedef typename viennagrid::topology::bndcells<CellTag, dim>::tag     ElementTag;
00118         typedef viennagrid::element_t<Config, ElementTag >                                 LevelElementType;
00119         typedef typename viennagrid::topology::bndcells<CellTag, 0>::tag       VertexTag; 
00120         typedef viennagrid::element_t<Config, VertexTag >                                  VertexType;
00121         typedef viennagrid::element_t<Config, typename Config::cell_tag>                   CellType;
00122         typedef typename viennagrid::result_of::element_container< segment_t<Config>,
00123                                                       dim>::type                   container_type;
00124         typedef typename next_segment_layer_selector<Config, dim-1>::type                  base_type;
00125         
00126       public:
00127         
00128         void fill(CellType & cell)
00129         {
00130           //add vertices to segment: (note that the ncells<0>() is not available here)
00131           LevelElementType ** level_elements = cell.container(dimension_tag<dim>());
00132           for (long i=0; i<topology::bndcells<typename Config::cell_tag, dim>::num; ++i)
00133             elements.insert(level_elements[i]);
00134           
00135           base_type::fill(cell);
00136         }
00137         
00139 
00140         using base_type::container;
00141 
00142         //non-const:
00143         container_type *
00144         container(dimension_tag<dim>) { return &elements; }
00145 
00146         //const:
00147         const container_type * 
00148         container(dimension_tag<dim>) const { return &elements; }
00149         
00150         
00151       private:
00152         container_type elements;
00153     };
00154 
00155     
00156     //vertex level:
00158     template <typename Config>
00159     class segment_layers_full<Config, 0> : public segment_domain_holder<Config>
00160     {
00161         typedef typename Config::cell_tag                                 CellTag;
00162         typedef typename viennagrid::topology::bndcells<CellTag, 0>::tag    VertexTag;
00163         typedef viennagrid::element_t<Config, VertexTag >                               VertexType;
00164         typedef viennagrid::element_t<Config, typename Config::cell_tag>                CellType;
00165         typedef typename result_of::element_container< segment_t<Config>, 
00166                                                       0>::type           ContainerType;
00167         
00168       public:
00169         
00170         void fill(CellType & cell)
00171         {
00172           //add vertices to segment: (note that the ncells<0>() is not available here)
00173           VertexType ** cell_vertices = cell.container(dimension_tag<0>());
00174           for (long i=0; i<viennagrid::topology::bndcells<typename Config::cell_tag, 0>::num; ++i)
00175             elements.insert(cell_vertices[i]);
00176         }
00177         
00178         ContainerType * container(dimension_tag<0>) { return &elements; }
00179         const ContainerType * container(dimension_tag<0>) const { return &elements; }
00180 
00181       private:
00182         ContainerType    elements;        //container of elements
00183     };
00184 
00185     
00187     template <typename Config,
00188               long dim>
00189     class segment_layers_empty : public next_segment_layer_selector<Config, dim-1>::type
00190     {
00191         typedef typename Config::cell_tag                                      CellTag;
00192         typedef typename viennagrid::topology::bndcells<CellTag, dim>::tag     ElementTag;
00193         typedef viennagrid::element_t<Config, ElementTag >                                 LevelElementType;
00194         typedef typename viennagrid::topology::bndcells<CellTag, 0>::tag       VertexTag; 
00195         typedef viennagrid::element_t<Config, VertexTag >                                  VertexType;
00196         typedef viennagrid::element_t<Config, typename Config::cell_tag>                   CellType;
00197         typedef typename viennagrid::result_of::element_container< segment_t<Config>,
00198                                                       dim>::type                   container_type;
00199         typedef typename next_segment_layer_selector<Config, dim-1>::type          base_type;
00200         
00201       public:
00202         
00203         void fill(CellType & cell)
00204         {
00205           //nothing to do here. Just forward to lower level:
00206           base_type::fill(cell);
00207         }
00208         
00210 
00211         using base_type::container;
00212         
00213         //non-const:
00214         container_type * 
00215         container(dimension_tag<dim>)
00216         { 
00217           typedef typename result_of::bndcell_handling<Config,
00218                                                           CellTag,
00219                                                           dim
00220                                                          >::ERROR_HANDLING_OF_ELEMENTS_AT_THIS_TOPOLOGICAL_LEVEL_NOT_PROVIDED   error_type;
00221           return NULL; 
00222         }
00223 
00224         //const:
00225         const container_type * 
00226         container(dimension_tag<dim>) const
00227         { 
00228           typedef typename result_of::bndcell_handling<Config, 
00229                                                           CellTag,
00230                                                           dim
00231                                                          >::ERROR_HANDLING_OF_ELEMENTS_AT_THIS_TOPOLOGICAL_LEVEL_NOT_PROVIDED  error_type;
00232           return NULL; 
00233         }
00234 
00235     };
00236 
00238     template <typename Config,
00239               long dim>
00240     class segment_layers_top : public next_segment_layer_selector<Config, dim-1>::type
00241     {
00242         typedef typename Config::cell_tag                                                        CellTag;
00243         typedef typename viennagrid::topology::bndcells<typename Config::cell_tag, dim>::tag     ElementTag;
00244         typedef viennagrid::element_t<Config, ElementTag >                                                  ElementType;
00245         typedef typename viennagrid::topology::bndcells<typename Config::cell_tag, 0>::tag       VertexTag;
00246         typedef viennagrid::element_t<Config, VertexTag >                                               VertexType;
00247         typedef viennagrid::element_t<Config, typename Config::cell_tag>                                 CellType;
00248         typedef typename viennagrid::result_of::element_container< segment_t<Config>, dim>::type      container_type;
00249         typedef typename next_segment_layer_selector<Config, dim-1>::type                             base_type;
00250         
00251       public:
00252         
00253         void push_back(CellType & cell)
00254         {
00255           //add cell to domain and keep pointer in segment
00256           //std::cout << "Adding cell to domain and to segment" << std::endl;
00257           elements.push_back(base_type::domain_->push_back(cell));
00258           
00259           base_type::fill(*elements.back());
00260         }
00261         
00262         
00264 
00265         using base_type::container;
00266         
00267         //non-const:
00268         container_type *
00269         container(dimension_tag<dim>) { return &elements; }
00270 
00271         //const:
00272         const container_type * 
00273         container(dimension_tag<dim>) const { return &elements; }
00274         
00275       private:
00276         container_type elements;
00277     };
00278   
00279   } //namespace detail
00280 
00281 
00282   // a few metafunctions returning the correct container for segments:
00283   namespace result_of
00284   {
00285     //at cell level
00287     template <typename config_type, long cell_level>
00288     struct element_container< segment_t<config_type>, cell_level, cell_level>
00289     {
00290       typedef typename viennagrid::result_of::ncell<config_type, cell_level>::type     element_type;
00291       
00292       typedef std::deque< element_type * >      type;
00293     };
00294 
00295     //at vertex level
00297     template <typename config_type, long cell_level>
00298     struct element_container< segment_t<config_type>, 0, cell_level>
00299     {
00300       typedef typename viennagrid::result_of::ncell<config_type, 0>::type     element_type;
00301       
00302       // Note that with the use of deque, pointer comparison does not induce a valid ordering!
00303       // This is a problem when trying to write mesh files (vertices are not printed in order)
00304       typedef std::set< element_type *, viennagrid::detail::id_ptr_compare >      type;
00305     };
00306 
00307     //at any other level:
00309     template <typename config_type, long dim, long cell_level>
00310     struct element_container< segment_t<config_type>, dim, cell_level>
00311     {
00312       typedef typename viennagrid::result_of::ncell<config_type, dim>::type     element_type;
00313       
00314       typedef std::set< element_type * >      type;
00315     };
00316     
00318     template <typename ConfigType>
00319     struct segment
00320     {
00321       typedef segment_t<ConfigType>     type; 
00322     };
00323     
00324     
00325   } //namespace result_of
00326 
00327 } //namespace viennagrid
00328 #endif

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