Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
MeshGeneration.cpp
Go to the documentation of this file.
00001 /*
00002  * MGen.cpp
00003  *
00004  */
00005 
00006 #include "moab/MeshGeneration.hpp"
00007 #include "moab/MergeMesh.hpp"
00008 #include <iostream>
00009 #include <ctime>
00010 #include <vector>
00011 #ifdef WIN32 /* windows */
00012 #include <time.h>
00013 #endif
00014 
00015 #ifdef MOAB_HAVE_MPI
00016 #include "moab_mpi.h"
00017 #include "moab/ParallelComm.hpp"
00018 #include "MBParallelConventions.h"
00019 #include "moab/ParallelMergeMesh.hpp"
00020 #endif
00021 #include "moab/ReadUtilIface.hpp"
00022 
00023 using std::endl;
00024 using std::string;
00025 using std::vector;
00026 
00027 namespace moab
00028 {
00029 
00030 MeshGeneration::MeshGeneration( Interface* impl,
00031 #ifdef MOAB_HAVE_MPI
00032                                 ParallelComm* comm,
00033 #endif
00034                                 EntityHandle rset )
00035     : mb( impl ),
00036 #ifdef MOAB_HAVE_MPI
00037       pc( comm ),
00038 #endif
00039       cset( rset )
00040 {
00041     // ErrorCode error;
00042 
00043 #ifdef MOAB_HAVE_MPI
00044     // Get the Parallel Comm instance to prepare all new sets to work in parallel
00045     // in case the user did not provide any arguments
00046     if( !comm ) pc = moab::ParallelComm::get_pcomm( mb, 0 );
00047 #endif
00048 }
00049 
00050 MeshGeneration::~MeshGeneration() {}
00051 
00052 ErrorCode MeshGeneration::BrickInstance( MeshGeneration::BrickOpts& opts )
00053 {
00054     int A = opts.A, B = opts.B, C = opts.C, M = opts.M, N = opts.N, K = opts.K;
00055     int blockSize = opts.blockSize;
00056     double xsize = opts.xsize, ysize = opts.ysize, zsize = opts.zsize;  // The size of the region
00057     bool newMergeMethod = opts.newMergeMethod;
00058     bool quadratic      = opts.quadratic;
00059     bool tetra          = opts.tetra;
00060     bool adjEnts        = opts.adjEnts;
00061     bool parmerge       = opts.parmerge;
00062 
00063 #ifdef MOAB_HAVE_MPI
00064     int GL          = opts.GL;  // number of ghost layers
00065     bool keep_skins = opts.keep_skins;
00066 #endif
00067 
00068     int rank = 0, size = 1;
00069 #ifndef _MSC_VER /* windows */
00070     clock_t tt = clock();
00071 #endif
00072 #ifdef MOAB_HAVE_MPI
00073     rank = pc->rank();
00074     size = pc->size();
00075 #endif
00076 
00077     if( M * N * K != size )
00078     {
00079         if( 0 == rank ) std::cout << "M*N*K = " << M * N * K << " != size = " << size << "\n";
00080 
00081         return MB_FAILURE;
00082     }
00083     // Determine m, n, k for processor rank
00084     int m, n, k;
00085     k            = rank / ( M * N );
00086     int leftover = rank % ( M * N );
00087     n            = leftover / M;
00088     m            = leftover % M;
00089 
00090     // Used for nodes increments
00091     int q = ( quadratic ) ? 2 : 1;
00092     // Used for element increments
00093     int factor = ( tetra ) ? 6 : 1;
00094 
00095     double dx = xsize / ( A * M * blockSize * q );  // Distance between 2 nodes in x direction
00096     double dy = ysize / ( B * N * blockSize * q );  // Distance between 2 nodes in y direction
00097     double dz = zsize / ( C * K * blockSize * q );  // Distance between 2 nodes in z direction
00098 
00099     int NX  = ( q * M * A * blockSize + 1 );
00100     int NY  = ( q * N * B * blockSize + 1 );
00101     int nex = M * A * blockSize;  // Number of elements in x direction, used for global id on element
00102     int ney = N * B * blockSize;  // Number of elements in y direction ...
00103     // int NZ = (K * C * blockSize + 1); // Not used
00104     int blockSize1       = q * blockSize + 1;  // Used for vertices
00105     long num_total_verts = (long)NX * NY * ( K * C * blockSize + 1 );
00106     if( 0 == rank )
00107     {
00108         std::cout << "Generate mesh on " << size << " processors \n";
00109         std::cout << "Total number of vertices: " << num_total_verts << "\n";
00110     }
00111     // int xstride = 1;
00112     int ystride = blockSize1;
00113 
00114     int zstride = blockSize1 * blockSize1;
00115     // Generate the block at (a, b, c); it will represent a partition, it will get a partition tag
00116 
00117     ReadUtilIface* iface;
00118     ErrorCode rval = mb->query_interface( iface );MB_CHK_SET_ERR( rval, "Can't get reader interface" );
00119 
00120     Tag global_id_tag;
00121     rval = mb->tag_get_handle( "GLOBAL_ID", 1, MB_TYPE_INTEGER, global_id_tag );MB_CHK_SET_ERR( rval, "Can't get global id tag" );
00122 
00123     // set global ids
00124     Tag new_id_tag;
00125     if( !parmerge )
00126     {
00127         rval =
00128             mb->tag_get_handle( "HANDLEID", sizeof( long ), MB_TYPE_OPAQUE, new_id_tag, MB_TAG_CREAT | MB_TAG_DENSE );MB_CHK_SET_ERR( rval, "Can't get handle id tag" );
00129     }
00130     Tag part_tag;
00131     int dum_id = -1;
00132     rval =
00133         mb->tag_get_handle( "PARALLEL_PARTITION", 1, MB_TYPE_INTEGER, part_tag, MB_TAG_CREAT | MB_TAG_SPARSE, &dum_id );MB_CHK_SET_ERR( rval, "Can't get parallel partition tag" );
00134 
00135     Range wsets;  // write only part sets
00136     Range localVerts;
00137     Range all3dcells;
00138     for( int a = 0; a < A; a++ )
00139     {
00140         for( int b = 0; b < B; b++ )
00141         {
00142             for( int c = 0; c < C; c++ )
00143             {
00144                 // We will generate (q*block + 1)^3 vertices, and block^3 hexas; q is 1 for linear,
00145                 // 2 for quadratic the global id of the vertices will come from m, n, k, a, b, c x
00146                 // will vary from  m*A*q*block + a*q*block to m*A*q*block + (a+1)*q*block etc;
00147                 int num_nodes = blockSize1 * blockSize1 * blockSize1;
00148 
00149                 vector< double* > arrays;
00150                 EntityHandle startv;
00151                 rval = iface->get_node_coords( 3, num_nodes, 0, startv, arrays );MB_CHK_SET_ERR( rval, "Can't get node coords" );
00152 
00153                 // Will start with the lower corner:
00154                 int x  = m * A * q * blockSize + a * q * blockSize;
00155                 int y  = n * B * q * blockSize + b * q * blockSize;
00156                 int z  = k * C * q * blockSize + c * q * blockSize;
00157                 int ix = 0;
00158                 vector< int > gids( num_nodes );
00159                 vector< long > lgids( num_nodes );
00160                 Range verts( startv, startv + num_nodes - 1 );
00161                 for( int kk = 0; kk < blockSize1; kk++ )
00162                 {
00163                     for( int jj = 0; jj < blockSize1; jj++ )
00164                     {
00165                         for( int ii = 0; ii < blockSize1; ii++ )
00166                         {
00167                             arrays[0][ix] = ( x + ii ) * dx;
00168                             arrays[1][ix] = ( y + jj ) * dy;
00169                             arrays[2][ix] = ( z + kk ) * dz;
00170                             gids[ix]      = 1 + ( x + ii ) + ( y + jj ) * NX + ( z + kk ) * ( NX * NY );
00171                             if( !parmerge )
00172                                 lgids[ix] = 1 + ( x + ii ) + ( y + jj ) * NX + (long)( z + kk ) * ( NX * NY );
00173                             // Set int tags, some nice values?
00174 
00175                             ix++;
00176                         }
00177                     }
00178                 }
00179 
00180                 rval = mb->tag_set_data( global_id_tag, verts, &gids[0] );MB_CHK_SET_ERR( rval, "Can't set global ids to vertices" );
00181                 if( !parmerge )
00182                 {
00183                     rval = mb->tag_set_data( new_id_tag, verts, &lgids[0] );MB_CHK_SET_ERR( rval, "Can't set the new handle id tags" );
00184                 }
00185                 localVerts.merge( verts );
00186                 int num_hexas = blockSize * blockSize * blockSize;
00187                 int num_el    = num_hexas * factor;
00188 
00189                 EntityHandle starte;  // Connectivity
00190                 EntityHandle* conn;
00191                 int num_v_per_elem = 8;
00192                 if( quadratic )
00193                 {
00194                     num_v_per_elem = 27;
00195                     rval           = iface->get_element_connect( num_el, 27, MBHEX, 0, starte, conn );MB_CHK_SET_ERR( rval, "Can't get element connectivity" );
00196                 }
00197                 else if( tetra )
00198                 {
00199                     num_v_per_elem = 4;
00200                     rval           = iface->get_element_connect( num_el, 4, MBTET, 0, starte, conn );MB_CHK_SET_ERR( rval, "Can't get element connectivity" );
00201                 }
00202                 else
00203                 {
00204                     rval = iface->get_element_connect( num_el, 8, MBHEX, 0, starte, conn );MB_CHK_SET_ERR( rval, "Can't get element connectivity" );
00205                 }
00206 
00207                 Range cells( starte, starte + num_el - 1 );  // Should be elements
00208                 // Fill cells
00209                 ix = 0;
00210                 // Identify the elements at the lower corner, for their global ids
00211                 int xe = m * A * blockSize + a * blockSize;
00212                 int ye = n * B * blockSize + b * blockSize;
00213                 int ze = k * C * blockSize + c * blockSize;
00214                 gids.resize( num_el );
00215                 lgids.resize( num_el );
00216                 int ie = 0;  // Index now in the elements, for global ids
00217                 for( int kk = 0; kk < blockSize; kk++ )
00218                 {
00219                     for( int jj = 0; jj < blockSize; jj++ )
00220                     {
00221                         for( int ii = 0; ii < blockSize; ii++ )
00222                         {
00223                             EntityHandle corner = startv + q * ii + q * jj * ystride + q * kk * zstride;
00224                             // These could overflow for large numbers
00225                             gids[ie] = 1 + ( ( xe + ii ) + ( ye + jj ) * nex + ( ze + kk ) * ( nex * ney ) ) *
00226                                                factor;  // 6 more for tetra
00227                             lgids[ie] = 1 + ( ( xe + ii ) + ( ye + jj ) * nex + (long)( ze + kk ) * ( nex * ney ) ) *
00228                                                 factor;  // 6 more for tetra
00229                             // EntityHandle eh = starte + ie;
00230 
00231                             ie++;
00232                             if( quadratic )
00233                             {
00234                                 //                    4   ----- 19   -----  7
00235                                 //                .   |                 .   |
00236                                 //            16         25         18      |
00237                                 //         .          |          .          |
00238                                 //      5   ----- 17   -----  6             |
00239                                 //      |            12       | 23         15
00240                                 //      |                     |             |
00241                                 //      |     20      |  26   |     22      |
00242                                 //      |                     |             |
00243                                 //     13         21  |      14             |
00244                                 //      |             0   ----- 11   -----  3
00245                                 //      |         .           |         .
00246                                 //      |      8         24   |     10
00247                                 //      |  .                  |  .
00248                                 //      1   -----  9   -----  2
00249                                 //
00250                                 conn[ix]      = corner;
00251                                 conn[ix + 1]  = corner + 2;
00252                                 conn[ix + 2]  = corner + 2 + 2 * ystride;
00253                                 conn[ix + 3]  = corner + 2 * ystride;
00254                                 conn[ix + 4]  = corner + 2 * zstride;
00255                                 conn[ix + 5]  = corner + 2 + 2 * zstride;
00256                                 conn[ix + 6]  = corner + 2 + 2 * ystride + 2 * zstride;
00257                                 conn[ix + 7]  = corner + 2 * ystride + 2 * zstride;
00258                                 conn[ix + 8]  = corner + 1;                              // 0-1
00259                                 conn[ix + 9]  = corner + 2 + ystride;                    // 1-2
00260                                 conn[ix + 10] = corner + 1 + 2 * ystride;                // 2-3
00261                                 conn[ix + 11] = corner + ystride;                        // 3-0
00262                                 conn[ix + 12] = corner + zstride;                        // 0-4
00263                                 conn[ix + 13] = corner + 2 + zstride;                    // 1-5
00264                                 conn[ix + 14] = corner + 2 + 2 * ystride + zstride;      // 2-6
00265                                 conn[ix + 15] = corner + 2 * ystride + zstride;          // 3-7
00266                                 conn[ix + 16] = corner + 1 + 2 * zstride;                // 4-5
00267                                 conn[ix + 17] = corner + 2 + ystride + 2 * zstride;      // 5-6
00268                                 conn[ix + 18] = corner + 1 + 2 * ystride + 2 * zstride;  // 6-7
00269                                 conn[ix + 19] = corner + ystride + 2 * zstride;          // 4-7
00270                                 conn[ix + 20] = corner + 1 + zstride;                    // 0154
00271                                 conn[ix + 21] = corner + 2 + ystride + zstride;          // 1265
00272                                 conn[ix + 22] = corner + 1 + 2 * ystride + zstride;      // 2376
00273                                 conn[ix + 23] = corner + ystride + zstride;              // 0374
00274                                 conn[ix + 24] = corner + 1 + ystride;                    // 0123
00275                                 conn[ix + 25] = corner + 1 + ystride + 2 * zstride;      // 4567
00276                                 conn[ix + 26] = corner + 1 + ystride + zstride;          // center
00277                                 ix += 27;
00278                             }
00279                             else if( tetra )
00280                             {
00281                                 //        E      H
00282                                 //     F     G
00283                                 //
00284                                 //        A     D
00285                                 //     B     C
00286                                 EntityHandle AA = corner;
00287                                 EntityHandle BB = corner + 1;
00288                                 EntityHandle CC = corner + 1 + ystride;
00289                                 EntityHandle D  = corner + ystride;
00290                                 EntityHandle E  = corner + zstride;
00291                                 EntityHandle F  = corner + 1 + zstride;
00292                                 EntityHandle G  = corner + 1 + ystride + zstride;
00293                                 EntityHandle H  = corner + ystride + zstride;
00294 
00295                                 // tet EDHG
00296                                 conn[ix]     = E;
00297                                 conn[ix + 1] = D;
00298                                 conn[ix + 2] = H;
00299                                 conn[ix + 3] = G;
00300 
00301                                 // tet ABCF
00302                                 conn[ix + 4] = AA;
00303                                 conn[ix + 5] = BB;
00304                                 conn[ix + 6] = CC;
00305                                 conn[ix + 7] = F;
00306 
00307                                 // tet ADEF
00308                                 conn[ix + 8]  = AA;
00309                                 conn[ix + 9]  = D;
00310                                 conn[ix + 10] = E;
00311                                 conn[ix + 11] = F;
00312 
00313                                 // tet CGDF
00314                                 conn[ix + 12] = CC;
00315                                 conn[ix + 13] = G;
00316                                 conn[ix + 14] = D;
00317                                 conn[ix + 15] = F;
00318 
00319                                 // tet ACDF
00320                                 conn[ix + 16] = AA;
00321                                 conn[ix + 17] = CC;
00322                                 conn[ix + 18] = D;
00323                                 conn[ix + 19] = F;
00324 
00325                                 // tet DGEF
00326                                 conn[ix + 20] = D;
00327                                 conn[ix + 21] = G;
00328                                 conn[ix + 22] = E;
00329                                 conn[ix + 23] = F;
00330                                 ix += 24;
00331                                 for( int ff = 0; ff < factor - 1; ff++ )
00332                                 {
00333                                     gids[ie] = gids[ie - 1] + 1;  // 6 more for tetra
00334 
00335                                     // eh = starte + ie;
00336 
00337                                     ie++;
00338                                 }
00339                             }
00340                             else
00341                             {  // Linear hex
00342                                 conn[ix]     = corner;
00343                                 conn[ix + 1] = corner + 1;
00344                                 conn[ix + 2] = corner + 1 + ystride;
00345                                 conn[ix + 3] = corner + ystride;
00346                                 conn[ix + 4] = corner + zstride;
00347                                 conn[ix + 5] = corner + 1 + zstride;
00348                                 conn[ix + 6] = corner + 1 + ystride + zstride;
00349                                 conn[ix + 7] = corner + ystride + zstride;
00350                                 ix += 8;
00351                             }
00352                         }
00353                     }
00354                 }
00355 
00356                 EntityHandle part_set;
00357                 rval = mb->create_meshset( MESHSET_SET, part_set );MB_CHK_SET_ERR( rval, "Can't create mesh set" );
00358                 rval = mb->add_entities( part_set, cells );MB_CHK_SET_ERR( rval, "Can't add entities to set" );
00359                 all3dcells.merge( cells );
00360                 // update adjacencies now, because some elements are new;
00361                 rval = iface->update_adjacencies( starte, num_el, num_v_per_elem, conn );MB_CHK_SET_ERR( rval, "Can't update adjacencies" );
00362                 // If needed, add all edges and faces
00363                 if( adjEnts )
00364                 {
00365                     // Generate all adj entities dimension 1 and 2 (edges and faces/ tri or qua)
00366                     Range edges, faces;
00367                     rval = mb->get_adjacencies( cells, 1, true, edges, Interface::UNION );MB_CHK_SET_ERR( rval, "Can't get edges" );
00368                     rval = mb->get_adjacencies( cells, 2, true, faces, Interface::UNION );MB_CHK_SET_ERR( rval, "Can't get faces" );
00369                     // rval = mb->add_entities(part_set, edges);MB_CHK_SET_ERR(rval, "Can't add
00370                     // edges to partition set"); rval = mb->add_entities(part_set,
00371                     // faces);MB_CHK_SET_ERR(rval, "Can't add faces to partition set");
00372                 }
00373 
00374                 rval = mb->tag_set_data( global_id_tag, cells, &gids[0] );MB_CHK_SET_ERR( rval, "Can't set global ids to elements" );
00375                 if( !parmerge )
00376                 {
00377                     rval = mb->tag_set_data( new_id_tag, cells, &lgids[0] );MB_CHK_SET_ERR( rval, "Can't set new ids to elements" );
00378                 }
00379                 int part_num = a + m * A + ( b + n * B ) * ( M * A ) + ( c + k * C ) * ( M * A * N * B );
00380                 rval         = mb->tag_set_data( part_tag, &part_set, 1, &part_num );MB_CHK_SET_ERR( rval, "Can't set part tag on set" );
00381                 wsets.insert( part_set );
00382             }
00383         }
00384     }
00385 
00386     mb->add_entities( cset, all3dcells );
00387     rval = mb->add_entities( cset, wsets );MB_CHK_SET_ERR( rval, "Can't add entity sets" );
00388 #ifdef MOAB_HAVE_MPI
00389     pc->partition_sets() = wsets;
00390 #endif
00391 
00392     /*
00393     // Before merge locally
00394     rval = mb->write_file("test0.h5m", 0, ";;PARALLEL=WRITE_PART");MB_CHK_SET_ERR(rval, "Can't write
00395     in parallel, before merging");
00396     */
00397     // After the mesh is generated on each proc, merge the vertices
00398     MergeMesh mm( mb );
00399 
00400     // rval = mb->get_entities_by_dimension(0, 3, all3dcells);MB_CHK_SET_ERR(rval, "Can't get all 3d
00401     // cells elements");
00402 
00403     if( 0 == rank )
00404     {
00405 #ifndef _MSC_VER /* windows */
00406         std::cout << "generate local mesh: " << ( clock() - tt ) / (double)CLOCKS_PER_SEC << " seconds" << endl;
00407         tt = clock();
00408 #endif
00409 
00410         std::cout << "number of elements on rank 0: " << all3dcells.size() << endl;
00411         std::cout << "Total number of elements " << all3dcells.size() * size << endl;
00412         std::cout << "Element type: " << ( tetra ? "MBTET" : "MBHEX" )
00413                   << " order:" << ( quadratic ? "quadratic" : "linear" ) << endl;
00414     }
00415 
00416     if( A * B * C != 1 )
00417     {  // Merge needed
00418         if( newMergeMethod )
00419         {
00420             rval = mm.merge_using_integer_tag( localVerts, global_id_tag );MB_CHK_SET_ERR( rval, "Can't merge" );
00421         }
00422         else
00423         {
00424             rval = mm.merge_entities( all3dcells, 0.0001 );MB_CHK_SET_ERR( rval, "Can't merge" );
00425         }
00426 #ifndef _MSC_VER /* windows */
00427         if( 0 == rank )
00428         {
00429             std::cout << "merge locally: " << ( clock() - tt ) / (double)CLOCKS_PER_SEC << " seconds" << endl;
00430             tt = clock();
00431         }
00432 #endif
00433     }
00434     // if adjEnts, add now to each set
00435     if( adjEnts )
00436     {
00437         for( Range::iterator wsit = wsets.begin(); wsit != wsets.end(); ++wsit )
00438         {
00439             EntityHandle ws = *wsit;  // write set
00440             Range cells, edges, faces;
00441             rval = mb->get_entities_by_dimension( ws, 3, cells );MB_CHK_SET_ERR( rval, "Can't get cells" );
00442             rval = mb->get_adjacencies( cells, 1, false, edges, Interface::UNION );MB_CHK_SET_ERR( rval, "Can't get edges" );
00443             rval = mb->get_adjacencies( cells, 2, false, faces, Interface::UNION );MB_CHK_SET_ERR( rval, "Can't get faces" );
00444             rval = mb->add_entities( ws, edges );MB_CHK_SET_ERR( rval, "Can't add edges to partition set" );
00445             rval = mb->add_entities( ws, faces );MB_CHK_SET_ERR( rval, "Can't add faces to partition set" );
00446         }
00447     }
00448 #ifdef MOAB_HAVE_MPI
00449     if( size > 1 )
00450     {
00451 
00452         // rval = mb->create_meshset(MESHSET_SET, mesh_set);MB_CHK_SET_ERR(rval, "Can't create new
00453         // set");
00454 
00455         if( parmerge )
00456         {
00457             ParallelMergeMesh pm( pc, 0.00001 );
00458             rval = pm.merge();MB_CHK_SET_ERR( rval, "Can't resolve shared ents" );
00459 #ifndef _MSC_VER /* windows */
00460             if( 0 == rank )
00461             {
00462                 std::cout << "parallel mesh merge: " << ( clock() - tt ) / (double)CLOCKS_PER_SEC << " seconds" << endl;
00463                 tt = clock();
00464             }
00465 #endif
00466         }
00467         else
00468         {
00469             rval = pc->resolve_shared_ents( cset, -1, -1, &new_id_tag );MB_CHK_SET_ERR( rval, "Can't resolve shared ents" );
00470 #ifndef _MSC_VER /* windows */
00471             if( 0 == rank )
00472             {
00473                 std::cout << "resolve shared entities: " << ( clock() - tt ) / (double)CLOCKS_PER_SEC << " seconds"
00474                           << endl;
00475                 tt = clock();
00476             }
00477 #endif
00478         }
00479         if( !keep_skins )
00480         {  // Default is to delete the 1- and 2-dimensional entities
00481             // Delete all quads and edges
00482             Range toDelete;
00483             rval = mb->get_entities_by_dimension( cset, 1, toDelete );MB_CHK_SET_ERR( rval, "Can't get edges" );
00484 
00485             rval = mb->get_entities_by_dimension( cset, 2, toDelete );MB_CHK_SET_ERR( rval, "Can't get faces" );
00486 
00487             rval = pc->delete_entities( toDelete );MB_CHK_SET_ERR( rval, "Can't delete entities" );
00488             rval = mb->remove_entities( cset, toDelete );MB_CHK_SET_ERR( rval, "Can't remove entities from base set" );
00489             if( 0 == rank )
00490             {
00491 
00492                 std::cout << "delete edges and faces \n";
00493                 toDelete.print( std::cout );
00494 #ifndef _MSC_VER /* windows */
00495                 std::cout << ( clock() - tt ) / (double)CLOCKS_PER_SEC << " seconds" << endl;
00496                 tt = clock();
00497 #endif
00498             }
00499         }
00500         // do some ghosting if required
00501         if( GL > 0 )
00502         {
00503             rval = pc->exchange_ghost_cells( 3,   // int ghost_dim
00504                                              0,   // int bridge_dim
00505                                              GL,  // int num_layers
00506                                              0,   // int addl_ents
00507                                              true );MB_CHK_ERR( rval );  // bool store_remote_handles
00508 #ifndef _MSC_VER                 /* windows */
00509             if( 0 == rank )
00510             {
00511                 std::cout << "exchange  " << GL << " ghost layer(s) :" << ( clock() - tt ) / (double)CLOCKS_PER_SEC
00512                           << " seconds" << endl;
00513                 tt = clock();
00514             }
00515 #endif
00516         }
00517     }
00518 #endif
00519 
00520     if( !parmerge )
00521     {
00522         rval = mb->tag_delete( new_id_tag );MB_CHK_SET_ERR( rval, "Can't delete new ID tag" );
00523     }
00524 
00525     return MB_SUCCESS;
00526 }
00527 
00528 } /* namespace moab */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines