ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/topology/simplex.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_TOPOLOGY_SIMPLEX_HPP
00002 #define VIENNAGRID_TOPOLOGY_SIMPLEX_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 <sstream>
00017 
00018 #include "viennagrid/forwards.hpp"
00019 #include "viennagrid/topology/vertex.hpp"
00020 #include "viennagrid/topology/line.hpp"
00021 
00026 namespace viennagrid
00027 {
00028   namespace detail
00029   {
00030     template <int n, int k>
00031     struct n_over_k
00032     {
00033       static const int value = n_over_k<n-1, k-1>::value + n_over_k<n-1, k>::value;
00034     };
00035 
00036     template <int n>
00037     struct n_over_k<n, 0>
00038     {
00039       static const int value = 1;
00040     };
00041 
00042     template <int k>
00043     struct n_over_k<0, k>
00044     {
00045       static const int value = 0;
00046     };
00047 
00048     template <>
00049     struct n_over_k<0, 0>
00050     {
00051       static const int value = 1;
00052     };
00053 
00054   }
00055 
00056 
00058   template <int n>
00059   struct simplex_tag
00060   {
00061     typedef simplex_tag<n-1> facet_tag;
00062 
00063     static const int dim = n;
00064     static std::string name()
00065     {
00066       std::stringstream ss;
00067       ss << n << "-simplex";
00068       return ss.str();
00069     }
00070   };
00071 
00076   template <int n, int k>
00077   struct boundary_elements<simplex_tag<n>, simplex_tag<k> >
00078   {
00079     //typedef simplex_tag<k>             tag;
00080 
00081     typedef static_layout_tag     layout_tag;
00082     static const int num = detail::n_over_k<n+1, k+1>::value;
00083   };
00084 
00085 
00086   namespace detail
00087   {
00089 
00090 
00091     template<int n, typename BoundaryElementType>
00092     struct boundary_element_generator<simplex_tag<n>, simplex_tag<1>, BoundaryElementType>
00093     {
00094       template<typename element_type, typename inserter_type>
00095       static void create_boundary_elements(element_type & element, inserter_type & inserter)
00096       {
00097         BoundaryElementType boundary_element( inserter.get_physical_container_collection() );
00098 
00099         std::size_t index = 0;
00100         for (std::size_t i = 0; i < static_cast<std::size_t>(boundary_elements<simplex_tag<n>, vertex_tag >::num); ++i)
00101             for (std::size_t j = i+1; j < static_cast<std::size_t>(boundary_elements<simplex_tag<n>, vertex_tag >::num); ++j)
00102             {
00103                 boundary_element.container(dimension_tag<0>()).set_handle( element.container( dimension_tag<0>() ).handle_at(i), 0 );
00104                 boundary_element.container(dimension_tag<0>()).set_handle( element.container( dimension_tag<0>() ).handle_at(j), 1 );
00105 
00106                 element.set_boundary_element( boundary_element, inserter.template insert<true, true>(boundary_element), index++ );
00107             }
00108       }
00109     };
00110 
00111 
00112     template<int n, typename BoundaryElementType>
00113     struct boundary_element_generator<simplex_tag<n>, simplex_tag<2>, BoundaryElementType>
00114     {
00115       template<typename element_type, typename inserter_type>
00116       static void create_boundary_elements(element_type & element, inserter_type & inserter)
00117       {
00118         BoundaryElementType boundary_element( inserter.get_physical_container_collection() );
00119 
00120         std::size_t index = 0;
00121         for (std::size_t i = 0; i < static_cast<std::size_t>(boundary_elements<simplex_tag<n>, vertex_tag >::num); ++i)
00122             for (std::size_t j = i+1; j < static_cast<std::size_t>(boundary_elements<simplex_tag<n>, vertex_tag >::num); ++j)
00123                 for (std::size_t k = j+1; k < static_cast<std::size_t>(boundary_elements<simplex_tag<n>, vertex_tag >::num); ++k)
00124                 {
00125                     boundary_element.container(dimension_tag<0>()).set_handle( element.container( dimension_tag<0>() ).handle_at(i), 0 );
00126                     boundary_element.container(dimension_tag<0>()).set_handle( element.container( dimension_tag<0>() ).handle_at(j), 1 );
00127                     boundary_element.container(dimension_tag<0>()).set_handle( element.container( dimension_tag<0>() ).handle_at(k), 2 );
00128 
00129                     element.set_boundary_element( boundary_element, inserter.template insert<true, true>(boundary_element), index++ );
00130                 }
00131       }
00132     };
00133 
00134 
00135     // similarly for higher topological dimensions...
00136 
00137   } //topology
00138 
00139 
00140 }
00141 
00142 #endif
00143