17 #include "FiniteElementTools.h"
21 #ifdef MOAB_HAVE_NETCDF
22 #ifdef MOAB_HAVE_NETCDFPAR
25 #include "netcdfcpp.h"
29 #ifdef MOAB_HAVE_PNETCDF
35 #if defined( MOAB_HAVE_NETCDF ) || defined( MOAB_HAVE_PNETCDF )
39 #define ERR_MBNC( err, msg ) \
42 int _mbrc = ( err ); \
43 if( _mbrc != NC_NOERR ) { _EXCEPTION1( "MBNcDispatch error: %s", msg ); } \
49 #define MPI_CHK_ERR( err ) \
52 std::cout << "MPI Failure. ErrorCode (" << ( err ) << ") "; \
53 std::cout << "\nMPI Aborting... \n"; \
54 return moab::MB_FAILURE; \
57 #ifdef MOAB_HAVE_EIGEN3
60 template <
typename SparseMatrixType >
63 std::ofstream ofs( filename );
66 std::cerr <<
"Failed to open file for writing: " << filename << std::endl;
71 int rows = mat.rows();
72 int cols = mat.cols();
73 typename SparseMatrixType::Index nnz = mat.nonZeros();
74 ofs << rows <<
" " << cols <<
" " << nnz <<
"\n";
77 for(
int k = 0; k < mat.outerSize(); ++k )
79 for(
typename SparseMatrixType::InnerIterator it( mat, k ); it; ++it )
85 auto value = it.value();
86 ofs << row <<
" " << col <<
" " << value <<
"\n";
94 int moab::TempestOnlineMap::rearrange_arrays_by_dofs(
const std::vector< unsigned int >& gdofmap,
95 DataArray1D< double >& vecFaceArea,
96 DataArray1D< double >& dCenterLon,
97 DataArray1D< double >& dCenterLat,
98 DataArray2D< double >& dVertexLon,
99 DataArray2D< double >& dVertexLat,
100 std::vector< int >& masks,
106 unsigned int localmax = 0;
107 for(
unsigned i = 0; i < N; i++ )
108 if( gdofmap[i] > localmax ) localmax = gdofmap[i];
111 MPI_Allreduce( &localmax, &maxdof, 1, MPI_INT, MPI_MAX, m_pcomm->comm() );
114 int size_per_task = ( maxdof + 1 ) / size;
117 unsigned numr = 2 * nv + 3;
122 for(
unsigned i = 0; i < N; i++ )
124 int gdof = gdofmap[i];
125 int to_proc = gdof / size_per_task;
126 int mask = (i >= masks.size() ? 1: masks[i]);
127 if( to_proc >= size ) to_proc = size - 1;
129 tl.
vi_wr[3 * n] = to_proc;
130 tl.
vi_wr[3 * n + 1] = gdof;
131 tl.
vi_wr[3 * n + 2] = mask;
132 tl.
vr_wr[n * numr] = vecFaceArea[i];
133 tl.
vr_wr[n * numr + 1] = dCenterLon[i];
134 tl.
vr_wr[n * numr + 2] = dCenterLat[i];
135 for(
int j = 0; j < nv; j++ )
137 tl.
vr_wr[n * numr + 3 + j] = dVertexLon[i][j];
138 tl.
vr_wr[n * numr + 3 + nv + j] = dVertexLat[i][j];
144 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, tl, 0 );
149 sort_buffer.buffer_init( tl.
get_n() );
150 tl.
sort( 1, &sort_buffer );
153 for(
unsigned i = 0; i < tl.
get_n() - 1; i++ )
155 if( tl.
vi_wr[3 * i + 1] != tl.
vi_wr[3 * i + 4] ) nb_unique++;
157 vecFaceArea.Allocate( nb_unique );
158 dCenterLon.Allocate( nb_unique );
159 dCenterLat.Allocate( nb_unique );
160 dVertexLon.Allocate( nb_unique, nv );
161 dVertexLat.Allocate( nb_unique, nv );
162 masks.resize( nb_unique );
163 int current_size = 1;
164 vecFaceArea[0] = tl.
vr_wr[0];
165 dCenterLon[0] = tl.
vr_wr[1];
166 dCenterLat[0] = tl.
vr_wr[2];
167 masks[0] = tl.
vi_wr[2];
168 for(
int j = 0; j < nv; j++ )
170 dVertexLon[0][j] = tl.
vr_wr[3 + j];
171 dVertexLat[0][j] = tl.
vr_wr[3 + nv + j];
173 for(
unsigned i = 0; i < tl.
get_n() - 1; i++ )
176 if( tl.
vi_wr[3 * i + 1] != tl.
vi_wr[3 * i + 4] )
178 vecFaceArea[current_size] = tl.
vr_wr[i1 * numr];
179 dCenterLon[current_size] = tl.
vr_wr[i1 * numr + 1];
180 dCenterLat[current_size] = tl.
vr_wr[i1 * numr + 2];
181 for(
int j = 0; j < nv; j++ )
183 dVertexLon[current_size][j] = tl.
vr_wr[i1 * numr + 3 + j];
184 dVertexLat[current_size][j] = tl.
vr_wr[i1 * numr + 3 + nv + j];
186 masks[current_size] = tl.
vi_wr[3 * i1 + 2];
191 vecFaceArea[current_size - 1] += tl.
vr_wr[i1 * numr];
203 const std::map< std::string, std::string >& attrMap )
205 size_t lastindex = strFilename.find_last_of(
"." );
206 std::string extension = strFilename.substr( lastindex + 1, strFilename.size() );
209 if( extension ==
"nc" )
211 #if !defined( MOAB_HAVE_NETCDFPAR ) && !defined( MOAB_HAVE_PNETCDF )
216 #if defined( MOAB_HAVE_HDF5 )
219 std::string h5mFilename = strFilename.substr( 0, lastindex ) +
".h5m";
222 std::cout <<
" [WriteParallelMap]: Parallel NetCDF/PnetCDF not available; writing map to "
223 <<
"HDF5 format (" << h5mFilename <<
") instead of SCRIP (.nc)\n";
225 MB_CHK_ERR( this->WriteHDF5MapFile( h5mFilename.c_str() ) );
229 "Parallel SCRIP write requires NETCDFPAR or PnetCDF; HDF5 fallback unavailable" );
234 MB_CHK_ERR( this->WriteSCRIPMapFile( strFilename.c_str(), attrMap ) );
239 MB_CHK_ERR( this->WriteHDF5MapFile( strFilename.c_str() ) );
248 const std::map< std::string, std::string >& attrMap )
250 #if !defined( MOAB_HAVE_NETCDF ) && !defined( MOAB_HAVE_PNETCDF )
251 #error "Cannot enable SCRIP writing without NetCDF or PNetCDF interfaces"
267 DataArray1D< double > vecSourceFaceArea, vecTargetFaceArea;
268 DataArray1D< double > dSourceCenterLon, dSourceCenterLat, dTargetCenterLon, dTargetCenterLat;
269 DataArray2D< double > dSourceVertexLon, dSourceVertexLat, dTargetVertexLon, dTargetVertexLat;
270 if( m_srcDiscType == DiscretizationType_FV || m_srcDiscType == DiscretizationType_PCLOUD )
272 this->InitializeCoordinatesFromMeshFV(
273 *m_meshInput, dSourceCenterLon, dSourceCenterLat, dSourceVertexLon, dSourceVertexLat,
275 m_remapper->max_source_edges );
277 vecSourceFaceArea.Allocate( m_meshInput->vecFaceArea.GetRows() );
278 for(
unsigned i = 0; i < m_meshInput->vecFaceArea.GetRows(); ++i )
279 vecSourceFaceArea[i] = m_meshInput->vecFaceArea[i];
283 DataArray3D< double > dataGLLJacobianSrc;
284 this->InitializeCoordinatesFromMeshFE( *m_meshInput, m_nDofsPEl_Src, dataGLLNodesSrc, dSourceCenterLon,
285 dSourceCenterLat, dSourceVertexLon, dSourceVertexLat );
288 GenerateMetaData( *m_meshInput, m_nDofsPEl_Src,
false , dataGLLNodesSrc, dataGLLJacobianSrc );
290 if( m_srcDiscType == DiscretizationType_CGLL )
292 GenerateUniqueJacobian( dataGLLNodesSrc, dataGLLJacobianSrc, vecSourceFaceArea );
296 GenerateDiscontinuousJacobian( dataGLLJacobianSrc, vecSourceFaceArea );
300 if( m_destDiscType == DiscretizationType_FV || m_destDiscType == DiscretizationType_PCLOUD )
302 this->InitializeCoordinatesFromMeshFV(
303 *m_meshOutput, dTargetCenterLon, dTargetCenterLat, dTargetVertexLon, dTargetVertexLat,
305 m_remapper->max_target_edges );
307 vecTargetFaceArea.Allocate( m_meshOutput->vecFaceArea.GetRows() );
308 for(
unsigned i = 0; i < m_meshOutput->vecFaceArea.GetRows(); ++i )
310 vecTargetFaceArea[i] = m_meshOutput->vecFaceArea[i];
315 DataArray3D< double > dataGLLJacobianDest;
316 this->InitializeCoordinatesFromMeshFE( *m_meshOutput, m_nDofsPEl_Dest, dataGLLNodesDest, dTargetCenterLon,
317 dTargetCenterLat, dTargetVertexLon, dTargetVertexLat );
320 GenerateMetaData( *m_meshOutput, m_nDofsPEl_Dest,
false , dataGLLNodesDest, dataGLLJacobianDest );
322 if( m_destDiscType == DiscretizationType_CGLL )
324 GenerateUniqueJacobian( dataGLLNodesDest, dataGLLJacobianDest, vecTargetFaceArea );
328 GenerateDiscontinuousJacobian( dataGLLJacobianDest, vecTargetFaceArea );
333 unsigned nA = ( vecSourceFaceArea.GetRows() );
334 unsigned nB = ( vecTargetFaceArea.GetRows() );
336 std::vector< int > masksA, masksB;
341 int nSourceNodesPerFace = dSourceVertexLon.GetColumns();
342 int nTargetNodesPerFace = dTargetVertexLon.GetColumns();
348 for(
unsigned i = 0; i < nA; i++ )
350 const Face&
face = m_meshInput->faces[i];
352 int nNodes =
face.edges.size();
353 int indexNodeAtPole = -1;
356 for(
int j = 0; j < nNodes; j++ )
357 if( fabs( fabs( dSourceVertexLat[i][j] ) - 90.0 ) < 1.0e-12 )
363 if( indexNodeAtPole < 0 )
continue;
365 int nodeAtPole =
face[indexNodeAtPole];
366 Node nodePole = m_meshInput->nodes[nodeAtPole];
367 Node newCenter = nodePole * 2;
368 for(
int j = 1; j < nNodes; j++ )
370 int indexi = ( indexNodeAtPole + j ) % nNodes;
371 const Node& node = m_meshInput->nodes[
face[indexi]];
372 newCenter = newCenter + node;
374 newCenter = newCenter * 0.25;
375 newCenter = newCenter.Normalized();
378 double iniLon = dSourceCenterLon[i], iniLat = dSourceCenterLat[i];
381 XYZtoRLL_Deg( newCenter.x, newCenter.y, newCenter.z, dSourceCenterLon[i], dSourceCenterLat[i] );
383 std::cout <<
" modify center of triangle from " << iniLon <<
" " << iniLat <<
" to " << dSourceCenterLon[i]
384 <<
" " << dSourceCenterLat[i] <<
"\n";
389 #if defined( MOAB_HAVE_MPI )
390 int max_row_dof, max_col_dof;
393 int ierr = rearrange_arrays_by_dofs( srccol_gdofmap, vecSourceFaceArea, dSourceCenterLon, dSourceCenterLat,
394 dSourceVertexLon, dSourceVertexLat, masksA, nA, nSourceNodesPerFace,
398 _EXCEPTION1(
"Unable to arrange source data %d ", nA );
402 ierr = rearrange_arrays_by_dofs( row_gdofmap, vecTargetFaceArea, dTargetCenterLon, dTargetCenterLat,
403 dTargetVertexLon, dTargetVertexLat, masksB, nB, nTargetNodesPerFace,
407 _EXCEPTION1(
"Unable to arrange target data %d ", nB );
413 int nS = m_weightMatrix.nonZeros();
415 #if defined( MOAB_HAVE_MPI )
416 int locbuf[5] = { (int)nA, (
int)nB, nS, nSourceNodesPerFace, nTargetNodesPerFace };
417 int offbuf[3] = { 0, 0, 0 };
418 int globuf[5] = { 0, 0, 0, 0, 0 };
419 MPI_Scan( locbuf, offbuf, 3, MPI_INT, MPI_SUM, m_pcomm->comm() );
420 MPI_Allreduce( locbuf, globuf, 3, MPI_INT, MPI_SUM, m_pcomm->comm() );
421 MPI_Allreduce( &locbuf[3], &globuf[3], 2, MPI_INT, MPI_MAX, m_pcomm->comm() );
429 int offbuf[3] = { 0, 0, 0 };
430 int globuf[5] = { (int)nA, (
int)nB, nS, nSourceNodesPerFace, nTargetNodesPerFace };
433 std::vector< std::string > srcdimNames, tgtdimNames;
434 std::vector< int > srcdimSizes, tgtdimSizes;
438 srcdimNames.push_back(
"lat" );
439 srcdimNames.push_back(
"lon" );
440 srcdimSizes.resize( 2, 0 );
441 srcdimSizes[0] = m_remapper->m_source_metadata[0];
442 srcdimSizes[1] = m_remapper->m_source_metadata[1];
446 srcdimNames.push_back(
"num_elem" );
447 srcdimSizes.push_back( globuf[0] );
452 tgtdimNames.push_back(
"lat" );
453 tgtdimNames.push_back(
"lon" );
454 tgtdimSizes.resize( 2, 0 );
455 tgtdimSizes[0] = m_remapper->m_target_metadata[0];
456 tgtdimSizes[1] = m_remapper->m_target_metadata[1];
460 tgtdimNames.push_back(
"num_elem" );
461 tgtdimSizes.push_back( globuf[1] );
466 unsigned nSrcGridDims = ( srcdimSizes.size() );
467 unsigned nDstGridDims = ( tgtdimSizes.size() );
471 DataArray1D< int > vecRow( nS );
472 DataArray1D< int > vecCol( nS );
473 DataArray1D< double > vecS( nS );
474 DataArray1D< double > dFracA( nA );
475 DataArray1D< double > dFracB( nB );
491 #if defined( MOAB_HAVE_MPI )
492 int nAbase = ( max_col_dof + 1 ) / size;
493 int nBbase = ( max_row_dof + 1 ) / size;
495 for(
int i = 0; i < m_weightMatrix.outerSize(); ++i )
497 for( WeightMatrix::InnerIterator it( m_weightMatrix, i ); it; ++it )
499 vecRow[offset] = 1 + this->GetRowGlobalDoF( it.row() );
500 vecCol[offset] = 1 + this->GetColGlobalDoF( it.col() );
501 vecS[offset] = it.value();
503 #if defined( MOAB_HAVE_MPI )
506 int procRow = ( vecRow[offset] - 1 ) / nBbase;
507 if( procRow >= size ) procRow = size - 1;
508 int procCol = ( vecCol[offset] - 1 ) / nAbase;
509 if( procCol >= size ) procCol = size - 1;
510 int nrInd = tlValRow.
get_n();
511 tlValRow.
vi_wr[2 * nrInd] = procRow;
512 tlValRow.
vi_wr[2 * nrInd + 1] = vecRow[offset] - 1;
513 tlValRow.
vr_wr[nrInd] = vecS[offset];
515 int ncInd = tlValCol.
get_n();
516 tlValCol.
vi_wr[3 * ncInd] = procCol;
517 tlValCol.
vi_wr[3 * ncInd + 1] = vecRow[offset] - 1;
518 tlValCol.
vi_wr[3 * ncInd + 2] = vecCol[offset] - 1;
519 tlValCol.
vr_wr[ncInd] = vecS[offset];
527 #if defined( MOAB_HAVE_MPI )
530 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, tlValCol, 0 );
531 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, tlValRow, 0 );
537 for(
unsigned i = 0; i < tlValRow.
get_n(); i++ )
540 int gRowInd = tlValRow.
vi_wr[2 * i + 1];
541 int localIndexRow = gRowInd - nBbase * rank;
542 double wgt = tlValRow.
vr_wr[i];
543 assert( localIndexRow >= 0 );
544 assert( nB - localIndexRow > 0 );
545 dFracB[localIndexRow] += wgt;
549 std::set< int > neededRows;
550 for(
unsigned i = 0; i < tlValCol.
get_n(); i++ )
552 int rRowInd = tlValCol.
vi_wr[3 * i + 1];
553 neededRows.insert( rRowInd );
557 tgtAreaReq.
initialize( 2, 0, 0, 0, neededRows.size() );
559 for( std::set< int >::iterator sit = neededRows.begin(); sit != neededRows.end(); ++sit )
561 int neededRow = *sit;
562 int procRow = neededRow / nBbase;
563 if( procRow >= size ) procRow = size - 1;
564 int nr = tgtAreaReq.
get_n();
565 tgtAreaReq.
vi_wr[2 * nr] = procRow;
566 tgtAreaReq.
vi_wr[2 * nr + 1] = neededRow;
570 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, tgtAreaReq, 0 );
575 for(
unsigned i = 0; i < tgtAreaReq.
get_n(); i++ )
577 int from_proc = tgtAreaReq.
vi_wr[2 * i];
578 int row = tgtAreaReq.
vi_wr[2 * i + 1];
579 int locaIndexRow = row - rank * nBbase;
580 double areaToSend = vecTargetFaceArea[locaIndexRow];
583 tgtAreaInfo.
vi_wr[2 * i] = from_proc;
584 tgtAreaInfo.
vi_wr[2 * i + 1] = row;
585 tgtAreaInfo.
vr_wr[i] = areaToSend;
588 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, tgtAreaInfo, 0 );
590 std::map< int, double > areaAtRow;
591 for(
unsigned i = 0; i < tgtAreaInfo.
get_n(); i++ )
594 int row = tgtAreaInfo.
vi_wr[2 * i + 1];
595 areaAtRow[row] = tgtAreaInfo.
vr_wr[i];
603 for(
unsigned i = 0; i < tlValCol.
get_n(); i++ )
605 int rRowInd = tlValCol.
vi_wr[3 * i + 1];
606 int colInd = tlValCol.
vi_wr[3 * i + 2];
607 double val = tlValCol.
vr_wr[i];
608 int localColInd = colInd - rank * nAbase;
610 auto itMap = areaAtRow.find( rRowInd );
611 if( itMap != areaAtRow.end() )
613 double areaRow = itMap->second;
614 dFracA[localColInd] += val / vecSourceFaceArea[localColInd] * areaRow;
628 _EXCEPTION1(
"No NetCDF backend available to write SCRIP map \"%s\"", strFilename.c_str() );
631 const int cmode = NC_CLOBBER | NC_64BIT_DATA;
633 ERR_MBNC( mbnc_create_par( wbackend, m_pcomm->comm(), MPI_INFO_NULL, strFilename.c_str(), cmode, &ncid ),
636 ERR_MBNC(
mbnc_create( strFilename.c_str(), cmode, &ncid ),
"create map file" );
640 for( std::map< std::string, std::string >::const_iterator ait = attrMap.begin(); ait != attrMap.end();
642 ERR_MBNC(
mbnc_put_att_text( ncid, NC_GLOBAL, ait->first.c_str(), ait->second.size(), ait->second.c_str() ),
643 "global attribute" );
646 int dimSrcRank, dimDstRank, dimNAp, dimNBp, dimNVAp, dimNVBp, dimNSp;
647 ERR_MBNC(
mbnc_def_dim( ncid,
"src_grid_rank", nSrcGridDims, &dimSrcRank ),
"def src_grid_rank" );
648 ERR_MBNC(
mbnc_def_dim( ncid,
"dst_grid_rank", nDstGridDims, &dimDstRank ),
"def dst_grid_rank" );
649 ERR_MBNC(
mbnc_def_dim( ncid,
"n_a", (
size_t)globuf[0], &dimNAp ),
"def n_a" );
650 ERR_MBNC(
mbnc_def_dim( ncid,
"n_b", (
size_t)globuf[1], &dimNBp ),
"def n_b" );
651 ERR_MBNC(
mbnc_def_dim( ncid,
"nv_a", (
size_t)globuf[3], &dimNVAp ),
"def nv_a" );
652 ERR_MBNC(
mbnc_def_dim( ncid,
"nv_b", (
size_t)globuf[4], &dimNVBp ),
"def nv_b" );
653 ERR_MBNC(
mbnc_def_dim( ncid,
"n_s", (
size_t)globuf[2], &dimNSp ),
"def n_s" );
656 int vSrcGridDims, vDstGridDims, vYCA, vYCB, vXCA, vXCB, vYVA, vYVB, vXVA, vXVB, vMaskA, vMaskB, vAreaA, vAreaB,
657 vRow, vCol, vS, vFracA, vFracB;
660 ERR_MBNC(
mbnc_def_var( ncid,
"src_grid_dims", NC_INT, 1, d1, &vSrcGridDims ),
"def src_grid_dims" );
662 ERR_MBNC(
mbnc_def_var( ncid,
"dst_grid_dims", NC_INT, 1, d1, &vDstGridDims ),
"def dst_grid_dims" );
664 ERR_MBNC(
mbnc_def_var( ncid,
"yc_a", NC_DOUBLE, 1, d1, &vYCA ),
"def yc_a" );
665 ERR_MBNC(
mbnc_def_var( ncid,
"xc_a", NC_DOUBLE, 1, d1, &vXCA ),
"def xc_a" );
666 ERR_MBNC(
mbnc_def_var( ncid,
"mask_a", NC_INT, 1, d1, &vMaskA ),
"def mask_a" );
667 ERR_MBNC(
mbnc_def_var( ncid,
"area_a", NC_DOUBLE, 1, d1, &vAreaA ),
"def area_a" );
668 ERR_MBNC(
mbnc_def_var( ncid,
"frac_a", NC_DOUBLE, 1, d1, &vFracA ),
"def frac_a" );
670 ERR_MBNC(
mbnc_def_var( ncid,
"yc_b", NC_DOUBLE, 1, d1, &vYCB ),
"def yc_b" );
671 ERR_MBNC(
mbnc_def_var( ncid,
"xc_b", NC_DOUBLE, 1, d1, &vXCB ),
"def xc_b" );
672 ERR_MBNC(
mbnc_def_var( ncid,
"mask_b", NC_INT, 1, d1, &vMaskB ),
"def mask_b" );
673 ERR_MBNC(
mbnc_def_var( ncid,
"area_b", NC_DOUBLE, 1, d1, &vAreaB ),
"def area_b" );
674 ERR_MBNC(
mbnc_def_var( ncid,
"frac_b", NC_DOUBLE, 1, d1, &vFracB ),
"def frac_b" );
677 ERR_MBNC(
mbnc_def_var( ncid,
"yv_a", NC_DOUBLE, 2, d2, &vYVA ),
"def yv_a" );
678 ERR_MBNC(
mbnc_def_var( ncid,
"xv_a", NC_DOUBLE, 2, d2, &vXVA ),
"def xv_a" );
681 ERR_MBNC(
mbnc_def_var( ncid,
"yv_b", NC_DOUBLE, 2, d2, &vYVB ),
"def yv_b" );
682 ERR_MBNC(
mbnc_def_var( ncid,
"xv_b", NC_DOUBLE, 2, d2, &vXVB ),
"def xv_b" );
684 ERR_MBNC(
mbnc_def_var( ncid,
"row", NC_INT, 1, d1, &vRow ),
"def row" );
685 ERR_MBNC(
mbnc_def_var( ncid,
"col", NC_INT, 1, d1, &vCol ),
"def col" );
686 ERR_MBNC(
mbnc_def_var( ncid,
"S", NC_DOUBLE, 1, d1, &vS ),
"def S" );
691 for(
unsigned i = 0; i < srcdimSizes.size(); i++ )
693 snprintf( szDim, 64,
"name%u", i );
694 const std::string& nm = srcdimNames[nSrcGridDims - i - 1];
695 ERR_MBNC(
mbnc_put_att_text( ncid, vSrcGridDims, szDim, nm.size(), nm.c_str() ),
"src_grid_dims name" );
697 for(
unsigned i = 0; i < tgtdimSizes.size(); i++ )
699 snprintf( szDim, 64,
"name%u", i );
700 const std::string& nm = tgtdimNames[nDstGridDims - i - 1];
701 ERR_MBNC(
mbnc_put_att_text( ncid, vDstGridDims, szDim, nm.size(), nm.c_str() ),
"dst_grid_dims name" );
703 const std::string deg(
"degrees" );
704 const int vdeg[8] = { vYCA, vYCB, vXCA, vXCB, vYVA, vYVB, vXVA, vXVB };
705 for(
int k = 0; k < 8; k++ )
706 ERR_MBNC(
mbnc_put_att_text( ncid, vdeg[k],
"units", deg.size(), deg.c_str() ),
"units" );
707 const std::string faName(
"fraction of target coverage of source dof" );
708 const std::string fbName(
"fraction of source coverage of target dof" );
709 const std::string unitless(
"unitless" );
710 ERR_MBNC(
mbnc_put_att_text( ncid, vFracA,
"name", faName.size(), faName.c_str() ),
"frac_a name" );
711 ERR_MBNC(
mbnc_put_att_text( ncid, vFracA,
"units", unitless.size(), unitless.c_str() ),
"frac_a units" );
712 ERR_MBNC(
mbnc_put_att_text( ncid, vFracB,
"name", fbName.size(), fbName.c_str() ),
"frac_b name" );
713 ERR_MBNC(
mbnc_put_att_text( ncid, vFracB,
"units", unitless.size(), unitless.c_str() ),
"frac_b units" );
719 size_t sA = (size_t)offbuf[0], cA = (
size_t)nA;
720 size_t sB = (size_t)offbuf[1], cB = (
size_t)nB;
721 size_t sS = (size_t)offbuf[2], cS = (
size_t)nS;
722 double* pYCA = ( nA > 0 ) ? &dSourceCenterLat[0] : NULL;
723 double* pXCA = ( nA > 0 ) ? &dSourceCenterLon[0] : NULL;
724 double* pYCB = ( nB > 0 ) ? &dTargetCenterLat[0] : NULL;
725 double* pXCB = ( nB > 0 ) ? &dTargetCenterLon[0] : NULL;
726 int* pMaskA = ( nA > 0 ) ? &masksA[0] : NULL;
727 int* pMaskB = ( nB > 0 ) ? &masksB[0] : NULL;
728 double* pAreaA = ( nA > 0 ) ? &vecSourceFaceArea[0] : NULL;
729 double* pAreaB = ( nB > 0 ) ? &vecTargetFaceArea[0] : NULL;
730 double* pFracA = ( nA > 0 ) ? &dFracA[0] : NULL;
731 double* pFracB = ( nB > 0 ) ? &dFracB[0] : NULL;
732 int* pRow = ( nS > 0 ) ? &vecRow[0] : NULL;
733 int* pCol = ( nS > 0 ) ? &vecCol[0] : NULL;
734 double* pS = ( nS > 0 ) ? &vecS[0] : NULL;
750 size_t s2A[2] = { (size_t)offbuf[0], 0 }, c2A[2] = { (size_t)nA, (
size_t)nSourceNodesPerFace };
751 double* pYVA = ( nA > 0 ) ? &dSourceVertexLat[0][0] : NULL;
752 double* pXVA = ( nA > 0 ) ? &dSourceVertexLon[0][0] : NULL;
755 size_t s2B[2] = { (size_t)offbuf[1], 0 }, c2B[2] = { (size_t)nB, (
size_t)nTargetNodesPerFace };
756 double* pYVB = ( nB > 0 ) ? &dTargetVertexLat[0][0] : NULL;
757 double* pXVB = ( nB > 0 ) ? &dTargetVertexLon[0][0] : NULL;
764 size_t cgSrc = ( rank == 0 ) ? (
size_t)nSrcGridDims : 0;
765 size_t cgDst = ( rank == 0 ) ? (
size_t)nDstGridDims : 0;
766 ERR_MBNC(
mbnc_put_vara_int( ncid, vSrcGridDims, &sg, &cgSrc, ( rank == 0 ) ? &srcdimSizes[0] : NULL ),
767 "put src_grid_dims" );
768 ERR_MBNC(
mbnc_put_vara_int( ncid, vDstGridDims, &sg, &cgDst, ( rank == 0 ) ? &tgtdimSizes[0] : NULL ),
769 "put dst_grid_dims" );
778 serializeSparseMatrix( m_weightMatrix,
"map_operator_" + std::to_string( rank ) +
".txt" );
796 DataArray1D< double > vecSourceFaceArea, vecTargetFaceArea;
797 DataArray1D< double > dSourceCenterLon, dSourceCenterLat, dTargetCenterLon, dTargetCenterLat;
798 DataArray2D< double > dSourceVertexLon, dSourceVertexLat, dTargetVertexLon, dTargetVertexLat;
799 if( m_srcDiscType == DiscretizationType_FV || m_srcDiscType == DiscretizationType_PCLOUD )
801 this->InitializeCoordinatesFromMeshFV(
802 *m_meshInput, dSourceCenterLon, dSourceCenterLat, dSourceVertexLon, dSourceVertexLat,
804 m_remapper->max_source_edges );
806 vecSourceFaceArea.Allocate( m_meshInput->vecFaceArea.GetRows() );
807 for(
unsigned i = 0; i < m_meshInput->vecFaceArea.GetRows(); ++i )
808 vecSourceFaceArea[i] = m_meshInput->vecFaceArea[i];
812 DataArray3D< double > dataGLLJacobianSrc;
813 this->InitializeCoordinatesFromMeshFE( *m_meshInput, m_nDofsPEl_Src, dataGLLNodesSrc, dSourceCenterLon,
814 dSourceCenterLat, dSourceVertexLon, dSourceVertexLat );
817 GenerateMetaData( *m_meshInput, m_nDofsPEl_Src,
false , dataGLLNodesSrc, dataGLLJacobianSrc );
819 if( m_srcDiscType == DiscretizationType_CGLL )
821 GenerateUniqueJacobian( dataGLLNodesSrc, dataGLLJacobianSrc, vecSourceFaceArea );
825 GenerateDiscontinuousJacobian( dataGLLJacobianSrc, vecSourceFaceArea );
829 if( m_destDiscType == DiscretizationType_FV || m_destDiscType == DiscretizationType_PCLOUD )
831 this->InitializeCoordinatesFromMeshFV(
832 *m_meshOutput, dTargetCenterLon, dTargetCenterLat, dTargetVertexLon, dTargetVertexLat,
834 m_remapper->max_target_edges );
836 vecTargetFaceArea.Allocate( m_meshOutput->vecFaceArea.GetRows() );
837 for(
unsigned i = 0; i < m_meshOutput->vecFaceArea.GetRows(); ++i )
838 vecTargetFaceArea[i] = m_meshOutput->vecFaceArea[i];
842 DataArray3D< double > dataGLLJacobianDest;
843 this->InitializeCoordinatesFromMeshFE( *m_meshOutput, m_nDofsPEl_Dest, dataGLLNodesDest, dTargetCenterLon,
844 dTargetCenterLat, dTargetVertexLon, dTargetVertexLat );
847 GenerateMetaData( *m_meshOutput, m_nDofsPEl_Dest,
false , dataGLLNodesDest, dataGLLJacobianDest );
849 if( m_destDiscType == DiscretizationType_CGLL )
851 GenerateUniqueJacobian( dataGLLNodesDest, dataGLLJacobianDest, vecTargetFaceArea );
855 GenerateDiscontinuousJacobian( dataGLLJacobianDest, vecTargetFaceArea );
860 int tot_src_ents = m_remapper->m_source_entities.size();
861 int tot_tgt_ents = m_remapper->m_target_entities.size();
862 int tot_src_size = dSourceCenterLon.GetRows();
863 int tot_tgt_size = m_dTargetCenterLon.GetRows();
864 int tot_vsrc_size = dSourceVertexLon.GetRows() * dSourceVertexLon.GetColumns();
865 int tot_vtgt_size = m_dTargetVertexLon.GetRows() * m_dTargetVertexLon.GetColumns();
867 const int weightMatNNZ = m_weightMatrix.nonZeros();
868 moab::Tag tagMapMetaData, tagMapIndexRow, tagMapIndexCol, tagMapValues, srcEleIDs, tgtEleIDs;
871 "Retrieving tag handles failed" );
874 "Retrieving tag handles failed" );
877 "Retrieving tag handles failed" );
880 "Retrieving tag handles failed" );
883 "Retrieving tag handles failed" );
886 "Retrieving tag handles failed" );
890 "Retrieving tag handles failed" );
893 "Retrieving tag handles failed" );
894 moab::Tag tagSrcCoordsCLon, tagSrcCoordsCLat, tagTgtCoordsCLon, tagTgtCoordsCLat;
898 "Retrieving tag handles failed" );
902 "Retrieving tag handles failed" );
906 "Retrieving tag handles failed" );
910 "Retrieving tag handles failed" );
911 moab::Tag tagSrcCoordsVLon, tagSrcCoordsVLat, tagTgtCoordsVLon, tagTgtCoordsVLat;
915 "Retrieving tag handles failed" );
919 "Retrieving tag handles failed" );
923 "Retrieving tag handles failed" );
927 "Retrieving tag handles failed" );
929 if( m_iSourceMask.IsAttached() )
934 "Retrieving tag handles failed" );
936 if( m_iTargetMask.IsAttached() )
941 "Retrieving tag handles failed" );
944 std::vector< int > smatrowvals( weightMatNNZ ), smatcolvals( weightMatNNZ );
945 std::vector< double > smatvals( weightMatNNZ );
948 for(
int k = 0, offset = 0; k < m_weightMatrix.outerSize(); ++k )
950 for( moab::TempestOnlineMap::WeightMatrix::InnerIterator it( m_weightMatrix, k ); it; ++it, ++offset )
952 smatrowvals[offset] = this->GetRowGlobalDoF( it.row() );
953 smatcolvals[offset] = this->GetColGlobalDoF( it.col() );
954 smatvals[offset] = it.value();
963 int maxrow = 0, maxcol = 0;
964 std::vector< int > src_global_dofs( tot_src_size ), tgt_global_dofs( tot_tgt_size );
965 for(
int i = 0; i < tot_src_size; ++i )
967 src_global_dofs[i] = srccol_gdofmap[i];
968 maxcol = ( src_global_dofs[i] > maxcol ) ? src_global_dofs[i] : maxcol;
971 for(
int i = 0; i < tot_tgt_size; ++i )
973 tgt_global_dofs[i] = row_gdofmap[i];
974 maxrow = ( tgt_global_dofs[i] > maxrow ) ? tgt_global_dofs[i] : maxrow;
999 int map_disc_details[6];
1000 map_disc_details[0] = m_nDofsPEl_Src;
1001 map_disc_details[1] = m_nDofsPEl_Dest;
1002 map_disc_details[2] = ( m_srcDiscType == DiscretizationType_FV || m_srcDiscType == DiscretizationType_PCLOUD
1004 : ( m_srcDiscType == DiscretizationType_CGLL ? 1 : 2 ) );
1005 map_disc_details[3] = ( m_destDiscType == DiscretizationType_FV || m_destDiscType == DiscretizationType_PCLOUD
1007 : ( m_destDiscType == DiscretizationType_CGLL ? 1 : 2 ) );
1008 map_disc_details[4] = ( m_bConserved ? 1 : 0 );
1009 map_disc_details[5] = m_iMonotonicity;
1011 #ifdef MOAB_HAVE_MPI
1012 int loc_smatmetadata[13] = { tot_src_ents,
1014 m_remapper->max_source_edges,
1015 m_remapper->max_target_edges,
1019 map_disc_details[0],
1020 map_disc_details[1],
1021 map_disc_details[2],
1022 map_disc_details[3],
1023 map_disc_details[4],
1024 map_disc_details[5] };
1025 MB_CHK_SET_ERR( m_interface->tag_set_data( tagMapMetaData, &m_meshOverlapSet, 1, &loc_smatmetadata[0] ),
1026 "Setting local tag data failed" );
1027 int glb_smatmetadata[13] = { 0,
1034 map_disc_details[0],
1035 map_disc_details[1],
1036 map_disc_details[2],
1037 map_disc_details[3],
1038 map_disc_details[4],
1039 map_disc_details[5] };
1041 tot_src_ents, tot_tgt_ents, weightMatNNZ, m_remapper->max_source_edges, m_remapper->max_target_edges,
1043 int glb_buf[4] = { 0, 0, 0, 0 };
1044 MPI_Reduce( &loc_buf[0], &glb_buf[0], 3, MPI_INT, MPI_SUM, 0, m_pcomm->comm() );
1045 glb_smatmetadata[0] = glb_buf[0];
1046 glb_smatmetadata[1] = glb_buf[1];
1047 glb_smatmetadata[6] = glb_buf[2];
1048 MPI_Reduce( &loc_buf[3], &glb_buf[0], 4, MPI_INT, MPI_MAX, 0, m_pcomm->comm() );
1049 glb_smatmetadata[2] = glb_buf[0];
1050 glb_smatmetadata[3] = glb_buf[1];
1051 glb_smatmetadata[4] = glb_buf[2];
1052 glb_smatmetadata[5] = glb_buf[3];
1054 int glb_smatmetadata[13] = { tot_src_ents,
1056 m_remapper->max_source_edges,
1057 m_remapper->max_target_edges,
1061 map_disc_details[0],
1062 map_disc_details[1],
1063 map_disc_details[2],
1064 map_disc_details[3],
1065 map_disc_details[4],
1066 map_disc_details[5] };
1069 glb_smatmetadata[4]++;
1070 glb_smatmetadata[5]++;
1074 std::cout <<
" " << this->rank <<
" Writing remap weights with size [" << glb_smatmetadata[4] <<
" X "
1075 << glb_smatmetadata[5] <<
"] and NNZ = " << glb_smatmetadata[6] << std::endl;
1077 MB_CHK_SET_ERR( m_interface->tag_set_data( tagMapMetaData, &root_set, 1, &glb_smatmetadata[0] ),
1078 "Setting local tag data failed" );
1082 const int numval = weightMatNNZ;
1083 const void* smatrowvals_d = smatrowvals.data();
1084 const void* smatcolvals_d = smatcolvals.data();
1085 const void* smatvals_d = smatvals.data();
1086 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tagMapIndexRow, &m_meshOverlapSet, 1, &smatrowvals_d, &numval ),
1087 "Setting local tag data failed" );
1088 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tagMapIndexCol, &m_meshOverlapSet, 1, &smatcolvals_d, &numval ),
1089 "Setting local tag data failed" );
1090 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tagMapValues, &m_meshOverlapSet, 1, &smatvals_d, &numval ),
1091 "Setting local tag data failed" );
1094 const void* srceleidvals_d = src_global_dofs.data();
1095 const void* tgteleidvals_d = tgt_global_dofs.data();
1096 dsize = src_global_dofs.size();
1097 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( srcEleIDs, &m_meshOverlapSet, 1, &srceleidvals_d, &dsize ),
1098 "Setting local tag data failed" );
1099 dsize = tgt_global_dofs.size();
1100 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tgtEleIDs, &m_meshOverlapSet, 1, &tgteleidvals_d, &dsize ),
1101 "Setting local tag data failed" );
1104 const void* srcareavals_d = vecSourceFaceArea;
1105 const void* tgtareavals_d = vecTargetFaceArea;
1106 dsize = tot_src_size;
1107 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( srcAreaValues, &m_meshOverlapSet, 1, &srcareavals_d, &dsize ),
1108 "Setting local tag data failed" );
1109 dsize = tot_tgt_size;
1110 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tgtAreaValues, &m_meshOverlapSet, 1, &tgtareavals_d, &dsize ),
1111 "Setting local tag data failed" );
1114 const void* srccoordsclonvals_d = &dSourceCenterLon[0];
1115 const void* srccoordsclatvals_d = &dSourceCenterLat[0];
1116 dsize = dSourceCenterLon.GetRows();
1117 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tagSrcCoordsCLon, &m_meshOverlapSet, 1, &srccoordsclonvals_d, &dsize ),
1118 "Setting local tag data failed" );
1119 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tagSrcCoordsCLat, &m_meshOverlapSet, 1, &srccoordsclatvals_d, &dsize ),
1120 "Setting local tag data failed" );
1121 const void* tgtcoordsclonvals_d = &m_dTargetCenterLon[0];
1122 const void* tgtcoordsclatvals_d = &m_dTargetCenterLat[0];
1123 dsize = vecTargetFaceArea.GetRows();
1124 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tagTgtCoordsCLon, &m_meshOverlapSet, 1, &tgtcoordsclonvals_d, &dsize ),
1125 "Setting local tag data failed" );
1126 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tagTgtCoordsCLat, &m_meshOverlapSet, 1, &tgtcoordsclatvals_d, &dsize ),
1127 "Setting local tag data failed" );
1130 const void* srccoordsvlonvals_d = &( dSourceVertexLon[0][0] );
1131 const void* srccoordsvlatvals_d = &( dSourceVertexLat[0][0] );
1132 dsize = dSourceVertexLon.GetRows() * dSourceVertexLon.GetColumns();
1133 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tagSrcCoordsVLon, &m_meshOverlapSet, 1, &srccoordsvlonvals_d, &dsize ),
1134 "Setting local tag data failed" );
1135 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tagSrcCoordsVLat, &m_meshOverlapSet, 1, &srccoordsvlatvals_d, &dsize ),
1136 "Setting local tag data failed" );
1137 const void* tgtcoordsvlonvals_d = &( m_dTargetVertexLon[0][0] );
1138 const void* tgtcoordsvlatvals_d = &( m_dTargetVertexLat[0][0] );
1139 dsize = m_dTargetVertexLon.GetRows() * m_dTargetVertexLon.GetColumns();
1140 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tagTgtCoordsVLon, &m_meshOverlapSet, 1, &tgtcoordsvlonvals_d, &dsize ),
1141 "Setting local tag data failed" );
1142 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tagTgtCoordsVLat, &m_meshOverlapSet, 1, &tgtcoordsvlatvals_d, &dsize ),
1143 "Setting local tag data failed" );
1146 if( m_iSourceMask.IsAttached() )
1148 const void* srcmaskvals_d = m_iSourceMask;
1149 dsize = m_iSourceMask.GetRows();
1150 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( srcMaskValues, &m_meshOverlapSet, 1, &srcmaskvals_d, &dsize ),
1151 "Setting local tag data failed" );
1154 if( m_iTargetMask.IsAttached() )
1156 const void* tgtmaskvals_d = m_iTargetMask;
1157 dsize = m_iTargetMask.GetRows();
1158 MB_CHK_SET_ERR( m_interface->tag_set_by_ptr( tgtMaskValues, &m_meshOverlapSet, 1, &tgtmaskvals_d, &dsize ),
1159 "Setting local tag data failed" );
1162 #ifdef MOAB_HAVE_MPI
1163 const char* writeOptions = ( this->size > 1 ?
"PARALLEL=WRITE_PART" :
"" );
1165 const char* writeOptions =
"";
1170 MB_CHK_ERR( m_interface->write_file( strOutputFile.c_str(), NULL, writeOptions, sets, 1 ) );
1172 #ifdef WRITE_SCRIP_FILE
1174 sstr << ctx.outFilename.substr( 0, lastindex ) <<
"_" << proc_id <<
".nc";
1175 std::map< std::string, std::string > mapAttributes;
1176 mapAttributes[
"Creator"] =
"MOAB mbtempest workflow";
1177 if( !ctx.proc_id ) std::cout <<
"Writing offline map to file: " << sstr.str() << std::endl;
1178 this->Write( strOutputFile.c_str(), mapAttributes, NcFile::Netcdf4 );
1198 const std::vector< int >& owned_dof_ids,
1200 std::vector< double >& vecAreaA,
1202 std::vector< double >& vecAreaB,
1205 #if !defined( MOAB_HAVE_NETCDF ) && !defined( MOAB_HAVE_PNETCDF )
1206 #error "Cannot enable SCRIP reading without NetCDF or PNetCDF interfaces"
1209 const bool readAreaA = ( 1 == arearead || 3 == arearead );
1210 const bool readAreaB = ( 2 == arearead || 3 == arearead );
1223 std::vector< int > vecRow, vecCol;
1224 std::vector< double > vecS;
1234 #ifdef MOAB_HAVE_MPI
1236 MPI_Bcast( &fileFormat, 1, MPI_INT, 0, m_pcomm->comm() );
1242 _EXCEPTION1(
"Cannot read map file \"%s\": unrecognized format, or NetCDF-4/HDF5 without libnetcdf",
1246 #ifdef MOAB_HAVE_MPI
1247 ERR_MBNC( mbnc_open_par( rbackend, m_pcomm->comm(), MPI_INFO_NULL, strSource, 0, &ncid ),
"open map" );
1249 ERR_MBNC(
mbnc_open( strSource, 0, &ncid ),
"open map" );
1265 localSize = nS / size;
1266 size_t offsetRead = (size_t)rank * (
size_t)localSize;
1267 if( rank == size - 1 ) localSize += nS % size;
1268 int localSizeA = nA / size;
1269 size_t offsetReadA = (size_t)rank * (
size_t)localSizeA;
1270 if( rank == size - 1 ) localSizeA += nA % size;
1271 int localSizeB = nB / size;
1272 size_t offsetReadB = (size_t)rank * (
size_t)localSizeB;
1273 if( rank == size - 1 ) localSizeB += nB % size;
1275 vecRow.resize( localSize );
1276 vecCol.resize( localSize );
1277 vecS.resize( localSize );
1280 size_t st = offsetRead,
ct = (size_t)localSize;
1282 ERR_MBNC(
mbnc_get_vara_int( ncid, vid, &st, &
ct, localSize ? vecRow.data() : NULL ),
"get row" );
1284 ERR_MBNC(
mbnc_get_vara_int( ncid, vid, &st, &
ct, localSize ? vecCol.data() : NULL ),
"get col" );
1290 vecAreaA.resize( localSizeA );
1291 size_t sa = offsetReadA, ca = (size_t)localSizeA;
1292 ERR_MBNC(
mbnc_inq_varid( ncid,
"area_a", &vid ),
"inq area_a" );
1293 ERR_MBNC(
mbnc_get_vara_double( ncid, vid, &sa, &ca, localSizeA ? vecAreaA.data() : NULL ),
"get area_a" );
1297 vecAreaB.resize( localSizeB );
1298 size_t sb = offsetReadB, cb = (size_t)localSizeB;
1299 ERR_MBNC(
mbnc_inq_varid( ncid,
"area_b", &vid ),
"inq area_b" );
1300 ERR_MBNC(
mbnc_get_vara_double( ncid, vid, &sb, &cb, localSizeB ? vecAreaB.data() : NULL ),
"get area_b" );
1318 #ifdef MOAB_HAVE_EIGEN3
1320 typedef Eigen::Triplet< double >
Triplet;
1321 std::vector< Triplet > tripletList;
1323 #ifdef MOAB_HAVE_MPI
1327 const int nPerPart = nB / size;
1334 for(
int i = 0; i < localSize; i++ )
1336 int rowval = vecRow[i] - 1;
1337 int colval = vecCol[i] - 1;
1338 int to_proc = rowval / nPerPart;
1339 if( to_proc >= size ) to_proc = size - 1;
1341 int n = tl->
get_n();
1342 tl->
vi_wr[3 * n] = to_proc;
1343 tl->
vi_wr[3 * n + 1] = rowval;
1344 tl->
vi_wr[3 * n + 2] = colval;
1345 tl->
vr_wr[n] = vecS[i];
1350 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, *tl, 0 );
1352 if( owned_dof_ids.size() > 0 )
1356 tl_re.
initialize( 2, 0, 0, 0, owned_dof_ids.size() );
1360 for(
size_t i = 0; i < owned_dof_ids.size(); i++ )
1363 int dof_val = owned_dof_ids[i] - 1;
1364 to_proc = dof_val / nPerPart;
1365 if( to_proc == size ) to_proc = size - 1;
1367 int n = tl_re.
get_n();
1368 tl_re.
vi_wr[2 * n] = to_proc;
1369 tl_re.
vi_wr[2 * n + 1] = dof_val;
1373 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, tl_re, 0 );
1376 sort_buffer.buffer_init( tl_re.
get_n() );
1377 tl_re.
sort( 1, &sort_buffer );
1381 std::map< int, int > startDofIndex, endDofIndex;
1383 if( tl_re.
get_n() > 0 )
1385 dofVal = tl_re.
vi_rd[1];
1387 startDofIndex[dofVal] = 0;
1388 endDofIndex[dofVal] = 0;
1389 for(
unsigned k = 1; k < tl_re.
get_n(); k++ )
1391 int newDof = tl_re.
vi_rd[2 * k + 1];
1392 if( dofVal == newDof )
1394 endDofIndex[dofVal] = k;
1399 startDofIndex[dofVal] = k;
1400 endDofIndex[dofVal] = k;
1417 for(
unsigned k = 0; k < tl->
get_n(); k++ )
1419 int valDof = tl->
vi_rd[3 * k + 1];
1420 if( startDofIndex.find( valDof ) == startDofIndex.end() )
continue;
1421 for(
int ire = startDofIndex[valDof]; ire <= endDofIndex[valDof]; ire++ )
1423 int to_proc = tl_re.
vi_rd[2 * ire];
1424 int n = tl_back->
get_n();
1425 tl_back->
vi_wr[3 * n] = to_proc;
1426 tl_back->
vi_wr[3 * n + 1] = tl->
vi_rd[3 * k + 1];
1427 tl_back->
vi_wr[3 * n + 2] = tl->
vi_rd[3 * k + 2];
1434 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, *tl_back, 0 );
1442 std::set< int > rowSet;
1443 std::set< int > colSet;
1445 int n = tl->
get_n();
1446 for(
int i = 0; i < n; i++ )
1448 const int vecRowValue = tl->
vi_wr[3 * i + 1];
1449 const int vecColValue = tl->
vi_wr[3 * i + 2];
1450 rowSet.insert( vecRowValue );
1451 colSet.insert( vecColValue );
1454 row_gdofmap.resize( rowSet.size() );
1455 for(
auto setIt : rowSet )
1457 row_gdofmap[
index] = setIt;
1458 rowMap[setIt] =
index++;
1460 m_nTotDofs_Dest =
index;
1462 col_gdofmap.resize( colSet.size() );
1463 for(
auto setIt : colSet )
1465 col_gdofmap[
index] = setIt;
1466 colMap[setIt] =
index++;
1468 m_nTotDofs_SrcCov =
index;
1470 tripletList.reserve( n );
1471 for(
int i = 0; i < n; i++ )
1473 const int vecRowValue = tl->
vi_wr[3 * i + 1];
1474 const int vecColValue = tl->
vi_wr[3 * i + 2];
1475 double value = tl->
vr_wr[i];
1476 tripletList.emplace_back( rowMap[vecRowValue], colMap[vecColValue], value );
1484 std::set< int > rowSet;
1485 std::set< int > colSet;
1487 for(
int i = 0; i < nS; i++ )
1489 const int vecRowValue = vecRow[i] - 1;
1490 const int vecColValue = vecCol[i] - 1;
1491 rowSet.insert( vecRowValue );
1492 colSet.insert( vecColValue );
1496 row_gdofmap.resize( rowSet.size() );
1497 for(
auto setIt : rowSet )
1499 row_gdofmap[
index] = setIt;
1500 rowMap[setIt] =
index++;
1502 m_nTotDofs_Dest =
index;
1504 col_gdofmap.resize( colSet.size() );
1505 for(
auto setIt : colSet )
1507 col_gdofmap[
index] = setIt;
1508 colMap[setIt] =
index++;
1510 m_nTotDofs_SrcCov =
index;
1512 tripletList.reserve( nS );
1513 for(
int i = 0; i < nS; i++ )
1515 const int vecRowValue = vecRow[i] - 1;
1516 const int vecColValue = vecCol[i] - 1;
1517 double value = vecS[i];
1518 tripletList.emplace_back( rowMap[vecRowValue], colMap[vecColValue], value );
1522 m_weightMatrix.resize( m_nTotDofs_Dest, m_nTotDofs_SrcCov );
1523 m_rowVector.resize( m_nTotDofs_Dest );
1524 m_colVector.resize( m_nTotDofs_SrcCov );
1525 m_nTotDofs_Src = m_nTotDofs_SrcCov;
1529 m_nTotDofs_SrcGlobal = nA;
1530 m_weightMatrix.setFromTriplets( tripletList.begin(), tripletList.end() );
1532 m_rowVector.setZero();
1533 m_colVector.setZero();
1535 serializeSparseMatrix( m_weightMatrix,
"map_operator_" + std::to_string( rank ) +
".txt" );
1541 m_nDofsPEl_Dest = 1;