FEI  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fei_DofMapper.hpp
1 /*--------------------------------------------------------------------*/
2 /* Copyright 2009 Sandia Corporation. */
3 /* Under the terms of Contract DE-AC04-94AL85000, there is a */
4 /* non-exclusive license for use of this work by or on behalf */
5 /* of the U.S. Government. Export of this program may require */
6 /* a license from the United States Government. */
7 /*--------------------------------------------------------------------*/
8 
9 #ifndef _fei_DofMapper_hpp_
10 #define _fei_DofMapper_hpp_
11 
12 #include <fei_macros.hpp>
13 
14 #include <set>
15 #include <map>
16 #include <sstream>
17 #include <stdexcept>
18 
19 #include <fei_Dof.hpp>
20 
21 namespace fei {
22 
41 template<class LocalOrdinal, class GlobalOrdinal, class DofOrder=less_rank_id_field<LocalOrdinal, GlobalOrdinal> >
42 class DofMapper {
43  public:
46  : m_dof_idx(), m_idx_dof(), m_maps_are_valid(false), m_field_sizes() {}
47 
50 
51  void addDOF(LocalOrdinal rank, GlobalOrdinal id, LocalOrdinal field)
52  {
53  if (m_field_sizes.find(field) == m_field_sizes.end()) m_field_sizes.insert(std::make_pair(field,1));
54  //m_maps_are_valid is false when a new Dof is inserted.
55  m_maps_are_valid =
56  m_dof_idx.insert(std::make_pair(Dof<LocalOrdinal,GlobalOrdinal>(rank, id, field), 0)).second;
57  }
58 
63  void setFieldSize(LocalOrdinal field, LocalOrdinal field_size);
64 
65  LocalOrdinal getFieldSize(LocalOrdinal field) const;
66 
67  GlobalOrdinal getGlobalIndex(LocalOrdinal rank, GlobalOrdinal id, LocalOrdinal field) const;
68 
69  std::pair<const Dof<LocalOrdinal,GlobalOrdinal>*,LocalOrdinal> getDof(GlobalOrdinal global_index) const;
70 
71  bool maps_are_valid() const { return m_maps_are_valid; }
72  void set_maps_are_valid(bool flag) { m_maps_are_valid = flag; }
73 
74  typedef typename std::map<Dof<LocalOrdinal,GlobalOrdinal>,GlobalOrdinal,DofOrder> DofMap;
75 
76  typename DofMap::const_iterator begin_dof() const
77  { return m_dof_idx.begin(); }
78 
79  typename DofMap::const_iterator end_dof() const
80  { return m_dof_idx.end(); }
81 
82  typename DofMap::iterator begin_dof()
83  { return m_dof_idx.begin(); }
84 
85  typename DofMap::iterator end_dof()
86  { return m_dof_idx.end(); }
87 
88  typedef typename std::map<GlobalOrdinal,const Dof<LocalOrdinal,GlobalOrdinal>*> IdxMap;
89 
90  typename IdxMap::const_iterator begin_idx() const
91  { return m_idx_dof.begin(); }
92 
93  typename IdxMap::const_iterator end_idx() const
94  { return m_idx_dof.end(); }
95 
96  typename IdxMap::iterator begin_idx()
97  { return m_idx_dof.begin(); }
98 
99  typename IdxMap::iterator end_idx()
100  { return m_idx_dof.end(); }
101 
102  const DofMap& get_dof_idx_map() const {return m_dof_idx;}
103  DofMap& get_dof_idx_map() {return m_dof_idx;}
104 
105  const IdxMap& get_idx_dof_map() const {return m_idx_dof;}
106  IdxMap& get_idx_dof_map() {return m_idx_dof;}
107 
108  typedef typename std::map<LocalOrdinal,LocalOrdinal> FieldSizeMap;
109  const FieldSizeMap& getFieldSizeMap() const {return m_field_sizes;}
110 
111  private:
112  std::map<Dof<LocalOrdinal, GlobalOrdinal>, GlobalOrdinal, DofOrder > m_dof_idx;
113 
114  std::map<GlobalOrdinal, const Dof<LocalOrdinal, GlobalOrdinal>*> m_idx_dof;
115  bool m_maps_are_valid;
116 
117  std::map<LocalOrdinal,LocalOrdinal> m_field_sizes;
118 
119  DofMapper(const DofMapper<LocalOrdinal,GlobalOrdinal>& src);
120  DofMapper& operator=(const DofMapper<LocalOrdinal,GlobalOrdinal>& src);
121 };//class DofMapper
122 
123 template<class LocalOrdinal,class GlobalOrdinal,class DofOrder>
124 void DofMapper<LocalOrdinal,GlobalOrdinal,DofOrder>::setFieldSize(LocalOrdinal field, LocalOrdinal field_size)
125 {
126  typename FieldSizeMap::iterator f_iter = m_field_sizes.find(field);
127  if (f_iter == m_field_sizes.end()) {
128  m_field_sizes.insert(std::make_pair(field, field_size));
129  }
130  else {
131  //field already present, resetting field_size:
132  f_iter->second = field_size;
133  }
134 }
135 
136 template<class LocalOrdinal,class GlobalOrdinal,class DofOrder>
137 LocalOrdinal DofMapper<LocalOrdinal,GlobalOrdinal,DofOrder>::getFieldSize(LocalOrdinal field) const
138 {
139  typename FieldSizeMap::const_iterator f_iter = m_field_sizes.find(field);
140  if (f_iter == m_field_sizes.end()) {
141  std::ostringstream os;
142  os << "fei::DofMapper::getFieldSize ERROR, field=="
143  << field << " not found";
144  std::string str = os.str();
145  throw std::runtime_error(str);
146  }
147  return f_iter->second;
148 }
149 
150 template<class LocalOrdinal,class GlobalOrdinal,class DofOrder>
151 GlobalOrdinal DofMapper<LocalOrdinal,GlobalOrdinal,DofOrder>::getGlobalIndex(LocalOrdinal rank, GlobalOrdinal id, LocalOrdinal field) const
152 {
153  typename DofMap::const_iterator iter = m_dof_idx.find(Dof<LocalOrdinal,GlobalOrdinal>(rank,id,field));
154  if (iter == m_dof_idx.end()) {
155  std::ostringstream osstr;
156  osstr << "fei::DofMapper::getGlobalIndex ERROR, dof("
157  << rank << "," << id << "," << field << ") not found.";
158  std::string str = osstr.str();
159  throw std::runtime_error(str);
160  }
161 
162  return iter->second;
163 }
164 
165 template<class LocalOrdinal,class GlobalOrdinal,class DofOrder>
166 std::pair<const Dof<LocalOrdinal,GlobalOrdinal>*,LocalOrdinal>
167 DofMapper<LocalOrdinal,GlobalOrdinal,DofOrder>::getDof(GlobalOrdinal global_index) const
168 {
169  typename IdxMap::const_iterator iter = m_idx_dof.lower_bound(global_index);
170  if (iter == m_idx_dof.begin()) {
171  if (iter->first == global_index) {
172  return std::make_pair(iter->second, global_index);
173  }
174  else {
175  std::ostringstream osstr;
176  osstr << "fei::DofMapper::getDof ERROR, dof not found for global_index=="
177  << global_index;
178  std::string str = osstr.str();
179  throw std::runtime_error(str);
180  }
181  }
182  else if (iter != m_idx_dof.end() && iter->first == global_index) {
183  //return pair(dof,component-of-field)
184  return std::make_pair(iter->second, 0);
185  }
186 
187  bool last_dof = iter == m_idx_dof.end();
188  --iter;
189  //return pair(dof,component-of-field)
190  LocalOrdinal component = global_index - iter->first;
191  bool check_range_of_component = last_dof && !m_field_sizes.empty();
192  if (check_range_of_component) {
193  typename std::map<LocalOrdinal,LocalOrdinal>::const_iterator f_iter = m_field_sizes.find(iter->second->field());
194  if (f_iter == m_field_sizes.end() || f_iter->second <= component) {
195  std::ostringstream os;
196  os << "fei::DofMapper::getDof ERROR2, dof not found for global_index=="
197  << global_index;
198  std::string str = os.str();
199  throw std::runtime_error(str);
200  }
201  }
202 
203  return std::make_pair(iter->second, component);
204 }
205 
206 }//namespace fei
207 
208 #endif
209 
void setFieldSize(LocalOrdinal field, LocalOrdinal field_size)