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

dcthomp at mcs.anl.gov dcthomp at mcs.anl.gov
Mon Aug 25 18:02:58 CDT 2008


Author: dcthomp
Date: 2008-08-25 18:02:57 -0500 (Mon, 25 Aug 2008)
New Revision: 2048

Modified:
   MOAB/trunk/refiner/MBEntityRefiner.hpp
   MOAB/trunk/refiner/MBMeshOutputFunctor.cpp
   MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
   MOAB/trunk/refiner/MBProcessSet.cpp
   MOAB/trunk/refiner/MBRefinerTagManager.cpp
   MOAB/trunk/refiner/MBRefinerTagManager.hpp
   MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp
   MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp
   MOAB/trunk/refiner/MBSplitVertices.cpp
   MOAB/trunk/refiner/MBSplitVertices.hpp
   MOAB/trunk/refiner/test_mesh_refiner.cpp
Log:
ENH: Checkpoint of progress. The input mesh and output mesh
     need not be the same any longer.
STYLE: Moved some code dealing with parallel status/sharing
       tags from the output functor to the tag manager.


Modified: MOAB/trunk/refiner/MBEntityRefiner.hpp
===================================================================
--- MOAB/trunk/refiner/MBEntityRefiner.hpp	2008-08-18 17:28:19 UTC (rev 2047)
+++ MOAB/trunk/refiner/MBEntityRefiner.hpp	2008-08-25 23:02:57 UTC (rev 2048)
@@ -52,6 +52,10 @@
   * one used for appending a vertex to an entity,
   * the other used to finalize the creation of the entity by specifying its type.
   *
+  * You are also responsible for implementing the map_vertex() function to map an input vertex handle
+  * into an output vertex handle (which may then be appended to an entity using the first form
+  * of the parenthesis operator above).
+  *
   * \author David Thompson
   * \author Philippe Pebay
   *
@@ -72,7 +76,16 @@
 {
 public:
   virtual ~MBEntityRefinerOutputFunctor() { }
-  virtual MBEntityHandle operator () ( MBEntityHandle vhash, const double* vcoords, const void* vtags ) = 0;
+  /// Map an input vertex to the output mesh. This should return the same value when given the same input across multiple calls.
+  virtual MBEntityHandle map_vertex( MBEntityHandle vhash, const double* vcoords, const void* vtags ) = 0;
+  /**\brief Create a new vertex along an edge.
+    *
+    * @param[in] h0 An edge endpoint handle on the output mesh.
+    * @param[in] h1 An edge endpoint handle on the output mesh.
+    * @param[in] vcoords The location of the midpoint in world coordinates.
+    * @param[in] vtags Field values at the midpoint.
+    * @retval    A handle for the midpoint on the output mesh.
+    */
   MBEntityHandle operator () ( MBEntityHandle h0, MBEntityHandle h1, const double* vcoords, const void* vtags )
     {
     MBEntityHandle harr[2];
@@ -80,6 +93,15 @@
     harr[1] = h1;
     return (*this)( 2, harr, vcoords, vtags );
     }
+  /**\brief Create a new vertex on a triangular face.
+    *
+    * @param[in] h0 A triangle corner handle on the output mesh.
+    * @param[in] h1 A triangle corner handle on the output mesh.
+    * @param[in] h2 A triangle corner handle on the output mesh.
+    * @param[in] vcoords The location of the mid-face point in world coordinates.
+    * @param[in] vtags Field values at the mid-face point.
+    * @retval    A handle for the mid-face point on the output mesh.
+    */
   virtual MBEntityHandle operator () ( MBEntityHandle h0, MBEntityHandle h1, MBEntityHandle h2, const double* vcoords, const void* vtags )
     {
     MBEntityHandle harr[3];
@@ -88,8 +110,25 @@
     harr[2] = h2;
     return (*this)( 3, harr, vcoords, vtags );
     }
+  /**\brief Create a new vertex along a \f$k\f$-facet.
+    *
+    * @param[in] nhash The number of corner vertices (i.e, \f$k\f$ ).
+    * @param[in] hash An array of corner handles on the output mesh.
+    * @param[in] vcoords The location of the new point in world coordinates.
+    * @param[in] vtags Field values at the new point.
+    * @retval    A handle for the new point on the output mesh.
+    */
   virtual MBEntityHandle operator () ( int nhash, MBEntityHandle* hash, const double* vcoords, const void* vtags ) = 0;
+  /**\brief Append an output vertex to the list of vertices defining a new entity.
+    *
+    * @param[in] vhash A vertex of the output mesh.
+    */
   virtual void operator () ( MBEntityHandle vhash ) = 0;
+  /**\brief Create a new entity from all previously appended output vertices.
+    *
+    * This resets the list of appended vertices.
+    * @param[in] etyp The type of entity to create.
+    */
   virtual void operator () ( MBEntityType etyp ) = 0;
 };
 

Modified: MOAB/trunk/refiner/MBMeshOutputFunctor.cpp
===================================================================
--- MOAB/trunk/refiner/MBMeshOutputFunctor.cpp	2008-08-18 17:28:19 UTC (rev 2047)
+++ MOAB/trunk/refiner/MBMeshOutputFunctor.cpp	2008-08-25 23:02:57 UTC (rev 2048)
@@ -26,22 +26,24 @@
 
   // 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.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 );
 }
 
 MBMeshOutputFunctor::~MBMeshOutputFunctor()
 {
-  for ( int i = 0; i < 4; ++ i )
+  for ( int i = 1; i < 4; ++ i )
     delete this->split_vertices[i];
-  for ( int i = 0; i < 4; ++ i )
+  for ( int i = 0; i < 5; ++ i )
     delete this->new_entities[i];
 }
 
