00001 #ifndef VIENNAGRID_ALGORITHM_INTERFACE_HPP
00002 #define VIENNAGRID_ALGORITHM_INTERFACE_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <vector>
00022 #include "viennagrid/forwards.h"
00023 #include "viennagrid/detail/element_iterators.hpp"
00024 #include "viennagrid/detail/domain_iterators.hpp"
00025 #include "viennagrid/algorithm/norm.hpp"
00026 #include "viennagrid/algorithm/centroid.hpp"
00027 #include "viennagrid/algorithm/boundary.hpp"
00028
00034 namespace viennagrid
00035 {
00037 class interface_key
00038 {
00039 public:
00040 interface_key(std::size_t id1, std::size_t id2) : id_(id1, id2) {}
00041
00043 bool operator<(interface_key const & other) const
00044 {
00045 return id_ < other.id_;
00046 }
00047
00048 private:
00049 std::pair<std::size_t, std::size_t> id_;
00050 };
00051
00052
00054 template <long dim>
00055 struct interface_setter
00056 {
00057 template <typename FacetType, typename KeyType>
00058 static void apply(FacetType const & facet, KeyType const & key, full_handling_tag)
00059 {
00060 typedef typename FacetType::config_type ConfigType;
00061 typedef typename ConfigType::cell_tag CellTag;
00062
00063 typedef typename viennagrid::result_of::const_ncell_range<FacetType, dim>::type ElementOnFacetRange;
00064 typedef typename result_of::iterator<ElementOnFacetRange>::type ElementOnFacetIterator;
00065
00066 ElementOnFacetRange eof_container = ncells<dim>(facet);
00067 for (ElementOnFacetIterator eofit = eof_container.begin();
00068 eofit != eof_container.end();
00069 ++eofit)
00070 {
00071 viennadata::access<KeyType, bool>(key)(*eofit) = true;
00072 }
00073
00074
00075 interface_setter<dim-1>::apply(facet,
00076 key,
00077 typename viennagrid::result_of::bndcell_handling<ConfigType, CellTag, dim-1>::type());
00078 }
00079
00080 template <typename FacetType, typename KeyType>
00081 static void apply(FacetType const & facet, KeyType const & key, no_handling_tag)
00082 {
00083 typedef typename FacetType::config_type ConfigType;
00084 typedef typename ConfigType::cell_tag CellTag;
00085
00086
00087 interface_setter<dim-1>::apply(facet,
00088 key,
00089 typename viennagrid::result_of::bndcell_handling<ConfigType, CellTag, dim-1>::type());
00090 }
00091
00092 };
00093
00094
00096 template <>
00097 struct interface_setter< -1 >
00098 {
00099 template <typename FacetType, typename KeyType, typename HandlingTag>
00100 static void apply(FacetType const & facet, KeyType const & key, HandlingTag) {}
00101 };
00102
00104 template <typename SegmentType, typename KeyType>
00105 void detect_interface_impl(SegmentType const & seg1,
00106 SegmentType const & seg2,
00107 KeyType const & key,
00108 no_handling_tag)
00109 {
00110 typedef typename SegmentType::ERROR_CANNOT_DETECT_INTERFACE_BECAUSE_FACETS_ARE_DISABLED error_type;
00111 }
00112
00119 template <typename SegmentType, typename KeyType>
00120 void detect_interface_impl(SegmentType const & seg1,
00121 SegmentType const & seg2,
00122 KeyType const & key,
00123 full_handling_tag)
00124 {
00125 typedef typename SegmentType::config_type ConfigType;
00126 typedef typename ConfigType::cell_tag CellTag;
00127 typedef typename viennagrid::result_of::point<ConfigType>::type PointType;
00128 typedef typename viennagrid::result_of::ncell<ConfigType, CellTag::dim-1>::type FacetType;
00129 typedef typename viennagrid::result_of::ncell<ConfigType, CellTag::dim>::type CellType;
00130
00131 typedef typename viennagrid::result_of::const_ncell_range<SegmentType, CellTag::dim-1>::type FacetRange;
00132 typedef typename viennagrid::result_of::iterator<FacetRange>::type FacetIterator;
00133
00134 typedef typename ConfigType::numeric_type numeric_type;
00135
00136 std::set<FacetType const *> facets_ptrs_seg1;
00137
00138
00139
00140
00141 FacetRange facets_seg1 = viennagrid::ncells<CellTag::dim-1>(seg1);
00142 for (FacetIterator fit = facets_seg1.begin();
00143 fit != facets_seg1.end();
00144 ++fit)
00145 {
00146 if (is_boundary(*fit, seg1))
00147 facets_ptrs_seg1.insert( &(*fit) );
00148 }
00149
00150
00151
00152
00153 FacetRange facets_seg2 = viennagrid::ncells<CellTag::dim-1>(seg2);
00154 for (FacetIterator fit = facets_seg2.begin();
00155 fit != facets_seg2.end();
00156 ++fit)
00157 {
00158 if (facets_ptrs_seg1.find( &(*fit) ) != facets_ptrs_seg1.end())
00159 viennadata::access<KeyType, bool>(key)(*fit) = true;
00160 }
00161
00162
00163
00164
00165 for (FacetIterator fit = facets_seg1.begin();
00166 fit != facets_seg1.end();
00167 ++fit)
00168 {
00169 if (viennadata::find<KeyType, bool>(key)(*fit) != NULL)
00170 {
00171 if (viennadata::access<KeyType, bool>(key)(*fit) == true)
00172 interface_setter<CellTag::dim-2>::apply(*fit,
00173 key,
00174 typename viennagrid::result_of::bndcell_handling<ConfigType, CellTag, CellTag::dim-2>::type()
00175 );
00176 }
00177 }
00178 }
00179
00180
00181
00188 template <typename SegmentType, typename KeyType>
00189 void detect_interface(SegmentType const & seg1,
00190 SegmentType const & seg2,
00191 KeyType const & key)
00192 {
00193 typedef typename SegmentType::config_type ConfigType;
00194 typedef typename ConfigType::cell_tag CellTag;
00195 typedef typename result_of::bndcell_handling<ConfigType, CellTag,
00196 CellTag::dim-1>::type HandlingTag;
00197
00198 if (viennadata::access<KeyType, bool>(key)(seg1) == false)
00199 {
00200 detect_interface_impl(seg1, seg2, key, HandlingTag());
00201 viennadata::access<KeyType, bool>(key)(seg1) = true;
00202 viennadata::access<KeyType, bool>(key)(seg2) = true;
00203 }
00204 }
00205
00212 template <typename ConfigType, typename ElementTag>
00213 bool is_interface(element_t<ConfigType, ElementTag> const & el,
00214 segment_t<ConfigType> const & seg1,
00215 segment_t<ConfigType> const & seg2)
00216 {
00217 typedef interface_key InterfaceKey;
00218
00219 std::size_t seg_id_lower = std::min(seg1.id(), seg2.id());
00220 std::size_t seg_id_higher = std::max(seg1.id(), seg2.id());
00221
00222 InterfaceKey key(seg_id_lower, seg_id_higher);
00223 detect_interface(seg1, seg2, key);
00224
00225 if (viennadata::find<InterfaceKey, bool>(key)(el) != NULL)
00226 return viennadata::access<InterfaceKey, bool>(key)(el);
00227
00228 return false;
00229 }
00230
00231 }
00232
00233 #endif