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

dcthomp at mcs.anl.gov dcthomp at mcs.anl.gov
Mon Jun 23 20:21:00 CDT 2008


Author: dcthomp
Date: 2008-06-23 20:21:00 -0500 (Mon, 23 Jun 2008)
New Revision: 1918

Added:
   MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
Modified:
   MOAB/trunk/refiner/MBEdgeSizeEvaluator.cpp
   MOAB/trunk/refiner/MBEdgeSizeEvaluator.hpp
   MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.cpp
   MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.hpp
   MOAB/trunk/refiner/MBEntityRefiner.cpp
   MOAB/trunk/refiner/MBEntityRefiner.hpp
   MOAB/trunk/refiner/MBMeshRefiner.cpp
   MOAB/trunk/refiner/MBMeshRefiner.hpp
   MOAB/trunk/refiner/MBRefinerTagManager.hpp
   MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp
   MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp
   MOAB/trunk/refiner/MBSimplexTemplateTagAssigner.cpp
   MOAB/trunk/refiner/MBSimplexTemplateTagAssigner.hpp
   MOAB/trunk/refiner/test_mesh_refiner.cpp
Log:
ENH: Move the output functor to its own file since it
     is a full implementation and not a test implementation.
ENH: First step towards MBMeshRefiner... the refine() method now works
     in serial mode but no parallel GID assignments are made. The test
     harness now uses the mesh refiner instead of directly calling the
     entity refiner.
STYLE: Clean up object management so it is more clear who owns what.


Modified: MOAB/trunk/refiner/MBEdgeSizeEvaluator.cpp
===================================================================
--- MOAB/trunk/refiner/MBEdgeSizeEvaluator.cpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBEdgeSizeEvaluator.cpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -6,9 +6,9 @@
 #include <assert.h>
 
 /// Construct an evaluator.
-MBEdgeSizeEvaluator::MBEdgeSizeEvaluator( MBRefinerTagManager* tag_mgr )
+MBEdgeSizeEvaluator::MBEdgeSizeEvaluator()
 {
-  this->tag_manager = tag_mgr;
+  this->tag_manager = 0;
 }
 
 /// Destruction is virtual so subclasses may clean up after refinement.