-void MBMeshOutputFunctor::print_vert_crud( MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags )
+void MBMeshOutputFunctor::print_vert_crud(
+  MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags )
 {
   std::cout << "+ {";
   for ( int i = 0; i < nvhash; ++ i )
@@ -63,6 +65,9 @@
 #endif // 0
 
   std::cout << " >\n";
+  //std::cout << "##############################\n";
+  //this->mesh_out->list_entities( 0, 1 );
+  //std::cout << "##############################\n";
 }
 
 void MBMeshOutputFunctor::assign_global_ids( MBParallelComm* comm )
@@ -144,10 +149,12 @@
     std::cout << "Partition " << pcit->first << ": " << pcit->second << " # [" << gids[pcit->first] << "]\n";
     }
   std::vector<MBSplitVerticesBase*>::iterator vit;
-  for ( vit = this->split_vertices.begin(); vit != this->split_vertices.end(); ++ vit )
+  vit = this->split_vertices.begin();
+  ++ vit; // Skip split_vertices[0] since it's empty.
+  ++ vit; // Skip split_vertices[1] since those entries already have global IDs... they exist in the input mesh.
+  for ( /* skip */; vit != this->split_vertices.end(); ++ vit )
     {
-    if ( *vit )
-      (*vit)->assign_global_ids( gids );
+    (*vit)->assign_global_ids( gids );
     }
   for ( vit = this->new_entities.begin(); vit != this->new_entities.end(); ++ vit )
     {
@@ -156,6 +163,10 @@
     }
 }
 
+void MBMeshOutputFunctor::exchange_handles( MBParallelComm* comm )
+{
+}
+
 void MBMeshOutputFunctor::assign_tags( MBEntityHandle vhandle, const void* vtags )
 {
   if ( ! vhandle )
@@ -171,7 +182,7 @@
     }
 }
 
-MBEntityHandle MBMeshOutputFunctor::operator () ( MBEntityHandle vhash, const double* vcoords, const void* vtags )
+MBEntityHandle MBMeshOutputFunctor::map_vertex( MBEntityHandle vhash, const double* vcoords, const void* vtags )
 {
   if ( this->input_is_output )
     { // Don't copy the original vertex!
@@ -179,11 +190,16 @@
     return vhash;
     }
   MBEntityHandle vertex_handle;
-  bool newly_created = this->new_entities[0]->find_or_create(
-    &vhash, vcoords, vertex_handle, this->proc_partition_counts );
+  bool newly_created = this->new_entities[1]->find_or_create(
+    &vhash, vcoords, vertex_handle, this->proc_partition_counts, false );
   if ( newly_created )
     {
+    std::vector<int> gid;
     this->assign_tags( vertex_handle, vtags );
+    if ( this->tag_manager->get_input_gids( 1, &vhash, gid ) == MB_SUCCESS )
+      {
+      this->tag_manager->set_gid( vertex_handle, gid[0] );
+      }
     }
   if ( ! vertex_handle )
     {
@@ -196,14 +212,10 @@
 MBEntityHandle MBMeshOutputFunctor::operator () ( int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags )
 {
   MBEntityHandle vertex_handle;
-  if ( nvhash == 1 )
+  if ( nvhash < 4 )
     {
-    vertex_handle = (*this)( *vhash, vcoords, vtags );
-    }
-  else if ( nvhash < 4 )
-    {
     bool newly_created = this->split_vertices[nvhash]->find_or_create(
-      vhash, vcoords, vertex_handle, this->proc_partition_counts );
+      vhash, vcoords, vertex_handle, this->proc_partition_counts, true );
     if ( newly_created )
       {
       this->assign_tags( vertex_handle, vtags );
@@ -212,6 +224,7 @@
       {
       std::cerr << "Could not insert mid-edge vertex!\n";
       }
+    std::cout << "(-" << nvhash << "-) ";
     this->print_vert_crud( vertex_handle, nvhash, vhash, vcoords, vtags );
     }
   else
@@ -225,31 +238,26 @@
 void MBMeshOutputFunctor::operator () ( MBEntityHandle h )
 {
   std::cout << h << " ";
-  this->elem_vert.push_back( h );
   if ( ! this->input_is_output )
     {
     // FIXME: Copy to output mesh
     }
+  this->elem_vert.push_back( h );
 }
 
 void MBMeshOutputFunctor::operator () ( MBEntityType etyp )
 {
   MBEntityHandle elem_handle;
   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 );
+    etyp, nconn, &this->elem_vert[0], elem_handle, this->proc_partition_counts );
   if ( newly_created )
     {
+    std::cout << " *** ";
     // FIXME: Handle tag assignment for elements as well as vertices
     //this->assign_tags( elem_handle, this->element_tag_data );
     }
-#endif // 0
+  std::cout << "---------> " << elem_handle << " ( " << etyp << " )\n\n";
   this->elem_vert.clear();
 }
 

Modified: MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
===================================================================
--- MOAB/trunk/refiner/MBMeshOutputFunctor.hpp	2008-08-18 17:28:19 UTC (rev 2047)
+++ MOAB/trunk/refiner/MBMeshOutputFunctor.hpp	2008-08-25 23:02:57 UTC (rev 2048)
@@ -48,10 +48,11 @@
 
   void print_vert_crud( MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags );
   void assign_global_ids( MBParallelComm* comm );
+  void exchange_handles( MBParallelComm* comm );
 
   void assign_tags( MBEntityHandle vhandle, const void* vtags );
 
-  virtual MBEntityHandle operator () ( MBEntityHandle vhash, const double* vcoords, const void* vtags );
+  virtual MBEntityHandle map_vertex( MBEntityHandle vhash, const double* vcoords, const void* vtags );
   virtual MBEntityHandle operator () ( int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags );
   virtual void operator () ( MBEntityHandle h );
   virtual void operator () ( MBEntityType etyp );

Modified: MOAB/trunk/refiner/MBProcessSet.cpp
===================================================================
--- MOAB/trunk/refiner/MBProcessSet.cpp	2008-08-18 17:28:19 UTC (rev 2047)
+++ MOAB/trunk/refiner/MBProcessSet.cpp	2008-08-25 23:02:57 UTC (rev 2048)
@@ -95,6 +95,10 @@
         }
       }
     }
