Changeset 2048

Show
Ignore:
Timestamp:
08/25/08 18:02:57 (3 months ago)
Author:
dcthomp
Message:

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.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • MOAB/trunk/refiner/MBEntityRefiner.hpp

    r2029 r2048  
    5353  * the other used to finalize the creation of the entity by specifying its type. 
    5454  * 
     55  * You are also responsible for implementing the map_vertex() function to map an input vertex handle 
     56  * into an output vertex handle (which may then be appended to an entity using the first form 
     57  * of the parenthesis operator above). 
     58  * 
    5559  * \author David Thompson 
    5660  * \author Philippe Pebay 
     
    7377public: 
    7478  virtual ~MBEntityRefinerOutputFunctor() { } 
    75   virtual MBEntityHandle operator () ( MBEntityHandle vhash, const double* vcoords, const void* vtags ) = 0; 
     79  /// Map an input vertex to the output mesh. This should return the same value when given the same input across multiple calls. 
     80  virtual MBEntityHandle map_vertex( MBEntityHandle vhash, const double* vcoords, const void* vtags ) = 0; 
     81  /**\brief Create a new vertex along an edge. 
     82    * 
     83    * @param[in] h0 An edge endpoint handle on the output mesh. 
     84    * @param[in] h1 An edge endpoint handle on the output mesh. 
     85    * @param[in] vcoords The location of the midpoint in world coordinates. 
     86    * @param[in] vtags Field values at the midpoint. 
     87    * @retval    A handle for the midpoint on the output mesh. 
     88    */ 
    7689  MBEntityHandle operator () ( MBEntityHandle h0, MBEntityHandle h1, const double* vcoords, const void* vtags ) 
    7790    { 
     
    8194    return (*this)( 2, harr, vcoords, vtags ); 
    8295    } 
     96  /**\brief Create a new vertex on a triangular face. 
     97    * 
     98    * @param[in] h0 A triangle corner handle on the output mesh. 
     99    * @param[in] h1 A triangle corner handle on the output mesh. 
     100    * @param[in] h2 A triangle corner handle on the output mesh. 
     101    * @param[in] vcoords The location of the mid-face point in world coordinates. 
     102    * @param[in] vtags Field values at the mid-face point. 
     103    * @retval    A handle for the mid-face point on the output mesh. 
     104    */ 
    83105  virtual MBEntityHandle operator () ( MBEntityHandle h0, MBEntityHandle h1, MBEntityHandle h2, const double* vcoords, const void* vtags ) 
    84106    { 
     
    89111    return (*this)( 3, harr, vcoords, vtags ); 
    90112    } 
     113  /**\brief Create a new vertex along a \f$k\f$-facet. 
     114    * 
     115    * @param[in] nhash The number of corner vertices (i.e, \f$k\f$ ). 
     116    * @param[in] hash An array of corner handles on the output mesh. 
     117    * @param[in] vcoords The location of the new point in world coordinates. 
     118    * @param[in] vtags Field values at the new point. 
     119    * @retval    A handle for the new point on the output mesh. 
     120    */ 
    91121  virtual MBEntityHandle operator () ( int nhash, MBEntityHandle* hash, const double* vcoords, const void* vtags ) = 0; 
     122  /**\brief Append an output vertex to the list of vertices defining a new entity. 
     123    * 
     124    * @param[in] vhash A vertex of the output mesh. 
     125    */ 
    92126  virtual void operator () ( MBEntityHandle vhash ) = 0; 
     127  /**\brief Create a new entity from all previously appended output vertices. 
     128    * 
     129    * This resets the list of appended vertices. 
     130    * @param[in] etyp The type of entity to create. 
     131    */ 
    93132  virtual void operator () ( MBEntityType etyp ) = 0; 
    94133}; 
  • MOAB/trunk/refiner/MBMeshOutputFunctor.cpp

    r2024 r2048  
    2727  // Hold information about newly-created mesh entities (other than split vertices) 
    2828  // This is necessary in order for global IDs to be assigned consistently across processes. 
    29   this->new_entities.resize( 4 ); 
     29  this->new_entities.resize( 5 ); 
    3030  this->new_entities[0] = new MBSplitVertices<0>( this->tag_manager ); 
    3131  this->new_entities[1] = new MBSplitVertices<1>( this->tag_manager ); 
    3232  this->new_entities[2] = new MBSplitVertices<2>( this->tag_manager ); 
    3333  this->new_entities[3] = new MBSplitVertices<3>( this->tag_manager ); 
     34  this->new_entities[4] = new MBSplitVertices<4>( this->tag_manager ); 
    3435} 
    3536 
    3637MBMeshOutputFunctor::~MBMeshOutputFunctor() 
    3738{ 
    38   for ( int i = 0; i < 4; ++ i ) 
     39  for ( int i = 1; i < 4; ++ i ) 
    3940    delete this->split_vertices[i]; 
    40   for ( int i = 0; i < 4; ++ i ) 
     41  for ( int i = 0; i < 5; ++ i ) 
    4142    delete this->new_entities[i]; 
    4243} 
    4344 
    44 void MBMeshOutputFunctor::print_vert_crud( MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags ) 
     45void MBMeshOutputFunctor::print_vert_crud( 
     46  MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags ) 
    4547{ 
    4648  std::cout << "+ {"; 
     
    6466 
    6567  std::cout << " >\n"; 
     68  //std::cout << "##############################\n"; 
     69  //this->mesh_out->list_entities( 0, 1 ); 
     70  //std::cout << "##############################\n"; 
    6671} 
    6772 
     
    145150    } 
    146151  std::vector<MBSplitVerticesBase*>::iterator vit; 
    147   for ( vit = this->split_vertices.begin(); vit != this->split_vertices.end(); ++ vit ) 
     152  vit = this->split_vertices.begin(); 
     153  ++ vit; // Skip split_vertices[0] since it's empty. 
     154  ++ vit; // Skip split_vertices[1] since those entries already have global IDs... they exist in the input mesh. 
     155  for ( /* skip */; vit != this->split_vertices.end(); ++ vit ) 
     156    { 
     157    (*vit)->assign_global_ids( gids ); 
     158    } 
     159  for ( vit = this->new_entities.begin(); vit != this->new_entities.end(); ++ vit ) 
    148160    { 
    149161    if ( *vit ) 
    150162      (*vit)->assign_global_ids( gids ); 
    151163    } 
    152   for ( vit = this->new_entities.begin(); vit != this->new_entities.end(); ++ vit ) 
    153     { 
    154     if ( *vit ) 
    155       (*vit)->assign_global_ids( gids ); 
    156     } 
     164
     165 
     166void MBMeshOutputFunctor::exchange_handles( MBParallelComm* comm ) 
     167
    157168} 
    158169 
     
    172183} 
    173184 
    174 MBEntityHandle MBMeshOutputFunctor::operator () ( MBEntityHandle vhash, const double* vcoords, const void* vtags ) 
     185MBEntityHandle MBMeshOutputFunctor::map_vertex( MBEntityHandle vhash, const double* vcoords, const void* vtags ) 
    175186{ 
    176187  if ( this->input_is_output ) 
     
    180191    } 
    181192  MBEntityHandle vertex_handle; 
    182   bool newly_created = this->new_entities[0]->find_or_create( 
    183     &vhash, vcoords, vertex_handle, this->proc_partition_counts ); 
     193  bool newly_created = this->new_entities[1]->find_or_create( 
     194    &vhash, vcoords, vertex_handle, this->proc_partition_counts, false ); 
    184195  if ( newly_created ) 
    185196    { 
     197    std::vector<int> gid; 
    186198    this->assign_tags( vertex_handle, vtags ); 
     199    if ( this->tag_manager->get_input_gids( 1, &vhash, gid ) == MB_SUCCESS ) 
     200      { 
     201      this->tag_manager->set_gid( vertex_handle, gid[0] ); 
     202      } 
    187203    } 
    188204  if ( ! vertex_handle ) 
     
    197213{ 
    198214  MBEntityHandle vertex_handle; 
    199   if ( nvhash == 1 ) 
    200     { 
    201     vertex_handle = (*this)( *vhash, vcoords, vtags ); 
    202     } 
    203   else if ( nvhash < 4 ) 
     215  if ( nvhash < 4 ) 
    204216    { 
    205217    bool newly_created = this->split_vertices[nvhash]->find_or_create( 
    206       vhash, vcoords, vertex_handle, this->proc_partition_counts ); 
     218      vhash, vcoords, vertex_handle, this->proc_partition_counts, true ); 
    207219    if ( newly_created ) 
    208220      { 
     
    213225      std::cerr << "Could not insert mid-edge vertex!\n"; 
    214226      } 
     227    std::cout << "(-" << nvhash << "-) "; 
    215228    this->print_vert_crud( vertex_handle, nvhash, vhash, vcoords, vtags ); 
    216229    } 
     
    226239{ 
    227240  std::cout << h << " "; 
     241  if ( ! this->input_is_output ) 
     242    { 
     243    // FIXME: Copy to output mesh 
     244    } 
    228245  this->elem_vert.push_back( h ); 
    229   if ( ! this->input_is_output ) 
    230     { 
    231     // FIXME: Copy to output mesh 
    232     } 
    233246} 
    234247 
     
    237250  MBEntityHandle elem_handle; 
    238251  int nconn = this->elem_vert.size(); 
    239   if ( this->mesh_out->create_element( etyp, &this->elem_vert[0], nconn, elem_handle ) == MB_FAILURE ) 
    240     { 
    241     std::cerr << " *** "; 
    242     } 
    243   std::cout << "---------> " << elem_handle << " ( " << etyp << " )\n\n"; 
    244 #if 0 
    245252  bool newly_created = this->new_entities[nconn]->create_element( 
    246     &this->elem_vert[0], elem_handle, this->proc_partition_counts ); 
     253    etyp, nconn, &this->elem_vert[0], elem_handle, this->proc_partition_counts ); 
    247254  if ( newly_created ) 
    248255    { 
     256    std::cout << " *** "; 
    249257    // FIXME: Handle tag assignment for elements as well as vertices 
    250258    //this->assign_tags( elem_handle, this->element_tag_data ); 
    251259    } 
    252 #endif // 0 
     260  std::cout << "---------> " << elem_handle << " ( " << etyp << " )\n\n"; 
    253261  this->elem_vert.clear(); 
    254262} 
  • MOAB/trunk/refiner/MBMeshOutputFunctor.hpp

    r2029 r2048  
    4949  void print_vert_crud( MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags ); 
    5050  void assign_global_ids( MBParallelComm* comm ); 
     51  void exchange_handles( MBParallelComm* comm ); 
    5152 
    5253  void assign_tags( MBEntityHandle vhandle, const void* vtags ); 
    5354 
    54   virtual MBEntityHandle operator () ( MBEntityHandle vhash, const double* vcoords, const void* vtags ); 
     55  virtual MBEntityHandle map_vertex( MBEntityHandle vhash, const double* vcoords, const void* vtags ); 
    5556  virtual MBEntityHandle operator () ( int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags ); 
    5657  virtual void operator () ( MBEntityHandle h ); 
  • MOAB/trunk/refiner/MBProcessSet.cpp

    r2029 r2048  
    9696      } 
    9797    } 
     98  for ( i = procs.size(); i < MAX_SHARING_PROCS; ++ i ) 
     99    { 
     100    procs.push_back( -1 ); // pad with invalid values 
     101    } 
    98102  return rank_owner; 
    99103} 
  • MOAB/trunk/refiner/MBRefinerTagManager.cpp

    r1971 r2048  
    33#include "MBInterface.hpp" 
    44#include "MBParallelComm.hpp" 
     5#include "MBParallelConventions.h" 
     6#include "MBTagConventions.hpp" 
    57 
    68#include <iostream> 
     9#include <stdexcept> 
    710#include <assert.h> 
    811 
    912/// Construct an evaluator. 
    1013MBRefinerTagManager::MBRefinerTagManager( MBInterface* in_mesh, MBInterface* out_mesh ) 
     14  : shared_procs_in( 5 * MAX_SHARING_PROCS, -1 ), shared_procs_out( MAX_SHARING_PROCS, -1 ) 
    1115{ 
    1216  assert( in_mesh ); 
     
    1822  this->reset_vertex_tags(); 
    1923  MBParallelComm* ipcomm = MBParallelComm::get_pcomm( this->input_mesh, 0 ); 
     24  MBParallelComm* opcomm = 0; 
     25  if ( this->output_mesh != this->input_mesh ) 
     26    { 
     27    opcomm = MBParallelComm::get_pcomm( this->output_mesh, 0 ); 
     28    if ( ! opcomm ) 
     29      { 
     30      std::cout << "Creating opcomm: " << opcomm << "\n"; 
     31      opcomm = new MBParallelComm( this->output_mesh, MPI_COMM_WORLD ); 
     32      } 
     33    } 
     34  else 
     35    { 
     36    opcomm = ipcomm; 
     37    } 
     38 
    2039  if ( ipcomm ) 
    2140    { 
    2241    ipcomm->get_shared_proc_tags( 
    23       this->tag_psproc, this->tag_psprocs, 
    24       this->tag_pshand, this->tag_pshands, 
    25       this->tag_pstatus ); 
    26     } 
    27   else 
    28     { 
    29     this->tag_psproc = this->tag_psprocs = 0; 
    30     this->tag_pshand = this->tag_pshands = 0; 
    31     this->tag_pstatus = 0; 
    32     } 
     42      this->tag_ipsproc, this->tag_ipsprocs, 
     43      this->tag_ipshand, this->tag_ipshands, 
     44      this->tag_ipstatus ); 
     45    } 
     46  else 
     47    { 
     48    this->tag_ipsproc = this->tag_ipsprocs = 0; 
     49    this->tag_ipshand = this->tag_ipshands = 0; 
     50    this->tag_ipstatus = 0; 
     51    } 
     52 
     53  if ( opcomm ) 
     54    { 
     55    opcomm->get_shared_proc_tags( 
     56      this->tag_opsproc, this->tag_opsprocs, 
     57      this->tag_opshand, this->tag_opshands, 
     58      this->tag_opstatus ); 
     59    } 
     60  else 
     61    { 
     62    this->tag_opsproc = this->tag_opsprocs = 0; 
     63    this->tag_opshand = this->tag_opshands = 0; 
     64    this->tag_opstatus = 0; 
     65    } 
     66 
     67  this->rank = 
     68    ipcomm ? ipcomm->proc_config().proc_rank() : 
     69    ( opcomm ? opcomm->proc_config().proc_rank() : 0 ); 
     70 
     71  // Create the mesh global ID tags if they aren't already there. 
     72  int zero = 0; 
     73  MBErrorCode result; 
     74  result = this->input_mesh->tag_create( 
     75    GLOBAL_ID_TAG_NAME, sizeof(int), MB_TAG_DENSE, MB_TYPE_INTEGER, this->tag_igid, &zero, true ); 
     76  if ( result != MB_SUCCESS && result != MB_ALREADY_ALLOCATED ) 
     77    { 
     78    throw new std::logic_error( "Unable to find input mesh global ID tag \"" GLOBAL_ID_TAG_NAME "\"" ); 
     79    } 
     80  result = this->output_mesh->tag_create( 
     81    GLOBAL_ID_TAG_NAME, sizeof(int), MB_TAG_DENSE, MB_TYPE_INTEGER, this->tag_ogid, &zero, true ); 
     82  if ( result != MB_SUCCESS && result != MB_ALREADY_ALLOCATED ) 
     83    { 
     84    throw new std::logic_error( "Unable to find/create output mesh global ID tag \"" GLOBAL_ID_TAG_NAME "\"" ); 
     85    } 
     86 
     87  std::cout 
     88    << "psproc:  " << this->tag_ipsproc  << ", " << this->tag_opsproc << "\n" 
     89    << "psprocs: " << this->tag_ipsprocs << ", " << this->tag_opsprocs << "\n" 
     90    << "pshand:  " << this->tag_ipshand  << ", " << this->tag_opshand << "\n" 
     91    << "pshands: " << this->tag_ipshands << ", " << this->tag_opshands << "\n" 
     92    << "pstatus: " << this->tag_ipstatus << ", " << this->tag_opstatus << "\n" 
     93    << "gid:     " << this->tag_igid     << ", " << this->tag_ogid     << "\n"; 
    3394} 
    3495 
     
    182243  byte_offset = it->second; 
    183244} 
     245 
     246/**\brief Retrieve the global ID of each input entity and push it onto the output vector. 
     247  * 
     248  * The \a gids array is emptied by this call before any new values are added. 
     249  * Note that this routine fetches global IDs from the input mesh, not the output mesh; 
     250  * your entity handles must be from the input mesh. 
     251  * 
     252  * @param[in] ents An array of entities in the input mesh whose global IDs you desire 
     253  * @param[in] n The number of entities in the \a ents array. 
     254  * @param[out] gids A vector to contain the resulting global IDs. 
     255  * @retval A MOAB error code as supplied by the MBInterface::tag_get_data() call. 
     256  */ 
     257int MBRefinerTagManager::get_input_gids( int n, const MBEntityHandle* ents, std::vector<int>& gids ) 
     258{ 
     259  int stat; 
     260  gids.clear(); 
     261  for ( int i = 0; i < n; ++ i ) 
     262    { 
     263    int gid = -1; 
     264    stat |= this->input_mesh->tag_get_data( this->tag_igid, ents + i, 1, &gid ); 
     265    gids.push_back( gid ); 
     266    } 
     267  return stat; 
     268} 
     269 
     270/**\brief Retrieve the global ID of each output entity and push it onto the output vector. 
     271  * 
     272  * The \a gids array is emptied by this call before any new values are added. 
     273  * Note that this routine fetches global IDs from the output mesh, not the input mesh; 
     274  * your entity handles must be from the output mesh. 
     275  * Also, be aware that many output entities will not have global IDs assigned; 
     276  * only those vertices which exist in the input mesh are guaranteed to have global IDs 
     277  * assigned to them -- vertices that only exist in the output mesh and all higher-dimensional 
     278  * output entities have no global IDs assigned until after a complete subdivision pass has been made. 
     279  * 
     280  * @param[in] ents An array of entities in the output mesh whose global IDs you desire 
     281  * @param[in] n The number of entities in the \a ents array. 
     282  * @param[out] gids A vector to contain the resulting global IDs. 
     283  * @retval A MOAB error code as supplied by the MBInterface::tag_get_data() call. 
     284  */ 
     285int MBRefinerTagManager::get_output_gids( int n, const MBEntityHandle* ents, std::vector<int>& gids ) 
     286{ 
     287  int stat; 
     288  gids.clear(); 
     289  for ( int i = 0; i < n; ++ i ) 
     290    { 
     291    int gid = -1; 
     292    stat |= this->output_mesh->tag_get_data( this->tag_igid, ents + i, 1, &gid ); 
     293    gids.push_back( gid ); 
     294    } 
     295  return stat; 
     296} 
     297 
     298/**\brief Assign a global ID to an output entity. 
     299  * 
     300  * @param[in] ent The entity whose ID will be set 
     301  * @param[out] id The global ID 
     302  * @retval An error code as returned by MBInterface::tag_set_data(). 
     303  */ 
     304int MBRefinerTagManager::set_gid( MBEntityHandle ent, int gid ) 
     305{ 
     306  return this->output_mesh->tag_set_data( this->tag_ogid, &ent, 1, &gid ); 
     307} 
     308 
     309/**\brief Set parallel status and sharing process list on an entity. 
     310  * 
     311  * This sets tag values for the PARALLEL_STATUS and one of PARALLEL_SHARED_PROC or PARALLEL_SHARED_PROCS tags 
     312  * if \a procs contains any processes (the current process is assumed <b>not</b> to be set in \a procs). 
     313  * 
     314  * @param[in] ent_handle The entity whose information will be set 
     315  * @param[in] procs The set of sharing processes. 
     316  */ 
     317void MBRefinerTagManager::set_sharing( MBEntityHandle ent_handle, MBProcessSet& procs ) 
     318{ 
     319  int pstat; 
     320  if ( procs.get_process_members( this->rank, this->shared_procs_out ) ) 
     321    pstat = PSTATUS_SHARED | PSTATUS_INTERFACE; 
     322  else 
     323    pstat = PSTATUS_SHARED | PSTATUS_INTERFACE | PSTATUS_NOT_OWNED; 
     324  if ( this->shared_procs_out[0] >= 0 ) 
     325    { 
     326    // assert( MAX_SHARING_PROCS > 1 ); 
     327    // Since get_process_members pads to MAX_SHARING_PROCS, this will be work: 
     328    if ( this->shared_procs_out[1] <= 0 ) 
     329      { 
     330      //std::cout << "  (proc )"; 
     331      this->output_mesh->tag_set_data( this->tag_opsproc, &ent_handle, 1, &this->shared_procs_out[0] ); 
     332      this->output_mesh->tag_set_data( this->tag_opstatus, &ent_handle, 1, &pstat ); 
     333      } 
     334    else 
     335      { 
     336      //std::cout << "  (procS)"; 
     337      this->output_mesh->tag_set_data( this->tag_opsprocs, &ent_handle, 1, &this->shared_procs_out[0] ); 
     338      this->output_mesh->tag_set_data( this->tag_opstatus, &ent_handle, 1, &pstat ); 
     339      } 
     340    } 
     341  else 
     342    { 
     343    //std::cout << "  (none )"; 
     344    } 
     345  //std::cout << " new pstat: " << pstat << "\n"; 
     346} 
     347 
     348/**\brief Determine the subset of processes which all share the specified entities. 
     349  * 
     350  * This is used to determine which processes an output entity should reside on when 
     351  * it is defined using several input entities (such as vertices). 
     352  */ 
     353void MBRefinerTagManager::get_common_processes( 
     354  int num, const MBEntityHandle* src, MBProcessSet& common_shared_procs, bool on_output_mesh ) 
     355{ 
     356  MBInterface* mesh; 
     357  MBTag psproc; 
     358  MBTag psprocs; 
     359  if ( on_output_mesh ) 
     360    { 
     361    mesh = this->output_mesh; 
     362    psproc = this->tag_opsproc; 
     363    psprocs = this->tag_opsprocs; 
     364    } 
     365  else 
     366    { 
     367    mesh = this->input_mesh; 
     368    psproc = this->tag_ipsproc; 
     369    psprocs = this->tag_ipsprocs; 
     370    } 
     371  bool first_ent = true; 
     372  common_shared_procs.clear(); 
     373  for ( int i = 0; i < num; ++ i ) 
     374    { 
     375    MBEntityHandle ent_in = src[i]; 
     376    //std::cout << "<(" << ent_in << ")>"; 
     377    int stat; 
     378    bool got = false; 
     379    this->current_shared_procs.clear(); 
     380    stat = mesh->tag_get_data( psproc, &ent_in, 1, &this->shared_procs_in[0] ); 
     381    if ( stat == MB_SUCCESS && this->shared_procs_in[0] != -1 ) 
     382      { 
     383      got = true; 
     384      //std::cout << " s" << this->rank << " s" << this->shared_procs_in[0] << " | "; 
     385      this->shared_procs_in[1] = -1; 
     386      } 
     387    stat = mesh->tag_get_data( psprocs, &ent_in, 1, &this->shared_procs_in[0] ); 
     388    if ( stat == MB_SUCCESS && this->shared_procs_in[0] != -1 ) 
     389      { 
     390      got = true; 
     391      int i; 
     392      /* 
     393      for ( i = 0; i < MAX_SHARING_PROCS && this->shared_procs_in[i] != -1; ++ i ) 
     394        std::cout << " m" << this->shared_procs_in[i]; 
     395      std::cout << " | "; 
     396      */ 
     397      } 
     398    if ( got ) 
     399      { 
     400      this->current_shared_procs.set_process_members( this->shared_procs_in ); 
     401      this->current_shared_procs.set_process_member( this->rank ); 
     402      if ( first_ent ) 
     403        { 
     404        common_shared_procs.unite( this->current_shared_procs ); 
     405        first_ent = false; 
     406        } 
     407      else 
     408        { 
     409        common_shared_procs.intersect( this->current_shared_procs ); 
     410        } 
     411      } 
     412    else 
     413      { 
     414      //std::cout << " not shared | "; 
     415      } 
     416    } 
     417  std::cout << "    Common procs " << common_shared_procs; 
     418  std::cout << "\n"; 
     419} 
     420 
  • MOAB/trunk/refiner/MBRefinerTagManager.hpp

    r2029 r2048  
    2929#include "MBTypes.h" // for MB_DLL_EXPORT 
    3030 
     31#include "MBProcessSet.hpp" 
     32 
    3133#include <vector> 
    3234 
     
    5254  MBInterface* get_output_mesh() { return this->output_mesh; } 
    5355 
    54   MBTag parallel_status() { return this->tag_pstatus; } 
    55   MBTag shared_proc() { return this->tag_psproc; } 
    56   MBTag shared_procs() { return this->tag_psprocs; } 
     56  MBTag input_parallel_status() { return this->tag_ipstatus; } 
     57  MBTag input_shared_proc() { return this->tag_ipsproc; } 
     58  MBTag input_shared_procs() { return this->tag_ipsprocs; } 
     59 
     60  int get_input_gids( int n, const MBEntityHandle* ents, std::vector<int>& gids ); 
     61  int get_output_gids( int n, const MBEntityHandle* ents, std::vector<int>& gids ); 
     62  int set_gid( MBEntityHandle ent, int gid ); 
     63 
     64  void set_sharing( MBEntityHandle ent_handle, MBProcessSet& procs ); 
     65  void get_common_processes( int num, const MBEntityHandle* src, MBProcessSet& common_shared_procs, bool on_output_mesh = true ); 
    5766 
    5867protected: 
     
    6271  MBInterface* input_mesh; 
    6372  MBInterface* output_mesh; 
    64   MBTag tag_pstatus; // Handle for PARALLEL_STATUS on mesh_in 
    65   MBTag tag_psprocs; // Handle for PARALLEL_SHARED_PROCS on mesh_in 
    66   MBTag tag_psproc;  // Handle for PARALLEL_SHARED_PROC on mesh_in 
    67   MBTag tag_pshands; // Handle for PARALLEL_SHARED_HANDLES on mesh_in 
    68   MBTag tag_pshand;  // Handle for PARALLEL_SHARED_HANDLE on mesh_in 
     73  MBTag tag_ipstatus; // Handle for PARALLEL_STATUS on mesh_in 
     74  MBTag tag_ipsprocs; // Handle for PARALLEL_SHARED_PROCS on mesh_in 
     75  MBTag tag_ipsproc;  // Handle for PARALLEL_SHARED_PROC on mesh_in 
     76  MBTag tag_ipshands; // Handle for PARALLEL_SHARED_HANDLES on mesh_in 
     77  MBTag tag_ipshand;  // Handle for PARALLEL_SHARED_HANDLE on mesh_in 
     78  MBTag tag_igid;     // Handle for global IDs on mesh_in 
     79  MBTag tag_opstatus; // Handle for PARALLEL_STATUS on mesh_out 
     80  MBTag tag_opsprocs; // Handle for PARALLEL_SHARED_PROCS on mesh_out 
     81  MBTag tag_opsproc;  // Handle for PARALLEL_SHARED_PROC on mesh_out 
     82  MBTag tag_opshands; // Handle for PARALLEL_SHARED_HANDLES on mesh_out 
     83  MBTag tag_opshand;  // Handle for PARALLEL_SHARED_HANDLE on mesh_out 
     84  MBTag tag_ogid;     // Handle for global IDs on mesh_out 
     85  int rank; 
     86  std::vector<int> shared_procs_in; // Used to hold procs sharing an input vert. 
     87  std::vector<int> shared_procs_out; // Used to hold procs sharing an output entity. 
     88  MBProcessSet current_shared_procs; // Holds process list as it is being accumulated 
    6989}; 
    7090 
  • MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp

    r1918 r2048  
    3131  this->corner_tags.resize( 8 ); // Hex has 8 verts (this is a pointer, not the actual tag data) 
    3232  this->corner_handles.resize( 8 ); // Hex has 8 verts (this is a pointer, not actual hash data) 
     33  this->input_is_output = false; // Until we know better 
    3334} 
    3435 
     
    6263  for ( int n = 0; n < num_nodes; ++ n ) 
    6364    { 
    64     this->corner_handles[n] = conn[n]; 
    6565    if ( imesh->get_coords( &conn[n], 1, &corner_coords[6 * n + 3] ) != MB_SUCCESS ) 
    6666      { 
     
    7575        return false; 
    7676        } 
     77      } 
     78    if ( this->input_is_output ) 
     79      { 
     80      this->corner_handles[n] = conn[n]; 
     81      } 
     82    else 
     83      { 
     84      this->corner_handles[n] = this->output_functor->map_vertex( conn[n], &corner_coords[6 * n], tag_data ); 
     85#if 0 
     86      std::cout << "#+# " << this->corner_handles[n] << " < " 
     87        << corner_coords[ 6 * n + 3 ] << ", " 
     88        << corner_coords[ 6 * n + 4 ] << ", " 
     89        << corner_coords[ 6 * n + 5 ] << ">\n"; 
     90#endif // 0 
    7791      } 
    7892    this->corner_tags[n] = tag_data; 
     
    171185  this->tag_manager = tmgr; 
    172186  this->tag_assigner->set_tag_manager( tmgr ); 
     187  this->input_is_output = ( this->tag_manager->get_input_mesh() == this->tag_manager->get_output_mesh() ); 
    173188  //this->tag_assigner->set_edge_size_evaluator( this->edge_size_evaluator ); 
    174189  return this->MBEntityRefiner::prepare( tmgr, ofunc ); 
  • MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp

    r2029 r2048  
    5757  std::vector<void*> corner_tags; 
    5858  std::vector<MBEntityHandle> corner_handles; 
     59  bool input_is_output; 
    5960 
    6061  static int template_index[64][2]; 
  • MOAB/trunk/refiner/MBSplitVertices.cpp

    r2029 r2048  
    77{ 
    88  this->tag_manager = tag_mgr; 
    9   this->mesh_in  = tag_mgr->get_input_mesh(); 
    109  this->mesh_out = tag_mgr->get_output_mesh(); 
    11   this->shared_procs_in.resize( MAX_SHARING_PROCS ); 
    12   MBParallelComm* ipcomm = MBParallelComm::get_pcomm( this->mesh_in, 0 ); 
    13   this->rank = ipcomm ? ipcomm->proc_config().proc_rank() : 0; 
    14   int zero = 0; 
    15   MBErrorCode result = this->mesh_out->tag_create( 
    16     GLOBAL_ID_TAG_NAME, sizeof(int), MB_TAG_DENSE, MB_TYPE_INTEGER, this->tag_gid, &zero, true ); 
    17   if ( result != MB_SUCCESS && result != MB_ALREADY_ALLOCATED ) 
    18     return; 
    1910} 
    2011 
     
    2314} 
    2415 
    25 /// Determine which processes will contain an output vertex given the split vertices defining it. 
    26 void MBSplitVerticesBase::update_partition_counts( 
    27   int num, const MBEntityHandle* split_src, std::map<MBProcessSet,int>& proc_partition_counts ) 
    28 { 
    29   this->begin_vertex_procs(); 
    30   for ( int i = 0; i < num; ++ i ) 
    31     { 
    32     this->add_vertex_procs( split_src[i] ); 
    33     } 
    34   this->end_vertex_procs(); 
    35   proc_partition_counts[this->common_shared_procs]++; 
    36 } 
    37  
    38 /// Prepare to compute the processes on which a new split-vertex will live. 
    39 void MBSplitVerticesBase::begin_vertex_procs() 
    40 { 
    41   this->first_vertex = true; 
    42   this->common_shared_procs.clear(); 
    43 } 
    44  
    45 /// Call this for each existing corner vertex used to define a split-vertex. 
    46 void MBSplitVerticesBase::add_vertex_procs( MBEntityHandle vert_in ) 
    47 { 
    48   int stat; 
    49   bool got = false; 
    50   this->current_shared_procs.clear(); 
    51   stat = this->mesh_in->tag_get_data( 
    52     this->tag_manager->shared_proc(), &vert_in, 1, &this->shared_procs_in[0] ); 
    53   if ( stat == MB_SUCCESS && this->shared_procs_in[0] != -1 ) 
    54     { 
    55     got = true; 
    56     std::cout << " s" << this->rank << " s" << this->shared_procs_in[0] << " | "; 
    57     this->shared_procs_in[1] = -1; 
    58     } 
    59   stat = this->mesh_in->tag_get_data( 
    60     this->tag_manager->shared_procs(), &vert_in, 1, &this->shared_procs_in[0] ); 
    61   if ( stat == MB_SUCCESS && this->shared_procs_in[0] != -1 ) 
    62     { 
    63     got = true; 
    64     int i; 
    65     for ( i = 0; i < MAX_SHARING_PROCS && this->shared_procs_in[i] != -1; ++ i ) 
    66       std::cout << " m" << this->shared_procs_in[i]; 
    67     std::cout << " | "; 
    68     } 
    69   if ( got ) 
    70     { 
    71     this->current_shared_procs.set_process_members( this->shared_procs_in ); 
    72     this->current_shared_procs.set_process_member( this->rank ); 
    73     if ( this->first_vertex ) 
    74       { 
    75       this->common_shared_procs.unite( this->current_shared_procs ); 
    76       this->first_vertex = false; 
    77       } 
    78     else 
    79       { 
    80       this->common_shared_procs.intersect( this->current_shared_procs ); 
    81       } 
    82     } 
    83   else 
    84     { 
    85     std::cout << " not shared | "; 
    86     } 
    87 } 
    88  
    89 /// Call this once after all the add_vertex_procs() calls for a split-vertex to prepare queues for the second stage MPI send.  
    90 void MBSplitVerticesBase::end_vertex_procs() 
    91 { 
    92   std::cout << "    Common procs " << this->common_shared_procs; 
    93   std::cout << "\n"; 
    94   // FIXME: Here is where we add the vertex to the appropriate queues. 
    95 } 
    96  
    97 void MBSplitVerticesBase::set_sharing( MBEntityHandle ent_handle, MBProcessSet& procs ) 
    98 { 
    99   int pstat; 
    100   if ( procs.get_process_members( this->rank, this->shared_procs_out ) ) 
    101     pstat = PSTATUS_SHARED | PSTATUS_INTERFACE; 
    102   else 
    103     pstat = PSTATUS_SHARED | PSTATUS_INTERFACE | PSTATUS_NOT_OWNED; 
    104   int sps = this->shared_procs_out.size(); 
    105   std::cout << " new pstat: " << pstat << " sps: " << sps << "\n"; 
    106   switch ( sps ) 
    107     { 
    108   case 0: 
    109     break; 
    110   case 1: 
    111     this->mesh_out->tag_set_data( this->tag_manager->shared_proc(), &ent_handle, 1, &this->shared_procs_out[0] ); 
    112     this->mesh_out->tag_set_data( this->tag_manager->parallel_status(), &ent_handle, 1, &pstat ); 
    113     break; 
    114   default: 
    115     this->mesh_out->tag_set_data( this->tag_manager->shared_procs(), &ent_handle, sps, &this->shared_procs_out[0] ); 
    116     this->mesh_out->tag_set_data( this->tag_manager->parallel_status(), &ent_handle, 1, &pstat ); 
    117     break; 
    118     } 
    119 } 
    120  
  • MOAB/trunk/refiner/MBSplitVertices.hpp

    r2030 r2048  
    9191  virtual bool find_or_create( 
    9292    const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle, 
     93    std::map<MBProcessSet,int>& proc_partition_counts, bool handles_on_output_mesh ) = 0; 
     94 
     95  virtual bool create_element( 
     96    MBEntityType etyp, int nconn, const MBEntityHandle* elem_verts, MBEntityHandle& elem_handle, 
    9397    std::map<MBProcessSet,int>& proc_partition_counts ) = 0; 
    9498 
    95   virtual bool create_element( 
    96     const MBEntityHandle* split_src, MBEntityHandle& elem_handle, 
    97     std::map<MBProcessSet,int>& proc_partition_counts ) = 0; 
    98  
    9999  virtual void assign_global_ids( std::map<MBProcessSet,int>& gids ) = 0; 
    100100 
    101   /// Determine which processes will contain an output vertex given the split vertices defining it. 
    102   void update_partition_counts( int num, const MBEntityHandle* split_src, std::map<MBProcessSet,int>& proc_partition_counts ); 
    103  
    104   /// Prepare to compute the processes on which a new split-vertex will live. 
    105   void begin_vertex_procs(); 
    106  
    107   /// Call this for each existing corner vertex used to define a split-vertex. 
    108   void add_vertex_procs( MBEntityHandle vert_in ); 
    109  
    110   /// Call this once after all the add_vertex_procs() calls for a split-vertex to prepare queues for the second stage MPI send.  
    111   void end_vertex_procs(); 
    112  
    113   /// Set the tags which indicate sharing process(es) for an entity. 
    114   void set_sharing( MBEntityHandle vert_handle, MBProcessSet& procs ); 
    115  
    116   MBInterface* mesh_in; // Input mesh. Needed to determine tag values on split_src verts 
    117101  MBInterface* mesh_out; // Output mesh. Needed for new vertex set in vert_handle 
    118102  MBRefinerTagManager* tag_manager; 
    119   std::vector<int> shared_procs_in; // Used to hold procs sharing an input vert. 
    120   std::vector<int> shared_procs_out; // Used to hold procs sharing an output vert. 
    121103  std::vector<int> split_gids; // Used to hold global IDs of split vertices 
    122   MBProcessSet current_shared_procs; // Holds process list as it is being accumulated 
    123104  MBProcessSet common_shared_procs; // Holds intersection of several shared_procs_ins. 
    124   int rank; // This process' rank. 
    125   bool first_vertex; // True just after begin_vertex_procs() is called. 
    126   MBTag tag_gid; 
    127105}; 
    128106 
     
    144122  virtual bool find_or_create( 
    145123    const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle, 
    146     std::map<MBProcessSet,int>& proc_partition_counts ); 
     124    std::map<MBProcessSet,int>& proc_partition_counts, bool handles_on_output_mesh ); 
    147125  virtual bool create_element( 
    148     const MBEntityHandle* split_src, MBEntityHandle& elem_handle, 
     126    MBEntityType etyp, int nconn, const MBEntityHandle* split_src, MBEntityHandle& elem_handle, 
    149127    std::map<MBProcessSet,int>& proc_partition_counts ); 
    150128 
     
    157135  : MBSplitVerticesBase( tag_mgr ) 
    158136{ 
    159   this->shared_procs_in.resize( _n * MAX_SHARING_PROCS ); 
    160137  this->split_gids.resize( _n ); 
    161138} 
     
    169146bool MBSplitVertices<_n>::find_or_create( 
    170147  const MBEntityHandle* split_src, const double* coords, MBEntityHandle& vert_handle, 
    171   std::map<MBProcessSet,int>& proc_partition_counts
     148  std::map<MBProcessSet,int>& proc_partition_counts, bool handles_on_output_mesh
    172149{ 
    173150  // Get the global IDs of the input vertices 
    174151  int stat; 
    175   for ( int i = 0; i < _n; ++ i ) 
    176     { 
    177     int gid = -1; 
    178     stat = this->mesh_in->tag_get_data( this->tag_gid, split_src + i, 1, &gid ); 
    179     this->split_gids[i] = gid; 
     152  if ( handles_on_output_mesh ) 
     153    { 
     154    stat = this->tag_manager->get_output_gids( _n, split_src, this->split_gids ); 
     155    } 
     156  else 
     157    { 
     158    stat = this->tag_manager->get_input_gids( _n, split_src, this->split_gids ); 
    180159    } 
    181160  MBSplitVertexIndex<_n> key( &this->split_gids[0] ); 
     
    183162  if ( it == this->end() ) 
    184163    { 
    185     this->update_partition_counts( _n, split_src, proc_partition_counts ); 
     164    std::cout << " wrt output: " << handles_on_output_mesh << " "; 
     165    this->tag_manager->get_common_processes( _n, split_src, this->common_shared_procs, handles_on_output_mesh ); 
     166    proc_partition_counts[this->common_shared_procs]++; 
    186167    key.set_common_processes( this->common_shared_procs ); 
    187     if ( this->mesh_out->create_vertex( coords, vert_handle ) != MB_SUCCESS ) 
     168    if ( this->mesh_out->create_vertex( coords + 3, vert_handle ) != MB_SUCCESS ) 
    188169      { 
    189170      return false; 
    190171      } 
    191172    (*this)[key] = vert_handle; 
    192     this->set_sharing( vert_handle, this->common_shared_procs ); 
     173    this->tag_manager->set_sharing( vert_handle, this->common_shared_procs ); 
    193174    return true; 
    194175    } 
     
    199180template< int _n > 
    200181bool MBSplitVertices<_n>::create_element( 
    201   const MBEntityHandle* split_src, MBEntityHandle& elem_handle, 
     182  MBEntityType etyp, int nconn, const MBEntityHandle* elem_verts, MBEntityHandle& elem_handle, 
    202183  std::map<MBProcessSet,int>& proc_partition_counts ) 
    203184{ 
     185  // Get the global IDs of the input vertices 
     186  int stat; 
     187  stat = this->tag_manager->get_input_gids( _n, elem_verts, this->split_gids ); 
     188  MBSplitVertexIndex<_n> key( &this->split_gids[0] ); 
     189  this->tag_manager->get_common_processes( _n, elem_verts, this->common_shared_procs ); 
     190  proc_partition_counts[this->common_shared_procs]++; 
     191  key.set_common_processes( this->common_shared_procs ); 
     192  if ( this->mesh_out->create_element( etyp, elem_verts, nconn, elem_handle ) != MB_SUCCESS ) 
     193    { 
     194    return false; 
     195    } 
     196  (*this)[key] = elem_handle; 
     197  this->tag_manager->set_sharing( elem_handle, this->common_shared_procs ); 
     198  return true; 
    204199} 
    205200 
     
    211206    { 
    212207    int gid = gids[it->first.process_set] ++; 
    213     this->mesh_out->tag_set_data( this->tag_gid, &it->second, 1, &gid ); 
    214     std::cout << "Assigning " << it->first << " -> " << gid << "\n"; 
     208    this->tag_manager->set_gid( it->second, gid ); 
     209    std::cout << "Assigning entity: " << it->first << " GID: " << gid << "\n"; 
    215210    } 
    216211} 
  • MOAB/trunk/refiner/test_mesh_refiner.cpp

    r2024 r2048  
    3131 
    3232  // Create the input mesh and, if -new-mesh is specified, an output mesh 
    33   const char* ifname = argc > 1 ? argv[1] : "/home/dcthomp/fourVolsBare.cub"; 
     33  const char* ifname = argc > 1 ? argv[1] : "fourVolsBare.cub"; 
    3434  bool input_is_output = ( argc > 2 && ! strcmp( argv[2], "-new-mesh" ) ) ? false : true; 
    3535  MBInterface* imesh = new MBCore( rank, nprocs ); 
     
    4242#endif // USE_MPI 
    4343 
    44   // Get the global ID tag so we can set things up for resolve_shared_ents 
    45   //MBTag tag_gid; 
    46   //imesh->tag_create( PARALLEL_GID_TAG_NAME, sizeof( int ), MB_TAG_DENSE, MB_TYPE_INTEGER, tag_gid, default_gid ); 
    47  
    48 #ifdef USE_MPI 
    49   // Get tags for the various data-distributed mesh annotations 
    50   MBTag tag_sproc; 
    51   MBTag tag_sprocs; 
    52   MBTag tag_shand; 
    53   MBTag tag_shands; 
    54   MBTag tag_pstat; 
    55   ipcomm->get_shared_proc_tags( tag_sproc, tag_sprocs, tag_shand, tag_shands, tag_pstat ); 
    56   MBTag tag_part = ipcomm->partition_tag(); 
    57 #endif // USE_MPI 
    58  
    5944  MBEntityHandle set_handle; 
    6045  std::ostringstream parallel_options; 
    6146  parallel_options 
    62     << "PARALLEL=BCAST_DELETE" << ";" // NB: You can also use READ_DELETE here. 
     47    << "PARALLEL=BCAST_DELETE" << ";" // NB: You can use BCAST_DELETE or READ_DELETE here. 
    6348    << "PARTITION=MATERIAL_SET" << ";" 
    6449    //<< "PARTITION_DISTRIBUTE" << ";" 
     
    8469  imesh->list_entities( 0, 1 ); 
    8570#endif // USE_MPI 
     71  std::ostringstream ifs; 
     72  ifs << "prerefiner." << nprocs << "." << rank << ".vtk"; 
     73  imesh->write_mesh( ifs.str().c_str() ); 
    8674 
    8775  // The refiner will need an implicit function to be used as an indicator function for subdivision: 
     
    9785  eref->set_edge_size_evaluator( eval ); 
    9886  MBRange ents_to_refine; 
    99   ents_to_refine.insert( set_handle ); 
     87  imesh->get_entities_by_type( set_handle, MBTET, ents_to_refine ); // refine just the tets 
     88  //ents_to_refine.insert( set_handle ); // refine everything multiple times (because subsets are not disjoint) 
    10089  mref->refine( ents_to_refine ); 
    10190 
     91  std::ostringstream ofs; 
     92  ofs << "refiner." << nprocs << "." << rank << ".vtk"; 
     93  omesh->write_mesh( ofs.str().c_str() ); 
    10294  // Print out the results, one process at a time 
    10395#ifdef USE_MPI