[MOAB-dev] r2024 - MOAB/trunk/refiner
dcthomp at mcs.anl.gov
dcthomp at mcs.anl.gov
Thu Jul 24 23:14:30 CDT 2008
Author: dcthomp
Date: 2008-07-24 23:14:30 -0500 (Thu, 24 Jul 2008)
New Revision: 2024
Modified:
MOAB/trunk/refiner/MBMeshOutputFunctor.cpp
MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
MOAB/trunk/refiner/MBProcessSet.cpp
MOAB/trunk/refiner/MBProcessSet.hpp
MOAB/trunk/refiner/MBRefinerTagManager.hpp
MOAB/trunk/refiner/MBSplitVertices.cpp
MOAB/trunk/refiner/MBSplitVertices.hpp
MOAB/trunk/refiner/test_mesh_refiner.cpp
Log:
ENH: The tet refiner now sets the global IDs of newly-created
vertices properly. It also sets the PARALLEL_SHARED_PROC(S)
and PARALLEL_STATUS tag values properly, although the way
this is accomplished may change in the future.
Modified: MOAB/trunk/refiner/MBMeshOutputFunctor.cpp
===================================================================
--- MOAB/trunk/refiner/MBMeshOutputFunctor.cpp 2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBMeshOutputFunctor.cpp 2008-07-25 04:14:30 UTC (rev 2024)
@@ -17,17 +17,28 @@
this->tag_manager = tag_mgr;
this->destination_set = 0; // don't place output entities in a set by default.
+ // Hold information about newly-created vertices on subdivided edges and faces.
this->split_vertices.resize( 4 );
this->split_vertices[0] = 0; // Vertices (0-faces) cannot be split
this->split_vertices[1] = new MBSplitVertices<1>( this->tag_manager );
this->split_vertices[2] = new MBSplitVertices<2>( this->tag_manager );
this->split_vertices[3] = new MBSplitVertices<3>( this->tag_manager );
+
+ // Hold information about newly-created mesh entities (other than split vertices)
+ // This is necessary in order for global IDs to be assigned consistently across processes.
+ this->new_entities.resize( 4 );
+ this->new_entities[0] = new MBSplitVertices<0>( this->tag_manager );
+ this->new_entities[1] = new MBSplitVertices<1>( this->tag_manager );
+ this->new_entities[2] = new MBSplitVertices<2>( this->tag_manager );
+ this->new_entities[3] = new MBSplitVertices<3>( this->tag_manager );
}
MBMeshOutputFunctor::~MBMeshOutputFunctor()
{
for ( int i = 0; i < 4; ++ i )
delete this->split_vertices[i];
+ for ( int i = 0; i < 4; ++ i )
+ delete this->new_entities[i];
}
void MBMeshOutputFunctor::print_vert_crud( MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags )
@@ -123,21 +134,26 @@
this->proc_partition_counts[pset] = part_sizes[i];
}
}
- std::map<MBProcessSet,MBEntityHandle> gids;
+ std::map<MBProcessSet,int> gids;
std::map<MBProcessSet,int>::iterator pcit;
MBEntityHandle start_gid = 100; // FIXME: Get actual maximum GID across all processes and add 1
for ( pcit = this->proc_partition_counts.begin(); pcit != this->proc_partition_counts.end(); ++ pcit )
{
gids[pcit->first] = start_gid;
start_gid += pcit->second;
- std::cout << "Partition " << pcit->first << ": " << pcit->second << " #\n";
+ std::cout << "Partition " << pcit->first << ": " << pcit->second << " # [" << gids[pcit->first] << "]\n";
}
- std::vector<MBSplitVerticesBase*>::iterator splitit;
- for ( splitit = this->split_vertices.begin(); splitit != this->split_vertices.end(); ++ splitit )
+ std::vector<MBSplitVerticesBase*>::iterator vit;
+ for ( vit = this->split_vertices.begin(); vit != this->split_vertices.end(); ++ vit )
{
- if ( *splitit )
- (*splitit)->assign_global_ids( gids );
+ if ( *vit )
+ (*vit)->assign_global_ids( gids );
}
+ for ( vit = this->new_entities.begin(); vit != this->new_entities.end(); ++ vit )
+ {
+ if ( *vit )
+ (*vit)->assign_global_ids( gids );
+ }
}
void MBMeshOutputFunctor::assign_tags( MBEntityHandle vhandle, const void* vtags )
@@ -163,11 +179,16 @@
return vhash;
}
MBEntityHandle vertex_handle;
- if ( this->mesh_out->create_vertex( vcoords + 3, vertex_handle ) != MB_SUCCESS )
+ bool newly_created = this->new_entities[0]->find_or_create(
+ &vhash, vcoords, vertex_handle, this->proc_partition_counts );
+ if ( newly_created )
{
- std::cerr << "Could not insert mid-edge vertex!\n";
+ this->assign_tags( vertex_handle, vtags );
}
- this->assign_tags( vertex_handle, vtags );
+ if ( ! vertex_handle )
+ {
+ std::cerr << "Could not insert vertex into new mesh!\n";
+ }
this->print_vert_crud( vertex_handle, 1, &vhash, vcoords, vtags );
return vertex_handle;
}
@@ -205,16 +226,30 @@
{
std::cout << h << " ";
this->elem_vert.push_back( h );
+ if ( ! this->input_is_output )
+ {
+ // FIXME: Copy to output mesh
+ }
}
void MBMeshOutputFunctor::operator () ( MBEntityType etyp )
{
MBEntityHandle elem_handle;
- if ( this->mesh_out->create_element( etyp, &this->elem_vert[0], this->elem_vert.size(), elem_handle ) == MB_FAILURE )
+ int nconn = this->elem_vert.size();
+ if ( this->mesh_out->create_element( etyp, &this->elem_vert[0], nconn, elem_handle ) == MB_FAILURE )
{
std::cerr << " *** ";
}
+ std::cout << "---------> " << elem_handle << " ( " << etyp << " )\n\n";
+#if 0
+ bool newly_created = this->new_entities[nconn]->create_element(
+ &this->elem_vert[0], elem_handle, this->proc_partition_counts );
+ if ( newly_created )
+ {
+ // FIXME: Handle tag assignment for elements as well as vertices
+ //this->assign_tags( elem_handle, this->element_tag_data );
+ }
+#endif // 0
this->elem_vert.clear();
- std::cout << "---------> " << elem_handle << " ( " << etyp << " )\n\n";
}
Modified: MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
===================================================================
--- MOAB/trunk/refiner/MBMeshOutputFunctor.hpp 2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBMeshOutputFunctor.hpp 2008-07-25 04:14:30 UTC (rev 2024)
@@ -33,6 +33,7 @@
MBInterface* mesh_out;
bool input_is_output;
std::vector<MBSplitVerticesBase*> split_vertices;
+ std::vector<MBSplitVerticesBase*> new_entities;
std::vector<MBEntityHandle> elem_vert;
MBRefinerTagManager* tag_manager;
MBEntityHandle destination_set;
Modified: MOAB/trunk/refiner/MBProcessSet.cpp
===================================================================
--- MOAB/trunk/refiner/MBProcessSet.cpp 2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBProcessSet.cpp 2008-07-25 04:14:30 UTC (rev 2024)
@@ -1,5 +1,7 @@
#include "MBProcessSet.hpp"
+#include <assert.h>
+
MBProcessSet::MBProcessSet()
{
this->clear();
@@ -51,6 +53,40 @@
}
}
+/**\brief Retrieve a vector containing processes in this set.
+ *
+ * @param [in] rank The rank of the local process. This integer will not be included in the output list.
+ * @param [out] procs The vector in which the list of sharing processes is listed.
+ * @return True when \a rank is the owning process and false otherwise.
+ */
+bool MBProcessSet::get_process_members( int rank, std::vector<int>& procs )
+{
+ int i = 0;
+ assert( rank >= 0 );
+ procs.clear();
+ bool rank_owner = false;
+ for ( int byte = 0; byte < SHARED_PROC_BYTES; ++ byte )
+ {
+ char val = this->processes[byte];
+ for ( int bit = 0; val && ( bit < 8 ); ++ bit, ++ i )
+ {
+ if ( ! val )
+ {
+ i += 8 - bit;
+ break;
+ }
+ else if ( val & 0x1 )
+ {
+ if ( i != rank )
+ procs.push_back( i );
+ else if ( ! procs.size() )
+ rank_owner = true;
+ }
+ }
+ }
+ return rank_owner;
+}
+
bool MBProcessSet::is_process_member( int i ) const
{
int byte = i / 8;
Modified: MOAB/trunk/refiner/MBProcessSet.hpp
===================================================================
--- MOAB/trunk/refiner/MBProcessSet.hpp 2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBProcessSet.hpp 2008-07-25 04:14:30 UTC (rev 2024)
@@ -34,6 +34,7 @@
void set_process_member( int i );
void set_process_members( const std::vector<int>& procs );
+ bool get_process_members( int rank, std::vector<int>& procs );
bool is_process_member( int i ) const;
const unsigned char* data() const;
Modified: MOAB/trunk/refiner/MBRefinerTagManager.hpp
===================================================================
--- MOAB/trunk/refiner/MBRefinerTagManager.hpp 2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBRefinerTagManager.hpp 2008-07-25 04:14:30 UTC (rev 2024)
@@ -51,6 +51,7 @@
MBInterface* get_input_mesh() { return this->input_mesh; }
MBInterface* get_output_mesh() { return this->output_mesh; }
+ MBTag parallel_status() { return this->tag_pstatus; }
MBTag shared_proc() { return this->tag_psproc; }
MBTag shared_procs() { return this->tag_psprocs; }
Modified: MOAB/trunk/refiner/MBSplitVertices.cpp
===================================================================
--- MOAB/trunk/refiner/MBSplitVertices.cpp 2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBSplitVertices.cpp 2008-07-25 04:14:30 UTC (rev 2024)
@@ -1,6 +1,8 @@
#include "MBSplitVertices.hpp"
#include "MBRefinerTagManager.hpp"
+#include "MBParallelConventions.h"
+
MBSplitVerticesBase::MBSplitVerticesBase( MBRefinerTagManager* tag_mgr )
{
this->tag_manager = tag_mgr;
@@ -9,6 +11,11 @@
this->shared_procs_val.resize( MAX_SHARING_PROCS );
MBParallelComm* ipcomm = MBParallelComm::get_pcomm( this->mesh_in, 0 );
this->rank = ipcomm ? ipcomm->proc_config().proc_rank() : 0;
+ int zero = 0;
+ MBErrorCode result = this->mesh_out->tag_create(
+ GLOBAL_ID_TAG_NAME, sizeof(int), MB_TAG_DENSE, MB_TYPE_INTEGER, this->tag_gid, &zero, true );
+ if ( result != MB_SUCCESS && result != MB_ALREADY_ALLOCATED )
+ return;
}
MBSplitVerticesBase::~MBSplitVerticesBase()
@@ -87,3 +94,26 @@
// FIXME: Here is where we add the vertex to the appropriate queues.
}
+void MBSplitVerticesBase::set_sharing( MBEntityHandle ent_handle, MBProcessSet& procs )
+{
+ int pstat;
+ if ( procs.get_process_members( this->rank, this->shared_procs_val ) )
+ pstat = PSTATUS_SHARED | PSTATUS_INTERFACE | PSTATUS_NOT_OWNED;
+ else
+ pstat = PSTATUS_SHARED | PSTATUS_INTERFACE;
+ int sps = this->shared_procs_val.size();
+ switch ( sps )
+ {
+ case 0:
+ break;
+ case 1:
+ this->mesh_out->tag_set_data( this->tag_manager->shared_proc(), &ent_handle, 1, &this->shared_procs_val[0] );
+ this->mesh_out->tag_set_data( this->tag_manager->parallel_status(), &ent_handle, 1, &pstat );
+ break;
+ default:
+ this->mesh_out->tag_set_data( this->tag_manager->shared_procs(), &ent_handle, sps, &this->shared_procs_val[0] );
+ this->mesh_out->tag_set_data( this->tag_manager->parallel_status(), &ent_handle, 1, &pstat );
+ break;
+ }
+}
+
Modified: MOAB/trunk/refiner/MBSplitVertices.hpp
===================================================================
--- MOAB/trunk/refiner/MBSplitVertices.hpp 2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/MBSplitVertices.hpp 2008-07-25 04:14:30 UTC (rev 2024)
@@ -17,7 +17,7 @@
{
public:
MBSplitVertexIndex() { }
- MBSplitVertexIndex( const MBEntityHandle* src )
+ MBSplitVertexIndex( const int* src )
{ for ( int i = 0; i < _n; ++ i ) this->handles[i] = src[i]; std::sort( this->handles, this->handles + _n ); }
MBSplitVertexIndex( const MBSplitVertexIndex<_n>& src )
{ for ( int i = 0; i < _n; ++ i ) this->handles[i] = src.handles[i]; this->process_set = src.process_set; }
@@ -42,10 +42,21 @@
return false;
}
- MBEntityHandle handles[_n];
+ int handles[_n + 1];
MBProcessSet process_set;
};
+template< int _n >
+std::ostream& operator << ( std::ostream& os, const MBSplitVertexIndex<_n>& idx )
+{
+ for ( int i = 0; i < _n; ++ i )
+ {
+ os << idx.handles[i] << " ";
+ }
+ os << "(" << idx.process_set << ")";
+ return os;
+}
+
/** A non-templated base class that the template subclasses all share.
*
* All methods that need to be accessed by other classes should be
@@ -62,8 +73,12 @@
const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
std::map<MBProcessSet,int>& proc_partition_counts ) = 0;
- virtual void assign_global_ids( std::map<MBProcessSet,MBEntityHandle>& gids ) = 0;
+ virtual bool create_element(
+ const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
+ std::map<MBProcessSet,int>& proc_partition_counts ) = 0;
+ virtual void assign_global_ids( std::map<MBProcessSet,int>& gids ) = 0;
+
/// Determine which processes will contain an output vertex given the split vertices defining it.
void update_partition_counts( int num, const MBEntityHandle* split_src, std::map<MBProcessSet,int>& proc_partition_counts );
@@ -76,14 +91,19 @@
/// Call this once after all the add_vertex_procs() calls for a split-vertex to prepare queues for the second stage MPI send.
void end_vertex_procs();
+ /// Set the tags which indicate sharing process(es) for an entity.
+ void set_sharing( MBEntityHandle vert_handle, MBProcessSet& procs );
+
MBInterface* mesh_in; // Input mesh. Needed to determine tag values on split_src verts
MBInterface* mesh_out; // Output mesh. Needed for new vertex set in vert_handle
MBRefinerTagManager* tag_manager;
std::vector<int> shared_procs_val; // Used to hold procs sharing an input vert.
+ std::vector<int> split_gids; // Used to hold global IDs of split vertices
MBProcessSet current_shared_procs; // Holds process list as it is being accumulated
MBProcessSet common_shared_procs; // Holds intersection of several shared_procs_vals.
int rank; // This process' rank.
bool first_vertex; // True just after begin_vertex_procs() is called.
+ MBTag tag_gid;
};
/** A map from a set of pre-existing entities to a new mesh entity.
@@ -104,7 +124,11 @@
virtual bool find_or_create(
const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
std::map<MBProcessSet,int>& proc_partition_counts );
- virtual void assign_global_ids( std::map<MBProcessSet,MBEntityHandle>& gids );
+ virtual bool create_element(
+ const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
+ std::map<MBProcessSet,int>& proc_partition_counts );
+
+ virtual void assign_global_ids( std::map<MBProcessSet,int>& gids );
};
// ------------------------- Template member definitions ----------------------
@@ -113,6 +137,7 @@
: MBSplitVerticesBase( tag_mgr )
{
this->shared_procs_val.resize( _n * MAX_SHARING_PROCS );
+ this->split_gids.resize( _n );
}
template< int _n >
@@ -125,7 +150,15 @@
const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle,
std::map<MBProcessSet,int>& proc_partition_counts )
{
- MBSplitVertexIndex<_n> key( split_src );
+ // Get the global IDs of the input vertices
+ int stat;
+ for ( int i = 0; i < _n; ++ i )
+ {
+ int gid = -1;
+ stat = this->mesh_in->tag_get_data( this->tag_gid, split_src + i, 1, &gid );
+ this->split_gids[i] = gid;
+ }
+ MBSplitVertexIndex<_n> key( &this->split_gids[0] );
MapIteratorType it = this->find( key );
if ( it == this->end() )
{
@@ -136,6 +169,7 @@
return false;
}
(*this)[key] = vert_handle;
+ this->set_sharing( vert_handle, this->common_shared_procs );
return true;
}
vert_handle = it->second;
@@ -143,20 +177,21 @@
}
template< int _n >
-void MBSplitVertices<_n>::assign_global_ids( std::map<MBProcessSet,MBEntityHandle>& gids )
+bool MBSplitVertices<_n>::create_element(
+ const MBEntityHandle* split_src, MBEntityHandle& elem_handle,
+ std::map<MBProcessSet,int>& proc_partition_counts )
{
- MBTag tag_gid;
- int zero = 0;
- MBErrorCode result = this->mesh_out->tag_create(
- GLOBAL_ID_TAG_NAME, sizeof(int), MB_TAG_DENSE, MB_TYPE_INTEGER, tag_gid, &zero, true );
- if ( result != MB_SUCCESS && result != MB_ALREADY_ALLOCATED )
- return;
+}
+template< int _n >
+void MBSplitVertices<_n>::assign_global_ids( std::map<MBProcessSet,int>& gids )
+{
typename std::map<MBSplitVertexIndex<_n>,MBEntityHandle>::iterator it;
for ( it = this->begin(); it != this->end(); ++ it )
{
int gid = gids[it->first.process_set] ++;
- this->mesh_out->tag_set_data( tag_gid, &it->second, 1, &gid );
+ this->mesh_out->tag_set_data( this->tag_gid, &it->second, 1, &gid );
+ std::cout << "Assigning " << it->first << " -> " << gid << "\n";
}
}
Modified: MOAB/trunk/refiner/test_mesh_refiner.cpp
===================================================================
--- MOAB/trunk/refiner/test_mesh_refiner.cpp 2008-07-25 02:42:10 UTC (rev 2023)
+++ MOAB/trunk/refiner/test_mesh_refiner.cpp 2008-07-25 04:14:30 UTC (rev 2024)
@@ -27,6 +27,7 @@
nprocs = 1;
rank = 0;
#endif // USE_MPI
+ //sleep(20);
// Create the input mesh and, if -new-mesh is specified, an output mesh
const char* ifname = argc > 1 ? argv[1] : "/home/dcthomp/fourVolsBare.cub";
More information about the moab-dev
mailing list