+  for ( i = procs.size(); i < MAX_SHARING_PROCS; ++ i )
+    {
+    procs.push_back( -1 ); // pad with invalid values
+    }
   return rank_owner;
 }
 

Modified: MOAB/trunk/refiner/MBRefinerTagManager.cpp
===================================================================
--- MOAB/trunk/refiner/MBRefinerTagManager.cpp	2008-08-18 17:28:19 UTC (rev 2047)
+++ MOAB/trunk/refiner/MBRefinerTagManager.cpp	2008-08-25 23:02:57 UTC (rev 2048)
@@ -2,12 +2,16 @@
 
 #include "MBInterface.hpp"
 #include "MBParallelComm.hpp"
+#include "MBParallelConventions.h"
+#include "MBTagConventions.hpp"
 
 #include <iostream>
+#include <stdexcept>
 #include <assert.h>
 
 /// Construct an evaluator.
 MBRefinerTagManager::MBRefinerTagManager( MBInterface* in_mesh, MBInterface* out_mesh )
+  : shared_procs_in( 5 * MAX_SHARING_PROCS, -1 ), shared_procs_out( MAX_SHARING_PROCS, -1 )
 {
   assert( in_mesh );
   if ( ! out_mesh )
@@ -17,19 +21,76 @@
   this->output_mesh = out_mesh;
   this->reset_vertex_tags();
   MBParallelComm* ipcomm = MBParallelComm::get_pcomm( this->input_mesh, 0 );
+  MBParallelComm* opcomm = 0;
+  if ( this->output_mesh != this->input_mesh )
+    {
+    opcomm = MBParallelComm::get_pcomm( this->output_mesh, 0 );
+    if ( ! opcomm )
+      {
+      std::cout << "Creating opcomm: " << opcomm << "\n";
+      opcomm = new MBParallelComm( this->output_mesh, MPI_COMM_WORLD );
+      }
+    }
+  else
+    {
+    opcomm = ipcomm;
+    }
+
   if ( ipcomm )
     {
     ipcomm->get_shared_proc_tags(
-      this->tag_psproc, this->tag_psprocs,
-      this->tag_pshand, this->tag_pshands,
-      this->tag_pstatus );
+      this->tag_ipsproc, this->tag_ipsprocs,
+      this->tag_ipshand, this->tag_ipshands,
+      this->tag_ipstatus );
     }
   else
     {
-    this->tag_psproc = this->tag_psprocs = 0;
-    this->tag_pshand = this->tag_pshands = 0;
-    this->tag_pstatus = 0;
+    this->tag_ipsproc = this->tag_ipsprocs = 0;
+    this->tag_ipshand = this->tag_ipshands = 0;
+    this->tag_ipstatus = 0;
     }
+
+  if ( opcomm )
+    {
+    opcomm->get_shared_proc_tags(
+      this->tag_opsproc, this->tag_opsprocs,
+      this->tag_opshand, this->tag_opshands,
+      this->tag_opstatus );
+    }
+  else
+    {
+    this->tag_opsproc = this->tag_opsprocs = 0;
+    this->tag_opshand = this->tag_opshands = 0;
+    this->tag_opstatus = 0;
+    }
+
+  this->rank =
+    ipcomm ? ipcomm->proc_config().proc_rank() :
+    ( opcomm ? opcomm->proc_config().proc_rank() : 0 );
+
+  // Create the mesh global ID tags if they aren't already there.
+  int zero = 0;
+  MBErrorCode result;
+  result = this->input_mesh->tag_create(
+    GLOBAL_ID_TAG_NAME, sizeof(int), MB_TAG_DENSE, MB_TYPE_INTEGER, this->tag_igid, &zero, true );
+  if ( result != MB_SUCCESS && result != MB_ALREADY_ALLOCATED )
+    {
+    throw new std::logic_error( "Unable to find input mesh global ID tag \"" GLOBAL_ID_TAG_NAME "\"" );
+    }
+  result = this->output_mesh->tag_create(
+    GLOBAL_ID_TAG_NAME, sizeof(int), MB_TAG_DENSE, MB_TYPE_INTEGER, this->tag_ogid, &zero, true );
+  if ( result != MB_SUCCESS && result != MB_ALREADY_ALLOCATED )
+    {
+    throw new std::logic_error( "Unable to find/create output mesh global ID tag \"" GLOBAL_ID_TAG_NAME "\"" );
+    }
+
+  std::cout
+    << "psproc:  " << this->tag_ipsproc  << ", " << this->tag_opsproc << "\n"
+    << "psprocs: " << this->tag_ipsprocs << ", " << this->tag_opsprocs << "\n"
+    << "pshand:  " << this->tag_ipshand  << ", " << this->tag_opshand << "\n"
+    << "pshands: " << this->tag_ipshands << ", " << this->tag_opshands << "\n"
+    << "pstatus: " << this->tag_ipstatus << ", " << this->tag_opstatus << "\n"
+    << "gid:     " << this->tag_igid     << ", " << this->tag_ogid     << "\n";
 }
 
 /// Destruction is virtual so subclasses may clean up after refinement.
