[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