Go to the documentation of this file.00001 #ifndef VIENNAFEM_MAPPING_HPP
00002 #define VIENNAFEM_MAPPING_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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
00105 viennadata::access<MappingKeyType, long>(map_key)(*vit) = -1;
00106 }
00107 else
00108 {
00109
00110 if (viennadata::access<MappingKeyType, long>(map_key)(*vit) < 0)
00111 {
00112 viennadata::access<MappingKeyType, long>(map_key)(*vit) = map_index;
00113 map_index += pde_system.unknown(0).size();
00114 }
00115
00116
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
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)
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;
00172 }
00173
00174
00175 }
00176
00177 #endif