@@ -181,3 +242,179 @@
   tag = it->first;
   byte_offset = it->second;
 }
+
+/**\brief Retrieve the global ID of each input entity and push it onto the output vector.
+  *
+  * The \a gids array is emptied by this call before any new values are added.
+  * Note that this routine fetches global IDs from the input mesh, not the output mesh;
+  * your entity handles must be from the input mesh.
+  *
+  * @param[in] ents An array of entities in the input mesh whose global IDs you desire
+  * @param[in] n The number of entities in the \a ents array.
+  * @param[out] gids A vector to contain the resulting global IDs.
+  * @retval A MOAB error code as supplied by the MBInterface::tag_get_data() call.
+  */
+int MBRefinerTagManager::get_input_gids( int n, const MBEntityHandle* ents, std::vector<int>& gids )
+{
+  int stat;
+  gids.clear();
+  for ( int i = 0; i < n; ++ i )
+    {
+    int gid = -1;
+    stat |= this->input_mesh->tag_get_data( this->tag_igid, ents + i, 1, &gid );
+    gids.push_back( gid );
+    }
+  return stat;
+}
+
+/**\brief Retrieve the global ID of each output entity and push it onto the output vector.
+  *
+  * The \a gids array is emptied by this call before any new values are added.
+  * Note that this routine fetches global IDs from the output mesh, not the input mesh;
+  * your entity handles must be from the output mesh.
+  * Also, be aware that many output entities will not have global IDs assigned;
+  * only those vertices which exist in the input mesh are guaranteed to have global IDs
+  * assigned to them -- vertices that only exist in the output mesh and all higher-dimensional
+  * output entities have no global IDs assigned until after a complete subdivision pass has been made.
+  *
+  * @param[in] ents An array of entities in the output mesh whose global IDs you desire
+  * @param[in] n The number of entities in the \a ents array.
+  * @param[out] gids A vector to contain the resulting global IDs.
+  * @retval A MOAB error code as supplied by the MBInterface::tag_get_data() call.
+  */
+int MBRefinerTagManager::get_output_gids( int n, const MBEntityHandle* ents, std::vector<int>& gids )
+{
+  int stat;
+  gids.clear();
+  for ( int i = 0; i < n; ++ i )
+    {
+    int gid = -1;
+    stat |= this->output_mesh->tag_get_data( this->tag_igid, ents + i, 1, &gid );
+    gids.push_back( gid );
+    }
+  return stat;
+}
+
+/**\brief Assign a global ID to an output entity.
+  *
+  * @param[in] ent The entity whose ID will be set
+  * @param[out] id The global ID
+  * @retval An error code as returned by MBInterface::tag_set_data().
+  */
+int MBRefinerTagManager::set_gid( MBEntityHandle ent, int gid )
+{
+  return this->output_mesh->tag_set_data( this->tag_ogid, &ent, 1, &gid );
+}
+
+/**\brief Set parallel status and sharing process list on an entity.
+  *
+  * This sets tag values for the PARALLEL_STATUS and one of PARALLEL_SHARED_PROC or PARALLEL_SHARED_PROCS tags
+  * if \a procs contains any processes (the current process is assumed <b>not</b> to be set in \a procs).
+  *
+  * @param[in] ent_handle The entity whose information will be set
+  * @param[in] procs The set of sharing processes.
+  */
+void MBRefinerTagManager::set_sharing( MBEntityHandle ent_handle, MBProcessSet& procs )
+{
+  int pstat;
+  if ( procs.get_process_members( this->rank, this->shared_procs_out ) )
+    pstat = PSTATUS_SHARED | PSTATUS_INTERFACE;
+  else
+    pstat = PSTATUS_SHARED | PSTATUS_INTERFACE | PSTATUS_NOT_OWNED;
+  if ( this->shared_procs_out[0] >= 0 )
+    {
+    // assert( MAX_SHARING_PROCS > 1 );
+    // Since get_process_members pads to MAX_SHARING_PROCS, this will be work:
+    if ( this->shared_procs_out[1] <= 0 )
+      {
+      //std::cout << "  (proc )";
+      this->output_mesh->tag_set_data( this->tag_opsproc, &ent_handle, 1, &this->shared_procs_out[0] );
+      this->output_mesh->tag_set_data( this->tag_opstatus, &ent_handle, 1, &pstat );
+      }
+    else
+      {
+      //std::cout << "  (procS)";
+      this->output_mesh->tag_set_data( this->tag_opsprocs, &ent_handle, 1, &this->shared_procs_out[0] );
+      this->output_mesh->tag_set_data( this->tag_opstatus, &ent_handle, 1, &pstat );
+      }
+    }
+  else
+    {
+    //std::cout << "  (none )";
+    }
+  //std::cout << " new pstat: " << pstat << "\n";
+}
+
+/**\brief Determine the subset of processes which all share the specified entities.
+  *
+  * This is used to determine which processes an output entity should reside on when
+  * it is defined using several input entities (such as vertices).
+  */
+void MBRefinerTagManager::get_common_processes(
+  int num, const MBEntityHandle* src, MBProcessSet& common_shared_procs, bool on_output_mesh )
+{
+  MBInterface* mesh;
+  MBTag psproc;
+  MBTag psprocs;
+  if ( on_output_mesh )
+    {
+    mesh = this->output_mesh;
+    psproc = this->tag_opsproc;
+    psprocs = this->tag_opsprocs;
+    }
+  else
+    {
+    mesh = this->input_mesh;
+    psproc = this->tag_ipsproc;
+    psprocs = this->tag_ipsprocs;
+    }
+  bool first_ent = true;
+  common_shared_procs.clear();
+  for ( int i = 0; i < num; ++ i )
+    {
+    MBEntityHandle ent_in = src[i];
+    //std::cout << "<(" << ent_in << ")>";
+    int stat;
+    bool got = false;
+    this->current_shared_procs.clear();
+    stat = mesh->tag_get_data( psproc, &ent_in, 1, &this->shared_procs_in[0] );
+    if ( stat == MB_SUCCESS && this->shared_procs_in[0] != -1 )
+      {
+      got = true;
+      //std::cout << " s" << this->rank << " s" << this->shared_procs_in[0] << " | ";
+      this->shared_procs_in[1] = -1;
+      }
+    stat = mesh->tag_get_data( psprocs, &ent_in, 1, &this->shared_procs_in[0] );
+    if ( stat == MB_SUCCESS && this->shared_procs_in[0] != -1 )
+      {
+      got = true;
+      int i;
+      /*
+      for ( i = 0; i < MAX_SHARING_PROCS && this->shared_procs_in[i] != -1; ++ i )
+        std::cout << " m" << this->shared_procs_in[i];
+      std::cout << " | ";
+      */
+      }
+    if ( got )
+      {
+      this->current_shared_procs.set_process_members( this->shared_procs_in );
+      this->current_shared_procs.set_process_member( this->rank );
+      if ( first_ent )
+        {
+        common_shared_procs.unite( this->current_shared_procs );
+        first_ent = false;
+        }
+      else
+        {
+        common_shared_procs.intersect( this->current_shared_procs );
+        }
+      }
+    else
+      {
+      //std::cout << " not shared | ";
+      }
+    }
+  std::cout << "    Common procs " << common_shared_procs;
+  std::cout << "\n";
+}
+

