1
6
7 #include "NCHelperESMF.hpp"
8 #include "moab/ReadUtilIface.hpp"
9 #include "moab/FileOptions.hpp"
10 #include "MBTagConventions.hpp"
11
12 #ifdef MOAB_HAVE_ZOLTAN
13 #include "moab/ZoltanPartitioner.hpp"
14 #endif
15
16 #include <cmath>
17
18 namespace moab
19 {
20
21 const int DEFAULT_MAX_EDGES_PER_CELL = 10;
22 const double pideg = acos( -1.0 ) / 180.0;
23
24 NCHelperESMF::NCHelperESMF( ReadNC* readNC, int fileId, const FileOptions& opts, EntityHandle fileSet )
25 : UcdNCHelper( readNC, fileId, opts, fileSet ), maxEdgesPerCell( DEFAULT_MAX_EDGES_PER_CELL ), coordDim( 0 ),
26 centerCoordsId( -1 ), degrees( true )
27 {
28 }
29
30 bool NCHelperESMF::can_read_file( ReadNC* readNC )
31 {
32 std::vector< std::string >& dimNames = readNC->dimNames;
33 if( ( std::find( dimNames.begin(), dimNames.end(), std::string( "nodeCount" ) ) != dimNames.end() ) &&
34 ( std::find( dimNames.begin(), dimNames.end(), std::string( "elementCount" ) ) != dimNames.end() ) &&
35 ( std::find( dimNames.begin(), dimNames.end(), std::string( "maxNodePElement" ) ) != dimNames.end() ) &&
36 ( std::find( dimNames.begin(), dimNames.end(), std::string( "coordDim" ) ) != dimNames.end() ) )
37 {
38 return true;
39 }
40
41 return false;
42 }
43
44 ErrorCode NCHelperESMF::init_mesh_vals()
45 {
46 std::vector< std::string >& dimNames = _readNC->dimNames;
47 std::vector< int >& dimLens = _readNC->dimLens;
48 std::map< std::string, ReadNC::VarData >& varInfo = _readNC->varInfo;
49
50 ErrorCode rval;
51 unsigned int idx;
52 std::vector< std::string >::iterator vit;
53
54
55 if( ( vit = std::find( dimNames.begin(), dimNames.end(), "maxNodePElement" ) ) != dimNames.end() )
56 {
57 idx = vit - dimNames.begin();
58 maxEdgesPerCell = dimLens[idx];
59 if( maxEdgesPerCell > DEFAULT_MAX_EDGES_PER_CELL )
60 {
61 MB_SET_ERR( MB_INVALID_SIZE,
62 "maxEdgesPerCell read from the ESMF file header has exceeded " << DEFAULT_MAX_EDGES_PER_CELL );
63 }
64 }
65
66
67 if( ( vit = std::find( dimNames.begin(), dimNames.end(), "elementCount" ) ) != dimNames.end() )
68 idx = vit - dimNames.begin();
69 else
70 {
71 MB_SET_ERR( MB_FAILURE, "Couldn't find 'elementCount' dimension" );
72 }
73 cDim = idx;
74 nCells = dimLens[idx];
75
76
77 if( ( vit = std::find( dimNames.begin(), dimNames.end(), "maxNodePElement" ) ) != dimNames.end() )
78 idx = vit - dimNames.begin();
79 else
80 {
81 MB_SET_ERR( MB_FAILURE, "Couldn't find 'maxNodePElement' dimension" );
82 }
83
84 maxEdgesPerCell = dimLens[idx];
85
86
87 vDim = -1;
88 if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nodeCount" ) ) != dimNames.end() )
89 idx = vit - dimNames.begin();
90 else
91 {
92 MB_SET_ERR( MB_FAILURE, "Couldn't find 'nodeCount' dimension" );
93 }
94 vDim = idx;
95 nVertices = dimLens[idx];
96
97
98 if( ( vit = std::find( dimNames.begin(), dimNames.end(), "coordDim" ) ) != dimNames.end() )
99 idx = vit - dimNames.begin();
100 else
101 {
102 MB_SET_ERR( MB_FAILURE, "Couldn't find 'coordDim' dimension" );
103 }
104
105 coordDim = dimLens[idx];
106
107 int success = NCFUNC( inq_varid )( _fileId, "centerCoords", ¢erCoordsId );
108 if( success ) centerCoordsId = -1;
109
110
111 int nodeCoordsId;
112 success = NCFUNC( inq_varid )( _fileId, "nodeCoords", &nodeCoordsId );
113 if( success ) MB_CHK_SET_ERR( MB_FAILURE, "Trouble getting nodeCoords" );
114
115 auto vmit = varInfo.find( "nodeCoords" );
116 if( varInfo.end() == vmit )
117 MB_SET_ERR( MB_FAILURE, "Couldn't find variable "
118 << "nodeCoords" );
119 ReadNC::VarData& glData = vmit->second;
120 auto attIt = glData.varAtts.find( "units" );
121 if( attIt != glData.varAtts.end() )
122 {
123 unsigned int sz = attIt->second.attLen;
124 std::string att_data;
125 att_data.resize( sz + 1 );
126 att_data[sz] = '\000';
127 success =
128 NCFUNC( get_att_text )( _fileId, attIt->second.attVarId, attIt->second.attName.c_str(), &att_data[0] );
129 if( 0 == success && att_data.find( "radians" ) != std::string::npos ) degrees = false;
130 }
131
132
133
134 rval = create_dummy_variables();MB_CHK_SET_ERR( rval, "Failed to create dummy variables" );
135
136 return MB_SUCCESS;
137 }
138
139 ErrorCode NCHelperESMF::create_mesh( Range& faces )
140 {
141 bool& noMixedElements = _readNC->noMixedElements;
142 DebugOutput& dbgOut = _readNC->dbgOut;
143
144 #ifdef MOAB_HAVE_MPI
145 int rank = 0;
146 int procs = 1;
147 bool& isParallel = _readNC->isParallel;
148 ParallelComm* myPcomm = NULL;
149 if( isParallel )
150 {
151 myPcomm = _readNC->myPcomm;
152 rank = myPcomm->proc_config().proc_rank();
153 procs = myPcomm->proc_config().proc_size();
154 }
155
156 if( procs >= 2 )
157 {
158
159 int shifted_rank = rank;
160 int& trivialPartitionShift = _readNC->trivialPartitionShift;
161 if( trivialPartitionShift > 0 ) shifted_rank = ( rank + trivialPartitionShift ) % procs;
162
163
164 nLocalCells = int( std::floor( 1.0 * nCells / procs ) );
165
166
167 int start_cell_idx = shifted_rank * nLocalCells;
168
169
170 int iextra = nCells % procs;
171
172
173 if( shifted_rank < iextra ) nLocalCells++;
174 start_cell_idx += std::min( shifted_rank, iextra );
175
176 start_cell_idx++;
177
178
179 ErrorCode rval = redistribute_local_cells( start_cell_idx, myPcomm );MB_CHK_SET_ERR( rval, "Failed to redistribute local cells after trivial partition" );
180 }
181 else
182 {
183 nLocalCells = nCells;
184 localGidCells.insert( 1, nLocalCells );
185 }
186 #else
187 nLocalCells = nCells;
188 localGidCells.insert( 1, nLocalCells );
189 #endif
190 dbgOut.tprintf( 1, " localGidCells.psize() = %d\n", (int)localGidCells.psize() );
191 dbgOut.tprintf( 1, " localGidCells.size() = %d\n", (int)localGidCells.size() );
192
193
194 int nEdgesOnCellVarId;
195 int success = NCFUNC( inq_varid )( _fileId, "numElementConn", &nEdgesOnCellVarId );
196 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of numElementConn" );
197 std::vector< int > num_edges_on_local_cells( nLocalCells );
198
199 #ifdef MOAB_HAVE_PNETCDF
200 size_t nb_reads = localGidCells.psize();
201 std::vector< int > requests( nb_reads );
202 std::vector< int > statuss( nb_reads );
203 size_t idxReq = 0;
204 #endif
205 size_t indexInArray = 0;
206 for( Range::pair_iterator pair_iter = localGidCells.pair_begin(); pair_iter != localGidCells.pair_end();
207 ++pair_iter )
208 {
209 EntityHandle starth = pair_iter->first;
210 EntityHandle endh = pair_iter->second;
211 NCDF_SIZE read_start = (NCDF_SIZE)( starth - 1 );
212 NCDF_SIZE read_count = (NCDF_SIZE)( endh - starth + 1 );
213
214
215 #ifdef MOAB_HAVE_PNETCDF
216 success = NCFUNCREQG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count,
217 &( num_edges_on_local_cells[indexInArray] ), &requests[idxReq++] );
218 #else
219 success = NCFUNCAG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count,
220 &( num_edges_on_local_cells[indexInArray] ) );
221 #endif
222 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nEdgesOnCell data in a loop" );
223
224
225 indexInArray += ( endh - starth + 1 );
226 }
227
228 #ifdef MOAB_HAVE_PNETCDF
229
230 success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
231 if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
232 #endif
233
234
235 int verticesOnCellVarId;
236 success = NCFUNC( inq_varid )( _fileId, "elementConn", &verticesOnCellVarId );
237 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of elementConn" );
238 std::vector< int > vertices_on_local_cells( nLocalCells * maxEdgesPerCell );
239 #ifdef MOAB_HAVE_PNETCDF
240 idxReq = 0;
241 #endif
242 indexInArray = 0;
243 for( Range::pair_iterator pair_iter = localGidCells.pair_begin(); pair_iter != localGidCells.pair_end();
244 ++pair_iter )
245 {
246 EntityHandle starth = pair_iter->first;
247 EntityHandle endh = pair_iter->second;
248 NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 };
249 NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ),
250 static_cast< NCDF_SIZE >( maxEdgesPerCell ) };
251
252
253 #ifdef MOAB_HAVE_PNETCDF
254 success = NCFUNCREQG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
255 &( vertices_on_local_cells[indexInArray] ), &requests[idxReq++] );
256 #else
257 success = NCFUNCAG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
258 &( vertices_on_local_cells[indexInArray] ) );
259 #endif
260 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnCell data in a loop" );
261
262
263 indexInArray += ( endh - starth + 1 ) * maxEdgesPerCell;
264 }
265
266 #ifdef MOAB_HAVE_PNETCDF
267
268 success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
269 if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
270 #endif
271
272
273
274
275 for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ )
276 {
277 int num_edges = num_edges_on_local_cells[local_cell_idx];
278 int idx_in_local_vert_arr = local_cell_idx * maxEdgesPerCell;
279 int last_vert_idx = vertices_on_local_cells[idx_in_local_vert_arr + num_edges - 1];
280 for( int i = num_edges; i < maxEdgesPerCell; i++ )
281 vertices_on_local_cells[idx_in_local_vert_arr + i] = last_vert_idx;
282 }
283
284
285 EntityHandle start_vertex;
286 ErrorCode rval = create_local_vertices( vertices_on_local_cells, start_vertex );MB_CHK_SET_ERR( rval, "Failed to create local vertices for MPAS mesh" );
287
288
289 if( noMixedElements )
290 {
291 rval = create_padded_local_cells( vertices_on_local_cells, start_vertex, faces );MB_CHK_SET_ERR( rval, "Failed to create padded local cells for MPAS mesh" );
292 }
293 else
294 {
295 rval = create_local_cells( vertices_on_local_cells, num_edges_on_local_cells, start_vertex, faces );MB_CHK_SET_ERR( rval, "Failed to create local cells for MPAS mesh" );
296 }
297
298 return MB_SUCCESS;
299 }
300
301 #ifdef MOAB_HAVE_MPI
302 ErrorCode NCHelperESMF::redistribute_local_cells( int start_cell_idx, ParallelComm* pco )
303 {
304
305
306
307
308
309 #ifdef MOAB_HAVE_ZOLTAN
310 if( ScdParData::RCBZOLTAN == _readNC->partMethod )
311 {
312
313 std::vector< double > xverts, yverts, zverts;
314 xverts.resize( nLocalCells );
315 yverts.resize( nLocalCells );
316 zverts.resize( nLocalCells );
317
318 if( centerCoordsId >= 0 )
319 {
320
321 std::vector< double > coords( nLocalCells * coordDim );
322
323 NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( start_cell_idx - 1 ), 0 };
324 NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( nLocalCells ),
325 static_cast< NCDF_SIZE >( coordDim ) };
326 int success = NCFUNCAG( _vara_double )( _fileId, centerCoordsId, read_starts, read_counts, &( coords[0] ) );
327 if( success ) MB_SET_ERR( MB_FAILURE, "Failed on reading center coordinates" );
328 if( 2 == coordDim )
329 {
330 double factor = 1.;
331 if( degrees ) factor = pideg;
332 for( int i = 0; i < nLocalCells; i++ )
333 {
334 double lon = coords[i * 2] * factor;
335 double lat = coords[i * 2 + 1] * factor;
336 double cosphi = cos( lat );
337 zverts[i] = sin( lat );
338 xverts[i] = cosphi * cos( lon );
339 yverts[i] = cosphi * sin( lon );
340 }
341 }
342 }
343 else
344 {
345
346
347 int verticesOnCellVarId;
348 int success = NCFUNC( inq_varid )( _fileId, "elementConn", &verticesOnCellVarId );
349 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of elementConn" );
350 std::vector< int > vertices_on_local_cells( nLocalCells * maxEdgesPerCell );
351
352 NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( start_cell_idx - 1 ), 0 };
353 NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( nLocalCells ),
354 static_cast< NCDF_SIZE >( maxEdgesPerCell ) };
355
356 success = NCFUNCAG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
357 &( vertices_on_local_cells[0] ) );
358 if( success ) MB_SET_ERR( MB_FAILURE, "Failed on reading elementConn variable" );
359 std::vector< int > num_edges_on_local_cells( nLocalCells );
360
361 NCDF_SIZE read_start = start_cell_idx - 1;
362 NCDF_SIZE read_count = (NCDF_SIZE)( nLocalCells );
363
364 int nEdgesOnCellVarId;
365 success = NCFUNC( inq_varid )( _fileId, "numElementConn", &nEdgesOnCellVarId );
366 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of numElementConn" );
367 success = NCFUNCAG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count,
368 &( num_edges_on_local_cells[0] ) );
369 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get numElementConn" );
370
371
372
373
374
375
376 for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ )
377 {
378 int num_edges = num_edges_on_local_cells[local_cell_idx];
379 int idx_in_local_vert_arr = local_cell_idx * maxEdgesPerCell;
380 int last_vert_idx = vertices_on_local_cells[idx_in_local_vert_arr + num_edges - 1];
381 for( int i = num_edges; i < maxEdgesPerCell; i++ )
382 vertices_on_local_cells[idx_in_local_vert_arr + i] = last_vert_idx;
383 }
384
385 std::vector< int > vertices_on_local_cells_sorted( vertices_on_local_cells );
386 std::sort( vertices_on_local_cells_sorted.begin(), vertices_on_local_cells_sorted.end() );
387 std::copy( vertices_on_local_cells_sorted.rbegin(), vertices_on_local_cells_sorted.rend(),
388 range_inserter( localGidVerts ) );
389 nLocalVertices = localGidVerts.size();
390
391
392 double* coords = new double[localGidVerts.size() * coordDim];
393 int nodeCoordVarId;
394 success = NCFUNC( inq_varid )( _fileId, "nodeCoords", &nodeCoordVarId );
395 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of nodeCoords" );
396 #ifdef MOAB_HAVE_PNETCDF
397 size_t nb_reads = localGidVerts.psize();
398 std::vector< int > requests( nb_reads );
399 std::vector< int > statuss( nb_reads );
400 size_t idxReq = 0;
401 #endif
402 size_t indexInArray = 0;
403 for( Range::pair_iterator pair_iter = localGidVerts.pair_begin(); pair_iter != localGidVerts.pair_end();
404 ++pair_iter )
405 {
406 EntityHandle starth = pair_iter->first;
407 EntityHandle endh = pair_iter->second;
408 NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 };
409 NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ),
410 static_cast< NCDF_SIZE >( coordDim ) };
411
412
413 #ifdef MOAB_HAVE_PNETCDF
414 success = NCFUNCREQG( _vara_double )( _fileId, nodeCoordVarId, read_starts, read_counts,
415 &coords[indexInArray], &requests[idxReq++] );
416 #else
417 success = NCFUNCAG( _vara_double )( _fileId, nodeCoordVarId, read_starts, read_counts,
418 &coords[indexInArray] );
419 #endif
420 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nodeCoords data in a loop" );
421
422
423 indexInArray += ( endh - starth + 1 ) * coordDim;
424 }
425
426 #ifdef MOAB_HAVE_PNETCDF
427
428 success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
429 if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
430 #endif
431
432 double* coords3d = new double[localGidVerts.size() * 3];
433
434 if( 2 == coordDim )
435 {
436
437 double factor = 1.;
438 if( degrees ) factor = pideg;
439 for( int i = 0; i < (int)localGidVerts.size(); i++ )
440 {
441 double lon = coords[i * 2] * factor;
442 double lat = coords[i * 2 + 1] * factor;
443 double cosphi = cos( lat );
444 coords3d[3 * i + 2] = sin( lat );
445 coords3d[3 * i] = cosphi * cos( lon );
446 coords3d[3 * i + 1] = cosphi * sin( lon );
447 }
448 }
449
450
451 for( int i = 0; i < nLocalCells; i++ )
452 {
453 int nv = num_edges_on_local_cells[i];
454 double x = 0., y = 0., z = 0.;
455 for( int j = 0; j < nv; j++ )
456 {
457 int vertexId = vertices_on_local_cells[i * maxEdgesPerCell + j];
458
459 int index = localGidVerts.index( vertexId );
460 x += coords3d[3 * index];
461 y += coords3d[3 * index + 1];
462 z += coords3d[3 * index + 2];
463 }
464 if( nv != 0 )
465 {
466 x /= nv;
467 y /= nv;
468 z /= nv;
469 }
470 xverts[i] = x;
471 yverts[i] = y;
472 zverts[i] = z;
473 }
474 delete[] coords3d;
475 }
476
477
478 Interface*& mbImpl = _readNC->mbImpl;
479 DebugOutput& dbgOut = _readNC->dbgOut;
480 ZoltanPartitioner* mbZTool = new ZoltanPartitioner( mbImpl, pco, false, 0, NULL );
481 ErrorCode rval = mbZTool->repartition( xverts, yverts, zverts, start_cell_idx, "RCB", localGidCells );MB_CHK_SET_ERR( rval, "Error in Zoltan partitioning" );
482 delete mbZTool;
483
484 dbgOut.tprintf( 1, "After Zoltan partitioning, localGidCells.psize() = %d\n", (int)localGidCells.psize() );
485 dbgOut.tprintf( 1, " localGidCells.size() = %d\n", (int)localGidCells.size() );
486
487
488 nLocalCells = localGidCells.size();
489 localGidVerts.clear();
490 return MB_SUCCESS;
491 }
492 #endif
493
494
495 localGidCells.insert( start_cell_idx, start_cell_idx + nLocalCells - 1 );
496
497 return MB_SUCCESS;
498 }
499 #endif
500
501 ErrorCode NCHelperESMF::create_local_vertices( const std::vector< int >& vertices_on_local_cells,
502 EntityHandle& start_vertex )
503 {
504 Interface*& mbImpl = _readNC->mbImpl;
505 Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
506 const Tag*& mpFileIdTag = _readNC->mpFileIdTag;
507 DebugOutput& dbgOut = _readNC->dbgOut;
508
509
510
511 std::vector< int > vertices_on_local_cells_sorted( vertices_on_local_cells );
512 std::sort( vertices_on_local_cells_sorted.begin(), vertices_on_local_cells_sorted.end() );
513 std::copy( vertices_on_local_cells_sorted.rbegin(), vertices_on_local_cells_sorted.rend(),
514 range_inserter( localGidVerts ) );
515 nLocalVertices = localGidVerts.size();
516
517 dbgOut.tprintf( 1, " localGidVerts.psize() = %d\n", (int)localGidVerts.psize() );
518 dbgOut.tprintf( 1, " localGidVerts.size() = %d\n", (int)localGidVerts.size() );
519
520
521 std::vector< double* > arrays;
522 ErrorCode rval =
523 _readNC->readMeshIface->get_node_coords( 3, nLocalVertices, 0, start_vertex, arrays, nLocalVertices );MB_CHK_SET_ERR( rval, "Failed to create local vertices" );
524
525
526 Range local_verts_range( start_vertex, start_vertex + nLocalVertices - 1 );
527 rval = _readNC->mbImpl->add_entities( _fileSet, local_verts_range );MB_CHK_SET_ERR( rval, "Failed to add local vertices to current file set" );
528
529
530 int count = 0;
531 void* data = NULL;
532 rval = mbImpl->tag_iterate( mGlobalIdTag, local_verts_range.begin(), local_verts_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate global id tag on local vertices" );
533 assert( count == nLocalVertices );
534 int* gid_data = (int*)data;
535 std::copy( localGidVerts.begin(), localGidVerts.end(), gid_data );
536
537
538 if( mpFileIdTag )
539 {
540 rval = mbImpl->tag_iterate( *mpFileIdTag, local_verts_range.begin(), local_verts_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate file id tag on local vertices" );
541 assert( count == nLocalVertices );
542 int bytes_per_tag = 4;
543 rval = mbImpl->tag_get_bytes( *mpFileIdTag, bytes_per_tag );MB_CHK_SET_ERR( rval, "Can't get number of bytes for file id tag" );
544 if( 4 == bytes_per_tag )
545 {
546 gid_data = (int*)data;
547 std::copy( localGidVerts.begin(), localGidVerts.end(), gid_data );
548 }
549 else if( 8 == bytes_per_tag )
550 {
551 long* handle_tag_data = (long*)data;
552 std::copy( localGidVerts.begin(), localGidVerts.end(), handle_tag_data );
553 }
554 }
555
556 #ifdef MOAB_HAVE_PNETCDF
557 size_t nb_reads = localGidVerts.psize();
558 std::vector< int > requests( nb_reads );
559 std::vector< int > statuss( nb_reads );
560 size_t idxReq = 0;
561 #endif
562
563
564 double* coords = new double[localGidVerts.size() * coordDim];
565 int nodeCoordVarId;
566 int success = NCFUNC( inq_varid )( _fileId, "nodeCoords", &nodeCoordVarId );
567 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of nodeCoords" );
568 size_t indexInArray = 0;
569 for( Range::pair_iterator pair_iter = localGidVerts.pair_begin(); pair_iter != localGidVerts.pair_end();
570 ++pair_iter )
571 {
572 EntityHandle starth = pair_iter->first;
573 EntityHandle endh = pair_iter->second;
574 NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 };
575 NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ),
576 static_cast< NCDF_SIZE >( coordDim ) };
577
578
579 #ifdef MOAB_HAVE_PNETCDF
580 success = NCFUNCREQG( _vara_double )( _fileId, nodeCoordVarId, read_starts, read_counts, &coords[indexInArray],
581 &requests[idxReq++] );
582 #else
583 success = NCFUNCAG( _vara_double )( _fileId, nodeCoordVarId, read_starts, read_counts, &coords[indexInArray] );
584 #endif
585 if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nodeCoords data in a loop" );
586
587
588 indexInArray += ( endh - starth + 1 ) * coordDim;
589 }
590
591 #ifdef MOAB_HAVE_PNETCDF
592
593 success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
594 if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
595 #endif
596
597
598 if( 2 == coordDim )
599 {
600
601 double factor = 1;
602 if( degrees ) factor = pideg;
603 for( int i = 0; i < (int)localGidVerts.size(); i++ )
604 {
605 double lon = coords[i * 2] * factor;
606 double lat = coords[i * 2 + 1] * factor;
607 double cosphi = cos( lat );
608 arrays[2][i] = sin( lat );
609 arrays[0][i] = cosphi * cos( lon );
610 arrays[1][i] = cosphi * sin( lon );
611 }
612 }
613 delete[] coords;
614 return MB_SUCCESS;
615 }
616
617 ErrorCode NCHelperESMF::create_local_cells( const std::vector< int >& vertices_on_local_cells,
618 const std::vector< int >& num_edges_on_local_cells,
619 EntityHandle start_vertex,
620 Range& faces )
621 {
622 Interface*& mbImpl = _readNC->mbImpl;
623 Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
624
625
626 Range local_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
627
628 for( int i = nLocalCells - 1; i >= 0; i-- )
629 {
630 int num_edges = num_edges_on_local_cells[i];
631 local_cells_with_n_edges[num_edges].insert( localGidCells[i] );
632 }
633
634 std::vector< int > num_edges_on_cell_groups;
635 for( int i = 3; i <= maxEdgesPerCell; i++ )
636 {
637 if( local_cells_with_n_edges[i].size() > 0 ) num_edges_on_cell_groups.push_back( i );
638 }
639 int numCellGroups = (int)num_edges_on_cell_groups.size();
640 EntityHandle* conn_arr_local_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
641 for( int i = 0; i < numCellGroups; i++ )
642 {
643 int num_edges_per_cell = num_edges_on_cell_groups[i];
644 int num_group_cells = (int)local_cells_with_n_edges[num_edges_per_cell].size();
645
646 EntityType typeEl = MBTRI;
647 if( num_edges_per_cell == 4 ) typeEl = MBQUAD;
648 if( num_edges_per_cell > 4 ) typeEl = MBPOLYGON;
649
650 EntityHandle start_element;
651 ErrorCode rval =
652 _readNC->readMeshIface->get_element_connect( num_group_cells, num_edges_per_cell, typeEl, 0, start_element,
653 conn_arr_local_cells_with_n_edges[num_edges_per_cell],
654 num_group_cells );MB_CHK_SET_ERR( rval, "Failed to create local cells" );
655 faces.insert( start_element, start_element + num_group_cells - 1 );
656
657
658 Range local_cells_range( start_element, start_element + num_group_cells - 1 );
659 rval = _readNC->mbImpl->add_entities( _fileSet, local_cells_range );MB_CHK_SET_ERR( rval, "Failed to add local cells to current file set" );
660
661
662 int count = 0;
663 void* data = NULL;
664 rval = mbImpl->tag_iterate( mGlobalIdTag, local_cells_range.begin(), local_cells_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate global id tag on local cells" );
665 assert( count == num_group_cells );
666 int* gid_data = (int*)data;
667 std::copy( local_cells_with_n_edges[num_edges_per_cell].begin(),
668 local_cells_with_n_edges[num_edges_per_cell].end(), gid_data );
669
670
671 for( int j = 0; j < num_group_cells; j++ )
672 {
673 EntityHandle global_cell_idx =
674 local_cells_with_n_edges[num_edges_per_cell][j];
675 int local_cell_idx = localGidCells.index( global_cell_idx );
676 assert( local_cell_idx != -1 );
677
678 for( int k = 0; k < num_edges_per_cell; k++ )
679 {
680 EntityHandle global_vert_idx =
681 vertices_on_local_cells[local_cell_idx * maxEdgesPerCell + k];
682 int local_vert_idx = localGidVerts.index( global_vert_idx );
683 assert( local_vert_idx != -1 );
684 conn_arr_local_cells_with_n_edges[num_edges_per_cell][j * num_edges_per_cell + k] =
685 start_vertex + local_vert_idx;
686 }
687 }
688 }
689
690 return MB_SUCCESS;
691 }
692
693 ErrorCode NCHelperESMF::create_padded_local_cells( const std::vector< int >& vertices_on_local_cells,
694 EntityHandle start_vertex,
695 Range& faces )
696 {
697 Interface*& mbImpl = _readNC->mbImpl;
698 Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
699
700
701 EntityHandle start_element;
702 EntityHandle* conn_arr_local_cells = NULL;
703 ErrorCode rval = _readNC->readMeshIface->get_element_connect( nLocalCells, maxEdgesPerCell, MBPOLYGON, 0,
704 start_element, conn_arr_local_cells, nLocalCells );MB_CHK_SET_ERR( rval, "Failed to create local cells" );
705 faces.insert( start_element, start_element + nLocalCells - 1 );
706
707
708 Range local_cells_range( start_element, start_element + nLocalCells - 1 );
709 rval = _readNC->mbImpl->add_entities( _fileSet, local_cells_range );MB_CHK_SET_ERR( rval, "Failed to add local cells to current file set" );
710
711
712 int count = 0;
713 void* data = NULL;
714 rval = mbImpl->tag_iterate( mGlobalIdTag, local_cells_range.begin(), local_cells_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate global id tag on local cells" );
715 assert( count == nLocalCells );
716 int* gid_data = (int*)data;
717 std::copy( localGidCells.begin(), localGidCells.end(), gid_data );
718
719
720
721
722 for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ )
723 {
724 for( int i = 0; i < maxEdgesPerCell; i++ )
725 {
726 EntityHandle global_vert_idx =
727 vertices_on_local_cells[local_cell_idx * maxEdgesPerCell + i];
728 int local_vert_idx = localGidVerts.index( global_vert_idx );
729 assert( local_vert_idx != -1 );
730 conn_arr_local_cells[local_cell_idx * maxEdgesPerCell + i] = start_vertex + local_vert_idx;
731 }
732 }
733
734 return MB_SUCCESS;
735 }
736
737 }