MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 #include "NCHelperDomain.hpp" 00002 #include "moab/FileOptions.hpp" 00003 #include "moab/ReadUtilIface.hpp" 00004 #include "moab/IntxMesh/IntxUtils.hpp" 00005 #ifdef MOAB_HAVE_MPI 00006 #include "moab/ParallelMergeMesh.hpp" 00007 #endif 00008 #include <cmath> 00009 #include <sstream> 00010 00011 namespace moab 00012 { 00013 00014 bool NCHelperDomain::can_read_file( ReadNC* readNC, int fileId ) 00015 { 00016 std::vector< std::string >& dimNames = readNC->dimNames; 00017 00018 // If dimension names "n" AND "ni" AND "nj" AND "nv" exist then it should be the Domain grid 00019 if( ( std::find( dimNames.begin(), dimNames.end(), std::string( "n" ) ) != dimNames.end() ) && 00020 ( std::find( dimNames.begin(), dimNames.end(), std::string( "ni" ) ) != dimNames.end() ) && 00021 ( std::find( dimNames.begin(), dimNames.end(), std::string( "nj" ) ) != dimNames.end() ) && 00022 ( std::find( dimNames.begin(), dimNames.end(), std::string( "nv" ) ) != dimNames.end() ) ) 00023 { 00024 // Make sure it is CAM grid 00025 std::map< std::string, ReadNC::AttData >::iterator attIt = readNC->globalAtts.find( "source" ); 00026 if( attIt == readNC->globalAtts.end() ) return false; 00027 unsigned int sz = attIt->second.attLen; 00028 std::string att_data; 00029 att_data.resize( sz + 1 ); 00030 att_data[sz] = '\000'; 00031 int success = 00032 NCFUNC( get_att_text )( fileId, attIt->second.attVarId, attIt->second.attName.c_str(), &att_data[0] ); 00033 if( success ) return false; 00034 /*if (att_data.find("CAM") == std::string::npos) 00035 return false;*/ 00036 00037 return true; 00038 } 00039 00040 return false; 00041 } 00042 00043 ErrorCode NCHelperDomain::init_mesh_vals() 00044 { 00045 Interface*& mbImpl = _readNC->mbImpl; 00046 std::vector< std::string >& dimNames = _readNC->dimNames; 00047 std::vector< int >& dimLens = _readNC->dimLens; 00048 std::map< std::string, ReadNC::VarData >& varInfo = _readNC->varInfo; 00049 DebugOutput& dbgOut = _readNC->dbgOut; 00050 bool& isParallel = _readNC->isParallel; 00051 int& partMethod = _readNC->partMethod; 00052 ScdParData& parData = _readNC->parData; 00053 00054 ErrorCode rval; 00055 00056 // Look for names of i/j dimensions 00057 // First i 00058 std::vector< std::string >::iterator vit; 00059 unsigned int idx; 00060 if( ( vit = std::find( dimNames.begin(), dimNames.end(), "ni" ) ) != dimNames.end() ) 00061 idx = vit - dimNames.begin(); 00062 else 00063 { 00064 MB_SET_ERR( MB_FAILURE, "Couldn't find 'ni' variable" ); 00065 } 00066 iDim = idx; 00067 gDims[0] = 0; 00068 gDims[3] = dimLens[idx]; 00069 00070 // Then j 00071 if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nj" ) ) != dimNames.end() ) 00072 idx = vit - dimNames.begin(); 00073 else 00074 { 00075 MB_SET_ERR( MB_FAILURE, "Couldn't find 'nj' variable" ); 00076 } 00077 jDim = idx; 00078 gDims[1] = 0; 00079 gDims[4] = dimLens[idx]; // Add 2 for the pole points ? not needed 00080 00081 // do not use gcdims ? or use only gcdims? 00082 00083 // Try a truly 2D mesh 00084 gDims[2] = -1; 00085 gDims[5] = -1; 00086 00087 // Get number of vertices per cell 00088 if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nv" ) ) != dimNames.end() ) 00089 idx = vit - dimNames.begin(); 00090 else 00091 { 00092 MB_SET_ERR( MB_FAILURE, "Couldn't find 'nv' dimension" ); 00093 } 00094 nvDim = idx; 00095 nv = dimLens[idx]; 00096 00097 // Parse options to get subset 00098 int rank = 0, procs = 1; 00099 #ifdef MOAB_HAVE_MPI 00100 if( isParallel ) 00101 { 00102 ParallelComm*& myPcomm = _readNC->myPcomm; 00103 rank = myPcomm->proc_config().proc_rank(); 00104 procs = myPcomm->proc_config().proc_size(); 00105 } 00106 #endif 00107 if( procs > 1 ) 00108 { 00109 for( int i = 0; i < 6; i++ ) 00110 parData.gDims[i] = gDims[i]; 00111 parData.partMethod = partMethod; 00112 int pdims[3]; 00113 00114 locallyPeriodic[0] = locallyPeriodic[1] = locallyPeriodic[2] = 0; 00115 rval = ScdInterface::compute_partition( procs, rank, parData, lDims, locallyPeriodic, pdims );MB_CHK_ERR( rval ); 00116 for( int i = 0; i < 3; i++ ) 00117 parData.pDims[i] = pdims[i]; 00118 00119 dbgOut.tprintf( 1, "Partition: %dx%d (out of %dx%d)\n", lDims[3] - lDims[0], lDims[4] - lDims[1], 00120 gDims[3] - gDims[0], gDims[4] - gDims[1] ); 00121 if( 0 == rank ) 00122 dbgOut.tprintf( 1, "Contiguous chunks of size %d bytes.\n", 00123 8 * ( lDims[3] - lDims[0] ) * ( lDims[4] - lDims[1] ) ); 00124 } 00125 else 00126 { 00127 for( int i = 0; i < 6; i++ ) 00128 lDims[i] = gDims[i]; 00129 locallyPeriodic[0] = globallyPeriodic[0]; 00130 } 00131 00132 // Now get actual coordinate values for vertices and cell centers 00133 lCDims[0] = lDims[0]; 00134 00135 lCDims[3] = lDims[3]; 00136 00137 // For FV models, will always be non-periodic in j 00138 lCDims[1] = lDims[1]; 00139 lCDims[4] = lDims[4]; 00140 00141 #if 0 00142 // Resize vectors to store values later 00143 if (-1 != lDims[0]) 00144 ilVals.resize(lDims[3] - lDims[0] + 1); 00145 if (-1 != lCDims[0]) 00146 ilCVals.resize(lCDims[3] - lCDims[0] + 1); 00147 if (-1 != lDims[1]) 00148 jlVals.resize(lDims[4] - lDims[1] + 1); 00149 if (-1 != lCDims[1]) 00150 jlCVals.resize(lCDims[4] - lCDims[1] + 1); 00151 if (nTimeSteps > 0) 00152 tVals.resize(nTimeSteps); 00153 #endif 00154 00155 dbgOut.tprintf( 1, "I=%d-%d, J=%d-%d\n", lDims[0], lDims[3], lDims[1], lDims[4] ); 00156 dbgOut.tprintf( 1, "%d elements, %d vertices\n", ( lDims[3] - lDims[0] ) * ( lDims[4] - lDims[1] ), 00157 ( lDims[3] - lDims[0] ) * ( lDims[4] - lDims[1] ) * nv ); 00158 00159 // For each variable, determine the entity location type and number of levels 00160 std::map< std::string, ReadNC::VarData >::iterator mit; 00161 for( mit = varInfo.begin(); mit != varInfo.end(); ++mit ) 00162 { 00163 ReadNC::VarData& vd = ( *mit ).second; 00164 00165 // Default entLoc is ENTLOCSET 00166 if( std::find( vd.varDims.begin(), vd.varDims.end(), tDim ) != vd.varDims.end() ) 00167 { 00168 if( ( std::find( vd.varDims.begin(), vd.varDims.end(), iCDim ) != vd.varDims.end() ) && 00169 ( std::find( vd.varDims.begin(), vd.varDims.end(), jCDim ) != vd.varDims.end() ) ) 00170 vd.entLoc = ReadNC::ENTLOCFACE; 00171 else if( ( std::find( vd.varDims.begin(), vd.varDims.end(), jDim ) != vd.varDims.end() ) && 00172 ( std::find( vd.varDims.begin(), vd.varDims.end(), iCDim ) != vd.varDims.end() ) ) 00173 vd.entLoc = ReadNC::ENTLOCNSEDGE; 00174 else if( ( std::find( vd.varDims.begin(), vd.varDims.end(), jCDim ) != vd.varDims.end() ) && 00175 ( std::find( vd.varDims.begin(), vd.varDims.end(), iDim ) != vd.varDims.end() ) ) 00176 vd.entLoc = ReadNC::ENTLOCEWEDGE; 00177 } 00178 00179 // Default numLev is 0 00180 if( std::find( vd.varDims.begin(), vd.varDims.end(), levDim ) != vd.varDims.end() ) vd.numLev = nLevels; 00181 } 00182 00183 std::vector< std::string > ijdimNames( 2 ); 00184 ijdimNames[0] = "__ni"; 00185 ijdimNames[1] = "__nj"; 00186 std::string tag_name; 00187 Tag tagh; 00188 00189 // __<dim_name>_LOC_MINMAX (for slon, slat, lon and lat) 00190 for( unsigned int i = 0; i != ijdimNames.size(); i++ ) 00191 { 00192 std::vector< int > val( 2, 0 ); 00193 if( ijdimNames[i] == "__ni" ) 00194 { 00195 val[0] = lDims[0]; 00196 val[1] = lDims[3]; 00197 } 00198 else if( ijdimNames[i] == "__nj" ) 00199 { 00200 val[0] = lDims[1]; 00201 val[1] = lDims[4]; 00202 } 00203 00204 std::stringstream ss_tag_name; 00205 ss_tag_name << ijdimNames[i] << "_LOC_MINMAX"; 00206 tag_name = ss_tag_name.str(); 00207 rval = mbImpl->tag_get_handle( tag_name.c_str(), 2, MB_TYPE_INTEGER, tagh, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating conventional tag " << tag_name ); 00208 rval = mbImpl->tag_set_data( tagh, &_fileSet, 1, &val[0] );MB_CHK_SET_ERR( rval, "Trouble setting data to conventional tag " << tag_name ); 00209 if( MB_SUCCESS == rval ) dbgOut.tprintf( 2, "Conventional tag %s is created.\n", tag_name.c_str() ); 00210 } 00211 00212 // __<dim_name>_LOC_VALS (for slon, slat, lon and lat) 00213 // Assume all have the same data type as lon (expected type is float or double) 00214 switch( varInfo["xc"].varDataType ) 00215 { 00216 case NC_FLOAT: 00217 case NC_DOUBLE: 00218 break; 00219 default: 00220 MB_SET_ERR( MB_FAILURE, "Unexpected variable data type for 'lon'" ); 00221 } 00222 00223 // do not need conventional tags 00224 Tag convTagsCreated = 0; 00225 int def_val = 0; 00226 rval = mbImpl->tag_get_handle( "__CONV_TAGS_CREATED", 1, MB_TYPE_INTEGER, convTagsCreated, 00227 MB_TAG_SPARSE | MB_TAG_CREAT, &def_val );MB_CHK_SET_ERR( rval, "Trouble getting _CONV_TAGS_CREATED tag" ); 00228 int create_conv_tags_flag = 1; 00229 rval = mbImpl->tag_set_data( convTagsCreated, &_fileSet, 1, &create_conv_tags_flag );MB_CHK_SET_ERR( rval, "Trouble setting _CONV_TAGS_CREATED tag" ); 00230 00231 return MB_SUCCESS; 00232 } 00233 00234 ErrorCode NCHelperDomain::create_mesh( Range& faces ) 00235 { 00236 Interface*& mbImpl = _readNC->mbImpl; 00237 // std::string& fileName = _readNC->fileName; 00238 Tag& mGlobalIdTag = _readNC->mGlobalIdTag; 00239 // const Tag*& mpFileIdTag = _readNC->mpFileIdTag; 00240 DebugOutput& dbgOut = _readNC->dbgOut; 00241 /*int& gatherSetRank = _readNC->gatherSetRank; 00242 int& trivialPartitionShift = _readNC->trivialPartitionShift;*/ 00243 /* 00244 00245 int rank = 0; 00246 int procs = 1; 00247 #ifdef MOAB_HAVE_MPI 00248 bool& isParallel = _readNC->isParallel; 00249 if (isParallel) { 00250 ParallelComm*& myPcomm = _readNC->myPcomm; 00251 rank = myPcomm->proc_config().proc_rank(); 00252 procs = myPcomm->proc_config().proc_size(); 00253 } 00254 #endif 00255 */ 00256 00257 ErrorCode rval; 00258 int success = 0; 00259 00260 /* 00261 bool create_gathers = false; 00262 if (rank == gatherSetRank) 00263 create_gathers = true; 00264 00265 // Shift rank to obtain a rotated trivial partition 00266 int shifted_rank = rank; 00267 if (procs >= 2 && trivialPartitionShift > 0) 00268 shifted_rank = (rank + trivialPartitionShift) % procs;*/ 00269 00270 // how many will have mask 0 or 1 00271 // how many will have a fraction ? we will not instantiate all elements; only those with mask 1 00272 // ? also, not all vertices, only those that belong to mask 1 elements ? we will not care about 00273 // duplicate vertices; maybe another time ? we will start reading masks, vertices 00274 int local_elems = ( lDims[4] - lDims[1] ) * ( lDims[3] - lDims[0] ); 00275 dbgOut.tprintf( 1, "local cells: %d \n", local_elems ); 00276 00277 // count how many will be with mask 1 here 00278 // basically, read the mask variable on the local elements; 00279 std::string maskstr( "mask" ); 00280 ReadNC::VarData& vmask = _readNC->varInfo[maskstr]; 00281 00282 // mask is (nj, ni) 00283 vmask.readStarts.push_back( lDims[1] ); 00284 vmask.readStarts.push_back( lDims[0] ); 00285 vmask.readCounts.push_back( lDims[4] - lDims[1] ); 00286 vmask.readCounts.push_back( lDims[3] - lDims[0] ); 00287 std::vector< int > mask( local_elems ); 00288 success = NCFUNCAG( _vara_int )( _fileId, vmask.varId, &vmask.readStarts[0], &vmask.readCounts[0], &mask[0] ); 00289 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read int data for mask variable " ); 00290 00291 int nb_with_mask1 = 0; 00292 for( int i = 0; i < local_elems; i++ ) 00293 if( 1 == mask[i] ) nb_with_mask1++; 00294 00295 std::vector< NCDF_SIZE > startsv( 3 ); 00296 startsv[0] = vmask.readStarts[0]; 00297 startsv[1] = vmask.readStarts[1]; 00298 startsv[2] = 0; 00299 std::vector< NCDF_SIZE > countsv( 3 ); 00300 countsv[0] = vmask.readCounts[0]; 00301 countsv[1] = vmask.readCounts[1]; 00302 countsv[2] = nv; // number of vertices per element 00303 00304 // read xv and yv coords for vertices, and create elements; 00305 std::string xvstr( "xv" ); 00306 ReadNC::VarData& var_xv = _readNC->varInfo[xvstr]; 00307 std::vector< double > xv( local_elems * nv ); 00308 success = NCFUNCAG( _vara_double )( _fileId, var_xv.varId, &startsv[0], &countsv[0], &xv[0] ); 00309 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read double data for xv variable " ); 00310 00311 std::string yvstr( "yv" ); 00312 ReadNC::VarData& var_yv = _readNC->varInfo[yvstr]; 00313 std::vector< double > yv( local_elems * nv ); 00314 success = NCFUNCAG( _vara_double )( _fileId, var_yv.varId, &startsv[0], &countsv[0], &yv[0] ); 00315 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read double data for yv variable " ); 00316 00317 // read other variables, like xc, yc, frac, area 00318 std::string xcstr( "xc" ); 00319 ReadNC::VarData& var_xc = _readNC->varInfo[xcstr]; 00320 std::vector< double > xc( local_elems ); 00321 success = NCFUNCAG( _vara_double )( _fileId, var_xc.varId, &vmask.readStarts[0], &vmask.readCounts[0], &xc[0] ); 00322 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read double data for xc variable " ); 00323 00324 std::string ycstr( "yc" ); 00325 ReadNC::VarData& var_yc = _readNC->varInfo[ycstr]; 00326 std::vector< double > yc( local_elems ); 00327 success = NCFUNCAG( _vara_double )( _fileId, var_yc.varId, &vmask.readStarts[0], &vmask.readCounts[0], &yc[0] ); 00328 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read double data for yc variable " ); 00329 00330 std::string fracstr( "frac" ); 00331 ReadNC::VarData& var_frac = _readNC->varInfo[fracstr]; 00332 std::vector< double > frac( local_elems ); 00333 success = NCFUNCAG( _vara_double )( _fileId, var_frac.varId, &vmask.readStarts[0], &vmask.readCounts[0], &frac[0] ); 00334 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read double data for frac variable " ); 00335 std::string areastr( "area" ); 00336 ReadNC::VarData& var_area = _readNC->varInfo[areastr]; 00337 std::vector< double > area( local_elems ); 00338 success = NCFUNCAG( _vara_double )( _fileId, var_area.varId, &vmask.readStarts[0], &vmask.readCounts[0], &area[0] ); 00339 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read double data for area variable " ); 00340 // create tags for them 00341 Tag areaTag, fracTag, xcTag, ycTag; 00342 rval = mbImpl->tag_get_handle( "area", 1, MB_TYPE_DOUBLE, areaTag, MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating area tag" ); 00343 rval = mbImpl->tag_get_handle( "frac", 1, MB_TYPE_DOUBLE, fracTag, MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating frac tag" ); 00344 rval = mbImpl->tag_get_handle( "xc", 1, MB_TYPE_DOUBLE, xcTag, MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating xc tag" ); 00345 rval = mbImpl->tag_get_handle( "yc", 1, MB_TYPE_DOUBLE, ycTag, MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating yc tag" ); 00346 00347 // 00348 EntityHandle* conn_arr; 00349 EntityHandle start_vertex; 00350 Range tmp_range; 00351 00352 // set connectivity into that space 00353 00354 EntityHandle start_cell; 00355 EntityType mdb_type = MBVERTEX; 00356 if( nv == 3 ) 00357 mdb_type = MBTRI; 00358 else if( nv == 4 ) 00359 mdb_type = MBQUAD; 00360 else if( nv > 4 ) // (nv > 4) 00361 mdb_type = MBPOLYGON; 00362 // for nv = 1 , type is vertex 00363 00364 if( nv > 1 ) 00365 { 00366 rval = _readNC->readMeshIface->get_element_connect( nb_with_mask1, nv, mdb_type, 0, start_cell, conn_arr );MB_CHK_SET_ERR( rval, "Failed to create local cells" ); 00367 00368 tmp_range.insert( start_cell, start_cell + nb_with_mask1 - 1 ); 00369 // create also nv*nb_with_mask1 vertices, and compute their coordinates 00370 } 00371 00372 // Create vertices 00373 int nLocalVertices = nb_with_mask1 * nv; 00374 std::vector< double* > arrays; 00375 rval = _readNC->readMeshIface->get_node_coords( 3, nLocalVertices, 0, start_vertex, arrays );MB_CHK_SET_ERR( rval, "Failed to create local vertices" ); 00376 00377 // Set vertex coordinates 00378 // will read all xv, yv, but use only those with correct mask on 00379 Range::iterator rit; 00380 double* xptr = arrays[0]; 00381 double* yptr = arrays[1]; 00382 double* zptr = arrays[2]; 00383 int index = 0; // consider the mask for advancing in moab arrays; 00384 int elem_index = 0; // total index in netcdf arrays 00385 const double pideg = acos( -1.0 ) / 180.0; 00386 double radius = 1; 00387 00388 // int nj = gDims[4]-gDims[1]; // is it about 1 in irregular cases 00389 int j = lDims[1]; 00390 int i = lDims[0]; // if elem_index is getting to next row, increase j 00391 int local_row_size = lDims[3] - lDims[0]; 00392 for( ; elem_index < local_elems; elem_index++ ) 00393 { 00394 if( 0 == mask[elem_index] ) continue; // nothing to do, do not advance elem_index in actual moab arrays 00395 // set area and fraction on those elements too 00396 for( int k = 0; k < nv; k++ ) 00397 { 00398 EntityHandle vertex = start_vertex + nv * index + k; 00399 00400 int index_v_arr = nv * elem_index + k; 00401 double x, y; 00402 if( nv > 1 ) 00403 { 00404 conn_arr[nv * index + k] = vertex; 00405 x = xv[index_v_arr]; 00406 y = yv[index_v_arr]; 00407 double cosphi = cos( pideg * y ); 00408 double zmult = sin( pideg * y ); 00409 double xmult = cosphi * cos( x * pideg ); 00410 double ymult = cosphi * sin( x * pideg ); 00411 xptr[nv * index + k] = radius * xmult; 00412 yptr[nv * index + k] = radius * ymult; 00413 zptr[nv * index + k] = radius * zmult; 00414 } 00415 else // nv ==1 , tempest remap case, only xc make sense 00416 { 00417 x = xc[elem_index]; 00418 y = yc[elem_index]; 00419 xptr[nv * index + k] = x; 00420 yptr[nv * index + k] = y; 00421 zptr[nv * index + k] = 0; 00422 } 00423 } 00424 EntityHandle cell = start_vertex + index; 00425 if( nv > 1 ) cell = start_cell + index; 00426 // set other tags, like xc, yc, frac, area 00427 rval = mbImpl->tag_set_data( xcTag, &cell, 1, &xc[elem_index] );MB_CHK_SET_ERR( rval, "Failed to set xc tag" ); 00428 rval = mbImpl->tag_set_data( ycTag, &cell, 1, &yc[elem_index] );MB_CHK_SET_ERR( rval, "Failed to set yc tag" ); 00429 rval = mbImpl->tag_set_data( areaTag, &cell, 1, &area[elem_index] );MB_CHK_SET_ERR( rval, "Failed to set area tag" ); 00430 rval = mbImpl->tag_set_data( fracTag, &cell, 1, &frac[elem_index] );MB_CHK_SET_ERR( rval, "Failed to set frac tag" ); 00431 00432 // set the global id too: 00433 int globalId = j * local_row_size + i + 1; 00434 i++; 00435 if( ( i - lDims[0] ) % local_row_size == 0 ) 00436 { 00437 j++; 00438 i = lDims[0]; // start over next row 00439 } 00440 rval = mbImpl->tag_set_data( mGlobalIdTag, &cell, 1, &globalId );MB_CHK_SET_ERR( rval, "Failed to set global id tag" ); 00441 index++; 00442 } 00443 00444 rval = mbImpl->add_entities( _fileSet, tmp_range );MB_CHK_SET_ERR( rval, "Failed to add new cells to current file set" ); 00445 00446 // modify local file set, to merge coincident vertices, and to correct repeated vertices in elements 00447 std::vector< Tag > tagList; 00448 tagList.push_back( mGlobalIdTag ); 00449 tagList.push_back( xcTag ); 00450 tagList.push_back( ycTag ); 00451 tagList.push_back( areaTag ); 00452 tagList.push_back( fracTag ); 00453 double tol = 1.e-9; 00454 rval = IntxUtils::remove_duplicate_vertices( mbImpl, _fileSet, tol, tagList );MB_CHK_SET_ERR( rval, "Failed to remove duplicate vertices" ); 00455 00456 rval = mbImpl->get_entities_by_dimension( _fileSet, 2, faces );MB_CHK_ERR( rval ); 00457 Range all_verts; 00458 rval = mbImpl->get_connectivity( faces, all_verts );MB_CHK_ERR( rval ); 00459 rval = mbImpl->add_entities( _fileSet, all_verts );MB_CHK_ERR( rval ); 00460 #ifdef MOAB_HAVE_MPI 00461 ParallelComm*& myPcomm = _readNC->myPcomm; 00462 if( myPcomm ) 00463 { 00464 ParallelMergeMesh pmm( myPcomm, tol ); 00465 rval = pmm.merge( _fileSet, 00466 /* do not do local merge*/ false, 00467 /* 2d cells*/ 2 );MB_CHK_SET_ERR( rval, "Failed to merge vertices in parallel" ); 00468 00469 // assign global ids only for vertices, cells have them fine 00470 rval = myPcomm->assign_global_ids( _fileSet, /*dim*/ 0 );MB_CHK_ERR( rval ); 00471 } 00472 #endif 00473 00474 return MB_SUCCESS; 00475 } 00476 } // namespace moab