ViennaGrid  1.0.1
/export/development/ViennaGrid/release/ViennaGrid-1.0.1/viennagrid/forwards.h
Go to the documentation of this file.
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