ViennaGrid  1.0.1
/export/development/ViennaGrid/release/ViennaGrid-1.0.1/viennagrid/detail/domain_layers.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_DETAIL_DOMAIN_LAYERS_HPP
00002 #define VIENNAGRID_DETAIL_DOMAIN_LAYERS_HPP
00003 
00004 /* =======================================================================
00005    Copyright (c) 2011-2012, 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 <iostream>
00023 #include <vector>
00024 #include <deque>
00025 #include <list>
00026 #include <set>
00027 #include <map>
00028 #include <stack>
00029 #include <algorithm>
00030 #include "viennagrid/forwards.h"
00031 #include "viennagrid/point.hpp"
00032 #include "viennagrid/element.hpp"
00033 #include "viennagrid/detail/element_key.hpp"
00034 #include "viennagrid/detail/element_orientation.hpp"
00035 #include "viennagrid/segment.hpp"
00036 #include "viennagrid/traits/container.hpp"
00037 
00042 namespace viennagrid
00043 {
00044   namespace detail
00045   {
00047     template <typename DomainType, typename SegmentType>
00048     class domain_segment_container
00049     {
00050         typedef std::deque<SegmentType>     container_type;
00051       
00052       public:
00053         typedef typename container_type::iterator           iterator;
00054         typedef typename container_type::const_iterator     const_iterator;
00055         typedef typename container_type::value_type         value_type;
00056         typedef typename container_type::reference          reference;
00057         typedef typename container_type::const_reference    const_reference;
00058         typedef typename container_type::difference_type    difference_type;
00059         typedef typename container_type::pointer            pointer;
00060         typedef typename container_type::size_type          size_type;
00061         
00062         domain_segment_container(DomainType * d) : domain_ptr(d) {}
00063         
00064         SegmentType & operator[](std::size_t i) { return segments_[i]; }
00065         SegmentType const & operator[](std::size_t i) const { return segments_[i]; }
00066         
00067         SegmentType & at(std::size_t i) { return segments_.at(i); }
00068         SegmentType const & at(std::size_t i) const { return segments_.at(i); }
00069         
00070         std::size_t size() const { return segments_.size(); }
00071         std::size_t max_size() const { return segments_.max_size(); }
00072         bool empty() const { return segments_.empty(); }
00073         
00074         void resize(std::size_t n)
00075         {
00076           std::size_t old_size = segments_.size();
00077           segments_.resize(n);
00078           for (std::size_t i=old_size; i<n; ++i)
00079             segments_[i].domain(*domain_ptr);
00080         }
00081         
00082         iterator begin() { return segments_.begin(); }
00083         const_iterator begin() const { return segments_.begin(); }
00084         
00085         iterator end() { return segments_.end(); }
00086         const_iterator end() const { return segments_.end(); }
00087 
00088         void swap(domain_segment_container & other)
00089         {
00090           assert(domain_ptr == other.domain_ptr);
00091           segments_.swap(other.segments_);
00092         }
00093       private:
00094         container_type segments_;
00095         DomainType * domain_ptr;
00096     };
00097   
00098 
00106     template <typename Config, // config class
00107               long dim,  // dimension of the elements covered here
00108               bool is_cell = false,                   // whether this layer holds the cells (i.e. highest topological element)
00109               typename STOR = typename viennagrid::result_of::bndcell_handling<Config, domain_t<Config>, dim>::type       //Storage scheme: Full storage, or ignore layer
00110             >
00111     class domain_layers  : public domain_layers<Config,
00112                                                 dim-1>
00113     {
00114         //typedef typename result_of::tag<typename Config::cell_tag, dim>::type    tag;
00115         typedef domain_t<Config>                                                          domain_type;
00116         typedef typename topology::bndcells<typename Config::cell_tag, dim>::tag    tag;
00117         typedef topology::bndcells<tag, 0>                                       VertexOnElementSpecs;
00118         typedef element_t<Config, tag >                                              element_type;
00119         typedef element_t<Config, typename Config::cell_tag>                                   cell_type;
00120         typedef typename result_of::element_container<domain_type, dim, Config::cell_tag::dim>::type           container_type;
00121         typedef domain_layers<Config,
00122                               dim-1>                                               base_type;
00123         typedef element_orientation<VertexOnElementSpecs::num>                    ElementOrientationType;
00124         typedef element_key<Config, element_type>                                 ElementKeyType;
00125       
00126       public:
00127         typedef Config                                    config_type;
00128         
00129         using base_type::push_back;
00130         
00136         element_type *
00137         push_back(element_type & elem, ElementOrientationType * orientation) {
00138 
00139           typedef typename std::map< element_key<Config, element_type>, element_type >::iterator  ElementIterator;
00140           
00141           typedef typename result_of::ncell_range<element_type, 0>::type      VertexOnElementRange;
00142           typedef typename result_of::iterator<element_type, 0>::type         VertexOnElementIterator;
00143 
00144           ElementKeyType epc(elem);
00145           //check whether already inserted:
00146           ElementIterator elit = elements.find(epc);
00147           //std::cout << "Candidate: "; elem.print_short();
00148 
00149           if (elit == elements.end())
00150           {
00151             //provide ID for element:
00152             elem.id(elements.size());
00153 
00154             //std::cout << "ACCEPTED " << std::endl;
00155 
00156             //set default orientation:
00157             if (orientation != NULL)
00158               orientation->setDefaultOrientation();
00159 
00160             std::pair<ElementKeyType, element_type> p(epc, elem);
00161             return &((elements.insert(p).first)->second);
00162           }
00163 
00164           //std::cout << "REJECTED" << std::endl;
00165           dim_type i=0; dim_type j=0;
00166           
00167           
00168           //set orientation:
00169           VertexOnElementRange vertices_on_element = ncells<0>(elem);
00170           for (VertexOnElementIterator voeit = vertices_on_element.begin();
00171                 voeit != vertices_on_element.end();
00172                 ++voeit, ++i)
00173           {
00174               
00175               VertexOnElementRange vertices_on_element_2 = ncells<0>(elit->second);
00176               for (VertexOnElementIterator voeit2 = vertices_on_element_2.begin();
00177                     voeit2 != vertices_on_element_2.end();
00178                     ++voeit2, ++j)
00179               {
00180                 if (voeit->id() == voeit2->id())
00181                 {
00182                   if (orientation != NULL)
00183                     orientation->setPermutation(i,j);   //local (elem) to global (elit->second)
00184                     //orientation->setPermutation(j,i);   //global (elit->second) to local (elem)
00185                   break;
00186                 }
00187               }
00188               j=0;
00189           }
00190 
00191           return &(elit->second);
00192         }
00193 
00194 
00196 
00197         using base_type::container;
00198 
00199         //non-const:
00200         container_type * 
00201         container(dimension_tag<dim>) { return &elements; }
00202         
00203         //const:
00204         const container_type * 
00205         container(dimension_tag<dim>) const { return &elements; }
00206         
00207       private:
00208         container_type    elements;        //container of elements
00209     };
00210 
00212     template <typename Config,
00213               long dim>
00214     class domain_layers<Config, dim, false, no_handling_tag> : public domain_layers<Config, dim-1>
00215     {
00216         //typedef typename result_of::tag<typename Config::cell_tag, dim>::type    tag;
00217         typedef typename Config::cell_tag                                                 CellTag;
00218         typedef domain_t<Config>                                                          domain_type;
00219         typedef domain_layers<Config, dim-1>        base_type;
00220         typedef typename result_of::element_container<domain_type, dim, Config::cell_tag::dim>::type           container_type;
00221       
00222       public:
00223 
00225         using base_type::container;
00226 
00227         //non-const:
00228         container_type * 
00229         container(dimension_tag<dim>)
00230         {
00231           typedef typename result_of::bndcell_handling<Config,
00232                                                           domain_type,
00233                                                           dim
00234                                                          >::ERROR_HANDLING_OF_ELEMENTS_AT_THIS_TOPOLOGICAL_LEVEL_NOT_PROVIDED   error_type;
00235           return NULL;
00236         }
00237 
00238         //const:
00239         const container_type * 
00240         container(dimension_tag<dim>) const
00241         {
00242           typedef typename result_of::bndcell_handling<Config,
00243                                                           domain_type,
00244                                                           dim
00245                                                          >::ERROR_HANDLING_OF_ELEMENTS_AT_THIS_TOPOLOGICAL_LEVEL_NOT_PROVIDED   error_type;
00246           return NULL;
00247         }
00248     };
00249      
00250     
00251     // special handling for cells:
00253     template <typename Config,
00254               long dim>
00255     class domain_layers<Config, dim, true, full_handling_tag> : public domain_layers<Config,
00256                                                                                      dim-1>
00257     {
00258         //typedef typename result_of::tag<typename Config::cell_tag, 0>::type   tag;
00259         typedef domain_t<Config>                                                          domain_type;
00260         typedef element_t<Config, typename Config::cell_tag >                                         element_type;
00261         typedef typename result_of::element_container<domain_type,
00262                                                       Config::cell_tag::dim,
00263                                                       Config::cell_tag::dim>::type                container_type;
00264         typedef domain_layers<Config,
00265                               dim-1>                                               base_type;
00266       
00267       public:
00268         typedef Config    config_type;
00269         typedef std::size_t   size_type;
00270 
00271         using base_type::push_back;
00272         
00273         element_type * push_back(element_type & e)
00274         {
00275           assert(viennagrid::traits::capacity(elements) > elements.size() && "Not enough memory for cells reserved!");
00276           
00277           elements.push_back(e);
00278           elements.back().id(elements.size()-1);
00279           //std::cout << "Filling cell for domain " << this << std::endl;
00280           elements.back().fill(*this);
00281           return &(elements.back());
00282         }
00283         
00284         using base_type::container;
00285 
00286         //non-const:
00287         container_type * 
00288         container(dimension_tag<dim>) { return &elements; }
00289         
00290         //const:
00291         const container_type * 
00292         container(dimension_tag<dim>) const { return &elements; }
00293         
00294       private:
00295         container_type    elements;        //container of elements
00296     };
00297     
00298     //terminate recursion at vertex level:
00300     template <typename Config,
00301               bool is_cell,
00302               typename STOR >
00303     class domain_layers<Config, 0, is_cell, STOR>
00304     {
00305         //typedef typename result_of::tag<typename Config::cell_tag, 0>::type   tag;
00306         typedef typename result_of::point<Config>::type                                   PointType;
00307         typedef domain_t<Config>                                                          domain_type;
00308         typedef element_t<Config, point_tag >                                             element_type;
00309         typedef element_t<Config, typename Config::cell_tag >                             cell_type;
00310         typedef typename result_of::element_container<domain_type,
00311                                                       0,
00312                                                       Config::cell_tag::dim
00313                                                       >::type                            container_type;
00314       
00315       public:
00316         typedef Config    config_type;
00317         typedef std::size_t size_type;
00318         
00319         element_type * push_back(element_type const & e)
00320         {
00321           assert(viennagrid::traits::capacity(elements) > elements.size() && "Not enough memory for vertices reserved!");
00322           //element_type temp(e);
00323           //temp.id(elements.size());
00324           elements.push_back(e);
00325           elements.back().id(elements.size()-1);
00326           return &(elements.back());
00327         }
00328         
00329         element_type * push_back(PointType const & p)
00330         {
00331           element_type temp_vertex(p);
00332           return push_back(temp_vertex);
00333         }
00334 
00335         //non-const:
00336         container_type * 
00337         container(dimension_tag<0>) { return &elements; }
00338         
00339         //const:
00340         const container_type * 
00341         container(dimension_tag<0>) const { return &elements; }
00342         
00343       private:
00344         container_type    elements;        //container of elements
00345     };
00346 
00347   } //namespace detail
00348   
00349 } //namespace viennagrid
00350 #endif