Branch data Line data Source code
1 : : #include "NCHelperMPAS.hpp"
2 : : #include "moab/ReadUtilIface.hpp"
3 : : #include "moab/FileOptions.hpp"
4 : : #include "moab/SpectralMeshTool.hpp"
5 : : #include "MBTagConventions.hpp"
6 : :
7 : : #ifdef MOAB_HAVE_ZOLTAN
8 : : #include "moab/ZoltanPartitioner.hpp"
9 : : #endif
10 : :
11 : : #include <cmath>
12 : :
13 : : namespace moab
14 : : {
15 : :
16 : : const int DEFAULT_MAX_EDGES_PER_CELL = 10;
17 : :
18 : 0 : NCHelperMPAS::NCHelperMPAS( ReadNC* readNC, int fileId, const FileOptions& opts, EntityHandle fileSet )
19 : : : UcdNCHelper( readNC, fileId, opts, fileSet ), maxEdgesPerCell( DEFAULT_MAX_EDGES_PER_CELL ), numCellGroups( 0 ),
20 [ # # ][ # # ]: 0 : createGatherSet( false )
21 : : {
22 : : // Ignore variables containing topological information
23 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "nEdgesOnEdge" );
24 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "nEdgesOnCell" );
25 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "edgesOnVertex" );
26 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "cellsOnVertex" );
27 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "verticesOnEdge" );
28 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "edgesOnEdge" );
29 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "cellsOnEdge" );
30 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "verticesOnCell" );
31 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "edgesOnCell" );
32 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "cellsOnCell" );
33 : : // ignore variables containing mesh related info, that are currently saved as variable tags on
34 : : // file set ; if needed, these should be saved as dense tags, and read accordingly, in parallel
35 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "weightsOnEdge" );
36 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "angleEdge" );
37 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "areaCell" );
38 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "areaTriangle" );
39 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "dcEdge" );
40 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "dv1Edge" );
41 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "dv2Edge" );
42 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "fEdge" );
43 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "fVertex" );
44 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "h_s" );
45 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "kiteAreasOnVertex" );
46 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "latCell" );
47 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "latEdge" );
48 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "latVertex" );
49 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "lonCell" );
50 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "lonEdge" );
51 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "lonVertex" );
52 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "meshDensity" );
53 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "xCell" );
54 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "xEdge" );
55 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "xVertex" );
56 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "yCell" );
57 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "yEdge" );
58 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "yVertex" );
59 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "zCell" );
60 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "zEdge" );
61 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "zVertex" );
62 : : // Ignore variables for index conversion
63 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "indexToVertexID" );
64 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "indexToEdgeID" );
65 [ # # ][ # # ]: 0 : ignoredVarNames.insert( "indexToCellID" );
66 : 0 : }
67 : :
68 : 0 : bool NCHelperMPAS::can_read_file( ReadNC* readNC )
69 : : {
70 : 0 : std::vector< std::string >& dimNames = readNC->dimNames;
71 : :
72 : : // If dimension name "vertexDegree" exists then it should be the MPAS grid
73 [ # # ][ # # ]: 0 : if( std::find( dimNames.begin(), dimNames.end(), std::string( "vertexDegree" ) ) != dimNames.end() ) return true;
[ # # ][ # # ]
74 : :
75 : 0 : return false;
76 : : }
77 : :
78 : 0 : ErrorCode NCHelperMPAS::init_mesh_vals()
79 : : {
80 : 0 : std::vector< std::string >& dimNames = _readNC->dimNames;
81 : 0 : std::vector< int >& dimLens = _readNC->dimLens;
82 : 0 : std::map< std::string, ReadNC::VarData >& varInfo = _readNC->varInfo;
83 : :
84 : : ErrorCode rval;
85 : : unsigned int idx;
86 : 0 : std::vector< std::string >::iterator vit;
87 : :
88 : : // Get max edges per cell reported in the MPAS file header
89 [ # # ][ # # ]: 0 : if( ( vit = std::find( dimNames.begin(), dimNames.end(), "maxEdges" ) ) != dimNames.end() )
[ # # ]
90 : : {
91 [ # # ]: 0 : idx = vit - dimNames.begin();
92 [ # # ]: 0 : maxEdgesPerCell = dimLens[idx];
93 [ # # ]: 0 : if( maxEdgesPerCell > DEFAULT_MAX_EDGES_PER_CELL )
94 : : {
95 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_INVALID_SIZE,
[ # # ][ # # ]
[ # # ][ # # ]
96 : : "maxEdgesPerCell read from the MPAS file header has exceeded " << DEFAULT_MAX_EDGES_PER_CELL );
97 : : }
98 : : }
99 : :
100 : : // Look for time dimension
101 [ # # ][ # # ]: 0 : if( ( vit = std::find( dimNames.begin(), dimNames.end(), "Time" ) ) != dimNames.end() )
[ # # ]
102 [ # # ]: 0 : idx = vit - dimNames.begin();
103 [ # # ][ # # ]: 0 : else if( ( vit = std::find( dimNames.begin(), dimNames.end(), "time" ) ) != dimNames.end() )
[ # # ]
104 [ # # ]: 0 : idx = vit - dimNames.begin();
105 : : else
106 : : {
107 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Couldn't find 'Time' or 'time' dimension" );
[ # # ][ # # ]
[ # # ]
108 : : }
109 : 0 : tDim = idx;
110 [ # # ]: 0 : nTimeSteps = dimLens[idx];
111 : :
112 : : // Get number of cells
113 [ # # ][ # # ]: 0 : if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nCells" ) ) != dimNames.end() )
[ # # ]
114 [ # # ]: 0 : idx = vit - dimNames.begin();
115 : : else
116 : : {
117 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Couldn't find 'nCells' dimension" );
[ # # ][ # # ]
[ # # ]
118 : : }
119 : 0 : cDim = idx;
120 [ # # ]: 0 : nCells = dimLens[idx];
121 : :
122 : : // Get number of edges
123 [ # # ][ # # ]: 0 : if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nEdges" ) ) != dimNames.end() )
[ # # ]
124 [ # # ]: 0 : idx = vit - dimNames.begin();
125 : : else
126 : : {
127 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Couldn't find 'nEdges' dimension" );
[ # # ][ # # ]
[ # # ]
128 : : }
129 : 0 : eDim = idx;
130 [ # # ]: 0 : nEdges = dimLens[idx];
131 : :
132 : : // Get number of vertices
133 : 0 : vDim = -1;
134 [ # # ][ # # ]: 0 : if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nVertices" ) ) != dimNames.end() )
[ # # ]
135 [ # # ]: 0 : idx = vit - dimNames.begin();
136 : : else
137 : : {
138 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Couldn't find 'nVertices' dimension" );
[ # # ][ # # ]
[ # # ]
139 : : }
140 : 0 : vDim = idx;
141 [ # # ]: 0 : nVertices = dimLens[idx];
142 : :
143 : : // Get number of vertex levels
144 [ # # ][ # # ]: 0 : if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nVertLevels" ) ) != dimNames.end() )
[ # # ]
145 [ # # ]: 0 : idx = vit - dimNames.begin();
146 : : else
147 : : {
148 : : std::cerr << "Warning: dimension nVertLevels not found in header.\nThe file may contain "
149 [ # # ]: 0 : "just the mesh"
150 [ # # ]: 0 : << std::endl;
151 : : }
152 : 0 : levDim = idx;
153 [ # # ]: 0 : nLevels = dimLens[idx];
154 : :
155 : : // Dimension indices for other optional levels
156 [ # # ]: 0 : std::vector< unsigned int > opt_lev_dims;
157 : :
158 : : // Get index of vertex levels P1
159 [ # # ][ # # ]: 0 : if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nVertLevelsP1" ) ) != dimNames.end() )
[ # # ]
160 : : {
161 [ # # ]: 0 : idx = vit - dimNames.begin();
162 [ # # ]: 0 : opt_lev_dims.push_back( idx );
163 : : }
164 : :
165 : : // Get index of vertex levels P2
166 [ # # ][ # # ]: 0 : if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nVertLevelsP2" ) ) != dimNames.end() )
[ # # ]
167 : : {
168 [ # # ]: 0 : idx = vit - dimNames.begin();
169 [ # # ]: 0 : opt_lev_dims.push_back( idx );
170 : : }
171 : :
172 : : // Get index of soil levels
173 [ # # ][ # # ]: 0 : if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nSoilLevels" ) ) != dimNames.end() )
[ # # ]
174 : : {
175 [ # # ]: 0 : idx = vit - dimNames.begin();
176 [ # # ]: 0 : opt_lev_dims.push_back( idx );
177 : : }
178 : :
179 [ # # ]: 0 : std::map< std::string, ReadNC::VarData >::iterator vmit;
180 : :
181 : : // Store time coordinate values in tVals
182 [ # # ]: 0 : if( nTimeSteps > 0 )
183 : : {
184 : : // Note, two possible types for xtime variable: double(Time) or char(Time, StrLen)
185 [ # # ][ # # ]: 0 : if( ( vmit = varInfo.find( "xtime" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# ]
186 : : {
187 : : // If xtime variable is double type, read time coordinate values to tVals
188 [ # # ][ # # ]: 0 : rval = read_coordinate( "xtime", 0, nTimeSteps - 1, tVals );MB_CHK_SET_ERR( rval, "Trouble reading 'xtime' variable" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
189 : : }
190 : : else
191 : : {
192 : : // If xtime variable does not exist, or it is string type, set dummy values to tVals
193 [ # # ]: 0 : for( int t = 0; t < nTimeSteps; t++ )
194 [ # # ]: 0 : tVals.push_back( (double)t );
195 : : }
196 : : }
197 : :
198 : : // For each variable, determine the entity location type and number of levels
199 [ # # ][ # # ]: 0 : for( vmit = varInfo.begin(); vmit != varInfo.end(); ++vmit )
[ # # ]
200 : : {
201 [ # # ]: 0 : ReadNC::VarData& vd = ( *vmit ).second;
202 : :
203 : : // Default entLoc is ENTLOCSET
204 [ # # ][ # # ]: 0 : if( std::find( vd.varDims.begin(), vd.varDims.end(), tDim ) != vd.varDims.end() )
[ # # ]
205 : : {
206 [ # # ][ # # ]: 0 : if( std::find( vd.varDims.begin(), vd.varDims.end(), vDim ) != vd.varDims.end() )
[ # # ]
207 : 0 : vd.entLoc = ReadNC::ENTLOCVERT;
208 [ # # ][ # # ]: 0 : else if( std::find( vd.varDims.begin(), vd.varDims.end(), eDim ) != vd.varDims.end() )
[ # # ]
209 : 0 : vd.entLoc = ReadNC::ENTLOCEDGE;
210 [ # # ][ # # ]: 0 : else if( std::find( vd.varDims.begin(), vd.varDims.end(), cDim ) != vd.varDims.end() )
[ # # ]
211 : 0 : vd.entLoc = ReadNC::ENTLOCFACE;
212 : : }
213 : :
214 : : // Default numLev is 0
215 [ # # ][ # # ]: 0 : if( std::find( vd.varDims.begin(), vd.varDims.end(), levDim ) != vd.varDims.end() )
[ # # ]
216 : 0 : vd.numLev = nLevels;
217 : : else
218 : : {
219 : : // If nVertLevels dimension is not found, try other optional levels such as
220 : : // nVertLevelsP1
221 [ # # ]: 0 : for( unsigned int i = 0; i < opt_lev_dims.size(); i++ )
222 : : {
223 [ # # ][ # # ]: 0 : if( std::find( vd.varDims.begin(), vd.varDims.end(), opt_lev_dims[i] ) != vd.varDims.end() )
[ # # ][ # # ]
224 : : {
225 [ # # ][ # # ]: 0 : vd.numLev = dimLens[opt_lev_dims[i]];
226 : 0 : break;
227 : : }
228 : : }
229 : : }
230 : :
231 : : // Hack: ignore variables with more than 3 dimensions, e.g. tracers(Time, nCells,
232 : : // nVertLevels, nTracers)
233 [ # # ][ # # ]: 0 : if( vd.varDims.size() > 3 ) ignoredVarNames.insert( vd.varName );
234 : : }
235 : :
236 : : // Hack: create dummy variables for dimensions (like nCells) with no corresponding coordinate
237 : : // variables
238 [ # # ][ # # ]: 0 : rval = create_dummy_variables();MB_CHK_SET_ERR( rval, "Failed to create dummy variables" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
239 : :
240 : 0 : return MB_SUCCESS;
241 : : }
242 : :
243 : : // When noMesh option is used on this read, the old ReadNC class instance for last read can get out
244 : : // of scope (and deleted). The old instance initialized some variables properly when the mesh was
245 : : // created, but they are now lost. The new instance (will not create the mesh with noMesh option)
246 : : // has to restore them based on the existing mesh from last read
247 : 0 : ErrorCode NCHelperMPAS::check_existing_mesh()
248 : : {
249 : 0 : Interface*& mbImpl = _readNC->mbImpl;
250 : 0 : Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
251 : 0 : bool& noMesh = _readNC->noMesh;
252 : :
253 [ # # ]: 0 : if( noMesh )
254 : : {
255 : : ErrorCode rval;
256 : :
257 : : // Restore numCellGroups
258 [ # # ]: 0 : if( 0 == numCellGroups )
259 : : {
260 : : Tag numCellGroupsTag;
261 [ # # ][ # # ]: 0 : rval = mbImpl->tag_get_handle( "__NUM_CELL_GROUPS", 1, MB_TYPE_INTEGER, numCellGroupsTag );MB_CHK_SET_ERR( rval, "Trouble getting __NUM_CELL_GROUPS tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
262 [ # # ][ # # ]: 0 : if( MB_SUCCESS == rval ) rval = mbImpl->tag_get_data( numCellGroupsTag, &_fileSet, 1, &numCellGroups );MB_CHK_SET_ERR( rval, "Trouble getting data of __NUM_CELL_GROUPS tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
263 : : }
264 : :
265 [ # # ]: 0 : if( localGidVerts.empty() )
266 : : {
267 : : // Get all vertices from current file set (it is the input set in no_mesh scenario)
268 [ # # ]: 0 : Range local_verts;
269 [ # # ][ # # ]: 0 : rval = mbImpl->get_entities_by_dimension( _fileSet, 0, local_verts );MB_CHK_SET_ERR( rval, "Trouble getting local vertices in current file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
270 : :
271 [ # # ][ # # ]: 0 : if( !local_verts.empty() )
272 : : {
273 [ # # ][ # # ]: 0 : std::vector< int > gids( local_verts.size() );
274 : :
275 : : // !IMPORTANT : this has to be the GLOBAL_ID tag
276 [ # # ][ # # ]: 0 : rval = mbImpl->tag_get_data( mGlobalIdTag, local_verts, &gids[0] );MB_CHK_SET_ERR( rval, "Trouble getting local gid values of vertices" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
277 : :
278 : : // Restore localGidVerts
279 [ # # ][ # # ]: 0 : std::copy( gids.rbegin(), gids.rend(), range_inserter( localGidVerts ) );
280 [ # # ][ # # ]: 0 : nLocalVertices = localGidVerts.size();
[ # # ]
281 : 0 : }
282 : : }
283 : :
284 [ # # ]: 0 : if( localGidEdges.empty() )
285 : : {
286 : : // Get all edges from current file set (it is the input set in no_mesh scenario)
287 [ # # ]: 0 : Range local_edges;
288 [ # # ][ # # ]: 0 : rval = mbImpl->get_entities_by_dimension( _fileSet, 1, local_edges );MB_CHK_SET_ERR( rval, "Trouble getting local edges in current file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
289 : :
290 [ # # ][ # # ]: 0 : if( !local_edges.empty() )
291 : : {
292 [ # # ][ # # ]: 0 : std::vector< int > gids( local_edges.size() );
293 : :
294 : : // !IMPORTANT : this has to be the GLOBAL_ID tag
295 [ # # ][ # # ]: 0 : rval = mbImpl->tag_get_data( mGlobalIdTag, local_edges, &gids[0] );MB_CHK_SET_ERR( rval, "Trouble getting local gid values of edges" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
296 : :
297 : : // Restore localGidEdges
298 [ # # ][ # # ]: 0 : std::copy( gids.rbegin(), gids.rend(), range_inserter( localGidEdges ) );
299 [ # # ][ # # ]: 0 : nLocalEdges = localGidEdges.size();
[ # # ]
300 : 0 : }
301 : : }
302 : :
303 [ # # ]: 0 : if( localGidCells.empty() )
304 : : {
305 : : // Get all cells from current file set (it is the input set in no_mesh scenario)
306 [ # # ]: 0 : Range local_cells;
307 [ # # ][ # # ]: 0 : rval = mbImpl->get_entities_by_dimension( _fileSet, 2, local_cells );MB_CHK_SET_ERR( rval, "Trouble getting local cells in current file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
308 : :
309 [ # # ][ # # ]: 0 : if( !local_cells.empty() )
310 : : {
311 [ # # ][ # # ]: 0 : std::vector< int > gids( local_cells.size() );
312 : :
313 : : // !IMPORTANT : this has to be the GLOBAL_ID tag
314 [ # # ][ # # ]: 0 : rval = mbImpl->tag_get_data( mGlobalIdTag, local_cells, &gids[0] );MB_CHK_SET_ERR( rval, "Trouble getting local gid values of cells" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
315 : :
316 : : // Restore localGidCells
317 [ # # ][ # # ]: 0 : std::copy( gids.rbegin(), gids.rend(), range_inserter( localGidCells ) );
318 [ # # ]: 0 : nLocalCells = localGidCells.size();
319 : :
320 [ # # ]: 0 : if( numCellGroups > 1 )
321 : : {
322 : : // Restore cellHandleToGlobalID map
323 [ # # ]: 0 : Range::const_iterator rit;
324 : : int i;
325 [ # # ][ # # ]: 0 : for( rit = local_cells.begin(), i = 0; rit != local_cells.end(); ++rit, i++ )
[ # # ][ # # ]
[ # # ][ # # ]
326 [ # # ][ # # ]: 0 : cellHandleToGlobalID[*rit] = gids[i];
[ # # ]
327 [ # # ]: 0 : }
328 : 0 : }
329 : : }
330 : : }
331 : :
332 : 0 : return MB_SUCCESS;
333 : : }
334 : :
335 : 0 : ErrorCode NCHelperMPAS::create_mesh( Range& faces )
336 : : {
337 : 0 : Interface*& mbImpl = _readNC->mbImpl;
338 : 0 : bool& noMixedElements = _readNC->noMixedElements;
339 : 0 : bool& noEdges = _readNC->noEdges;
340 : 0 : DebugOutput& dbgOut = _readNC->dbgOut;
341 : :
342 : : #ifdef MOAB_HAVE_MPI
343 : 0 : int rank = 0;
344 : 0 : int procs = 1;
345 : 0 : bool& isParallel = _readNC->isParallel;
346 [ # # ]: 0 : if( isParallel )
347 : : {
348 : 0 : ParallelComm*& myPcomm = _readNC->myPcomm;
349 [ # # ][ # # ]: 0 : rank = myPcomm->proc_config().proc_rank();
350 [ # # ][ # # ]: 0 : procs = myPcomm->proc_config().proc_size();
351 : : }
352 : :
353 : : // Need to know whether we'll be creating gather mesh
354 [ # # ]: 0 : if( rank == _readNC->gatherSetRank ) createGatherSet = true;
355 : :
356 [ # # ]: 0 : if( procs >= 2 )
357 : : {
358 : : // Shift rank to obtain a rotated trivial partition
359 : 0 : int shifted_rank = rank;
360 : 0 : int& trivialPartitionShift = _readNC->trivialPartitionShift;
361 [ # # ]: 0 : if( trivialPartitionShift > 0 ) shifted_rank = ( rank + trivialPartitionShift ) % procs;
362 : :
363 : : // Compute the number of local cells on this proc
364 : 0 : nLocalCells = int( std::floor( 1.0 * nCells / procs ) );
365 : :
366 : : // The starting global cell index in the MPAS file for this proc
367 : 0 : int start_cell_idx = shifted_rank * nLocalCells;
368 : :
369 : : // Number of extra cells after equal split over procs
370 : 0 : int iextra = nCells % procs;
371 : :
372 : : // Allocate extra cells over procs
373 [ # # ]: 0 : if( shifted_rank < iextra ) nLocalCells++;
374 [ # # ]: 0 : start_cell_idx += std::min( shifted_rank, iextra );
375 : :
376 : 0 : start_cell_idx++; // 0 based -> 1 based
377 : :
378 : : // Redistribute local cells after trivial partition (e.g. apply Zoltan partition)
379 [ # # ][ # # ]: 0 : ErrorCode rval = redistribute_local_cells( start_cell_idx );MB_CHK_SET_ERR( rval, "Failed to redistribute local cells after trivial partition" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
380 : : }
381 : : else
382 : : {
383 : 0 : nLocalCells = nCells;
384 [ # # ]: 0 : localGidCells.insert( 1, nLocalCells );
385 : : }
386 : : #else
387 : : nLocalCells = nCells;
388 : : localGidCells.insert( 1, nLocalCells );
389 : : #endif
390 [ # # ][ # # ]: 0 : dbgOut.tprintf( 1, " localGidCells.psize() = %d\n", (int)localGidCells.psize() );
391 [ # # ][ # # ]: 0 : dbgOut.tprintf( 1, " localGidCells.size() = %d\n", (int)localGidCells.size() );
392 : :
393 : : // Read number of edges on each local cell, to calculate actual maxEdgesPerCell
394 : : int nEdgesOnCellVarId;
395 [ # # ]: 0 : int success = NCFUNC( inq_varid )( _fileId, "nEdgesOnCell", &nEdgesOnCellVarId );
396 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of nEdgesOnCell" );
[ # # ][ # # ]
[ # # ][ # # ]
397 [ # # ]: 0 : std::vector< int > num_edges_on_local_cells( nLocalCells );
398 : : #ifdef MOAB_HAVE_PNETCDF
399 : : size_t nb_reads = localGidCells.psize();
400 : : std::vector< int > requests( nb_reads );
401 : : std::vector< int > statuss( nb_reads );
402 : : size_t idxReq = 0;
403 : : #endif
404 : 0 : size_t indexInArray = 0;
405 [ # # ][ # # ]: 0 : for( Range::pair_iterator pair_iter = localGidCells.pair_begin(); pair_iter != localGidCells.pair_end();
[ # # ][ # # ]
[ # # ]
406 : : ++pair_iter )
407 : : {
408 [ # # ]: 0 : EntityHandle starth = pair_iter->first;
409 [ # # ]: 0 : EntityHandle endh = pair_iter->second;
410 : 0 : NCDF_SIZE read_start = ( NCDF_SIZE )( starth - 1 );
411 : 0 : NCDF_SIZE read_count = ( NCDF_SIZE )( endh - starth + 1 );
412 : :
413 : : // Do a partial read in each subrange
414 : : #ifdef MOAB_HAVE_PNETCDF
415 : : success = NCFUNCREQG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count,
416 : : &( num_edges_on_local_cells[indexInArray] ), &requests[idxReq++] );
417 : : #else
418 : : success = NCFUNCAG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count,
419 [ # # ][ # # ]: 0 : &( num_edges_on_local_cells[indexInArray] ) );
420 : : #endif
421 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nEdgesOnCell data in a loop" );
[ # # ][ # # ]
[ # # ][ # # ]
422 : :
423 : : // Increment the index for next subrange
424 : 0 : indexInArray += ( endh - starth + 1 );
425 : : }
426 : :
427 : : #ifdef MOAB_HAVE_PNETCDF
428 : : // Wait outside the loop
429 : : success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
430 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
431 : : #endif
432 : :
433 : : // Get local maxEdgesPerCell on this proc
434 : : int local_max_edges_per_cell =
435 [ # # ][ # # ]: 0 : *( std::max_element( num_edges_on_local_cells.begin(), num_edges_on_local_cells.end() ) );
436 : 0 : maxEdgesPerCell = local_max_edges_per_cell;
437 : :
438 : : // If parallel, do a MPI_Allreduce to get global maxEdgesPerCell across all procs
439 : : #ifdef MOAB_HAVE_MPI
440 [ # # ]: 0 : if( procs >= 2 )
441 : : {
442 : : int global_max_edges_per_cell;
443 : 0 : ParallelComm*& myPcomm = _readNC->myPcomm;
444 : : MPI_Allreduce( &local_max_edges_per_cell, &global_max_edges_per_cell, 1, MPI_INT, MPI_MAX,
445 [ # # ][ # # ]: 0 : myPcomm->proc_config().proc_comm() );
[ # # ]
446 [ # # ]: 0 : assert( local_max_edges_per_cell <= global_max_edges_per_cell );
447 : 0 : maxEdgesPerCell = global_max_edges_per_cell;
448 [ # # ][ # # ]: 0 : if( 0 == rank ) dbgOut.tprintf( 1, " global_max_edges_per_cell = %d\n", global_max_edges_per_cell );
449 : : }
450 : : #endif
451 : :
452 : : // Read vertices on each local cell, to get localGidVerts and cell connectivity later
453 : : int verticesOnCellVarId;
454 [ # # ]: 0 : success = NCFUNC( inq_varid )( _fileId, "verticesOnCell", &verticesOnCellVarId );
455 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of verticesOnCell" );
[ # # ][ # # ]
[ # # ][ # # ]
456 [ # # ]: 0 : std::vector< int > vertices_on_local_cells( nLocalCells * maxEdgesPerCell );
457 : : #ifdef MOAB_HAVE_PNETCDF
458 : : idxReq = 0;
459 : : #endif
460 : 0 : indexInArray = 0;
461 [ # # ][ # # ]: 0 : for( Range::pair_iterator pair_iter = localGidCells.pair_begin(); pair_iter != localGidCells.pair_end();
[ # # ][ # # ]
[ # # ]
462 : : ++pair_iter )
463 : : {
464 [ # # ]: 0 : EntityHandle starth = pair_iter->first;
465 [ # # ]: 0 : EntityHandle endh = pair_iter->second;
466 : 0 : NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 };
467 : 0 : NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ),
468 : 0 : static_cast< NCDF_SIZE >( maxEdgesPerCell ) };
469 : :
470 : : // Do a partial read in each subrange
471 : : #ifdef MOAB_HAVE_PNETCDF
472 : : success = NCFUNCREQG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
473 : : &( vertices_on_local_cells[indexInArray] ), &requests[idxReq++] );
474 : : #else
475 : : success = NCFUNCAG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
476 [ # # ][ # # ]: 0 : &( vertices_on_local_cells[indexInArray] ) );
477 : : #endif
478 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnCell data in a loop" );
[ # # ][ # # ]
[ # # ][ # # ]
479 : :
480 : : // Increment the index for next subrange
481 : 0 : indexInArray += ( endh - starth + 1 ) * maxEdgesPerCell;
482 : : }
483 : :
484 : : #ifdef MOAB_HAVE_PNETCDF
485 : : // Wait outside the loop
486 : : success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
487 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
488 : : #endif
489 : :
490 : : // Correct local cell vertices array, replace the padded vertices with the last vertices
491 : : // in the corresponding cells; sometimes the padded vertices are 0, sometimes a large
492 : : // vertex id. Make sure they are consistent to our padded option
493 [ # # ]: 0 : for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ )
494 : : {
495 [ # # ]: 0 : int num_edges = num_edges_on_local_cells[local_cell_idx];
496 : 0 : int idx_in_local_vert_arr = local_cell_idx * maxEdgesPerCell;
497 [ # # ]: 0 : int last_vert_idx = vertices_on_local_cells[idx_in_local_vert_arr + num_edges - 1];
498 [ # # ]: 0 : for( int i = num_edges; i < maxEdgesPerCell; i++ )
499 [ # # ]: 0 : vertices_on_local_cells[idx_in_local_vert_arr + i] = last_vert_idx;
500 : : }
501 : :
502 : : // Create local vertices
503 : : EntityHandle start_vertex;
504 [ # # ][ # # ]: 0 : ErrorCode rval = create_local_vertices( vertices_on_local_cells, start_vertex );MB_CHK_SET_ERR( rval, "Failed to create local vertices for MPAS mesh" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
505 : :
506 : : // Create local edges (unless NO_EDGES read option is set)
507 [ # # ]: 0 : if( !noEdges )
508 : : {
509 [ # # ][ # # ]: 0 : rval = create_local_edges( start_vertex, num_edges_on_local_cells );MB_CHK_SET_ERR( rval, "Failed to create local edges for MPAS mesh" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
510 : : }
511 : :
512 : : // Create local cells, either unpadded or padded
513 [ # # ]: 0 : if( noMixedElements )
514 : : {
515 [ # # ][ # # ]: 0 : 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" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
516 : : }
517 : : else
518 : : {
519 [ # # ][ # # ]: 0 : 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" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
520 : : }
521 : :
522 : : // Set tag for numCellGroups
523 : 0 : Tag numCellGroupsTag = 0;
524 : : rval = mbImpl->tag_get_handle( "__NUM_CELL_GROUPS", 1, MB_TYPE_INTEGER, numCellGroupsTag,
525 [ # # ][ # # ]: 0 : MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating __NUM_CELL_GROUPS tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
526 [ # # ][ # # ]: 0 : rval = mbImpl->tag_set_data( numCellGroupsTag, &_fileSet, 1, &numCellGroups );MB_CHK_SET_ERR( rval, "Trouble setting data to __NUM_CELL_GROUPS tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
527 : :
528 [ # # ]: 0 : if( createGatherSet )
529 : : {
530 : : EntityHandle gather_set;
531 [ # # ][ # # ]: 0 : rval = _readNC->readMeshIface->create_gather_set( gather_set );MB_CHK_SET_ERR( rval, "Failed to create gather set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
532 : :
533 : : // Create gather set vertices
534 : : EntityHandle start_gather_set_vertex;
535 [ # # ][ # # ]: 0 : rval = create_gather_set_vertices( gather_set, start_gather_set_vertex );MB_CHK_SET_ERR( rval, "Failed to create gather set vertices for MPAS mesh" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
536 : :
537 : : // Create gather set edges (unless NO_EDGES read option is set)
538 [ # # ]: 0 : if( !noEdges )
539 : : {
540 [ # # ][ # # ]: 0 : rval = create_gather_set_edges( gather_set, start_gather_set_vertex );MB_CHK_SET_ERR( rval, "Failed to create gather set edges for MPAS mesh" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
541 : : }
542 : :
543 : : // Create gather set cells, either unpadded or padded
544 [ # # ]: 0 : if( noMixedElements )
545 : : {
546 [ # # ][ # # ]: 0 : rval = create_padded_gather_set_cells( gather_set, start_gather_set_vertex );MB_CHK_SET_ERR( rval, "Failed to create padded gather set cells for MPAS mesh" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
547 : : }
548 : : else
549 : : {
550 [ # # ][ # # ]: 0 : rval = create_gather_set_cells( gather_set, start_gather_set_vertex );MB_CHK_SET_ERR( rval, "Failed to create gather set cells for MPAS mesh" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
551 : : }
552 : : }
553 : :
554 : 0 : return MB_SUCCESS;
555 : : }
556 : :
557 : 0 : ErrorCode NCHelperMPAS::read_ucd_variables_to_nonset_allocate( std::vector< ReadNC::VarData >& vdatas,
558 : : std::vector< int >& tstep_nums )
559 : : {
560 : 0 : Interface*& mbImpl = _readNC->mbImpl;
561 : 0 : std::vector< int >& dimLens = _readNC->dimLens;
562 : 0 : bool& noEdges = _readNC->noEdges;
563 : 0 : DebugOutput& dbgOut = _readNC->dbgOut;
564 : :
565 : 0 : Range* range = NULL;
566 : :
567 : : // Get vertices
568 [ # # ]: 0 : Range verts;
569 [ # # ][ # # ]: 0 : ErrorCode rval = mbImpl->get_entities_by_dimension( _fileSet, 0, verts );MB_CHK_SET_ERR( rval, "Trouble getting vertices in current file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
570 [ # # ][ # # ]: 0 : assert( "Should only have a single vertex subrange, since they were read in one shot" && verts.psize() == 1 );
571 : :
572 : : // Get edges
573 [ # # ]: 0 : Range edges;
574 [ # # ][ # # ]: 0 : rval = mbImpl->get_entities_by_dimension( _fileSet, 1, edges );MB_CHK_SET_ERR( rval, "Trouble getting edges in current file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
575 : :
576 : : // Get faces
577 [ # # ]: 0 : Range faces;
578 [ # # ][ # # ]: 0 : rval = mbImpl->get_entities_by_dimension( _fileSet, 2, faces );MB_CHK_SET_ERR( rval, "Trouble getting faces in current file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
579 : : // Note, for MPAS faces.psize() can be more than 1
580 : :
581 : : #ifdef MOAB_HAVE_MPI
582 : 0 : bool& isParallel = _readNC->isParallel;
583 [ # # ]: 0 : if( isParallel )
584 : : {
585 : 0 : ParallelComm*& myPcomm = _readNC->myPcomm;
586 [ # # ][ # # ]: 0 : rval = myPcomm->filter_pstatus( faces, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &facesOwned );MB_CHK_SET_ERR( rval, "Trouble getting owned faces in current file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
587 : : }
588 : : else
589 [ # # ]: 0 : facesOwned = faces; // not running in parallel, but still with MPI
590 : : #else
591 : : facesOwned = faces;
592 : : #endif
593 : :
594 [ # # ]: 0 : for( unsigned int i = 0; i < vdatas.size(); i++ )
595 : : {
596 : : // Skip edge variables, if specified by the read options
597 [ # # ][ # # ]: 0 : if( noEdges && vdatas[i].entLoc == ReadNC::ENTLOCEDGE ) continue;
[ # # ][ # # ]
598 : :
599 : : // Support non-set variables with 3 dimensions like (Time, nCells, nVertLevels), or
600 : : // 2 dimensions like (Time, nCells)
601 [ # # ][ # # ]: 0 : assert( 3 == vdatas[i].varDims.size() || 2 == vdatas[i].varDims.size() );
[ # # ][ # # ]
602 : :
603 : : // For a non-set variable, time should be the first dimension
604 [ # # ][ # # ]: 0 : assert( tDim == vdatas[i].varDims[0] );
[ # # ]
605 : :
606 : : // Set up readStarts and readCounts
607 [ # # ][ # # ]: 0 : vdatas[i].readStarts.resize( 3 );
608 [ # # ][ # # ]: 0 : vdatas[i].readCounts.resize( 3 );
609 : :
610 : : // First: Time
611 [ # # ][ # # ]: 0 : vdatas[i].readStarts[0] = 0; // This value is timestep dependent, will be set later
612 [ # # ][ # # ]: 0 : vdatas[i].readCounts[0] = 1;
613 : :
614 : : // Next: nVertices / nCells / nEdges
615 [ # # ]: 0 : switch( vdatas[i].entLoc )
[ # # # # ]
616 : : {
617 : : case ReadNC::ENTLOCVERT:
618 : : // Vertices
619 : : // Start from the first localGidVerts
620 : : // Actually, this will be reset later on in a loop
621 [ # # ][ # # ]: 0 : vdatas[i].readStarts[1] = localGidVerts[0] - 1;
[ # # ]
622 [ # # ][ # # ]: 0 : vdatas[i].readCounts[1] = nLocalVertices;
623 : 0 : range = &verts;
624 : 0 : break;
625 : : case ReadNC::ENTLOCFACE:
626 : : // Faces
627 : : // Start from the first localGidCells
628 : : // Actually, this will be reset later on in a loop
629 [ # # ][ # # ]: 0 : vdatas[i].readStarts[1] = localGidCells[0] - 1;
[ # # ]
630 [ # # ][ # # ]: 0 : vdatas[i].readCounts[1] = nLocalCells;
631 : 0 : range = &facesOwned;
632 : 0 : break;
633 : : case ReadNC::ENTLOCEDGE:
634 : : // Edges
635 : : // Start from the first localGidEdges
636 : : // Actually, this will be reset later on in a loop
637 [ # # ][ # # ]: 0 : vdatas[i].readStarts[1] = localGidEdges[0] - 1;
[ # # ]
638 [ # # ][ # # ]: 0 : vdatas[i].readCounts[1] = nLocalEdges;
639 : 0 : range = &edges;
640 : 0 : break;
641 : : default:
642 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << vdatas[i].varName );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
643 : : }
644 : :
645 : : // Finally: nVertLevels or other optional levels, it is possible that there is no
646 : : // level dimension (numLev is 0) for this non-set variable, e.g. (Time, nCells)
647 [ # # ][ # # ]: 0 : if( vdatas[i].numLev < 1 ) vdatas[i].numLev = 1;
[ # # ]
648 [ # # ][ # # ]: 0 : vdatas[i].readStarts[2] = 0;
649 [ # # ][ # # ]: 0 : vdatas[i].readCounts[2] = vdatas[i].numLev;
[ # # ]
650 : :
651 : : // Get variable size
652 [ # # ]: 0 : vdatas[i].sz = 1;
653 [ # # ]: 0 : for( std::size_t idx = 0; idx != 3; idx++ )
654 [ # # ][ # # ]: 0 : vdatas[i].sz *= vdatas[i].readCounts[idx];
[ # # ]
655 : :
656 [ # # ]: 0 : for( unsigned int t = 0; t < tstep_nums.size(); t++ )
657 : : {
658 [ # # ][ # # ]: 0 : dbgOut.tprintf( 2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t] );
[ # # ]
659 : :
660 [ # # ][ # # ]: 0 : if( tstep_nums[t] >= dimLens[tDim] )
[ # # ]
661 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number " << tstep_nums[t] ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
662 : :
663 : : // Get the tag to read into
664 [ # # ][ # # ]: 0 : if( !vdatas[i].varTags[t] )
[ # # ]
665 : : {
666 [ # # ][ # # ]: 0 : rval = get_tag_to_nonset( vdatas[i], tstep_nums[t], vdatas[i].varTags[t], vdatas[i].numLev );MB_CHK_SET_ERR( rval, "Trouble getting tag for variable " << vdatas[i].varName );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
667 : : }
668 : :
669 : : // Get ptr to tag space
670 [ # # ][ # # ]: 0 : if( vdatas[i].entLoc == ReadNC::ENTLOCFACE && numCellGroups > 1 )
[ # # ][ # # ]
671 : : {
672 : : // For a cell variable that is NOT on one contiguous chunk of faces, defer its tag
673 : : // space allocation
674 [ # # ][ # # ]: 0 : vdatas[i].varDatas[t] = NULL;
675 : : }
676 : : else
677 : : {
678 [ # # ][ # # ]: 0 : assert( 1 == range->psize() );
679 : : void* data;
680 : : int count;
681 [ # # ][ # # ]: 0 : rval = mbImpl->tag_iterate( vdatas[i].varTags[t], range->begin(), range->end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate tag for variable " << vdatas[i].varName );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
682 [ # # ][ # # ]: 0 : assert( (unsigned)count == range->size() );
683 [ # # ][ # # ]: 0 : vdatas[i].varDatas[t] = data;
684 : : }
685 : : }
686 : : }
687 : :
688 : 0 : return rval;
689 : : }
690 : :
691 : : #ifdef MOAB_HAVE_PNETCDF
692 : : ErrorCode NCHelperMPAS::read_ucd_variables_to_nonset_async( std::vector< ReadNC::VarData >& vdatas,
693 : : std::vector< int >& tstep_nums )
694 : : {
695 : : Interface*& mbImpl = _readNC->mbImpl;
696 : : bool& noEdges = _readNC->noEdges;
697 : : DebugOutput& dbgOut = _readNC->dbgOut;
698 : :
699 : : ErrorCode rval = read_ucd_variables_to_nonset_allocate( vdatas, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble allocating space to read non-set variables" );
700 : :
701 : : // Finally, read into that space
702 : : int success;
703 : : Range* pLocalGid = NULL;
704 : :
705 : : for( unsigned int i = 0; i < vdatas.size(); i++ )
706 : : {
707 : : // Skip edge variables, if specified by the read options
708 : : if( noEdges && vdatas[i].entLoc == ReadNC::ENTLOCEDGE ) continue;
709 : :
710 : : switch( vdatas[i].entLoc )
711 : : {
712 : : case ReadNC::ENTLOCVERT:
713 : : pLocalGid = &localGidVerts;
714 : : break;
715 : : case ReadNC::ENTLOCFACE:
716 : : pLocalGid = &localGidCells;
717 : : break;
718 : : case ReadNC::ENTLOCEDGE:
719 : : pLocalGid = &localGidEdges;
720 : : break;
721 : : default:
722 : : MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << vdatas[i].varName );
723 : : }
724 : :
725 : : std::size_t sz = vdatas[i].sz;
726 : :
727 : : for( unsigned int t = 0; t < tstep_nums.size(); t++ )
728 : : {
729 : : // We will synchronize all these reads with the other processors,
730 : : // so the wait will be inside this double loop; is it too much?
731 : : size_t nb_reads = pLocalGid->psize();
732 : : std::vector< int > requests( nb_reads ), statuss( nb_reads );
733 : : size_t idxReq = 0;
734 : :
735 : : // Set readStart for each timestep along time dimension
736 : : vdatas[i].readStarts[0] = tstep_nums[t];
737 : :
738 : : switch( vdatas[i].varDataType )
739 : : {
740 : : case NC_FLOAT:
741 : : case NC_DOUBLE: {
742 : : // Read float as double
743 : : std::vector< double > tmpdoubledata( sz );
744 : :
745 : : // In the case of ucd mesh, and on multiple proc,
746 : : // we need to read as many times as subranges we have in the
747 : : // localGid range;
748 : : // basically, we have to give a different point
749 : : // for data to start, for every subrange :(
750 : : size_t indexInDoubleArray = 0;
751 : : size_t ic = 0;
752 : : for( Range::pair_iterator pair_iter = pLocalGid->pair_begin(); pair_iter != pLocalGid->pair_end();
753 : : ++pair_iter, ic++ )
754 : : {
755 : : EntityHandle starth = pair_iter->first;
756 : : EntityHandle endh = pair_iter->second; // Inclusive
757 : : vdatas[i].readStarts[1] = ( NCDF_SIZE )( starth - 1 );
758 : : vdatas[i].readCounts[1] = ( NCDF_SIZE )( endh - starth + 1 );
759 : :
760 : : // Do a partial read, in each subrange
761 : : // Wait outside this loop
762 : : success =
763 : : NCFUNCREQG( _vara_double )( _fileId, vdatas[i].varId, &( vdatas[i].readStarts[0] ),
764 : : &( vdatas[i].readCounts[0] ),
765 : : &( tmpdoubledata[indexInDoubleArray] ), &requests[idxReq++] );
766 : : if( success )
767 : : MB_SET_ERR( MB_FAILURE,
768 : : "Failed to read double data in a loop for variable " << vdatas[i].varName );
769 : : // We need to increment the index in double array for the
770 : : // next subrange
771 : : indexInDoubleArray += ( endh - starth + 1 ) * 1 * vdatas[i].numLev;
772 : : }
773 : : assert( ic == pLocalGid->psize() );
774 : :
775 : : success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
776 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
777 : :
778 : : if( vdatas[i].entLoc == ReadNC::ENTLOCFACE && numCellGroups > 1 )
779 : : {
780 : : // For a cell variable that is NOT on one contiguous chunk of faces,
781 : : // allocate tag space for each cell group, and utilize cellHandleToGlobalID
782 : : // map to read tag data
783 : : Range::iterator iter = facesOwned.begin();
784 : : while( iter != facesOwned.end() )
785 : : {
786 : : int count;
787 : : void* ptr;
788 : : rval = mbImpl->tag_iterate( vdatas[i].varTags[t], iter, facesOwned.end(), count, ptr );MB_CHK_SET_ERR( rval, "Failed to iterate tag on owned faces" );
789 : :
790 : : for( int j = 0; j < count; j++ )
791 : : {
792 : : int global_cell_idx =
793 : : cellHandleToGlobalID[*( iter + j )]; // Global cell index, 1 based
794 : : int local_cell_idx =
795 : : localGidCells.index( global_cell_idx ); // Local cell index, 0 based
796 : : assert( local_cell_idx != -1 );
797 : : for( int level = 0; level < vdatas[i].numLev; level++ )
798 : : ( (double*)ptr )[j * vdatas[i].numLev + level] =
799 : : tmpdoubledata[local_cell_idx * vdatas[i].numLev + level];
800 : : }
801 : :
802 : : iter += count;
803 : : }
804 : : }
805 : : else
806 : : {
807 : : void* data = vdatas[i].varDatas[t];
808 : : for( std::size_t idx = 0; idx != tmpdoubledata.size(); idx++ )
809 : : ( (double*)data )[idx] = tmpdoubledata[idx];
810 : : }
811 : :
812 : : break;
813 : : }
814 : : default:
815 : : MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName );
816 : : }
817 : : }
818 : : }
819 : :
820 : : // Debug output, if requested
821 : : if( 1 == dbgOut.get_verbosity() )
822 : : {
823 : : dbgOut.printf( 1, "Read variables: %s", vdatas.begin()->varName.c_str() );
824 : : for( unsigned int i = 1; i < vdatas.size(); i++ )
825 : : dbgOut.printf( 1, ", %s ", vdatas[i].varName.c_str() );
826 : : dbgOut.tprintf( 1, "\n" );
827 : : }
828 : :
829 : : return rval;
830 : : }
831 : : #else
832 : 0 : ErrorCode NCHelperMPAS::read_ucd_variables_to_nonset( std::vector< ReadNC::VarData >& vdatas,
833 : : std::vector< int >& tstep_nums )
834 : : {
835 : 0 : Interface*& mbImpl = _readNC->mbImpl;
836 : 0 : bool& noEdges = _readNC->noEdges;
837 : 0 : DebugOutput& dbgOut = _readNC->dbgOut;
838 : :
839 [ # # ][ # # ]: 0 : ErrorCode rval = read_ucd_variables_to_nonset_allocate( vdatas, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble allocating space to read non-set variables" );
[ # # ][ # # ]
[ # # ][ # # ]
840 : :
841 : : // Finally, read into that space
842 : : int success;
843 : 0 : Range* pLocalGid = NULL;
844 : :
845 [ # # ]: 0 : for( unsigned int i = 0; i < vdatas.size(); i++ )
846 : : {
847 : : // Skip edge variables, if specified by the read options
848 [ # # ][ # # ]: 0 : if( noEdges && vdatas[i].entLoc == ReadNC::ENTLOCEDGE ) continue;
[ # # ]
849 : :
850 [ # # # # ]: 0 : switch( vdatas[i].entLoc )
851 : : {
852 : : case ReadNC::ENTLOCVERT:
853 : 0 : pLocalGid = &localGidVerts;
854 : 0 : break;
855 : : case ReadNC::ENTLOCFACE:
856 : 0 : pLocalGid = &localGidCells;
857 : 0 : break;
858 : : case ReadNC::ENTLOCEDGE:
859 : 0 : pLocalGid = &localGidEdges;
860 : 0 : break;
861 : : default:
862 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << vdatas[i].varName );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
863 : : }
864 : :
865 : 0 : std::size_t sz = vdatas[i].sz;
866 : :
867 [ # # ]: 0 : for( unsigned int t = 0; t < tstep_nums.size(); t++ )
868 : : {
869 : : // Set readStart for each timestep along time dimension
870 : 0 : vdatas[i].readStarts[0] = tstep_nums[t];
871 : :
872 [ # # ]: 0 : switch( vdatas[i].varDataType )
873 : : {
874 : : case NC_FLOAT:
875 : : case NC_DOUBLE: {
876 : : // Read float as double
877 [ # # ]: 0 : std::vector< double > tmpdoubledata( sz );
878 : :
879 : : // In the case of ucd mesh, and on multiple proc,
880 : : // we need to read as many times as subranges we have in the
881 : : // localGid range;
882 : : // basically, we have to give a different point
883 : : // for data to start, for every subrange :(
884 : 0 : size_t indexInDoubleArray = 0;
885 : 0 : size_t ic = 0;
886 [ # # ][ # # ]: 0 : for( Range::pair_iterator pair_iter = pLocalGid->pair_begin(); pair_iter != pLocalGid->pair_end();
[ # # ][ # # ]
[ # # ]
887 : : ++pair_iter, ic++ )
888 : : {
889 [ # # ]: 0 : EntityHandle starth = pair_iter->first;
890 [ # # ]: 0 : EntityHandle endh = pair_iter->second; // Inclusive
891 [ # # ][ # # ]: 0 : vdatas[i].readStarts[1] = ( NCDF_SIZE )( starth - 1 );
892 [ # # ][ # # ]: 0 : vdatas[i].readCounts[1] = ( NCDF_SIZE )( endh - starth + 1 );
893 : :
894 [ # # ][ # # ]: 0 : success = NCFUNCAG( _vara_double )( _fileId, vdatas[i].varId, &( vdatas[i].readStarts[0] ),
[ # # ]
895 [ # # ][ # # ]: 0 : &( vdatas[i].readCounts[0] ),
896 [ # # ][ # # ]: 0 : &( tmpdoubledata[indexInDoubleArray] ) );
897 [ # # ]: 0 : if( success )
898 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
899 : : "Failed to read double data in a loop for variable " << vdatas[i].varName );
900 : : // We need to increment the index in double array for the
901 : : // next subrange
902 [ # # ]: 0 : indexInDoubleArray += ( endh - starth + 1 ) * 1 * vdatas[i].numLev;
903 : : }
904 [ # # ][ # # ]: 0 : assert( ic == pLocalGid->psize() );
905 : :
906 [ # # ][ # # ]: 0 : if( vdatas[i].entLoc == ReadNC::ENTLOCFACE && numCellGroups > 1 )
[ # # ][ # # ]
907 : : {
908 : : // For a cell variable that is NOT on one contiguous chunk of faces,
909 : : // allocate tag space for each cell group, and utilize cellHandleToGlobalID
910 : : // map to read tag data
911 [ # # ]: 0 : Range::iterator iter = facesOwned.begin();
912 [ # # ][ # # ]: 0 : while( iter != facesOwned.end() )
[ # # ]
913 : : {
914 : : int count;
915 : : void* ptr;
916 [ # # ][ # # ]: 0 : rval = mbImpl->tag_iterate( vdatas[i].varTags[t], iter, facesOwned.end(), count, ptr );MB_CHK_SET_ERR( rval, "Failed to iterate tag on owned faces" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
917 : :
918 [ # # ]: 0 : for( int j = 0; j < count; j++ )
919 : : {
920 : : int global_cell_idx =
921 [ # # ][ # # ]: 0 : cellHandleToGlobalID[*( iter + j )]; // Global cell index, 1 based
[ # # ]
922 : : int local_cell_idx =
923 [ # # ]: 0 : localGidCells.index( global_cell_idx ); // Local cell index, 0 based
924 [ # # ]: 0 : assert( local_cell_idx != -1 );
925 [ # # ][ # # ]: 0 : for( int level = 0; level < vdatas[i].numLev; level++ )
926 [ # # ]: 0 : ( (double*)ptr )[j * vdatas[i].numLev + level] =
927 [ # # ][ # # ]: 0 : tmpdoubledata[local_cell_idx * vdatas[i].numLev + level];
928 : : }
929 : :
930 [ # # ]: 0 : iter += count;
931 : : }
932 : : }
933 : : else
934 : : {
935 [ # # ][ # # ]: 0 : void* data = vdatas[i].varDatas[t];
936 [ # # ]: 0 : for( std::size_t idx = 0; idx != tmpdoubledata.size(); idx++ )
937 [ # # ]: 0 : ( (double*)data )[idx] = tmpdoubledata[idx];
938 : : }
939 : :
940 [ # # ]: 0 : break;
941 : : }
942 : : default:
943 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
944 : : }
945 : : }
946 : : }
947 : :
948 : : // Debug output, if requested
949 [ # # ]: 0 : if( 1 == dbgOut.get_verbosity() )
950 : : {
951 [ # # ][ # # ]: 0 : dbgOut.printf( 1, "Read variables: %s", vdatas.begin()->varName.c_str() );
952 [ # # ]: 0 : for( unsigned int i = 1; i < vdatas.size(); i++ )
953 : 0 : dbgOut.printf( 1, ", %s ", vdatas[i].varName.c_str() );
954 : 0 : dbgOut.tprintf( 1, "\n" );
955 : : }
956 : :
957 : 0 : return rval;
958 : : }
959 : : #endif
960 : :
961 : : #ifdef MOAB_HAVE_MPI
962 : 0 : ErrorCode NCHelperMPAS::redistribute_local_cells( int start_cell_idx )
963 : : {
964 : : // If possible, apply Zoltan partition
965 : : #ifdef MOAB_HAVE_ZOLTAN
966 : : if( ScdParData::RCBZOLTAN == _readNC->partMethod )
967 : : {
968 : : // Read x coordinates of cell centers
969 : : int xCellVarId;
970 : : int success = NCFUNC( inq_varid )( _fileId, "xCell", &xCellVarId );
971 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of xCell" );
972 : : std::vector< double > xCell( nLocalCells );
973 : : NCDF_SIZE read_start = static_cast< NCDF_SIZE >( start_cell_idx - 1 );
974 : : NCDF_SIZE read_count = static_cast< NCDF_SIZE >( nLocalCells );
975 : : success = NCFUNCAG( _vara_double )( _fileId, xCellVarId, &read_start, &read_count, &xCell[0] );
976 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read xCell data" );
977 : :
978 : : // Read y coordinates of cell centers
979 : : int yCellVarId;
980 : : success = NCFUNC( inq_varid )( _fileId, "yCell", &yCellVarId );
981 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of yCell" );
982 : : std::vector< double > yCell( nLocalCells );
983 : : success = NCFUNCAG( _vara_double )( _fileId, yCellVarId, &read_start, &read_count, &yCell[0] );
984 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read yCell data" );
985 : :
986 : : // Read z coordinates of cell centers
987 : : int zCellVarId;
988 : : success = NCFUNC( inq_varid )( _fileId, "zCell", &zCellVarId );
989 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of zCell" );
990 : : std::vector< double > zCell( nLocalCells );
991 : : success = NCFUNCAG( _vara_double )( _fileId, zCellVarId, &read_start, &read_count, &zCell[0] );
992 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read zCell data" );
993 : :
994 : : // Zoltan partition using RCB; maybe more studies would be good, as to which partition
995 : : // is better
996 : : Interface*& mbImpl = _readNC->mbImpl;
997 : : DebugOutput& dbgOut = _readNC->dbgOut;
998 : : ZoltanPartitioner* mbZTool = new ZoltanPartitioner( mbImpl, false, 0, NULL );
999 : : ErrorCode rval = mbZTool->repartition( xCell, yCell, zCell, start_cell_idx, "RCB", localGidCells );MB_CHK_SET_ERR( rval, "Error in Zoltan partitioning" );
1000 : : delete mbZTool;
1001 : :
1002 : : dbgOut.tprintf( 1, "After Zoltan partitioning, localGidCells.psize() = %d\n", (int)localGidCells.psize() );
1003 : : dbgOut.tprintf( 1, " localGidCells.size() = %d\n", (int)localGidCells.size() );
1004 : :
1005 : : // This is important: local cells are now redistributed, so nLocalCells might be different!
1006 : : nLocalCells = localGidCells.size();
1007 : :
1008 : : return MB_SUCCESS;
1009 : : }
1010 : : #endif
1011 : :
1012 : : // By default, apply trivial partition
1013 : 0 : localGidCells.insert( start_cell_idx, start_cell_idx + nLocalCells - 1 );
1014 : :
1015 : 0 : return MB_SUCCESS;
1016 : : }
1017 : : #endif
1018 : :
1019 : 0 : ErrorCode NCHelperMPAS::create_local_vertices( const std::vector< int >& vertices_on_local_cells,
1020 : : EntityHandle& start_vertex )
1021 : : {
1022 : 0 : Interface*& mbImpl = _readNC->mbImpl;
1023 : 0 : Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
1024 : 0 : const Tag*& mpFileIdTag = _readNC->mpFileIdTag;
1025 : 0 : DebugOutput& dbgOut = _readNC->dbgOut;
1026 : :
1027 : : // Make a copy of vertices_on_local_cells for sorting (keep original one to set cell
1028 : : // connectivity later)
1029 [ # # ]: 0 : std::vector< int > vertices_on_local_cells_sorted( vertices_on_local_cells );
1030 [ # # ]: 0 : std::sort( vertices_on_local_cells_sorted.begin(), vertices_on_local_cells_sorted.end() );
1031 : : std::copy( vertices_on_local_cells_sorted.rbegin(), vertices_on_local_cells_sorted.rend(),
1032 [ # # ][ # # ]: 0 : range_inserter( localGidVerts ) );
1033 [ # # ]: 0 : nLocalVertices = localGidVerts.size();
1034 : :
1035 [ # # ][ # # ]: 0 : dbgOut.tprintf( 1, " localGidVerts.psize() = %d\n", (int)localGidVerts.psize() );
1036 [ # # ][ # # ]: 0 : dbgOut.tprintf( 1, " localGidVerts.size() = %d\n", (int)localGidVerts.size() );
1037 : :
1038 : : // Create local vertices
1039 [ # # ]: 0 : std::vector< double* > arrays;
1040 : : ErrorCode rval =
1041 : : _readNC->readMeshIface->get_node_coords( 3, nLocalVertices, 0, start_vertex, arrays,
1042 : : // Might have to create gather mesh later
1043 [ # # ][ # # ]: 0 : ( createGatherSet ? nLocalVertices + nVertices : nLocalVertices ) );MB_CHK_SET_ERR( rval, "Failed to create local vertices" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1044 : :
1045 : : // Add local vertices to current file set
1046 [ # # ]: 0 : Range local_verts_range( start_vertex, start_vertex + nLocalVertices - 1 );
1047 [ # # ][ # # ]: 0 : rval = _readNC->mbImpl->add_entities( _fileSet, local_verts_range );MB_CHK_SET_ERR( rval, "Failed to add local vertices to current file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1048 : :
1049 : : // Get ptr to GID memory for local vertices
1050 : 0 : int count = 0;
1051 : 0 : void* data = NULL;
1052 [ # # ][ # # ]: 0 : 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" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1053 [ # # ]: 0 : assert( count == nLocalVertices );
1054 : 0 : int* gid_data = (int*)data;
1055 [ # # ][ # # ]: 0 : std::copy( localGidVerts.begin(), localGidVerts.end(), gid_data );
[ # # ]
1056 : :
1057 : : // Duplicate GID data, which will be used to resolve sharing
1058 [ # # ]: 0 : if( mpFileIdTag )
1059 : : {
1060 [ # # ][ # # ]: 0 : 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" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1061 [ # # ]: 0 : assert( count == nLocalVertices );
1062 : 0 : int bytes_per_tag = 4;
1063 [ # # ][ # # ]: 0 : rval = mbImpl->tag_get_bytes( *mpFileIdTag, bytes_per_tag );MB_CHK_SET_ERR( rval, "Can't get number of bytes for file id tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1064 [ # # ]: 0 : if( 4 == bytes_per_tag )
1065 : : {
1066 : 0 : gid_data = (int*)data;
1067 [ # # ][ # # ]: 0 : std::copy( localGidVerts.begin(), localGidVerts.end(), gid_data );
[ # # ]
1068 : : }
1069 [ # # ]: 0 : else if( 8 == bytes_per_tag )
1070 : : { // Should be a handle tag on 64 bit machine?
1071 : 0 : long* handle_tag_data = (long*)data;
1072 [ # # ][ # # ]: 0 : std::copy( localGidVerts.begin(), localGidVerts.end(), handle_tag_data );
[ # # ]
1073 : : }
1074 : : }
1075 : :
1076 : : #ifdef MOAB_HAVE_PNETCDF
1077 : : size_t nb_reads = localGidVerts.psize();
1078 : : std::vector< int > requests( nb_reads );
1079 : : std::vector< int > statuss( nb_reads );
1080 : : size_t idxReq = 0;
1081 : : #endif
1082 : :
1083 : : // Read x coordinates for local vertices
1084 [ # # ]: 0 : double* xptr = arrays[0];
1085 : : int xVertexVarId;
1086 [ # # ]: 0 : int success = NCFUNC( inq_varid )( _fileId, "xVertex", &xVertexVarId );
1087 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of xVertex" );
[ # # ][ # # ]
[ # # ][ # # ]
1088 : 0 : size_t indexInArray = 0;
1089 [ # # ][ # # ]: 0 : for( Range::pair_iterator pair_iter = localGidVerts.pair_begin(); pair_iter != localGidVerts.pair_end();
[ # # ][ # # ]
[ # # ]
1090 : : ++pair_iter )
1091 : : {
1092 [ # # ]: 0 : EntityHandle starth = pair_iter->first;
1093 [ # # ]: 0 : EntityHandle endh = pair_iter->second;
1094 : 0 : NCDF_SIZE read_start = ( NCDF_SIZE )( starth - 1 );
1095 : 0 : NCDF_SIZE read_count = ( NCDF_SIZE )( endh - starth + 1 );
1096 : :
1097 : : // Do a partial read in each subrange
1098 : : #ifdef MOAB_HAVE_PNETCDF
1099 : : success = NCFUNCREQG( _vara_double )( _fileId, xVertexVarId, &read_start, &read_count, &( xptr[indexInArray] ),
1100 : : &requests[idxReq++] );
1101 : : #else
1102 [ # # ]: 0 : success = NCFUNCAG( _vara_double )( _fileId, xVertexVarId, &read_start, &read_count, &( xptr[indexInArray] ) );
1103 : : #endif
1104 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read xVertex data in a loop" );
[ # # ][ # # ]
[ # # ][ # # ]
1105 : :
1106 : : // Increment the index for next subrange
1107 : 0 : indexInArray += ( endh - starth + 1 );
1108 : : }
1109 : :
1110 : : #ifdef MOAB_HAVE_PNETCDF
1111 : : // Wait outside the loop
1112 : : success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
1113 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
1114 : : #endif
1115 : :
1116 : : // Read y coordinates for local vertices
1117 [ # # ]: 0 : double* yptr = arrays[1];
1118 : : int yVertexVarId;
1119 [ # # ]: 0 : success = NCFUNC( inq_varid )( _fileId, "yVertex", &yVertexVarId );
1120 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of yVertex" );
[ # # ][ # # ]
[ # # ][ # # ]
1121 : : #ifdef MOAB_HAVE_PNETCDF
1122 : : idxReq = 0;
1123 : : #endif
1124 : 0 : indexInArray = 0;
1125 [ # # ][ # # ]: 0 : for( Range::pair_iterator pair_iter = localGidVerts.pair_begin(); pair_iter != localGidVerts.pair_end();
[ # # ][ # # ]
[ # # ]
1126 : : ++pair_iter )
1127 : : {
1128 [ # # ]: 0 : EntityHandle starth = pair_iter->first;
1129 [ # # ]: 0 : EntityHandle endh = pair_iter->second;
1130 : 0 : NCDF_SIZE read_start = ( NCDF_SIZE )( starth - 1 );
1131 : 0 : NCDF_SIZE read_count = ( NCDF_SIZE )( endh - starth + 1 );
1132 : :
1133 : : // Do a partial read in each subrange
1134 : : #ifdef MOAB_HAVE_PNETCDF
1135 : : success = NCFUNCREQG( _vara_double )( _fileId, yVertexVarId, &read_start, &read_count, &( yptr[indexInArray] ),
1136 : : &requests[idxReq++] );
1137 : : #else
1138 [ # # ]: 0 : success = NCFUNCAG( _vara_double )( _fileId, yVertexVarId, &read_start, &read_count, &( yptr[indexInArray] ) );
1139 : : #endif
1140 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read yVertex data in a loop" );
[ # # ][ # # ]
[ # # ][ # # ]
1141 : :
1142 : : // Increment the index for next subrange
1143 : 0 : indexInArray += ( endh - starth + 1 );
1144 : : }
1145 : :
1146 : : #ifdef MOAB_HAVE_PNETCDF
1147 : : // Wait outside the loop
1148 : : success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
1149 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
1150 : : #endif
1151 : :
1152 : : // Read z coordinates for local vertices
1153 [ # # ]: 0 : double* zptr = arrays[2];
1154 : : int zVertexVarId;
1155 [ # # ]: 0 : success = NCFUNC( inq_varid )( _fileId, "zVertex", &zVertexVarId );
1156 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of zVertex" );
[ # # ][ # # ]
[ # # ][ # # ]
1157 : : #ifdef MOAB_HAVE_PNETCDF
1158 : : idxReq = 0;
1159 : : #endif
1160 : 0 : indexInArray = 0;
1161 [ # # ][ # # ]: 0 : for( Range::pair_iterator pair_iter = localGidVerts.pair_begin(); pair_iter != localGidVerts.pair_end();
[ # # ][ # # ]
[ # # ]
1162 : : ++pair_iter )
1163 : : {
1164 [ # # ]: 0 : EntityHandle starth = pair_iter->first;
1165 [ # # ]: 0 : EntityHandle endh = pair_iter->second;
1166 : 0 : NCDF_SIZE read_start = ( NCDF_SIZE )( starth - 1 );
1167 : 0 : NCDF_SIZE read_count = ( NCDF_SIZE )( endh - starth + 1 );
1168 : :
1169 : : // Do a partial read in each subrange
1170 : : #ifdef MOAB_HAVE_PNETCDF
1171 : : success = NCFUNCREQG( _vara_double )( _fileId, zVertexVarId, &read_start, &read_count, &( zptr[indexInArray] ),
1172 : : &requests[idxReq++] );
1173 : : #else
1174 [ # # ]: 0 : success = NCFUNCAG( _vara_double )( _fileId, zVertexVarId, &read_start, &read_count, &( zptr[indexInArray] ) );
1175 : : #endif
1176 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read zVertex data in a loop" );
[ # # ][ # # ]
[ # # ][ # # ]
1177 : :
1178 : : // Increment the index for next subrange
1179 : 0 : indexInArray += ( endh - starth + 1 );
1180 : : }
1181 : :
1182 : : #ifdef MOAB_HAVE_PNETCDF
1183 : : // Wait outside the loop
1184 : : success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
1185 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
1186 : : #endif
1187 : :
1188 : 0 : return MB_SUCCESS;
1189 : : }
1190 : :
1191 : 0 : ErrorCode NCHelperMPAS::create_local_edges( EntityHandle start_vertex,
1192 : : const std::vector< int >& num_edges_on_local_cells )
1193 : : {
1194 : 0 : Interface*& mbImpl = _readNC->mbImpl;
1195 : 0 : Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
1196 : 0 : DebugOutput& dbgOut = _readNC->dbgOut;
1197 : :
1198 : : // Read edges on each local cell, to get localGidEdges
1199 : : int edgesOnCellVarId;
1200 [ # # ]: 0 : int success = NCFUNC( inq_varid )( _fileId, "edgesOnCell", &edgesOnCellVarId );
1201 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of edgesOnCell" );
[ # # ][ # # ]
[ # # ][ # # ]
1202 : :
1203 [ # # ]: 0 : std::vector< int > edges_on_local_cells( nLocalCells * maxEdgesPerCell );
1204 [ # # ]: 0 : dbgOut.tprintf( 1, " edges_on_local_cells.size() = %d\n", (int)edges_on_local_cells.size() );
1205 : :
1206 : : #ifdef MOAB_HAVE_PNETCDF
1207 : : size_t nb_reads = localGidCells.psize();
1208 : : std::vector< int > requests( nb_reads );
1209 : : std::vector< int > statuss( nb_reads );
1210 : : size_t idxReq = 0;
1211 : : #endif
1212 : 0 : size_t indexInArray = 0;
1213 [ # # ][ # # ]: 0 : for( Range::pair_iterator pair_iter = localGidCells.pair_begin(); pair_iter != localGidCells.pair_end();
[ # # ][ # # ]
[ # # ]
1214 : : ++pair_iter )
1215 : : {
1216 [ # # ]: 0 : EntityHandle starth = pair_iter->first;
1217 [ # # ]: 0 : EntityHandle endh = pair_iter->second;
1218 : 0 : NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 };
1219 : 0 : NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ),
1220 : 0 : static_cast< NCDF_SIZE >( maxEdgesPerCell ) };
1221 : :
1222 : : // Do a partial read in each subrange
1223 : : #ifdef MOAB_HAVE_PNETCDF
1224 : : success = NCFUNCREQG( _vara_int )( _fileId, edgesOnCellVarId, read_starts, read_counts,
1225 : : &( edges_on_local_cells[indexInArray] ), &requests[idxReq++] );
1226 : : #else
1227 : : success = NCFUNCAG( _vara_int )( _fileId, edgesOnCellVarId, read_starts, read_counts,
1228 [ # # ][ # # ]: 0 : &( edges_on_local_cells[indexInArray] ) );
1229 : : #endif
1230 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read edgesOnCell data in a loop" );
[ # # ][ # # ]
[ # # ][ # # ]
1231 : :
1232 : : // Increment the index for next subrange
1233 : 0 : indexInArray += ( endh - starth + 1 ) * maxEdgesPerCell;
1234 : : }
1235 : :
1236 : : #ifdef MOAB_HAVE_PNETCDF
1237 : : // Wait outside the loop
1238 : : success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
1239 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
1240 : : #endif
1241 : :
1242 : : // Correct local cell edges array in the same way as local cell vertices array, replace the
1243 : : // padded edges with the last edges in the corresponding cells
1244 [ # # ]: 0 : for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ )
1245 : : {
1246 [ # # ]: 0 : int num_edges = num_edges_on_local_cells[local_cell_idx];
1247 : 0 : int idx_in_local_edge_arr = local_cell_idx * maxEdgesPerCell;
1248 [ # # ]: 0 : int last_edge_idx = edges_on_local_cells[idx_in_local_edge_arr + num_edges - 1];
1249 [ # # ]: 0 : for( int i = num_edges; i < maxEdgesPerCell; i++ )
1250 [ # # ]: 0 : edges_on_local_cells[idx_in_local_edge_arr + i] = last_edge_idx;
1251 : : }
1252 : :
1253 : : // Collect local edges
1254 [ # # ]: 0 : std::sort( edges_on_local_cells.begin(), edges_on_local_cells.end() );
1255 [ # # ][ # # ]: 0 : std::copy( edges_on_local_cells.rbegin(), edges_on_local_cells.rend(), range_inserter( localGidEdges ) );
1256 [ # # ]: 0 : nLocalEdges = localGidEdges.size();
1257 : :
1258 [ # # ][ # # ]: 0 : dbgOut.tprintf( 1, " localGidEdges.psize() = %d\n", (int)localGidEdges.psize() );
1259 [ # # ][ # # ]: 0 : dbgOut.tprintf( 1, " localGidEdges.size() = %d\n", (int)localGidEdges.size() );
1260 : :
1261 : : // Create local edges
1262 : : EntityHandle start_edge;
1263 : 0 : EntityHandle* conn_arr_edges = NULL;
1264 : : ErrorCode rval =
1265 : : _readNC->readMeshIface->get_element_connect( nLocalEdges, 2, MBEDGE, 0, start_edge, conn_arr_edges,
1266 : : // Might have to create gather mesh later
1267 [ # # ][ # # ]: 0 : ( createGatherSet ? nLocalEdges + nEdges : nLocalEdges ) );MB_CHK_SET_ERR( rval, "Failed to create local edges" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1268 : :
1269 : : // Add local edges to current file set
1270 [ # # ]: 0 : Range local_edges_range( start_edge, start_edge + nLocalEdges - 1 );
1271 [ # # ][ # # ]: 0 : rval = _readNC->mbImpl->add_entities( _fileSet, local_edges_range );MB_CHK_SET_ERR( rval, "Failed to add local edges to current file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1272 : :
1273 : : // Get ptr to GID memory for edges
1274 : 0 : int count = 0;
1275 : 0 : void* data = NULL;
1276 [ # # ][ # # ]: 0 : rval = mbImpl->tag_iterate( mGlobalIdTag, local_edges_range.begin(), local_edges_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate global id tag on local edges" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1277 [ # # ]: 0 : assert( count == nLocalEdges );
1278 : 0 : int* gid_data = (int*)data;
1279 [ # # ][ # # ]: 0 : std::copy( localGidEdges.begin(), localGidEdges.end(), gid_data );
[ # # ]
1280 : :
1281 : : int verticesOnEdgeVarId;
1282 : :
1283 : : // Read vertices on each local edge, to get edge connectivity
1284 [ # # ]: 0 : success = NCFUNC( inq_varid )( _fileId, "verticesOnEdge", &verticesOnEdgeVarId );
1285 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of verticesOnEdge" );
[ # # ][ # # ]
[ # # ][ # # ]
1286 : : // Utilize the memory storage pointed by conn_arr_edges
1287 : 0 : int* vertices_on_local_edges = (int*)conn_arr_edges;
1288 : : #ifdef MOAB_HAVE_PNETCDF
1289 : : nb_reads = localGidEdges.psize();
1290 : : requests.resize( nb_reads );
1291 : : statuss.resize( nb_reads );
1292 : : idxReq = 0;
1293 : : #endif
1294 : 0 : indexInArray = 0;
1295 [ # # ][ # # ]: 0 : for( Range::pair_iterator pair_iter = localGidEdges.pair_begin(); pair_iter != localGidEdges.pair_end();
[ # # ][ # # ]
[ # # ]
1296 : : ++pair_iter )
1297 : : {
1298 [ # # ]: 0 : EntityHandle starth = pair_iter->first;
1299 [ # # ]: 0 : EntityHandle endh = pair_iter->second;
1300 : 0 : NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 };
1301 : 0 : NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ), 2 };
1302 : :
1303 : : // Do a partial read in each subrange
1304 : : #ifdef MOAB_HAVE_PNETCDF
1305 : : success = NCFUNCREQG( _vara_int )( _fileId, verticesOnEdgeVarId, read_starts, read_counts,
1306 : : &( vertices_on_local_edges[indexInArray] ), &requests[idxReq++] );
1307 : : #else
1308 : : success = NCFUNCAG( _vara_int )( _fileId, verticesOnEdgeVarId, read_starts, read_counts,
1309 [ # # ]: 0 : &( vertices_on_local_edges[indexInArray] ) );
1310 : : #endif
1311 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnEdge data in a loop" );
[ # # ][ # # ]
[ # # ][ # # ]
1312 : :
1313 : : // Increment the index for next subrange
1314 : 0 : indexInArray += ( endh - starth + 1 ) * 2;
1315 : : }
1316 : :
1317 : : #ifdef MOAB_HAVE_PNETCDF
1318 : : // Wait outside the loop
1319 : : success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
1320 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
1321 : : #endif
1322 : :
1323 : : // Populate connectivity data for local edges
1324 : : // Convert in-place from int (stored in the first half) to EntityHandle
1325 : : // Reading backward is the trick
1326 [ # # ]: 0 : for( int edge_vert = nLocalEdges * 2 - 1; edge_vert >= 0; edge_vert-- )
1327 : : {
1328 : 0 : int global_vert_idx = vertices_on_local_edges[edge_vert]; // Global vertex index, 1 based
1329 [ # # ]: 0 : int local_vert_idx = localGidVerts.index( global_vert_idx ); // Local vertex index, 0 based
1330 [ # # ]: 0 : assert( local_vert_idx != -1 );
1331 : 0 : conn_arr_edges[edge_vert] = start_vertex + local_vert_idx;
1332 : : }
1333 : :
1334 : 0 : return MB_SUCCESS;
1335 : : }
1336 : :
1337 : 0 : ErrorCode NCHelperMPAS::create_local_cells( const std::vector< int >& vertices_on_local_cells,
1338 : : const std::vector< int >& num_edges_on_local_cells,
1339 : : EntityHandle start_vertex, Range& faces )
1340 : : {
1341 : 0 : Interface*& mbImpl = _readNC->mbImpl;
1342 : 0 : Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
1343 : :
1344 : : // Divide local cells into groups based on the number of edges
1345 [ # # ][ # # ]: 0 : Range local_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
[ # # ]
1346 : : // Insert larger values before smaller ones to increase efficiency
1347 [ # # ]: 0 : for( int i = nLocalCells - 1; i >= 0; i-- )
1348 : : {
1349 [ # # ]: 0 : int num_edges = num_edges_on_local_cells[i];
1350 [ # # ][ # # ]: 0 : local_cells_with_n_edges[num_edges].insert( localGidCells[i] ); // Global cell index
1351 : : }
1352 : :
1353 [ # # ]: 0 : std::vector< int > num_edges_on_cell_groups;
1354 [ # # ]: 0 : for( int i = 3; i <= maxEdgesPerCell; i++ )
1355 : : {
1356 [ # # ][ # # ]: 0 : if( local_cells_with_n_edges[i].size() > 0 ) num_edges_on_cell_groups.push_back( i );
[ # # ]
1357 : : }
1358 : 0 : numCellGroups = num_edges_on_cell_groups.size();
1359 : :
1360 : : EntityHandle* conn_arr_local_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
1361 [ # # ]: 0 : for( int i = 0; i < numCellGroups; i++ )
1362 : : {
1363 [ # # ]: 0 : int num_edges_per_cell = num_edges_on_cell_groups[i];
1364 [ # # ]: 0 : int num_group_cells = (int)local_cells_with_n_edges[num_edges_per_cell].size();
1365 : :
1366 : : // Create local cells for each non-empty cell group
1367 : : EntityHandle start_element;
1368 : : ErrorCode rval = _readNC->readMeshIface->get_element_connect(
1369 : : num_group_cells, num_edges_per_cell, MBPOLYGON, 0, start_element,
1370 [ # # ][ # # ]: 0 : conn_arr_local_cells_with_n_edges[num_edges_per_cell], num_group_cells );MB_CHK_SET_ERR( rval, "Failed to create local cells" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1371 [ # # ]: 0 : faces.insert( start_element, start_element + num_group_cells - 1 );
1372 : :
1373 : : // Add local cells to current file set
1374 [ # # ]: 0 : Range local_cells_range( start_element, start_element + num_group_cells - 1 );
1375 [ # # ][ # # ]: 0 : rval = _readNC->mbImpl->add_entities( _fileSet, local_cells_range );MB_CHK_SET_ERR( rval, "Failed to add local cells to current file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1376 : :
1377 : : // Get ptr to gid memory for local cells
1378 : 0 : int count = 0;
1379 : 0 : void* data = NULL;
1380 [ # # ][ # # ]: 0 : 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" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1381 [ # # ]: 0 : assert( count == num_group_cells );
1382 : 0 : int* gid_data = (int*)data;
1383 : : std::copy( local_cells_with_n_edges[num_edges_per_cell].begin(),
1384 [ # # ][ # # ]: 0 : local_cells_with_n_edges[num_edges_per_cell].end(), gid_data );
[ # # ]
1385 : :
1386 : : // Set connectivity array with proper local vertices handles
1387 [ # # ][ # # ]: 0 : for( int j = 0; j < num_group_cells; j++ )
1388 : : {
1389 : : EntityHandle global_cell_idx =
1390 [ # # ]: 0 : local_cells_with_n_edges[num_edges_per_cell][j]; // Global cell index, 1 based
1391 [ # # ]: 0 : int local_cell_idx = localGidCells.index( global_cell_idx ); // Local cell index, 0 based
1392 [ # # ]: 0 : assert( local_cell_idx != -1 );
1393 : :
1394 [ # # ]: 0 : if( numCellGroups > 1 )
1395 : : {
1396 : : // Populate cellHandleToGlobalID map to read cell variables
1397 [ # # ]: 0 : cellHandleToGlobalID[start_element + j] = global_cell_idx;
1398 : : }
1399 : :
1400 [ # # ]: 0 : for( int k = 0; k < num_edges_per_cell; k++ )
1401 : : {
1402 : : EntityHandle global_vert_idx =
1403 [ # # ]: 0 : vertices_on_local_cells[local_cell_idx * maxEdgesPerCell + k]; // Global vertex index, 1 based
1404 [ # # ]: 0 : int local_vert_idx = localGidVerts.index( global_vert_idx ); // Local vertex index, 0 based
1405 [ # # ]: 0 : assert( local_vert_idx != -1 );
1406 : 0 : conn_arr_local_cells_with_n_edges[num_edges_per_cell][j * num_edges_per_cell + k] =
1407 : 0 : start_vertex + local_vert_idx;
1408 : : }
1409 : : }
1410 : 0 : }
1411 : :
1412 [ # # ]: 0 : return MB_SUCCESS;
[ # # # # ]
1413 : : }
1414 : :
1415 : 0 : ErrorCode NCHelperMPAS::create_padded_local_cells( const std::vector< int >& vertices_on_local_cells,
1416 : : EntityHandle start_vertex, Range& faces )
1417 : : {
1418 : 0 : Interface*& mbImpl = _readNC->mbImpl;
1419 : 0 : Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
1420 : :
1421 : : // Only one group of cells (each cell is represented by a polygon with maxEdgesPerCell edges)
1422 : 0 : numCellGroups = 1;
1423 : :
1424 : : // Create cells for this cell group
1425 : : EntityHandle start_element;
1426 : 0 : EntityHandle* conn_arr_local_cells = NULL;
1427 : : ErrorCode rval =
1428 : : _readNC->readMeshIface->get_element_connect( nLocalCells, maxEdgesPerCell, MBPOLYGON, 0, start_element,
1429 : : conn_arr_local_cells,
1430 : : // Might have to create gather mesh later
1431 [ # # ][ # # ]: 0 : ( createGatherSet ? nLocalCells + nCells : nLocalCells ) );MB_CHK_SET_ERR( rval, "Failed to create local cells" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1432 [ # # ]: 0 : faces.insert( start_element, start_element + nLocalCells - 1 );
1433 : :
1434 : : // Add local cells to current file set
1435 [ # # ]: 0 : Range local_cells_range( start_element, start_element + nLocalCells - 1 );
1436 [ # # ][ # # ]: 0 : rval = _readNC->mbImpl->add_entities( _fileSet, local_cells_range );MB_CHK_SET_ERR( rval, "Failed to add local cells to current file set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1437 : :
1438 : : // Get ptr to GID memory for local cells
1439 : 0 : int count = 0;
1440 : 0 : void* data = NULL;
1441 [ # # ][ # # ]: 0 : 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" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1442 [ # # ]: 0 : assert( count == nLocalCells );
1443 : 0 : int* gid_data = (int*)data;
1444 [ # # ][ # # ]: 0 : std::copy( localGidCells.begin(), localGidCells.end(), gid_data );
[ # # ]
1445 : :
1446 : : // Set connectivity array with proper local vertices handles
1447 : : // vertices_on_local_cells array was already corrected to have the last vertices padded
1448 : : // no need for extra checks considering
1449 [ # # ]: 0 : for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ )
1450 : : {
1451 [ # # ]: 0 : for( int i = 0; i < maxEdgesPerCell; i++ )
1452 : : {
1453 : : EntityHandle global_vert_idx =
1454 [ # # ]: 0 : vertices_on_local_cells[local_cell_idx * maxEdgesPerCell + i]; // Global vertex index, 1 based
1455 [ # # ]: 0 : int local_vert_idx = localGidVerts.index( global_vert_idx ); // Local vertex index, 0 based
1456 [ # # ]: 0 : assert( local_vert_idx != -1 );
1457 : 0 : conn_arr_local_cells[local_cell_idx * maxEdgesPerCell + i] = start_vertex + local_vert_idx;
1458 : : }
1459 : : }
1460 : :
1461 : 0 : return MB_SUCCESS;
1462 : : }
1463 : :
1464 : 0 : ErrorCode NCHelperMPAS::create_gather_set_vertices( EntityHandle gather_set, EntityHandle& gather_set_start_vertex )
1465 : : {
1466 : 0 : Interface*& mbImpl = _readNC->mbImpl;
1467 : 0 : Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
1468 : 0 : const Tag*& mpFileIdTag = _readNC->mpFileIdTag;
1469 : :
1470 : : // Create gather set vertices
1471 [ # # ]: 0 : std::vector< double* > arrays;
1472 : : // Don't need to specify allocation number here, because we know enough vertices were created
1473 : : // before
1474 [ # # ][ # # ]: 0 : ErrorCode rval = _readNC->readMeshIface->get_node_coords( 3, nVertices, 0, gather_set_start_vertex, arrays );MB_CHK_SET_ERR( rval, "Failed to create gather set vertices" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1475 : :
1476 : : // Add vertices to the gather set
1477 [ # # ]: 0 : Range gather_set_verts_range( gather_set_start_vertex, gather_set_start_vertex + nVertices - 1 );
1478 [ # # ][ # # ]: 0 : rval = mbImpl->add_entities( gather_set, gather_set_verts_range );MB_CHK_SET_ERR( rval, "Failed to add vertices to the gather set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1479 : :
1480 : : // Read x coordinates for gather set vertices
1481 [ # # ]: 0 : double* xptr = arrays[0];
1482 : : int xVertexVarId;
1483 [ # # ]: 0 : int success = NCFUNC( inq_varid )( _fileId, "xVertex", &xVertexVarId );
1484 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of xVertex" );
[ # # ][ # # ]
[ # # ][ # # ]
1485 : 0 : NCDF_SIZE read_start = 0;
1486 : 0 : NCDF_SIZE read_count = static_cast< NCDF_SIZE >( nVertices );
1487 : : #ifdef MOAB_HAVE_PNETCDF
1488 : : // Enter independent I/O mode, since this read is only for the gather processor
1489 : : success = NCFUNC( begin_indep_data )( _fileId );
1490 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1491 : : success = NCFUNCG( _vara_double )( _fileId, xVertexVarId, &read_start, &read_count, xptr );
1492 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read xVertex data" );
1493 : : success = NCFUNC( end_indep_data )( _fileId );
1494 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1495 : : #else
1496 [ # # ]: 0 : success = NCFUNCG( _vara_double )( _fileId, xVertexVarId, &read_start, &read_count, xptr );
1497 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read xVertex data" );
[ # # ][ # # ]
[ # # ][ # # ]
1498 : : #endif
1499 : :
1500 : : // Read y coordinates for gather set vertices
1501 [ # # ]: 0 : double* yptr = arrays[1];
1502 : : int yVertexVarId;
1503 [ # # ]: 0 : success = NCFUNC( inq_varid )( _fileId, "yVertex", &yVertexVarId );
1504 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of yVertex" );
[ # # ][ # # ]
[ # # ][ # # ]
1505 : : #ifdef MOAB_HAVE_PNETCDF
1506 : : // Enter independent I/O mode, since this read is only for the gather processor
1507 : : success = NCFUNC( begin_indep_data )( _fileId );
1508 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1509 : : success = NCFUNCG( _vara_double )( _fileId, yVertexVarId, &read_start, &read_count, yptr );
1510 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read yVertex data" );
1511 : : success = NCFUNC( end_indep_data )( _fileId );
1512 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1513 : : #else
1514 [ # # ]: 0 : success = NCFUNCG( _vara_double )( _fileId, yVertexVarId, &read_start, &read_count, yptr );
1515 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read yVertex data" );
[ # # ][ # # ]
[ # # ][ # # ]
1516 : : #endif
1517 : :
1518 : : // Read z coordinates for gather set vertices
1519 [ # # ]: 0 : double* zptr = arrays[2];
1520 : : int zVertexVarId;
1521 [ # # ]: 0 : success = NCFUNC( inq_varid )( _fileId, "zVertex", &zVertexVarId );
1522 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of zVertex" );
[ # # ][ # # ]
[ # # ][ # # ]
1523 : : #ifdef MOAB_HAVE_PNETCDF
1524 : : // Enter independent I/O mode, since this read is only for the gather processor
1525 : : success = NCFUNC( begin_indep_data )( _fileId );
1526 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1527 : : success = NCFUNCG( _vara_double )( _fileId, zVertexVarId, &read_start, &read_count, zptr );
1528 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read zVertex data" );
1529 : : success = NCFUNC( end_indep_data )( _fileId );
1530 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1531 : : #else
1532 [ # # ]: 0 : success = NCFUNCG( _vara_double )( _fileId, zVertexVarId, &read_start, &read_count, zptr );
1533 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read zVertex data" );
[ # # ][ # # ]
[ # # ][ # # ]
1534 : : #endif
1535 : :
1536 : : // Get ptr to GID memory for gather set vertices
1537 : 0 : int count = 0;
1538 : 0 : void* data = NULL;
1539 : : rval =
1540 [ # # ][ # # ]: 0 : mbImpl->tag_iterate( mGlobalIdTag, gather_set_verts_range.begin(), gather_set_verts_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate global id tag on gather set vertices" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1541 [ # # ]: 0 : assert( count == nVertices );
1542 : 0 : int* gid_data = (int*)data;
1543 [ # # ]: 0 : for( int j = 1; j <= nVertices; j++ )
1544 : 0 : gid_data[j - 1] = j;
1545 : :
1546 : : // Set the file id tag too, it should be bigger something not interfering with global id
1547 [ # # ]: 0 : if( mpFileIdTag )
1548 : : {
1549 : : rval = mbImpl->tag_iterate( *mpFileIdTag, gather_set_verts_range.begin(), gather_set_verts_range.end(), count,
1550 [ # # ][ # # ]: 0 : data );MB_CHK_SET_ERR( rval, "Failed to iterate file id tag on gather set vertices" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1551 [ # # ]: 0 : assert( count == nVertices );
1552 : 0 : int bytes_per_tag = 4;
1553 [ # # ][ # # ]: 0 : rval = mbImpl->tag_get_bytes( *mpFileIdTag, bytes_per_tag );MB_CHK_SET_ERR( rval, "Can't get number of bytes for file id tag" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1554 [ # # ]: 0 : if( 4 == bytes_per_tag )
1555 : : {
1556 : 0 : gid_data = (int*)data;
1557 [ # # ]: 0 : for( int j = 1; j <= nVertices; j++ )
1558 : 0 : gid_data[j - 1] = nVertices + j; // Bigger than global id tag
1559 : : }
1560 [ # # ]: 0 : else if( 8 == bytes_per_tag )
1561 : : { // Should be a handle tag on 64 bit machine?
1562 : 0 : long* handle_tag_data = (long*)data;
1563 [ # # ]: 0 : for( int j = 1; j <= nVertices; j++ )
1564 : 0 : handle_tag_data[j - 1] = nVertices + j; // Bigger than global id tag
1565 : : }
1566 : : }
1567 : :
1568 : 0 : return MB_SUCCESS;
1569 : : }
1570 : :
1571 : 0 : ErrorCode NCHelperMPAS::create_gather_set_edges( EntityHandle gather_set, EntityHandle gather_set_start_vertex )
1572 : : {
1573 : 0 : Interface*& mbImpl = _readNC->mbImpl;
1574 : :
1575 : : // Create gather set edges
1576 : : EntityHandle start_edge;
1577 : 0 : EntityHandle* conn_arr_gather_set_edges = NULL;
1578 : : // Don't need to specify allocation number here, because we know enough edges were created
1579 : : // before
1580 : : ErrorCode rval =
1581 [ # # ][ # # ]: 0 : _readNC->readMeshIface->get_element_connect( nEdges, 2, MBEDGE, 0, start_edge, conn_arr_gather_set_edges );MB_CHK_SET_ERR( rval, "Failed to create gather set edges" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1582 : :
1583 : : // Add edges to the gather set
1584 [ # # ]: 0 : Range gather_set_edges_range( start_edge, start_edge + nEdges - 1 );
1585 [ # # ][ # # ]: 0 : rval = mbImpl->add_entities( gather_set, gather_set_edges_range );MB_CHK_SET_ERR( rval, "Failed to add edges to the gather set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1586 : :
1587 : : // Read vertices on each edge
1588 : : int verticesOnEdgeVarId;
1589 [ # # ]: 0 : int success = NCFUNC( inq_varid )( _fileId, "verticesOnEdge", &verticesOnEdgeVarId );
1590 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of verticesOnEdge" );
[ # # ][ # # ]
[ # # ][ # # ]
1591 : : // Utilize the memory storage pointed by conn_arr_gather_set_edges
1592 : 0 : int* vertices_on_gather_set_edges = (int*)conn_arr_gather_set_edges;
1593 : 0 : NCDF_SIZE read_starts[2] = { 0, 0 };
1594 : 0 : NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( nEdges ), 2 };
1595 : : #ifdef MOAB_HAVE_PNETCDF
1596 : : // Enter independent I/O mode, since this read is only for the gather processor
1597 : : success = NCFUNC( begin_indep_data )( _fileId );
1598 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1599 : : success =
1600 : : NCFUNCG( _vara_int )( _fileId, verticesOnEdgeVarId, read_starts, read_counts, vertices_on_gather_set_edges );
1601 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnEdge data" );
1602 : : success = NCFUNC( end_indep_data )( _fileId );
1603 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1604 : : #else
1605 : : success =
1606 [ # # ]: 0 : NCFUNCG( _vara_int )( _fileId, verticesOnEdgeVarId, read_starts, read_counts, vertices_on_gather_set_edges );
1607 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnEdge data" );
[ # # ][ # # ]
[ # # ][ # # ]
1608 : : #endif
1609 : :
1610 : : // Populate connectivity data for gather set edges
1611 : : // Convert in-place from int (stored in the first half) to EntityHandle
1612 : : // Reading backward is the trick
1613 [ # # ]: 0 : for( int edge_vert = nEdges * 2 - 1; edge_vert >= 0; edge_vert-- )
1614 : : {
1615 : 0 : int gather_set_vert_idx = vertices_on_gather_set_edges[edge_vert]; // Global vertex index, 1 based
1616 : 0 : gather_set_vert_idx--; // 1 based -> 0 based
1617 : : // Connectivity array is shifted by where the gather set vertices start
1618 : 0 : conn_arr_gather_set_edges[edge_vert] = gather_set_start_vertex + gather_set_vert_idx;
1619 : : }
1620 : :
1621 : 0 : return MB_SUCCESS;
1622 : : }
1623 : :
1624 : 0 : ErrorCode NCHelperMPAS::create_gather_set_cells( EntityHandle gather_set, EntityHandle gather_set_start_vertex )
1625 : : {
1626 : 0 : Interface*& mbImpl = _readNC->mbImpl;
1627 : :
1628 : : // Read number of edges on each gather set cell
1629 : : int nEdgesOnCellVarId;
1630 [ # # ]: 0 : int success = NCFUNC( inq_varid )( _fileId, "nEdgesOnCell", &nEdgesOnCellVarId );
1631 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of nEdgesOnCell" );
[ # # ][ # # ]
[ # # ][ # # ]
1632 [ # # ]: 0 : std::vector< int > num_edges_on_gather_set_cells( nCells );
1633 : 0 : NCDF_SIZE read_start = 0;
1634 : 0 : NCDF_SIZE read_count = static_cast< NCDF_SIZE >( nCells );
1635 : : #ifdef MOAB_HAVE_PNETCDF
1636 : : // Enter independent I/O mode, since this read is only for the gather processor
1637 : : success = NCFUNC( begin_indep_data )( _fileId );
1638 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1639 : : success =
1640 : : NCFUNCG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count, &num_edges_on_gather_set_cells[0] );
1641 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nEdgesOnCell data" );
1642 : : success = NCFUNC( end_indep_data )( _fileId );
1643 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1644 : : #else
1645 : : success =
1646 [ # # ][ # # ]: 0 : NCFUNCG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count, &num_edges_on_gather_set_cells[0] );
1647 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nEdgesOnCell data" );
[ # # ][ # # ]
[ # # ][ # # ]
1648 : : #endif
1649 : :
1650 : : // Read vertices on each gather set cell (connectivity)
1651 : : int verticesOnCellVarId;
1652 [ # # ]: 0 : success = NCFUNC( inq_varid )( _fileId, "verticesOnCell", &verticesOnCellVarId );
1653 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of verticesOnCell" );
[ # # ][ # # ]
[ # # ][ # # ]
1654 [ # # ]: 0 : std::vector< int > vertices_on_gather_set_cells( nCells * maxEdgesPerCell );
1655 : 0 : NCDF_SIZE read_starts[2] = { 0, 0 };
1656 : 0 : NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( nCells ), static_cast< NCDF_SIZE >( maxEdgesPerCell ) };
1657 : : #ifdef MOAB_HAVE_PNETCDF
1658 : : // Enter independent I/O mode, since this read is only for the gather processor
1659 : : success = NCFUNC( begin_indep_data )( _fileId );
1660 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1661 : : success = NCFUNCG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
1662 : : &vertices_on_gather_set_cells[0] );
1663 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnCell data" );
1664 : : success = NCFUNC( end_indep_data )( _fileId );
1665 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1666 : : #else
1667 : : success = NCFUNCG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
1668 [ # # ][ # # ]: 0 : &vertices_on_gather_set_cells[0] );
1669 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnCell data" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1670 : : #endif
1671 : :
1672 : : // Divide gather set cells into groups based on the number of edges
1673 [ # # ][ # # ]: 0 : Range gather_set_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
[ # # ]
[ # # # # ]
1674 : : // Insert larger values before smaller values to increase efficiency
1675 [ # # ]: 0 : for( int i = nCells - 1; i >= 0; i-- )
1676 : : {
1677 [ # # ]: 0 : int num_edges = num_edges_on_gather_set_cells[i];
1678 [ # # ]: 0 : gather_set_cells_with_n_edges[num_edges].insert( i + 1 ); // 0 based -> 1 based
1679 : : }
1680 : :
1681 : : // Create gather set cells
1682 : : EntityHandle* conn_arr_gather_set_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
1683 [ # # ]: 0 : for( int num_edges_per_cell = 3; num_edges_per_cell <= maxEdgesPerCell; num_edges_per_cell++ )
1684 : : {
1685 [ # # ]: 0 : int num_group_cells = gather_set_cells_with_n_edges[num_edges_per_cell].size();
1686 [ # # ]: 0 : if( num_group_cells > 0 )
1687 : : {
1688 : : EntityHandle start_element;
1689 : : ErrorCode rval = _readNC->readMeshIface->get_element_connect(
1690 : : num_group_cells, num_edges_per_cell, MBPOLYGON, 0, start_element,
1691 [ # # ][ # # ]: 0 : conn_arr_gather_set_cells_with_n_edges[num_edges_per_cell], num_group_cells );MB_CHK_SET_ERR( rval, "Failed to create gather set cells" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1692 : :
1693 : : // Add cells to the gather set
1694 [ # # ]: 0 : Range gather_set_cells_range( start_element, start_element + num_group_cells - 1 );
1695 [ # # ][ # # ]: 0 : rval = mbImpl->add_entities( gather_set, gather_set_cells_range );MB_CHK_SET_ERR( rval, "Failed to add cells to the gather set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1696 : :
1697 [ # # ][ # # ]: 0 : for( int j = 0; j < num_group_cells; j++ )
1698 : : {
1699 : : int gather_set_cell_idx =
1700 [ # # ]: 0 : gather_set_cells_with_n_edges[num_edges_per_cell][j]; // Global cell index, 1 based
1701 : 0 : gather_set_cell_idx--; // 1 based -> 0 based
1702 : :
1703 [ # # ]: 0 : for( int k = 0; k < num_edges_per_cell; k++ )
1704 : : {
1705 : : EntityHandle gather_set_vert_idx =
1706 : 0 : vertices_on_gather_set_cells[gather_set_cell_idx * maxEdgesPerCell +
1707 [ # # ]: 0 : k]; // Global vertex index, 1 based
1708 : 0 : gather_set_vert_idx--; // 1 based -> 0 based
1709 : :
1710 : : // Connectivity array is shifted by where the gather set vertices start
1711 : 0 : conn_arr_gather_set_cells_with_n_edges[num_edges_per_cell][j * num_edges_per_cell + k] =
1712 : 0 : gather_set_start_vertex + gather_set_vert_idx;
1713 : : }
1714 : 0 : }
1715 : : }
1716 : : }
1717 : :
1718 : 0 : return MB_SUCCESS;
1719 : : }
1720 : :
1721 : 0 : ErrorCode NCHelperMPAS::create_padded_gather_set_cells( EntityHandle gather_set, EntityHandle gather_set_start_vertex )
1722 : : {
1723 : 0 : Interface*& mbImpl = _readNC->mbImpl;
1724 : :
1725 : : // Read number of edges on each gather set cell
1726 : : int nEdgesOnCellVarId;
1727 [ # # ]: 0 : int success = NCFUNC( inq_varid )( _fileId, "nEdgesOnCell", &nEdgesOnCellVarId );
1728 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of nEdgesOnCell" );
[ # # ][ # # ]
[ # # ][ # # ]
1729 [ # # ]: 0 : std::vector< int > num_edges_on_gather_set_cells( nCells );
1730 : 0 : NCDF_SIZE read_start = 0;
1731 : 0 : NCDF_SIZE read_count = static_cast< NCDF_SIZE >( nCells );
1732 : : #ifdef MOAB_HAVE_PNETCDF
1733 : : // Enter independent I/O mode, since this read is only for the gather processor
1734 : : success = NCFUNC( begin_indep_data )( _fileId );
1735 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1736 : : success =
1737 : : NCFUNCG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count, &num_edges_on_gather_set_cells[0] );
1738 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nEdgesOnCell data" );
1739 : : success = NCFUNC( end_indep_data )( _fileId );
1740 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1741 : : #else
1742 : : success =
1743 [ # # ][ # # ]: 0 : NCFUNCG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count, &num_edges_on_gather_set_cells[0] );
1744 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nEdgesOnCell data" );
[ # # ][ # # ]
[ # # ][ # # ]
1745 : : #endif
1746 : :
1747 : : // Create gather set cells
1748 : : EntityHandle start_element;
1749 : 0 : EntityHandle* conn_arr_gather_set_cells = NULL;
1750 : : // Don't need to specify allocation number here, because we know enough cells were created
1751 : : // before
1752 : : ErrorCode rval = _readNC->readMeshIface->get_element_connect( nCells, maxEdgesPerCell, MBPOLYGON, 0, start_element,
1753 [ # # ][ # # ]: 0 : conn_arr_gather_set_cells );MB_CHK_SET_ERR( rval, "Failed to create gather set cells" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1754 : :
1755 : : // Add cells to the gather set
1756 [ # # ]: 0 : Range gather_set_cells_range( start_element, start_element + nCells - 1 );
1757 [ # # ][ # # ]: 0 : rval = mbImpl->add_entities( gather_set, gather_set_cells_range );MB_CHK_SET_ERR( rval, "Failed to add cells to the gather set" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1758 : :
1759 : : // Read vertices on each gather set cell (connectivity)
1760 : : int verticesOnCellVarId;
1761 [ # # ]: 0 : success = NCFUNC( inq_varid )( _fileId, "verticesOnCell", &verticesOnCellVarId );
1762 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of verticesOnCell" );
[ # # ][ # # ]
[ # # ][ # # ]
1763 : : // Utilize the memory storage pointed by conn_arr_gather_set_cells
1764 : 0 : int* vertices_on_gather_set_cells = (int*)conn_arr_gather_set_cells;
1765 : 0 : NCDF_SIZE read_starts[2] = { 0, 0 };
1766 : 0 : NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( nCells ), static_cast< NCDF_SIZE >( maxEdgesPerCell ) };
1767 : : #ifdef MOAB_HAVE_PNETCDF
1768 : : // Enter independent I/O mode, since this read is only for the gather processor
1769 : : success = NCFUNC( begin_indep_data )( _fileId );
1770 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1771 : : success =
1772 : : NCFUNCG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts, vertices_on_gather_set_cells );
1773 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnCell data" );
1774 : : success = NCFUNC( end_indep_data )( _fileId );
1775 : : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1776 : : #else
1777 : : success =
1778 [ # # ]: 0 : NCFUNCG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts, vertices_on_gather_set_cells );
1779 [ # # ][ # # ]: 0 : if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnCell data" );
[ # # ][ # # ]
[ # # ][ # # ]
1780 : : #endif
1781 : :
1782 : : // Correct gather set cell vertices array in the same way as local cell vertices array,
1783 : : // replace the padded vertices with the last vertices in the corresponding cells
1784 [ # # ]: 0 : for( int gather_set_cell_idx = 0; gather_set_cell_idx < nCells; gather_set_cell_idx++ )
1785 : : {
1786 [ # # ]: 0 : int num_edges = num_edges_on_gather_set_cells[gather_set_cell_idx];
1787 : 0 : int idx_in_gather_set_vert_arr = gather_set_cell_idx * maxEdgesPerCell;
1788 : 0 : int last_vert_idx = vertices_on_gather_set_cells[idx_in_gather_set_vert_arr + num_edges - 1];
1789 [ # # ]: 0 : for( int i = num_edges; i < maxEdgesPerCell; i++ )
1790 : 0 : vertices_on_gather_set_cells[idx_in_gather_set_vert_arr + i] = last_vert_idx;
1791 : : }
1792 : :
1793 : : // Populate connectivity data for gather set cells
1794 : : // Convert in-place from int (stored in the first half) to EntityHandle
1795 : : // Reading backward is the trick
1796 [ # # ]: 0 : for( int cell_vert = nCells * maxEdgesPerCell - 1; cell_vert >= 0; cell_vert-- )
1797 : : {
1798 : 0 : int gather_set_vert_idx = vertices_on_gather_set_cells[cell_vert]; // Global vertex index, 1 based
1799 : 0 : gather_set_vert_idx--; // 1 based -> 0 based
1800 : : // Connectivity array is shifted by where the gather set vertices start
1801 : 0 : conn_arr_gather_set_cells[cell_vert] = gather_set_start_vertex + gather_set_vert_idx;
1802 : : }
1803 : :
1804 : 0 : return MB_SUCCESS;
1805 : : }
1806 : :
1807 [ + - ][ + - ]: 228 : } // namespace moab
|