Modified: MOAB/trunk/refiner/MBRefinerTagManager.hpp
===================================================================
--- MOAB/trunk/refiner/MBRefinerTagManager.hpp	2008-08-18 17:28:19 UTC (rev 2047)
+++ MOAB/trunk/refiner/MBRefinerTagManager.hpp	2008-08-25 23:02:57 UTC (rev 2048)
@@ -28,6 +28,8 @@
 
 #include "MBTypes.h" // for MB_DLL_EXPORT
 
+#include "MBProcessSet.hpp"
+
 #include <vector>
 
 class MBInterface;
@@ -51,21 +53,39 @@
   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; }
+  MBTag input_parallel_status() { return this->tag_ipstatus; }
+  MBTag input_shared_proc() { return this->tag_ipsproc; }
+  MBTag input_shared_procs() { return this->tag_ipsprocs; }
 
+  int get_input_gids( int n, const MBEntityHandle* ents, std::vector<int>& gids );
+  int get_output_gids( int n, const MBEntityHandle* ents, std::vector<int>& gids );
+  int set_gid( MBEntityHandle ent, int gid );
+
+  void set_sharing( MBEntityHandle ent_handle, MBProcessSet& procs );
+  void get_common_processes( int num, const MBEntityHandle* src, MBProcessSet& common_shared_procs, bool on_output_mesh = true );
+
 protected:
   std::vector< std::pair< MBTag, int > > input_vertex_tags;
   std::vector< std::pair< MBTag, int > > output_vertex_tags;
   int vertex_size;
   MBInterface* input_mesh;
   MBInterface* output_mesh;
