|
ViennaGrid
1.0.1
|
00001 #ifndef VIENNAGRID_FORWARDS_H 00002 #define VIENNAGRID_FORWARDS_H 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 00030 #include <iostream> 00031 #include <vector> 00032 #include <map> 00033 #include <cstddef> //for std::size_t 00034 #include <cstdlib> //for EXIT_SUCCESS and EXIT_FAILURE 00035 00036 #include "viennadata/api.hpp" 00037 00038 //Debug levels: 00039 //VIENNAGRID_DEBUG_ALL Output every little piece of debug information 00040 //VIENNAGRID_DEBUG_IO Debug IO operations 00041 //VIENNAGRID_DEBUG_REFINEMENT Debug refinement algorithms 00042 //VIENNAGRID_DEBUG_STATUS Print status messages to std::cout (very little debug info) 00043 00044 #ifdef VIENNAGRID_DEBUG_ALL 00045 #define VIENNAGRID_DEBUG_IO 00046 #define VIENNAGRID_DEBUG_REFINEMENT 00047 #define VIENNAGRID_DEBUG_STATUS 00048 #endif 00049 00055 namespace viennagrid 00056 { 00058 typedef std::size_t dim_type; 00059 00060 /********* Tags ***********************/ 00061 00063 template <long d> 00064 struct cartesian_cs; //Cartesian coordinate system 00065 00067 struct polar_cs; //Polar coordinate system (r, phi) 00069 struct spherical_cs; //Spherical coordinate system (r, theta, phi) 00071 struct cylindrical_cs; //Cylindrical coordinate system (rho, theta, z) 00072 00073 //Dimension Tag: (for tag dispatching) 00075 template <long d> 00076 struct dimension_tag 00077 { 00078 enum{ value = d }; 00079 }; 00080 00081 //Tags for the handling of elements at different topological levels (see topology::subcell_desc) 00083 struct full_handling_tag {}; 00085 struct no_handling_tag {}; 00086 00087 00088 /********* Forward definitions of main classes *******************/ 00089 00091 struct point_tag; 00092 00093 // Simplex family: 00095 template <long dim> 00096 struct simplex_tag; 00097 00099 typedef simplex_tag<1> line_tag; 00101 typedef simplex_tag<2> triangle_tag; 00103 typedef simplex_tag<3> tetrahedron_tag; 00104 00105 // Hypercube family: 00107 template <long dim> 00108 struct hypercube_tag; 00109 00110 //typedef hypercube_tag<1> line_tag; 00112 typedef hypercube_tag<2> quadrilateral_tag; 00114 typedef hypercube_tag<3> hexahedron_tag; 00115 00116 00117 //forward declarations: 00118 template <typename CoordType, typename CoordinateSystem> 00119 class point_t; 00120 00121 template <typename ConfigType, typename ElementTag> 00122 class element_t; 00123 00124 template <typename ConfigType, typename ElementType> 00125 class element_key; 00126 00127 //Segment type: 00128 template <typename ConfigType> 00129 class segment_t; 00130 00131 template <typename ConfigType> 00132 class domain_t; 00133 00134 /********* Other *******************/ 00135 00136 template <typename host_element, 00137 long dim, 00138 bool is_coboundary = false> 00139 class ncell_range; 00140 00141 template <typename host_element, 00142 long dim, 00143 bool is_coboundary = false> 00144 class const_ncell_range; 00145 00147 template <typename T, long dim> //topological dimension of the elements over which to iterate 00148 class coboundary_key 00149 { 00150 public: 00151 coboundary_key(T const & t_) : t(&t_) {} 00152 00154 bool operator<(coboundary_key const & other) const 00155 { 00156 return t < other.t; 00157 } 00158 private: 00159 T const * t; 00160 }; 00161 00162 template <typename T> 00163 class boundary_key; 00164 00165 class interface_key; 00166 00167 template <typename SegmentType> 00168 class segment_mapping_key 00169 { 00170 public: 00171 segment_mapping_key(SegmentType const & seg) : pSeg(&seg) {} 00172 00173 //for compatibility with std::map 00174 bool operator<(segment_mapping_key const & other) const 00175 { 00176 return pSeg < other.pSeg; 00177 } 00178 00179 private: 00180 SegmentType const * pSeg; 00181 }; 00182 00183 00184 //proxy classes for iterator/container retrieval: 00186 template <typename T> 00187 class const_ncell_proxy 00188 { 00189 public: 00190 const_ncell_proxy(T const & t_) : t(t_) {} 00191 00192 T const & get() const { return t; } 00193 00194 private: 00195 T const & t; 00196 }; 00197 00199 template <typename T> 00200 class ncell_proxy 00201 { 00202 public: 00203 ncell_proxy(T & t_) : t(t_) {} 00204 00205 T & get() const { return t; } 00206 00207 private: 00208 T & t; 00209 }; 00210 00211 00212 //ID handling: 00214 class pointer_id 00215 { 00216 public: 00217 typedef pointer_id * id_type; 00218 00219 //for compatibility: 00220 void id(const pointer_id *) { }; 00221 void id(long) { }; 00222 const pointer_id * id() const { return this; }; 00223 pointer_id * id() { return this; }; 00224 }; 00225 00227 class integral_id 00228 { 00229 public: 00230 typedef long id_type; 00231 00232 integral_id() : id_(-1) {}; 00233 00234 long id() const { return id_; }; 00235 void id(long new_id) { id_ = new_id; }; 00236 00237 protected: 00238 id_type id_; 00239 }; 00240 00242 namespace topology 00243 { 00244 00250 template <typename ElementTag, 00251 long level = ElementTag::dim> 00252 struct bndcells 00253 { 00254 //the default case is simultaneously a pathetic case: 00255 //cell-handling within the cell 00256 00258 enum{ num = 1 }; //1 cell 00259 00261 typedef ElementTag tag; 00262 }; 00263 00269 template <typename ElementTag, long k> 00270 struct bndcell_filler {}; 00271 00272 } 00273 00274 00276 namespace result_of 00277 { 00279 template <typename ConfigType, typename ElementTag> //by default, every element is equipped with an ID 00280 struct element_id_handler 00281 { 00282 typedef integral_id type; 00283 }; 00284 00285 template <typename T, long dim = 0> 00286 struct iterator; 00287 00289 template <typename T> 00290 struct config 00291 { 00292 typedef typename T::config_type type; 00293 }; 00294 00296 template <typename ConfigType> 00297 struct config< domain_t<ConfigType> > 00298 { 00299 typedef ConfigType type; 00300 }; 00301 00303 template <typename ConfigType> 00304 struct config< segment_t<ConfigType> > 00305 { 00306 typedef ConfigType type; 00307 }; 00308 00310 template <typename ConfigType, typename ElementTag> 00311 struct config< element_t<ConfigType, ElementTag> > 00312 { 00313 typedef ConfigType type; 00314 }; 00315 00316 00317 template <typename T, //type of host (domain, segment, other element) 00318 long dim, 00319 long cell_level = config<T>::type::cell_tag::dim> 00320 struct element_container; 00321 00322 template <typename T, 00323 long dim> //topological level 00324 struct ncell_range; 00325 00326 template <typename T, 00327 long dim> //topological level 00328 struct const_ncell_range; 00329 00330 00337 template <typename Config, 00338 long dim, 00339 long cell_level = Config::cell_tag::dim> 00340 struct ncell 00341 { 00342 typedef element_t<Config, 00343 typename topology::bndcells<typename Config::cell_tag, 00344 dim>::tag 00345 > type; 00346 }; 00347 00349 template <typename Config, 00350 long cell_level> 00351 struct ncell <Config, cell_level, cell_level> 00352 { 00353 typedef element_t<Config, 00354 typename Config::cell_tag> type; 00355 }; 00356 00358 template <typename Config> 00359 struct point 00360 { 00361 typedef viennagrid::point_t<typename Config::numeric_type, typename Config::coordinate_system_tag> type; 00362 }; 00363 00365 template <typename CoordType, typename CoordinateSystem> 00366 struct point< point_t<CoordType, CoordinateSystem> > 00367 { 00368 typedef viennagrid::point_t<CoordType, CoordinateSystem> type; 00369 }; 00370 00372 template <typename Config, typename ElementTag> 00373 struct point< element_t<Config, ElementTag> > 00374 { 00375 typedef viennagrid::point_t<typename Config::numeric_type, typename Config::coordinate_system_tag> type; 00376 }; 00377 00379 template <typename Config> 00380 struct point< segment_t<Config> > 00381 { 00382 typedef viennagrid::point_t<typename Config::numeric_type, typename Config::coordinate_system_tag> type; 00383 }; 00384 00386 template <typename Config> 00387 struct point< domain_t<Config> > 00388 { 00389 typedef viennagrid::point_t<typename Config::numeric_type, typename Config::coordinate_system_tag> type; 00390 }; 00391 00392 00393 00395 template <typename Config> 00396 struct numeric 00397 { 00398 typedef typename Config::numeric_type type; 00399 }; 00400 00402 template <typename CoordType, typename CoordinateSystem> 00403 struct numeric< point_t<CoordType, CoordinateSystem> > 00404 { 00405 typedef CoordType type; 00406 }; 00407 00409 template <typename Config, typename ElementTag> 00410 struct numeric< element_t<Config, ElementTag> > 00411 { 00412 typedef typename Config::numeric_type type; 00413 }; 00414 00416 template <typename Config> 00417 struct numeric< segment_t<Config> > 00418 { 00419 typedef typename Config::numeric_type type; 00420 }; 00421 00423 template <typename Config> 00424 struct numeric< domain_t<Config> > 00425 { 00426 typedef typename Config::numeric_type type; 00427 }; 00428 00429 00436 template <typename ConfigType, typename T, long dim> 00437 struct bndcell_orientation 00438 { 00439 typedef full_handling_tag type; 00440 }; 00441 00442 00449 template <typename ConfigType, typename T, long dim> 00450 struct bndcell_handling 00451 { 00452 typedef full_handling_tag type; 00453 }; 00454 00455 00461 template <typename ConfigType, typename T> 00462 struct bndcell_handling<ConfigType, T, 0> 00463 { 00464 typedef full_handling_tag type; 00465 }; 00466 00467 00468 00469 //for domains 00473 template <typename ConfigType, long dim> 00474 struct bndcell_handling<ConfigType, domain_t<ConfigType>, dim> 00475 { 00476 typedef full_handling_tag type; 00477 }; 00478 00483 template <typename ConfigType> 00484 struct bndcell_handling<ConfigType, domain_t<ConfigType>, 0> 00485 { 00486 typedef full_handling_tag type; 00487 }; 00488 00489 00490 //for segments: 00494 template <typename ConfigType, long dim> 00495 struct bndcell_handling<ConfigType, segment_t<ConfigType>, dim> 00496 { 00497 typedef typename bndcell_handling<ConfigType, typename ConfigType::cell_tag, dim>::type type; 00498 }; 00499 00504 template <typename ConfigType> 00505 struct bndcell_handling<ConfigType, segment_t<ConfigType>, 0> //avoid ambiguities 00506 { 00507 typedef typename bndcell_handling<ConfigType, typename ConfigType::cell_tag, 0>::type type; 00508 }; 00509 00510 } 00511 00512 // providing forwards for the ncells function 00513 template <long dim, typename DomainConfig> 00514 ncell_range<domain_t<DomainConfig>, dim> 00515 ncells(domain_t<DomainConfig> & d); 00516 00517 template <typename DomainConfig> 00518 ncell_proxy< domain_t<DomainConfig> > 00519 ncells(domain_t<DomainConfig> & d); 00520 00521 template <long dim, typename DomainConfig> 00522 ncell_range<segment_t<DomainConfig>, dim> 00523 ncells(segment_t<DomainConfig> & d); 00524 00525 template <typename DomainConfig> 00526 ncell_proxy< segment_t<DomainConfig> > 00527 ncells(segment_t<DomainConfig> & d); 00528 00529 template <long dim, typename Config, typename ElementTag> 00530 typename result_of::ncell_range< element_t<Config, ElementTag>, dim>::type 00531 ncells(element_t<Config, ElementTag> & d); 00532 00533 template <typename Config, typename ElementTag> 00534 ncell_proxy< element_t<Config, ElementTag> > 00535 ncells(element_t<Config, ElementTag> & d); 00536 00537 //same for const: 00538 template <long dim, typename DomainConfig> 00539 const_ncell_range<domain_t<DomainConfig>, dim> 00540 ncells(domain_t<DomainConfig> const & d); 00541 00542 template <typename DomainConfig> 00543 const_ncell_proxy< domain_t<DomainConfig> > 00544 ncells(domain_t<DomainConfig> const & d); 00545 00546 template <long dim, typename DomainConfig> 00547 const_ncell_range<segment_t<DomainConfig>, dim> 00548 ncells(segment_t<DomainConfig> const & d); 00549 00550 template <typename DomainConfig> 00551 const_ncell_proxy< segment_t<DomainConfig> > 00552 ncells(segment_t<DomainConfig> const & d); 00553 00554 template <long dim, typename Config, typename ElementTag> 00555 typename result_of::const_ncell_range< element_t<Config, ElementTag>, dim>::type 00556 ncells(element_t<Config, ElementTag> const & d); 00557 00558 template <typename Config, typename ElementTag> 00559 const_ncell_proxy< element_t<Config, ElementTag> > 00560 ncells(element_t<Config, ElementTag> const & d); 00561 00562 00563 // norm tags for: algorithm/norm.hpp 00565 struct one_tag {}; 00567 struct two_tag {}; 00569 struct inf_tag {}; 00570 00572 struct seg_cell_normal_tag {}; 00573 00575 struct seg_cell_normal_data { 00576 typedef viennagrid::point_t<double, cartesian_cs<3> > point_type; 00577 typedef std::map<std::size_t, point_type> type; 00578 }; 00579 00580 00581 // 00582 //refinement 00583 // 00584 00585 template <typename T> 00586 struct element_refinement; 00587 00589 struct refinement_key {}; 00590 00591 template <typename DomainType, typename RefinementTag> 00592 class refinement_proxy; 00593 00595 struct uniform_refinement_tag {}; 00596 00598 struct local_refinement_tag {}; 00599 00601 namespace detail 00602 { 00603 template <typename ConfigTypeIn, typename ConfigTypeOut> 00604 void refine_impl(domain_t<ConfigTypeIn> const & domain_in, 00605 domain_t<ConfigTypeOut> & domain_out, 00606 uniform_refinement_tag); 00607 00608 template <typename ConfigTypeIn, typename ConfigTypeOut> 00609 void refine_impl(domain_t<ConfigTypeIn> const & domain_in, 00610 domain_t<ConfigTypeOut> & domain_out, 00611 local_refinement_tag); 00612 } 00613 00614 // 00615 // Voronoi information: 00616 // 00618 struct voronoi_interface_area_key {}; 00620 struct voronoi_box_volume_key {}; 00621 } 00622 00623 /* 00624 namespace viennadata 00625 { 00626 namespace config 00627 { 00628 template <> 00629 struct key_dispatch<viennagrid::refinement_key> 00630 { 00631 typedef type_key_dispatch_tag tag; 00632 }; 00633 00634 template <> 00635 struct key_dispatch<viennagrid::voronoi_interface_area_key> 00636 { 00637 typedef type_key_dispatch_tag tag; 00638 }; 00639 00640 template <> 00641 struct key_dispatch<viennagrid::voronoi_box_volume_key> 00642 { 00643 typedef type_key_dispatch_tag tag; 00644 }; 00645 } 00646 } 00647 */ 00648 00649 // tell ViennaData to use a type-based key dispatch for the refinement and the voronoi keys 00650 VIENNADATA_ENABLE_TYPE_BASED_KEY_DISPATCH(viennagrid::refinement_key) 00651 VIENNADATA_ENABLE_TYPE_BASED_KEY_DISPATCH(viennagrid::voronoi_interface_area_key) 00652 VIENNADATA_ENABLE_TYPE_BASED_KEY_DISPATCH(viennagrid::voronoi_box_volume_key) 00653 00655 00657 #define VIENNAGRID_DISABLE_BOUNDARY_NCELL(arg_CONFIG, arg_TAG, arg_DIM) \ 00658 namespace viennagrid { namespace result_of { \ 00659 template <> \ 00660 struct bndcell_handling<arg_CONFIG, arg_TAG, arg_DIM> { \ 00661 typedef no_handling_tag type; \ 00662 }; \ 00663 } } 00664 00666 #define VIENNAGRID_ENABLE_BOUNDARY_NCELL(arg_CONFIG, arg_TAG, arg_DIM) \ 00667 namespace viennagrid { namespace result_of { \ 00668 template <> \ 00669 struct bndcell_handling<arg_CONFIG, arg_TAG, arg_DIM> { \ 00670 typedef full_handling_tag type; \ 00671 }; \ 00672 } } 00673 00675 #define VIENNAGRID_GLOBAL_DISABLE_BOUNDARY_NCELL(arg_TAG, arg_DIM) \ 00676 namespace viennagrid { namespace result_of { \ 00677 template <typename ConfigType> \ 00678 struct bndcell_handling<ConfigType, arg_TAG, arg_DIM> { \ 00679 typedef no_handling_tag type; \ 00680 }; \ 00681 } } 00682 00683 //note that VIENNAGRID_GLOBAL_ENABLE_BOUNDARY_NCELL(arg_TAG, arg_DIM) does not make sense, since the default is full_handling already. 00684 00685 // 00686 // Same for orientation 00687 // 00689 #define VIENNAGRID_DISABLE_BOUNDARY_NCELL_ORIENTATION(arg_CONFIG, arg_TAG, arg_DIM) \ 00690 namespace viennagrid { namespace result_of { \ 00691 template <> \ 00692 struct bndcell_orientation<arg_CONFIG, arg_TAG, arg_DIM> { \ 00693 typedef no_handling_tag type; \ 00694 }; \ 00695 } } 00696 00698 #define VIENNAGRID_ENABLE_BOUNDARY_NCELL_ORIENTATION(arg_CONFIG, arg_TAG, arg_DIM) \ 00699 namespace viennagrid { namespace result_of { \ 00700 template <> \ 00701 struct bndcell_orientation<arg_CONFIG, arg_TAG, arg_DIM> { \ 00702 typedef full_handling_tag type; \ 00703 }; \ 00704 } } 00705 00707 #define VIENNAGRID_GLOBAL_DISABLE_BOUNDARY_NCELL_ORIENTATION(arg_TAG, arg_DIM) \ 00708 namespace viennagrid { namespace result_of { \ 00709 template <typename ConfigType> \ 00710 struct bndcell_orientation<ConfigType, arg_TAG, arg_DIM> { \ 00711 typedef no_handling_tag type; \ 00712 }; \ 00713 } } 00714 00715 // 00716 // ID for elements: 00717 // 00719 #define VIENNAGRID_DISABLE_NCELL_ID(arg_CONFIG, arg_TAG) \ 00720 namespace viennagrid { namespace result_of { \ 00721 template <> \ 00722 struct element_id_handler<arg_CONFIG, arg_TAG> { \ 00723 typedef pointer_id type; \ 00724 }; \ 00725 } } 00726 00728 #define VIENNAGRID_ENABLE_NCELL_ID(arg_CONFIG, arg_TAG) \ 00729 namespace viennagrid { namespace result_of { \ 00730 template <> \ 00731 struct element_id_handler<arg_CONFIG, arg_TAG> { \ 00732 typedef integral_id type; \ 00733 }; \ 00734 } } 00735 00737 #define VIENNAGRID_GLOBAL_DISABLE_NCELL_ID(arg_TAG) \ 00738 namespace viennagrid { namespace result_of { \ 00739 template <typename ConfigType> \ 00740 struct element_id_handler<ConfigType, arg_TAG> { \ 00741 typedef pointer_id type; \ 00742 }; \ 00743 } } 00744 00745 00746 // 00748 // 00750 #define VIENNAGRID_DISABLE_DOMAIN_NCELL(arg_CONFIG, arg_DIM) \ 00751 namespace viennagrid { namespace result_of { \ 00752 template <> \ 00753 struct bndcell_handling<arg_CONFIG, domain_t<arg_CONFIG>, arg_DIM> { \ 00754 typedef no_handling_tag type; \ 00755 }; \ 00756 } } 00757 00759 #define VIENNAGRID_ENABLE_DOMAIN_NCELL(arg_CONFIG, arg_DIM) \ 00760 namespace viennagrid { namespace result_of { \ 00761 template <> \ 00762 struct bndcell_handling<arg_CONFIG, domain_t<arg_CONFIG>, arg_DIM> { \ 00763 typedef full_handling_tag type; \ 00764 }; \ 00765 } } 00766 00768 #define VIENNAGRID_GLOBAL_DISABLE_DOMAIN_NCELL(arg_DIM) \ 00769 namespace viennagrid { namespace result_of { \ 00770 template <typename ConfigType> \ 00771 struct bndcell_handling<ConfigType, domain_t<ConfigType>, arg_DIM> { \ 00772 typedef no_handling_tag type; \ 00773 }; \ 00774 } } 00775 00776 // 00778 // 00780 #define VIENNAGRID_ENABLE_NCELL_ID_FOR_DATA(arg_CONFIG, arg_CELLTAG) \ 00781 namespace viennadata { namespace config { \ 00782 template <> struct object_identifier<viennagrid::element_t<arg_CONFIG, arg_CELLTAG> > { \ 00783 typedef object_provided_id tag; \ 00784 typedef size_t id_type; \ 00785 static size_t get(viennagrid::element_t<arg_CONFIG, arg_CELLTAG> const & obj) { return obj.id(); } \ 00786 }; } } 00787 00789 #define VIENNAGRID_ENABLE_ALL_NCELL_ID_FOR_DATA(arg_CONFIG) \ 00790 namespace viennadata { namespace config { \ 00791 template <typename CellTag> struct object_identifier<viennagrid::element_t<arg_CONFIG, CellTag> > { \ 00792 typedef object_provided_id tag; \ 00793 typedef size_t id_type; \ 00794 static size_t get(viennagrid::element_t<arg_CONFIG, CellTag> const & obj) { return obj.id(); } \ 00795 }; } } 00796 00798 #define VIENNAGRID_GLOBAL_ENABLE_NCELL_ID_FOR_DATA(arg_CELLTAG) \ 00799 namespace viennadata { namespace config { \ 00800 template <typename ConfigType> struct object_identifier<viennagrid::element_t<ConfigType, arg_CELLTAG> > { \ 00801 typedef object_provided_id tag; \ 00802 typedef size_t id_type; \ 00803 static size_t get(viennagrid::element_t<ConfigType, arg_CELLTAG> const & obj) { return obj.id(); } \ 00804 }; } } 00805 00807 #define VIENNAGRID_GLOBAL_ENABLE_ALL_NCELL_ID_FOR_DATA() \ 00808 namespace viennadata { namespace config { \ 00809 template <typename ConfigType, typename CellTag> struct object_identifier<viennagrid::element_t<ConfigType, CellTag> > { \ 00810 typedef object_provided_id tag; \ 00811 typedef size_t id_type; \ 00812 static size_t get(viennagrid::element_t<ConfigType, CellTag> const & obj) { return obj.id(); } \ 00813 }; } } 00814 00815 #endif
1.7.6.1