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

dcthomp at mcs.anl.gov dcthomp at mcs.anl.gov
Thu Jul 24 23:14:30 CDT 2008


Author: dcthomp
Date: 2008-07-24 23:14:30 -0500 (Thu, 24 Jul 2008)
New Revision: 2024

Modified:
   MOAB/trunk/refiner/MBMeshOutputFunctor.cpp
   MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
   MOAB/trunk/refiner/MBProcessSet.cpp
   MOAB/trunk/refiner/MBProcessSet.hpp
   MOAB/trunk/refiner/MBRefinerTagManager.hpp
   MOAB/trunk/refiner/MBSplitVertices.cpp
   MOAB/trunk/refiner/MBSplitVertices.hpp
   MOAB/trunk/refiner/test_mesh_refiner.cpp
Log:
ENH: The tet refiner now sets the global IDs of newly-created
     vertices properly. It also sets the PARALLEL_SHARED_PROC(S)
     and PARALLEL_STATUS tag values properly, although the way
     this is accomplished may change in the future.


Modified: MOAB/trunk/refiner/MBMeshOutputFunctor.cpp
===================================================================
--- MOAB/trunk/refiner/MBMeshOutputFunctor.cpp	2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBMeshOutputFunctor.cpp	2008-07-25 04:14:30 UTC (rev 2024)
@@ -17,17 +17,28 @@
   this->tag_manager = tag_mgr;
   this->destination_set = 0; // don't place output entities in a set by default.
 
+  // 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
   this->split_vertices[1] = new MBSplitVertices<1>( this->tag_manager );
   this->split_vertices[2] = new MBSplitVertices<2>( this->tag_manager );
   this->split_vertices[3] = new MBSplitVertices<3>( this->tag_manager );
+
+  // 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( 4 );
+  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 );
 }
 
 MBMeshOutputFunctor::~MBMeshOutputFunctor()
 {
   for ( int i = 0; i < 4; ++ i )
     delete this->split_vertices[i];
+  for ( int i = 0; i < 4; ++ i )
+    delete this->new_entities[i];
 }
 
 void MBMeshOutputFunctor::print_vert_crud( MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags )
@@ -123,21 +134,26 @@
       this->proc_partition_counts[pset] = part_sizes[i];
       }
     }
-  std::map<MBProcessSet,MBEntityHandle> gids;
+  std::map<MBProcessSet,int> gids;
   std::map<MBProcessSet,int>::iterator pcit;
   MBEntityHandle start_gid = 100; // FIXME: Get actual maximum GID across all processes and add 1
   for ( pcit = this->proc_partition_counts.begin(); pcit != this->proc_partition_counts.end(); ++ pcit )
     {
     gids[pcit->first] = start_gid;
     start_gid += pcit->second;
-    std::cout << "Partition " << pcit->first << ": " << pcit->second << " #\n";
+    std::cout << "Partition " << pcit->first << ": " << pcit->second << " # [" << gids[pcit->first] << "]\n";
     }
-  std::vector<MBSplitVerticesBase*>::iterator splitit;
-  for ( splitit = this->split_vertices.begin(); splitit != this->split_vertices.end(); ++ splitit )
+  std::vector<MBSplitVerticesBase*>::iterator vit;
+  for ( vit = this->split_vertices.begin(); vit != this->split_vertices.end(); ++ vit )
     {
-    if ( *splitit )
-      (*splitit)->assign_global_ids( gids );
+    if ( *vit )
+      (*vit)->assign_global_ids( gids );
     }
+  for ( vit = this->new_entities.begin(); vit != this->new_entities.end(); ++ vit )
+    {
+    if ( *vit )
+      (*vit)->assign_global_ids( gids );
+    }
 }
 
 void MBMeshOutputFunctor::assign_tags( MBEntityHandle vhandle, const void* vtags )
@@ -163,11 +179,16 @@
     return vhash;
     }
   MBEntityHandle vertex_handle;
-  if ( this->mesh_out->create_vertex( vcoords + 3, vertex_handle ) != MB_SUCCESS )
+  bool newly_created = this->new_entities[0]->find_or_create(
+    &vhash, vcoords, vertex_handle, this->proc_partition_counts );
+  if ( newly_created )
     {
-    std::cerr << "Could not insert mid-edge vertex!\n";
+    this->assign_tags( vertex_handle, vtags );
     }
-  this->assign_tags( vertex_handle, vtags );
+  if ( ! vertex_handle )
+    {
+    std::cerr << "Could not insert vertex into new mesh!\n";
+    }
   this->print_vert_crud( vertex_handle, 1, &vhash, vcoords, vtags );
   return vertex_handle;
 }
