[MOAB-dev] r1626 - MOAB/trunk

tautges at mcs.anl.gov tautges at mcs.anl.gov
Fri Feb 29 12:46:33 CST 2008


Author: tautges
Date: 2008-02-29 12:46:32 -0600 (Fri, 29 Feb 2008)
New Revision: 1626

Added:
   MOAB/trunk/RangeMap.hpp
Modified:
   MOAB/trunk/MBRange.cpp
   MOAB/trunk/MBRange.hpp
   MOAB/trunk/Makefile.am
   MOAB/trunk/mbparallelcomm_test.cpp
Log:
Changed parallel communication to not require that entities be restored remotely with the same handles as the sending proc.  Adding RangeMap (from Jason) for mapping between ranges of handles.


Modified: MOAB/trunk/MBRange.cpp
===================================================================
--- MOAB/trunk/MBRange.cpp	2008-02-28 20:25:04 UTC (rev 1625)
+++ MOAB/trunk/MBRange.cpp	2008-02-29 18:46:32 UTC (rev 1626)
@@ -819,11 +819,19 @@
 
 }
 
-MBEntityHandle MBRange::operator[](MBEntityID index) const
+int MBRange::index(MBEntityHandle handle) const 
 {
-  MBRange::const_iterator i = begin();
-  i += index;
-  return *i;
+  if (handle < *begin() || handle > *rbegin()) return -1;
+  
+  unsigned int i = 0;
+  MBRange::const_pair_iterator pit = const_pair_begin(); 
+  while (handle > (*pit).second && pit != const_pair_end()) {
+    i += (*pit).second - (*pit).first + 1;
+    pit++;
+  }
+  if (handle < (*pit).first || pit == const_pair_end()) return -1;
+  
+  return i + handle - (*pit).first;
 }
 
     //! return a subset of this range, by type

Modified: MOAB/trunk/MBRange.hpp
===================================================================
--- MOAB/trunk/MBRange.hpp	2008-02-28 20:25:04 UTC (rev 1625)
+++ MOAB/trunk/MBRange.hpp	2008-02-29 18:46:32 UTC (rev 1626)
@@ -330,6 +330,8 @@
 
   
   MBEntityHandle operator[](MBEntityID index) const;
