fei_DofMapper.hpp

00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2009 Sandia Corporation.                              */
00003 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00004 /*    non-exclusive license for use of this work by or on behalf      */
00005 /*    of the U.S. Government.  Export of this program may require     */
00006 /*    a license from the United States Government.                    */
00007 /*--------------------------------------------------------------------*/
00008 
00009 #ifndef _fei_DofMapper_hpp_
00010 #define _fei_DofMapper_hpp_
00011 
00012 #include <fei_macros.hpp>
00013 
00014 #include <set>
00015 #include <map>
00016 #include <sstream>
00017 #include <stdexcept>
00018 
00019 #include <fei_Dof.hpp>
00020 
00021 namespace fei {
00022 
00041 template<class LocalOrdinal, class GlobalOrdinal, class DofOrder=less_rank_id_field<LocalOrdinal, GlobalOrdinal> >
00042 class DofMapper {
00043  public:
00045   DofMapper()
00046   : m_dof_idx(), m_idx_dof(), m_maps_are_valid(false), m_field_sizes() {}
00047 
00049   ~DofMapper() {}
00050 
00051   void addDOF(LocalOrdinal rank, GlobalOrdinal id, LocalOrdinal field)
00052   {
00053   if (m_field_sizes.find(field) == m_field_sizes.end()) m_field_sizes.insert(std::make_pair(field,1));
00054     //m_maps_are_valid is false when a new Dof is inserted.
00055     m_maps_are_valid =
00056       m_dof_idx.insert(std::make_pair(Dof<LocalOrdinal,GlobalOrdinal>(rank, id, field), 0)).second;
00057   }
00058 
00063   void setFieldSize(LocalOrdinal field, LocalOrdinal field_size);
00064 
00065   LocalOrdinal getFieldSize(LocalOrdinal field) const;
00066 
00067   GlobalOrdinal getGlobalIndex(LocalOrdinal rank, GlobalOrdinal id, LocalOrdinal field) const;
00068 
00069   std::pair<const Dof<LocalOrdinal,GlobalOrdinal>*,LocalOrdinal> getDof(GlobalOrdinal global_index) const;
00070 
00071   bool maps_are_valid() const { return m_maps_are_valid; }
00072   void set_maps_are_valid(bool flag) { m_maps_are_valid = flag; }
00073 
00074   typedef typename std::map<Dof<LocalOrdinal,GlobalOrdinal>,GlobalOrdinal,DofOrder> DofMap;
00075 
00076   typename DofMap::const_iterator begin_dof() const
00077   { return m_dof_idx.begin(); }
00078 
00079   typename DofMap::const_iterator end_dof() const
00080   { return m_dof_idx.end(); }
00081 
00082   typename DofMap::iterator begin_dof()
00083   { return m_dof_idx.begin(); }
00084 
00085   typename DofMap::iterator end_dof()
00086   { return m_dof_idx.end(); }
00087 
00088   typedef typename std::map<GlobalOrdinal,const Dof<LocalOrdinal,GlobalOrdinal>*> IdxMap;
00089 
00090   typename IdxMap::const_iterator begin_idx() const
00091   { return m_idx_dof.begin(); }
00092 
00093   typename IdxMap::const_iterator end_idx() const
00094   { return m_idx_dof.end(); }
00095 
00096   typename IdxMap::iterator begin_idx()
00097   { return m_idx_dof.begin(); }
00098 
00099   typename IdxMap::iterator end_idx()
00100   { return m_idx_dof.end(); }
00101 
00102   const DofMap& get_dof_idx_map() const {return m_dof_idx;}
00103   DofMap& get_dof_idx_map() {return m_dof_idx;}
00104 
00105   const IdxMap& get_idx_dof_map() const {return m_idx_dof;}
00106   IdxMap& get_idx_dof_map() {return m_idx_dof;}
00107 
00108   typedef typename std::map<LocalOrdinal,LocalOrdinal> FieldSizeMap;
00109   const FieldSizeMap& getFieldSizeMap() const {return m_field_sizes;}
00110 
00111  private:
00112   std::map<Dof<LocalOrdinal, GlobalOrdinal>, GlobalOrdinal, DofOrder > m_dof_idx;
00113 
00114   std::map<GlobalOrdinal, const Dof<LocalOrdinal, GlobalOrdinal>*> m_idx_dof;
00115   bool m_maps_are_valid;
00116 
00117   std::map<LocalOrdinal,LocalOrdinal> m_field_sizes;
00118 
00119   DofMapper(const DofMapper<LocalOrdinal,GlobalOrdinal>& src);
00120   DofMapper& operator=(const DofMapper<LocalOrdinal,GlobalOrdinal>& src);
00121 };//class DofMapper
00122 
00123 template<class LocalOrdinal,class GlobalOrdinal,class DofOrder>
00124 void DofMapper<LocalOrdinal,GlobalOrdinal,DofOrder>::setFieldSize(LocalOrdinal field, LocalOrdinal field_size)
00125 {
00126   typename FieldSizeMap::iterator f_iter = m_field_sizes.find(field);
00127   if (f_iter == m_field_sizes.end()) {
00128     m_field_sizes.insert(std::make_pair(field, field_size));
00129   }
00130   else {
00131     //field already present, resetting field_size:
00132     f_iter->second = field_size;
00133   }
00134 }
00135 
00136 template<class LocalOrdinal,class GlobalOrdinal,class DofOrder>
00137 LocalOrdinal DofMapper<LocalOrdinal,GlobalOrdinal,DofOrder>::getFieldSize(LocalOrdinal field) const
00138 {
00139   typename FieldSizeMap::const_iterator f_iter = m_field_sizes.find(field);
00140   if (f_iter == m_field_sizes.end()) {
00141     std::ostringstream os;
00142     os << "fei::DofMapper::getFieldSize ERROR, field=="
00143       << field << " not found";
00144     std::string str = os.str();
00145     throw std::runtime_error(str);
00146   }
00147   return f_iter->second;
00148 }
00149 
00150 template<class LocalOrdinal,class GlobalOrdinal,class DofOrder>
00151 GlobalOrdinal DofMapper<LocalOrdinal,GlobalOrdinal,DofOrder>::getGlobalIndex(LocalOrdinal rank, GlobalOrdinal id, LocalOrdinal field) const
00152 {
00153   typename DofMap::const_iterator iter = m_dof_idx.find(Dof<LocalOrdinal,GlobalOrdinal>(rank,id,field));
00154   if (iter == m_dof_idx.end()) {
00155     std::ostringstream osstr;
00156     osstr << "fei::DofMapper::getGlobalIndex ERROR, dof("
00157         << rank << "," << id << "," << field << ") not found.";
00158     std::string str = osstr.str();
00159     throw std::runtime_error(str);
00160   }
00161 
00162   return iter->second;
00163 }
00164 
00165 template<class LocalOrdinal,class GlobalOrdinal,class DofOrder>
00166 std::pair<const Dof<LocalOrdinal,GlobalOrdinal>*,LocalOrdinal>
00167 DofMapper<LocalOrdinal,GlobalOrdinal,DofOrder>::getDof(GlobalOrdinal global_index) const
00168 {
00169   typename IdxMap::const_iterator iter = m_idx_dof.lower_bound(global_index);
00170   if (iter == m_idx_dof.begin()) {
00171   if (iter->first == global_index) {
00172     return std::make_pair(iter->second, global_index);
00173   }
00174   else {
00175       std::ostringstream osstr;
00176       osstr << "fei::DofMapper::getDof ERROR, dof not found for global_index=="
00177         << global_index;
00178       std::string str = osstr.str();
00179       throw std::runtime_error(str);
00180   }
00181   }
00182   else if (iter != m_idx_dof.end() && iter->first == global_index) {
00183     //return pair(dof,component-of-field)
00184   return std::make_pair(iter->second, 0);
00185   }
00186 
00187   bool last_dof = iter == m_idx_dof.end();
00188   --iter;
00189   //return pair(dof,component-of-field)
00190   LocalOrdinal component = global_index - iter->first;
00191   bool check_range_of_component = last_dof && !m_field_sizes.empty();
00192   if (check_range_of_component) {
00193   typename std::map<LocalOrdinal,LocalOrdinal>::const_iterator f_iter = m_field_sizes.find(iter->second->field());
00194   if (f_iter == m_field_sizes.end() || f_iter->second <= component) {
00195     std::ostringstream os;
00196     os << "fei::DofMapper::getDof ERROR2, dof not found for global_index=="
00197       << global_index;
00198     std::string str = os.str();
00199     throw std::runtime_error(str);
00200   }
00201   }
00202 
00203   return std::make_pair(iter->second, component);
00204 }
00205 
00206 }//namespace fei
00207 
00208 #endif
00209 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends
Generated on Wed Apr 13 10:08:23 2011 for FEI by  doxygen 1.6.3