ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_ELEMENT_HPP 00002 #define VIENNAGRID_ELEMENT_HPP 00003 00004 /* ======================================================================= 00005 Copyright (c) 2011-2014, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 00009 ----------------- 00010 ViennaGrid - The Vienna Grid Library 00011 ----------------- 00012 00013 License: MIT (X11), see file LICENSE in the base directory 00014 ======================================================================= */ 00015 00016 00017 #include "viennagrid/forwards.hpp" 00018 #include "viennagrid/point.hpp" 00019 #include "viennagrid/meta/typelist.hpp" 00020 #include "viennagrid/meta/algorithm.hpp" 00021 00022 #include "viennagrid/storage/collection.hpp" 00023 #include "viennagrid/storage/range.hpp" 00024 00025 #include "viennagrid/topology/simplex.hpp" 00026 #include "viennagrid/element/element_orientation.hpp" 00027 00028 #include "viennagrid/config/element_config.hpp" 00029 00034 namespace viennagrid 00035 { 00040 template<typename element_tag, typename boundary_config_typemap> 00041 class boundary_element_layer; 00042 00044 template<typename element_tag, typename bnd_cell_container_type_, typename orientation_container_type_, typename tail> 00045 class boundary_element_layer<element_tag, viennagrid::typelist< viennagrid::static_pair<bnd_cell_container_type_, orientation_container_type_>, tail > > : 00046 public boundary_element_layer<element_tag, tail> 00047 { 00048 public: 00049 typedef boundary_element_layer<element_tag, tail> base; 00050 00051 typedef bnd_cell_container_type_ bnd_cell_container_type; 00052 typedef typename bnd_cell_container_type::value_type bnd_cell_type; 00053 typedef typename bnd_cell_container_type::handle_type bnd_cell_handle_type; 00054 typedef typename bnd_cell_container_type::const_handle_type bnd_cell_const_handle_type; 00055 00056 typedef typename bnd_cell_type::tag bnd_cell_tag; 00057 static const int dim = bnd_cell_tag::dim; 00058 00059 typedef orientation_container_type_ orientation_container_type; 00060 typedef typename orientation_container_type::value_type orientation_type; 00061 00062 boundary_element_layer() {} 00063 00064 boundary_element_layer( const boundary_element_layer & llh) : base(llh), elements_(llh.elements_), orientations_(llh.orientations_) {} 00065 00066 template<typename container_typelist> 00067 void set_container( viennagrid::collection<container_typelist> & container_collection ) 00068 { 00069 elements_.set_base_container( viennagrid::get<bnd_cell_type>(container_collection) ); 00070 base::set_container( container_collection ); 00071 } 00072 00073 template<typename element_type, typename inserter_type> 00074 void create_boundary_elements(element_type & element, inserter_type & inserter) 00075 { 00076 detail::boundary_element_generator<element_tag, bnd_cell_tag, bnd_cell_type>::create_boundary_elements(element, inserter); 00077 base::create_boundary_elements(element, inserter); 00078 } 00079 00080 00081 using base::container; 00082 using base::set_boundary_element; 00083 using base::add_boundary_element; 00084 using base::dereference_handle; 00085 using base::handle; 00086 using base::global_to_local_orientation; 00087 00088 00089 bnd_cell_type & dereference_handle(bnd_cell_handle_type handle) 00090 { return elements_.dereference_handle(handle); } 00091 00092 const bnd_cell_type & dereference_handle(bnd_cell_const_handle_type handle) const 00093 { return elements_.dereference_handle(handle); } 00094 00095 00096 00097 bnd_cell_handle_type handle(bnd_cell_type & boundary_element) 00098 { return elements_.handle(boundary_element); } 00099 00100 bnd_cell_const_handle_type handle(bnd_cell_type const & boundary_element) const 00101 { return elements_.handle(boundary_element); } 00102 00103 00104 00105 bnd_cell_container_type & container(bnd_cell_tag) { return elements_; } 00106 const bnd_cell_container_type & container(bnd_cell_tag) const { return elements_; } 00107 00108 bnd_cell_container_type & container(dimension_tag<dim>) { return elements_; } 00109 const bnd_cell_container_type & container(dimension_tag<dim>) const { return elements_; } 00110 00111 00112 00113 template<typename handle_type> 00114 void set_boundary_element(const bnd_cell_type & to_insert, std::pair<handle_type, bool> inserted, std::size_t pos) 00115 { 00116 elements_.set_handle(inserted.first, pos); 00117 orientations_.resize(pos+1); 00118 00119 if (inserted.second) 00120 orientations_[pos].setDefaultOrientation(); 00121 else 00122 { 00123 typedef typename result_of::const_element_range<bnd_cell_type, vertex_tag>::type VertexOnElementConstRange; 00124 typedef typename result_of::const_iterator<VertexOnElementConstRange>::type VertexOnElementConstIterator; 00125 00126 typedef typename result_of::element_range<bnd_cell_type, vertex_tag>::type VertexOnElementRange; 00127 typedef typename result_of::iterator<VertexOnElementRange>::type VertexOnElementIterator; 00128 00129 long i=0; dim_type j=0; 00130 00131 //set orientation: 00132 VertexOnElementRange vertices_on_element = elements<vertex_tag>( elements_[pos] ); 00133 for (VertexOnElementIterator voeit = vertices_on_element.begin(); 00134 voeit != vertices_on_element.end(); 00135 ++voeit, ++i) 00136 { 00137 VertexOnElementConstRange vertices_on_element_2 = elements<vertex_tag>( to_insert ); 00138 for (VertexOnElementConstIterator voeit2 = vertices_on_element_2.begin(); 00139 voeit2 != vertices_on_element_2.end(); 00140 ++voeit2, ++j) 00141 { 00142 if (voeit.handle() == voeit2.handle()) 00143 { 00144 orientations_[pos].setPermutation(j,static_cast<dim_type>(i)); 00145 break; 00146 } 00147 } 00148 j=0; 00149 } 00150 } 00151 } 00152 00153 template<typename handle_type> 00154 void add_boundary_element(const bnd_cell_type & to_insert, std::pair<handle_type, bool> inserted) 00155 { set_boundary_element(to_insert, inserted, elements_.size()); } 00156 00157 00159 std::size_t global_to_local_orientation(bnd_cell_handle_type const & el, std::size_t index) const 00160 { 00161 for (std::size_t i=0; i<elements_.size(); ++i) 00162 { 00163 if (elements_.handle_at(i) == el) 00164 return orientations_[i](index); 00165 } 00166 assert(false && "Provided k-cell is not a boundary element of the hosting n-cell!"); 00167 return static_cast<std::size_t>(index); 00168 } 00169 00170 00171 static void print_class() 00172 { 00173 std::cout << " [ + + ] " << bnd_cell_tag::name() << std::endl; 00174 base::print_class(); 00175 } 00176 00177 void print_orientation() 00178 { 00179 std::cout << " [ + + ] " << bnd_cell_tag::name() << std::endl; 00180 for (std::size_t i = 0; i < orientations_.size(); ++i) 00181 std::cout << " " << orientations_[i] << std::endl; 00182 base::print_orientation(); 00183 } 00184 00185 private: 00186 00187 bnd_cell_container_type elements_; 00188 orientation_container_type orientations_; 00189 }; 00190 00191 00192 template<typename element_tag, typename bnd_cell_container_type_, typename tail> 00193 class boundary_element_layer<element_tag, viennagrid::typelist< viennagrid::static_pair<bnd_cell_container_type_, viennagrid::null_type>, tail > > : 00194 public boundary_element_layer<element_tag, tail> 00195 { 00196 public: 00197 typedef boundary_element_layer<element_tag, tail> base; 00198 00199 typedef bnd_cell_container_type_ bnd_cell_container_type; 00200 typedef typename bnd_cell_container_type::value_type bnd_cell_type; 00201 typedef typename bnd_cell_container_type::handle_type bnd_cell_handle_type; 00202 typedef typename bnd_cell_container_type::const_handle_type bnd_cell_const_handle_type; 00203 00204 typedef typename bnd_cell_type::tag bnd_cell_tag; 00205 static const int dim = bnd_cell_tag::dim; 00206 00207 boundary_element_layer() {} 00208 00209 boundary_element_layer( const boundary_element_layer & llh) : base(llh), elements_(llh.elements_) {} 00210 00211 template<typename container_typelist> 00212 void set_container( viennagrid::collection<container_typelist> & container_collection ) 00213 { 00214 elements_.set_base_container( viennagrid::get<bnd_cell_type>(container_collection) ); 00215 base::set_container( container_collection ); 00216 } 00217 00218 template<typename element_type, typename inserter_type> 00219 void create_boundary_elements(element_type & element, inserter_type & inserter) 00220 { 00221 detail::boundary_element_generator<element_tag, bnd_cell_tag, bnd_cell_type>::create_boundary_elements(element, inserter); 00222 base::create_boundary_elements(element, inserter); 00223 } 00224 00225 using base::container; 00226 using base::set_boundary_element; 00227 using base::add_boundary_element; 00228 using base::dereference_handle; 00229 using base::handle; 00230 00231 00232 bnd_cell_type & dereference_handle(bnd_cell_handle_type handle) 00233 { return elements_.dereference_handle(handle); } 00234 00235 const bnd_cell_type & dereference_handle(bnd_cell_const_handle_type handle) const 00236 { return elements_.dereference_handle(handle); } 00237 00238 00239 00240 bnd_cell_handle_type handle(bnd_cell_type & boundary_element) 00241 { return elements_.handle(boundary_element); } 00242 00243 bnd_cell_const_handle_type handle(bnd_cell_type const & boundary_element) const 00244 { return elements_.handle(boundary_element); } 00245 00246 00247 00248 bnd_cell_container_type & container(bnd_cell_tag) { return elements_; } 00249 const bnd_cell_container_type & container(bnd_cell_tag) const { return elements_; } 00250 00251 bnd_cell_container_type & container(dimension_tag<dim>) { return elements_; } 00252 const bnd_cell_container_type & container(dimension_tag<dim>) const { return elements_; } 00253 00254 00255 00256 template<typename handle_type> 00257 void set_boundary_element(const bnd_cell_type &, std::pair<handle_type, bool> inserted, unsigned int pos) 00258 { elements_.set_handle(inserted.first, pos); } 00259 00260 template<typename handle_type> 00261 void add_boundary_element(const bnd_cell_type & to_insert, std::pair<handle_type, bool> inserted) 00262 { set_boundary_element(to_insert, inserted, elements_.size()); } 00263 00264 static void print_class() 00265 { 00266 std::cout << " [ + - ] " << bnd_cell_tag::name() << std::endl; 00267 base::print_class(); 00268 } 00269 00270 void print_orientation() 00271 { 00272 std::cout << " [ - - ] " << bnd_cell_tag::name() << std::endl; 00273 base::print_orientation(); 00274 } 00275 00276 private: 00277 bnd_cell_container_type elements_; 00278 }; 00279 00280 template<typename element_tag> 00281 class boundary_element_layer<element_tag, viennagrid::null_type > 00282 { 00283 public: 00284 00285 boundary_element_layer() {} 00286 00287 template<typename container_typelist> 00288 void set_container( viennagrid::collection<container_typelist> & ) {} 00289 00290 template<typename element_type, typename inserter_type> 00291 void create_boundary_elements(element_type &, inserter_type &) {} 00292 00293 static void print_class() {} 00294 void print_orientation() {} 00295 00296 void container(); 00297 void set_boundary_element(); 00298 void add_boundary_element(); 00299 void dereference_handle(); 00300 void handle(); 00301 void global_to_local_orientation(); 00302 00303 private: 00304 }; 00308 namespace result_of 00309 { 00314 template<typename bnd_cell_typelist> 00315 struct boundary_element_typelist; 00316 00318 template<> 00319 struct boundary_element_typelist<viennagrid::null_type> 00320 { 00321 typedef viennagrid::null_type type; 00322 }; 00323 00324 template<typename boundary_cell_container_type, typename orientation_container_type, typename tail> 00325 struct boundary_element_typelist< viennagrid::typelist<viennagrid::static_pair<boundary_cell_container_type, orientation_container_type>, tail > > 00326 { 00327 typedef viennagrid::typelist< 00328 typename boundary_cell_container_type::value_type, 00329 typename boundary_element_typelist<tail>::type 00330 > type; 00331 }; 00332 00333 template<typename element_tag, typename WrappedConfigType> 00334 struct boundary_element_typelist< viennagrid::element<element_tag, WrappedConfigType> > 00335 { 00336 typedef typename boundary_element_typelist<typename viennagrid::element<element_tag, WrappedConfigType>::bnd_cell_container_typelist>::type type; 00337 }; 00345 template<typename bnd_cell_typelist> 00346 struct boundary_element_taglist {}; 00347 00349 template<> 00350 struct boundary_element_taglist<viennagrid::null_type> 00351 { 00352 typedef viennagrid::null_type type; 00353 }; 00354 00355 template<typename boundary_cell_container_type, typename orientation_container_type, typename tail> 00356 struct boundary_element_taglist< viennagrid::typelist<viennagrid::static_pair<boundary_cell_container_type, orientation_container_type>, tail > > 00357 { 00358 typedef viennagrid::typelist< 00359 typename boundary_cell_container_type::value_type::tag, 00360 typename boundary_element_taglist<tail>::type 00361 > type; 00362 }; 00363 00364 template<typename element_tag, typename WrappedConfigType> 00365 struct boundary_element_taglist< viennagrid::element<element_tag, WrappedConfigType> > 00366 { 00367 typedef typename boundary_element_taglist< typename viennagrid::element<element_tag, WrappedConfigType>::bnd_cell_container_typelist >::type type; 00368 }; 00369 00370 00371 00372 00373 00374 template<typename typelist, typename tag> 00375 struct container_of_tag_for_element; 00376 00377 template<typename tag> 00378 struct container_of_tag_for_element< viennagrid::null_type, tag > 00379 { 00380 typedef viennagrid::null_type type; 00381 }; 00382 00383 template<typename container_pair, typename tail, typename tag> 00384 struct container_of_tag_for_element< viennagrid::typelist<container_pair, tail>, tag > 00385 { 00386 typedef typename container_pair::first container_type; 00387 typedef typename container_type::value_type value_type; 00388 00389 typedef typename viennagrid::detail::IF< 00390 viennagrid::detail::EQUAL<typename value_type::tag, tag>::value, 00391 container_type, 00392 typename container_of_tag_for_element<tail, tag>::type 00393 >::type type; 00394 }; 00395 00396 00397 00398 00399 00400 template<typename typelist, int dim> 00401 struct container_of_dimension_for_element; 00402 00403 template<int dim> 00404 struct container_of_dimension_for_element< viennagrid::null_type, dim > 00405 { 00406 typedef viennagrid::null_type type; 00407 }; 00408 00409 template<typename container_pair, typename tail, int dim> 00410 struct container_of_dimension_for_element< viennagrid::typelist<container_pair, tail>, dim > 00411 { 00412 typedef typename container_pair::first container_type; 00413 typedef typename container_type::value_type value_type; 00414 00415 typedef typename viennagrid::detail::IF< 00416 value_type::tag::dim == dim, 00417 container_type, 00418 typename container_of_dimension_for_element<tail, dim>::type 00419 >::type type; 00420 }; 00421 00422 00423 00424 template<typename container_collection_typemap, typename element_tag> 00425 struct container_of_tag_for_collection; 00426 00427 template<typename element_tag> 00428 struct container_of_tag_for_collection<viennagrid::null_type, element_tag> 00429 { 00430 typedef viennagrid::null_type type; 00431 }; 00432 00433 template<typename element_type, typename container_type, typename tail, typename element_tag> 00434 struct container_of_tag_for_collection<viennagrid::typelist< viennagrid::static_pair<element_type, container_type>, tail >, element_tag> 00435 { 00436 typedef typename viennagrid::detail::IF< 00437 viennagrid::detail::EQUAL<typename element_type::tag, element_tag>::value, 00438 container_type, 00439 typename container_of_tag_for_collection<tail, element_tag>::type 00440 >::type type; 00441 }; 00442 00443 00444 00445 template<typename container_collection_typemap, int dim> 00446 struct container_of_dimension_for_collection; 00447 00448 template<int dim> 00449 struct container_of_dimension_for_collection<viennagrid::null_type, dim> 00450 { 00451 typedef viennagrid::null_type type; 00452 }; 00453 00454 template<typename element_type, typename container_type, typename tail, int dim> 00455 struct container_of_dimension_for_collection<viennagrid::typelist< viennagrid::static_pair<element_type, container_type>, tail >, dim> 00456 { 00457 typedef typename viennagrid::detail::IF< 00458 element_type::tag::dim == dim, 00459 container_type, 00460 typename container_of_dimension_for_collection<tail, dim>::type 00461 >::type type; 00462 }; 00463 00464 00465 00466 00467 template<typename element_or_collection, typename tag> 00468 struct container_of_tag; 00469 00470 template<typename container_collection_typemap, typename tag> 00471 struct container_of_tag< collection<container_collection_typemap>, tag > 00472 { 00473 typedef typename container_of_tag_for_collection<container_collection_typemap, tag>::type type; 00474 }; 00475 00476 template<typename element_tag, typename WrappedConfigType, typename tag> 00477 struct container_of_tag< viennagrid::element<element_tag, WrappedConfigType>, tag > 00478 { 00479 typedef typename container_of_tag_for_element<typename viennagrid::element<element_tag, WrappedConfigType>::bnd_cell_container_typelist, tag>::type type; 00480 }; 00481 00482 template<typename element_or_collection, long dim> 00483 struct container_of_dimension; 00484 00485 template<typename container_collection_typemap, long dim> 00486 struct container_of_dimension< collection<container_collection_typemap>, dim > 00487 { 00488 typedef typename container_of_dimension_for_collection<container_collection_typemap, dim>::type type; 00489 }; 00490 00491 template<typename element_tag, typename WrappedConfigType, long dim> 00492 struct container_of_dimension< viennagrid::element<element_tag, WrappedConfigType>, dim > 00493 { 00494 typedef typename container_of_dimension_for_element<typename viennagrid::element<element_tag, WrappedConfigType>::bnd_cell_container_typelist, dim>::type type; 00495 }; 00498 } 00499 00500 00501 00502 namespace config 00503 { 00505 template<typename bnd_cell_container_typelist_, typename id_tag_, typename appendix_type_> 00506 struct element_config_wrapper_t 00507 { 00508 typedef bnd_cell_container_typelist_ bnd_cell_container_typelist; 00509 typedef id_tag_ id_tag; 00510 typedef appendix_type_ appendix_type; 00511 }; 00513 } 00514 00515 00516 00522 template<typename ElementTagT> 00523 class element_extension {}; 00524 00530 template<typename ElementTag, typename WrappedConfigType> 00531 class element : 00532 public boundary_element_layer<ElementTag, typename config::result_of::element_boundary_element_container_typelist<WrappedConfigType, ElementTag>::type>, 00533 public viennagrid::detail::id_handler< 00534 typename viennagrid::detail::result_of::make_id< 00535 viennagrid::element< 00536 ElementTag, 00537 WrappedConfigType 00538 >, 00539 typename config::result_of::query_element_id_tag<WrappedConfigType, ElementTag>::type 00540 >::type 00541 >, 00542 public element_extension<ElementTag> 00543 { 00544 public: 00545 00546 typedef viennagrid::detail::id_handler< 00547 typename viennagrid::detail::result_of::make_id< 00548 viennagrid::element< 00549 ElementTag, 00550 WrappedConfigType 00551 >, 00552 typename config::result_of::query_element_id_tag<WrappedConfigType, ElementTag>::type 00553 >::type 00554 > id_handler_type; 00555 00556 typedef ElementTag tag; 00557 00558 typedef typename config::result_of::element_boundary_element_container_typelist<WrappedConfigType, ElementTag>::type bnd_cell_container_typelist; 00559 typedef typename config::result_of::query_element_id_tag<WrappedConfigType, ElementTag>::type id_tag; 00560 typedef typename config::result_of::query_appendix_type<WrappedConfigType, ElementTag>::type appendix_type; 00561 00562 typedef boundary_element_layer<ElementTag, bnd_cell_container_typelist> base; 00563 00564 typedef typename result_of::boundary_element_typelist<bnd_cell_container_typelist>::type boundary_cell_typelist; 00565 00566 typedef typename viennagrid::detail::result_of::make_id< viennagrid::element<ElementTag, WrappedConfigType>, id_tag>::type id_type; 00567 typedef typename viennagrid::detail::result_of::const_id<id_type>::type const_id_type; 00568 00569 template<typename container_typelist> 00570 element( viennagrid::collection<container_typelist> & container_collection ) 00571 { 00572 base::set_container(container_collection); 00573 } 00574 00575 template<typename inserter_type> 00576 void insert_callback( inserter_type & inserter, bool inserted ) 00577 { 00578 if (inserted) 00579 { 00580 base::create_boundary_elements(*this, inserter); 00581 } 00582 } 00583 00584 static void print_class() 00585 { 00586 std::cout << ElementTag::name() << std::endl; 00587 base::print_class(); 00588 } 00589 00590 void print_orientation() 00591 { 00592 std::cout << ElementTag::name() << std::endl; 00593 base::print_orientation(); 00594 } 00595 00596 00597 typedef typename result_of::container_of_dimension_for_element< bnd_cell_container_typelist, 0>::type::handle_type vertex_handle_type; 00598 void set_vertex( const vertex_handle_type & vertex, unsigned int pos ) 00599 { 00600 this->container(viennagrid::dimension_tag<0>()).set_handle( vertex, pos ); 00601 } 00602 00603 appendix_type & appendix() { return appendix_; } 00604 appendix_type const & appendix() const { return appendix_; } 00605 00606 private: 00607 appendix_type appendix_; 00608 }; 00609 00610 00611 // separate specialization for vertices at the moment 00613 template<typename WrappedConfigType> 00614 class element<vertex_tag, WrappedConfigType> : 00615 public viennagrid::detail::id_handler< 00616 typename viennagrid::detail::result_of::make_id< 00617 viennagrid::element< 00618 vertex_tag, 00619 WrappedConfigType 00620 >, 00621 typename config::result_of::query_element_id_tag<WrappedConfigType, vertex_tag>::type 00622 >::type 00623 >, 00624 public element_extension<vertex_tag> 00625 { 00626 public: 00627 00628 typedef viennagrid::detail::id_handler< 00629 typename viennagrid::detail::result_of::make_id< 00630 viennagrid::element< 00631 vertex_tag, 00632 WrappedConfigType 00633 >, 00634 typename config::result_of::query_element_id_tag<WrappedConfigType, vertex_tag>::type 00635 >::type 00636 > id_handler_type; 00637 00638 typedef vertex_tag tag; 00639 00640 typedef typename config::result_of::element_boundary_element_container_typelist<WrappedConfigType, vertex_tag>::type bnd_cell_container_typelist; 00641 typedef typename config::result_of::query_element_id_tag<WrappedConfigType, vertex_tag>::type id_tag; 00642 typedef typename config::result_of::query_appendix_type<WrappedConfigType, vertex_tag>::type appendix_type; 00643 00644 typedef viennagrid::element<vertex_tag, WrappedConfigType> self_type; 00645 00646 element() {} 00647 00648 template<typename container_typelist> 00649 element( viennagrid::collection<container_typelist> & ) {} 00650 00651 typedef typename result_of::boundary_element_typelist<bnd_cell_container_typelist>::type boundary_cell_typelist; 00652 typedef typename viennagrid::detail::result_of::make_id< viennagrid::element<vertex_tag, WrappedConfigType>, id_tag>::type id_type; 00653 typedef typename viennagrid::detail::result_of::const_id<id_type>::type const_id_type; 00654 00655 template<typename inserter_type> 00656 void insert_callback( inserter_type &, bool ) {} 00657 00658 void print_orientation() 00659 { 00660 std::cout << vertex_tag::name() << std::endl; 00661 } 00662 00663 static void print_class() 00664 { 00665 std::cout << vertex_tag::name() << std::endl; 00666 } 00667 00668 appendix_type & appendix() { return appendix_; } 00669 appendix_type const & appendix() const { return appendix_; } 00670 00671 private: 00672 appendix_type appendix_; 00673 }; 00678 namespace result_of 00679 { 00681 template<typename element_type_or_tag> 00682 struct topologic_dimension 00683 { 00684 static const int value = element_tag<element_type_or_tag>::type::dim; 00685 }; 00686 00687 00693 template<typename element_type, typename boundary_cell_type_or_tag> 00694 struct has_boundary 00695 {}; 00696 00698 template<typename element_tag_, typename WrappedConfigType, typename boundary_cell_type_or_tag> 00699 struct has_boundary< viennagrid::element<element_tag_, WrappedConfigType>, boundary_cell_type_or_tag > 00700 { 00701 typedef typename element_tag<boundary_cell_type_or_tag>::type boundary_cell_tag; 00702 00703 const static bool value = 00704 !viennagrid::detail::EQUAL< 00705 typename container_of_tag< viennagrid::element<element_tag_, WrappedConfigType>, boundary_cell_tag >::type, 00706 viennagrid::null_type>::value; 00707 }; 00708 00709 00710 00711 00712 // Defines a SUB-ELEMENT from an ELEMENT using SUB-ELEMENT TYPE or TAG 00713 template<typename element_tag_, typename WrappedConfigType, typename sub_element_type_or_tag> 00714 struct element< viennagrid::element<element_tag_, WrappedConfigType>, sub_element_type_or_tag > 00715 { 00716 typedef typename viennagrid::element<element_tag_, WrappedConfigType>::bnd_cell_container_typelist boundary_cell_container_typelist; 00717 typedef typename element_tag<sub_element_type_or_tag>::type sub_element_tag; 00718 typedef typename container_of_tag_for_element<boundary_cell_container_typelist , sub_element_tag >::type::value_type type; 00719 }; 00720 00721 template<typename element_tag_, typename WrappedConfigType, typename sub_element_type_or_tag> 00722 struct element< const viennagrid::element<element_tag_, WrappedConfigType>, sub_element_type_or_tag > 00723 { 00724 typedef typename viennagrid::element<element_tag_, WrappedConfigType>::bnd_cell_container_typelist boundary_cell_container_typelist; 00725 typedef typename element_tag<sub_element_type_or_tag>::type sub_element_tag; 00726 typedef const typename container_of_tag_for_element< boundary_cell_container_typelist, sub_element_tag >::type::value_type type; 00727 }; 00728 00729 // Defines a HOOK TO a SUB-ELEMENT from an ELEMENT using SUB-ELEMENT TYPE or TAG 00730 template<typename element_tag_, typename WrappedConfigType, typename sub_element_type_or_tag> 00731 struct handle< viennagrid::element<element_tag_, WrappedConfigType>, sub_element_type_or_tag > 00732 { 00733 typedef typename viennagrid::element<element_tag_, WrappedConfigType>::bnd_cell_container_typelist boundary_cell_container_typelist; 00734 typedef typename element_tag<sub_element_type_or_tag>::type sub_element_tag; 00735 typedef typename container_of_tag_for_element< boundary_cell_container_typelist, sub_element_tag >::type::handle_type type; 00736 }; 00737 00738 // Defines a const HOOK TO a SUB-ELEMENT from an ELEMENT using SUB-ELEMENT TYPE or TAG 00739 template<typename element_tag_, typename WrappedConfigType, typename sub_element_type_or_tag> 00740 struct const_handle< viennagrid::element<element_tag_, WrappedConfigType>, sub_element_type_or_tag > 00741 { 00742 typedef typename viennagrid::element<element_tag_, WrappedConfigType>::bnd_cell_container_typelist boundary_cell_container_typelist; 00743 typedef typename element_tag<sub_element_type_or_tag>::type sub_element_tag; 00744 typedef typename container_of_tag_for_element< boundary_cell_container_typelist, sub_element_tag >::type::const_handle_type type; 00745 }; 00746 00747 00748 template<typename element_tag_, typename WrappedConfigType, typename sub_element_type_or_tag> 00749 struct element_range< viennagrid::element<element_tag_, WrappedConfigType>, sub_element_type_or_tag > 00750 { 00751 typedef typename viennagrid::element<element_tag_, WrappedConfigType>::bnd_cell_container_typelist boundary_cell_container_typelist; 00752 typedef typename element< viennagrid::element<element_tag_, WrappedConfigType>, sub_element_type_or_tag>::type sub_element_type; 00753 typedef viennagrid::detail::container_range_wrapper< typename container_of_tag_for_element<boundary_cell_container_typelist, typename sub_element_type::tag>::type > type; 00754 }; 00755 00756 template<typename element_tag_, typename WrappedConfigType, typename sub_element_type_or_tag> 00757 struct const_element_range< viennagrid::element<element_tag_, WrappedConfigType>, sub_element_type_or_tag > 00758 { 00759 typedef typename viennagrid::element<element_tag_, WrappedConfigType>::bnd_cell_container_typelist boundary_cell_container_typelist; 00760 typedef typename element< viennagrid::element<element_tag_, WrappedConfigType>, sub_element_type_or_tag>::type sub_element_type; 00761 typedef viennagrid::detail::container_range_wrapper< const typename container_of_tag_for_element<boundary_cell_container_typelist, typename sub_element_type::tag>::type > type; 00762 }; 00763 00764 template<typename element_tag_, typename WrappedConfigType, typename sub_element_type_or_tag> 00765 struct element_range< const viennagrid::element<element_tag_, WrappedConfigType>, sub_element_type_or_tag > 00766 { 00767 typedef typename const_element_range< viennagrid::element<element_tag_, WrappedConfigType>, sub_element_type_or_tag >::type type; 00768 }; 00769 00770 template<typename element_tag_, typename WrappedConfigType, typename sub_element_type_or_tag> 00771 struct const_element_range< const viennagrid::element<element_tag_, WrappedConfigType>, sub_element_type_or_tag > 00772 { 00773 typedef typename const_element_range< viennagrid::element<element_tag_, WrappedConfigType>, sub_element_type_or_tag >::type type; 00774 }; 00775 00776 00777 00778 template<typename container_collection_typemap, typename element_type_or_tag> 00779 struct element<viennagrid::collection<container_collection_typemap>, element_type_or_tag> 00780 { 00781 typedef typename element_tag<element_type_or_tag>::type element_tag; 00782 typedef typename container_of_tag_for_collection<container_collection_typemap, element_tag>::type::value_type type; 00783 }; 00784 00785 template<typename container_collection_typemap, typename element_type_or_tag> 00786 struct handle<viennagrid::collection<container_collection_typemap>, element_type_or_tag> 00787 { 00788 typedef typename element_tag<element_type_or_tag>::type element_tag; 00789 00790 // Error in line below possibly means that there is no element_type_or_tag in 00791 typedef typename container_of_tag_for_collection<container_collection_typemap, element_tag>::type::handle_type type; 00792 }; 00793 00794 template<typename container_collection_typemap, typename element_type_or_tag> 00795 struct const_handle<viennagrid::collection<container_collection_typemap>, element_type_or_tag> 00796 { 00797 typedef typename element_tag<element_type_or_tag>::type element_tag; 00798 typedef typename container_of_tag_for_collection<container_collection_typemap, element_tag>::type::const_handle_type type; 00799 }; 00800 00801 00802 template<typename container_collection_typemap, typename element_type_or_tag> 00803 struct element_range<viennagrid::collection<container_collection_typemap>, element_type_or_tag> 00804 { 00805 typedef typename element_tag<element_type_or_tag>::type element_tag_; 00806 typedef viennagrid::detail::container_range_wrapper< typename container_of_tag_for_collection<container_collection_typemap, element_tag_>::type > type; 00807 }; 00808 00809 template<typename container_collection_typemap, typename element_type_or_tag> 00810 struct const_element_range<viennagrid::collection<container_collection_typemap>, element_type_or_tag> 00811 { 00812 typedef typename element_tag<element_type_or_tag>::type element_tag_; 00813 typedef viennagrid::detail::container_range_wrapper< const typename container_of_tag_for_collection<container_collection_typemap, element_tag_>::type > type; 00814 }; 00815 00816 template<typename container_collection_typemap, typename element_type_or_tag> 00817 struct element_range< const viennagrid::collection<container_collection_typemap>, element_type_or_tag> 00818 { 00819 typedef typename const_element_range<viennagrid::collection<container_collection_typemap>, element_type_or_tag>::type type; 00820 }; 00821 00822 template<typename container_collection_typemap, typename element_type_or_tag> 00823 struct const_element_range< const viennagrid::collection<container_collection_typemap>, element_type_or_tag> 00824 { 00825 typedef typename const_element_range<viennagrid::collection<container_collection_typemap>, element_type_or_tag>::type type; 00826 }; 00828 } 00829 00830 00831 00832 // doxygen docu in forwards.hpp 00833 template<typename sub_element_type_or_tag, typename element_tag, typename WrappedConfigType> 00834 typename result_of::element_range<viennagrid::element<element_tag, WrappedConfigType>, sub_element_type_or_tag>::type 00835 elements( viennagrid::element<element_tag, WrappedConfigType> & element) 00836 { 00837 typedef typename result_of::element<viennagrid::element<element_tag, WrappedConfigType>, sub_element_type_or_tag>::type sub_element_type; 00838 return typename result_of::element_range<viennagrid::element<element_tag, WrappedConfigType>, sub_element_type_or_tag>::type( element.container( typename sub_element_type::tag() ) ); 00839 } 00840 00841 // doxygen docu in forwards.hpp 00842 template<typename sub_element_type_or_tag, typename element_tag, typename WrappedConfigType> 00843 typename result_of::const_element_range<viennagrid::element<element_tag, WrappedConfigType>, sub_element_type_or_tag>::type 00844 elements( const viennagrid::element<element_tag, WrappedConfigType> & element) 00845 { 00846 typedef typename result_of::element<viennagrid::element<element_tag, WrappedConfigType>, sub_element_type_or_tag>::type sub_element_type; 00847 return typename result_of::const_element_range<viennagrid::element<element_tag, WrappedConfigType>, sub_element_type_or_tag>::type( element.container( typename sub_element_type::tag() ) ); 00848 } 00849 00850 00851 00858 template<typename element_tag, typename WrappedConfigType, typename handle_type> 00859 typename detail::result_of::value_type<handle_type>::type & dereference_handle( viennagrid::element<element_tag, WrappedConfigType> & element, handle_type const & handle) 00860 { 00861 return element.dereference_handle(handle); 00862 } 00863 00870 template<typename element_tag, typename WrappedConfigType, typename handle_type> 00871 const typename detail::result_of::value_type<handle_type>::type & dereference_handle( viennagrid::element<element_tag, WrappedConfigType> const & element, handle_type const & handle) 00872 { 00873 return element.dereference_handle(handle); 00874 } 00875 00876 00878 template<typename ElementTag1, typename WrappedConfigType1, typename ElementTag2, typename WrappedConfigType2> 00879 typename result_of::handle<viennagrid::element<ElementTag1, WrappedConfigType1>, viennagrid::element<ElementTag2, WrappedConfigType2> >::type 00880 handle( viennagrid::element<ElementTag1, WrappedConfigType1> & element, viennagrid::element<ElementTag2, WrappedConfigType2> & boundary_element ) 00881 { 00882 return element.handle(boundary_element); 00883 } 00884 00886 template<typename ElementTag1, typename WrappedConfigType1, typename ElementTag2, typename WrappedConfigType2> 00887 typename result_of::const_handle<viennagrid::element<ElementTag1, WrappedConfigType1>, viennagrid::element<ElementTag2, WrappedConfigType2> >::type 00888 handle( viennagrid::element<ElementTag1, WrappedConfigType1> const & element, viennagrid::element<ElementTag2, WrappedConfigType2> const & boundary_element ) 00889 { 00890 return element.handle(boundary_element); 00891 } 00892 00893 00894 00895 00903 template<typename element_type_or_tag, typename container_collection_typemap> 00904 typename result_of::element_range<collection<container_collection_typemap>, element_type_or_tag>::type elements( collection<container_collection_typemap> & collection) 00905 { 00906 typedef typename result_of::element<viennagrid::collection<container_collection_typemap>, element_type_or_tag>::type element_type; 00907 return typename result_of::element_range<viennagrid::collection<container_collection_typemap>, element_type_or_tag>::type( get<element_type>(collection) ); 00908 } 00909 00917 template<typename element_type_or_tag, typename container_collection_typemap> 00918 typename result_of::const_element_range<collection<container_collection_typemap>, element_type_or_tag>::type elements( const collection<container_collection_typemap> & collection) 00919 { 00920 typedef typename result_of::element<viennagrid::collection<container_collection_typemap>, element_type_or_tag>::type element_type; 00921 return typename result_of::const_element_range<viennagrid::collection<container_collection_typemap>, element_type_or_tag>::type( get<element_type>(collection) ); 00922 } 00923 00924 00925 00926 00927 namespace detail 00928 { 00929 00931 template<typename ElementT, typename FunctorT> 00932 struct for_each_boundary_element_functor 00933 { 00934 public: 00935 00936 for_each_boundary_element_functor( ElementT & element_, FunctorT functor_ ) : element(element_), functor(functor_) {} 00937 00938 template<typename boundary_cell_type> 00939 void operator()( viennagrid::detail::tag<boundary_cell_type> ) 00940 { 00941 typedef typename viennagrid::result_of::element_range<ElementT, boundary_cell_type>::type boundary_cell_range_type; 00942 typedef typename viennagrid::result_of::iterator<boundary_cell_range_type>::type boundary_cell_iterator_type; 00943 00944 boundary_cell_range_type range = viennagrid::elements<boundary_cell_type>( element ); 00945 for (boundary_cell_iterator_type it = range.begin(); it != range.end(); ++it) 00946 functor(*it); 00947 } 00948 00949 private: 00950 ElementT & element; 00951 FunctorT functor; 00952 }; 00953 00954 } // namespace detail 00955 00957 template<typename BoundaryElementTypelistT, typename ElementT, typename FunctorT> 00958 void for_each_boundary_element( ElementT & element, FunctorT functor ) 00959 { 00960 detail::for_each_boundary_element_functor<ElementT, FunctorT> for_each_functor( element, functor ); 00961 00962 viennagrid::detail::for_each<BoundaryElementTypelistT>(for_each_functor); 00963 } 00964 00965 template<typename ElementT, typename FunctorT> 00966 void for_each_boundary_element( ElementT & element, FunctorT functor ) 00967 { 00968 for_each_boundary_element<typename ElementT::boundary_cell_typelist>( element, functor ); 00969 } 00970 00971 00972 00973 00974 inline std::ostream & operator<<(std::ostream & os, viennagrid::null_type) { return os; } 00975 00976 00978 template <typename WrappedConfigType> 00979 std::ostream & operator<<(std::ostream & os, viennagrid::element<vertex_tag, WrappedConfigType> const & el) 00980 { 00981 os << "-- Vertex, ID: " << el.id() << " " << el.appendix(); 00982 00983 return os; 00984 } 00985 00986 00988 template <typename element_tag, typename WrappedConfigType> 00989 std::ostream & operator<<(std::ostream & os, viennagrid::element<element_tag, WrappedConfigType> const & el) 00990 { 00991 typedef viennagrid::element<element_tag, WrappedConfigType> element_type; 00992 typedef typename viennagrid::result_of::const_element_range< element_type, vertex_tag >::type vertex_range; 00993 typedef typename viennagrid::result_of::const_iterator< vertex_range >::type const_vertex_iterator; 00994 00995 00996 os << "-- " << element_tag::name() << ", ID: " << el.id() << " --"; 00997 const vertex_range & vertices = elements<vertex_tag>(el); 00998 for (const_vertex_iterator vit = vertices.begin(); 00999 vit != vertices.end(); 01000 ++vit) 01001 os << std::endl << " " << *vit; 01002 01003 return os; 01004 } 01005 01006 } 01007 01008 01009 #endif