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

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

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