38 #ifdef MOAB_HAVE_TEMPESTREMAP
39 #include "GaussLobattoQuadrature.h"
52 if( initialize_fsets )
71 MPI_Initialized( &flagInit );
74 assert( m_pcomm !=
nullptr );
75 rank = m_pcomm->rank();
76 size = m_pcomm->size();
148 std::string inputFilename,
168 MB_CHK_SET_ERR( MB_FAILURE,
"Invalid IntersectionContext context provided" );
175 if( outputEnabled ) std::cout <<
"\nLoading TempestRemap Mesh object from file = " << inputFilename <<
" ...\n";
178 NcError
error( NcError::silent_nonfatal );
183 if( outputEnabled ) std::cout <<
"Loading mesh ...\n";
184 Mesh* mesh =
new Mesh( inputFilename );
185 mesh->RemoveZeroEdges();
186 if( outputEnabled ) std::cout <<
"----------------\n";
191 if( outputEnabled ) std::cout <<
"Validating mesh ...\n";
193 if( outputEnabled ) std::cout <<
"-------------------\n";
199 if( outputEnabled ) std::cout <<
"Constructing edge map on mesh ...\n";
200 mesh->ConstructEdgeMap(
false );
201 if( outputEnabled ) std::cout <<
"---------------------------------\n";
204 if( tempest_mesh ) *tempest_mesh = mesh;
206 catch( Exception& e )
208 std::cout <<
"TempestRemap ERROR: " << e.ToString() <<
"\n";
226 if( outputEnabled ) std::cout <<
"Converting (source) TempestRemap Mesh object to MOAB representation ...\n";
232 if( outputEnabled ) std::cout <<
"Converting (target) TempestRemap Mesh object to MOAB representation ...\n";
238 if( outputEnabled ) std::cout <<
"Converting (overlap) TempestRemap Mesh object to MOAB representation ...\n";
243 MB_CHK_SET_ERR( MB_FAILURE,
"Invalid IntersectionContext context provided" );
247 #define NEW_CONVERT_LOGIC
249 #ifdef NEW_CONVERT_LOGIC
259 const NodeVector& nodes = mesh->nodes;
260 const FaceVector& faces = mesh->faces;
271 std::vector< double* > arrays;
272 std::vector< int > gidsv( nodes.size() );
274 rval =
iface->get_node_coords( 3, nodes.size(), 0, startv, arrays );
MB_CHK_SET_ERR( rval,
"Can't get node coords" );
275 for(
unsigned iverts = 0; iverts < nodes.size(); ++iverts )
277 const Node& node = nodes[iverts];
278 arrays[0][iverts] = node.x;
279 arrays[1][iverts] = node.y;
280 arrays[2][iverts] = node.z;
281 gidsv[iverts] = iverts + 1;
283 Range mbverts( startv, startv + nodes.size() - 1 );
290 Tag srcParentTag, tgtParentTag;
291 std::vector< int > srcParent( faces.size(), -1 ), tgtParent( faces.size(), -1 );
292 std::vector< int > gidse( faces.size(), -1 );
293 bool storeParentInfo = ( mesh->vecSourceFaceIx.size() > 0 );
295 if( storeParentInfo )
313 dbgprint.printf( 0,
"..Mesh size: Nodes [%zu] Elements [%zu].\n", nodes.size(), faces.size() );
314 std::vector< EntityHandle > mbcells( faces.size() );
315 unsigned ntris = 0, nquads = 0, npolys = 0;
316 std::vector< EntityHandle > conn( 16 );
318 for(
unsigned ifaces = 0; ifaces < faces.size(); ++ifaces )
320 const Face&
face = faces[ifaces];
321 const unsigned num_v_per_elem =
face.edges.size();
323 for(
unsigned iedges = 0; iedges < num_v_per_elem; ++iedges )
325 conn[iedges] = startv +
face.edges[iedges].node[0];
328 switch( num_v_per_elem )
351 gidse[ifaces] = ifaces + 1;
353 if( storeParentInfo )
355 srcParent[ifaces] = mesh->vecSourceFaceIx[ifaces] + 1;
356 tgtParent[ifaces] = mesh->vecTargetFaceIx[ifaces] + 1;
360 if( ntris )
dbgprint.printf( 0,
"....Triangular Elements [%u].\n", ntris );
361 if( nquads )
dbgprint.printf( 0,
"....Quadrangular Elements [%u].\n", nquads );
362 if( npolys )
dbgprint.printf( 0,
"....Polygonal Elements [%u].\n", npolys );
367 if( storeParentInfo )
377 if( vertices ) *vertices = mbverts;
392 const NodeVector& nodes = mesh->nodes;
393 const FaceVector& faces = mesh->faces;
396 dbgprint.set_prefix(
"[TempestToMOAB]: " );
404 std::vector< double* > arrays;
405 std::vector< int > gidsv( nodes.size() );
407 rval =
iface->get_node_coords( 3, nodes.size(), 0, startv, arrays );
MB_CHK_SET_ERR( rval,
"Can't get node coords" );
408 for(
unsigned iverts = 0; iverts < nodes.size(); ++iverts )
410 const Node& node = nodes[iverts];
411 arrays[0][iverts] = node.x;
412 arrays[1][iverts] = node.y;
413 arrays[2][iverts] = node.z;
414 gidsv[iverts] = iverts + 1;
416 Range mbverts( startv, startv + nodes.size() - 1 );
423 Tag srcParentTag, tgtParentTag;
424 std::vector< int > srcParent, tgtParent;
425 bool storeParentInfo = ( mesh->vecSourceFaceIx.size() > 0 );
427 if( storeParentInfo )
445 dbgprint.printf( 0,
"..Mesh size: Nodes [%zu] Elements [%zu].\n", nodes.size(), faces.size() );
446 const int NMAXPOLYEDGES = 15;
447 std::vector< unsigned > nPolys( NMAXPOLYEDGES, 0 );
448 std::vector< std::vector< int > > typeNSeqs( NMAXPOLYEDGES );
449 for(
unsigned ifaces = 0; ifaces < faces.size(); ++ifaces )
451 const int iType = faces[ifaces].edges.size();
453 typeNSeqs[iType].push_back( ifaces );
456 for(
unsigned iType = 0; iType < NMAXPOLYEDGES; ++iType )
458 if( !nPolys[iType] )
continue;
460 const unsigned num_v_per_elem = iType;
465 switch( num_v_per_elem )
469 dbgprint.printf( 0,
"....Block %d: Triangular Elements [%u].\n", iBlock++, nPolys[iType] );
470 rval =
iface->get_element_connect( nPolys[iType], num_v_per_elem,
MBTRI, 0, starte, conn );
MB_CHK_SET_ERR( rval,
"Can't get element connectivity" );
474 dbgprint.printf( 0,
"....Block %d: Quadrilateral Elements [%u].\n", iBlock++, nPolys[iType] );
475 rval =
iface->get_element_connect( nPolys[iType], num_v_per_elem,
MBQUAD, 0, starte, conn );
MB_CHK_SET_ERR( rval,
"Can't get element connectivity" );
479 dbgprint.printf( 0,
"....Block %d: Polygonal [%u] Elements [%u].\n", iBlock++, iType,
481 rval =
iface->get_element_connect( nPolys[iType], num_v_per_elem,
MBPOLYGON, 0, starte, conn );
MB_CHK_SET_ERR( rval,
"Can't get element connectivity" );
485 Range mbcells( starte, starte + nPolys[iType] - 1 );
488 if( storeParentInfo )
490 srcParent.resize( mbcells.size(), -1 );
491 tgtParent.resize( mbcells.size(), -1 );
494 std::vector< int > gids( typeNSeqs[iType].
size() );
495 for(
unsigned ifaces = 0, offset = 0; ifaces < typeNSeqs[iType].size(); ++ifaces )
497 const int fIndex = typeNSeqs[iType][ifaces];
498 const Face&
face = faces[fIndex];
500 for(
unsigned iedges = 0; iedges <
face.edges.size(); ++iedges )
502 conn[offset++] = startv +
face.edges[iedges].node[0];
505 if( storeParentInfo )
507 srcParent[ifaces] = mesh->vecSourceFaceIx[fIndex] + 1;
508 tgtParent[ifaces] = mesh->vecTargetFaceIx[fIndex] + 1;
511 gids[ifaces] = typeNSeqs[iType][ifaces] + 1;
518 rval =
iface->update_adjacencies( starte, nPolys[iType], num_v_per_elem, conn );
MB_CHK_SET_ERR( rval,
"Can't update adjacencies" );
524 if( storeParentInfo )
533 if( vertices ) *vertices = mbverts;
552 if( outputEnabled )
dbgprint.printf( 0,
"Converting (source) MOAB to TempestRemap Mesh representation ...\n" );
562 if( outputEnabled )
dbgprint.printf( 0,
"Converting (target) MOAB to TempestRemap Mesh representation ...\n" );
569 if( outputEnabled )
dbgprint.printf( 0,
"Converting (overlap) MOAB to TempestRemap Mesh representation ...\n" );
574 MB_CHK_SET_ERR( MB_FAILURE,
"Invalid IntersectionContext context provided" );
588 NodeVector& nodes = mesh->nodes;
589 FaceVector& faces = mesh->faces;
594 const size_t nelems = elems.
size();
597 faces.resize( nelems );
601 if( verts.
size() == 0 )
607 std::map< EntityHandle, int > indxMap;
608 bool useRange =
true;
617 std::vector< int > globIds( nelems );
622 std::vector< size_t > sortedIdx( nelems );
623 std::iota( sortedIdx.begin(), sortedIdx.end(), 0 );
626 std::sort( sortedIdx.begin(), sortedIdx.end(),
627 [&globIds](
size_t i1,
size_t i2 ) { return globIds[i1] < globIds[i2]; } );
639 while( connectface[nnodesf - 2] == connectface[nnodesf - 1] && nnodesf > 3 )
642 face.edges.resize( nnodesf );
643 for(
int iverts = 0; iverts < nnodesf; ++iverts )
645 int indx = ( useRange ? verts.
index( connectface[iverts] ) : indxMap[connectface[iverts]] );
647 face.SetNode( iverts, indx );
651 unsigned nnodes = verts.
size();
652 nodes.resize( nnodes );
655 std::vector< double > coordx( nnodes ), coordy( nnodes ), coordz( nnodes );
657 for(
unsigned inode = 0; inode < nnodes; ++inode )
659 Node& node = nodes[inode];
660 node.x = coordx[inode];
661 node.y = coordy[inode];
662 node.z = coordz[inode];
668 mesh->RemoveZeroEdges();
669 mesh->RemoveCoincidentNodes();
691 if( a.first == b.first )
692 return a.second < b.second;
694 return a.first < b.first;
699 sharedGhostEntities.
clear();
704 if( is_parallel &&
size > 1 )
707 rval = m_interface->get_entities_by_dimension( m_overlap_set, 2, allents );
MB_CHK_SET_ERR( rval,
"Getting entities dim 2 failed" );
711 std::vector< int > ghFlags( allents.
size() );
712 rval = m_interface->tag_get_handle(
"ORIG_PROC", ghostTag );
MB_CHK_ERR( rval );
713 rval = m_interface->tag_get_data( ghostTag, allents, &ghFlags[0] );
MB_CHK_ERR( rval );
714 for(
unsigned i = 0; i < allents.
size(); ++i )
715 if( ghFlags[i] >= 0 )
716 sharedents.
insert( allents[i] );
718 allents =
subtract( allents, sharedents );
723 rval = m_interface->get_connectivity( allents, ownedverts );
MB_CHK_SET_ERR( rval,
"Deleting entities dim 0 failed" );
724 rval = m_interface->get_connectivity( sharedents, sharedverts );
MB_CHK_SET_ERR( rval,
"Deleting entities dim 0 failed" );
725 sharedverts =
subtract( sharedverts, ownedverts );
730 sharedGhostEntities.
merge( sharedents );
749 std::vector< std::pair< int, int > > sorted_overlap_order( n_overlap_entitites );
751 Tag srcParentTag, tgtParentTag;
755 m_overlap->vecTargetFaceIx.resize( n_overlap_entitites );
756 m_overlap->vecSourceFaceIx.resize( n_overlap_entitites );
759 std::vector< int > rbids_src( n_overlap_entitites ), rbids_tgt( n_overlap_entitites );
762 for(
size_t ix = 0; ix < n_overlap_entitites; ++ix )
764 sorted_overlap_order[ix].first =
766 sorted_overlap_order[ix].second = ix;
768 std::sort( sorted_overlap_order.begin(), sorted_overlap_order.end(),
IntPairComparator );
772 std::vector< int > ghFlags;
776 ghFlags.resize( n_overlap_entitites );
780 for(
unsigned ie = 0; ie < n_overlap_entitites; ++ie )
782 int ix = sorted_overlap_order[ie].second;
794 faces.resize( n_overlap_entitites );
802 std::map< EntityHandle, int > indxMap;
803 bool useRange =
true;
814 const unsigned iface = sorted_overlap_order[ifac].second;
815 Face&
face = faces[ifac];
823 face.edges.resize( nnodesf );
824 for(
int iverts = 0; iverts < nnodesf; ++iverts )
826 int indx = ( useRange ? verts.
index( connectface[iverts] ) : indxMap[connectface[iverts]] );
828 face.SetNode( iverts, indx );
832 unsigned nnodes = verts.
size();
834 nodes.resize( nnodes );
837 std::vector< double > coordx( nnodes ), coordy( nnodes ), coordz( nnodes );
839 for(
unsigned inode = 0; inode < nnodes; ++inode )
841 Node& node = nodes[inode];
842 node.x = coordx[inode];
843 node.y = coordy[inode];
844 node.z = coordz[inode];
852 m_overlap->RemoveCoincidentNodes(
false );
879 m_target->Write( std::string(
"target_TR_p" + std::to_string(
rank ) +
".g" ) );
890 std::vector< int > gids;
901 for(
unsigned ie = 0; ie < gids.size(); ++ie )
917 for(
unsigned ie = 0; ie < gids.size(); ++ie )
933 for(
unsigned ie = 0; ie < gids.size(); ++ie )
946 const bool fAllParallel,
947 const bool fInputConcave,
948 const bool fOutputConcave )
953 if( is_root &&
size == 1 )
955 this->m_source->CalculateFaceAreas( fInputConcave );
956 this->m_target->CalculateFaceAreas( fOutputConcave );
957 this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
965 this->m_source->CalculateFaceAreas( fInputConcave );
966 this->m_covering_source->CalculateFaceAreas( fInputConcave );
967 this->m_target->CalculateFaceAreas( fOutputConcave );
968 this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
973 this->m_source->CalculateFaceAreas( fInputConcave );
974 this->m_target->CalculateFaceAreas( fOutputConcave );
975 this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
1008 #ifndef MOAB_HAVE_MPI
1011 const int dimension,
1012 const int start_id )
1022 int idoffset = start_id;
1023 std::vector< int > gid(
entities.size() );
1024 for(
unsigned i = 0; i <
entities.size(); ++i )
1025 gid[i] = idoffset++;
1038 return std::pow( lhs.x - rhs.x, 2.0 ) + std::pow( lhs.y - rhs.y, 2.0 ) + std::pow( lhs.z - rhs.z, 2.0 );
1044 const std::string& dofTagName,
1051 const int res = std::sqrt( ntot_elements / 6 );
1055 err = GenerateCSMesh( csMesh, res,
"",
"NetCDF4" );
1058 MB_CHK_SET_ERR( MB_FAILURE,
"Failed to generate CS mesh through TempestRemap" );
1068 const int ntot_elements,
1071 const std::string dofTagName,
1077 bool created =
false;
1082 int nElements =
static_cast< int >( csMesh.faces.size() );
1087 DataArray3D< int > dataGLLnodes;
1088 dataGLLnodes.Allocate( nP, nP, nElements );
1090 std::map< Node, int > mapNodes;
1091 std::map< Node, moab::EntityHandle > mapLocalMBNodes;
1094 DataArray1D< double > dG;
1095 DataArray1D< double > dW;
1096 GaussLobattoQuadrature::GetPoints( nP, 0.0, 1.0, dG, dW );
1099 if( secondary_ents )
entities.insert( secondary_ents->
begin(), secondary_ents->
end() );
1101 for(
unsigned iel = 0; iel <
entities.size(); ++iel )
1105 Node elCentroid( elcoords[0], elcoords[1], elcoords[2] );
1106 mapLocalMBNodes.insert( std::pair< Node, moab::EntityHandle >( elCentroid, eh ) );
1115 int* dofIDs =
new int[nP * nP];
1118 for(
int k = 0; k < nElements; k++ )
1120 const Face&
face = csMesh.faces[k];
1121 const NodeVector& nodes = csMesh.nodes;
1123 if(
face.edges.size() != 4 )
1125 _EXCEPTIONT(
"Mesh must only contain quadrilateral elements" );
1129 centroid.x = centroid.y = centroid.z = 0.0;
1130 for(
unsigned l = 0; l <
face.edges.size(); ++l )
1132 centroid.x += nodes[
face[l]].x;
1133 centroid.y += nodes[
face[l]].y;
1134 centroid.z += nodes[
face[l]].z;
1136 const double factor = 1.0 /
face.edges.size();
1137 centroid.x *= factor;
1138 centroid.y *= factor;
1139 centroid.z *= factor;
1141 bool locElem =
false;
1143 if( mapLocalMBNodes.find( centroid ) != mapLocalMBNodes.end() )
1146 current_eh = mapLocalMBNodes[centroid];
1149 for(
int j = 0; j < nP; j++ )
1151 for(
int i = 0; i < nP; i++ )
1166 const double& dAlpha = dG[i];
1167 const double& dBeta = dG[j];
1170 double dXc = nodes[
face[0]].x * ( 1.0 - dAlpha ) * ( 1.0 - dBeta ) +
1171 nodes[
face[1]].x * dAlpha * ( 1.0 - dBeta ) + nodes[
face[2]].x * dAlpha * dBeta +
1172 nodes[
face[3]].x * ( 1.0 - dAlpha ) * dBeta;
1174 double dYc = nodes[
face[0]].y * ( 1.0 - dAlpha ) * ( 1.0 - dBeta ) +
1175 nodes[
face[1]].y * dAlpha * ( 1.0 - dBeta ) + nodes[
face[2]].y * dAlpha * dBeta +
1176 nodes[
face[3]].y * ( 1.0 - dAlpha ) * dBeta;
1178 double dZc = nodes[
face[0]].z * ( 1.0 - dAlpha ) * ( 1.0 - dBeta ) +
1179 nodes[
face[1]].z * dAlpha * ( 1.0 - dBeta ) + nodes[
face[2]].z * dAlpha * dBeta +
1180 nodes[
face[3]].z * ( 1.0 - dAlpha ) * dBeta;
1182 double dR = sqrt( dXc * dXc + dYc * dYc + dZc * dZc );
1185 nodeGLL.x = dXc / dR;
1186 nodeGLL.y = dYc / dR;
1187 nodeGLL.z = dZc / dR;
1190 std::map< Node, int >::const_iterator iter = mapNodes.find( nodeGLL );
1191 if( iter == mapNodes.end() )
1194 int ixNode =
static_cast< int >( mapNodes.size() );
1195 mapNodes.insert( std::pair< Node, int >( nodeGLL, ixNode ) );
1196 dataGLLnodes[j][i][k] = ixNode + 1;
1200 dataGLLnodes[j][i][k] = iter->second + 1;
1203 dofIDs[j * nP + i] = dataGLLnodes[j][i][k];
1215 mapLocalMBNodes.clear();
1242 #ifdef MOAB_HAVE_MPI
1243 mbintx->set_parallel_comm( m_pcomm );
1253 #ifdef MOAB_HAVE_MPI
1269 double tolerance = 1e-6, btolerance = 1e-3;
1277 for(
unsigned ie = 0; ie < targetVerts.
size(); ++ie )
1294 std::vector< moab::EntityHandle > leaf_elems;
1299 if( !leaf_elems.size() )
1307 std::vector< double > centroids( leaf_elems.size() * 3 );
1312 for(
size_t il = 0; il < leaf_elems.size(); ++il )
1314 const double* centroid = ¢roids[il * 3];
1315 const double locdist = std::pow( point[0] - centroid[0], 2 ) +
1316 std::pow( point[1] - centroid[1], 2 ) +
1317 std::pow( point[2] - centroid[2], 2 );
1319 if( locdist < dist )
1330 <<
": [Error] - Could not find a minimum distance within the leaf "
1332 << dist << std::endl;
1348 #ifdef MOAB_HAVE_MPI
1358 const bool outputEnabled = ( this->
rank == 0 );
1360 dbgprint.
set_prefix(
"[ComputeOverlapMesh]: " );
1382 bool concaveMeshA =
false, concaveMeshB =
false;
1384 "exact", concaveMeshA, concaveMeshB,
false );
1387 MB_CHK_SET_ERR( MB_FAILURE,
"TempestRemap: Can't compute the intersection of meshes on the sphere" );
1404 if( gid[0] + gid[1] == 0 )
1406 #ifdef MOAB_HAVE_MPI
1422 if( gid[0] + gid[1] == 0 )
1424 #ifdef MOAB_HAVE_MPI
1435 if( outputEnabled )
dbgprint.printf( 0,
"Computing intersection mesh with the Kd-tree search algorithm" );
1441 dbgprint.printf( 0,
"Computing intersection mesh with the advancing-front propagation algorithm" );
1445 #ifdef MOAB_HAVE_MPI
1449 std::stringstream ffc, fft, ffo;
1450 ffc <<
"cover_" <<
rank <<
".h5m";
1451 fft <<
"target_" <<
rank <<
".h5m";
1452 ffo <<
"intx_" <<
rank <<
".h5m";
1466 std::map< int, int > loc_gid_to_lid_covsrc;
1467 std::vector< int > gids( covEnts.
size(), -1 );
1469 for(
unsigned ie = 0; ie < gids.size(); ++ie )
1471 loc_gid_to_lid_covsrc[gids[ie]] = ie;
1474 Range intxCov, intxCells;
1485 assert( srcParent >= 0 );
1486 intxCov.
insert( covEnts[loc_gid_to_lid_covsrc[srcParent]] );
1509 rval =
mb->get_connectivity( eh, conn, num_nodes );
MB_CHK_ERR( rval );
1522 rval =
mb->get_connectivity( *it, conn, len,
false );
MB_CHK_ERR( rval );
1523 for(
int ie = 0; ie < len; ++ie )
1525 std::vector< EntityHandle > adjacent_entities;
1527 for(
auto ent : adjacent_entities )
1528 notNeededCovCells.
erase( ent );
1533 std::string(
"sourcecoveragemesh_p" + std::to_string(
rank ) +
".h5m" ).c_str(),
1544 std::cout <<
" total participating elements in the covering set: " << intxCov.
size() <<
"\n";
1545 std::cout <<
" remove from coverage set elements that are not intersected: " << notNeededCovCells.
size()
1587 #ifdef MOAB_HAVE_MPI
1609 Range targetCells, boundaryEdges;
1612 rval = skinner.find_skin( 0, targetCells,
false, boundaryEdges );
MB_CHK_ERR( rval );
1615 Range boundaryCells;
1617 boundaryCells =
intersect( boundaryCells, targetCells );
1624 std::stringstream ffs;
1625 ffs <<
"boundaryCells_0" <<
rank <<
".h5m";
1632 std::set< int > targetBoundaryIds;
1638 if( tid < 0 ) std::cout <<
" incorrect id for a target cell\n";
1639 targetBoundaryIds.insert( tid );
1645 std::set< int > affectedSourceCellsIds;
1646 Tag targetParentTag, sourceParentTag;
1649 for(
Range::iterator it = overlapCells.begin(); it != overlapCells.end(); it++ )
1652 int targetParentID, sourceParentID;
1654 if( targetBoundaryIds.find( targetParentID ) != targetBoundaryIds.end() )
1658 affectedSourceCellsIds.insert( sourceParentID );
1664 std::map< int, EntityHandle > affectedCovCellFromID;
1670 std::set< EntityHandle > affectedCovCells;
1677 for(
Range::iterator it = covCells.begin(); it != covCells.end(); it++ )
1682 if( affectedSourceCellsIds.find( covID ) != affectedSourceCellsIds.end() )
1685 affectedCovCellFromID[covID] = covCell;
1686 affectedCovCells.insert( covCell );
1697 std::map< int, std::set< EntityHandle > > overlapCellsForTask;
1700 std::set< EntityHandle > overlapCellsToSend;
1702 for(
Range::iterator it = overlapCells.begin(); it != overlapCells.end(); it++ )
1707 if( affectedSourceCellsIds.find( sourceParentID ) != affectedSourceCellsIds.end() )
1709 EntityHandle covCell = affectedCovCellFromID[sourceParentID];
1712 overlapCellsForTask[orgTask].insert(
1714 overlapCellsToSend.insert( intxCell );
1724 for( std::set< EntityHandle >::iterator it = overlapCellsToSend.begin(); it != overlapCellsToSend.end(); it++ )
1730 if( maxEdges < nnodes ) maxEdges = nnodes;
1736 MPI_Allreduce( &maxEdges, &globalMaxEdges, 1, MPI_INT, MPI_MAX, m_pcomm->comm() );
1738 globalMaxEdges = maxEdges;
1741 if(
is_root ) std::cout <<
"maximum number of edges for polygons to send is " << globalMaxEdges <<
"\n";
1748 for( std::set< EntityHandle >::iterator it = overlapCellsToSend.begin(); it != overlapCellsToSend.end(); it++ )
1753 for( std::set< EntityHandle >::iterator it = affectedCovCells.begin(); it != affectedCovCells.end(); it++ )
1758 std::stringstream ffs2;
1760 ffs2 <<
"affectedCells_" << m_pcomm->rank() <<
".h5m";
1773 std::map< int, std::set< EntityHandle > > verticesOverlapForTask;
1775 std::set< EntityHandle > allVerticesToSend;
1776 std::map< EntityHandle, int > allVerticesToSendMap;
1778 int numOverlapCells = 0;
1779 for( std::map<
int, std::set< EntityHandle > >::iterator it = overlapCellsForTask.begin();
1780 it != overlapCellsForTask.end(); it++ )
1782 int sendToProc = it->first;
1783 std::set< EntityHandle >& overlapCellsToSend2 = it->second;
1785 std::set< EntityHandle > vertices;
1786 for( std::set< EntityHandle >::iterator set_it = overlapCellsToSend2.begin();
1787 set_it != overlapCellsToSend2.end(); ++set_it )
1789 int nnodes_local = 0;
1792 for(
int k = 0; k < nnodes_local; k++ )
1793 vertices.insert( conn1[k] );
1795 verticesOverlapForTask[sendToProc] = vertices;
1796 numVerts += (int)vertices.size();
1797 numOverlapCells += (int)overlapCellsToSend2.size();
1798 allVerticesToSend.insert( vertices.begin(), vertices.end() );
1802 for( std::set< EntityHandle >::iterator vert_it = allVerticesToSend.begin(); vert_it != allVerticesToSend.end();
1806 allVerticesToSendMap[vert] = j;
1812 TLv.initialize( 2, 0, 0, 3, numVerts );
1813 TLv.enableWriteAccess();
1815 for( std::map<
int, std::set< EntityHandle > >::iterator it = verticesOverlapForTask.begin();
1816 it != verticesOverlapForTask.end(); it++ )
1818 int sendToProc = it->first;
1819 std::set< EntityHandle >& vertices = it->second;
1821 for( std::set< EntityHandle >::iterator it2 = vertices.begin(); it2 != vertices.end(); it2++, i++ )
1823 int n = TLv.get_n();
1824 TLv.vi_wr[2 * n] = sendToProc;
1826 int indexInAllVert = allVerticesToSendMap[v];
1827 TLv.vi_wr[2 * n + 1] = indexInAllVert;
1831 TLv.vr_wr[3 * n] = coords[0];
1832 TLv.vr_wr[3 * n + 1] = coords[1];
1833 TLv.vr_wr[3 * n + 2] = coords[2];
1839 int sizeTuple = 4 + globalMaxEdges;
1841 TLc.initialize( sizeTuple, 0, 0, 0,
1844 TLc.enableWriteAccess();
1846 for( std::map<
int, std::set< EntityHandle > >::iterator it = overlapCellsForTask.begin();
1847 it != overlapCellsForTask.end(); it++ )
1849 int sendToProc = it->first;
1850 std::set< EntityHandle >& overlapCellsToSend2 = it->second;
1852 for( std::set< EntityHandle >::iterator it2 = overlapCellsToSend2.begin(); it2 != overlapCellsToSend2.end();
1856 int sourceParentID, targetParentID;
1859 int n = TLc.get_n();
1860 TLc.vi_wr[sizeTuple * n] = sendToProc;
1861 TLc.vi_wr[sizeTuple * n + 1] = sourceParentID;
1862 TLc.vi_wr[sizeTuple * n + 2] = targetParentID;
1866 TLc.vi_wr[sizeTuple * n + 3] = nnodes;
1867 for(
int i = 0; i < nnodes; i++ )
1869 int indexVertex = allVerticesToSendMap[conn[i]];
1871 if( -1 == indexVertex )
MB_CHK_SET_ERR( MB_FAILURE,
"Can't find vertex in range of vertices to send" );
1872 TLc.vi_wr[sizeTuple * n + 4 + i] = indexVertex;
1875 for(
int i = nnodes; i < globalMaxEdges; i++ )
1876 TLc.vi_wr[sizeTuple * n + 4 + i] = 0;
1885 std::stringstream ff1;
1886 ff1 <<
"TLc_" <<
rank <<
".txt";
1887 TLc.print_to_file( ff1.str().c_str() );
1888 std::stringstream ffv;
1889 ffv <<
"TLv_" <<
rank <<
".txt";
1890 TLv.print_to_file( ffv.str().c_str() );
1892 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, TLv, 0 );
1893 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, TLc, 0 );
1896 TLc.print_to_file( ff1.str().c_str() );
1897 TLv.print_to_file( ffv.str().c_str() );
1903 buffer.buffer_init( sizeTuple * TLc.get_n() * 2 );
1906 TLc.print_to_file( ff1.str().c_str() );
1917 std::map< int, std::map< int, int > > availVertexIndicesPerProcessor;
1918 int nv = TLv.get_n();
1919 for(
int i = 0; i < nv; i++ )
1922 int orgProc = TLv.vi_rd[2 * i];
1923 int indexVert = TLv.vi_rd[2 * i + 1];
1924 availVertexIndicesPerProcessor[orgProc][indexVert] = i;
1934 int n = TLc.get_n();
1935 std::map< int, int > currentProcsCount;
1939 std::map< int, std::set< int > > sourcesForTasks;
1943 int currentSourceID = TLc.vi_rd[sizeTuple * 0 + 1];
1944 int proc0 = TLc.vi_rd[sizeTuple * 0];
1945 currentProcsCount[proc0] = 1;
1947 for(
int i = 1; i < n; i++ )
1949 int proc = TLc.vi_rd[sizeTuple * i];
1950 int sourceID = TLc.vi_rd[sizeTuple * i + 1];
1951 if( sourceID == currentSourceID )
1953 if( currentProcsCount.find( proc ) == currentProcsCount.end() )
1955 currentProcsCount[proc] = 1;
1958 currentProcsCount[proc]++;
1960 if( sourceID != currentSourceID || ( ( n - 1 ) == i ) )
1964 if( currentProcsCount.size() > 1 )
1967 std::cout <<
" source element " << currentSourceID <<
" intersects with "
1968 << currentProcsCount.size() <<
" target partitions\n";
1969 for( std::map< int, int >::iterator it = currentProcsCount.begin(); it != currentProcsCount.end();
1972 int procID = it->first;
1973 int numOverCells = it->second;
1974 std::cout <<
" task:" << procID <<
" " << numOverCells <<
" cells\n";
1979 for( std::map< int, int >::iterator it1 = currentProcsCount.begin(); it1 != currentProcsCount.end();
1982 int proc1 = it1->first;
1983 sourcesForTasks[currentSourceID].insert( proc1 );
1984 for( std::map< int, int >::iterator it2 = currentProcsCount.begin();
1985 it2 != currentProcsCount.end(); it2++ )
1987 int proc2 = it2->first;
1988 if( proc1 != proc2 ) sizeOfTLc2 += it2->second;
1993 if( sourceID != currentSourceID )
1995 currentSourceID = sourceID;
1996 currentProcsCount.clear();
1997 currentProcsCount[proc] = 1;
2006 std::cout <<
" need to initialize TLc2 with " << sizeOfTLc2 <<
" cells\n ";
2010 int sizeTuple2 = 5 + globalMaxEdges;
2013 TLc2.initialize( sizeTuple2, 0, 0, 0, sizeOfTLc2 );
2014 TLc2.enableWriteAccess();
2017 std::map< int, std::set< int > > verticesToSendForProc;
2019 for(
int i = 0; i < n; i++ )
2021 int sourceID = TLc.vi_rd[sizeTuple * i + 1];
2022 if( sourcesForTasks.find( sourceID ) != sourcesForTasks.end() )
2025 std::set< int > procs = sourcesForTasks[sourceID];
2026 if( procs.size() < 2 )
MB_CHK_SET_ERR( MB_FAILURE,
" not enough processes involved with a sourceID cell" );
2028 int orgProc = TLc.vi_rd[sizeTuple * i];
2031 std::map< int, int >& availableVerticesFromThisProc = availVertexIndicesPerProcessor[orgProc];
2032 for( std::set< int >::iterator setIt = procs.begin(); setIt != procs.end(); setIt++ )
2034 int procID = *setIt;
2037 if( procID != orgProc )
2040 int n2 = TLc2.get_n();
2041 if( n2 >= sizeOfTLc2 )
MB_CHK_SET_ERR( MB_FAILURE,
" memory overflow" );
2043 std::set< int >& indexVerticesInTLv = verticesToSendForProc[procID];
2044 TLc2.vi_wr[n2 * sizeTuple2] = procID;
2045 TLc2.vi_wr[n2 * sizeTuple2 + 1] = orgProc;
2046 TLc2.vi_wr[n2 * sizeTuple2 + 2] = sourceID;
2047 TLc2.vi_wr[n2 * sizeTuple2 + 3] = TLc.vi_rd[sizeTuple * i + 2];
2049 int nvert = TLc.vi_rd[sizeTuple * i + 3];
2050 TLc2.vi_wr[n2 * sizeTuple2 + 4] = nvert;
2055 for(
int j = 0; j < nvert; j++ )
2057 int vertexIndex = TLc.vi_rd[i * sizeTuple + 4 + j];
2059 if( availableVerticesFromThisProc.find( vertexIndex ) == availableVerticesFromThisProc.end() )
2061 MB_CHK_SET_ERR( MB_FAILURE,
" vertex index not available from processor" );
2063 TLc2.vi_wr[n2 * sizeTuple2 + 5 + j] = vertexIndex;
2064 int indexInTLv = availVertexIndicesPerProcessor[orgProc][vertexIndex];
2065 indexVerticesInTLv.insert( indexInTLv );
2068 for(
int j = nvert; j < globalMaxEdges; j++ )
2070 TLc2.vi_wr[n2 * sizeTuple2 + 5 + j] = 0;
2084 for( std::map<
int, std::set< int > >::iterator it = verticesToSendForProc.begin();
2085 it != verticesToSendForProc.end(); it++ )
2087 std::set< int >& indexInTLvSet = it->second;
2088 numVerts2 += (int)indexInTLvSet.size();
2090 TLv2.initialize( 3, 0, 0, 3,
2092 TLv2.enableWriteAccess();
2093 for( std::map<
int, std::set< int > >::iterator it = verticesToSendForProc.begin();
2094 it != verticesToSendForProc.end(); it++ )
2096 int sendToProc = it->first;
2097 std::set< int >& indexInTLvSet = it->second;
2099 for( std::set< int >::iterator itSet = indexInTLvSet.begin(); itSet != indexInTLvSet.end(); itSet++ )
2101 int indexInTLv = *itSet;
2102 int orgProc = TLv.vi_rd[2 * indexInTLv];
2103 int indexVertexInOrgProc = TLv.vi_rd[2 * indexInTLv + 1];
2104 int nv2 = TLv2.get_n();
2105 TLv2.vi_wr[3 * nv2] = sendToProc;
2106 TLv2.vi_wr[3 * nv2 + 1] = orgProc;
2107 TLv2.vi_wr[3 * nv2 + 2] = indexVertexInOrgProc;
2108 for(
int j = 0; j < 3; j++ )
2109 TLv2.vr_wr[3 * nv2 + j] =
2110 TLv.vr_rd[3 * indexInTLv + j];
2115 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, TLv2, 0 );
2116 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, TLc2, 0 );
2120 std::stringstream ff2;
2121 ff2 <<
"TLc2_" <<
rank <<
".txt";
2122 TLc2.print_to_file( ff2.str().c_str() );
2123 std::stringstream ffv2;
2124 ffv2 <<
"TLv2_" <<
rank <<
".txt";
2125 TLv2.print_to_file( ffv2.str().c_str() );
2134 int nvNew = TLv2.get_n();
2142 std::map< int, std::map< int, EntityHandle > > vertexPerProcAndIndex;
2143 for(
int i = 0; i < nvNew; i++ )
2145 int orgProc = TLv2.vi_rd[3 * i + 1];
2146 int indexInVert = TLv2.vi_rd[3 * i + 2];
2147 vertexPerProcAndIndex[orgProc][indexInVert] = newVerts[i];
2155 int ne = TLc2.get_n();
2156 for(
int i = 0; i < ne; i++ )
2158 int orgProc = TLc2.vi_rd[i * sizeTuple2 + 1];
2159 int sourceID = TLc2.vi_rd[i * sizeTuple2 + 2];
2160 int targetID = TLc2.vi_wr[i * sizeTuple2 + 3];
2161 int nve = TLc2.vi_wr[i * sizeTuple2 + 4];
2162 std::vector< EntityHandle > conn;
2164 for(
int j = 0; j < nve; j++ )
2166 int indexV = TLc2.vi_wr[i * sizeTuple2 + 5 + j];
2167 EntityHandle vh = vertexPerProcAndIndex[orgProc][indexV];
2172 newPolygons.insert( polyNew );
2184 std::stringstream ffs4;
2185 ffs4 <<
"extraIntxCells" <<
rank <<
".h5m";