|
ViennaGrid
1.0.1
|
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
1.7.6.1