Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
moab::NCWriteScrip Class Reference

#include <NCWriteScrip.hpp>

+ Inheritance diagram for moab::NCWriteScrip:
+ Collaboration diagram for moab::NCWriteScrip:

Public Member Functions

 NCWriteScrip (WriteNC *writeNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
 
virtual ~NCWriteScrip () override
 
ErrorCode collect_mesh_info () override
 Collect cells + compute SCRIP-ready center/corner lat/lon arrays. More...
 
ErrorCode init_file (std::vector< std::string > &var_names, std::vector< std::string > &desired_names, bool _append) override
 Override: synthesize the SCRIP schema directly — no need for the climate var_names / dim plumbing that the base init_file walks through. More...
 
ErrorCode write_values (std::vector< std::string > &var_names, std::vector< int > &tstep_nums) override
 Override: write SCRIP grid arrays (cells gathered to rank 0 and written serially via the dispatch layer). More...
 
- Public Member Functions inherited from moab::NCWriteHelper
 NCWriteHelper (WriteNC *writeNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
 
virtual ~NCWriteHelper ()
 
virtual ErrorCode collect_variable_data (std::vector< std::string > &var_names, std::vector< int > &tstep_nums)
 Collect data for specified variables (partially implemented in child classes) More...
 

Protected Member Functions

ErrorCode write_nonset_variables (std::vector< WriteNC::VarData > &vdatas, std::vector< int > &tstep_nums) override
 Required by the abstract base; no climate "nonset" variables exist in a SCRIP grid file, so this is a no-op. More...
 

Private Attributes

long mLocalCells
 Per-rank cell count and the global total (set in collect_mesh_info). More...
 
long mGlobalCells
 
int mMaxCornersGlobal
 Global max corners per cell. Used to size the corner arrays. More...
 
bool mHasAreas
 True if a cell-area tag was present on the input mesh and we'll emit grid_area; false otherwise. More...
 
std::vector< int > mLocalGids
 Per-cell local data (size mLocalCells; corners are mLocalCells * mMaxCornersGlobal, row-major). More...
 
std::vector< double > mCenterLon
 
std::vector< double > mCenterLat
 
std::vector< double > mCornerLon
 
std::vector< double > mCornerLat
 
std::vector< int > mImask
 
std::vector< double > mAreas
 
int mDimGridSize
 NetCDF dimension and variable handles populated by init_file(). More...
 
int mDimGridCorners
 
int mDimGridRank
 
int mVarGridDims
 
int mVarCenterLon
 
int mVarCenterLat
 
int mVarCornerLon
 
int mVarCornerLat
 
int mVarImask
 
int mVarArea
 

Additional Inherited Members

- Static Public Member Functions inherited from moab::NCWriteHelper
static NCWriteHelperget_nc_helper (WriteNC *writeNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
 Get appropriate helper instance for WriteNC class based on some info in the file set. More...
 
- Protected Attributes inherited from moab::NCWriteHelper
WriteNC_writeNC
 Allow NCWriteHelper to directly access members of WriteNC. More...
 
int _fileId
 Cache some information from WriteNC. More...
 
const FileOptions_opts
 
EntityHandle _fileSet
 
int nTimeSteps
 Dimensions of time and level. More...
 
int nLevels
 
int tDim
 Dimension numbers for time and level. More...
 
int levDim
 
Range localCellsOwned
 Local owned cells, edges and vertices. More...
 
Range localEdgesOwned
 
Range localVertsOwned
 
std::vector< double > timeStepVals
 Time values of output timesteps. More...
 

Detailed Description

Definition at line 39 of file NCWriteScrip.hpp.

Constructor & Destructor Documentation

◆ NCWriteScrip()

moab::NCWriteScrip::NCWriteScrip ( WriteNC writeNC,
int  fileId,
const FileOptions opts,
EntityHandle  fileSet 
)
inline

Definition at line 42 of file NCWriteScrip.hpp.

43  : NCWriteHelper( writeNC, fileId, opts, fileSet ),
44  mLocalCells( 0 ), mGlobalCells( 0 ), mMaxCornersGlobal( 0 ), mHasAreas( false ),
45  mDimGridSize( -1 ), mDimGridCorners( -1 ), mDimGridRank( -1 ),
46  mVarGridDims( -1 ), mVarCenterLon( -1 ), mVarCenterLat( -1 ), mVarCornerLon( -1 ),
47  mVarCornerLat( -1 ), mVarImask( -1 ), mVarArea( -1 )
48  {
49  }

◆ ~NCWriteScrip()

moab::NCWriteScrip::~NCWriteScrip ( )
overridevirtual

Definition at line 20 of file NCWriteScrip.cpp.

20 {}

Member Function Documentation

◆ collect_mesh_info()

ErrorCode moab::NCWriteScrip::collect_mesh_info ( )
overridevirtual

Collect cells + compute SCRIP-ready center/corner lat/lon arrays.

Implements moab::NCWriteHelper.

Definition at line 51 of file NCWriteScrip.cpp.

52 {
53  Interface*& mbImpl = _writeNC->mbImpl;
54  Tag& mGlobalIdTag = _writeNC->mGlobalIdTag;
55  DebugOutput& dbgOut = _writeNC->dbgOut;
56 
57  // Pick up all 2-D cells (polygonal: tris, quads, polygons).
58  Range allCells;
59  MB_CHK_SET_ERR( mbImpl->get_entities_by_dimension( _fileSet, 2, allCells ),
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" );
62 
63  // In parallel, restrict to owned cells so each rank contributes
64  // exactly its share (no double-writing of ghosts).
65  localCellsOwned = allCells;
66 #ifdef MOAB_HAVE_MPI
67  bool& isParallel = _writeNC->isParallel;
68  if( isParallel )
69  {
70  ParallelComm*& myPcomm = _writeNC->myPcomm;
71  if( myPcomm && myPcomm->proc_config().proc_size() > 1 )
72  {
73  MB_CHK_SET_ERR( myPcomm->filter_pstatus( localCellsOwned, PSTATUS_NOT_OWNED, PSTATUS_NOT ),
74  "Failed to filter owned cells for SCRIP write" );
75  }
76  }
77 #endif
78 
79  mLocalCells = static_cast< long >( localCellsOwned.size() );
80 
81  // Allreduce to find the global maximum corner count so every rank's
82  // arrays are sized identically — required for the final write because
83  // grid_corner_lon/lat is a 2-D variable.
84  int localMaxCorners = 0;
85  for( Range::iterator cit = localCellsOwned.begin(); cit != localCellsOwned.end(); ++cit )
86  {
87  const EntityHandle* conn = nullptr;
88  int numConn = 0;
89  ErrorCode rc = mbImpl->get_connectivity( *cit, conn, numConn );
90  if( MB_SUCCESS == rc && numConn > localMaxCorners ) localMaxCorners = numConn;
91  }
92 #ifdef MOAB_HAVE_MPI
93  if( _writeNC->isParallel && _writeNC->myPcomm )
94  {
95  MPI_Allreduce( &localMaxCorners, &mMaxCornersGlobal, 1, MPI_INT, MPI_MAX,
96  _writeNC->myPcomm->proc_config().proc_comm() );
97  }
98  else
99 #endif
100  {
101  mMaxCornersGlobal = localMaxCorners;
102  }
103  if( mMaxCornersGlobal <= 0 )
104  MB_SET_ERR( MB_FAILURE, "Mesh contains cells but all reported zero connectivity; cannot write SCRIP" );
105 
106  // Pre-allocate per-cell arrays.
107  mLocalGids.resize( mLocalCells );
108  mCenterLon.resize( mLocalCells );
109  mCenterLat.resize( mLocalCells );
110  mCornerLon.assign( static_cast< size_t >( mLocalCells ) * mMaxCornersGlobal, 0.0 );
111  mCornerLat.assign( static_cast< size_t >( mLocalCells ) * mMaxCornersGlobal, 0.0 );
112  mImask.assign( mLocalCells, 1 );
113 
114  // Optional: pull a GRID_IMASK tag if it exists (matches the reader).
115  Tag maskTag = 0;
116  if( MB_SUCCESS == mbImpl->tag_get_handle( "GRID_IMASK", 1, MB_TYPE_INTEGER, maskTag ) && maskTag )
117  {
118  // Read per-cell mask; if call fails (e.g. tag isn't densely set),
119  // just keep the default 1's — the mask field is still well-formed.
120  ErrorCode mrc = mbImpl->tag_get_data( maskTag, localCellsOwned, mImask.data() );
121  if( MB_SUCCESS != mrc )
122  {
123  dbgOut.tprintf( 1, " GRID_IMASK tag exists but read failed; writing all-1 mask\n" );
124  std::fill( mImask.begin(), mImask.end(), 1 );
125  }
126  }
127 
128  // Optional: cell area tag.
129  Tag areaTag = 0;
130  if( MB_SUCCESS == mbImpl->tag_get_handle( "GRID_AREA", 1, MB_TYPE_DOUBLE, areaTag ) && areaTag )
131  {
132  mAreas.assign( mLocalCells, 0.0 );
133  if( MB_SUCCESS == mbImpl->tag_get_data( areaTag, localCellsOwned, mAreas.data() ) )
134  mHasAreas = true;
135  else
136  mAreas.clear();
137  }
138 
139  // Fill the global-id, center, and corner arrays.
140  long ci = 0;
141  for( Range::iterator cit = localCellsOwned.begin(); cit != localCellsOwned.end(); ++cit, ++ci )
142  {
143  // Global ID for this cell — used to make the on-disk ordering
144  // deterministic after a gather to rank 0.
145  int gid = 0;
146  if( mGlobalIdTag ) mbImpl->tag_get_data( mGlobalIdTag, &( *cit ), 1, &gid );
147  mLocalGids[ci] = gid;
148 
149  const EntityHandle* conn = nullptr;
150  int numConn = 0;
151  MB_CHK_SET_ERR( mbImpl->get_connectivity( *cit, conn, numConn ), "Cell connectivity lookup failed" );
152 
153  // Accumulate XYZ for the cell centroid as we go.
154  double cx = 0.0, cy = 0.0, cz = 0.0;
155  // First-corner fallback used to pad smaller polygons up to the
156  // global max corner count (standard SCRIP convention).
157  double firstLat = 0.0, firstLon = 0.0;
158 
159  for( int k = 0; k < numConn; ++k )
160  {
161  double vc[3] = { 0.0, 0.0, 0.0 };
162  MB_CHK_SET_ERR( mbImpl->get_coords( &conn[k], 1, vc ), "Vertex coordinate lookup failed" );
163  cx += vc[0];
164  cy += vc[1];
165  cz += vc[2];
166  double vlat = 0.0, vlon = 0.0;
167  xyz_to_latlon_deg( vc[0], vc[1], vc[2], vlat, vlon );
168  mCornerLat[ci * mMaxCornersGlobal + k] = vlat;
169  mCornerLon[ci * mMaxCornersGlobal + k] = vlon;
170  if( k == 0 )
171  {
172  firstLat = vlat;
173  firstLon = vlon;
174  }
175  }
176  // Pad unused corners with the first corner (SCRIP convention).
177  for( int k = numConn; k < mMaxCornersGlobal; ++k )
178  {
179  mCornerLat[ci * mMaxCornersGlobal + k] = firstLat;
180  mCornerLon[ci * mMaxCornersGlobal + k] = firstLon;
181  }
182 
183  // Center: average XYZ projected to the sphere.
184  cx /= numConn;
185  cy /= numConn;
186  cz /= numConn;
187  xyz_to_latlon_deg( cx, cy, cz, mCenterLat[ci], mCenterLon[ci] );
188  }
189 
190  // Global cell count for the file-level grid_size dim.
192 #ifdef MOAB_HAVE_MPI
193  if( _writeNC->isParallel && _writeNC->myPcomm )
194  {
195  long localN = mLocalCells;
196  MPI_Allreduce( &localN, &mGlobalCells, 1, MPI_LONG, MPI_SUM,
197  _writeNC->myPcomm->proc_config().proc_comm() );
198  }
199 #endif
200 
201  dbgOut.tprintf( 1, " SCRIP write: local_cells=%ld global_cells=%ld max_corners=%d hasAreas=%d\n", mLocalCells,
203 
204  return MB_SUCCESS;
205 }

References moab::NCWriteHelper::_fileSet, moab::NCWriteHelper::_writeNC, moab::Range::begin(), moab::WriteNC::dbgOut, moab::Range::empty(), moab::Range::end(), ErrorCode, moab::ParallelComm::filter_pstatus(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_dimension(), moab::WriteNC::isParallel, moab::NCWriteHelper::localCellsOwned, mAreas, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TYPE_DOUBLE, MB_TYPE_INTEGER, moab::WriteNC::mbImpl, mCenterLat, mCenterLon, mCornerLat, mCornerLon, mGlobalCells, moab::WriteNC::mGlobalIdTag, mHasAreas, mImask, mLocalCells, mLocalGids, mMaxCornersGlobal, moab::ParallelComm::proc_config(), moab::ProcConfig::proc_size(), PSTATUS_NOT, PSTATUS_NOT_OWNED, moab::Range::size(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::DebugOutput::tprintf(), and moab::anonymous_namespace{NCWriteScrip.cpp}::xyz_to_latlon_deg().

◆ init_file()

ErrorCode moab::NCWriteScrip::init_file ( std::vector< std::string > &  var_names,
std::vector< std::string > &  desired_names,
bool  _append 
)
overridevirtual

Override: synthesize the SCRIP schema directly — no need for the climate var_names / dim plumbing that the base init_file walks through.

Reimplemented from moab::NCWriteHelper.

Definition at line 212 of file NCWriteScrip.cpp.

215 {
216  // Dimensions
217  MB_CHK_SET_ERR( ( NCFUNC( def_dim )( _fileId, "grid_size", static_cast< size_t >( mGlobalCells ), &mDimGridSize ) )
218  ? MB_FAILURE
219  : MB_SUCCESS,
220  "Failed to define grid_size dimension" );
222  ( NCFUNC( def_dim )( _fileId, "grid_corners", static_cast< size_t >( mMaxCornersGlobal ), &mDimGridCorners ) )
223  ? MB_FAILURE
224  : MB_SUCCESS,
225  "Failed to define grid_corners dimension" );
226  MB_CHK_SET_ERR( ( NCFUNC( def_dim )( _fileId, "grid_rank", static_cast< size_t >( 1 ), &mDimGridRank ) )
227  ? MB_FAILURE
228  : MB_SUCCESS,
229  "Failed to define grid_rank dimension" );
230 
231  int dim1[1] = { mDimGridRank };
232  int dim1c[1] = { mDimGridSize };
233  int dim2[2] = { mDimGridSize, mDimGridCorners };
234 
235  // Variables — match NCHelperScrip's reader expectations.
237  ( NCFUNC( def_var )( _fileId, "grid_dims", NC_INT, 1, dim1, &mVarGridDims ) ) ? MB_FAILURE : MB_SUCCESS,
238  "Failed to define grid_dims variable" );
239 
240  MB_CHK_SET_ERR( ( NCFUNC( def_var )( _fileId, "grid_center_lat", NC_DOUBLE, 1, dim1c, &mVarCenterLat ) )
241  ? MB_FAILURE
242  : MB_SUCCESS,
243  "Failed to define grid_center_lat variable" );
244  MB_CHK_SET_ERR( ( NCFUNC( def_var )( _fileId, "grid_center_lon", NC_DOUBLE, 1, dim1c, &mVarCenterLon ) )
245  ? MB_FAILURE
246  : MB_SUCCESS,
247  "Failed to define grid_center_lon variable" );
248  MB_CHK_SET_ERR( ( NCFUNC( def_var )( _fileId, "grid_corner_lat", NC_DOUBLE, 2, dim2, &mVarCornerLat ) )
249  ? MB_FAILURE
250  : MB_SUCCESS,
251  "Failed to define grid_corner_lat variable" );
252  MB_CHK_SET_ERR( ( NCFUNC( def_var )( _fileId, "grid_corner_lon", NC_DOUBLE, 2, dim2, &mVarCornerLon ) )
253  ? MB_FAILURE
254  : MB_SUCCESS,
255  "Failed to define grid_corner_lon variable" );
257  ( NCFUNC( def_var )( _fileId, "grid_imask", NC_INT, 1, dim1c, &mVarImask ) ) ? MB_FAILURE : MB_SUCCESS,
258  "Failed to define grid_imask variable" );
259 
260  if( mHasAreas )
261  {
263  ( NCFUNC( def_var )( _fileId, "grid_area", NC_DOUBLE, 1, dim1c, &mVarArea ) ) ? MB_FAILURE : MB_SUCCESS,
264  "Failed to define grid_area variable" );
265  }
266 
267  // Unit attributes — readers (including NCHelperScrip) key off these.
268  const char* deg = "degrees";
269  NCFUNC( put_att_text )( _fileId, mVarCenterLat, "units", 7, deg );
270  NCFUNC( put_att_text )( _fileId, mVarCenterLon, "units", 7, deg );
271  NCFUNC( put_att_text )( _fileId, mVarCornerLat, "units", 7, deg );
272  NCFUNC( put_att_text )( _fileId, mVarCornerLon, "units", 7, deg );
273  if( mHasAreas )
274  {
275  const char* rad2 = "radians^2";
276  NCFUNC( put_att_text )( _fileId, mVarArea, "units", 9, rad2 );
277  }
278 
279  // Global title attribute mirrors what the reader looks for in a few places.
280  const char* title = "MOAB:NCWriteScrip generated SCRIP grid file";
281  NCFUNC( put_att_text )( _fileId, NC_GLOBAL, "title", std::strlen( title ), title );
282 
283  // Close define mode so subsequent writes are data-mode operations.
284  int endrc = NCFUNC( enddef )( _fileId );
285  if( endrc ) MB_SET_ERR( MB_FAILURE, "enddef failed for SCRIP write" );
286 
287  return MB_SUCCESS;
288 }

References moab::NCWriteHelper::_fileId, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, mDimGridCorners, mDimGridRank, mDimGridSize, mGlobalCells, mHasAreas, mMaxCornersGlobal, mVarArea, mVarCenterLat, mVarCenterLon, mVarCornerLat, mVarCornerLon, mVarGridDims, mVarImask, and NCFUNC.

◆ write_nonset_variables()

ErrorCode moab::NCWriteScrip::write_nonset_variables ( std::vector< WriteNC::VarData > &  vdatas,
std::vector< int > &  tstep_nums 
)
overrideprotectedvirtual

Required by the abstract base; no climate "nonset" variables exist in a SCRIP grid file, so this is a no-op.

Implements moab::NCWriteHelper.

Definition at line 457 of file NCWriteScrip.cpp.

459 {
460  return MB_SUCCESS;
461 }

References MB_SUCCESS.

◆ write_values()

ErrorCode moab::NCWriteScrip::write_values ( std::vector< std::string > &  var_names,
std::vector< int > &  tstep_nums 
)
overridevirtual

Override: write SCRIP grid arrays (cells gathered to rank 0 and written serially via the dispatch layer).

Reimplemented from moab::NCWriteHelper.

Definition at line 299 of file NCWriteScrip.cpp.

301 {
302  DebugOutput& dbgOut = _writeNC->dbgOut;
303 
304  // Helper to assemble the global-ordered arrays on rank 0.
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() );
310  const int ncpc = mMaxCornersGlobal;
311 
312  // Permutation by global id for BfB output across rank counts.
313  std::vector< long > perm( N );
314  for( long i = 0; i < N; ++i )
315  perm[i] = i;
316  std::sort( perm.begin(), perm.end(),
317  [&]( long a, long b ) { return allGids[a] < allGids[b]; } );
318 
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 );
323 
324  for( long i = 0; i < N; ++i )
325  {
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 )
332  {
333  sCornerLat[i * ncpc + k] = allCornerLat[src * ncpc + k];
334  sCornerLon[i * ncpc + k] = allCornerLon[src * ncpc + k];
335  }
336  }
337 
338  // grid_dims = [grid_size]
339  int gridDimsValue = static_cast< int >( N );
340  size_t startD = 0, countD = 1;
341  if( NCFUNCAP( _vara_int )( _fileId, mVarGridDims, &startD, &countD, &gridDimsValue ) )
342  MB_SET_ERR( MB_FAILURE, "Failed to write grid_dims" );
343 
344  size_t s1 = 0, c1 = static_cast< size_t >( N );
345  if( NCFUNCAP( _vara_double )( _fileId, mVarCenterLat, &s1, &c1, sCenterLat.data() ) )
346  MB_SET_ERR( MB_FAILURE, "Failed to write grid_center_lat" );
347  if( NCFUNCAP( _vara_double )( _fileId, mVarCenterLon, &s1, &c1, sCenterLon.data() ) )
348  MB_SET_ERR( MB_FAILURE, "Failed to write grid_center_lon" );
349  if( NCFUNCAP( _vara_int )( _fileId, mVarImask, &s1, &c1, sImask.data() ) )
350  MB_SET_ERR( MB_FAILURE, "Failed to write grid_imask" );
351  if( !sAreas.empty() )
352  {
353  if( NCFUNCAP( _vara_double )( _fileId, mVarArea, &s1, &c1, sAreas.data() ) )
354  MB_SET_ERR( MB_FAILURE, "Failed to write grid_area" );
355  }
356 
357  const size_t s2[2] = { 0, 0 };
358  const size_t c2[2] = { static_cast< size_t >( N ), static_cast< size_t >( ncpc ) };
359  if( NCFUNCAP( _vara_double )( _fileId, mVarCornerLat, s2, c2, sCornerLat.data() ) )
360  MB_SET_ERR( MB_FAILURE, "Failed to write grid_corner_lat" );
361  if( NCFUNCAP( _vara_double )( _fileId, mVarCornerLon, s2, c2, sCornerLon.data() ) )
362  MB_SET_ERR( MB_FAILURE, "Failed to write grid_corner_lon" );
363 
364  return MB_SUCCESS;
365  };
366 
367 #ifdef MOAB_HAVE_MPI
368  if( _writeNC->isParallel && _writeNC->myPcomm && _writeNC->myPcomm->proc_config().proc_size() > 1 )
369  {
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();
373  const int ncpc = mMaxCornersGlobal;
374 
375  // Counts of cells per rank (Gatherv setup).
376  int myN = static_cast< int >( mLocalCells );
377  std::vector< int > counts( size, 0 ), displs( size, 0 );
378  MPI_Gather( &myN, 1, MPI_INT, counts.data(), 1, MPI_INT, 0, comm );
379  if( rank == 0 )
380  {
381  int acc = 0;
382  for( int i = 0; i < size; ++i )
383  {
384  displs[i] = acc;
385  acc += counts[i];
386  }
387  }
388 
389  // Per-cell gather targets on rank 0.
390  std::vector< int > allGids;
391  std::vector< double > allCenterLat, allCenterLon, allCornerLat, allCornerLon;
392  std::vector< int > allImask;
393  std::vector< double > allAreas;
394  if( rank == 0 )
395  {
396  allGids.resize( mGlobalCells );
397  allCenterLat.resize( mGlobalCells );
398  allCenterLon.resize( mGlobalCells );
399  allCornerLat.resize( static_cast< size_t >( mGlobalCells ) * ncpc );
400  allCornerLon.resize( static_cast< size_t >( mGlobalCells ) * ncpc );
401  allImask.resize( mGlobalCells );
402  if( mHasAreas ) allAreas.resize( mGlobalCells );
403  }
404 
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,
407  0, comm );
408  MPI_Gatherv( mCenterLon.data(), myN, MPI_DOUBLE, allCenterLon.data(), counts.data(), displs.data(), MPI_DOUBLE,
409  0, comm );
410  MPI_Gatherv( mImask.data(), myN, MPI_INT, allImask.data(), counts.data(), displs.data(), MPI_INT, 0, comm );
411 
412  // Corner arrays have a different per-rank count (myN * ncpc), so
413  // build a second counts/displs.
414  std::vector< int > countsC( size, 0 ), displsC( size, 0 );
415  if( rank == 0 )
416  {
417  int acc = 0;
418  for( int i = 0; i < size; ++i )
419  {
420  countsC[i] = counts[i] * ncpc;
421  displsC[i] = acc;
422  acc += countsC[i];
423  }
424  }
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 );
429  if( mHasAreas )
430  {
431  MPI_Gatherv( mAreas.data(), myN, MPI_DOUBLE, allAreas.data(), counts.data(), displs.data(), MPI_DOUBLE, 0,
432  comm );
433  }
434 
435  // Rank 0 writes. Other ranks no-op (their file handle is still
436  // open via the dispatch layer; close happens later in WriteNC).
437  ErrorCode rc = MB_SUCCESS;
438  if( rank == 0 )
439  {
440  rc = sortAndWrite( allGids, allCenterLat, allCenterLon, allCornerLat, allCornerLon, allImask, allAreas );
441  }
442  int rcInt = static_cast< int >( rc );
443  MPI_Bcast( &rcInt, 1, MPI_INT, 0, comm );
444  if( rcInt != MB_SUCCESS ) MB_SET_ERR( MB_FAILURE, "SCRIP write failed on rank 0" );
445 
446  dbgOut.tprintf( 1, " SCRIP write: gathered+wrote %ld cells from %d ranks\n", mGlobalCells, size );
447  return MB_SUCCESS;
448  }
449 #endif
450 
451  // Serial path: rank-0-only arrays are already complete; sort + write.
452  return sortAndWrite( mLocalGids, mCenterLat, mCenterLon, mCornerLat, mCornerLon, mImask, mAreas );
453 }

References moab::NCWriteHelper::_fileId, moab::NCWriteHelper::_writeNC, moab::WriteNC::dbgOut, ErrorCode, moab::WriteNC::isParallel, mAreas, MB_SET_ERR, MB_SUCCESS, mCenterLat, mCenterLon, mCornerLat, mCornerLon, mGlobalCells, mHasAreas, mImask, mLocalCells, mLocalGids, mMaxCornersGlobal, mVarArea, mVarCenterLat, mVarCenterLon, mVarCornerLat, mVarCornerLon, mVarGridDims, mVarImask, NCFUNCAP, and moab::DebugOutput::tprintf().

Member Data Documentation

◆ mAreas

std::vector< double > moab::NCWriteScrip::mAreas
private

Definition at line 95 of file NCWriteScrip.hpp.

Referenced by collect_mesh_info(), and write_values().

◆ mCenterLat

std::vector< double > moab::NCWriteScrip::mCenterLat
private

Definition at line 91 of file NCWriteScrip.hpp.

Referenced by collect_mesh_info(), and write_values().

◆ mCenterLon

std::vector< double > moab::NCWriteScrip::mCenterLon
private

Definition at line 90 of file NCWriteScrip.hpp.

Referenced by collect_mesh_info(), and write_values().

◆ mCornerLat

std::vector< double > moab::NCWriteScrip::mCornerLat
private

Definition at line 93 of file NCWriteScrip.hpp.

Referenced by collect_mesh_info(), and write_values().

◆ mCornerLon

std::vector< double > moab::NCWriteScrip::mCornerLon
private

Definition at line 92 of file NCWriteScrip.hpp.

Referenced by collect_mesh_info(), and write_values().

◆ mDimGridCorners

int moab::NCWriteScrip::mDimGridCorners
private

Definition at line 99 of file NCWriteScrip.hpp.

Referenced by init_file().

◆ mDimGridRank

int moab::NCWriteScrip::mDimGridRank
private

Definition at line 100 of file NCWriteScrip.hpp.

Referenced by init_file().

◆ mDimGridSize

int moab::NCWriteScrip::mDimGridSize
private

NetCDF dimension and variable handles populated by init_file().

Definition at line 98 of file NCWriteScrip.hpp.

Referenced by init_file().

◆ mGlobalCells

long moab::NCWriteScrip::mGlobalCells
private

Definition at line 78 of file NCWriteScrip.hpp.

Referenced by collect_mesh_info(), init_file(), and write_values().

◆ mHasAreas

bool moab::NCWriteScrip::mHasAreas
private

True if a cell-area tag was present on the input mesh and we'll emit grid_area; false otherwise.

