Changeset 2048
- Timestamp:
- 08/25/08 18:02:57 (3 months ago)
- Files:
-
- MOAB/trunk/refiner/MBEntityRefiner.hpp (modified) (4 diffs)
- MOAB/trunk/refiner/MBMeshOutputFunctor.cpp (modified) (9 diffs)
- MOAB/trunk/refiner/MBMeshOutputFunctor.hpp (modified) (1 diff)
- MOAB/trunk/refiner/MBProcessSet.cpp (modified) (1 diff)
- MOAB/trunk/refiner/MBRefinerTagManager.cpp (modified) (3 diffs)
- MOAB/trunk/refiner/MBRefinerTagManager.hpp (modified) (3 diffs)
- MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp (modified) (4 diffs)
- MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp (modified) (1 diff)
- MOAB/trunk/refiner/MBSplitVertices.cpp (modified) (2 diffs)
- MOAB/trunk/refiner/MBSplitVertices.hpp (modified) (7 diffs)
- MOAB/trunk/refiner/test_mesh_refiner.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
MOAB/trunk/refiner/MBEntityRefiner.hpp
r2029 r2048 53 53 * the other used to finalize the creation of the entity by specifying its type. 54 54 * 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 * 55 59 * \author David Thompson 56 60 * \author Philippe Pebay … … 73 77 public: 74 78 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 */ 76 89 MBEntityHandle operator () ( MBEntityHandle h0, MBEntityHandle h1, const double* vcoords, const void* vtags ) 77 90 { … … 81 94 return (*this)( 2, harr, vcoords, vtags ); 82 95 } 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 */ 83 105 virtual MBEntityHandle operator () ( MBEntityHandle h0, MBEntityHandle h1, MBEntityHandle h2, const double* vcoords, const void* vtags ) 84 106 { … … 89 111 return (*this)( 3, harr, vcoords, vtags ); 90 112 } 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 */ 91 121 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 */ 92 126 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 */ 93 132 virtual void operator () ( MBEntityType etyp ) = 0; 94 133 }; MOAB/trunk/refiner/MBMeshOutputFunctor.cpp
r2024 r2048 27 27 // Hold information about newly-created mesh entities (other than split vertices) 28 28 // 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 ); 30 30 this->new_entities[0] = new MBSplitVertices<0>( this->tag_manager ); 31 31 this->new_entities[1] = new MBSplitVertices<1>( this->tag_manager ); 32 32 this->new_entities[2] = new MBSplitVertices<2>( this->tag_manager ); 33 33 this->new_entities[3] = new MBSplitVertices<3>( this->tag_manager ); 34 this->new_entities[4] = new MBSplitVertices<4>( this->tag_manager ); 34 35 } 35 36 36 37 MBMeshOutputFunctor::~MBMeshOutputFunctor() 37 38 { 38 for ( int i = 0; i < 4; ++ i )39 for ( int i = 1; i < 4; ++ i ) 39 40 delete this->split_vertices[i]; 40 for ( int i = 0; i < 4; ++ i )41 for ( int i = 0; i < 5; ++ i ) 41 42 delete this->new_entities[i]; 42 43 } 43 44 44 void MBMeshOutputFunctor::print_vert_crud( MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags ) 45 void MBMeshOutputFunctor::print_vert_crud( 46 MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags ) 45 47 { 46 48 std::cout << "+ {"; … … 64 66 65 67 std::cout << " >\n"; 68 //std::cout << "##############################\n"; 69 //this->mesh_out->list_entities( 0, 1 ); 70 //std::cout << "##############################\n"; 66 71 } 67 72 … … 145 150 } 146 151 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 ) 148 160 { 149 161 if ( *vit ) 150 162 (*vit)->assign_global_ids( gids ); 151 163 } 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 166 void MBMeshOutputFunctor::exchange_handles( MBParallelComm* comm ) 167 { 157 168 } 158 169 … … 172 183 } 173 184 174 MBEntityHandle MBMeshOutputFunctor:: operator ()( MBEntityHandle vhash, const double* vcoords, const void* vtags )185 MBEntityHandle MBMeshOutputFunctor::map_vertex( MBEntityHandle vhash, const double* vcoords, const void* vtags ) 175 186 { 176 187 if ( this->input_is_output ) … … 180 191 } 181 192 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 ); 184 195 if ( newly_created ) 185 196 { 197 std::vector<int> gid; 186 198 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 } 187 203 } 188 204 if ( ! vertex_handle ) … … 197 213 { 198 214 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 ) 204 216 { 205 217 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 ); 207 219 if ( newly_created ) 208 220 { … … 213 225 std::cerr << "Could not insert mid-edge vertex!\n"; 214 226 } 227 std::cout << "(-" << nvhash << "-) "; 215 228 this->print_vert_crud( vertex_handle, nvhash, vhash, vcoords, vtags ); 216 229 } … … 226 239 { 227 240 std::cout << h << " "; 241 if ( ! this->input_is_output ) 242 { 243 // FIXME: Copy to output mesh 244 } 228 245 this->elem_vert.push_back( h ); 229 if ( ! this->input_is_output )230 {231 // FIXME: Copy to output mesh232 }233 246 } 234 247 … … 237 250 MBEntityHandle elem_handle; 238 251 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 0245 252 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 ); 247 254 if ( newly_created ) 248 255 { 256 std::cout << " *** "; 249 257 // FIXME: Handle tag assignment for elements as well as vertices 250 258 //this->assign_tags( elem_handle, this->element_tag_data ); 251 259 } 252 #endif // 0 260 std::cout << "---------> " << elem_handle << " ( " << etyp << " )\n\n"; 253 261 this->elem_vert.clear(); 254 262 } MOAB/trunk/refiner/MBMeshOutputFunctor.hpp
r2029 r2048 49 49 void print_vert_crud( MBEntityHandle vout, int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags ); 50 50 void assign_global_ids( MBParallelComm* comm ); 51 void exchange_handles( MBParallelComm* comm ); 51 52 52 53 void assign_tags( MBEntityHandle vhandle, const void* vtags ); 53 54 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 ); 55 56 virtual MBEntityHandle operator () ( int nvhash, MBEntityHandle* vhash, const double* vcoords, const void* vtags ); 56 57 virtual void operator () ( MBEntityHandle h ); MOAB/trunk/refiner/MBProcessSet.cpp
r2029 r2048 96 96 } 97 97 } 98 for ( i = procs.size(); i < MAX_SHARING_PROCS; ++ i ) 99 { 100 procs.push_back( -1 ); // pad with invalid values 101 } 98 102 return rank_owner; 99 103 } MOAB/trunk/refiner/MBRefinerTagManager.cpp
r1971 r2048 3 3 #include "MBInterface.hpp" 4 4 #include "MBParallelComm.hpp" 5 #include "MBParallelConventions.h" 6 #include "MBTagConventions.hpp" 5 7 6 8 #include <iostream> 9 #include <stdexcept> 7 10 #include <assert.h> 8 11 9 12 /// Construct an evaluator. 10 13 MBRefinerTagManager::MBRefinerTagManager( MBInterface* in_mesh, MBInterface* out_mesh ) 14 : shared_procs_in( 5 * MAX_SHARING_PROCS, -1 ), shared_procs_out( MAX_SHARING_PROCS, -1 ) 11 15 { 12 16 assert( in_mesh ); … … 18 22 this->reset_vertex_tags(); 19 23 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 20 39 if ( ipcomm ) 21 40 { 22 41 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"; 33 94 } 34 95 … … 182 243 byte_offset = it->second; 183 244 } 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 */ 257 int 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 */ 285 int 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 */ 304 int 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 */ 317 void 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 */ 353 void 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 29 29 #include "MBTypes.h" // for MB_DLL_EXPORT 30 30 31 #include "MBProcessSet.hpp" 32 31 33 #include <vector> 32 34 … … 52 54 MBInterface* get_output_mesh() { return this->output_mesh; } 53 55 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 ); 57 66 58 67 protected: … … 62 71 MBInterface* input_mesh; 63 72 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 69 89 }; 70 90 MOAB/trunk/refiner/MBSimplexTemplateRefiner.cpp
r1918 r2048 31 31 this->corner_tags.resize( 8 ); // Hex has 8 verts (this is a pointer, not the actual tag data) 32 32 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 33 34 } 34 35 … … 62 63 for ( int n = 0; n < num_nodes; ++ n ) 63 64 { 64 this->corner_handles[n] = conn[n];65 65 if ( imesh->get_coords( &conn[n], 1, &corner_coords[6 * n + 3] ) != MB_SUCCESS ) 66 66 { … … 75 75 return false; 76 76 } 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 77 91 } 78 92 this->corner_tags[n] = tag_data; … … 171 185 this->tag_manager = tmgr; 172 186 this->tag_assigner->set_tag_manager( tmgr ); 187 this->input_is_output = ( this->tag_manager->get_input_mesh() == this->tag_manager->get_output_mesh() ); 173 188 //this->tag_assigner->set_edge_size_evaluator( this->edge_size_evaluator ); 174 189 return this->MBEntityRefiner::prepare( tmgr, ofunc ); MOAB/trunk/refiner/MBSimplexTemplateRefiner.hpp
r2029 r2048 57 57 std::vector<void*> corner_tags; 58 58 std::vector<MBEntityHandle> corner_handles; 59 bool input_is_output; 59 60 60 61 static int template_index[64][2]; MOAB/trunk/refiner/MBSplitVertices.cpp
r2029 r2048 7 7 { 8 8 this->tag_manager = tag_mgr; 9 this->mesh_in = tag_mgr->get_input_mesh();10 9 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;19 10 } 20 11 … … 23 14 } 24 15 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 else79 {80 this->common_shared_procs.intersect( this->current_shared_procs );81 }82 }83 else84 {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 else103 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 91 91 virtual bool find_or_create( 92 92 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, 93 97 std::map<MBProcessSet,int>& proc_partition_counts ) = 0; 94 98 95 virtual bool create_element(96 const MBEntityHandle* split_src, MBEntityHandle& elem_handle,97 std::map<MBProcessSet,int>& proc_partition_counts ) = 0;98 99 99 virtual void assign_global_ids( std::map<MBProcessSet,int>& gids ) = 0; 100 100 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 verts117 101 MBInterface* mesh_out; // Output mesh. Needed for new vertex set in vert_handle 118 102 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.121 103 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 accumulated123 104 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;127 105 }; 128 106 … … 144 122 virtual bool find_or_create( 145 123 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 ); 147 125 virtual bool create_element( 148 const MBEntityHandle* split_src, MBEntityHandle& elem_handle,126 MBEntityType etyp, int nconn, const MBEntityHandle* split_src, MBEntityHandle& elem_handle, 149 127 std::map<MBProcessSet,int>& proc_partition_counts ); 150 128 … … 157 135 : MBSplitVerticesBase( tag_mgr ) 158 136 { 159 this->shared_procs_in.resize( _n * MAX_SHARING_PROCS );160 137 this->split_gids.resize( _n ); 161 138 } … … 169 146 bool MBSplitVertices<_n>::find_or_create( 170 147 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 ) 172 149 { 173 150 // Get the global IDs of the input vertices 174 151 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 ); 180 159 } 181 160 MBSplitVertexIndex<_n> key( &this->split_gids[0] ); … … 183 162 if ( it == this->end() ) 184 163 { 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]++; 186 167 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 ) 188 169 { 189 170 return false; 190 171 } 191 172 (*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 ); 193 174 return true; 194 175 } … … 199 180 template< int _n > 200 181 bool MBSplitVertices<_n>::create_element( 201 const MBEntityHandle* split_src, MBEntityHandle& elem_handle,182 MBEntityType etyp, int nconn, const MBEntityHandle* elem_verts, MBEntityHandle& elem_handle, 202 183 std::map<MBProcessSet,int>& proc_partition_counts ) 203 184 { 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; 204 199 } 205 200 … … 211 206 { 212 207 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"; 215 210 } 216 211 } MOAB/trunk/refiner/test_mesh_refiner.cpp
r2024 r2048 31 31 32 32 // 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"; 34 34 bool input_is_output = ( argc > 2 && ! strcmp( argv[2], "-new-mesh" ) ) ? false : true; 35 35 MBInterface* imesh = new MBCore( rank, nprocs ); … … 42 42 #endif // USE_MPI 43 43 44 // Get the global ID tag so we can set things up for resolve_shared_ents45 //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_MPI49 // Get tags for the various data-distributed mesh annotations50 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_MPI58 59 44 MBEntityHandle set_handle; 60 45 std::ostringstream parallel_options; 61 46 parallel_options 62 << "PARALLEL=BCAST_DELETE" << ";" // NB: You can also useREAD_DELETE here.47 << "PARALLEL=BCAST_DELETE" << ";" // NB: You can use BCAST_DELETE or READ_DELETE here. 63 48 << "PARTITION=MATERIAL_SET" << ";" 64 49 //<< "PARTITION_DISTRIBUTE" << ";" … … 84 69 imesh->list_entities( 0, 1 ); 85 70 #endif // USE_MPI 71 std::ostringstream ifs; 72 ifs << "prerefiner." << nprocs << "." << rank << ".vtk"; 73 imesh->write_mesh( ifs.str().c_str() ); 86 74 87 75 // The refiner will need an implicit function to be used as an indicator function for subdivision: … … 97 85 eref->set_edge_size_evaluator( eval ); 98 86 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) 100 89 mref->refine( ents_to_refine ); 101 90 91 std::ostringstream ofs; 92 ofs << "refiner." << nprocs << "." << rank << ".vtk"; 93 omesh->write_mesh( ofs.str().c_str() ); 102 94 // Print out the results, one process at a time 103 95 #ifdef USE_MPI
