25 constexpr
double kPi = 3.14159265358979323846;
33 const double r = std::sqrt( x * x + y * y + z * z );
42 if( lon < 0.0 ) lon += 360.0;
60 "Failed to gather 2-D cells for SCRIP write" );
61 if( allCells.
empty() )
MB_SET_ERR( MB_FAILURE,
"No 2-D cells in file set; cannot write SCRIP grid" );
74 "Failed to filter owned cells for SCRIP write" );
84 int localMaxCorners = 0;
90 if(
MB_SUCCESS == rc && numConn > localMaxCorners ) localMaxCorners = numConn;
96 _writeNC->myPcomm->proc_config().proc_comm() );
104 MB_SET_ERR( MB_FAILURE,
"Mesh contains cells but all reported zero connectivity; cannot write SCRIP" );
123 dbgOut.
tprintf( 1,
" GRID_IMASK tag exists but read failed; writing all-1 mask\n" );
146 if( mGlobalIdTag ) mbImpl->
tag_get_data( mGlobalIdTag, &( *cit ), 1, &gid );
154 double cx = 0.0, cy = 0.0, cz = 0.0;
157 double firstLat = 0.0, firstLon = 0.0;
159 for(
int k = 0; k < numConn; ++k )
161 double vc[3] = { 0.0, 0.0, 0.0 };
166 double vlat = 0.0, vlon = 0.0;
196 MPI_Allreduce( &localN, &
mGlobalCells, 1, MPI_LONG, MPI_SUM,
197 _writeNC->myPcomm->proc_config().proc_comm() );
201 dbgOut.
tprintf( 1,
" SCRIP write: local_cells=%ld global_cells=%ld max_corners=%d hasAreas=%d\n",
mLocalCells,
213 std::vector< std::string >& ,
220 "Failed to define grid_size dimension" );
225 "Failed to define grid_corners dimension" );
229 "Failed to define grid_rank dimension" );
238 "Failed to define grid_dims variable" );
243 "Failed to define grid_center_lat variable" );
247 "Failed to define grid_center_lon variable" );
251 "Failed to define grid_corner_lat variable" );
255 "Failed to define grid_corner_lon variable" );
258 "Failed to define grid_imask variable" );
264 "Failed to define grid_area variable" );
268 const char* deg =
"degrees";
275 const char* rad2 =
"radians^2";
280 const char* title =
"MOAB:NCWriteScrip generated SCRIP grid file";
281 NCFUNC( put_att_text )(
_fileId, NC_GLOBAL,
"title", std::strlen( title ), title );
285 if( endrc )
MB_SET_ERR( MB_FAILURE,
"enddef failed for SCRIP write" );
300 std::vector< int >& )
305 auto sortAndWrite = [&](
const std::vector< int >& allGids,
const std::vector< double >& allCenterLat,
306 const std::vector< double >& allCenterLon,
const std::vector< double >& allCornerLat,
307 const std::vector< double >& allCornerLon,
const std::vector< int >& allImask,
308 const std::vector< double >& allAreas ) ->
ErrorCode {
309 const long N =
static_cast< long >( allGids.size() );
313 std::vector< long > perm( N );
314 for(
long i = 0; i < N; ++i )
316 std::sort( perm.begin(), perm.end(),
317 [&](
long a,
long b ) { return allGids[a] < allGids[b]; } );
319 std::vector< double > sCenterLat( N ), sCenterLon( N ), sCornerLat( N * ncpc ), sCornerLon( N * ncpc );
320 std::vector< int > sImask( N );
321 std::vector< double > sAreas;
322 if( !allAreas.empty() ) sAreas.resize( N );
324 for(
long i = 0; i < N; ++i )
326 const long src = perm[i];
327 sCenterLat[i] = allCenterLat[src];
328 sCenterLon[i] = allCenterLon[src];
329 sImask[i] = allImask[src];
330 if( !sAreas.empty() ) sAreas[i] = allAreas[src];
331 for(
int k = 0; k < ncpc; ++k )
333 sCornerLat[i * ncpc + k] = allCornerLat[src * ncpc + k];
334 sCornerLon[i * ncpc + k] = allCornerLon[src * ncpc + k];
339 int gridDimsValue =
static_cast< int >( N );
340 size_t startD = 0, countD = 1;
342 MB_SET_ERR( MB_FAILURE,
"Failed to write grid_dims" );
344 size_t s1 = 0, c1 =
static_cast< size_t >( N );
346 MB_SET_ERR( MB_FAILURE,
"Failed to write grid_center_lat" );
348 MB_SET_ERR( MB_FAILURE,
"Failed to write grid_center_lon" );
350 MB_SET_ERR( MB_FAILURE,
"Failed to write grid_imask" );
351 if( !sAreas.empty() )
354 MB_SET_ERR( MB_FAILURE,
"Failed to write grid_area" );
357 const size_t s2[2] = { 0, 0 };
358 const size_t c2[2] = {
static_cast< size_t >( N ),
static_cast< size_t >( ncpc ) };
360 MB_SET_ERR( MB_FAILURE,
"Failed to write grid_corner_lat" );
362 MB_SET_ERR( MB_FAILURE,
"Failed to write grid_corner_lon" );
370 MPI_Comm comm =
_writeNC->myPcomm->proc_config().proc_comm();
371 const int rank =
_writeNC->myPcomm->proc_config().proc_rank();
372 const int size =
_writeNC->myPcomm->proc_config().proc_size();
377 std::vector< int > counts( size, 0 ), displs( size, 0 );
378 MPI_Gather( &myN, 1, MPI_INT, counts.data(), 1, MPI_INT, 0, comm );
382 for(
int i = 0; i < size; ++i )
390 std::vector< int > allGids;
391 std::vector< double > allCenterLat, allCenterLon, allCornerLat, allCornerLon;
392 std::vector< int > allImask;
393 std::vector< double > allAreas;
399 allCornerLat.resize(
static_cast< size_t >(
mGlobalCells ) * ncpc );
400 allCornerLon.resize(
static_cast< size_t >(
mGlobalCells ) * ncpc );
405 MPI_Gatherv(
mLocalGids.data(), myN, MPI_INT, allGids.data(), counts.data(), displs.data(), MPI_INT, 0, comm );
406 MPI_Gatherv(
mCenterLat.data(), myN, MPI_DOUBLE, allCenterLat.data(), counts.data(), displs.data(), MPI_DOUBLE,
408 MPI_Gatherv(
mCenterLon.data(), myN, MPI_DOUBLE, allCenterLon.data(), counts.data(), displs.data(), MPI_DOUBLE,
410 MPI_Gatherv(
mImask.data(), myN, MPI_INT, allImask.data(), counts.data(), displs.data(), MPI_INT, 0, comm );
414 std::vector< int > countsC( size, 0 ), displsC( size, 0 );
418 for(
int i = 0; i < size; ++i )
420 countsC[i] = counts[i] * ncpc;
425 MPI_Gatherv(
mCornerLat.data(), myN * ncpc, MPI_DOUBLE, allCornerLat.data(), countsC.data(), displsC.data(),
426 MPI_DOUBLE, 0, comm );
427 MPI_Gatherv(
mCornerLon.data(), myN * ncpc, MPI_DOUBLE, allCornerLon.data(), countsC.data(), displsC.data(),
428 MPI_DOUBLE, 0, comm );
431 MPI_Gatherv(
mAreas.data(), myN, MPI_DOUBLE, allAreas.data(), counts.data(), displs.data(), MPI_DOUBLE, 0,
440 rc = sortAndWrite( allGids, allCenterLat, allCenterLon, allCornerLat, allCornerLon, allImask, allAreas );
442 int rcInt =
static_cast< int >( rc );
443 MPI_Bcast( &rcInt, 1, MPI_INT, 0, comm );
446 dbgOut.
tprintf( 1,
" SCRIP write: gathered+wrote %ld cells from %d ranks\n",
mGlobalCells, size );
458 std::vector< int >& )