[MOAB-dev] r2051 - MOAB/trunk/refiner

dcthomp at mcs.anl.gov dcthomp at mcs.anl.gov
Thu Aug 28 22:21:07 CDT 2008


Author: dcthomp
Date: 2008-08-28 22:21:07 -0500 (Thu, 28 Aug 2008)
New Revision: 2051

Modified:
   MOAB/trunk/refiner/MBMeshOutputFunctor.cpp
   MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
   MOAB/trunk/refiner/MBRefinerTagManager.cpp
   MOAB/trunk/refiner/MBSplitVertices.cpp
   MOAB/trunk/refiner/MBSplitVertices.hpp
Log:
BUG: Global IDs were being assigned to elements out-of-order across
     processes because their corner vertex IDs aren't assigned at
     the time they were being sorted. Delay sorting until later.


Modified: MOAB/trunk/refiner/MBMeshOutputFunctor.cpp
===================================================================
--- MOAB/trunk/refiner/MBMeshOutputFunctor.cpp	2008-08-28 19:13:05 UTC (rev 2050)
+++ MOAB/trunk/refiner/MBMeshOutputFunctor.cpp	2008-08-29 03:21:07 UTC (rev 2051)
@@ -17,6 +17,10 @@
   this->tag_manager = tag_mgr;
   this->destination_set = 0; // don't place output entities in a set by default.
 
+  // When the input mesh and the output mesh are different, this map serves
+  // as a dictionary from input vertices to output vertices.
+  this->vertex_map = new MBSplitVertices<1>( this->tag_manager );
+
   // Hold information about newly-created vertices on subdivided edges and faces.
   this->split_vertices.resize( 4 );
   this->split_vertices[0] = 0; // Vertices (0-faces) cannot be split
@@ -27,15 +31,16 @@
   // Hold information about newly-created mesh entities (other than split vertices)
   // This is necessary in order for global IDs to be assigned consistently across processes.
   this->new_entities.resize( 5 );
-  this->new_entities[0] = new MBSplitVertices<0>( this->tag_manager );
-  this->new_entities[1] = new MBSplitVertices<1>( this->tag_manager );
-  this->new_entities[2] = new MBSplitVertices<2>( this->tag_manager );
-  this->new_entities[3] = new MBSplitVertices<3>( this->tag_manager );
-  this->new_entities[4] = new MBSplitVertices<4>( this->tag_manager );
+  this->new_entities[0] = new MBEntitySource( 1, this->tag_manager );
+  this->new_entities[1] = new MBEntitySource( 2, this->tag_manager );
+  this->new_entities[2] = new MBEntitySource( 3, this->tag_manager );
+  this->new_entities[3] = new MBEntitySource( 4, this->tag_manager );
+  this->new_entities[4] = new MBEntitySource( 5, this->tag_manager );
 }
 
 MBMeshOutputFunctor::~MBMeshOutputFunctor()
 {
+  delete this->vertex_map;
   for ( int i = 1; i < 4; ++ i )
     delete this->split_vertices[i];
   for ( int i = 0; i < 5; ++ i )
@@ -156,10 +161,11 @@
     {
     (*vit)->assign_global_ids( gids );
     }
-  for ( vit = this->new_entities.begin(); vit != this->new_entities.end(); ++ vit )
+  std::vector<MBEntitySource*>::iterator sit;
+  for ( sit = this->new_entities.begin(); sit != this->new_entities.end(); ++ sit )
     {
-    if ( *vit )
-      (*vit)->assign_global_ids( gids );
+    if ( *sit )
+      (*sit)->assign_global_ids( gids );
     }
 }
 
@@ -190,7 +196,7 @@
     return vhash;
     }
   MBEntityHandle vertex_handle;
-  bool newly_created = this->new_entities[1]->find_or_create(
+  bool newly_created = this->vertex_map->find_or_create(
     &vhash, vcoords, vertex_handle, this->proc_partition_counts, false );
   if ( newly_created )
     {
@@ -206,6 +212,7 @@
     std::cerr << "Could not insert vertex into new mesh!\n";
     }
   this->print_vert_crud( vertex_handle, 1, &vhash, vcoords, vtags );
+  std::cout << "\nMap vert: " << vhash << " to: " << vertex_handle << "\n";
   return vertex_handle;
 }
 

Modified: MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
===================================================================
--- MOAB/trunk/refiner/MBMeshOutputFunctor.hpp	2008-08-28 19:13:05 UTC (rev 2050)
+++ MOAB/trunk/refiner/MBMeshOutputFunctor.hpp	2008-08-29 03:21:07 UTC (rev 2051)
@@ -38,6 +38,7 @@
 #include <string.h>
 
 class MBSplitVerticesBase;
+class MBEntitySource;
 class MBParallelComm;
 
 class MBMeshOutputFunctor : public MBEntityRefinerOutputFunctor
@@ -60,8 +61,9 @@
   MBInterface* mesh_in;
   MBInterface* mesh_out;
   bool input_is_output;
+  MBSplitVerticesBase* vertex_map;
   std::vector<MBSplitVerticesBase*> split_vertices;
-  std::vector<MBSplitVerticesBase*> new_entities;
+  std::vector<MBEntitySource*> new_entities;
   std::vector<MBEntityHandle> elem_vert;
   MBRefinerTagManager* tag_manager;
   MBEntityHandle destination_set;

Modified: MOAB/trunk/refiner/MBRefinerTagManager.cpp
===================================================================
--- MOAB/trunk/refiner/MBRefinerTagManager.cpp	2008-08-28 19:13:05 UTC (rev 2050)
+++ MOAB/trunk/refiner/MBRefinerTagManager.cpp	2008-08-29 03:21:07 UTC (rev 2051)
@@ -451,7 +451,8 @@
       }
     else
       {
-      //std::cout << " not shared | ";
+      // not shared, but everthing exists on this process, so make sure that bit is set...
+      common_shared_procs.set_process_member( this->rank );
       }
     }
   std::cout << "    Common procs " << common_shared_procs;

Modified: MOAB/trunk/refiner/MBSplitVertices.cpp
===================================================================
--- MOAB/trunk/refiner/MBSplitVertices.cpp	2008-08-28 19:13:05 UTC (rev 2050)
+++ MOAB/trunk/refiner/MBSplitVertices.cpp	2008-08-29 03:21:07 UTC (rev 2051)
@@ -13,3 +13,53 @@
 {
 }
 
+MBEntitySource::MBEntitySource( int nc, MBRefinerTagManager* tag_mgr )
+{
+  this->tag_manager = tag_mgr;
+  this->mesh_out = tag_mgr->get_output_mesh();
+  this->num_corners = nc;
+}
+
+MBEntitySource::~MBEntitySource()
+{
+}
+
+bool MBEntitySource::create_element(
+  MBEntityType etyp, int nconn, const MBEntityHandle* elem_verts, MBEntityHandle& elem_handle,
+  std::map<MBProcessSet,int>& proc_partition_counts )
+{
+  // Get the global IDs of the input vertices
+  int stat;
+  proc_partition_counts[this->tag_manager->get_element_procs()]++;
+  if ( this->mesh_out->create_element( etyp, elem_verts, nconn, elem_handle ) != MB_SUCCESS )
+    {
+    return false;
+    }
+  this->push_back( MBEntitySourceRecord( this->num_corners, elem_handle, this->tag_manager->get_element_procs() ) );
+  this->tag_manager->set_sharing( elem_handle, this->tag_manager->get_element_procs() );
+  return true;
+}
+
+void MBEntitySource::assign_global_ids( std::map<MBProcessSet,int>& gids )
+{
+  std::vector<MBEntityHandle> adjacencies;
+  adjacencies.resize( this->num_corners );
+  std::vector<MBEntitySourceRecord>::iterator it;
+  int stat;
+  for ( it = this->begin(); it != this->end(); ++ it )
+    {
+    int num_nodes;
+    const MBEntityHandle* conn;
+    this->mesh_out->get_connectivity( it->handle, conn, num_nodes );
+    stat = this->tag_manager->get_output_gids( this->num_corners, conn, it->ids );
+    std::sort( it->ids.begin(), it->ids.end() );
+    }
+  std::sort( this->begin(), this->end() );
+  for ( it = this->begin(); it != this->end(); ++ it )
+    {
+    int gid = gids[it->process_set] ++;
+    this->tag_manager->set_gid( it->handle, gid );
+    std::cout << "Assigning entity: " << it->handle << " GID: " << gid << "\n";
+    }
+}
+