@@ -205,16 +226,30 @@
 {
   std::cout << h << " ";
   this->elem_vert.push_back( h );
+  if ( ! this->input_is_output )
+    {
+    // FIXME: Copy to output mesh
+    }
 }
 
 void MBMeshOutputFunctor::operator () ( MBEntityType etyp )
 {
   MBEntityHandle elem_handle;
-  if ( this->mesh_out->create_element( etyp, &this->elem_vert[0], this->elem_vert.size(), elem_handle ) == MB_FAILURE )
+  int nconn = this->elem_vert.size();
+  if ( this->mesh_out->create_element( etyp, &this->elem_vert[0], nconn, elem_handle ) == MB_FAILURE )
     {
     std::cerr << " *** ";
     }
+  std::cout << "---------> " << elem_handle << " ( " << etyp << " )\n\n";
+#if 0
+  bool newly_created = this->new_entities[nconn]->create_element(
+    &this->elem_vert[0], elem_handle, this->proc_partition_counts );
+  if ( newly_created )
+    {
+    // FIXME: Handle tag assignment for elements as well as vertices
+    //this->assign_tags( elem_handle, this->element_tag_data );
+    }
+#endif // 0
   this->elem_vert.clear();
-  std::cout << "---------> " << elem_handle << " ( " << etyp << " )\n\n";
 }
 

Modified: MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
===================================================================
--- MOAB/trunk/refiner/MBMeshOutputFunctor.hpp	2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBMeshOutputFunctor.hpp	2008-07-25 04:14:30 UTC (rev 2024)
@@ -33,6 +33,7 @@
   MBInterface* mesh_out;
   bool input_is_output;
   std::vector<MBSplitVerticesBase*> split_vertices;
+  std::vector<MBSplitVerticesBase*> new_entities;
   std::vector<MBEntityHandle> elem_vert;
   MBRefinerTagManager* tag_manager;
   MBEntityHandle destination_set;

Modified: MOAB/trunk/refiner/MBProcessSet.cpp
===================================================================
--- MOAB/trunk/refiner/MBProcessSet.cpp	2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBProcessSet.cpp	2008-07-25 04:14:30 UTC (rev 2024)
@@ -1,5 +1,7 @@
 #include "MBProcessSet.hpp"
 
+#include <assert.h>
+
 MBProcessSet::MBProcessSet()
 {
   this->clear();
@@ -51,6 +53,40 @@
     }
 }
 
+/**\brief Retrieve a vector containing processes in this set.
+  *
+  * @param [in] rank The rank of the local process. This integer will not be included in the output list.
+  * @param [out] procs The vector in which the list of sharing processes is listed.
+  * @return   True when \a rank is the owning process and false otherwise.
+  */
+bool MBProcessSet::get_process_members( int rank, std::vector<int>& procs )
+{
+  int i = 0;
+  assert( rank >= 0 );
+  procs.clear();
+  bool rank_owner = false;
+  for ( int byte = 0; byte < SHARED_PROC_BYTES; ++ byte )
+    {
+    char val = this->processes[byte];
+    for ( int bit = 0; val && ( bit < 8 ); ++ bit, ++ i )
+      {
+      if ( ! val )
+        {
+        i += 8 - bit;
+        break;
+        }
+      else if ( val & 0x1 )
+        {
+        if ( i != rank )
+          procs.push_back( i );
+        else if ( ! procs.size() )
+          rank_owner = true;
+        }
+      }
+    }
+  return rank_owner;
+}
+
 bool MBProcessSet::is_process_member( int i ) const
 {
   int byte = i / 8;

Modified: MOAB/trunk/refiner/MBProcessSet.hpp
===================================================================
--- MOAB/trunk/refiner/MBProcessSet.hpp	2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBProcessSet.hpp	2008-07-25 04:14:30 UTC (rev 2024)
@@ -34,6 +34,7 @@
   void set_process_member( int i );
   void set_process_members( const std::vector<int>& procs );
 
+  bool get_process_members( int rank, std::vector<int>& procs );
   bool is_process_member( int i ) const;
 
   const unsigned char* data() const;

Modified: MOAB/trunk/refiner/MBRefinerTagManager.hpp
===================================================================
--- MOAB/trunk/refiner/MBRefinerTagManager.hpp	2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBRefinerTagManager.hpp	2008-07-25 04:14:30 UTC (rev 2024)
@@ -51,6 +51,7 @@
   MBInterface* get_input_mesh() { return this->input_mesh; }
   MBInterface* get_output_mesh() { return this->output_mesh; }
 
+  MBTag parallel_status() { return this->tag_pstatus; }
   MBTag shared_proc() { return this->tag_psproc; }
   MBTag shared_procs() { return this->tag_psprocs; }
 

Modified: MOAB/trunk/refiner/MBSplitVertices.cpp
===================================================================
--- MOAB/trunk/refiner/MBSplitVertices.cpp	2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBSplitVertices.cpp	2008-07-25 04:14:30 UTC (rev 2024)
@@ -1,6 +1,8 @@
 #include "MBSplitVertices.hpp"
 #include "MBRefinerTagManager.hpp"
 
+#include "MBParallelConventions.h"
+
 MBSplitVerticesBase::MBSplitVerticesBase( MBRefinerTagManager* tag_mgr )
 {
   this->tag_manager = tag_mgr;
@@ -9,6 +11,11 @@
   this->shared_procs_val.resize( MAX_SHARING_PROCS );
   MBParallelComm* ipcomm = MBParallelComm::get_pcomm( this->mesh_in, 0 );
   this->rank = ipcomm ? ipcomm->proc_config().proc_rank() : 0;
+  int zero = 0;
+  MBErrorCode result = this->mesh_out->tag_create(
+    GLOBAL_ID_TAG_NAME, sizeof(int), MB_TAG_DENSE, MB_TYPE_INTEGER, this->tag_gid, &zero, true );
+  if ( result != MB_SUCCESS && result != MB_ALREADY_ALLOCATED )
+    return;
 }
 
 MBSplitVerticesBase::~MBSplitVerticesBase()
@@ -87,3 +94,26 @@
   // FIXME: Here is where we add the vertex to the appropriate queues.
 }
 
