00001 #ifndef VIENNAGRID_DETAIL_DOMAIN_LAYERS_HPP
00002 #define VIENNAGRID_DETAIL_DOMAIN_LAYERS_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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,
00106 long dim,
00107 bool is_cell = false,
00108 typename STOR = typename viennagrid::result_of::bndcell_handling<Config, domain_t<Config>, dim>::type
00109 >
00110 class domain_layers : public domain_layers<Config,
00111 dim-1>
00112 {
00113
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
00145 ElementIterator elit = elements.find(epc);
00146
00147
00148 if (elit == elements.end())
00149 {
00150
00151 elem.id(elements.size());
00152
00153
00154
00155
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
00164 dim_type i=0; dim_type j=0;
00165
00166
00167
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);
00183
00184 break;
00185 }
00186 }
00187 j=0;
00188 }
00189
00190 return &(elit->second);
00191 }
00192
00193
00195
00196 using base_type::container;
00197
00198
00199 container_type *
00200 container(dimension_tag<dim>) { return &elements; }
00201
00202
00203 const container_type *
00204 container(dimension_tag<dim>) const { return &elements; }
00205
00206 private:
00207 container_type 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
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
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
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
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
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
00279 elements.back().fill(*this);
00280 return &(elements.back());
00281 }
00282
00283 using base_type::container;
00284
00285
00286 container_type *
00287 container(dimension_tag<dim>) { return &elements; }
00288
00289
00290 const container_type *
00291 container(dimension_tag<dim>) const { return &elements; }
00292
00293 private:
00294 container_type elements;
00295 };
00296
00297
00299 template <typename Config,
00300 bool is_cell,
00301 typename STOR >
00302 class domain_layers<Config, 0, is_cell, STOR>
00303 {
00304
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
00322
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
00335 container_type *
00336 container(dimension_tag<0>) { return &elements; }
00337
00338
00339 const container_type *
00340 container(dimension_tag<0>) const { return &elements; }
00341
00342 private:
00343 container_type elements;
00344 };
00345
00346 }
00347
00348 }
00349 #endif