+
+  int index(MBEntityHandle handle) const;
   
   MBRange::iterator insert( MBRange::iterator prev,
                             MBEntityHandle first,
@@ -750,6 +752,13 @@
 inline bool operator!=( const MBRange& r1, const MBRange& r2 )
   { return !(r1 == r2); }
 
+inline MBEntityHandle MBRange::operator[](MBEntityID index) const
+{
+  MBRange::const_iterator i = begin();
+  i += index;
+  return *i;
+}
+
 #endif // MB_RANGE_HPP
 
 

Modified: MOAB/trunk/Makefile.am
===================================================================
--- MOAB/trunk/Makefile.am	2008-02-28 20:25:04 UTC (rev 1625)
+++ MOAB/trunk/Makefile.am	2008-02-29 18:46:32 UTC (rev 1626)
@@ -148,6 +148,7 @@
   MeshTopoUtil.cpp \
   PolyElementSeq.cpp \
   PolyElementSeq.hpp \
+  RangeMap.hpp \
   ReadGmsh.cpp \
   ReadGmsh.hpp \
   ReadSTL.cpp \

Copied: MOAB/trunk/RangeMap.hpp (from rev 1624, MOAB/branches/range_map/RangeMap.hpp)
===================================================================
--- MOAB/trunk/RangeMap.hpp	                        (rev 0)
+++ MOAB/trunk/RangeMap.hpp	2008-02-29 18:46:32 UTC (rev 1626)
@@ -0,0 +1,199 @@
+/*
+ * MOAB, a Mesh-Oriented datABase, is a software component for creating,
+ * storing and accessing finite element mesh data.
+ * 
+ * Copyright 2004 Sandia Corporation.  Under the terms of Contract
+ * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
+ * retains certain rights in this software.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ */
+
+/**\file RangeMap.hpp
+ *\author Jason Kraftcheck (kraftche at cae.wisc.edu)
+ *\date 2007-04-25
+ */
+
+#ifndef RANGE_MAP_HPP
+#define RANGE_MAP_HPP
+
+#include <vector>
+#include <algorithm>
+
+/**\brief Map ranges of values 
+ *
+ * This class provides a map between ranges of values, such as
+ * a map between file IDs and MBEntityHandles.  It is intended
+ * for use in situations where there are relatively few insertions
+ * of large contiguous ranges of values.
+ */
+template <typename KeyType, typename ValType, ValType NullVal>
+class RangeMap 
+{
+public:
+  struct Range {
+    KeyType begin, count;
+    ValType value;
+    bool operator<( const Range& other ) const
+      { return begin + count <= other.begin; } // equal if overlapping!
+  };
+  typedef typename std::vector<Range> RangeList;
+  typedef typename RangeList::const_iterator iterator;
+  
+  /**\brief Insert mapping between range of keys and range of values
+   * 
+   * Insert mapping from [first_key, first_key+count) to [first_val, first_val+count) 
+   *
+   * Input range of keys many not overlap any other input range.  If it does overlap
+   * an existing range, false is returned and the internal map is not changed.
+   */
+  inline iterator insert( KeyType first_key, ValType first_val, KeyType count );
+  
+  /** Find the value corresponding to the specified key.  Returns NullVal if not found */
+  inline ValType find( KeyType key ) const;
+
+  /** Remove a block of values */
+  inline iterator erase( KeyType beg, KeyType count );
+
+  inline unsigned num_ranges() const { return data.size(); }
+  
+  inline iterator begin() const { return data.begin(); }
+  inline iterator end() const { return data.end(); }
+  inline iterator lower_bound( KeyType key ) const 
+    { 
+      Range b = { key, 1, NullVal }; 
+      return std::lower_bound( begin(), end(), b );
+    }
+  inline iterator upper_bound( KeyType key ) const
+    { 
+      Range b = { key, 1, NullVal }; 
+      return std::upper_bound( begin(), end(), b );
+    }
+  inline std::pair<iterator,iterator>
+    equal_range( KeyType key ) const
+    { 
+      Range b = { key, 1, NullVal }; 
+      return std::equal_range( begin(), end(), b );
+    }
+    
+  inline void clear() { data.clear(); }
+
+protected:
+  RangeList data;
+};
+
+template <typename KeyType, typename ValType, ValType NullVal> 
+inline typename RangeMap<KeyType,ValType,NullVal>::iterator
+RangeMap<KeyType,ValType,NullVal>::insert( KeyType first_key, ValType first_val, KeyType count )
+{
+  Range block = { first_key, count, first_val };
+  typename RangeList::iterator i = std::lower_bound( data.begin(), data.end(), block );
+  
+  if (i == data.end()) {
+    if (i != data.begin()) {
+      --i;
+      if (i->begin + i->count == first_key && 
+          i->value + i->count == first_val) {
+        i->count += count;
+        return i;
+      }
+    }
+    data.push_back( block );
+    return data.end() - 1;
+  }
+  
+  if (i->begin < first_key + count)
+    return data.end();
+  
+  if (i->begin == first_key + count &&
+      i->value == first_val + count) {
+    i->begin = first_key;
+    i->value = first_val;
+    i->count += count;
+    if (i != data.begin()) {
+      count = i->count;
+      --i;
+      if (i->begin + i->count == first_key &&
+          i->value + i->count == first_val) {
+        i->count += count;
+        ++i;
+        i = data.erase(i);
+        --i;
+      }
+    }
+    return i;
+  }
+  
+  if (i != data.begin()) {
+    --i;
+    if (i->begin + i->count == first_key &&
+        i->value + i->count == first_val) {
+      i->count += count;
+      return i;
+    }
+    ++i;
+  }
+  
+  return data.insert( i, block );
+}
+
+
+
+template <typename KeyType, typename ValType, ValType NullVal> inline
+ValType RangeMap<KeyType,ValType,NullVal>::find( KeyType key ) const
+{
+  Range search = { key, 1, NullVal };
+  typename RangeList::const_iterator i = std::lower_bound( data.begin(), data.end(), search );
+  if (i == data.end() || i->begin > key)
+    return NullVal;
+  
+  return i->value + key - i->begin;
+}
+
+template <typename KeyType, typename ValType, ValType NullVal>
+inline typename RangeMap<KeyType,ValType,NullVal>::iterator
+RangeMap<KeyType,ValType,NullVal>::erase( KeyType key, KeyType count )
+{
+  Range search = { key, 1, NullVal };
+  typename RangeList::iterator i, j;
+  i = std::lower_bound( data.begin(), data.end(), search );
+  
+  if (i == data.end())
+    return i;
+  
+  if (key > i->begin) {
+    KeyType offset = key - i->begin;
+      // special case - split existing entry
+    if((offset + count) < i->count) {
+      Range ins = { i->begin, offset, i->value };
+      offset += count;
+      i->begin += offset;
+      i->value += offset;
+      i->count -= offset;
+      return data.insert( i, ins ) + 1;
+    }
+      // otherwise remove the latter part of i
+    i->count = offset;
+    ++i;
+  }
+  
+    // remove any entries entirely convered by the input range
+  for (j = i; j != data.end() && (j->begin + j->count) <= (key + count); ++j);
+  i = data.erase(i,j);
+  
+    // remove beginning of last block
+  if (i != data.end() && (key + count) >= i->begin) {
+    KeyType offset = key + count - i->begin;
+    i->begin += offset;
+    i->value += offset;
+    i->count -= offset;
+  }
+  
+  return i;
+}
+
+#endif

Modified: MOAB/trunk/mbparallelcomm_test.cpp
===================================================================
--- MOAB/trunk/mbparallelcomm_test.cpp	2008-02-28 20:25:04 UTC (rev 1625)
+++ MOAB/trunk/mbparallelcomm_test.cpp	2008-02-29 18:46:32 UTC (rev 1626)
@@ -74,7 +74,7 @@
         << "===   =====" << std::endl
         << " 1     <linear_ints> <shared_verts> " << std::endl
         << " 2     <n_ints> " << std::endl
-        << " 3*    <file_name> [<tag_name>=\"MATERIAL_SET\" [tag_val] [distribute=true] ]" << std::endl
+        << " 3*    <file_name> [<tag_name>=\"MATERIAL_SET\" [tag_val] [distribute=1] ]" << std::endl
         << "*Note: if opt 3 is used, it must be the last one." << std::endl;
     
     err = MPI_Finalize();




More information about the moab-dev mailing list