20 #ifndef MOAB_HAVE_TEMPESTREMAP
21 #error Tool requires compilation with TempestRemap dependency
25 #include "OfflineMap.h"
26 #include "netcdfcpp.h"
27 #include "NetCDFUtilities.h"
28 #include "DataArray2D.h"
32 template <
typename T >
37 std::vector< T >& data )
39 int* tag_sizes =
new int[sets.
size()];
40 const void** tag_data = (
const void**)
new void*[sets.
size()];
45 for(
unsigned is = 0; is < sets.
size(); ++is )
46 out_data_size += tag_sizes[is];
48 data.resize( out_data_size );
50 for(
unsigned index = 0; index < sets.
size(); index++ )
52 T* m_vals = (
T*)tag_data[index];
53 for(
int k = 0; k < tag_sizes[index]; k++ )
55 data[ioffset++] = m_vals[k];
62 void ReadFileMetaData( std::string& metaFilename, std::map< std::string, std::string >& metadataVals )
64 std::ifstream metafile;
67 metafile.open( metaFilename.c_str() );
68 metadataVals[
"Title"] =
"MOAB-TempestRemap (MBTR) Offline Regridding Weight Converter (h5mtoscrip)";
69 std::string key, value;
70 while( std::getline( metafile, line ) )
72 size_t lastindex = line.find_last_of(
"=" );
73 key = line.substr( 0, lastindex - 1 );
74 value = line.substr( lastindex + 2, line.length() );
76 metadataVals[std::string( key )] = std::string( value );
81 int main(
int argc,
char* argv[] )
85 NcError error2( NcError::verbose_nonfatal );
86 std::stringstream sstr;
88 std::string h5mfilename, scripfile;
90 bool writeXYCoords =
false;
93 MPI_Init( &argc, &argv );
96 opts.
addOpt< std::string >(
"weights,w",
"h5m remapping weights filename", &h5mfilename );
97 opts.
addOpt< std::string >(
"scrip,s",
"Output SCRIP map filename", &scripfile );
98 opts.
addOpt<
int >(
"dim,d",
"Dimension of entities to use for partitioning", &dimension );
99 opts.
addOpt<
void >(
"mesh,m",
"Only convert the mesh and exclude the remap weight details", &noMap );
100 opts.
addOpt<
void >(
"coords,c",
"Write the center and vertex coordinates in lat/lon format", &writeXYCoords );
104 if( h5mfilename.empty() || scripfile.empty() )
118 const std::string partition_set_name =
"PARALLEL_PARTITION";
119 const std::string global_id_name =
"GLOBAL_ID";
128 NcError error_temp( NcError::verbose_fatal );
131 NcFile ncMap( scripfile.c_str(), NcFile::Replace, NULL, 0, NcFile::Offset64Bits );
132 if( !ncMap.is_valid() )
134 _EXCEPTION1(
"Unable to open output map file \"%s\"", scripfile.c_str() );
139 std::map< std::string, std::string > mapAttributes;
140 size_t lastindex = h5mfilename.find_last_of(
"." );
141 std::stringstream sstr;
142 sstr << h5mfilename.substr( 0, lastindex ) <<
".meta";
143 std::string metaFilename = sstr.str();
145 mapAttributes[
"Command"] =
146 "Converted with MOAB:h5mtoscrip with --w=" + h5mfilename +
" and --s=" + scripfile;
149 std::map< std::string, std::string >::const_iterator iterAttributes = mapAttributes.begin();
150 for( ; iterAttributes != mapAttributes.end(); iterAttributes++ )
153 std::cout << iterAttributes->first <<
" -- " << iterAttributes->second << std::endl;
154 ncMap.add_att( iterAttributes->first.c_str(), iterAttributes->second.c_str() );
159 Tag globalIDTag, materialSetTag;
193 int smat_metadata_glb[13];
200 ( ( ( a ) == 0 ) ? "FV" : ( ( ( a ) == 1 ) ? "cGLL" : "dGLL" ) ) \
203 int nA = smat_metadata_glb[0];
204 int nB = smat_metadata_glb[1];
205 int nVA = smat_metadata_glb[2];
206 int nVB = smat_metadata_glb[3];
207 int nDofB = smat_metadata_glb[4];
208 int nDofA = smat_metadata_glb[5];
209 int NNZ = smat_metadata_glb[6];
210 int nOrdA = smat_metadata_glb[7];
211 int nOrdB = smat_metadata_glb[8];
212 int nBasA = smat_metadata_glb[9];
213 std::string methodA =
DTYPE( nBasA );
214 int nBasB = smat_metadata_glb[10];
215 std::string methodB =
DTYPE( nBasB );
216 int bConserved = smat_metadata_glb[11];
217 int bMonotonicity = smat_metadata_glb[12];
219 EntityHandle source_mesh = 0, target_mesh = 0, overlap_mesh = 0;
220 for(
unsigned im = 0; im < meshsets.
size(); ++im )
224 if( elems.
size() - nA == 0 && source_mesh == 0 )
225 source_mesh = meshsets[im];
226 else if( elems.
size() - nB == 0 && target_mesh == 0 )
227 target_mesh = meshsets[im];
228 else if( overlap_mesh == 0 )
229 overlap_mesh = meshsets[im];
234 Tag srcIDTag, srcAreaTag, tgtIDTag, tgtAreaTag;
239 Tag smatRowdataTag, smatColdataTag, smatValsdataTag;
243 Tag srcCenterLon, srcCenterLat, tgtCenterLon, tgtCenterLat;
248 Tag srcVertexLon, srcVertexLat, tgtVertexLon, tgtVertexLat;
260 std::vector< int > src_gids, tgt_gids;
261 std::vector< double > src_areas, tgt_areas;
262 int srcID_size, tgtID_size, srcArea_size, tgtArea_size;
268 assert( srcArea_size == srcID_size );
269 assert( tgtArea_size == tgtID_size );
271 std::vector< double > src_glob_areas( nDofA, 0.0 ), tgt_glob_areas( nDofB, 0.0 );
272 for(
int i = 0; i < srcArea_size; ++i )
276 assert( i < srcID_size );
277 assert( src_gids[i] < nDofA );
278 if( src_areas[i] > src_glob_areas[src_gids[i]] ) src_glob_areas[src_gids[i]] = src_areas[i];
280 for(
int i = 0; i < tgtArea_size; ++i )
284 assert( i < tgtID_size );
285 assert( tgt_gids[i] < nDofB );
286 if( tgt_areas[i] > tgt_glob_areas[tgt_gids[i]] ) tgt_glob_areas[tgt_gids[i]] = tgt_areas[i];
290 int nSrcGridDims = 1;
291 int nDstGridDims = 1;
293 NcDim* dimSrcGridRank = ncMap.add_dim(
"src_grid_rank", nSrcGridDims );
294 NcDim* dimDstGridRank = ncMap.add_dim(
"dst_grid_rank", nDstGridDims );
296 NcVar* varSrcGridDims = ncMap.add_var(
"src_grid_dims", ncInt, dimSrcGridRank );
297 NcVar* varDstGridDims = ncMap.add_var(
"dst_grid_dims", ncInt, dimDstGridRank );
301 varSrcGridDims->put( &nA, 1 );
302 varSrcGridDims->add_att(
"name0",
"num_elem" );
306 varSrcGridDims->put( &nDofA, 1 );
307 varSrcGridDims->add_att(
"name1",
"num_dof" );
312 varDstGridDims->put( &nB, 1 );
313 varDstGridDims->add_att(
"name0",
"num_elem" );
317 varDstGridDims->put( &nDofB, 1 );
318 varDstGridDims->add_att(
"name1",
"num_dof" );
322 NcDim* dimNA = ncMap.add_dim(
"n_a", nDofA );
323 NcDim* dimNB = ncMap.add_dim(
"n_b", nDofB );
326 const int nva = ( nA == nDofA ? nVA : 1 );
327 const int nvb = ( nB == nDofB ? nVB : 1 );
328 NcDim* dimNVA = ncMap.add_dim(
"nv_a", nva );
329 NcDim* dimNVB = ncMap.add_dim(
"nv_b", nvb );
338 NcVar* varYCA = ncMap.add_var(
"yc_a", ncDouble, dimNA );
339 NcVar* varYCB = ncMap.add_var(
"yc_b", ncDouble, dimNB );
341 NcVar* varXCA = ncMap.add_var(
"xc_a", ncDouble, dimNA );
342 NcVar* varXCB = ncMap.add_var(
"xc_b", ncDouble, dimNB );
344 NcVar* varYVA = ncMap.add_var(
"yv_a", ncDouble, dimNA , dimNVA );
345 NcVar* varYVB = ncMap.add_var(
"yv_b", ncDouble, dimNB , dimNVB );
347 NcVar* varXVA = ncMap.add_var(
"xv_a", ncDouble, dimNA , dimNVA );
348 NcVar* varXVB = ncMap.add_var(
"xv_b", ncDouble, dimNB , dimNVB );
350 varYCA->add_att(
"units",
"degrees" );
351 varYCB->add_att(
"units",
"degrees" );
353 varXCA->add_att(
"units",
"degrees" );
354 varXCB->add_att(
"units",
"degrees" );
356 varYVA->add_att(
"units",
"degrees" );
357 varYVB->add_att(
"units",
"degrees" );
359 varXVA->add_att(
"units",
"degrees" );
360 varXVB->add_att(
"units",
"degrees" );
362 std::vector< double > src_centerlat, src_centerlon;
364 rval =
get_vartag_data( mbCore, srcCenterLat, sets, srccenter_size, src_centerlat );
MB_CHK_SET_ERR( rval,
"Getting source mesh areas failed" );
365 rval =
get_vartag_data( mbCore, srcCenterLon, sets, srccenter_size, src_centerlon );
MB_CHK_SET_ERR( rval,
"Getting target mesh areas failed" );
366 std::vector< double > src_glob_centerlat( nDofA, 0.0 ), src_glob_centerlon( nDofA, 0.0 );
368 for(
int i = 0; i < srccenter_size; ++i )
370 assert( i < srcID_size );
371 assert( src_gids[i] < nDofA );
373 src_glob_centerlat[src_gids[i]] = src_centerlat[i];
374 src_glob_centerlon[src_gids[i]] = src_centerlon[i];
377 std::vector< double > tgt_centerlat, tgt_centerlon;
379 rval =
get_vartag_data( mbCore, tgtCenterLat, sets, tgtcenter_size, tgt_centerlat );
MB_CHK_SET_ERR( rval,
"Getting source mesh areas failed" );
380 rval =
get_vartag_data( mbCore, tgtCenterLon, sets, tgtcenter_size, tgt_centerlon );
MB_CHK_SET_ERR( rval,
"Getting target mesh areas failed" );
381 std::vector< double > tgt_glob_centerlat( nDofB, 0.0 ), tgt_glob_centerlon( nDofB, 0.0 );
382 for(
int i = 0; i < tgtcenter_size; ++i )
384 assert( i < tgtID_size );
385 assert( tgt_gids[i] < nDofB );
387 tgt_glob_centerlat[tgt_gids[i]] = tgt_centerlat[i];
388 tgt_glob_centerlon[tgt_gids[i]] = tgt_centerlon[i];
391 varYCA->put( &( src_glob_centerlat[0] ), nDofA );
392 varYCB->put( &( tgt_glob_centerlat[0] ), nDofB );
393 varXCA->put( &( src_glob_centerlon[0] ), nDofA );
394 varXCB->put( &( tgt_glob_centerlon[0] ), nDofB );
396 src_centerlat.clear();
397 src_centerlon.clear();
398 tgt_centerlat.clear();
399 tgt_centerlon.clear();
401 DataArray2D< double > src_glob_vertexlat( nDofA, nva ), src_glob_vertexlon( nDofA, nva );
404 std::vector< double > src_vertexlat, src_vertexlon;
406 rval =
get_vartag_data( mbCore, srcVertexLat, sets, srcvertex_size, src_vertexlat );
MB_CHK_SET_ERR( rval,
"Getting source mesh areas failed" );
407 rval =
get_vartag_data( mbCore, srcVertexLon, sets, srcvertex_size, src_vertexlon );
MB_CHK_SET_ERR( rval,
"Getting target mesh areas failed" );
409 for(
unsigned vIndex = 0; vIndex < src_gids.size(); ++vIndex )
411 for(
int vNV = 0; vNV < nva; ++vNV )
413 assert( offset < srcvertex_size );
414 src_glob_vertexlat[src_gids[vIndex]][vNV] = src_vertexlat[offset];
415 src_glob_vertexlon[src_gids[vIndex]][vNV] = src_vertexlon[offset];
421 DataArray2D< double > tgt_glob_vertexlat( nDofB, nvb ), tgt_glob_vertexlon( nDofB, nvb );
424 std::vector< double > tgt_vertexlat, tgt_vertexlon;
426 rval =
get_vartag_data( mbCore, tgtVertexLat, sets, tgtvertex_size, tgt_vertexlat );
MB_CHK_SET_ERR( rval,
"Getting source mesh areas failed" );
427 rval =
get_vartag_data( mbCore, tgtVertexLon, sets, tgtvertex_size, tgt_vertexlon );
MB_CHK_SET_ERR( rval,
"Getting target mesh areas failed" );
429 for(
unsigned vIndex = 0; vIndex < tgt_gids.size(); ++vIndex )
431 for(
int vNV = 0; vNV < nvb; ++vNV )
433 assert( offset < tgtvertex_size );
434 tgt_glob_vertexlat[tgt_gids[vIndex]][vNV] = tgt_vertexlat[offset];
435 tgt_glob_vertexlon[tgt_gids[vIndex]][vNV] = tgt_vertexlon[offset];
441 varYVA->put( &( src_glob_vertexlat[0][0] ), nDofA, nva );
442 varYVB->put( &( tgt_glob_vertexlat[0][0] ), nDofB, nvb );
444 varXVA->put( &( src_glob_vertexlon[0][0] ), nDofA, nva );
445 varXVB->put( &( tgt_glob_vertexlon[0][0] ), nDofB, nvb );
449 NcVar* varAreaA = ncMap.add_var(
"area_a", ncDouble, dimNA );
450 varAreaA->put( &( src_glob_areas[0] ), nDofA );
453 NcVar* varAreaB = ncMap.add_var(
"area_b", ncDouble, dimNB );
454 varAreaB->put( &( tgt_glob_areas[0] ), nDofB );
457 std::vector< int > mat_rows, mat_cols;
458 std::vector< double > mat_vals;
459 int row_sizes, col_sizes, val_sizes;
461 assert( row_sizes == NNZ );
463 assert( col_sizes == NNZ );
465 assert( val_sizes == NNZ );
469 SparseMatrix< double > mapMatrix;
471 for(
int innz = 0; innz < NNZ; ++innz )
474 if( fabs( mapMatrix( mat_rows[innz], mat_cols[innz] ) ) > 1e-12 )
476 printf(
"Adding to existing loc: (%d, %d) = %12.8f\n", mat_rows[innz], mat_cols[innz],
477 mapMatrix( mat_rows[innz], mat_cols[innz] ) );
480 mapMatrix( mat_rows[innz], mat_cols[innz] ) += mat_vals[innz];
484 DataArray1D< int > vecRow;
485 DataArray1D< int > vecCol;
486 DataArray1D< double > vecS;
488 mapMatrix.GetEntries( vecRow, vecCol, vecS );
490 int nS = vecS.GetRows();
498 printf(
"Primary sets: %15zu\n", sets.
size() );
499 printf(
"Original NNZ: %18d\n", NNZ );
500 printf(
"Consolidated Total NNZ: %8d\n", nS );
501 printf(
"Conservative weights ? %6d\n", ( bConserved > 0 ) );
502 printf(
"Monotone weights ? %10d\n", ( bMonotonicity > 0 ) );
504 printf(
"\n--------------------------------------------------------------\n" );
505 printf(
"%20s %21s %15s\n",
"Description",
"Source",
"Target" );
506 printf(
"--------------------------------------------------------------\n" );
508 printf(
"%25s %15d %15d\n",
"Number of elements:", nA, nB );
509 printf(
"%25s %15d %15d\n",
"Number of DoFs:", nDofA, nDofB );
510 printf(
"%25s %15d %15d\n",
"Maximum vertex/element:", nVA, nVB );
511 printf(
"%25s %15s %15s\n",
"Discretization type:", methodA.c_str(), methodB.c_str() );
512 printf(
"%25s %15d %15d\n",
"Discretization order:", nOrdA, nOrdB );
516 DataArray1D< double > dFracA( nDofA );
517 DataArray1D< double > dFracB( nDofB );
519 for(
int i = 0; i < nS; i++ )
523 dFracA[vecCol[i]] += vecS[i] / src_glob_areas[vecCol[i]] * tgt_glob_areas[vecRow[i]];
524 dFracB[vecRow[i]] += vecS[i];
527 NcVar* varFracA = ncMap.add_var(
"frac_a", ncDouble, dimNA );
528 varFracA->put( &( dFracA[0] ), nDofA );
529 varFracA->add_att(
"name",
"fraction of target coverage of source dof" );
530 varFracA->add_att(
"units",
"unitless" );
532 NcVar* varFracB = ncMap.add_var(
"frac_b", ncDouble, dimNB );
533 varFracB->put( &( dFracB[0] ), nDofB );
534 varFracB->add_att(
"name",
"fraction of source coverage of target dof" );
535 varFracB->add_att(
"units",
"unitless" );
539 NcDim* dimNS = ncMap.add_dim(
"n_s", nS );
541 NcVar* varRow = ncMap.add_var(
"row", ncInt, dimNS );
542 varRow->add_att(
"name",
"sparse matrix target dof index" );
543 varRow->add_att(
"first_index",
"1" );
545 NcVar* varCol = ncMap.add_var(
"col", ncInt, dimNS );
546 varCol->add_att(
"name",
"sparse matrix source dof index" );
547 varCol->add_att(
"first_index",
"1" );
549 NcVar* varS = ncMap.add_var(
"S", ncDouble, dimNS );
550 varS->add_att(
"name",
"sparse matrix coefficient" );
553 for(
int i = 0; i < nS; i++ )
559 varRow->set_cur( (
long)0 );
560 varRow->put( &( vecRow[0] ), nS );
562 varCol->set_cur( (
long)0 );
563 varCol->put( &( vecCol[0] ), nS );
565 varS->set_cur( (
long)0 );
566 varS->put( &( vecS[0] ), nS );
572 catch( std::exception& e )
574 std::cout <<
" exception caught during tree initialization " << e.what() << std::endl;