00001 #ifndef VIENNAGRID_DETAIL_LOWER_LEVEL_HOLDER_HPP
00002 #define VIENNAGRID_DETAIL_LOWER_LEVEL_HOLDER_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <iostream>
00023
00024 #include "viennagrid/forwards.h"
00025
00026
00027 #include "viennagrid/detail/element_orientation.hpp"
00028
00029 #include <vector>
00030
00036 namespace viennagrid
00037 {
00038
00039
00040
00050 template <typename ConfigType,
00051 typename ElementTag,
00052 unsigned long dim,
00053 typename handling_tag = typename result_of::bndcell_handling<ConfigType, ElementTag, dim>::type,
00054 typename orienter_tag = typename result_of::bndcell_orientation<ConfigType, ElementTag, dim>::type,
00055 bool LevelNull = (dim == 0)>
00056 class boundary_ncell_layer { };
00057
00058
00059
00060
00061
00063 template <typename ConfigType, typename ElementTag, unsigned long dim>
00064 class boundary_ncell_layer <ConfigType, ElementTag, dim, full_handling_tag, full_handling_tag, false> :
00065 public boundary_ncell_layer <ConfigType, ElementTag, dim - 1>
00066 {
00067
00068
00069 typedef topology::bndcells<ElementTag, dim> LevelSpecs;
00070 typedef topology::bndcells<typename LevelSpecs::tag, 0> VertexOnElementSpecs;
00071 typedef boundary_ncell_layer <ConfigType, ElementTag, dim - 1 > Base;
00072
00073 typedef element_t<ConfigType, typename LevelSpecs::tag> LevelElementType;
00074 typedef element_orientation<VertexOnElementSpecs::num> ElementOrientationType;
00075 typedef typename result_of::element_container<element_t<ConfigType, ElementTag>, dim, ElementTag::dim>::type container_type;
00076
00077 protected:
00078 template <typename DomainType>
00079 void fill_level(DomainType & dom)
00080 {
00081
00082 Base::fill_level(dom);
00083
00084
00085
00086
00087 topology::bndcell_filler<ElementTag, dim>::fill(&(elements_[0]),
00088 &(Base::vertices_[0]),
00089 &(orientations_[0]),
00090 dom);
00091 }
00092
00093 public:
00094
00095 boundary_ncell_layer( )
00096 {
00097 for (long i=0; i < LevelSpecs::num; ++i)
00098 elements_[i] = NULL;
00099 };
00100
00101 boundary_ncell_layer( const boundary_ncell_layer & llh) : Base (llh)
00102 {
00103 for (long i=0; i < LevelSpecs::num; ++i)
00104 elements_[i] = llh.elements_[i];
00105 }
00106
00108
00109 using Base::container;
00110
00111
00112 container_type *
00113 container(dimension_tag<dim>)
00114 {
00115 return &(elements_[0]);
00116 }
00117
00118
00119
00120 const container_type *
00121 container(dimension_tag<dim>) const
00122 {
00123 return &(elements_[0]);
00124 }
00125
00126
00128 std::size_t global_to_local_orientation(LevelElementType const & el, long index) const
00129 {
00130 for (std::size_t i=0; i<LevelSpecs::num; ++i)
00131 {
00132 if (elements_[i] == &el)
00133 return orientations_[i](index);
00134 }
00135 assert(false && "Provided k-cell is not a boundary element of the hosting n-cell!");
00136 return index;
00137 }
00138
00139 private:
00140 container_type elements_[LevelSpecs::num];
00141 ElementOrientationType orientations_[LevelSpecs::num];
00142 };
00143
00144
00145
00146
00147
00148
00149
00151 template <typename ConfigType, typename ElementTag, unsigned long dim>
00152 class boundary_ncell_layer <ConfigType, ElementTag, dim, full_handling_tag, no_handling_tag, false> :
00153 public boundary_ncell_layer <ConfigType, ElementTag, dim - 1>
00154 {
00155
00156
00157 typedef topology::bndcells<ElementTag, dim> LevelSpecs;
00158 typedef topology::bndcells<typename LevelSpecs::tag, 0> VertexOnElementSpecs;
00159 typedef boundary_ncell_layer <ConfigType, ElementTag, dim - 1 > Base;
00160
00161 typedef element_t<ConfigType, typename LevelSpecs::tag> LevelElementType;
00162 typedef element_orientation<VertexOnElementSpecs::num> ElementOrientationType;
00163 typedef typename result_of::element_container<element_t<ConfigType, ElementTag>, dim, ElementTag::dim>::type container_type;
00164
00165 protected:
00166 template <typename DomainType>
00167 void fill_level(DomainType & dom)
00168 {
00169 typedef ElementOrientationType * OrientationPointer;
00170
00171 Base::fill_level(dom);
00172
00173 topology::bndcell_filler<ElementTag, dim>::fill(&(elements_[0]),
00174 &(Base::vertices_[0]),
00175 OrientationPointer(NULL),
00176 dom);
00177 }
00178
00179 public:
00180
00181 boundary_ncell_layer( )
00182 {
00183 for (long i=0; i < LevelSpecs::num; ++i)
00184 elements_[i] = NULL;
00185 };
00186
00187 boundary_ncell_layer( const boundary_ncell_layer & llh) : Base (llh)
00188 {
00189 for (long i=0; i < LevelSpecs::num; ++i)
00190 elements_[i] = llh.elements_[i];
00191 }
00192
00194
00195 using Base::container;
00196
00197
00198 container_type *
00199 container(dimension_tag<dim>)
00200 {
00201 return &(elements_[0]);
00202 }
00203
00204
00205 const container_type *
00206 container(dimension_tag<dim>) const
00207 {
00208 return &(elements_[0]);
00209 }
00210
00211 private:
00212 container_type elements_[LevelSpecs::num];
00213 };
00214
00215
00216
00217
00218
00219
00221 template <typename ConfigType, typename ElementTag, unsigned long dim, typename orienter_tag>
00222 class boundary_ncell_layer <ConfigType, ElementTag, dim, no_handling_tag, orienter_tag, false> :
00223 public boundary_ncell_layer < ConfigType, ElementTag, dim - 1 >
00224 {
00225
00226
00227
00228 typedef topology::bndcells<ElementTag, dim> LevelSpecs;
00229 typedef boundary_ncell_layer < ConfigType, ElementTag, dim - 1 > Base;
00230
00231 typedef element_t<ConfigType, typename LevelSpecs::tag> LevelElementType;
00232
00233 protected:
00234 template <typename DomainType>
00235 void fill_level(DomainType & dom)
00236 {
00237
00238 Base::fill_level(dom);
00239 }
00240
00241 public:
00242
00243 boundary_ncell_layer( ) {};
00244
00245 boundary_ncell_layer( const boundary_ncell_layer & llh) : Base (llh) {}
00246
00247
00248 };
00249
00250
00251
00253 template <typename ConfigType, typename ElementTag, typename handling_tag, typename orienter_tag>
00254 class boundary_ncell_layer <ConfigType, ElementTag, 0, handling_tag, orienter_tag, true>
00255 {
00256
00257
00258 typedef topology::bndcells<ElementTag, 0> LevelSpecs;
00259
00260 typedef element_t<ConfigType, typename LevelSpecs::tag> VertexType;
00261 typedef typename result_of::point<ConfigType>::type PointType;
00262
00263 typedef typename result_of::iterator< element_t<ConfigType, ElementTag>, 0>::type VertexIterator;
00264
00265 protected:
00266
00267 template <typename DomainType>
00268 void fill_level(DomainType & dom) {}
00269
00270 public:
00271 boundary_ncell_layer() {};
00272
00273 boundary_ncell_layer( const boundary_ncell_layer & llh)
00274 {
00275 for (long i=0; i < LevelSpecs::num; ++i)
00276 vertices_[i] = llh.vertices_[i];
00277 }
00278
00280
00281
00282 VertexType * *
00283 container(dimension_tag<0>)
00284 {
00285 return &(vertices_[0]);
00286 }
00287
00288
00289 VertexType * const *
00290 container(dimension_tag<0>) const
00291 {
00292 return &(vertices_[0]);
00293 }
00294
00295
00296 protected:
00297 VertexType * vertices_[LevelSpecs::num];
00298 };
00299
00300
00301
00302 }
00303
00304
00305 #endif
00306