[MOAB-dev] r1538 - MOAB/trunk/refiner
dcthomp at mcs.anl.gov
dcthomp at mcs.anl.gov
Thu Jan 17 19:04:45 CST 2008
Author: dcthomp
Date: 2008-01-17 19:04:45 -0600 (Thu, 17 Jan 2008)
New Revision: 1538
Modified:
MOAB/trunk/refiner/MBEntityRefiner.cpp
MOAB/trunk/refiner/MBMeshRefiner.cpp
MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp
MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp
Log:
STYLE: Added some documentation.
ENH: Force the tag assigner to be non-NULL for the lifetime
of the entity refiner.
PERF: Make the coordinate and tag storage used for corner vertices
in MBEntityRefiner::refine_entity() member variables to avoid
repeated allocation/deallocation.
Modified: MOAB/trunk/refiner/MBEntityRefiner.cpp
===================================================================
--- MOAB/trunk/refiner/MBEntityRefiner.cpp 2008-01-17 20:09:23 UTC (rev 1537)
+++ MOAB/trunk/refiner/MBEntityRefiner.cpp 2008-01-18 01:04:45 UTC (rev 1538)
@@ -30,7 +30,9 @@
/**\fn int MBEntityRefiner::get_heap_size_bound( int max_recursions ) const
*\brief When an entity is refined, what is the maximum number of new vertices that will be created?
*
- * This must be the maximum number of vertices for any entity type (tetrahedra, hexahedra, etc.).
+ * This must be the maximum number of initial corner vertices for any entity type (hex, tet, etc.)
+ * to be processed plus the maximum number of new vertices that might be created at edge or face
+ * mid-points during the refinement of a single entity.
*/
/**\brief Set the object that specifies which edges of a given entity should be subdivided.
@@ -149,7 +151,7 @@
void MBEntityRefiner::update_heap_size()
{
unsigned long n = this->get_heap_size_bound( this->maximum_number_of_subdivisions );
- this->coord_heap.resize( 6 * n + 8 );
+ this->coord_heap.resize( 6 * n );
if ( this->edge_size_evaluator )
{
unsigned long m = this->edge_size_evaluator->get_vertex_tag_size();
Modified: MOAB/trunk/refiner/MBMeshRefiner.cpp
===================================================================
--- MOAB/trunk/refiner/MBMeshRefiner.cpp 2008-01-17 20:09:23 UTC (rev 1537)
+++ MOAB/trunk/refiner/MBMeshRefiner.cpp 2008-01-18 01:04:45 UTC (rev 1538)
@@ -1,7 +1,94 @@
#include "MBMeshRefiner.hpp"
+#include "MBEntityRefiner.hpp"
#include "MBInterface.hpp"
+#ifdef USE_MPI
+#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;
+ /// 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;
+
+ virtual ~MBMeshRefinerOutputFunctor() { }
+ virtual void operator () ( const double* vcoords, const void* vtags )
+ {
+ // Assume that vtags contains the proper global ID for the vertex (assigned by the TagAssigner)
+ }
+ virtual void operator () ( MBEntityType etyp )
+ {
+ }
+};
+
MBMeshRefiner::MBMeshRefiner( MBInterface* parentMesh )
{
this->mesh = parentMesh;
Modified: MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp
===================================================================
--- MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp 2008-01-17 20:09:23 UTC (rev 1537)
+++ MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp 2008-01-18 01:04:45 UTC (rev 1538)
@@ -25,13 +25,18 @@
: MBEntityRefiner( mesh )
{
this->tag_assigner = new MBSimplexTemplateTagAssigner( this );
+ 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)
}
/// Empty destructor for good form.
MBSimplexTemplateRefiner::~MBSimplexTemplateRefiner()
{
+ delete this->tag_assigner;
}
+/**\brief Stream a single mesh entity through the refiner.
+ */
bool MBSimplexTemplateRefiner::refine_entity( MBEntityHandle entity )
{
this->reset_heap_pointers();
@@ -42,50 +47,50 @@
{
return false;
}
- std::vector<double> entity_coords;
- std::vector<void*> entity_tags;
- entity_coords.resize( 6 * num_nodes );
- entity_tags.resize( num_nodes );
+ this->corner_coords.resize( 6 * num_nodes );
+ this->corner_tags.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;
+ void* tag_data;
for ( int n = 0; n < num_nodes; ++ n )
{
- if ( this->mesh->get_coords( &conn[n], 1, &entity_coords[6 * n + 3] ) != MB_SUCCESS )
+ if ( this->mesh->get_coords( &conn[n], 1, &corner_coords[6 * n + 3] ) != MB_SUCCESS )
{
return false;
}
- entity_tags[n] = this->heap_tag_storage();
+ tag_data = this->heap_tag_storage();
for ( int i = 0; i < this->edge_size_evaluator->get_number_of_vertex_tags(); ++ i )
{
this->edge_size_evaluator->get_vertex_tag( i, tag_handle, tag_offset );
- if ( this->mesh->tag_get_data( tag_handle, &conn[n], 1, (char*)( entity_tags[n] ) + tag_offset ) != MB_SUCCESS )
+ if ( this->mesh->tag_get_data( tag_handle, &conn[n], 1, (char*)tag_data + tag_offset ) != MB_SUCCESS )
{
return false;
}
}
+ this->corner_tags[n] = tag_data;
}
switch ( etyp )
{
case MBVERTEX:
- this->assign_parametric_coordinates( 1, MBVertexParametric, &entity_coords[0] );
- this->refine_0_simplex( &entity_coords[0], entity_tags[0] );
+ this->assign_parametric_coordinates( 1, MBVertexParametric, &this->corner_coords[0] );
+ this->refine_0_simplex( &this->corner_coords[0], this->corner_tags[0] );
rval = false;
break;
case MBEDGE:
- this->assign_parametric_coordinates( 2, MBEdgeParametric, &entity_coords[0] );
+ this->assign_parametric_coordinates( 2, MBEdgeParametric, &this->corner_coords[0] );
rval = this->refine_1_simplex( this->maximum_number_of_subdivisions,
- &entity_coords[0], entity_tags[0], &entity_coords[6], entity_tags[1] );
+ &this->corner_coords[0], this->corner_tags[0], &this->corner_coords[6], this->corner_tags[1] );
break;
case MBTRI:
- this->assign_parametric_coordinates( 3, MBTriParametric, &entity_coords[0] );
+ this->assign_parametric_coordinates( 3, MBTriParametric, &this->corner_coords[0] );
rval = this->refine_2_simplex( this->maximum_number_of_subdivisions, 7,
- &entity_coords[ 0], entity_tags[0],
- &entity_coords[ 6], entity_tags[1],
- &entity_coords[12], entity_tags[2] );
+ &this->corner_coords[ 0], this->corner_tags[0],
+ &this->corner_coords[ 6], this->corner_tags[1],
+ &this->corner_coords[12], this->corner_tags[2] );
break;
case MBQUAD:
std::cerr << "Quadrilaterals not handled yet\n";
@@ -96,7 +101,7 @@
rval = false;
break;
case MBTET:
- this->assign_parametric_coordinates( 4, MBTetParametric, &entity_coords[0] );
+ this->assign_parametric_coordinates( 4, MBTetParametric, &this->corner_coords[0] );
rval = this->refine_3_simplex( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); // FIXME
break;
case MBPYRAMID:
@@ -132,25 +137,30 @@
return rval;
}
+/**\brief Set the function object used to decide which tag values an edge or face midpoint is assigned.
+ *
+ * This will change the tag assigner's edge size evaluator to match the refiner's.
+ * @param[in] ta The new tag assigner. This must be non-NULL.
+ * @retval True if the tag assigner was changed and false otherwise.
+ */
bool MBSimplexTemplateRefiner::set_tag_assigner( MBSimplexTemplateTagAssigner* ta )
{
- if ( ta == this->tag_assigner )
+ if ( ! ta || ta == this->tag_assigner )
return false;
+
this->tag_assigner = ta;
- if ( ta )
- this->tag_assigner->set_edge_size_evaluator( this->edge_size_evaluator );
+ 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 )
{
if ( this->MBEntityRefiner::set_edge_size_evaluator( es ) )
{
- if ( this->tag_assigner )
- {
- this->tag_assigner->set_edge_size_evaluator( es );
- }
+ this->tag_assigner->set_edge_size_evaluator( es );
return true;
}
return false;
Modified: MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp
===================================================================
--- MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp 2008-01-17 20:09:23 UTC (rev 1537)
+++ MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp 2008-01-18 01:04:45 UTC (rev 1538)
@@ -41,7 +41,7 @@
virtual ~MBSimplexTemplateRefiner();
virtual bool refine_entity( MBEntityHandle entity );
- virtual unsigned long get_heap_size_bound( int max_recursions ) const { return 48 * 4 * ( 1 << max_recursions ); }
+ 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; }
@@ -50,6 +50,9 @@
protected:
MBSimplexTemplateTagAssigner* tag_assigner;
+ std::vector<double> corner_coords;
+ std::vector<void*> corner_tags;
+
static int template_index[64][2];
static int permutations_from_index[24][14];
static int templates[];
More information about the moab-dev
mailing list