-  MBTag tag_pstatus; // Handle for PARALLEL_STATUS on mesh_in
-  MBTag tag_psprocs; // Handle for PARALLEL_SHARED_PROCS on mesh_in
-  MBTag tag_psproc;  // Handle for PARALLEL_SHARED_PROC on mesh_in
-  MBTag tag_pshands; // Handle for PARALLEL_SHARED_HANDLES on mesh_in
-  MBTag tag_pshand;  // Handle for PARALLEL_SHARED_HANDLE on mesh_in
+  MBTag tag_ipstatus; // Handle for PARALLEL_STATUS on mesh_in
+  MBTag tag_ipsprocs; // Handle for PARALLEL_SHARED_PROCS on mesh_in
+  MBTag tag_ipsproc;  // Handle for PARALLEL_SHARED_PROC on mesh_in
+  MBTag tag_ipshands; // Handle for PARALLEL_SHARED_HANDLES on mesh_in
+  MBTag tag_ipshand;  // Handle for PARALLEL_SHARED_HANDLE on mesh_in
+  MBTag tag_igid;     // Handle for global IDs on mesh_in
+  MBTag tag_opstatus; // Handle for PARALLEL_STATUS on mesh_out
+  MBTag tag_opsprocs; // Handle for PARALLEL_SHARED_PROCS on mesh_out
+  MBTag tag_opsproc;  // Handle for PARALLEL_SHARED_PROC on mesh_out
+  MBTag tag_opshands; // Handle for PARALLEL_SHARED_HANDLES on mesh_out
+  MBTag tag_opshand;  // Handle for PARALLEL_SHARED_HANDLE on mesh_out
+  MBTag tag_ogid;     // Handle for global IDs on mesh_out
+  int rank;
+  std::vector<int> shared_procs_in; // Used to hold procs sharing an input vert.
+  std::vector<int> shared_procs_out; // Used to hold procs sharing an output entity.
+  MBProcessSet current_shared_procs; // Holds process list as it is being accumulated
 };
 
 #endif // MB_REFINERTAGMANAGER_H

Modified: MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp
===================================================================
--- MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp	2008-08-18 17:28:19 UTC (rev 2047)
+++ MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp	2008-08-25 23:02:57 UTC (rev 2048)
@@ -30,6 +30,7 @@
   this->corner_coords.resize( 6 * 8 ); // Hex has 8 verts w/ 6 coordinates each
   this->corner_tags.resize( 8 ); // Hex has 8 verts (this is a pointer, not the actual tag data)
   this->corner_handles.resize( 8 ); // Hex has 8 verts (this is a pointer, not actual hash data)
+  this->input_is_output = false; // Until we know better
 }
 
 /// Empty destructor for good form.
@@ -61,7 +62,6 @@
   void* tag_data;
   for ( int n = 0; n < num_nodes; ++ n )
     {
-    this->corner_handles[n] = conn[n];
     if ( imesh->get_coords( &conn[n], 1, &corner_coords[6 * n + 3] ) != MB_SUCCESS )
       {
       return false;
@@ -75,6 +75,20 @@
         return false;
         }
       }
+    if ( this->input_is_output )
+      {
+      this->corner_handles[n] = conn[n];
+      }
+    else
+      {
+      this->corner_handles[n] = this->output_functor->map_vertex( conn[n], &corner_coords[6 * n], tag_data );
+#if 0
+      std::cout << "#+# " << this->corner_handles[n] << " < "
+        << corner_coords[ 6 * n + 3 ] << ", "
+        << corner_coords[ 6 * n + 4 ] << ", "
+        << corner_coords[ 6 * n + 5 ] << ">\n";
+#endif // 0
+      }
     this->corner_tags[n] = tag_data;
     }
 
@@ -170,6 +184,7 @@
 { 
   this->tag_manager = tmgr;
   this->tag_assigner->set_tag_manager( tmgr );
+  this->input_is_output = ( this->tag_manager->get_input_mesh() == this->tag_manager->get_output_mesh() );
   //this->tag_assigner->set_edge_size_evaluator( this->edge_size_evaluator );
   return this->MBEntityRefiner::prepare( tmgr, ofunc );
 }

Modified: MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp
===================================================================
--- MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp	2008-08-18 17:28:19 UTC (rev 2047)
+++ MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp	2008-08-25 23:02:57 UTC (rev 2048)
@@ -56,6 +56,7 @@
   std::vector<double> corner_coords;
   std::vector<void*> corner_tags;
   std::vector<MBEntityHandle> corner_handles;
+  bool input_is_output;
 
   static int template_index[64][2];
   static int permutations_from_index[24][14];