+void MBSplitVerticesBase::set_sharing( MBEntityHandle ent_handle, MBProcessSet& procs )
+{
+  int pstat;
+  if ( procs.get_process_members( this->rank, this->shared_procs_val ) )
+    pstat = PSTATUS_SHARED | PSTATUS_INTERFACE | PSTATUS_NOT_OWNED;
+  else
+    pstat = PSTATUS_SHARED | PSTATUS_INTERFACE;
+  int sps = this->shared_procs_val.size();
+  switch ( sps )
+    {
+  case 0:
+    break;
+  case 1:
+    this->mesh_out->tag_set_data( this->tag_manager->shared_proc(), &ent_handle, 1, &this->shared_procs_val[0] );
+    this->mesh_out->tag_set_data( this->tag_manager->parallel_status(), &ent_handle, 1, &pstat );
+    break;
+  default:
+    this->mesh_out->tag_set_data( this->tag_manager->shared_procs(), &ent_handle, sps, &this->shared_procs_val[0] );
+    this->mesh_out->tag_set_data( this->tag_manager->parallel_status(), &ent_handle, 1, &pstat );
+    break;
+    }
+}
+

Modified: MOAB/trunk/refiner/MBSplitVertices.hpp
===================================================================
--- MOAB/trunk/refiner/MBSplitVertices.hpp	2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBSplitVertices.hpp	2008-07-25 04:14:30 UTC (rev 2024)
@@ -17,7 +17,7 @@
 {
 public:
   MBSplitVertexIndex() { }
-  MBSplitVertexIndex( const MBEntityHandle* src )
+  MBSplitVertexIndex( const int* src )
     { for ( int i = 0; i < _n; ++ i ) this->handles[i] = src[i]; std::sort( this->handles, this->handles + _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; }
@@ -42,10 +42,21 @@
     return false;
     }
 
-  MBEntityHandle handles[_n];
+  int handles[_n + 1];
   MBProcessSet process_set;
 };
 