Modified: MOAB/trunk/refiner/MBSplitVertices.hpp
===================================================================
--- MOAB/trunk/refiner/MBSplitVertices.hpp	2008-08-28 19:13:05 UTC (rev 2050)
+++ MOAB/trunk/refiner/MBSplitVertices.hpp	2008-08-29 03:21:07 UTC (rev 2051)
@@ -16,7 +16,7 @@
 /**\class MBSplitVertices
   *\brief A dictionary of new vertices.
   *
-  * An array of existing vertex handles used as a key in a dictionary of new vertices.
+  * An array of existing vertex ids used as a key in a dictionary of new vertices.
   */
 #ifndef MB_SPLITVERTICES_HPP
 #define MB_SPLITVERTICES_HPP
@@ -37,11 +37,11 @@
 public:
   MBSplitVertexIndex() { }
   MBSplitVertexIndex( const int* src )
-    { for ( int i = 0; i < _n; ++ i ) this->handles[i] = src[i]; std::sort( this->handles, this->handles + _n ); }
+    { for ( int i = 0; i < _n; ++ i ) this->ids[i] = src[i]; std::sort( this->ids, this->ids + _n ); }
   MBSplitVertexIndex( const MBSplitVertexIndex<_n>& src )
-    { for ( int i = 0; i < _n; ++ i ) this->handles[i] = src.handles[i]; this->process_set = src.process_set; }
+    { for ( int i = 0; i < _n; ++ i ) this->ids[i] = src.ids[i]; this->process_set = src.process_set; }
   MBSplitVertexIndex& operator = ( const MBSplitVertexIndex<_n>& src )
-    { for ( int i = 0; i < _n; ++ i ) this->handles[i] = src.handles[i]; this->process_set = src.process_set; return *this; }
+    { for ( int i = 0; i < _n; ++ i ) this->ids[i] = src.ids[i]; this->process_set = src.process_set; return *this; }
 
   void set_common_processes( const MBProcessSet& procs )
     { this->process_set = procs; }
@@ -52,16 +52,16 @@
 
   bool operator < ( const MBSplitVertexIndex<_n>& other ) const
     {
-    // Ignore the process set. Only program errors lead to mismatched process sets with identical handles.
+    // Ignore the process set. Only program errors lead to mismatched process sets with identical ids.
     for ( int i = 0; i < _n; ++ i )
-      if ( this->handles[i] < other.handles[i] )
+      if ( this->ids[i] < other.ids[i] )
         return true;
-      else if ( this->handles[i] > other.handles[i] )
+      else if ( this->ids[i] > other.ids[i] )
         return false;
     return false;
     }
 
-  int handles[_n + 1];
+  int ids[_n + 1];
   MBProcessSet process_set;
 };
 
@@ -70,13 +70,51 @@
 {
   for ( int i = 0; i < _n; ++ i )
     {
-    os << idx.handles[i] << " ";
+    os << idx.ids[i] << " ";
     }
   os << "(" << idx.process_set << ")";
   return os;
 }
 
-/** A non-templated base class that the template subclasses all share.
+class MBEntitySourceRecord
+{
+public:
+  MBEntitySourceRecord() { }
+  MBEntitySourceRecord( int nc, MBEntityHandle ent, const MBProcessSet& procs )
+    { this->ids.resize( nc ); this->handle = ent; this->process_set = procs; }
+  MBEntitySourceRecord( const MBEntitySourceRecord& src )
+    { this->handle = src.handle; this->process_set = src.process_set; this->ids = src.ids; }
+  MBEntitySourceRecord& operator = ( const MBEntitySourceRecord& src )
+    { this->handle = src.handle; this->process_set = src.process_set; this->ids = src.ids; return *this; }
+
+  void set_common_processes( const MBProcessSet& procs )
+    { this->process_set = procs; }
+  MBProcessSet& common_processes()
+    { return this->process_set; }
+  const MBProcessSet& common_processes() const
+    { return this->process_set; }
+
+  bool operator < ( const MBEntitySourceRecord& other ) const
+    {
+    //assert( this->ids.size() == other.ids.size() );
+    std::vector<int>::size_type N = this->ids.size();
+    std::vector<int>::size_type i;
+    // Ignore the process set. Only program errors lead to mismatched process sets with identical ids.
+    for ( i = 0; i < N; ++ i )
+      if ( this->ids[i] < other.ids[i] )
+        return true;
+      else if ( this->ids[i] > other.ids[i] )
+        return false;
+    return false;
+    }
+
+  std::vector<int> ids;
+  MBProcessSet process_set;
+  MBEntityHandle handle;
+};
+
+
+/** A non-templated base class that the MBSplitVertices template subclasses all share.
   *
   * All methods that need to be accessed by other classes should be
   * declared by the base class so that no knowledge of template parameters
@@ -92,10 +130,6 @@
     const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
     std::map<MBProcessSet,int>& proc_partition_counts, bool handles_on_output_mesh ) = 0;
 
-  virtual bool create_element(
-    MBEntityType etyp, int nconn, const MBEntityHandle* elem_verts, MBEntityHandle& elem_handle,
-    std::map<MBProcessSet,int>& proc_partition_counts ) = 0;
-
   virtual void assign_global_ids( std::map<MBProcessSet,int>& gids ) = 0;
 
   MBInterface* mesh_out; // Output mesh. Needed for new vertex set in vert_handle
@@ -104,12 +138,39 @@
   MBProcessSet common_shared_procs; // Holds intersection of several shared_procs_ins.
 };
 
-/** A map from a set of pre-existing entities to a new mesh entity.
+/** A vector of pre-existing entities to a new mesh entity.
   *
   * This is used as a dictionary to determine whether a new vertex should be
   * created on the given n-simplex (n being the template parameter) or whether
   * it has already been created as part of the refinement of a neighboring entity.
   */