Modified: MOAB/trunk/refiner/MBSplitVertices.cpp
===================================================================
--- MOAB/trunk/refiner/MBSplitVertices.cpp	2008-08-18 17:28:19 UTC (rev 2047)
+++ MOAB/trunk/refiner/MBSplitVertices.cpp	2008-08-25 23:02:57 UTC (rev 2048)
@@ -6,115 +6,10 @@
 MBSplitVerticesBase::MBSplitVerticesBase( MBRefinerTagManager* tag_mgr )
 {
   this->tag_manager = tag_mgr;
-  this->mesh_in  = tag_mgr->get_input_mesh();
   this->mesh_out = tag_mgr->get_output_mesh();
-  this->shared_procs_in.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()
 {
 }
 
-/// Determine which processes will contain an output vertex given the split vertices defining it.
-void MBSplitVerticesBase::update_partition_counts(
-  int num, const MBEntityHandle* split_src, std::map<MBProcessSet,int>& proc_partition_counts )
-{
-  this->begin_vertex_procs();
-  for ( int i = 0; i < num; ++ i )
-    {
-    this->add_vertex_procs( split_src[i] );
-    }
-  this->end_vertex_procs();
-  proc_partition_counts[this->common_shared_procs]++;
-}
-
-/// Prepare to compute the processes on which a new split-vertex will live.
-void MBSplitVerticesBase::begin_vertex_procs()
-{
-  this->first_vertex = true;
-  this->common_shared_procs.clear();
-}
-
-/// Call this for each existing corner vertex used to define a split-vertex.
-void MBSplitVerticesBase::add_vertex_procs( MBEntityHandle vert_in )
-{
-  int stat;
-  bool got = false;
-  this->current_shared_procs.clear();
-  stat = this->mesh_in->tag_get_data(
-    this->tag_manager->shared_proc(), &vert_in, 1, &this->shared_procs_in[0] );
-  if ( stat == MB_SUCCESS && this->shared_procs_in[0] != -1 )
-    {
-    got = true;
-    std::cout << " s" << this->rank << " s" << this->shared_procs_in[0] << " | ";
-    this->shared_procs_in[1] = -1;
-    }
-  stat = this->mesh_in->tag_get_data(
-    this->tag_manager->shared_procs(), &vert_in, 1, &this->shared_procs_in[0] );
-  if ( stat == MB_SUCCESS && this->shared_procs_in[0] != -1 )
-    {
-    got = true;
-    int i;
-    for ( i = 0; i < MAX_SHARING_PROCS && this->shared_procs_in[i] != -1; ++ i )
-      std::cout << " m" << this->shared_procs_in[i];
-    std::cout << " | ";
-    }
-  if ( got )
-    {
-    this->current_shared_procs.set_process_members( this->shared_procs_in );
-    this->current_shared_procs.set_process_member( this->rank );
-    if ( this->first_vertex )
-      {
-      this->common_shared_procs.unite( this->current_shared_procs );
-      this->first_vertex = false;
-      }
-    else
-      {
-      this->common_shared_procs.intersect( this->current_shared_procs );
-      }
-    }
-  else
-    {
-    std::cout << " not shared | ";
-    }
-}
-
-/// Call this once after all the add_vertex_procs() calls for a split-vertex to prepare queues for the second stage MPI send. 
-void MBSplitVerticesBase::end_vertex_procs()
-{
-  std::cout << "    Common procs " << this->common_shared_procs;
-  std::cout << "\n";
-  // 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_out ) )
-    pstat = PSTATUS_SHARED | PSTATUS_INTERFACE;
-  else
-    pstat = PSTATUS_SHARED | PSTATUS_INTERFACE | PSTATUS_NOT_OWNED;
-  int sps = this->shared_procs_out.size();
-  std::cout << " new pstat: " << pstat << " sps: " << sps << "\n";
-  switch ( sps )
-    {
-  case 0:
-    break;
-  case 1:
-    this->mesh_out->tag_set_data( this->tag_manager->shared_proc(), &ent_handle, 1, &this->shared_procs_out[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_out[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-08-18 17:28:19 UTC (rev 2047)
+++ MOAB/trunk/refiner/MBSplitVertices.hpp	2008-08-25 23:02:57 UTC (rev 2048)
@@ -90,40 +90,18 @@
 
   virtual bool find_or_create(
     const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
-    std::map<MBProcessSet,int>& proc_partition_counts ) = 0;
+    std::map<MBProcessSet,int>& proc_partition_counts, bool handles_on_output_mesh ) = 0;
 
   virtual bool create_element(
-    const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
+    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;
 
-  /// 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 );
-
-  /// Prepare to compute the processes on which a new split-vertex will live.
-  void begin_vertex_procs();
-
-  /// Call this for each existing corner vertex used to define a split-vertex.
-  void add_vertex_procs( MBEntityHandle vert_in );
-
-  /// 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_in; // Used to hold procs sharing an input vert.
-  std::vector<int> shared_procs_out; // Used to hold procs sharing an output 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_ins.
-  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.
@@ -143,9 +121,9 @@
   virtual ~MBSplitVertices();
   virtual bool find_or_create(
     const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
-    std::map<MBProcessSet,int>& proc_partition_counts );
+    std::map<MBProcessSet,int>& proc_partition_counts, bool handles_on_output_mesh );
   virtual bool create_element(
-    const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
+    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 );
@@ -156,7 +134,6 @@
 MBSplitVertices<_n>::MBSplitVertices( MBRefinerTagManager* tag_mgr )
   : MBSplitVerticesBase( tag_mgr )
 {
-  this->shared_procs_in.resize( _n * MAX_SHARING_PROCS );
   this->split_gids.resize( _n );
 }
 
@@ -168,28 +145,32 @@
 template< int _n >
 bool MBSplitVertices<_n>::find_or_create(
   const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
-  std::map<MBProcessSet,int>& proc_partition_counts )
+  std::map<MBProcessSet,int>& proc_partition_counts, bool handles_on_output_mesh )
 {
   // Get the global IDs of the input vertices
   int stat;
-  for ( int i = 0; i < _n; ++ i )
+  if ( handles_on_output_mesh )
     {
-    int gid = -1;
-    stat = this->mesh_in->tag_get_data( this->tag_gid, split_src + i, 1, &gid );
-    this->split_gids[i] = gid;
+    stat = this->tag_manager->get_output_gids( _n, split_src, this->split_gids );
     }
+  else
+    {
+    stat = this->tag_manager->get_input_gids( _n, split_src, this->split_gids );
+    }
   MBSplitVertexIndex<_n> key( &this->split_gids[0] );
   MapIteratorType it = this->find( key );
   if ( it == this->end() )
     {
-    this->update_partition_counts( _n, split_src, proc_partition_counts );
+    std::cout << " wrt output: " << handles_on_output_mesh << " ";
+    this->tag_manager->get_common_processes( _n, split_src, this->common_shared_procs, handles_on_output_mesh );
+    proc_partition_counts[this->common_shared_procs]++;
     key.set_common_processes( this->common_shared_procs );
-    if ( this->mesh_out->create_vertex( coords, vert_handle ) != MB_SUCCESS )
+    if ( this->mesh_out->create_vertex( coords + 3, vert_handle ) != MB_SUCCESS )
       {
       return false;
       }
     (*this)[key] = vert_handle;
-    this->set_sharing( vert_handle, this->common_shared_procs );
+    this->tag_manager->set_sharing( vert_handle, this->common_shared_procs );
     return true;
     }
   vert_handle = it->second;
@@ -198,9 +179,23 @@
 
 template< int _n >
 bool MBSplitVertices<_n>::create_element(
-  const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
+  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->common_shared_procs]++;
+  key.set_common_processes( this->common_shared_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->common_shared_procs );
+  return true;
 }
 
 template< int _n >
@@ -210,8 +205,8 @@
   for ( it = this->begin(); it != this->end(); ++ it )
     {
     int gid = gids[it->first.process_set] ++;
-    this->mesh_out->tag_set_data( this->tag_gid, &it->second, 1, &gid );
-    std::cout << "Assigning " << it->first << " -> " << gid << "\n";
+    this->tag_manager->set_gid( it->second, gid );
+    std::cout << "Assigning entity: " << it->first << " GID: " << gid << "\n";
     }
 }
 

Modified: MOAB/trunk/refiner/test_mesh_refiner.cpp
===================================================================
--- MOAB/trunk/refiner/test_mesh_refiner.cpp	2008-08-18 17:28:19 UTC (rev 2047)
+++ MOAB/trunk/refiner/test_mesh_refiner.cpp	2008-08-25 23:02:57 UTC (rev 2048)
@@ -30,7 +30,7 @@
   //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";
+  const char* ifname = argc > 1 ? argv[1] : "fourVolsBare.cub";
   bool input_is_output = ( argc > 2 && ! strcmp( argv[2], "-new-mesh" ) ) ? false : true;
   MBInterface* imesh = new MBCore( rank, nprocs );
   MBInterface* omesh = input_is_output ? imesh : new MBCore( rank, nprocs );
@@ -41,25 +41,10 @@
   ReadParallel* readpar = new ReadParallel( imesh, ipcomm );
 #endif // USE_MPI
 
-  // Get the global ID tag so we can set things up for resolve_shared_ents
-  //MBTag tag_gid;
-  //imesh->tag_create( PARALLEL_GID_TAG_NAME, sizeof( int ), MB_TAG_DENSE, MB_TYPE_INTEGER, tag_gid, default_gid );
-
-#ifdef USE_MPI
-  // Get tags for the various data-distributed mesh annotations
-  MBTag tag_sproc;
-  MBTag tag_sprocs;
-  MBTag tag_shand;
-  MBTag tag_shands;
-  MBTag tag_pstat;
-  ipcomm->get_shared_proc_tags( tag_sproc, tag_sprocs, tag_shand, tag_shands, tag_pstat );
-  MBTag tag_part = ipcomm->partition_tag();
-#endif // USE_MPI
-
   MBEntityHandle set_handle;
   std::ostringstream parallel_options;
   parallel_options
-    << "PARALLEL=BCAST_DELETE" << ";" // NB: You can also use READ_DELETE here.
+    << "PARALLEL=BCAST_DELETE" << ";" // NB: You can use BCAST_DELETE or READ_DELETE here.
     << "PARTITION=MATERIAL_SET" << ";"
     //<< "PARTITION_DISTRIBUTE" << ";"
     << "PARTITION_VAL=" << ( rank + 1 ) << ";"
@@ -83,6 +68,9 @@
   imesh->load_file( ifname, set_handle, parallel_options.str().c_str() );
   imesh->list_entities( 0, 1 );
 #endif // USE_MPI
+  std::ostringstream ifs;
+  ifs << "prerefiner." << nprocs << "." << rank << ".vtk";
+  imesh->write_mesh( ifs.str().c_str() );
 
   // The refiner will need an implicit function to be used as an indicator function for subdivision:
   MBEdgeSizeSimpleImplicit* eval = new MBEdgeSizeSimpleImplicit();
@@ -96,9 +84,13 @@
   // (We don't add tag_gid to the refiner's tag manager because it is special)
   eref->set_edge_size_evaluator( eval );
   MBRange ents_to_refine;
-  ents_to_refine.insert( set_handle );
+  imesh->get_entities_by_type( set_handle, MBTET, ents_to_refine ); // refine just the tets
+  //ents_to_refine.insert( set_handle ); // refine everything multiple times (because subsets are not disjoint)
   mref->refine( ents_to_refine );
 
+  std::ostringstream ofs;
+  ofs << "refiner." << nprocs << "." << rank << ".vtk";
+  omesh->write_mesh( ofs.str().c_str() );
   // Print out the results, one process at a time
 #ifdef USE_MPI
   for ( int i = 0; i < nprocs; ++ i )




More information about the moab-dev mailing list