Modified: MOAB/trunk/refiner/MBEdgeSizeEvaluator.hpp
===================================================================
--- MOAB/trunk/refiner/MBEdgeSizeEvaluator.hpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBEdgeSizeEvaluator.hpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -31,7 +31,7 @@
 class MB_DLL_EXPORT MBEdgeSizeEvaluator
 {
 public:
-  MBEdgeSizeEvaluator( MBRefinerTagManager* );
+  MBEdgeSizeEvaluator();
   virtual ~MBEdgeSizeEvaluator();
 
   virtual bool evaluate_edge(
@@ -39,6 +39,7 @@
     double* p1, void* t1,
     const double* p2, const void* t2 ) = 0;
 
+  void set_tag_manager( MBRefinerTagManager* tmgr ) { this->tag_manager = tmgr; }
   MBRefinerTagManager* get_tag_manager() { return this->tag_manager; }
 
 protected:

Modified: MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.cpp
===================================================================
--- MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.cpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.cpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -1,7 +1,6 @@
 #include "MBEdgeSizeSimpleImplicit.hpp"
 
-MBEdgeSizeSimpleImplicit::MBEdgeSizeSimpleImplicit( MBRefinerTagManager* tag_mgr )
-  : MBEdgeSizeEvaluator( tag_mgr )
+MBEdgeSizeSimpleImplicit::MBEdgeSizeSimpleImplicit()
 {
   int i;
   // Default to the plane: x = 0.

Modified: MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.hpp
===================================================================
--- MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.hpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBEdgeSizeSimpleImplicit.hpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -36,7 +36,7 @@
 {
 public:
   /// Construct an evaluator.
-  MBEdgeSizeSimpleImplicit( MBRefinerTagManager* );
+  MBEdgeSizeSimpleImplicit();
   /// Destruction is virtual so subclasses may clean up after refinement.
   virtual ~MBEdgeSizeSimpleImplicit();
 

Modified: MOAB/trunk/refiner/MBEntityRefiner.cpp
===================================================================
--- MOAB/trunk/refiner/MBEntityRefiner.cpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBEntityRefiner.cpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -4,9 +4,9 @@
 #include "MBInterface.hpp"
 
 /// Construct an entity refiner.
-MBEntityRefiner::MBEntityRefiner( MBInterface* parentMesh )
+MBEntityRefiner::MBEntityRefiner()
 {  
-  this->mesh = parentMesh;
+  this->mesh_in = 0;
   this->edge_size_evaluator = 0;
   this->output_functor = 0;
   // By default, allow at most one subdivision per edge
@@ -19,10 +19,33 @@
 {
   if ( this->edge_size_evaluator )
     delete this->edge_size_evaluator;
-  if ( this->output_functor )
-    delete this->output_functor;
 }
 
+/**\brief Prepare to start refining entities on a given mesh.
+  * This is called once before refine_entity() is ever invoked.
+  * The tag manager specifies the input and output meshes upon which the refiner will act.
+  *
+  * This function returns false if calling refine_entity() immediately
+  * afterwards would cause a failure (due, for example, to a NULL edge_size_evaluator).
+  * Otherwise it returns true.
+  */
+bool MBEntityRefiner::prepare( MBRefinerTagManager* tmgr, MBEntityRefinerOutputFunctor* ofunc )
+{
+  bool rval = true;
+  if ( this->edge_size_evaluator )
+    {
+    this->edge_size_evaluator->set_tag_manager( tmgr );
+    }
+  else
+    {
+    rval = false;
+    }
+  this->set_output_functor( ofunc );
+  this->mesh_in = tmgr->get_input_mesh();
+  this->update_heap_size();
+  return rval;
+}
+
 /**\fn bool MBEntityRefiner::refine_entity( MBEntityHandle )
   *\brief Method implemented by subclasses to create decompositions of entities using edge subdivisions.
   */
@@ -53,7 +76,6 @@
     delete this->edge_size_evaluator;
     }
   this->edge_size_evaluator = ese;
-  this->update_heap_size();
 
   return true;
 }

Modified: MOAB/trunk/refiner/MBEntityRefiner.hpp
===================================================================
--- MOAB/trunk/refiner/MBEntityRefiner.hpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBEntityRefiner.hpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -65,6 +65,7 @@
 
 class MBInterface;
 class MBEdgeSizeEvaluator;
+class MBRefinerTagManager;
 
 class MB_DLL_EXPORT MBEntityRefinerOutputFunctor
 {
@@ -94,12 +95,11 @@
 class MB_DLL_EXPORT MBEntityRefiner
 {
 public:
-  MBEntityRefiner( MBInterface* );
+  MBEntityRefiner();
   virtual ~MBEntityRefiner();
 
-  MBInterface* get_mesh() { return this->mesh; }
-
-  virtual bool refine_entity( MBEntityHandle ) = 0;
+  virtual bool prepare( MBRefinerTagManager* tmgr, MBEntityRefinerOutputFunctor* ofunc );
+  virtual bool refine_entity( MBEntityType typ, MBEntityHandle ent ) = 0;
   virtual unsigned long get_heap_size_bound( int max_recursions ) const = 0;
 
   virtual bool set_edge_size_evaluator( MBEdgeSizeEvaluator* );
@@ -115,7 +115,7 @@
   int get_maximum_number_of_subdivisions() const { return this->maximum_number_of_subdivisions; }
 
 protected:
-  MBInterface* mesh;
+  MBInterface* mesh_in;
   MBEdgeSizeEvaluator* edge_size_evaluator;
   MBEntityRefinerOutputFunctor* output_functor;
   int minimum_number_of_subdivisions;

Added: MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
===================================================================
--- MOAB/trunk/refiner/MBMeshOutputFunctor.hpp	                        (rev 0)
+++ MOAB/trunk/refiner/MBMeshOutputFunctor.hpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -0,0 +1,204 @@
+#ifndef MB_MESHOUTPUTFUNCTOR_HPP
+#define MB_MESHOUTPUTFUNCTOR_HPP
+
+#include "MBTypes.h"
+#include "MBEntityRefiner.hpp"
+
+#include <iostream>
+#include <map>
+
+template< int _n >
+class MBSplitVertexIndex
+{
+public:
+  MBSplitVertexIndex() { }
+  MBSplitVertexIndex( const MBEntityHandle* 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]; }
+  MBSplitVertexIndex& operator = ( const MBSplitVertexIndex<_n>& src )
+    { for ( int i = 0; i < _n; ++ i ) this->handles[i] = src.handles[i]; return *this; }
+
+  bool operator < ( const MBSplitVertexIndex<_n>& other ) const
+    {
+    for ( int i = 0; i < _n; ++ i )
+      if ( this->handles[i] < other.handles[i] )
+        return true;
+      else if ( this->handles[i] > other.handles[i] )
+        return false;
+    return true;
+    }
+
+  MBEntityHandle handles[_n];
+};
+
+class MBSplitVerticesBase
+{
+public:
+  MBSplitVerticesBase( MBInterface* m )
+    {
+    this->mesh = m;
+    }
+  virtual ~MBSplitVerticesBase() { }
+  virtual bool find_or_create( const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle ) = 0;
+  MBInterface* mesh;
+};
+
+template< int _n >
+class MBSplitVertices : public std::map<MBSplitVertexIndex<_n>,MBEntityHandle>, public MBSplitVerticesBase
+{
+public:
+  typedef std::map<MBSplitVertexIndex<_n>,MBEntityHandle> MapType;
+  typedef typename std::map<MBSplitVertexIndex<_n>,MBEntityHandle>::iterator MapIteratorType;
+
+  MBSplitVertices( MBInterface* m )
+    : MBSplitVerticesBase( m )
+    {
+    }
+  virtual ~MBSplitVertices() { }
+  virtual bool find_or_create( const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle )
+    {
+    MapIteratorType it = this->find( MBSplitVertexIndex<_n>( split_src ) );
+    if ( it == this->end() )
+      {
+      if ( this->mesh->create_vertex( coords, vert_handle ) != MB_SUCCESS )
+        {
+        return false;
+        }
+      return true;
+      }
+    vert_handle = it->second;
+    return false;
+    }
+};
+
+class MBMeshOutputFunctor : public MBEntityRefinerOutputFunctor
+{
+public:
+  MBInterface* mesh;
+  bool input_is_output;
+  std::vector<MBSplitVerticesBase*> split_vertices;
+  std::vector<MBEntityHandle> elem_vert;
+  MBRefinerTagManager* tag_manager;
+  MBEntityHandle destination_set;
+
+  MBMeshOutputFunctor( MBRefinerTagManager* tag_mgr )
+    {
+    this->mesh = tag_mgr->get_output_mesh();
+    this->input_is_output = ( tag_mgr->get_input_mesh() == this->mesh );
+    this->tag_manager = tag_mgr;
+    this->destination_set = 0; // don't place output entities in a set by default.
+
+    this->split_vertices.resize( 4 );
+    this->split_vertices[0] = 0; // Vertices (0-faces) cannot be split
+    this->split_vertices[1] = new MBSplitVertices<1>( this->mesh );
+    this->split_vertices[2] = new MBSplitVertices<2>( this->mesh );
+    this->split_vertices[3] = new MBSplitVertices<3>( this->mesh );
+    }
+
+  ~MBMeshOutputFunctor()
+    {
+    for ( int i = 0; i < 4; ++ i )
+      delete this->split_vertices[i];
+    }
+
+  void print_vert_crud( MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags )
+    {
+    std::cout << "+ {";
+    for ( int i = 0; i < nvhash; ++ i )
+      std::cout << " " << vhash[i];
+    std::cout << " } -> " << vout << " ";
+
+    std::cout << "[ " << vcoords[0];
+    for ( int i = 1; i < 6; ++i )
+      std::cout << ", " << vcoords[i];
+    std::cout << " ] ";
+
+    double* x = (double*)vtags;
+    int* m = (int*)( (char*)vtags + 2 * sizeof( double ) );
+    std::cout << "< " << x[0]
+              << ", " << x[1];
+    for ( int i = 0; i < 4; ++i )
+      std::cout << ", " << m[i];
+    std::cout << " >\n";
+    }
+
+  void assign_tags( MBEntityHandle vhandle, const void* vtags )
+    {
+    if ( ! vhandle )
+      return; // Ignore bad vertices
+
+    int num_tags = this->tag_manager->get_number_of_vertex_tags();
+    MBTag tag_handle;
+    int tag_offset;
+    for ( int i = 0; i < num_tags; ++i )
+      {
+      this->tag_manager->get_output_vertex_tag( i, tag_handle, tag_offset );
+      this->mesh->tag_set_data( tag_handle, &vhandle, 1, vtags );
+      }
+    }
+
+  virtual MBEntityHandle operator () ( MBEntityHandle vhash, const double* vcoords, const void* vtags )
+    {
+    if ( this->input_is_output )
+      { // Don't copy the original vertex!
+      this->print_vert_crud( vhash, 1, &vhash, vcoords, vtags );
+      return vhash;
+      }
+    MBEntityHandle vertex_handle;
+    if ( this->mesh->create_vertex( vcoords + 3, vertex_handle ) != MB_SUCCESS )
+      {
+      std::cerr << "Could not insert mid-edge vertex!\n";
+      }
+    this->assign_tags( vertex_handle, vtags );
+    this->print_vert_crud( vertex_handle, 1, &vhash, vcoords, vtags );
+    return vertex_handle;
+    }
+
+  virtual MBEntityHandle operator () ( int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags )
+    {
+    MBEntityHandle vertex_handle;
+    if ( nvhash == 1 )
+      {
+      vertex_handle = (*this)( *vhash, vcoords, vtags );
+      }
+    else if ( nvhash < 4 )
+      {
+      bool newly_created = this->split_vertices[nvhash]->find_or_create( vhash, vcoords, vertex_handle );
+      if ( newly_created )
+        {
+        this->assign_tags( vertex_handle, vtags );
+        }
+      if ( ! vertex_handle )
+        {
+        std::cerr << "Could not insert mid-edge vertex!\n";
+        }
+      this->print_vert_crud( vertex_handle, nvhash, vhash, vcoords, vtags );
+      }
+    else
+      {
+      vertex_handle = 0;
+      std::cerr << "Not handling splits on faces with " << nvhash << " corners yet.\n";
+      }
+    return vertex_handle;
+    }
+
+  virtual void operator () ( MBEntityHandle h )
+    {
+    std::cout << h << " ";
+    this->elem_vert.push_back( h );
+    }
+
+  virtual void operator () ( MBEntityType etyp )
+    {
+    MBEntityHandle elem_handle;
+    if ( this->mesh->create_element( etyp, &this->elem_vert[0], this->elem_vert.size(), elem_handle ) == MB_FAILURE )
+      {
+      std::cerr << " *** ";
+      }
+    this->elem_vert.clear();
+    std::cout << "---------> " << elem_handle << " ( " << etyp << " )\n\n";
+    }
+};
+
+#endif // MB_MESHOUTPUTFUNCTOR_HPP

Modified: MOAB/trunk/refiner/MBMeshRefiner.cpp
===================================================================
--- MOAB/trunk/refiner/MBMeshRefiner.cpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBMeshRefiner.cpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -3,189 +3,129 @@
 #include "MBEdgeSizeEvaluator.hpp"
 #include "MBEntityRefiner.hpp"
 #include "MBInterface.hpp"
+#include "MBRefinerTagManager.hpp"
+#include "MBMeshOutputFunctor.hpp"
 
 #ifdef USE_MPI
+#include "MBParallelComm.hpp"
 #include <mpi.h>
 #else // USE_MPI
 typedef int MPI_Comm;
 #endif // USE_MPI
 
-#include <map>
-
-class MBRefinerPartition;
-
-struct MBEdgeIndex
-{
-  MBEntityHandle corners[2];
-};
-
-struct MBFaceIndex
-{
-  MBEntityHandle corners[3];
-};
-
-/// A record of data to be sent to and received from a remote process in order to merge a refined mesh.
-class MBRefinerPartition
-{
-public:
-  /// Rank of the local process
-  int local_process;
-  /// Rank of the remote process to which this data belongs.
-  int remote_process;
-  /// A list of locally-owned vertices that are shared with the remote process associated with this object
-  std::vector<MBEntityHandle> vertex_list_local;
-  /// A list of remotely-owned vertices that are shared with the remote process associated with this object
-  std::vector<MBEntityHandle> vertex_list_remote;
-  /// A list of locally-owned global vertex IDs that are shared with the remote process associated with this object
-  std::vector<int> global_ids_local;
-  /// A list of remotely-owned global vertex IDs that are shared with the remote process associated with this object
-  std::vector<int> global_ids_remote;
-  /// Queue asynchronous sends and receives to merge data. You are responsible for calling MPI_Barrier() afterwards.
-  void queue_merge( MPI_Comm communicator )
-    {
-#ifdef USE_MPI
-    MPI_Request rq;
-    int sz;
-    sz = this->vertex_list_local.size();
-    if ( sz )
-      {
-      MPI_Isend( (void*)&global_ids_local[0], sz, MB_MPI_ENTITY_HANDLE_TYPE,
-        this->remote, this->local_rank, communicator, 0 /*request*/ );
-      }
-    sz = this->vertex_list_remote.size();
-    if ( sz )
-      {
-      MPI_Irecv( (void*)&global_ids_remote[0], sz, MB_MPI_ENTITY_HANDLE_TYPE,
-        this->remote, this->local_rank, communicator, 0 /*request*/ );
-      }
-#endif // USE_MPI
-    }
-  /// Perform the merge using the data. You must have called queue_merge() followed by MPI_Barrier() previous to this function.
-  void perform_merge()
-    {
-    // Now the remote global IDs have been properly transferred from the remote process... assign them to the vertices
-
-    }
-};
-
-class MBMeshRefinerOutputFunctor : public MBEntityRefinerOutputFunctor
-{
-public:
-  /// Mesh to hold output (may/may not be same as input mesh)
-  MBInterface* mesh;
-  /// Edge size evaluator is required because it has a list of output tags
-  MBEdgeSizeEvaluator* edge_size_evaluator;
-  /// Hash table of newly-created vertices at edge midpoints
-  std::map<MBEdgeIndex, MBEntityHandle> edge_vertices;
-  /// Hash table of newly-created vertices interior to triangle faces
-  std::map<MBFaceIndex, MBEntityHandle> face_vertices;
-  /// Storage allocated for interprocess communication of vertex global IDs
-  std::map<int,MBRefinerPartition*> partitions;
-  /// Number of tags defined on vertices
-  int num_tags;
-  /// The accumulated vertices that are used to create a new element when complete.
-  std::vector<MBEntityHandle> vertex_accum;
-  /**\brief True if the output mesh (this->mesh) is also the input mesh.
-    *
-    * This indicates whether pre-existing vertices should be inserted into the new mesh or not.
-    */
-  bool output_is_input;
-
-  MBMeshRefinerOutputFunctor( MBInterface* m, bool oii, MBEdgeSizeEvaluator* es )
-    {
-    this->mesh = m;
-    this->output_is_input = oii;
-    this->edge_size_evaluator = es;
-    }
-  virtual ~MBMeshRefinerOutputFunctor() { }
-  /// Insert a new vertex into the mesh and set its tag values. This has no effect when output_is_input is true.
-  virtual MBEntityHandle operator () ( MBEntityHandle hash, const double* vcoords, const void* vtags )
-    {
-    if ( this->output_is_input )
-      {
-      // Don't insert vertices that already exist in the output
-      return hash;
-      }
-
-    MBEntityHandle vertex_handle;
-    this->mesh->create_vertex( vcoords + 3, vertex_handle );
-    MBTag tag_handle;
-    int tag_offset;
-    for ( int i = 0; i < num_tags; ++i )
-      {
-      this->edge_size_evaluator->get_tag_manager()->get_output_vertex_tag( i, tag_handle, tag_offset );
-      this->mesh->tag_set_data( tag_handle, &vertex_handle, 1, (char*)vtags + tag_offset );
-      }
-    return vertex_handle;
-    }
-  /// Insert a new n-way hashed vertex into the mesh and set its tag values.
-  virtual MBEntityHandle operator () ( int nhash, MBEntityHandle* hash, const double* vcoords, const void* vtags )
-    {
-    // First, see if we've already created this vertex
-    MBEntityHandle hv;
-    if ( this->find_hashed_vertex( hv, nhash, hash ) )
-      {
-      return hv;
-      }
-
-    this->mesh->create_vertex( vcoords + 3, hv );
-    MBTag tag_handle;
-    int tag_offset;
-    for ( int i = 0; i < num_tags; ++i )
-      {
-      this->edge_size_evaluator->get_tag_manager()->get_output_vertex_tag( i, tag_handle, tag_offset );
-      this->mesh->tag_set_data( tag_handle, &hv, 1, (char*)vtags + tag_offset );
-      }
-    return hv;
-    }
-  /// Accumulate a vertex for use in the connectivity record of an element.
-  virtual void operator () ( MBEntityHandle hash )
-    {
-    this->vertex_accum.push_back( hash );
-    }
-  /// Create an element from all the accumulated vertices since the last element was created.
-  virtual void operator () ( MBEntityType etyp )
-    {
-    if ( ! this->vertex_accum.size() )
-      return; // Ignore creation of vertex-less entities
-
-    MBEntityHandle elem_handle;
-    this->mesh->create_element( etyp, &this->vertex_accum[0], this->vertex_accum.size(), elem_handle );
-    this->vertex_accum.clear();
-    }
-  bool find_hashed_vertex( MBEntityHandle& vout, int nhash, MBEntityHandle* hash )
-    {
-    return false;
-    }
-  void hash_vertex( MBEntityHandle vout, int nhash, MBEntityHandle* hash )
-    {
-    }
-};
-
-MBMeshRefiner::MBMeshRefiner( MBInterface* parent_mesh )
+/**\brief Construct a mesh refiner.
+  * The input and output mesh pointers may be identical.
+  * Existing elements will <b>not</b> be removed from the input mesh
+  * as they are refined, so the adjacencies for entitities may appear
+  * strange after refinement.
+  */
+MBMeshRefiner::MBMeshRefiner( MBInterface* imesh, MBInterface* omesh )
 {  
-  this->mesh = parent_mesh;
+  this->mesh_in = imesh;
+  this->mesh_out = omesh;
+  this->tag_manager = new MBRefinerTagManager( this->mesh_in, this->mesh_out );
+  this->output_functor = new MBMeshOutputFunctor( this->tag_manager );
   this->entity_refiner = 0;
+  this->comm = 0;
 }
 
+/**\brief Destroy a mesh refiner.
+  *
+  * Note that any MBEntityRefiner object associated with the mesh refiner will be deleted inside this destructor.
+  * Destruction is virtual so subclasses may clean up after refinement.
+  */
 MBMeshRefiner::~MBMeshRefiner()
 {
+  delete this->tag_manager;
+  delete this->output_functor;
   if ( this->entity_refiner )
     delete this->entity_refiner;
 }
 
+/**\brief Specify which techniqe will be used to refine entities in the mesh.
+  * The entity refiner object you specify is ``owned'' by the mesh refiner after this call;
+  * the entity refiner will be deleted when this mesh refiner is destroyed.
+  * You should not delete the entity refiner yourself.
+  */
 bool MBMeshRefiner::set_entity_refiner( MBEntityRefiner* er )
 {
   if ( ! er || er == this->entity_refiner )
     return false;
 
   this->entity_refiner = er;
-
   return true;
 }
 
-bool MBMeshRefiner::refine_mesh()
+/**\brief A convenience method to reset the list of tags to be copied to output vertices.
+  * This simply calls the method of the same name on the tag manager.
+  */
+void MBMeshRefiner::reset_vertex_tags()
 {
-  return false;
+  this->tag_manager->reset_vertex_tags();
 }
 
+/**\brief A convenience method to add a tag to be copied/interpolated from input vertices to output vertices.
+  * This simply calls the method of the same name on the tag manager.
+  */
+int MBMeshRefiner::add_vertex_tag( MBTag tag_handle )
+{
+  return this->tag_manager->add_vertex_tag( tag_handle );
+}
+
+struct MBMeshRefinerIterator {
+  MBRange subset;
+  MBEntityHandle destination_set;
+};
+
+/**\brief Refine entities in a mesh set.
+  * This will recursively descend any mesh sets contained in the \a range.
+  * It returns false when not able to refine (because no entity refiner is
+  * set or no edge size evaluator has been set on the entity refiner) and
+  * true otherwise.
+  */
+bool MBMeshRefiner::refine( MBRange& range )
+{
+  this->tag_manager->create_output_tags();
+  if ( ! this->entity_refiner->prepare( this->tag_manager, this->output_functor ) )
+    { // Oops, perhaps the edge_size_evaluator was not set?
+    return false;
+    }
+
+  MBMeshRefinerIterator entry;
+  std::vector<MBMeshRefinerIterator> work;
+
+  entry.subset = range;
+  entry.destination_set = 0;
+  work.push_back( entry );
+
+  while ( ! work.empty() )
+    {
+    entry = work.back();
+    work.pop_back();
+    this->output_functor->destination_set = entry.destination_set;
+    for ( MBRange::const_iterator it = entry.subset.begin(); it != entry.subset.end(); ++ it )
+      {
+      MBEntityType etyp = this->mesh_in->type_from_handle( *it );
+      if ( etyp == MBENTITYSET )
+        {
+        MBRange set_ents;
+        if ( this->mesh_in->get_entities_by_handle( *it, set_ents, false ) == MB_SUCCESS )
+          {
+          MBMeshRefinerIterator set_work;
+          unsigned int set_work_opts;
+          this->mesh_in->get_meshset_options( *it, set_work_opts );
+          this->mesh_out->create_meshset( set_work_opts, set_work.destination_set );
+          set_work.subset = set_ents;
+          work.push_back( set_work );
+          }
+        }
+      else
+        {
+        this->entity_refiner->refine_entity( etyp, *it );
+        }
+      }
+    }
+
+  return true;
+}
+

Modified: MOAB/trunk/refiner/MBMeshRefiner.hpp
===================================================================
--- MOAB/trunk/refiner/MBMeshRefiner.hpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBMeshRefiner.hpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -26,28 +26,42 @@
 #define MB_MESHREFINER_H
 
 #include "MBTypes.h" // for MB_DLL_EXPORT
+#include "MBRange.hpp"
 
 #include <vector>
 
 class MBInterface;
 class MBEntityRefiner;
+class MBParallelComm;
+class MBRefinerTagManager;
+class MBMeshOutputFunctor;
 
 class MB_DLL_EXPORT MBMeshRefiner
 {
 public:
-  /// Construct a mesh refiner.
-  MBMeshRefiner( MBInterface* );
-  /// Destruction is virtual so subclasses may clean up after refinement.
+  MBMeshRefiner( MBInterface* imesh, MBInterface* omesh );
   virtual ~MBMeshRefiner();
 
-  virtual bool refine_mesh();
-
   bool set_entity_refiner( MBEntityRefiner* );
-  MBEntityRefiner* get_entity_refiner() { return this->entity_refiner; };
+  MBEntityRefiner* get_entity_refiner() { return this->entity_refiner; }
 
+  bool set_comm( MBParallelComm* c ) { if ( ! c || this->comm == c ) return false; this->comm = c; return true; }
+  MBParallelComm* get_comm() { return this->comm; }
+
+  MBRefinerTagManager* get_tag_manager() { return this->tag_manager; }
+  const MBRefinerTagManager* get_tag_manager() const { return this->tag_manager; }
+  void reset_vertex_tags();
+  int add_vertex_tag( MBTag tag_handle );
+
+  virtual bool refine( MBRange& );
+
 protected:
-  MBInterface* mesh;
+  MBInterface* mesh_in;
+  MBInterface* mesh_out;
   MBEntityRefiner* entity_refiner;
+  MBRefinerTagManager* tag_manager;
+  MBMeshOutputFunctor* output_functor;
+  MBParallelComm* comm;
 };
 
 #endif // MB_MESHREFINER_H

Modified: MOAB/trunk/refiner/MBRefinerTagManager.hpp
===================================================================
--- MOAB/trunk/refiner/MBRefinerTagManager.hpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBRefinerTagManager.hpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -48,6 +48,9 @@
   void get_input_vertex_tag( int i, MBTag& tag, int& byte_offset );
   void get_output_vertex_tag( int i, MBTag& tag, int& byte_offset );
 
+  MBInterface* get_input_mesh() { return this->input_mesh; }
+  MBInterface* get_output_mesh() { return this->output_mesh; }
+
 protected:
   std::vector< std::pair< MBTag, int > > input_vertex_tags;
   std::vector< std::pair< MBTag, int > > output_vertex_tags;

Modified: MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp
===================================================================
--- MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -23,8 +23,7 @@
 #endif // MB_DEBUG_TESSELLATOR
 
 /// Construct a template refiner.
-MBSimplexTemplateRefiner::MBSimplexTemplateRefiner( MBInterface* mesh )
-  : MBEntityRefiner( mesh )
+MBSimplexTemplateRefiner::MBSimplexTemplateRefiner()
 {
   this->tag_manager = 0;
   this->tag_assigner = new MBSimplexTemplateTagAssigner( this );
@@ -41,13 +40,14 @@
 
 /**\brief Stream a single mesh entity through the refiner.
   */
-bool MBSimplexTemplateRefiner::refine_entity( MBEntityHandle entity )
+bool MBSimplexTemplateRefiner::refine_entity( MBEntityType etyp, MBEntityHandle entity )
 {
   this->reset_heap_pointers();
   bool rval = true;
   const MBEntityHandle* conn;
   int num_nodes;
-  if ( this->mesh->get_connectivity( entity, conn, num_nodes ) != MB_SUCCESS )
+  MBInterface* imesh = this->tag_manager->get_input_mesh();
+  if ( imesh->get_connectivity( entity, conn, num_nodes ) != MB_SUCCESS )
     {
     return false;
     }
@@ -55,7 +55,6 @@
   this->corner_tags.resize( num_nodes );
   this->corner_handles.resize( num_nodes );
 
-  MBEntityType etyp = this->mesh->type_from_handle( entity );
   // Have to make num_nodes calls to get_coords() because we need xyz interleaved with rst coords.
   MBTag tag_handle;
   int tag_offset;
@@ -63,7 +62,7 @@
   for ( int n = 0; n < num_nodes; ++ n )
     {
     this->corner_handles[n] = conn[n];
-    if ( this->mesh->get_coords( &conn[n], 1, &corner_coords[6 * n + 3] ) != MB_SUCCESS )
+    if ( imesh->get_coords( &conn[n], 1, &corner_coords[6 * n + 3] ) != MB_SUCCESS )
       {
       return false;
       }
@@ -71,7 +70,7 @@
     for ( int i = 0; i < this->tag_manager->get_number_of_vertex_tags(); ++ i )
       {
       this->tag_manager->get_input_vertex_tag( i, tag_handle, tag_offset );
-      if ( this->mesh->tag_get_data( tag_handle, &conn[n], 1, (char*)tag_data + tag_offset ) != MB_SUCCESS )
+      if ( imesh->tag_get_data( tag_handle, &conn[n], 1, (char*)tag_data + tag_offset ) != MB_SUCCESS )
         {
         return false;
         }
@@ -161,22 +160,18 @@
     return false;
 
   this->tag_assigner = ta; 
-  this->tag_assigner->set_edge_size_evaluator( this->edge_size_evaluator );
   return true;
 }
 
 
 /**\brief Set the function object used to decide whether an edge is subdivided or not.
   */
-bool MBSimplexTemplateRefiner::set_edge_size_evaluator( MBEdgeSizeEvaluator* es ) 
+bool MBSimplexTemplateRefiner::prepare( MBRefinerTagManager* tmgr, MBEntityRefinerOutputFunctor* ofunc )
 { 
-  if ( this->MBEntityRefiner::set_edge_size_evaluator( es ) )
-    {
-    this->tag_assigner->set_edge_size_evaluator( es );
-    this->tag_manager = this->edge_size_evaluator->get_tag_manager();
-    return true;
-    }
-  return false;
+  this->tag_manager = tmgr;
+  this->tag_assigner->set_tag_manager( tmgr );
+  //this->tag_assigner->set_edge_size_evaluator( this->edge_size_evaluator );
+  return this->MBEntityRefiner::prepare( tmgr, ofunc );
 }
 
 /**\fn unsigned long MBSimplexTemplateRefiner::get_heap_size_bound( int max_recursions ) const

Modified: MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp
===================================================================
--- MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -39,16 +39,16 @@
 class MB_DLL_EXPORT MBSimplexTemplateRefiner : public MBEntityRefiner
 {
 public:
-  MBSimplexTemplateRefiner( MBInterface* mesh );
+  MBSimplexTemplateRefiner();
   virtual ~MBSimplexTemplateRefiner();
 
-  virtual bool refine_entity( MBEntityHandle entity );
+  virtual bool refine_entity( MBEntityType etyp, MBEntityHandle entity );
   virtual unsigned long get_heap_size_bound( int max_recursions ) const { return 48 * 4 * ( 1 << max_recursions ) + 8; }
 
   virtual bool set_tag_assigner( MBSimplexTemplateTagAssigner* ta );
   MBSimplexTemplateTagAssigner* get_tag_assigner() const { return this->tag_assigner; }
 
-  virtual bool set_edge_size_evaluator( MBEdgeSizeEvaluator* );
+  virtual bool prepare( MBRefinerTagManager* tmgr, MBEntityRefinerOutputFunctor* ofunc );
 
 protected:
   MBSimplexTemplateTagAssigner* tag_assigner;

Modified: MOAB/trunk/refiner/MBSimplexTemplateTagAssigner.cpp
===================================================================
--- MOAB/trunk/refiner/MBSimplexTemplateTagAssigner.cpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBSimplexTemplateTagAssigner.cpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -2,6 +2,7 @@
 
 #include "MBEdgeSizeEvaluator.hpp"
 #include "MBInterface.hpp"
+#include "MBRefinerTagManager.hpp"
 #include "MBSimplexTemplateRefiner.hpp"
 
 #include <vector>
@@ -14,10 +15,7 @@
 MBSimplexTemplateTagAssigner::MBSimplexTemplateTagAssigner( MBSimplexTemplateRefiner* r )
 {
   this->mesh_refiner = r;
-  this->edge_size_evaluator = r->get_edge_size_evaluator();
   this->tag_manager = 0;
-  if ( this->edge_size_evaluator )
-    this->tag_manager = this->edge_size_evaluator->get_tag_manager();
 }
 
 /// Empty destructor for good form.
@@ -65,8 +63,8 @@
   for ( int i = 0; i < num_tags; ++i )
     {
     this->tag_manager->get_input_vertex_tag( i, tag_handle, tag_offset );
-    this->mesh_refiner->get_mesh()->tag_get_data_type( tag_handle, data_type );
-    this->mesh_refiner->get_mesh()->tag_get_size( tag_handle, tag_size );
+    this->tag_manager->get_input_mesh()->tag_get_data_type( tag_handle, data_type );
+    this->tag_manager->get_input_mesh()->tag_get_size( tag_handle, tag_size );
     
     switch ( data_type )
       {
@@ -98,9 +96,8 @@
   (void)tp;
 }
 
-void MBSimplexTemplateTagAssigner::set_edge_size_evaluator( MBEdgeSizeEvaluator* es )
+void MBSimplexTemplateTagAssigner::set_tag_manager( MBRefinerTagManager* tmgr )
 {
-  this->edge_size_evaluator = es;
-  this->tag_manager = es ? es->get_tag_manager() : 0;
+  this->tag_manager = tmgr;
 }
 

Modified: MOAB/trunk/refiner/MBSimplexTemplateTagAssigner.hpp
===================================================================
--- MOAB/trunk/refiner/MBSimplexTemplateTagAssigner.hpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/MBSimplexTemplateTagAssigner.hpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -29,7 +29,6 @@
 
 #include "MBTypes.h" // for MB_DLL_EXPORT
 
-class MBEdgeSizeEvaluator;
 class MBRefinerTagManager;
 class MBSimplexTemplateRefiner;
 
@@ -46,11 +45,10 @@
                              const void* t1,
                              const void* t2,
                              void* tp );
-  virtual void set_edge_size_evaluator( MBEdgeSizeEvaluator* es );
+  virtual void set_tag_manager( MBRefinerTagManager* tmgr );
 
 protected:
   MBSimplexTemplateRefiner* mesh_refiner;
-  MBEdgeSizeEvaluator* edge_size_evaluator;
   MBRefinerTagManager* tag_manager;
 };
 

Modified: MOAB/trunk/refiner/test_mesh_refiner.cpp
===================================================================
--- MOAB/trunk/refiner/test_mesh_refiner.cpp	2008-06-23 22:38:27 UTC (rev 1917)
+++ MOAB/trunk/refiner/test_mesh_refiner.cpp	2008-06-24 01:21:00 UTC (rev 1918)
@@ -1,6 +1,7 @@
 #include "MBCore.hpp"
 #include "MBEdgeSizeSimpleImplicit.hpp"
 #include "MBSimplexTemplateRefiner.hpp"
+#include "MBMeshRefiner.hpp"
 #include "MBInterface.hpp"
 #include "MBParallelConventions.h"
 
@@ -12,202 +13,6 @@
 #include <iostream>
 #include <map>
 
-// ============== The actual test code starts around line 211 ===============
-// === The code below is used to print debug info as the refiner operates ===
-
-template< int _n >
-class MBSplitVertexIndex
-{
-public:
-  MBSplitVertexIndex() { }
-  MBSplitVertexIndex( const MBEntityHandle* 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]; }
-  MBSplitVertexIndex& operator = ( const MBSplitVertexIndex<_n>& src )
-    { for ( int i = 0; i < _n; ++ i ) this->handles[i] = src.handles[i]; return *this; }
-
-  bool operator < ( const MBSplitVertexIndex<_n>& other ) const
-    {
-    for ( int i = 0; i < _n; ++ i )
-      if ( this->handles[i] < other.handles[i] )
-        return true;
-      else if ( this->handles[i] > other.handles[i] )
-        return false;
-    return true;
-    }
-
-  MBEntityHandle handles[_n];
-};
-
-class MBSplitVerticesBase
-{
-public:
-  MBSplitVerticesBase( MBInterface* m )
-    {
-    this->mesh = m;
-    }
-  virtual ~MBSplitVerticesBase() { }
-  virtual bool find_or_create( const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle ) = 0;
-  MBInterface* mesh;
-};
-
-template< int _n >
-class MBSplitVertices : public std::map<MBSplitVertexIndex<_n>,MBEntityHandle>, public MBSplitVerticesBase
-{
-public:
-  typedef std::map<MBSplitVertexIndex<_n>,MBEntityHandle> MapType;
-  typedef typename std::map<MBSplitVertexIndex<_n>,MBEntityHandle>::iterator MapIteratorType;
-
-  MBSplitVertices( MBInterface* m )
-    : MBSplitVerticesBase( m )
-    {
-    }
-  virtual ~MBSplitVertices() { }
-  virtual bool find_or_create( const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle )
-    {
-    MapIteratorType it = this->find( MBSplitVertexIndex<_n>( split_src ) );
-    if ( it == this->end() )
-      {
-      if ( this->mesh->create_vertex( coords, vert_handle ) != MB_SUCCESS )
-        {
-        return false;
-        }
-      return true;
-      }
-    vert_handle = it->second;
-    return false;
-    }
-};
-
-
-class MBTestOutputFunctor : public MBEntityRefinerOutputFunctor
-{
-public:
-  MBInterface* mesh;
-  bool input_is_output;
-  std::vector<MBSplitVerticesBase*> split_vertices;
-  std::vector<MBEntityHandle> elem_vert;
-  MBRefinerTagManager* tag_manager;
-
-  MBTestOutputFunctor( MBInterface* imesh, MBInterface* omesh, MBRefinerTagManager* tag_mgr )
-    {
-    this->mesh = omesh;
-    this->input_is_output = ( imesh == omesh );
-    this->tag_manager = tag_mgr;
-
-    this->split_vertices.resize( 4 );
-    this->split_vertices[0] = 0; // Vertices (0-faces) cannot be split
-    this->split_vertices[1] = new MBSplitVertices<1>( this->mesh );
-    this->split_vertices[2] = new MBSplitVertices<2>( this->mesh );
-    this->split_vertices[3] = new MBSplitVertices<3>( this->mesh );
-    }
-
-  ~MBTestOutputFunctor()
-    {
-    for ( int i = 0; i < 4; ++ i )
-      delete this->split_vertices[i];
-    }
-
-  void print_vert_crud( MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags )
-    {
-    std::cout << "+ {";
-    for ( int i = 0; i < nvhash; ++ i )
-      std::cout << " " << vhash[i];
-    std::cout << " } -> " << vout << " ";
-
-    std::cout << "[ " << vcoords[0];
-    for ( int i = 1; i < 6; ++i )
-      std::cout << ", " << vcoords[i];
-    std::cout << " ] ";
-
-    double* x = (double*)vtags;
-    int* m = (int*)( (char*)vtags + 2 * sizeof( double ) );
-    std::cout << "< " << x[0]
-              << ", " << x[1];
-    for ( int i = 0; i < 4; ++i )
-      std::cout << ", " << m[i];
-    std::cout << " >\n";
-    }
-
-  void assign_tags( MBEntityHandle vhandle, const void* vtags )
-    {
-    if ( ! vhandle )
-      return; // Ignore bad vertices
-
-    int num_tags = this->tag_manager->get_number_of_vertex_tags();
-    MBTag tag_handle;
-    int tag_offset;
-    for ( int i = 0; i < num_tags; ++i )
-      {
-      this->tag_manager->get_output_vertex_tag( i, tag_handle, tag_offset );
-      this->mesh->tag_set_data( tag_handle, &vhandle, 1, vtags );
-      }
-    }
-
-  virtual MBEntityHandle operator () ( MBEntityHandle vhash, const double* vcoords, const void* vtags )
-    {
-    if ( this->input_is_output )
-      { // Don't copy the original vertex!
-      this->print_vert_crud( vhash, 1, &vhash, vcoords, vtags );
-      return vhash;
-      }
-    MBEntityHandle vertex_handle;
-    if ( this->mesh->create_vertex( vcoords + 3, vertex_handle ) != MB_SUCCESS )
-      {
-      std::cerr << "Could not insert mid-edge vertex!\n";
-      }
-    this->assign_tags( vertex_handle, vtags );
-    this->print_vert_crud( vertex_handle, 1, &vhash, vcoords, vtags );
-    return vertex_handle;
-    }
-
-  virtual MBEntityHandle operator () ( int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags )
-    {
-    MBEntityHandle vertex_handle;
-    if ( nvhash == 1 )
-      {
-      vertex_handle = (*this)( *vhash, vcoords, vtags );
-      }
-    else if ( nvhash < 4 )
-      {
-      bool newly_created = this->split_vertices[nvhash]->find_or_create( vhash, vcoords, vertex_handle );
-      if ( newly_created )
-        {
-        this->assign_tags( vertex_handle, vtags );
-        }
-      if ( ! vertex_handle )
-        {
-        std::cerr << "Could not insert mid-edge vertex!\n";
-        }
-      this->print_vert_crud( vertex_handle, nvhash, vhash, vcoords, vtags );
-      }
-    else
-      {
-      vertex_handle = 0;
-      std::cerr << "Not handling splits on faces with " << nvhash << " corners yet.\n";
-      }
-    return vertex_handle;
-    }
-
-  virtual void operator () ( MBEntityHandle h )
-    {
-    std::cout << h << " ";
-    this->elem_vert.push_back( h );
-    }
-
-  virtual void operator () ( MBEntityType etyp )
-    {
-    MBEntityHandle elem_handle;
-    if ( this->mesh->create_element( etyp, &this->elem_vert[0], this->elem_vert.size(), elem_handle ) == MB_FAILURE )
-      {
-      std::cerr << " *** ";
-      }
-    this->elem_vert.clear();
-    std::cout << "---------> " << elem_handle << " ( " << etyp << " )\n\n";
-    }
-};
-
 int TestMeshRefiner( int argc, char* argv[] )
 {
   int nprocs, rank;
@@ -238,11 +43,8 @@
     }
 #endif // USE_MPI
 
-  // The refiner will need
-  // ... something to manage tag values on new simplices:
-  MBRefinerTagManager* tmgr = new MBRefinerTagManager( imesh, omesh );
-  // ... and an implicit function to be used as an indicator function for subdivision:
-  MBEdgeSizeSimpleImplicit* eval = new MBEdgeSizeSimpleImplicit( tmgr );
+  // The refiner will need an implicit function to be used as an indicator function for subdivision:
+  MBEdgeSizeSimpleImplicit* eval = new MBEdgeSizeSimpleImplicit();
   eval->set_ratio( 2. );
 #ifdef USE_MPI
   // Use an MBParallelComm object to help set up the input mesh
@@ -368,13 +170,8 @@
 
   // Set tag values on vertices
   imesh->tag_set_data( tag_floatular, node_handles, 4, fptrs, 0 );
-  tmgr->add_vertex_tag( tag_floatular );
-
   imesh->tag_set_data( tag_intular, node_handles, 4, iptrs, 0 );
-  tmgr->add_vertex_tag( tag_intular );
-
   imesh->tag_set_data( tag_gid, node_handles, 4, gptrs, 0 );
-  // (We don't add this tag to the refiner's tag manager because it is special)
 
   // Create a tetrahedron from the vertices
   imesh->create_element( MBTET, node_handles, 4, tet_handle );
@@ -402,7 +199,7 @@
 
   // Resolve shared entities (we really only care about vertices but
   // ipcomm.resolve_shared_ents( 0, 0 ) doesn't mark anything up.
-  ipcomm.resolve_shared_ents( 3, 2 );
+  ipcomm.resolve_shared_ents( 3, 0 );
   //ipcomm.resolve_shared_ents( 0, 0 );
   //ipcomm.resolve_shared_ents( 3, 3 );
 
@@ -423,12 +220,16 @@
 #endif // USE_MPI
 
   // Refine the mesh
-  MBSimplexTemplateRefiner eref( imesh );
-  MBTestOutputFunctor* ofunc = new MBTestOutputFunctor( imesh, omesh, tmgr );
-  eref.set_edge_size_evaluator( eval );
-  eref.set_output_functor( ofunc );
-  tmgr->create_output_tags();
-  eref.refine_entity( tet_handle );
+  MBMeshRefiner* mref = new MBMeshRefiner( imesh, omesh );
+  MBSimplexTemplateRefiner* eref = new MBSimplexTemplateRefiner;
+  mref->set_entity_refiner( eref );
+  mref->add_vertex_tag( tag_floatular );
+  mref->add_vertex_tag( tag_intular );
+  // (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 );
+  mref->refine( ents_to_refine );
 
   // Print out the results, one process at a time
 #ifdef USE_MPI
@@ -448,9 +249,10 @@
 #endif // USE_MPI
 
   // Clean up
-  if ( ! ofunc->input_is_output )
-    delete ofunc->mesh;
+  if ( omesh != imesh )
+    delete omesh;
   delete imesh;
+  delete mref; // mref will delete eref
 
 #ifdef USE_MPI
   err = MPI_Barrier( MPI_COMM_WORLD );




More information about the moab-dev mailing list