+template< int _n >
+std::ostream& operator << ( std::ostream& os, const MBSplitVertexIndex<_n>& idx )
+{
+  for ( int i = 0; i < _n; ++ i )
+    {
+    os << idx.handles[i] << " ";
+    }
+  os << "(" << idx.process_set << ")";
+  return os;
+}
+
 /** A non-templated base class that the template subclasses all share.
   *
   * All methods that need to be accessed by other classes should be
@@ -62,8 +73,12 @@
     const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
     std::map<MBProcessSet,int>& proc_partition_counts ) = 0;
 
-  virtual void assign_global_ids( std::map<MBProcessSet,MBEntityHandle>& gids ) = 0;
+  virtual bool create_element(
+    const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
+    std::map<MBProcessSet,int>& proc_partition_counts ) = 0;
 
+  virtual void assign_global_ids( std::map<MBProcessSet,int>& gids ) = 0;
+
   /// Determine which processes will contain an output vertex given the split vertices defining it.
   void update_partition_counts( int num, const MBEntityHandle* split_src, std::map<MBProcessSet,int>& proc_partition_counts );
 
@@ -76,14 +91,19 @@
   /// Call this once after all the add_vertex_procs() calls for a split-vertex to prepare queues for the second stage MPI send. 
   void end_vertex_procs();
 
+  /// Set the tags which indicate sharing process(es) for an entity.
+  void set_sharing( MBEntityHandle vert_handle, MBProcessSet& procs );
+
   MBInterface* mesh_in; // Input mesh. Needed to determine tag values on split_src verts
   MBInterface* mesh_out; // Output mesh. Needed for new vertex set in vert_handle
   MBRefinerTagManager* tag_manager;
   std::vector<int> shared_procs_val; // Used to hold procs sharing an input vert.
+  std::vector<int> split_gids; // Used to hold global IDs of split vertices
   MBProcessSet current_shared_procs; // Holds process list as it is being accumulated
   MBProcessSet common_shared_procs; // Holds intersection of several shared_procs_vals.
   int rank; // This process' rank.
   bool first_vertex; // True just after begin_vertex_procs() is called.
+  MBTag tag_gid;
 };
 
 /** A map from a set of pre-existing entities to a new mesh entity.
@@ -104,7 +124,11 @@
   virtual bool find_or_create(
     const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
     std::map<MBProcessSet,int>& proc_partition_counts );
-  virtual void assign_global_ids( std::map<MBProcessSet,MBEntityHandle>& gids );
+  virtual bool create_element(
+    const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
+    std::map<MBProcessSet,int>& proc_partition_counts );
+
+  virtual void assign_global_ids( std::map<MBProcessSet,int>& gids );
 };
 
 // ------------------------- Template member definitions ----------------------
@@ -113,6 +137,7 @@
   : MBSplitVerticesBase( tag_mgr )
 {
   this->shared_procs_val.resize( _n * MAX_SHARING_PROCS );
+  this->split_gids.resize( _n );
 }
 
 template< int _n >
@@ -125,7 +150,15 @@
   const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
   std::map<MBProcessSet,int>& proc_partition_counts )
 {
-  MBSplitVertexIndex<_n> key( split_src );
+  // Get the global IDs of the input vertices
+  int stat;
+  for ( int i = 0; i < _n; ++ i )
+    {
+    int gid = -1;
+    stat = this->mesh_in->tag_get_data( this->tag_gid, split_src + i, 1, &gid );
+    this->split_gids[i] = gid;
+    }
+  MBSplitVertexIndex<_n> key( &this->split_gids[0] );
   MapIteratorType it = this->find( key );
   if ( it == this->end() )
     {
@@ -136,6 +169,7 @@
       return false;
       }
     (*this)[key] = vert_handle;
+    this->set_sharing( vert_handle, this->common_shared_procs );
     return true;
     }
   vert_handle = it->second;
@@ -143,20 +177,21 @@
 }
 
 template< int _n >
-void MBSplitVertices<_n>::assign_global_ids( std::map<MBProcessSet,MBEntityHandle>& gids )
+bool MBSplitVertices<_n>::create_element(
+  const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
+  std::map<MBProcessSet,int>& proc_partition_counts )
 {
-  MBTag tag_gid;
-  int zero = 0;
-  MBErrorCode result = this->mesh_out->tag_create(
-    GLOBAL_ID_TAG_NAME, sizeof(int), MB_TAG_DENSE, MB_TYPE_INTEGER, tag_gid, &zero, true );
-  if ( result != MB_SUCCESS && result != MB_ALREADY_ALLOCATED )
-    return;
+}
 
+template< int _n >
+void MBSplitVertices<_n>::assign_global_ids( std::map<MBProcessSet,int>& gids )
+{
   typename std::map<MBSplitVertexIndex<_n>,MBEntityHandle>::iterator it;
   for ( it = this->begin(); it != this->end(); ++ it )
     {
     int gid = gids[it->first.process_set] ++;
-    this->mesh_out->tag_set_data( tag_gid, &it->second, 1, &gid );
+    this->mesh_out->tag_set_data( this->tag_gid, &it->second, 1, &gid );
+    std::cout << "Assigning " << it->first << " -> " << gid << "\n";
     }
 }
 

Modified: MOAB/trunk/refiner/test_mesh_refiner.cpp
===================================================================
--- MOAB/trunk/refiner/test_mesh_refiner.cpp	2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/test_mesh_refiner.cpp	2008-07-25 04:14:30 UTC (rev 2024)
@@ -27,6 +27,7 @@
   nprocs = 1;
   rank = 0;
 #endif // USE_MPI
+  //sleep(20);
 
   // Create the input mesh and, if -new-mesh is specified, an output mesh
   const char* ifname = argc > 1 ? argv[1] : "/home/dcthomp/fourVolsBare.cub";




More information about the moab-dev mailing list