9 #ifndef _fei_FieldDofMap_hpp_
10 #define _fei_FieldDofMap_hpp_
12 #include <fei_macros.hpp>
13 #include <fei_constants.hpp>
22 template<
class LocalOrdinal>
26 : m_dof_id_map(), m_need_to_compute_dof_ids(true)
31 void add_field(LocalOrdinal fieldID, LocalOrdinal fieldSize, LocalOrdinal fieldType=fei::UNKNOWN);
33 LocalOrdinal get_dof_id(LocalOrdinal fieldID, LocalOrdinal offset);
36 void compute_dof_ids();
39 typedef std::map<LocalOrdinal,std::pair<LocalOrdinal,LocalOrdinal> > dof_id_map;
41 dof_id_map m_dof_id_map;
42 bool m_need_to_compute_dof_ids;
45 template<
class LocalOrdinal>
46 void FieldDofMap<LocalOrdinal>::add_field(LocalOrdinal fieldID, LocalOrdinal fieldSize, LocalOrdinal fieldType)
49 m_dof_id_map.insert(std::make_pair(fieldID,std::make_pair(fieldSize,fieldType)));
50 m_need_to_compute_dof_ids =
true;
53 template<
class LocalOrdinal>
54 LocalOrdinal FieldDofMap<LocalOrdinal>::get_dof_id(LocalOrdinal fieldID, LocalOrdinal offset)
56 if (m_need_to_compute_dof_ids) {
60 typename dof_id_map::const_iterator
61 iter = m_dof_id_map.find(fieldID);
62 if (iter == m_dof_id_map.end()) {
63 throw std::runtime_error(
"fei::FieldDofMap ERROR, specified fieldID not found.");
66 if (offset >= iter->second.first) {
67 throw std::runtime_error(
"FieldDofMap::get_dof_id ERROR, specified offset is greater than field-size.");
72 return iter->second.second + offset;
75 template<
class LocalOrdinal>
76 void FieldDofMap<LocalOrdinal>::compute_dof_ids()
78 if (!m_need_to_compute_dof_ids)
return;
86 typedef std::map<LocalOrdinal, typename dof_id_map::iterator> dof_iter_map;
87 dof_iter_map dof_2_iter;
89 typename dof_id_map::iterator
90 iter = m_dof_id_map.begin(), iter_end = m_dof_id_map.end();
92 for(; iter!=iter_end; ++iter) {
93 LocalOrdinal this_dof_id = iter->second.second;
95 typename dof_iter_map::iterator di_iter = dof_2_iter.find(this_dof_id);
97 if (di_iter != dof_2_iter.end()) {
98 if (this_dof_id < fei::UNKNOWN) {
99 std::ostringstream osstr;
100 osstr <<
"fei::FieldDofMap::compute_dof_ids ERROR, duplicate field types found (";
101 osstr << this_dof_id <<
" used more than once.)";
102 std::string str = osstr.str();
103 throw std::runtime_error(str);
110 std::pair<LocalOrdinal,LocalOrdinal>& fsize_and_dof = di_iter->second->second;
111 LocalOrdinal fieldSize = fsize_and_dof.first;
112 LocalOrdinal last_dof_id = fsize_and_dof.second;
113 di_iter->second = iter;
114 iter->second.second = last_dof_id + fieldSize;
116 else dof_2_iter.insert(std::make_pair(this_dof_id, iter));
119 m_need_to_compute_dof_ids =
false;