• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List

/export/development/ViennaFEM/viennafem/mapping.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAFEM_MAPPING_HPP
00002 #define VIENNAFEM_MAPPING_HPP
00003 
00004 /* =========================================================================
00005    Copyright (c) 2012, Institute for Microelectronics,
00006                        Institute for Analysis and Scientific Computing,
00007                        TU Wien.
00008                              -----------------
00009                ViennaFEM - The Vienna Finite Element Method Library
00010                              -----------------
00011 
00012    Author:     Karl Rupp                          rupp@iue.tuwien.ac.at
00013 
00014    License:    MIT (X11), see file LICENSE in the ViennaFEM base directory
00015 ============================================================================ */
00016 
00017 
00018 #include <vector>
00019 #include "viennafem/forwards.h"
00020 #include "viennagrid/forwards.h"
00021 #include "viennagrid/domain.hpp"
00022 #include "viennagrid/segment.hpp"
00023 #include "viennagrid/iterators.hpp"
00024 
00025 
00030 namespace viennafem
00031 {
00032   
00033   namespace detail
00034   {
00037     template <typename EntityType>
00038     struct extract_domain
00039     {
00040       typedef EntityType  type;
00041       static EntityType & apply(EntityType & domain) { return domain; }
00042     };
00043     
00045     template <typename ConfigType>
00046     struct extract_domain<viennagrid::segment_t<ConfigType> >
00047     {
00048       typedef typename viennagrid::result_of::domain<ConfigType>::type    type;
00049       static type & apply(viennagrid::segment_t<ConfigType> & seg) { return seg.domain(); }
00050     };
00051   }
00052   
00053   
00057   template <typename SystemType, typename DomainType>
00058   long create_mapping(SystemType & pde_system,
00059                       DomainType & domain)
00060   {
00061     typedef typename DomainType::config_type              Config;
00062     typedef typename Config::cell_tag                     CellTag;
00063     
00064     typedef typename viennagrid::result_of::point<Config>::type                            PointType;
00065     typedef typename viennagrid::result_of::ncell<Config, CellTag::dim>::type   CellType;
00066 
00067     typedef typename viennagrid::result_of::ncell_range<DomainType, 0>::type                VertexContainer;
00068     typedef typename viennagrid::result_of::iterator<VertexContainer>::type                     VertexIterator;
00069 
00070     typedef typename SystemType::mapping_key_type   MappingKeyType;
00071     typedef typename SystemType::boundary_key_type  BoundaryKeyType;
00072     
00073     BoundaryKeyType bnd_key(pde_system.option(0).data_id());
00074     MappingKeyType  map_key(pde_system.option(0).data_id());
00075     
00076     long start_index = viennadata::access<MappingKeyType, long>(map_key)(detail::extract_domain<DomainType>::apply(domain));
00077     long map_index = start_index;
00078     bool init_done = viennadata::access<MappingKeyType, bool>(map_key)(detail::extract_domain<DomainType>::apply(domain));
00079 
00080     //eventually, map indices need to be set to invalid first:
00081     if (!init_done)
00082     {
00083       typedef typename detail::extract_domain<DomainType>::type   TrueDomainType;
00084       typedef typename viennagrid::result_of::ncell_range<TrueDomainType, 0>::type            DomainVertexContainer;
00085       typedef typename viennagrid::result_of::iterator<DomainVertexContainer>::type               DomainVertexIterator;
00086       
00087       DomainVertexContainer vertices = viennagrid::ncells<0>(detail::extract_domain<DomainType>::apply(domain));
00088       for (DomainVertexIterator vit = vertices.begin();
00089           vit != vertices.end();
00090           ++vit)
00091       {  
00092         viennadata::access<MappingKeyType, long>(map_key)(*vit) = -1;
00093       }
00094       viennadata::access<MappingKeyType, bool>(map_key)(detail::extract_domain<DomainType>::apply(domain)) = true;
00095     }
00096     
00097     VertexContainer vertices = viennagrid::ncells<0>(domain);
00098     for (VertexIterator vit = vertices.begin();
00099         vit != vertices.end();
00100         ++vit)
00101     {  
00102       if (viennadata::access<BoundaryKeyType, bool>(bnd_key)(*vit))
00103       {
00104         //std::cout << "boundary vertex" << std::endl;
00105         viennadata::access<MappingKeyType, long>(map_key)(*vit) = -1;
00106       }
00107       else
00108       {
00109         //std::cout << "interior vertex" << std::endl;
00110         if (viennadata::access<MappingKeyType, long>(map_key)(*vit) < 0) //only assign if no dof assigned yet
00111         {
00112           viennadata::access<MappingKeyType, long>(map_key)(*vit) = map_index;
00113           map_index += pde_system.unknown(0).size();
00114         }
00115         //else
00116         //  std::cout << "Found vertex with DOF!" << std::endl;
00117       }
00118     }
00119     
00120     viennadata::access<MappingKeyType, long>(map_key)(detail::extract_domain<DomainType>::apply(domain)) = map_index;
00121     
00122     return map_index;
00123   }
00124   
00125   
00126   
00127 
00130   template < typename SystemType, typename CellType>
00131   std::vector<long> mapping_indices(SystemType & pde_system, CellType const & cell, std::size_t pde_id = 0)
00132   {
00133     typedef typename CellType::config_type              Config;
00134     typedef typename Config::cell_tag                     CellTag;
00135     
00136     typedef typename viennagrid::result_of::const_ncell_range<CellType, 0>::type                 VertexOnCellContainer;
00137     typedef typename viennagrid::result_of::iterator<VertexOnCellContainer>::type               VertexOnCellIterator;
00138 
00139     typedef typename SystemType::mapping_key_type   MappingKeyType;
00140     typedef std::vector<long>                                   MappingContainer;
00141     
00142    
00143     MappingKeyType map_key(pde_system.option(pde_id).data_id());
00144 
00145     VertexOnCellContainer vertices_on_cell = viennagrid::ncells<0>(cell);
00146     
00147     std::size_t unknown_components = pde_system.unknown(pde_id).size();
00148     //std::cout << "* mapping_indices() with space_id = " << space_id << " and unknown_components = " << unknown_components << std::endl;
00149     
00150     MappingContainer ret(viennagrid::topology::bndcells<CellTag, 0>::num * unknown_components);
00151     
00152     long local_index = 0;
00153     for (VertexOnCellIterator vocit = vertices_on_cell.begin();
00154                               vocit != vertices_on_cell.end();
00155                               ++vocit)
00156     {
00157       long map_base = viennadata::access<MappingKeyType, long>(map_key)(*vocit);
00158       
00159       if (map_base < 0) //Dirichlet boundary
00160       {
00161         for (std::size_t i=0; i<unknown_components; ++i)
00162           ret[local_index++] = map_base;
00163       }
00164       else
00165       {
00166         for (std::size_t i=0; i<unknown_components; ++i)
00167           ret[local_index++] = map_base + i;
00168       }
00169     }
00170    
00171     return ret; //TODO: Avoid temporary
00172   }   
00173    
00174 
00175 }
00176 
00177 #endif

Generated on Wed Feb 29 2012 21:51:05 for ViennaFEM - The Vienna Finite Element Method Library by  doxygen 1.7.1