+class MBEntitySource : public std::vector<MBEntitySourceRecord>
+{
+public:
+  typedef std::vector<MBEntitySourceRecord> VecType;
+  typedef std::vector<MBEntitySourceRecord>::iterator VecIteratorType;
+
+  MBEntitySource( int num_corners, MBRefinerTagManager* tag_mgr );
+  ~MBEntitySource();
+  bool create_element(
+    MBEntityType etyp, int nconn, const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
+    std::map<MBProcessSet,int>& proc_partition_counts );
+
+  void assign_global_ids( std::map<MBProcessSet,int>& gids );
+
+  MBInterface* mesh_out; // Output mesh. Needed for new vertex set in vert_handle
+  MBRefinerTagManager* tag_manager;
+  MBProcessSet common_shared_procs; // Holds intersection of several shared_procs_ins.
+  int num_corners;
+};
+
+
+/** A map from a set of pre-existing vertices to a new mesh vertex.
+  *
+  * This is used as a dictionary to determine whether a new vertex should be
+  * created on the given n-simplex (n being the template parameter) or whether
+  * it has already been created as part of the refinement of a neighboring entity.
+  */
 template< int _n >
 class MBSplitVertices : public std::map<MBSplitVertexIndex<_n>,MBEntityHandle>, public MBSplitVerticesBase
 {
@@ -122,9 +183,6 @@
   virtual bool find_or_create(
     const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
     std::map<MBProcessSet,int>& proc_partition_counts, bool handles_on_output_mesh );
-  virtual bool create_element(
-    MBEntityType etyp, int nconn, const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
-    std::map<MBProcessSet,int>& proc_partition_counts );
 
   virtual void assign_global_ids( std::map<MBProcessSet,int>& gids );
 };
@@ -178,27 +236,6 @@
 }
 
 template< int _n >
-bool MBSplitVertices<_n>::create_element(
-  MBEntityType etyp, int nconn, const MBEntityHandle* elem_verts, MBEntityHandle& elem_handle,
-  std::map<MBProcessSet,int>& proc_partition_counts )
-{
-  // Get the global IDs of the input vertices
-  int stat;
-  stat = this->tag_manager->get_input_gids( _n, elem_verts, this->split_gids );
-  MBSplitVertexIndex<_n> key( &this->split_gids[0] );
-  //this->tag_manager->get_common_processes( _n, elem_verts, this->common_shared_procs );
-  proc_partition_counts[this->tag_manager->get_element_procs()]++;
-  key.set_common_processes( this->tag_manager->get_element_procs() );
-  if ( this->mesh_out->create_element( etyp, elem_verts, nconn, elem_handle ) != MB_SUCCESS )
-    {
-    return false;
-    }
-  (*this)[key] = elem_handle;
-  this->tag_manager->set_sharing( elem_handle, this->tag_manager->get_element_procs() );
-  return true;
-}
-
-template< int _n >
 void MBSplitVertices<_n>::assign_global_ids( std::map<MBProcessSet,int>& gids )
 {
   typename std::map<MBSplitVertexIndex<_n>,MBEntityHandle>::iterator it;




More information about the moab-dev mailing list