ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_CONFIG_TOPOLOGY_CONFIG_HPP 00002 #define VIENNAGRID_CONFIG_TOPOLOGY_CONFIG_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 #include "viennagrid/accessor.hpp" 00017 00018 #include "viennagrid/config/config.hpp" 00019 #include "viennagrid/config/id_generator_config.hpp" 00020 00021 00022 #include "viennagrid/topology/simplex.hpp" 00023 #include "viennagrid/storage/hidden_key_map.hpp" 00024 #include "viennagrid/element/element_key.hpp" 00025 #include "viennagrid/config/element_config.hpp" 00026 00031 namespace viennagrid 00032 { 00033 namespace config 00034 { 00035 namespace result_of 00036 { 00037 // 00038 // Meta Functions for creating a default config 00039 // 00040 00042 template<typename ElementTagT, typename boundary_cell_tag> 00043 struct storage_layout_config 00044 { 00045 typedef typename viennagrid::detail::result_of::insert< 00046 typename storage_layout_config<ElementTagT, typename boundary_cell_tag::facet_tag>::type, 00047 viennagrid::static_pair< 00048 boundary_cell_tag, 00049 viennagrid::full_handling_tag 00050 > 00051 >::type type; 00052 }; 00053 00054 template<typename ElementTagT> 00055 struct storage_layout_config<ElementTagT, viennagrid::vertex_tag> 00056 { 00057 typedef typename viennagrid::make_typemap< 00058 viennagrid::vertex_tag, 00059 viennagrid::no_orientation_handling_tag 00060 >::type type; 00061 }; 00062 00063 template<typename ElementTagT> 00064 struct storage_layout_config<ElementTagT, viennagrid::null_type> 00065 { 00066 typedef viennagrid::null_type type; 00067 }; 00068 00069 00071 template<typename ElementTagT, typename boundary_cell_tag, typename VertexContainerT, typename CellContainerT> 00072 struct default_container_tag 00073 { 00074 typedef viennagrid::hidden_key_map_tag< viennagrid::element_key_tag > type; 00075 }; 00076 00077 template<typename ElementTagT, typename VertexContainerT, typename CellContainerT> 00078 struct default_container_tag<ElementTagT, ElementTagT, VertexContainerT, CellContainerT> 00079 { 00080 typedef CellContainerT type; 00081 }; 00082 00083 template<typename ElementTagT, typename VertexContainerT, typename CellContainerT> 00084 struct default_container_tag<ElementTagT, viennagrid::vertex_tag, VertexContainerT, CellContainerT> 00085 { 00086 typedef VertexContainerT type; 00087 }; 00088 00089 template<typename VertexContainerT, typename CellContainerT> 00090 struct default_container_tag<viennagrid::vertex_tag, viennagrid::vertex_tag, VertexContainerT, CellContainerT> 00091 { 00092 typedef VertexContainerT type; 00093 }; 00094 00095 00097 template<typename CellTagT, typename ElementTagT, typename HandleTagT, typename VertexContainerT, typename CellContainerT> 00098 struct full_element_config 00099 { 00100 typedef typename viennagrid::result_of::handled_container<typename default_container_tag<CellTagT, ElementTagT, VertexContainerT, CellContainerT>::type, 00101 HandleTagT>::tag container_tag; 00102 00103 typedef typename storage_layout_config<CellTagT, 00104 typename ElementTagT::facet_tag>::type boundary_storage_layout; 00105 00106 typedef typename viennagrid::make_typemap< 00107 viennagrid::config::element_id_tag, 00108 viennagrid::smart_id_tag<int>, 00109 00110 viennagrid::config::element_container_tag, 00111 container_tag, 00112 00113 viennagrid::config::element_boundary_storage_layout_tag, 00114 boundary_storage_layout, 00115 00116 viennagrid::config::element_appendix_type_tag, 00117 viennagrid::null_type 00118 >::type type; 00119 }; 00120 00121 template<typename CellTagT, typename HandleTagT, typename VertexContainerT, typename CellContainerT> 00122 struct full_element_config<CellTagT, viennagrid::vertex_tag, HandleTagT, VertexContainerT, CellContainerT> 00123 { 00124 typedef typename viennagrid::result_of::handled_container<typename default_container_tag<CellTagT, viennagrid::vertex_tag, VertexContainerT, CellContainerT>::type, 00125 HandleTagT>::tag container_tag; 00126 00127 typedef typename viennagrid::make_typemap< 00128 viennagrid::config::element_id_tag, 00129 viennagrid::smart_id_tag<int>, 00130 00131 viennagrid::config::element_container_tag, 00132 container_tag, 00133 00134 viennagrid::config::element_boundary_storage_layout_tag, 00135 viennagrid::null_type, 00136 00137 viennagrid::config::element_appendix_type_tag, 00138 viennagrid::null_type 00139 >::type type; 00140 }; 00141 00142 00144 template<typename CellTagT, typename ElementTagT, typename HandleTagT, typename VertexContainerTagT, typename CellContainerTagT> 00145 struct full_topology_config_helper 00146 { 00147 typedef typename viennagrid::detail::result_of::insert< 00148 typename full_topology_config_helper<CellTagT, typename ElementTagT::facet_tag, HandleTagT, VertexContainerTagT, CellContainerTagT>::type, 00149 viennagrid::static_pair< 00150 ElementTagT, 00151 typename full_element_config<CellTagT, ElementTagT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type 00152 > 00153 >::type type; 00154 }; 00155 00156 template<typename CellTagT, typename HandleTagT, typename VertexContainerTagT, typename CellContainerTagT> 00157 struct full_topology_config_helper<CellTagT, viennagrid::vertex_tag, HandleTagT, VertexContainerTagT, CellContainerTagT> 00158 { 00159 typedef typename viennagrid::make_typemap< 00160 viennagrid::vertex_tag, 00161 typename full_element_config<CellTagT, viennagrid::vertex_tag, HandleTagT, VertexContainerTagT, CellContainerTagT>::type 00162 >::type type; 00163 }; 00164 00165 00172 template<typename CellTagT, 00173 typename HandleTagT = viennagrid::pointer_handle_tag, 00174 typename VertexContainerTagT = viennagrid::std_deque_tag, 00175 typename CellContainerTagT = viennagrid::std_deque_tag> 00176 struct full_topology_config 00177 { 00178 typedef typename full_topology_config_helper<CellTagT, CellTagT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type type; 00179 }; 00180 00181 00182 00183 00190 template<typename CellTagT, 00191 typename HandleTagT = viennagrid::pointer_handle_tag, 00192 typename VertexContainerTagT = viennagrid::std_deque_tag, 00193 typename CellContainerTagT = viennagrid::std_deque_tag> 00194 struct thin_topology_config 00195 { 00196 typedef typename viennagrid::make_typemap< 00197 CellTagT, 00198 typename viennagrid::make_typemap< 00199 viennagrid::config::element_id_tag, 00200 viennagrid::smart_id_tag<int>, 00201 00202 viennagrid::config::element_container_tag, 00203 typename viennagrid::result_of::handled_container<CellContainerTagT, HandleTagT>::tag, 00204 00205 viennagrid::config::element_boundary_storage_layout_tag, 00206 typename storage_layout_config<CellTagT, viennagrid::vertex_tag>::type, 00207 00208 viennagrid::config::element_appendix_type_tag, 00209 viennagrid::null_type 00210 >::type, 00211 00212 00213 viennagrid::vertex_tag, 00214 typename viennagrid::make_typemap< 00215 viennagrid::config::element_id_tag, 00216 viennagrid::smart_id_tag<int>, 00217 00218 viennagrid::config::element_container_tag, 00219 typename viennagrid::result_of::handled_container<VertexContainerTagT, HandleTagT>::tag, 00220 00221 viennagrid::config::element_boundary_storage_layout_tag, 00222 viennagrid::null_type, 00223 00224 viennagrid::config::element_appendix_type_tag, 00225 viennagrid::null_type 00226 >::type 00227 >::type type; 00228 }; 00229 00230 00231 00232 00240 template<typename CellTagT, 00241 typename PointType, 00242 typename HandleTagT = viennagrid::pointer_handle_tag, 00243 typename VertexContainerTagT = viennagrid::std_deque_tag, 00244 typename CellContainerTagT = viennagrid::std_deque_tag> 00245 struct full_mesh_config 00246 { 00247 typedef typename full_topology_config<CellTagT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type MeshConfig; 00248 typedef typename query<MeshConfig, null_type, vertex_tag>::type VertexConfig; 00249 00250 typedef typename viennagrid::detail::result_of::insert_or_modify< 00251 MeshConfig, 00252 viennagrid::static_pair< 00253 vertex_tag, 00254 typename viennagrid::detail::result_of::insert_or_modify< 00255 00256 VertexConfig, 00257 viennagrid::static_pair< 00258 element_appendix_type_tag, 00259 PointType 00260 > 00261 00262 >::type 00263 > 00264 >::type type; 00265 }; 00266 00267 template<typename CellTagT, typename HandleTagT, typename VertexContainerTagT, typename CellContainerTagT> 00268 struct full_mesh_config<CellTagT, void, HandleTagT, VertexContainerTagT, CellContainerTagT> 00269 { 00270 typedef typename viennagrid::config::result_of::full_topology_config<CellTagT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type type; 00271 }; 00272 00273 00274 00275 00283 template<typename CellTagT, 00284 typename PointType, 00285 typename HandleTagT = viennagrid::pointer_handle_tag, 00286 typename VertexContainerTagT = viennagrid::std_deque_tag, 00287 typename CellContainerTagT = viennagrid::std_deque_tag> 00288 struct thin_mesh_config 00289 { 00290 typedef typename thin_topology_config<CellTagT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type MeshConfig; 00291 typedef typename query<MeshConfig, null_type, vertex_tag>::type VertexConfig; 00292 00293 typedef typename viennagrid::detail::result_of::insert_or_modify< 00294 MeshConfig, 00295 viennagrid::static_pair< 00296 vertex_tag, 00297 typename viennagrid::detail::result_of::insert_or_modify< 00298 00299 VertexConfig, 00300 viennagrid::static_pair< 00301 element_appendix_type_tag, 00302 PointType 00303 > 00304 00305 >::type 00306 > 00307 >::type type; 00308 }; 00309 00310 template<typename CellTagT, typename HandleTagT, typename VertexContainerTagT, typename CellContainerTagT> 00311 struct thin_mesh_config<CellTagT, void, HandleTagT, VertexContainerTagT, CellContainerTagT> 00312 { 00313 typedef typename viennagrid::config::result_of::thin_topology_config<CellTagT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type type; 00314 }; 00315 00316 00317 00318 00320 template<typename WrappedConfigType, typename ElementTagT> 00321 struct element_container 00322 { 00323 typedef viennagrid::element<ElementTagT, WrappedConfigType> element_type; 00324 typedef typename viennagrid::result_of::container<element_type, typename query_element_container_tag<WrappedConfigType, ElementTagT>::type >::type type; 00325 }; 00326 00327 template<typename container_collection_typemap, typename ElementTagT> 00328 struct element_container< collection<container_collection_typemap>, ElementTagT > 00329 { 00330 typedef typename viennagrid::result_of::element<collection<container_collection_typemap>, ElementTagT>::type element_type; 00331 typedef typename viennagrid::detail::result_of::find< container_collection_typemap, element_type >::type::second type; 00332 }; 00333 00334 00336 template<typename WrappedConfigT, typename CurrentConfigT = typename WrappedConfigT::type> 00337 struct element_container_typemap; 00338 00339 template<typename WrappedConfigT, typename ElementTagT, typename ValueConfigT, typename TailT> 00340 struct element_container_typemap< WrappedConfigT, viennagrid::typelist< viennagrid::static_pair<ElementTagT, ValueConfigT>, TailT > > 00341 { 00342 typedef viennagrid::typelist< 00343 viennagrid::static_pair< 00344 viennagrid::element<ElementTagT, WrappedConfigT>, 00345 typename element_container<WrappedConfigT, ElementTagT>::type 00346 >, 00347 typename element_container_typemap<WrappedConfigT, TailT>::type 00348 > type; 00349 }; 00350 00351 template<typename WrappedConfigT> 00352 struct element_container_typemap<WrappedConfigT, viennagrid::null_type> 00353 { 00354 typedef viennagrid::null_type type; 00355 }; 00356 } 00357 00358 00359 00361 template<typename CellTagT, 00362 typename PointTypeT, 00363 typename HandleTagT = viennagrid::pointer_handle_tag, 00364 typename VertexContainerTagT = viennagrid::std_deque_tag, 00365 typename CellContainerTagT = viennagrid::std_deque_tag> 00366 struct wrapped_mesh_config_t 00367 { 00368 typedef typename result_of::full_mesh_config<CellTagT, PointTypeT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type type; 00369 }; 00370 } 00371 00372 namespace result_of 00373 { 00375 template<typename WrappedConfigType, typename ElementTagT, typename BoundaryElementTaglistT = 00376 typename boundary_element_taglist< viennagrid::element<ElementTagT, WrappedConfigType> >::type > 00377 struct coboundary_container_collection_per_element_typemap; 00378 00380 template<typename WrappedConfigType, typename ElementTagT> 00381 struct coboundary_container_collection_per_element_typemap<WrappedConfigType, ElementTagT, viennagrid::null_type> 00382 { 00383 typedef viennagrid::null_type type; 00384 }; 00385 00386 template<typename WrappedConfigType, typename ElementTagT, typename BoundaryElementTagT, typename tail> 00387 struct coboundary_container_collection_per_element_typemap<WrappedConfigType, ElementTagT, viennagrid::typelist<BoundaryElementTagT, tail> > 00388 { 00389 typedef typename config::result_of::query<WrappedConfigType, long, config::mesh_change_counter_tag>::type MeshChangeCounterType; 00390 00391 typedef typename config::result_of::query<WrappedConfigType, std_vector_tag, ElementTagT, config::coboundary_container_tag, BoundaryElementTagT>::type coboundary_container_tag; 00392 typedef typename config::result_of::query<WrappedConfigType, std_vector_tag, ElementTagT, config::coboundary_view_container_tag, BoundaryElementTagT>::type coboundary_view_container_tag; 00393 00394 00395 typedef typename config::result_of::element_container< WrappedConfigType, ElementTagT>::type base_element_container; 00396 typedef typename viennagrid::result_of::view<base_element_container, coboundary_view_container_tag>::type element_view_type; 00397 typedef typename result_of::container<element_view_type, coboundary_container_tag >::type base_coboundary_container; 00398 00399 typedef viennagrid::typelist< 00400 viennagrid::static_pair< 00401 viennagrid::static_pair< 00402 BoundaryElementTagT, 00403 ElementTagT 00404 >, 00405 detail::coboundary_container_wrapper<base_coboundary_container, MeshChangeCounterType> 00406 >, 00407 typename coboundary_container_collection_per_element_typemap<WrappedConfigType, ElementTagT, tail>::type 00408 > type; 00409 }; 00414 template<typename WrappedConfigType, typename ElementTaglistT = typename viennagrid::detail::result_of::key_typelist<typename WrappedConfigType::type>::type> 00415 struct coboundary_container_collection_typemap {}; 00416 00418 template<typename WrappedConfigType> 00419 struct coboundary_container_collection_typemap<WrappedConfigType, viennagrid::null_type> 00420 { 00421 typedef viennagrid::null_type type; 00422 }; 00423 00424 template<typename WrappedConfigType, typename ElementTagT, typename tail> 00425 struct coboundary_container_collection_typemap<WrappedConfigType, viennagrid::typelist<ElementTagT, tail> > 00426 { 00427 typedef typename viennagrid::detail::result_of::merge< 00428 typename coboundary_container_collection_per_element_typemap<WrappedConfigType, ElementTagT>::type, 00429 typename coboundary_container_collection_typemap<WrappedConfigType, tail>::type 00430 >::type type; 00431 }; 00433 } 00434 00435 00436 00437 00438 namespace result_of 00439 { 00441 template<typename WrappedConfigType, typename ElementTagT, typename BoundaryElementTaglistT = 00442 typename boundary_element_taglist< viennagrid::element<ElementTagT, WrappedConfigType> >::type > 00443 struct neighbor_container_collection_per_element_typemap {}; 00444 00446 template<typename WrappedConfigType, typename ElementTagT> 00447 struct neighbor_container_collection_per_element_typemap<WrappedConfigType, ElementTagT, viennagrid::null_type> 00448 { 00449 typedef viennagrid::null_type type; 00450 }; 00451 00452 template<typename WrappedConfigType, typename ElementTagT, typename ConnectorElementTagT, typename tail> 00453 struct neighbor_container_collection_per_element_typemap<WrappedConfigType, ElementTagT, viennagrid::typelist<ConnectorElementTagT, tail> > 00454 { 00455 typedef typename config::result_of::query<WrappedConfigType, long, config::mesh_change_counter_tag>::type MeshChangeCounterType; 00456 00457 typedef typename config::result_of::query<WrappedConfigType, std_vector_tag, ElementTagT, config::neighbor_container_tag, ConnectorElementTagT>::type neighbor_container_tag; 00458 typedef typename config::result_of::query<WrappedConfigType, std_vector_tag, ElementTagT, config::neighbor_view_container_tag, ConnectorElementTagT>::type neighbor_view_container_tag; 00459 00460 typedef typename config::result_of::element_container< WrappedConfigType, ElementTagT>::type base_element_container; 00461 typedef typename viennagrid::result_of::view<base_element_container, neighbor_view_container_tag>::type element_view_type; 00462 typedef typename result_of::container<element_view_type, neighbor_container_tag >::type base_container; 00463 00464 typedef viennagrid::typelist< 00465 viennagrid::static_pair< 00466 viennagrid::static_pair< 00467 ElementTagT, 00468 ConnectorElementTagT 00469 >, 00470 detail::neighbor_container_wrapper<base_container, MeshChangeCounterType> 00471 >, 00472 typename neighbor_container_collection_per_element_typemap<WrappedConfigType, ElementTagT, tail>::type 00473 > type; 00474 }; 00479 template<typename WrappedConfigType, typename ElementTaglistT = typename viennagrid::detail::result_of::key_typelist<typename WrappedConfigType::type>::type> 00480 struct neighbor_container_collection_typemap {}; 00481 00483 template<typename WrappedConfigType> 00484 struct neighbor_container_collection_typemap<WrappedConfigType, viennagrid::null_type> 00485 { 00486 typedef viennagrid::null_type type; 00487 }; 00488 00489 template<typename WrappedConfigType, typename ElementTagT, typename tail> 00490 struct neighbor_container_collection_typemap<WrappedConfigType, viennagrid::typelist<ElementTagT, tail> > 00491 { 00492 typedef typename viennagrid::detail::result_of::merge< 00493 typename neighbor_container_collection_per_element_typemap<WrappedConfigType, ElementTagT>::type, 00494 typename neighbor_container_collection_typemap<WrappedConfigType, tail>::type 00495 >::type type; 00496 }; 00498 } 00499 00500 00501 namespace result_of 00502 { 00507 template<typename ElementTypelistT> 00508 struct topologic_cell_dimension; 00509 00511 template<> 00512 struct topologic_cell_dimension<viennagrid::null_type> 00513 { 00514 static const int value = -1; 00515 }; 00516 00517 template<typename ElementTypeOrTagT, typename TailT> 00518 struct topologic_cell_dimension< viennagrid::typelist<ElementTypeOrTagT, TailT> > 00519 { 00520 typedef typename viennagrid::result_of::element_tag<ElementTypeOrTagT>::type ElementTag; 00521 static const int tail_cell_dimension = topologic_cell_dimension<TailT>::value; 00522 static const int current_element_dimension = ElementTag::dim; 00523 00524 static const int value = (tail_cell_dimension > current_element_dimension) ? tail_cell_dimension : current_element_dimension; 00525 }; 00531 template<typename ElementTypelistT, int TopologicDimensionV> 00532 struct elements_of_topologic_dim; 00533 00535 template<int TopologicDimensionV> 00536 struct elements_of_topologic_dim< viennagrid::null_type, TopologicDimensionV > 00537 { 00538 typedef viennagrid::null_type type; 00539 }; 00540 00541 template<typename ElementTypeOrTagT, typename TailT, int TopologicDimensionV> 00542 struct elements_of_topologic_dim< viennagrid::typelist<ElementTypeOrTagT, TailT>, TopologicDimensionV > 00543 { 00544 typedef typename viennagrid::result_of::element_tag<ElementTypeOrTagT>::type ElementTag; 00545 typedef typename elements_of_topologic_dim<TailT, TopologicDimensionV>::type TailTypelist; 00546 00547 typedef typename viennagrid::detail::IF< 00548 ElementTag::dim == TopologicDimensionV, 00549 typename viennagrid::detail::result_of::push_back<TailTypelist, ElementTag>::type, 00550 TailTypelist 00551 >::type type; 00552 }; 00557 template<typename ElementTypelistT> 00558 struct cell_tag_from_typelist 00559 { 00560 static const int dim = topologic_cell_dimension<ElementTypelistT>::value; 00561 typedef typename elements_of_topologic_dim<ElementTypelistT, dim>::type cell_types; 00562 typedef typename viennagrid::detail::result_of::at<cell_types,0>::type type; 00563 }; 00564 00565 00566 00567 00568 00570 template<typename WrappedConfigType, typename ElementTaglistT> 00571 struct boundary_information_collection_typemap_impl {}; 00572 00574 template<typename WrappedConfigType> 00575 struct boundary_information_collection_typemap_impl<WrappedConfigType, viennagrid::null_type> 00576 { 00577 typedef viennagrid::null_type type; 00578 }; 00579 00580 template<typename WrappedConfigType, typename ElementTagT, typename TailT> 00581 struct boundary_information_collection_typemap_impl<WrappedConfigType, viennagrid::typelist<ElementTagT, TailT> > 00582 { 00583 typedef typename config::result_of::query<WrappedConfigType, long, config::mesh_change_counter_tag>::type MeshChangeCounterType; 00584 00585 typedef typename config::result_of::query<WrappedConfigType, std_map_tag, ElementTagT, config::boundary_information_container_tag>::type boundary_container_tag; 00586 00587 typedef viennagrid::element<ElementTagT, WrappedConfigType> ElementType; 00588 typedef typename result_of::accessor_container<ElementType, bool, boundary_container_tag>::type base_container; 00589 00590 typedef viennagrid::typelist< 00591 viennagrid::static_pair< 00592 ElementTagT, 00593 detail::boundary_information_wrapper<base_container, MeshChangeCounterType> 00594 >, 00595 typename boundary_information_collection_typemap_impl<WrappedConfigType, TailT>::type 00596 > type; 00597 }; 00601 template<typename WrappedConfigType> 00602 struct boundary_information_collection_typemap 00603 { 00604 typedef typename viennagrid::detail::result_of::key_typelist<typename WrappedConfigType::type>::type ElementTagTlist; 00605 00606 typedef typename cell_tag_from_typelist<ElementTagTlist>::type CellTag; 00607 typedef typename viennagrid::detail::result_of::erase< ElementTagTlist, CellTag>::type ElementTypelistWithoutCellTag; 00608 00609 00610 typedef typename boundary_information_collection_typemap_impl<WrappedConfigType, ElementTypelistWithoutCellTag>::type type; 00611 }; 00612 } 00613 00614 00615 00616 namespace config 00617 { 00618 namespace result_of 00619 { 00621 template<typename WrappedConfigType> 00622 struct element_collection 00623 { 00624 typedef typename config::result_of::element_container_typemap<WrappedConfigType>::type element_container_typelist; 00625 typedef collection< element_container_typelist > type; 00626 }; 00627 } 00628 } 00629 } 00630 00631 00632 #endif