[MOAB-dev] r2051 - MOAB/trunk/refiner
dcthomp at mcs.anl.gov
dcthomp at mcs.anl.gov
Thu Aug 28 22:21:07 CDT 2008
Author: dcthomp
Date: 2008-08-28 22:21:07 -0500 (Thu, 28 Aug 2008)
New Revision: 2051
Modified:
MOAB/trunk/refiner/MBMeshOutputFunctor.cpp
MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
MOAB/trunk/refiner/MBRefinerTagManager.cpp
MOAB/trunk/refiner/MBSplitVertices.cpp
MOAB/trunk/refiner/MBSplitVertices.hpp
Log:
BUG: Global IDs were being assigned to elements out-of-order across
processes because their corner vertex IDs aren't assigned at
the time they were being sorted. Delay sorting until later.
Modified: MOAB/trunk/refiner/MBMeshOutputFunctor.cpp
===================================================================
--- MOAB/trunk/refiner/MBMeshOutputFunctor.cpp 2008-08-28 19:13:05 UTC (rev 2050)
+++ MOAB/trunk/refiner/MBMeshOutputFunctor.cpp 2008-08-29 03:21:07 UTC (rev 2051)
@@ -17,6 +17,10 @@
this->tag_manager = tag_mgr;
this->destination_set = 0; // don't place output entities in a set by default.
+ // When the input mesh and the output mesh are different, this map serves
+ // as a dictionary from input vertices to output vertices.
+ this->vertex_map = new MBSplitVertices<1>( this->tag_manager );
+
// Hold information about newly-created vertices on subdivided edges and faces.
this->split_vertices.resize( 4 );
this->split_vertices[0] = 0; // Vertices (0-faces) cannot be split
@@ -27,15 +31,16 @@
// Hold information about newly-created mesh entities (other than split vertices)
// This is necessary in order for global IDs to be assigned consistently across processes.
this->new_entities.resize( 5 );
- this->new_entities[0] = new MBSplitVertices<0>( this->tag_manager );
- this->new_entities[1] = new MBSplitVertices<1>( this->tag_manager );
- this->new_entities[2] = new MBSplitVertices<2>( this->tag_manager );
- this->new_entities[3] = new MBSplitVertices<3>( this->tag_manager );
- this->new_entities[4] = new MBSplitVertices<4>( this->tag_manager );
+ this->new_entities[0] = new MBEntitySource( 1, this->tag_manager );
+ this->new_entities[1] = new MBEntitySource( 2, this->tag_manager );
+ this->new_entities[2] = new MBEntitySource( 3, this->tag_manager );
+ this->new_entities[3] = new MBEntitySource( 4, this->tag_manager );
+ this->new_entities[4] = new MBEntitySource( 5, this->tag_manager );
}
MBMeshOutputFunctor::~MBMeshOutputFunctor()
{
+ delete this->vertex_map;
for ( int i = 1; i < 4; ++ i )
delete this->split_vertices[i];
for ( int i = 0; i < 5; ++ i )
@@ -156,10 +161,11 @@
{
(*vit)->assign_global_ids( gids );
}
- for ( vit = this->new_entities.begin(); vit != this->new_entities.end(); ++ vit )
+ std::vector<MBEntitySource*>::iterator sit;
+ for ( sit = this->new_entities.begin(); sit != this->new_entities.end(); ++ sit )
{
- if ( *vit )
- (*vit)->assign_global_ids( gids );
+ if ( *sit )
+ (*sit)->assign_global_ids( gids );
}
}
@@ -190,7 +196,7 @@
return vhash;
}
MBEntityHandle vertex_handle;
- bool newly_created = this->new_entities[1]->find_or_create(
+ bool newly_created = this->vertex_map->find_or_create(
&vhash, vcoords, vertex_handle, this->proc_partition_counts, false );
if ( newly_created )
{
@@ -206,6 +212,7 @@
std::cerr << "Could not insert vertex into new mesh!\n";
}
this->print_vert_crud( vertex_handle, 1, &vhash, vcoords, vtags );
+ std::cout << "\nMap vert: " << vhash << " to: " << vertex_handle << "\n";
return vertex_handle;
}
Modified: MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
===================================================================
--- MOAB/trunk/refiner/MBMeshOutputFunctor.hpp 2008-08-28 19:13:05 UTC (rev 2050)
+++ MOAB/trunk/refiner/MBMeshOutputFunctor.hpp 2008-08-29 03:21:07 UTC (rev 2051)
@@ -38,6 +38,7 @@
#include <string.h>
class MBSplitVerticesBase;
+class MBEntitySource;
class MBParallelComm;
class MBMeshOutputFunctor : public MBEntityRefinerOutputFunctor
@@ -60,8 +61,9 @@
MBInterface* mesh_in;
MBInterface* mesh_out;
bool input_is_output;
+ MBSplitVerticesBase* vertex_map;
std::vector<MBSplitVerticesBase*> split_vertices;
- std::vector<MBSplitVerticesBase*> new_entities;
+ std::vector<MBEntitySource*> new_entities;
std::vector<MBEntityHandle> elem_vert;
MBRefinerTagManager* tag_manager;
MBEntityHandle destination_set;
Modified: MOAB/trunk/refiner/MBRefinerTagManager.cpp
===================================================================
--- MOAB/trunk/refiner/MBRefinerTagManager.cpp 2008-08-28 19:13:05 UTC (rev 2050)
+++ MOAB/trunk/refiner/MBRefinerTagManager.cpp 2008-08-29 03:21:07 UTC (rev 2051)
@@ -451,7 +451,8 @@
}
else
{
- //std::cout << " not shared | ";
+ // not shared, but everthing exists on this process, so make sure that bit is set...
+ common_shared_procs.set_process_member( this->rank );
}
}
std::cout << " Common procs " << common_shared_procs;
Modified: MOAB/trunk/refiner/MBSplitVertices.cpp
===================================================================
--- MOAB/trunk/refiner/MBSplitVertices.cpp 2008-08-28 19:13:05 UTC (rev 2050)
+++ MOAB/trunk/refiner/MBSplitVertices.cpp 2008-08-29 03:21:07 UTC (rev 2051)
@@ -13,3 +13,53 @@
{
}
+MBEntitySource::MBEntitySource( int nc, MBRefinerTagManager* tag_mgr )
+{
+ this->tag_manager = tag_mgr;
+ this->mesh_out = tag_mgr->get_output_mesh();
+ this->num_corners = nc;
+}
+
+MBEntitySource::~MBEntitySource()
+{
+}
+
+bool MBEntitySource::create_element(
+ MBEntityType etyp, int nconn, const MBEntityHandle* elem_verts, MBEntityHandle& elem_handle,
+ std::map<MBProcessSet,int>& proc_partition_counts )
+{
+ // Get the global IDs of the input vertices
+ int stat;
+ proc_partition_counts[this->tag_manager->get_element_procs()]++;
+ if ( this->mesh_out->create_element( etyp, elem_verts, nconn, elem_handle ) != MB_SUCCESS )
+ {
+ return false;
+ }
+ this->push_back( MBEntitySourceRecord( this->num_corners, elem_handle, this->tag_manager->get_element_procs() ) );
+ this->tag_manager->set_sharing( elem_handle, this->tag_manager->get_element_procs() );
+ return true;
+}
+
+void MBEntitySource::assign_global_ids( std::map<MBProcessSet,int>& gids )
+{
+ std::vector<MBEntityHandle> adjacencies;
+ adjacencies.resize( this->num_corners );
+ std::vector<MBEntitySourceRecord>::iterator it;
+ int stat;
+ for ( it = this->begin(); it != this->end(); ++ it )
+ {
+ int num_nodes;
+ const MBEntityHandle* conn;
+ this->mesh_out->get_connectivity( it->handle, conn, num_nodes );
+ stat = this->tag_manager->get_output_gids( this->num_corners, conn, it->ids );
+ std::sort( it->ids.begin(), it->ids.end() );
+ }
+ std::sort( this->begin(), this->end() );
+ for ( it = this->begin(); it != this->end(); ++ it )
+ {
+ int gid = gids[it->process_set] ++;
+ this->tag_manager->set_gid( it->handle, gid );
+ std::cout << "Assigning entity: " << it->handle << " GID: " << gid << "\n";
+ }
+}
+
Modified: MOAB/trunk/refiner/MBSplitVertices.hpp
===================================================================
--- MOAB/trunk/refiner/MBSplitVertices.hpp 2008-08-28 19:13:05 UTC (rev 2050)
+++ MOAB/trunk/refiner/MBSplitVertices.hpp 2008-08-29 03:21:07 UTC (rev 2051)
@@ -16,7 +16,7 @@
/**\class MBSplitVertices
*\brief A dictionary of new vertices.
*
- * An array of existing vertex handles used as a key in a dictionary of new vertices.
+ * An array of existing vertex ids used as a key in a dictionary of new vertices.
*/
#ifndef MB_SPLITVERTICES_HPP
#define MB_SPLITVERTICES_HPP
@@ -37,11 +37,11 @@
public:
MBSplitVertexIndex() { }
MBSplitVertexIndex( const int* src )
- { for ( int i = 0; i < _n; ++ i ) this->handles[i] = src[i]; std::sort( this->handles, this->handles + _n ); }
+ { for ( int i = 0; i < _n; ++ i ) this->ids[i] = src[i]; std::sort( this->ids, this->ids + _n ); }
MBSplitVertexIndex( const MBSplitVertexIndex<_n>& src )
- { for ( int i = 0; i < _n; ++ i ) this->handles[i] = src.handles[i]; this->process_set = src.process_set; }
+ { for ( int i = 0; i < _n; ++ i ) this->ids[i] = src.ids[i]; this->process_set = src.process_set; }
MBSplitVertexIndex& operator = ( const MBSplitVertexIndex<_n>& src )
- { for ( int i = 0; i < _n; ++ i ) this->handles[i] = src.handles[i]; this->process_set = src.process_set; return *this; }
+ { for ( int i = 0; i < _n; ++ i ) this->ids[i] = src.ids[i]; this->process_set = src.process_set; return *this; }
void set_common_processes( const MBProcessSet& procs )
{ this->process_set = procs; }
@@ -52,16 +52,16 @@
bool operator < ( const MBSplitVertexIndex<_n>& other ) const
{
- // Ignore the process set. Only program errors lead to mismatched process sets with identical handles.
+ // Ignore the process set. Only program errors lead to mismatched process sets with identical ids.
for ( int i = 0; i < _n; ++ i )
- if ( this->handles[i] < other.handles[i] )
+ if ( this->ids[i] < other.ids[i] )
return true;
- else if ( this->handles[i] > other.handles[i] )
+ else if ( this->ids[i] > other.ids[i] )
return false;
return false;
}
- int handles[_n + 1];
+ int ids[_n + 1];
MBProcessSet process_set;
};
@@ -70,13 +70,51 @@
{
for ( int i = 0; i < _n; ++ i )
{
- os << idx.handles[i] << " ";
+ os << idx.ids[i] << " ";
}
os << "(" << idx.process_set << ")";
return os;
}
-/** A non-templated base class that the template subclasses all share.
+class MBEntitySourceRecord
+{
+public:
+ MBEntitySourceRecord() { }
+ MBEntitySourceRecord( int nc, MBEntityHandle ent, const MBProcessSet& procs )
+ { this->ids.resize( nc ); this->handle = ent; this->process_set = procs; }
+ MBEntitySourceRecord( const MBEntitySourceRecord& src )
+ { this->handle = src.handle; this->process_set = src.process_set; this->ids = src.ids; }
+ MBEntitySourceRecord& operator = ( const MBEntitySourceRecord& src )
+ { this->handle = src.handle; this->process_set = src.process_set; this->ids = src.ids; return *this; }
+
+ void set_common_processes( const MBProcessSet& procs )
+ { this->process_set = procs; }
+ MBProcessSet& common_processes()
+ { return this->process_set; }
+ const MBProcessSet& common_processes() const
+ { return this->process_set; }
+
+ bool operator < ( const MBEntitySourceRecord& other ) const
+ {
+ //assert( this->ids.size() == other.ids.size() );
+ std::vector<int>::size_type N = this->ids.size();
+ std::vector<int>::size_type i;
+ // Ignore the process set. Only program errors lead to mismatched process sets with identical ids.
+ for ( i = 0; i < N; ++ i )
+ if ( this->ids[i] < other.ids[i] )
+ return true;
+ else if ( this->ids[i] > other.ids[i] )
+ return false;
+ return false;
+ }
+
+ std::vector<int> ids;
+ MBProcessSet process_set;
+ MBEntityHandle handle;
+};
+
+
+/** A non-templated base class that the MBSplitVertices template subclasses all share.
*
* All methods that need to be accessed by other classes should be
* declared by the base class so that no knowledge of template parameters
@@ -92,10 +130,6 @@
const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
std::map<MBProcessSet,int>& proc_partition_counts, bool handles_on_output_mesh ) = 0;
- virtual bool create_element(
- MBEntityType etyp, int nconn, const MBEntityHandle* elem_verts, MBEntityHandle& elem_handle,
- std::map<MBProcessSet,int>& proc_partition_counts ) = 0;
-
virtual void assign_global_ids( std::map<MBProcessSet,int>& gids ) = 0;
MBInterface* mesh_out; // Output mesh. Needed for new vertex set in vert_handle
@@ -104,12 +138,39 @@
MBProcessSet common_shared_procs; // Holds intersection of several shared_procs_ins.
};
-/** A map from a set of pre-existing entities to a new mesh entity.
+/** A vector of pre-existing entities to a new mesh entity.
*
* This is used as a dictionary to determine whether a new vertex should be
* created on the given n-simplex (n being the template parameter) or whether
* it has already been created as part of the refinement of a neighboring entity.
*/
+class MBEntitySource : public std::vector<MBEntitySourceRecord>
+{
+public:
+ typedef std::vector<MBEntitySourceRecord> VecType;
+ typedef std::vector<MBEntitySourceRecord>::iterator VecIteratorType;
+
+ MBEntitySource( int num_corners, MBRefinerTagManager* tag_mgr );
+ ~MBEntitySource();
+ bool create_element(
+ MBEntityType etyp, int nconn, const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
+ std::map<MBProcessSet,int>& proc_partition_counts );
+
+ void assign_global_ids( std::map<MBProcessSet,int>& gids );
+
+ MBInterface* mesh_out; // Output mesh. Needed for new vertex set in vert_handle
+ MBRefinerTagManager* tag_manager;
+ MBProcessSet common_shared_procs; // Holds intersection of several shared_procs_ins.
+ int num_corners;
+};
+
+
+/** A map from a set of pre-existing vertices to a new mesh vertex.
+ *
+ * This is used as a dictionary to determine whether a new vertex should be
+ * created on the given n-simplex (n being the template parameter) or whether
+ * it has already been created as part of the refinement of a neighboring entity.
+ */
template< int _n >
class MBSplitVertices : public std::map<MBSplitVertexIndex<_n>,MBEntityHandle>, public MBSplitVerticesBase
{
@@ -122,9 +183,6 @@
virtual bool find_or_create(
const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
std::map<MBProcessSet,int>& proc_partition_counts, bool handles_on_output_mesh );
- virtual bool create_element(
- MBEntityType etyp, int nconn, const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
- std::map<MBProcessSet,int>& proc_partition_counts );
virtual void assign_global_ids( std::map<MBProcessSet,int>& gids );
};
@@ -178,27 +236,6 @@
}
template< int _n >
-bool MBSplitVertices<_n>::create_element(
- MBEntityType etyp, int nconn, const MBEntityHandle* elem_verts, MBEntityHandle& elem_handle,
- std::map<MBProcessSet,int>& proc_partition_counts )
-{
- // Get the global IDs of the input vertices
- int stat;
- stat = this->tag_manager->get_input_gids( _n, elem_verts, this->split_gids );
- MBSplitVertexIndex<_n> key( &this->split_gids[0] );
- //this->tag_manager->get_common_processes( _n, elem_verts, this->common_shared_procs );
- proc_partition_counts[this->tag_manager->get_element_procs()]++;
- key.set_common_processes( this->tag_manager->get_element_procs() );
- if ( this->mesh_out->create_element( etyp, elem_verts, nconn, elem_handle ) != MB_SUCCESS )
- {
- return false;
- }
- (*this)[key] = elem_handle;
- this->tag_manager->set_sharing( elem_handle, this->tag_manager->get_element_procs() );
- return true;
-}
-
-template< int _n >
void MBSplitVertices<_n>::assign_global_ids( std::map<MBProcessSet,int>& gids )
{
typename std::map<MBSplitVertexIndex<_n>,MBEntityHandle>::iterator it;
More information about the moab-dev
mailing list