ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/algorithm/surface.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_ALGORITHM_SURFACE_HPP
00002 #define VIENNAGRID_ALGORITHM_SURFACE_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 <iostream>
00017 #include <sstream>
00018 #include <string>
00019 #include <stdexcept>
00020 
00021 #include "viennagrid/forwards.hpp"
00022 #include "viennagrid/algorithm/volume.hpp"
00023 #include "viennagrid/algorithm/boundary.hpp"
00024 
00030 namespace viennagrid
00031 {
00032   namespace detail
00033   {
00035     template <typename ElementTypeOrTag, typename MeshT>
00036     typename viennagrid::result_of::coord< MeshT >::type
00037     surface_meshsegment(MeshT const & mesh_obj)
00038     {
00039       typedef typename viennagrid::result_of::const_element_range<MeshT, ElementTypeOrTag>::type  ElementRange;
00040       typedef typename viennagrid::result_of::iterator<ElementRange>::type                        ElementIterator;
00041 
00042       typename viennagrid::result_of::coord<MeshT>::type result = 0;
00043 
00044       ElementRange facets(mesh_obj);
00045       for (ElementIterator fit = facets.begin();
00046                            fit != facets.end();
00047                          ++fit)
00048       {
00049         if (is_boundary(mesh_obj, *fit))
00050           result += viennagrid::volume(*fit);
00051       }
00052       return result;
00053     }
00054   } //namespace detail
00055 
00056 
00057 
00058   //
00059   // The public interface functions
00060   //
00062   template <typename PointAccessorT, typename ElementTag, typename WrappedConfigT>
00063   typename viennagrid::result_of::coord< typename PointAccessorT::value_type >::type
00064   surface(PointAccessorT const accessor, viennagrid::element<ElementTag, WrappedConfigT> const & element)
00065   {
00066     typedef typename viennagrid::result_of::const_facet_range< viennagrid::element<ElementTag, WrappedConfigT> >::type   ElementBoundaryRange;
00067     typedef typename viennagrid::result_of::iterator<ElementBoundaryRange>::type                                         ElementBoundaryIterator;
00068 
00069     typedef typename viennagrid::result_of::coord< typename PointAccessorT::value_type >::type value_type;
00070 
00071     value_type result = 0;
00072 
00073     ElementBoundaryRange boundary = viennagrid::facets(element);
00074     for (ElementBoundaryIterator ebit = boundary.begin();
00075                                  ebit != boundary.end();
00076                                ++ebit)
00077     {
00078       result += viennagrid::volume(accessor, *ebit);
00079     }
00080 
00081     return result;
00082   }
00083 
00085   template < typename ElementTag, typename WrappedConfigT>
00086   typename viennagrid::result_of::coord< viennagrid::element<ElementTag, WrappedConfigT> >::type
00087   surface( viennagrid::element<ElementTag, WrappedConfigT> const & element)
00088   {
00089     return surface( default_point_accessor(element), element );
00090   }
00091 
00092 
00093 
00094   //special case: mesh
00096   template <typename ElementTypeOrTag, typename WrappedConfigT>
00097   typename viennagrid::result_of::coord< mesh<WrappedConfigT> >::type
00098   surface(mesh<WrappedConfigT> const & d)
00099   {
00100     return detail::surface_meshsegment<ElementTypeOrTag>(d);
00101   }
00102 
00104   template <typename WrappedConfigT>
00105   typename viennagrid::result_of::coord< mesh<WrappedConfigT> >::type
00106   surface(mesh<WrappedConfigT> const & d)
00107   {
00108     typedef typename viennagrid::result_of::cell_tag< mesh<WrappedConfigT> >::type CellTag;
00109     return detail::surface_meshsegment< typename viennagrid::result_of::facet_tag<CellTag>::type>(d);
00110   }
00111 
00113   template<typename SegmentationT>
00114   typename viennagrid::result_of::coord< typename SegmentationT::mesh_type >::type
00115   surface(segment_handle<SegmentationT> const & segment)
00116   {
00117     typedef typename viennagrid::result_of::cell_tag< typename SegmentationT::mesh_type >::type CellTag;
00118     return detail::surface_meshsegment< typename viennagrid::result_of::facet_tag<CellTag>::type >(segment);
00119   }
00120 
00121 
00122 
00124   template<typename BoundaryElementTTag, typename MeshT, typename ElementT>
00125   typename viennagrid::result_of::handle<MeshT, BoundaryElementTTag>::type
00126   smallest_boundary_volume( MeshT & mesh_obj, ElementT & element )
00127   {
00128     typedef typename viennagrid::result_of::coord<MeshT>::type numeric_type;
00129     typedef typename viennagrid::result_of::handle<ElementT, BoundaryElementTTag>::type           boundary_element_handle;
00130     typedef typename viennagrid::result_of::element_range<ElementT, BoundaryElementTTag>::type    boundary_element_range_type;
00131     typedef typename viennagrid::result_of::iterator<boundary_element_range_type>::type           boundary_element_range_iterator;
00132 
00133     boundary_element_range_type boundary_elements( element );
00134     boundary_element_range_iterator it = boundary_elements.begin();
00135 
00136     boundary_element_handle best_handle = it.handle();
00137     numeric_type best_volume = viennagrid::volume( mesh_obj, *it );
00138 
00139     for (; it != boundary_elements.end(); ++it)
00140     {
00141       numeric_type volume = viennagrid::volume( mesh_obj, *it );
00142       if (volume < best_volume)
00143       {
00144         best_handle = it.handle();
00145         best_volume = volume;
00146       }
00147     }
00148 
00149     return best_handle;
00150   }
00151 
00153   template<typename BoundaryElementTTag, typename MeshT, typename ElementT>
00154   typename viennagrid::result_of::const_handle<MeshT, BoundaryElementTTag>::type
00155   smallest_boundary_volume( MeshT const & mesh_obj, ElementT const & element )
00156   {
00157     typedef typename viennagrid::result_of::coord<MeshT>::type numeric_type;
00158     typedef typename viennagrid::result_of::const_handle<ElementT, BoundaryElementTTag>::type          boundary_element_handle;
00159     typedef typename viennagrid::result_of::const_element_range<ElementT, BoundaryElementTTag>::type   boundary_element_range_type;
00160     typedef typename viennagrid::result_of::iterator<boundary_element_range_type>::type                boundary_element_range_iterator;
00161 
00162     boundary_element_range_type boundary_elements( element );
00163     boundary_element_range_iterator it = boundary_elements.begin();
00164 
00165     boundary_element_handle best_handle = it.handle();
00166     numeric_type best_volume = viennagrid::volume( mesh_obj, *it );
00167 
00168     for (; it != boundary_elements.end(); ++it)
00169     {
00170       numeric_type volume = viennagrid::volume( mesh_obj, *it );
00171       if (volume < best_volume)
00172       {
00173         best_handle = it.handle();
00174         best_volume = volume;
00175       }
00176     }
00177 
00178     return best_handle;
00179   }
00180 
00182   template<typename BoundaryElementTTag, typename MeshT, typename ElementT>
00183   typename viennagrid::result_of::handle<MeshT, BoundaryElementTTag>::type largest_boundary_volume( MeshT & mesh_obj, ElementT & element )
00184   {
00185     typedef typename viennagrid::result_of::coord<MeshT>::type numeric_type;
00186     typedef typename viennagrid::result_of::handle<ElementT, BoundaryElementTTag>::type           boundary_element_handle;
00187     typedef typename viennagrid::result_of::element_range<ElementT, BoundaryElementTTag>::type    boundary_element_range_type;
00188     typedef typename viennagrid::result_of::iterator<boundary_element_range_type>::type           boundary_element_range_iterator;
00189 
00190     boundary_element_range_type boundary_elements( element );
00191     boundary_element_range_iterator it = boundary_elements.begin();
00192 
00193     boundary_element_handle best_handle = it.handle();
00194     numeric_type best_volume = viennagrid::volume( mesh_obj, *it );
00195 
00196     for (; it != boundary_elements.end(); ++it)
00197     {
00198       numeric_type volume = viennagrid::volume( mesh_obj, *it );
00199       if (volume > best_volume)
00200       {
00201         best_handle = it.handle();
00202         best_volume = volume;
00203       }
00204     }
00205 
00206     return best_handle;
00207   }
00208 
00210   template<typename BoundaryElementTTag, typename MeshT, typename ElementT>
00211   typename viennagrid::result_of::const_handle<MeshT, BoundaryElementTTag>::type largest_boundary_volume( MeshT const & mesh_obj, ElementT const & element )
00212   {
00213     typedef typename viennagrid::result_of::coord<MeshT>::type numeric_type;
00214     typedef typename viennagrid::result_of::const_handle<ElementT, BoundaryElementTTag>::type            boundary_element_handle;
00215     typedef typename viennagrid::result_of::const_element_range<ElementT, BoundaryElementTTag>::type     boundary_element_range_type;
00216     typedef typename viennagrid::result_of::iterator<boundary_element_range_type>::type                  boundary_element_range_iterator;
00217 
00218     boundary_element_range_type boundary_elements( element );
00219     boundary_element_range_iterator it = boundary_elements.begin();
00220 
00221     boundary_element_handle best_handle = it.handle();
00222     numeric_type best_volume = viennagrid::volume( mesh_obj, *it );
00223 
00224     for (; it != boundary_elements.end(); ++it)
00225     {
00226       numeric_type volume = viennagrid::volume( mesh_obj, *it );
00227       if (volume > best_volume)
00228       {
00229         best_handle = it.handle();
00230         best_volume = volume;
00231       }
00232     }
00233 
00234     return best_handle;
00235   }
00236 
00237 
00238 } //namespace viennagrid
00239 #endif