Definition at line 85 of file NCWriteScrip.hpp.

Referenced by collect_mesh_info(), init_file(), and write_values().

◆ mImask

std::vector< int > moab::NCWriteScrip::mImask
private

Definition at line 94 of file NCWriteScrip.hpp.

Referenced by collect_mesh_info(), and write_values().

◆ mLocalCells

long moab::NCWriteScrip::mLocalCells
private

Per-rank cell count and the global total (set in collect_mesh_info).

Definition at line 77 of file NCWriteScrip.hpp.

Referenced by collect_mesh_info(), and write_values().

◆ mLocalGids

std::vector< int > moab::NCWriteScrip::mLocalGids
private

Per-cell local data (size mLocalCells; corners are mLocalCells * mMaxCornersGlobal, row-major).

Definition at line 89 of file NCWriteScrip.hpp.

Referenced by collect_mesh_info(), and write_values().

◆ mMaxCornersGlobal

int moab::NCWriteScrip::mMaxCornersGlobal
private

Global max corners per cell. Used to size the corner arrays.

Definition at line 81 of file NCWriteScrip.hpp.

Referenced by collect_mesh_info(), init_file(), and write_values().

◆ mVarArea

int moab::NCWriteScrip::mVarArea
private

Definition at line 107 of file NCWriteScrip.hpp.

Referenced by init_file(), and write_values().

◆ mVarCenterLat

int moab::NCWriteScrip::mVarCenterLat
private

Definition at line 103 of file NCWriteScrip.hpp.

Referenced by init_file(), and write_values().

◆ mVarCenterLon

int moab::NCWriteScrip::mVarCenterLon
private

Definition at line 102 of file NCWriteScrip.hpp.

Referenced by init_file(), and write_values().

◆ mVarCornerLat

int moab::NCWriteScrip::mVarCornerLat
private

Definition at line 105 of file NCWriteScrip.hpp.

Referenced by init_file(), and write_values().

◆ mVarCornerLon

int moab::NCWriteScrip::mVarCornerLon
private

Definition at line 104 of file NCWriteScrip.hpp.

Referenced by init_file(), and write_values().

◆ mVarGridDims

int moab::NCWriteScrip::mVarGridDims
private

Definition at line 101 of file NCWriteScrip.hpp.

Referenced by init_file(), and write_values().

◆ mVarImask

int moab::NCWriteScrip::mVarImask
private

Definition at line 106 of file NCWriteScrip.hpp.

Referenced by init_file(), and write_values().


The documentation for this class was generated from the following files: