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