ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/config/mesh_config.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_CONFIG_TOPOLOGY_CONFIG_HPP
00002 #define VIENNAGRID_CONFIG_TOPOLOGY_CONFIG_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 "viennagrid/accessor.hpp"
00017 
00018 #include "viennagrid/config/config.hpp"
00019 #include "viennagrid/config/id_generator_config.hpp"
00020 
00021 
00022 #include "viennagrid/topology/simplex.hpp"
00023 #include "viennagrid/storage/hidden_key_map.hpp"
00024 #include "viennagrid/element/element_key.hpp"
00025 #include "viennagrid/config/element_config.hpp"
00026 
00031 namespace viennagrid
00032 {
00033   namespace config
00034   {
00035     namespace result_of
00036     {
00037       //
00038       // Meta Functions for creating a default config
00039       //
00040 
00042       template<typename ElementTagT, typename boundary_cell_tag>
00043       struct storage_layout_config
00044       {
00045         typedef typename viennagrid::detail::result_of::insert<
00046             typename storage_layout_config<ElementTagT, typename boundary_cell_tag::facet_tag>::type,
00047             viennagrid::static_pair<
00048                 boundary_cell_tag,
00049                 viennagrid::full_handling_tag
00050             >
00051         >::type type;
00052       };
00053 
00054       template<typename ElementTagT>
00055       struct storage_layout_config<ElementTagT, viennagrid::vertex_tag>
00056       {
00057         typedef typename viennagrid::make_typemap<
00058             viennagrid::vertex_tag,
00059             viennagrid::no_orientation_handling_tag
00060         >::type type;
00061       };
00062 
00063       template<typename ElementTagT>
00064       struct storage_layout_config<ElementTagT, viennagrid::null_type>
00065       {
00066         typedef viennagrid::null_type type;
00067       };
00068 
00069 
00071       template<typename ElementTagT, typename boundary_cell_tag, typename VertexContainerT, typename CellContainerT>
00072       struct default_container_tag
00073       {
00074         typedef viennagrid::hidden_key_map_tag< viennagrid::element_key_tag > type;
00075       };
00076 
00077       template<typename ElementTagT, typename VertexContainerT, typename CellContainerT>
00078       struct default_container_tag<ElementTagT, ElementTagT, VertexContainerT, CellContainerT>
00079       {
00080         typedef CellContainerT type;
00081       };
00082 
00083       template<typename ElementTagT, typename VertexContainerT, typename CellContainerT>
00084       struct default_container_tag<ElementTagT, viennagrid::vertex_tag, VertexContainerT, CellContainerT>
00085       {
00086         typedef VertexContainerT type;
00087       };
00088 
00089       template<typename VertexContainerT, typename CellContainerT>
00090       struct default_container_tag<viennagrid::vertex_tag, viennagrid::vertex_tag, VertexContainerT, CellContainerT>
00091       {
00092         typedef VertexContainerT type;
00093       };
00094 
00095 
00097       template<typename CellTagT, typename ElementTagT, typename HandleTagT, typename VertexContainerT, typename CellContainerT>
00098       struct full_element_config
00099       {
00100         typedef typename viennagrid::result_of::handled_container<typename default_container_tag<CellTagT, ElementTagT, VertexContainerT, CellContainerT>::type,
00101                                                                             HandleTagT>::tag                     container_tag;
00102 
00103         typedef typename storage_layout_config<CellTagT,
00104                                                 typename ElementTagT::facet_tag>::type   boundary_storage_layout;
00105 
00106         typedef typename viennagrid::make_typemap<
00107             viennagrid::config::element_id_tag,
00108             viennagrid::smart_id_tag<int>,
00109 
00110             viennagrid::config::element_container_tag,
00111             container_tag,
00112 
00113             viennagrid::config::element_boundary_storage_layout_tag,
00114             boundary_storage_layout,
00115 
00116             viennagrid::config::element_appendix_type_tag,
00117             viennagrid::null_type
00118         >::type type;
00119       };
00120 
00121       template<typename CellTagT, typename HandleTagT, typename VertexContainerT, typename CellContainerT>
00122       struct full_element_config<CellTagT, viennagrid::vertex_tag, HandleTagT, VertexContainerT, CellContainerT>
00123       {
00124         typedef typename viennagrid::result_of::handled_container<typename default_container_tag<CellTagT, viennagrid::vertex_tag, VertexContainerT, CellContainerT>::type,
00125                                                                             HandleTagT>::tag                     container_tag;
00126 
00127         typedef typename viennagrid::make_typemap<
00128             viennagrid::config::element_id_tag,
00129             viennagrid::smart_id_tag<int>,
00130 
00131             viennagrid::config::element_container_tag,
00132             container_tag,
00133 
00134             viennagrid::config::element_boundary_storage_layout_tag,
00135             viennagrid::null_type,
00136 
00137             viennagrid::config::element_appendix_type_tag,
00138             viennagrid::null_type
00139         >::type type;
00140       };
00141 
00142 
00144       template<typename CellTagT, typename ElementTagT, typename HandleTagT, typename VertexContainerTagT, typename CellContainerTagT>
00145       struct full_topology_config_helper
00146       {
00147         typedef typename viennagrid::detail::result_of::insert<
00148             typename full_topology_config_helper<CellTagT, typename ElementTagT::facet_tag, HandleTagT, VertexContainerTagT, CellContainerTagT>::type,
00149             viennagrid::static_pair<
00150                 ElementTagT,
00151                 typename full_element_config<CellTagT, ElementTagT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type
00152             >
00153         >::type type;
00154       };
00155 
00156       template<typename CellTagT, typename HandleTagT, typename VertexContainerTagT, typename CellContainerTagT>
00157       struct full_topology_config_helper<CellTagT, viennagrid::vertex_tag, HandleTagT, VertexContainerTagT, CellContainerTagT>
00158       {
00159         typedef typename viennagrid::make_typemap<
00160             viennagrid::vertex_tag,
00161             typename full_element_config<CellTagT, viennagrid::vertex_tag, HandleTagT, VertexContainerTagT, CellContainerTagT>::type
00162         >::type type;
00163       };
00164 
00165 
00172       template<typename CellTagT,
00173                typename HandleTagT  = viennagrid::pointer_handle_tag,
00174                typename VertexContainerTagT = viennagrid::std_deque_tag,
00175                typename CellContainerTagT = viennagrid::std_deque_tag>
00176       struct full_topology_config
00177       {
00178         typedef typename full_topology_config_helper<CellTagT, CellTagT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type type;
00179       };
00180 
00181 
00182 
00183 
00190       template<typename CellTagT,
00191                typename HandleTagT  = viennagrid::pointer_handle_tag,
00192                typename VertexContainerTagT = viennagrid::std_deque_tag,
00193                typename CellContainerTagT = viennagrid::std_deque_tag>
00194       struct thin_topology_config
00195       {
00196         typedef typename viennagrid::make_typemap<
00197             CellTagT,
00198             typename viennagrid::make_typemap<
00199                 viennagrid::config::element_id_tag,
00200                 viennagrid::smart_id_tag<int>,
00201 
00202                 viennagrid::config::element_container_tag,
00203                 typename viennagrid::result_of::handled_container<CellContainerTagT, HandleTagT>::tag,
00204 
00205                 viennagrid::config::element_boundary_storage_layout_tag,
00206                 typename storage_layout_config<CellTagT, viennagrid::vertex_tag>::type,
00207 
00208                 viennagrid::config::element_appendix_type_tag,
00209                 viennagrid::null_type
00210             >::type,
00211 
00212 
00213             viennagrid::vertex_tag,
00214             typename viennagrid::make_typemap<
00215               viennagrid::config::element_id_tag,
00216               viennagrid::smart_id_tag<int>,
00217 
00218               viennagrid::config::element_container_tag,
00219               typename viennagrid::result_of::handled_container<VertexContainerTagT, HandleTagT>::tag,
00220 
00221               viennagrid::config::element_boundary_storage_layout_tag,
00222               viennagrid::null_type,
00223 
00224               viennagrid::config::element_appendix_type_tag,
00225               viennagrid::null_type
00226             >::type
00227         >::type type;
00228       };
00229 
00230 
00231 
00232 
00240       template<typename CellTagT,
00241                 typename PointType,
00242                 typename HandleTagT = viennagrid::pointer_handle_tag,
00243                 typename VertexContainerTagT = viennagrid::std_deque_tag,
00244                 typename CellContainerTagT = viennagrid::std_deque_tag>
00245       struct full_mesh_config
00246       {
00247         typedef typename full_topology_config<CellTagT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type MeshConfig;
00248         typedef typename query<MeshConfig, null_type, vertex_tag>::type VertexConfig;
00249 
00250         typedef typename viennagrid::detail::result_of::insert_or_modify<
00251             MeshConfig,
00252             viennagrid::static_pair<
00253                 vertex_tag,
00254                 typename viennagrid::detail::result_of::insert_or_modify<
00255 
00256                     VertexConfig,
00257                     viennagrid::static_pair<
00258                         element_appendix_type_tag,
00259                         PointType
00260                     >
00261 
00262                 >::type
00263             >
00264         >::type type;
00265       };
00266 
00267       template<typename CellTagT, typename HandleTagT, typename VertexContainerTagT, typename CellContainerTagT>
00268       struct full_mesh_config<CellTagT, void, HandleTagT, VertexContainerTagT, CellContainerTagT>
00269       {
00270         typedef typename viennagrid::config::result_of::full_topology_config<CellTagT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type type;
00271       };
00272 
00273 
00274 
00275 
00283       template<typename CellTagT,
00284                 typename PointType,
00285                 typename HandleTagT = viennagrid::pointer_handle_tag,
00286                 typename VertexContainerTagT = viennagrid::std_deque_tag,
00287                 typename CellContainerTagT = viennagrid::std_deque_tag>
00288       struct thin_mesh_config
00289       {
00290         typedef typename thin_topology_config<CellTagT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type MeshConfig;
00291         typedef typename query<MeshConfig, null_type, vertex_tag>::type VertexConfig;
00292 
00293         typedef typename viennagrid::detail::result_of::insert_or_modify<
00294             MeshConfig,
00295             viennagrid::static_pair<
00296                 vertex_tag,
00297                 typename viennagrid::detail::result_of::insert_or_modify<
00298 
00299                     VertexConfig,
00300                     viennagrid::static_pair<
00301                         element_appendix_type_tag,
00302                         PointType
00303                     >
00304 
00305                 >::type
00306             >
00307         >::type type;
00308       };
00309 
00310       template<typename CellTagT, typename HandleTagT, typename VertexContainerTagT, typename CellContainerTagT>
00311       struct thin_mesh_config<CellTagT, void, HandleTagT, VertexContainerTagT, CellContainerTagT>
00312       {
00313         typedef typename viennagrid::config::result_of::thin_topology_config<CellTagT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type type;
00314       };
00315 
00316 
00317 
00318 
00320       template<typename WrappedConfigType, typename ElementTagT>
00321       struct element_container
00322       {
00323         typedef viennagrid::element<ElementTagT, WrappedConfigType> element_type;
00324         typedef typename viennagrid::result_of::container<element_type, typename query_element_container_tag<WrappedConfigType, ElementTagT>::type >::type type;
00325       };
00326 
00327       template<typename container_collection_typemap, typename ElementTagT>
00328       struct element_container< collection<container_collection_typemap>, ElementTagT >
00329       {
00330         typedef typename viennagrid::result_of::element<collection<container_collection_typemap>, ElementTagT>::type element_type;
00331         typedef typename viennagrid::detail::result_of::find< container_collection_typemap, element_type >::type::second type;
00332       };
00333 
00334 
00336       template<typename WrappedConfigT, typename CurrentConfigT = typename WrappedConfigT::type>
00337       struct element_container_typemap;
00338 
00339       template<typename WrappedConfigT, typename ElementTagT, typename ValueConfigT, typename TailT>
00340       struct element_container_typemap< WrappedConfigT, viennagrid::typelist< viennagrid::static_pair<ElementTagT, ValueConfigT>, TailT > >
00341       {
00342         typedef viennagrid::typelist<
00343             viennagrid::static_pair<
00344                 viennagrid::element<ElementTagT, WrappedConfigT>,
00345                 typename element_container<WrappedConfigT, ElementTagT>::type
00346             >,
00347             typename element_container_typemap<WrappedConfigT, TailT>::type
00348         > type;
00349       };
00350 
00351       template<typename WrappedConfigT>
00352       struct element_container_typemap<WrappedConfigT, viennagrid::null_type>
00353       {
00354           typedef viennagrid::null_type type;
00355       };
00356     }
00357 
00358 
00359 
00361     template<typename CellTagT,
00362               typename PointTypeT,
00363               typename HandleTagT = viennagrid::pointer_handle_tag,
00364               typename VertexContainerTagT = viennagrid::std_deque_tag,
00365               typename CellContainerTagT = viennagrid::std_deque_tag>
00366     struct wrapped_mesh_config_t
00367     {
00368       typedef typename result_of::full_mesh_config<CellTagT, PointTypeT, HandleTagT, VertexContainerTagT, CellContainerTagT>::type type;
00369     };
00370   }
00371 
00372   namespace result_of
00373   {
00375     template<typename WrappedConfigType, typename ElementTagT, typename BoundaryElementTaglistT =
00376       typename boundary_element_taglist< viennagrid::element<ElementTagT, WrappedConfigType> >::type >
00377     struct coboundary_container_collection_per_element_typemap;
00378 
00380     template<typename WrappedConfigType, typename ElementTagT>
00381     struct coboundary_container_collection_per_element_typemap<WrappedConfigType, ElementTagT, viennagrid::null_type>
00382     {
00383         typedef viennagrid::null_type type;
00384     };
00385 
00386     template<typename WrappedConfigType, typename ElementTagT, typename BoundaryElementTagT, typename tail>
00387     struct coboundary_container_collection_per_element_typemap<WrappedConfigType, ElementTagT, viennagrid::typelist<BoundaryElementTagT, tail> >
00388     {
00389       typedef typename config::result_of::query<WrappedConfigType, long, config::mesh_change_counter_tag>::type MeshChangeCounterType;
00390 
00391       typedef typename config::result_of::query<WrappedConfigType, std_vector_tag, ElementTagT, config::coboundary_container_tag, BoundaryElementTagT>::type coboundary_container_tag;
00392       typedef typename config::result_of::query<WrappedConfigType, std_vector_tag, ElementTagT, config::coboundary_view_container_tag, BoundaryElementTagT>::type coboundary_view_container_tag;
00393 
00394 
00395       typedef typename config::result_of::element_container< WrappedConfigType, ElementTagT>::type base_element_container;
00396       typedef typename viennagrid::result_of::view<base_element_container, coboundary_view_container_tag>::type element_view_type;
00397       typedef typename result_of::container<element_view_type, coboundary_container_tag >::type base_coboundary_container;
00398 
00399       typedef viennagrid::typelist<
00400           viennagrid::static_pair<
00401               viennagrid::static_pair<
00402                   BoundaryElementTagT,
00403                   ElementTagT
00404               >,
00405               detail::coboundary_container_wrapper<base_coboundary_container, MeshChangeCounterType>
00406           >,
00407           typename coboundary_container_collection_per_element_typemap<WrappedConfigType, ElementTagT, tail>::type
00408       > type;
00409     };
00414     template<typename WrappedConfigType, typename ElementTaglistT = typename viennagrid::detail::result_of::key_typelist<typename WrappedConfigType::type>::type>
00415     struct coboundary_container_collection_typemap {};
00416 
00418     template<typename WrappedConfigType>
00419     struct coboundary_container_collection_typemap<WrappedConfigType, viennagrid::null_type>
00420     {
00421       typedef viennagrid::null_type type;
00422     };
00423 
00424     template<typename WrappedConfigType, typename ElementTagT, typename tail>
00425     struct coboundary_container_collection_typemap<WrappedConfigType, viennagrid::typelist<ElementTagT, tail> >
00426     {
00427       typedef typename viennagrid::detail::result_of::merge<
00428         typename coboundary_container_collection_per_element_typemap<WrappedConfigType, ElementTagT>::type,
00429         typename coboundary_container_collection_typemap<WrappedConfigType, tail>::type
00430       >::type type;
00431     };
00433   }
00434 
00435 
00436 
00437 
00438   namespace result_of
00439   {
00441     template<typename WrappedConfigType, typename ElementTagT, typename BoundaryElementTaglistT =
00442       typename boundary_element_taglist< viennagrid::element<ElementTagT, WrappedConfigType> >::type >
00443     struct neighbor_container_collection_per_element_typemap {};
00444 
00446     template<typename WrappedConfigType, typename ElementTagT>
00447     struct neighbor_container_collection_per_element_typemap<WrappedConfigType, ElementTagT, viennagrid::null_type>
00448     {
00449       typedef viennagrid::null_type type;
00450     };
00451 
00452     template<typename WrappedConfigType, typename ElementTagT, typename ConnectorElementTagT, typename tail>
00453     struct neighbor_container_collection_per_element_typemap<WrappedConfigType, ElementTagT, viennagrid::typelist<ConnectorElementTagT, tail> >
00454     {
00455       typedef typename config::result_of::query<WrappedConfigType, long, config::mesh_change_counter_tag>::type MeshChangeCounterType;
00456 
00457       typedef typename config::result_of::query<WrappedConfigType, std_vector_tag, ElementTagT, config::neighbor_container_tag, ConnectorElementTagT>::type neighbor_container_tag;
00458       typedef typename config::result_of::query<WrappedConfigType, std_vector_tag, ElementTagT, config::neighbor_view_container_tag, ConnectorElementTagT>::type neighbor_view_container_tag;
00459 
00460       typedef typename config::result_of::element_container< WrappedConfigType, ElementTagT>::type base_element_container;
00461       typedef typename viennagrid::result_of::view<base_element_container, neighbor_view_container_tag>::type element_view_type;
00462       typedef typename result_of::container<element_view_type, neighbor_container_tag >::type base_container;
00463 
00464       typedef viennagrid::typelist<
00465           viennagrid::static_pair<
00466               viennagrid::static_pair<
00467                   ElementTagT,
00468                   ConnectorElementTagT
00469               >,
00470               detail::neighbor_container_wrapper<base_container, MeshChangeCounterType>
00471           >,
00472           typename neighbor_container_collection_per_element_typemap<WrappedConfigType, ElementTagT, tail>::type
00473       > type;
00474     };
00479     template<typename WrappedConfigType, typename ElementTaglistT = typename viennagrid::detail::result_of::key_typelist<typename WrappedConfigType::type>::type>
00480     struct neighbor_container_collection_typemap {};
00481 
00483     template<typename WrappedConfigType>
00484     struct neighbor_container_collection_typemap<WrappedConfigType, viennagrid::null_type>
00485     {
00486       typedef viennagrid::null_type type;
00487     };
00488 
00489     template<typename WrappedConfigType, typename ElementTagT, typename tail>
00490     struct neighbor_container_collection_typemap<WrappedConfigType, viennagrid::typelist<ElementTagT, tail> >
00491     {
00492       typedef typename viennagrid::detail::result_of::merge<
00493         typename neighbor_container_collection_per_element_typemap<WrappedConfigType, ElementTagT>::type,
00494         typename neighbor_container_collection_typemap<WrappedConfigType, tail>::type
00495       >::type type;
00496     };
00498   }
00499 
00500 
00501   namespace result_of
00502   {
00507     template<typename ElementTypelistT>
00508     struct topologic_cell_dimension;
00509 
00511     template<>
00512     struct topologic_cell_dimension<viennagrid::null_type>
00513     {
00514       static const int value = -1;
00515     };
00516 
00517     template<typename ElementTypeOrTagT, typename TailT>
00518     struct topologic_cell_dimension< viennagrid::typelist<ElementTypeOrTagT, TailT> >
00519     {
00520       typedef typename viennagrid::result_of::element_tag<ElementTypeOrTagT>::type ElementTag;
00521       static const int tail_cell_dimension = topologic_cell_dimension<TailT>::value;
00522       static const int current_element_dimension = ElementTag::dim;
00523 
00524       static const int value = (tail_cell_dimension > current_element_dimension) ? tail_cell_dimension : current_element_dimension;
00525     };
00531     template<typename ElementTypelistT, int TopologicDimensionV>
00532     struct elements_of_topologic_dim;
00533 
00535     template<int TopologicDimensionV>
00536     struct elements_of_topologic_dim< viennagrid::null_type, TopologicDimensionV >
00537     {
00538       typedef viennagrid::null_type type;
00539     };
00540 
00541     template<typename ElementTypeOrTagT, typename TailT, int TopologicDimensionV>
00542     struct elements_of_topologic_dim< viennagrid::typelist<ElementTypeOrTagT, TailT>, TopologicDimensionV >
00543     {
00544       typedef typename viennagrid::result_of::element_tag<ElementTypeOrTagT>::type ElementTag;
00545       typedef typename elements_of_topologic_dim<TailT, TopologicDimensionV>::type TailTypelist;
00546 
00547       typedef typename viennagrid::detail::IF<
00548           ElementTag::dim == TopologicDimensionV,
00549           typename viennagrid::detail::result_of::push_back<TailTypelist, ElementTag>::type,
00550           TailTypelist
00551       >::type type;
00552     };
00557     template<typename ElementTypelistT>
00558     struct cell_tag_from_typelist
00559     {
00560       static const int dim = topologic_cell_dimension<ElementTypelistT>::value;
00561       typedef typename elements_of_topologic_dim<ElementTypelistT, dim>::type cell_types;
00562       typedef typename viennagrid::detail::result_of::at<cell_types,0>::type type;
00563     };
00564 
00565 
00566 
00567 
00568 
00570     template<typename WrappedConfigType, typename ElementTaglistT>
00571     struct boundary_information_collection_typemap_impl {};
00572 
00574     template<typename WrappedConfigType>
00575     struct boundary_information_collection_typemap_impl<WrappedConfigType, viennagrid::null_type>
00576     {
00577       typedef viennagrid::null_type type;
00578     };
00579 
00580     template<typename WrappedConfigType, typename ElementTagT, typename TailT>
00581     struct boundary_information_collection_typemap_impl<WrappedConfigType, viennagrid::typelist<ElementTagT, TailT> >
00582     {
00583       typedef typename config::result_of::query<WrappedConfigType, long, config::mesh_change_counter_tag>::type MeshChangeCounterType;
00584 
00585       typedef typename config::result_of::query<WrappedConfigType, std_map_tag, ElementTagT, config::boundary_information_container_tag>::type boundary_container_tag;
00586 
00587       typedef viennagrid::element<ElementTagT, WrappedConfigType> ElementType;
00588       typedef typename result_of::accessor_container<ElementType, bool, boundary_container_tag>::type base_container;
00589 
00590       typedef viennagrid::typelist<
00591           viennagrid::static_pair<
00592               ElementTagT,
00593               detail::boundary_information_wrapper<base_container, MeshChangeCounterType>
00594           >,
00595           typename boundary_information_collection_typemap_impl<WrappedConfigType, TailT>::type
00596       > type;
00597     };
00601     template<typename WrappedConfigType>
00602     struct boundary_information_collection_typemap
00603     {
00604       typedef typename viennagrid::detail::result_of::key_typelist<typename WrappedConfigType::type>::type ElementTagTlist;
00605 
00606       typedef typename cell_tag_from_typelist<ElementTagTlist>::type CellTag;
00607       typedef typename viennagrid::detail::result_of::erase< ElementTagTlist, CellTag>::type ElementTypelistWithoutCellTag;
00608 
00609 
00610       typedef typename boundary_information_collection_typemap_impl<WrappedConfigType, ElementTypelistWithoutCellTag>::type type;
00611     };
00612   }
00613 
00614 
00615 
00616   namespace config
00617   {
00618     namespace result_of
00619     {
00621       template<typename WrappedConfigType>
00622       struct element_collection
00623       {
00624         typedef typename config::result_of::element_container_typemap<WrappedConfigType>::type element_container_typelist;
00625         typedef collection< element_container_typelist > type;
00626       };
00627     }
00628   }
00629 }
00630 
00631 
00632 #endif