40 #ifdef MOAB_HAVE_TEMPESTREMAP
42 #include "FiniteElementTools.h"
43 #include "GaussLobattoQuadrature.h"
55 if( initialize_fsets )
74 MPI_Initialized( &flagInit );
77 assert( m_pcomm !=
nullptr );
78 rank = m_pcomm->rank();
79 size = m_pcomm->size();
84 AnnounceOnlyOutputOnRankZero();
152 std::string inputFilename,
172 MB_CHK_SET_ERR( MB_FAILURE,
"Invalid IntersectionContext context provided" );
179 if( outputEnabled ) std::cout <<
"\nLoading TempestRemap Mesh object from file = " << inputFilename <<
" ...\n";
182 NcError
error( NcError::silent_nonfatal );
187 if( outputEnabled ) std::cout <<
"Loading mesh ...\n";
188 Mesh* mesh =
new Mesh( inputFilename );
189 mesh->RemoveZeroEdges();
190 if( outputEnabled ) std::cout <<
"----------------\n";
195 if( outputEnabled ) std::cout <<
"Validating mesh ...\n";
197 if( outputEnabled ) std::cout <<
"-------------------\n";
203 if( outputEnabled ) std::cout <<
"Constructing edge map on mesh ...\n";
204 mesh->ConstructEdgeMap(
false );
205 if( outputEnabled ) std::cout <<
"---------------------------------\n";
208 if( tempest_mesh ) *tempest_mesh = mesh;
210 catch( Exception& e )
212 std::cout <<
"TempestRemap ERROR: " << e.ToString() <<
"\n";
230 if( outputEnabled ) std::cout <<
"Converting (source) TempestRemap Mesh object to MOAB representation ...\n";
236 if( outputEnabled ) std::cout <<
"Converting (target) TempestRemap Mesh object to MOAB representation ...\n";
242 if( outputEnabled ) std::cout <<
"Converting (overlap) TempestRemap Mesh object to MOAB representation ...\n";
247 MB_CHK_SET_ERR( MB_FAILURE,
"Invalid IntersectionContext context provided" );
251 #define NEW_CONVERT_LOGIC
253 #ifdef NEW_CONVERT_LOGIC
261 const NodeVector& nodes = mesh->nodes;
262 const FaceVector& faces = mesh->faces;
273 std::vector< double* > arrays;
274 std::vector< int > gidsv( nodes.size() );
276 MB_CHK_SET_ERR(
iface->get_node_coords( 3, nodes.size(), 0, startv, arrays ),
"Can't get node coords" );
277 for(
unsigned iverts = 0; iverts < nodes.size(); ++iverts )
279 const Node& node = nodes[iverts];
280 arrays[0][iverts] = node.x;
281 arrays[1][iverts] = node.y;
282 arrays[2][iverts] = node.z;
283 gidsv[iverts] = iverts + 1;
285 Range mbverts( startv, startv + nodes.size() - 1 );
292 Tag srcParentTag, tgtParentTag;
293 std::vector< int > srcParent( faces.size(), -1 ), tgtParent( faces.size(), -1 );
294 std::vector< int > gidse( faces.size(), -1 );
295 bool storeParentInfo = ( mesh->vecSourceFaceIx.size() > 0 );
297 if( storeParentInfo )
302 "can't create positive tag" );
306 "can't create negative tag" );
317 dbgprint.printf( 0,
"..Mesh size: Nodes [%zu] Elements [%zu].\n", nodes.size(), faces.size() );
318 std::vector< EntityHandle > mbcells( faces.size() );
319 unsigned ntris = 0, nquads = 0, npolys = 0;
320 std::vector< EntityHandle > conn( 16 );
322 for(
unsigned ifaces = 0; ifaces < faces.size(); ++ifaces )
324 const Face&
face = faces[ifaces];
325 const unsigned num_v_per_elem =
face.edges.size();
327 for(
unsigned iedges = 0; iedges < num_v_per_elem; ++iedges )
329 conn[iedges] = startv +
face.edges[iedges].node[0];
332 switch( num_v_per_elem )
338 "Can't get element connectivity" );
345 "Can't get element connectivity" );
353 "Can't get element connectivity" );
358 gidse[ifaces] = ifaces + 1;
360 if( storeParentInfo )
362 srcParent[ifaces] = mesh->vecSourceFaceIx[ifaces] + 1;
363 tgtParent[ifaces] = mesh->vecTargetFaceIx[ifaces] + 1;
367 if( ntris )
dbgprint.printf( 0,
"....Triangular Elements [%u].\n", ntris );
368 if( nquads )
dbgprint.printf( 0,
"....Quadrangular Elements [%u].\n", nquads );
369 if( npolys )
dbgprint.printf( 0,
"....Polygonal Elements [%u].\n", npolys );
374 "Can't set global_id tag" );
376 MB_CHK_SET_ERR( m_pcomm->assign_global_ids(mesh_set, 2, 1,
false,
true,
false ),
"Unable to set global IDs" );
379 if( storeParentInfo )
382 "Can't set tag data" );
384 "Can't set tag data" );
388 std::copy( mbcells.begin(), mbcells.end(),
range_inserter( entities ) );
391 if( vertices ) *vertices = mbverts;
406 const NodeVector& nodes = mesh->nodes;
407 const FaceVector& faces = mesh->faces;
410 dbgprint.set_prefix(
"[TempestToMOAB]: " );
418 std::vector< double* > arrays;
419 std::vector< int > gidsv( nodes.size() );
421 MB_CHK_SET_ERR(
iface->get_node_coords( 3, nodes.size(), 0, startv, arrays ),
"Can't get node coords" );
422 for(
unsigned iverts = 0; iverts < nodes.size(); ++iverts )
424 const Node& node = nodes[iverts];
425 arrays[0][iverts] = node.x;
426 arrays[1][iverts] = node.y;
427 arrays[2][iverts] = node.z;
428 gidsv[iverts] = iverts + 1;
430 Range mbverts( startv, startv + nodes.size() - 1 );
437 Tag srcParentTag, tgtParentTag;
438 std::vector< int > srcParent, tgtParent;
439 bool storeParentInfo = ( mesh->vecSourceFaceIx.size() > 0 );
441 if( storeParentInfo )
446 "can't create positive tag" );
450 "can't create negative tag" );
461 dbgprint.printf( 0,
"..Mesh size: Nodes [%zu] Elements [%zu].\n", nodes.size(), faces.size() );
462 const int NMAXPOLYEDGES = 15;
463 std::vector< unsigned > nPolys( NMAXPOLYEDGES, 0 );
464 std::vector< std::vector< int > > typeNSeqs( NMAXPOLYEDGES );
465 for(
unsigned ifaces = 0; ifaces < faces.size(); ++ifaces )
467 const int iType = faces[ifaces].edges.size();
469 typeNSeqs[iType].push_back( ifaces );
472 for(
unsigned iType = 0; iType < NMAXPOLYEDGES; ++iType )
474 if( !nPolys[iType] )
continue;
476 const unsigned num_v_per_elem = iType;
481 switch( num_v_per_elem )
485 dbgprint.printf( 0,
"....Block %d: Triangular Elements [%u].\n", iBlock++, nPolys[iType] );
487 "Can't get element connectivity" );
491 dbgprint.printf( 0,
"....Block %d: Quadrilateral Elements [%u].\n", iBlock++, nPolys[iType] );
494 "Can't get element connectivity" );
498 dbgprint.printf( 0,
"....Block %d: Polygonal [%u] Elements [%u].\n", iBlock++, iType,
502 "Can't get element connectivity" );
506 Range mbcells( starte, starte + nPolys[iType] - 1 );
509 if( storeParentInfo )
511 srcParent.resize( mbcells.size(), -1 );
512 tgtParent.resize( mbcells.size(), -1 );
515 std::vector< int > gids( typeNSeqs[iType].
size() );
516 for(
unsigned ifaces = 0, offset = 0; ifaces < typeNSeqs[iType].size(); ++ifaces )
518 const int fIndex = typeNSeqs[iType][ifaces];
519 const Face&
face = faces[fIndex];
521 for(
unsigned iedges = 0; iedges <
face.edges.size(); ++iedges )
523 conn[offset++] = startv +
face.edges[iedges].node[0];
526 if( storeParentInfo )
528 srcParent[ifaces] = mesh->vecSourceFaceIx[fIndex] + 1;
529 tgtParent[ifaces] = mesh->vecTargetFaceIx[fIndex] + 1;
532 gids[ifaces] = typeNSeqs[iType][ifaces] + 1;
540 "Can't update adjacencies" );
547 if( storeParentInfo )
550 "Can't set tag data" );
552 "Can't set tag data" );
554 entities.
merge( mbcells );
558 if( vertices ) *vertices = mbverts;
574 "Can't convert source mesh to TempestRemap format" );
580 "Can't convert source coverage mesh to TempestRemap format" );
586 "Can't convert target mesh to TempestRemap format" );
603 if( outputEnabled )
dbgprint.printf( 0,
"Converting (source) MOAB to TempestRemap Mesh representation ...\n" );
606 "Can't convert source mesh to Tempest" );
616 dbgprint.printf( 0,
"Converting (covering source) MOAB to TempestRemap Mesh representation ...\n" );
619 "Can't convert convering source mesh to TempestRemap format" );
624 if( outputEnabled )
dbgprint.printf( 0,
"Converting (target) MOAB to TempestRemap Mesh representation ...\n" );
627 "Can't convert target mesh to Tempest" );
633 if( outputEnabled )
dbgprint.printf( 0,
"Converting (overlap) MOAB to TempestRemap Mesh representation ...\n" );
638 MB_CHK_SET_ERR( MB_FAILURE,
"Invalid IntersectionContext context provided" );
649 NodeVector& nodes = mesh->nodes;
650 FaceVector& faces = mesh->faces;
655 const size_t nelems = elems.
size();
658 faces.resize( nelems );
663 if( verts.
size() == 0 )
669 std::map< EntityHandle, int > indxMap;
670 bool useRange =
true;
679 std::vector< int > globIds( nelems );
682 std::vector< size_t > sortedIdx;
685 sortedIdx.resize( nelems );
687 std::iota( sortedIdx.begin(), sortedIdx.end(), 0 );
690 std::sort( sortedIdx.begin(), sortedIdx.end(),
691 [&globIds](
size_t i1,
size_t i2 ) { return globIds[i1] < globIds[i2]; } );
704 while( connectface[nnodesf - 2] == connectface[nnodesf - 1] && nnodesf > 3 )
707 face.edges.resize( nnodesf );
708 for(
int iverts = 0; iverts < nnodesf; ++iverts )
710 int indx = ( useRange ? verts.
index( connectface[iverts] ) : indxMap[connectface[iverts]] );
712 face.SetNode( iverts, indx );
716 unsigned nnodes = verts.
size();
717 nodes.resize( nnodes );
720 std::vector< double > coordx( nnodes ), coordy( nnodes ), coordz( nnodes );
722 for(
unsigned inode = 0; inode < nnodes; ++inode )
724 Node& node = nodes[inode];
725 node.x = coordx[inode];
726 node.y = coordy[inode];
727 node.z = coordz[inode];
733 mesh->RemoveCoincidentNodes();
734 mesh->RemoveZeroEdges();
756 if( std::get< 1 >( a ) == std::get< 1 >( b ) )
757 return std::get< 2 >( a ) < std::get< 2 >( b );
759 return std::get< 1 >( a ) < std::get< 1 >( b );
764 sharedGhostEntities.
clear();
771 MB_CHK_SET_ERR( m_interface->get_entities_by_dimension( m_overlap_set, 2, allents ),
772 "Getting entities dim 2 failed" );
776 std::vector< int > ghFlags( allents.
size() );
777 MB_CHK_ERR( m_interface->tag_get_handle(
"ORIG_PROC", ghostTag ) );
778 MB_CHK_ERR( m_interface->tag_get_data( ghostTag, allents, &ghFlags[0] ) );
779 for(
unsigned i = 0; i < allents.
size(); ++i )
780 if( ghFlags[i] >= 0 )
781 sharedents.
insert( allents[i] );
783 allents =
subtract( allents, sharedents );
788 MB_CHK_SET_ERR( m_interface->get_connectivity( allents, ownedverts ),
"Deleting entities dim 0 failed" );
789 MB_CHK_SET_ERR( m_interface->get_connectivity( sharedents, sharedverts ),
"Deleting entities dim 0 failed" );
790 sharedverts =
subtract( sharedverts, ownedverts );
794 sharedGhostEntities.
merge( sharedents );
810 std::vector< std::array< int, 3 > > sorted_overlap_order( n_overlap_entitites,
811 std::array< int, 3 >( { -1, -1, -1 } ) );
813 Tag srcParentTag, tgtParentTag;
817 m_overlap->vecTargetFaceIx.resize( n_overlap_entitites );
818 m_overlap->vecSourceFaceIx.resize( n_overlap_entitites );
827 #ifdef USE_SORTED_GIDS
829 std::sort( gids_src.begin(), gids_src.end() );
830 std::sort( gids_tgt.begin(), gids_tgt.end() );
832 auto find_lid = []( std::vector< int >& gids,
int gid ) ->
int {
836 auto it = std::lower_bound( gids.begin(), gids.end(), gid );
837 return ( it != gids.end() ? std::distance( gids.begin(), it ) : -1 );
840 auto find_lid = [
this]( std::vector< int >& gids,
int gid ) ->
int {
842 auto it = std::find( gids.begin(), gids.end(), gid );
843 return ( it != gids.end() ? std::distance( gids.begin(), it ) : -1 );
847 std::vector< int > ghFlags;
851 ghFlags.resize( n_overlap_entitites );
857 std::vector< int > rbids_src( n_overlap_entitites ), rbids_tgt( n_overlap_entitites );
861 for(
size_t ix = 0; ix < n_overlap_entitites; ++ix )
863 std::get< 0 >( sorted_overlap_order[ix] ) = ix;
864 std::get< 1 >( sorted_overlap_order[ix] ) = find_lid( gids_src, rbids_src[ix] );
865 assert( std::get< 1 >( sorted_overlap_order[ix] ) >= 0 );
872 std::get< 2 >( sorted_overlap_order[ix] ) = -1;
875 std::get< 2 >( sorted_overlap_order[ix] ) = find_lid( gids_tgt, rbids_tgt[ix] );
879 std::sort( sorted_overlap_order.begin(), sorted_overlap_order.end(),
IntPairComparator );
881 for(
unsigned ie = 0; ie < n_overlap_entitites; ++ie )
883 m_overlap->vecSourceFaceIx[ie] = std::get< 1 >( sorted_overlap_order[ie] );
884 m_overlap->vecTargetFaceIx[ie] = std::get< 2 >( sorted_overlap_order[ie] );
889 faces.resize( n_overlap_entitites );
895 std::map< EntityHandle, int > indxMap;
904 const unsigned iface = std::get< 0 >( sorted_overlap_order[ifac] );
905 Face&
face = faces[ifac];
913 face.edges.resize( nnodesf );
914 for(
int iverts = 0; iverts < nnodesf; ++iverts )
916 int indx = indxMap[connectface[iverts]];
918 face.SetNode( iverts, indx );
922 sorted_overlap_order.clear();
924 unsigned nnodes = verts.
size();
926 nodes.resize( nnodes );
929 std::vector< double > coordx( nnodes ), coordy( nnodes ), coordz( nnodes );
931 for(
unsigned inode = 0; inode < nnodes; ++inode )
933 Node& node = nodes[inode];
934 node.x = coordx[inode];
935 node.y = coordy[inode];
936 node.z = coordz[inode];
961 const bool fAllParallel,
962 const bool fInputConcave,
963 const bool fOutputConcave )
968 if( is_root && size == 1 )
970 this->m_source->CalculateFaceAreas( fInputConcave );
971 this->m_target->CalculateFaceAreas( fOutputConcave );
972 this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
980 this->m_source->CalculateFaceAreas( fInputConcave );
981 this->m_covering_source->CalculateFaceAreas( fInputConcave );
982 this->m_target->CalculateFaceAreas( fOutputConcave );
983 this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
988 this->m_source->CalculateFaceAreas( fInputConcave );
989 this->m_target->CalculateFaceAreas( fOutputConcave );
990 this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
1025 #ifndef MOAB_HAVE_MPI
1028 const int dimension,
1029 const int start_id )
1039 int idoffset = start_id;
1040 std::vector< int > gid( entities.
size() );
1041 for(
unsigned i = 0; i < entities.
size(); ++i )
1042 gid[i] = idoffset++;
1055 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 );
1061 const std::string& dofTagName,
1064 const int csResolution = std::sqrt( ntot_elements / 6.0 );
1065 if( csResolution * csResolution * 6 != ntot_elements )
return MB_INVALID_SIZE;
1070 if( GenerateCSMesh( csMesh, csResolution,
"",
"NetCDF4" ) )
1072 "Failed to generate CS mesh through TempestRemap" );
1075 if( this->
GenerateMeshMetadata( csMesh, ntot_elements, ents, secondary_ents, dofTagName, nP ) )
1076 MB_CHK_SET_ERR( moab::MB_FAILURE,
"Failed in call to GenerateMeshMetadata" );
1082 const int ntot_elements,
1085 const std::string& dofTagName,
1089 bool created =
false;
1092 "Failed creating DoF tag" );
1095 int nElements =
static_cast< int >( csMesh.faces.size() );
1100 DataArray3D< int > dataGLLnodes;
1101 dataGLLnodes.Allocate( nP, nP, nElements );
1103 std::map< Node, int > mapNodes;
1104 std::map< Node, moab::EntityHandle > mapLocalMBNodes;
1107 DataArray1D< double > dG;
1108 DataArray1D< double > dW;
1109 GaussLobattoQuadrature::GetPoints( nP, 0.0, 1.0, dG, dW );
1112 if( secondary_ents ) entities.
insert( secondary_ents->
begin(), secondary_ents->
end() );
1114 for(
unsigned iel = 0; iel < entities.
size(); ++iel )
1118 Node elCentroid( elcoords[0], elcoords[1], elcoords[2] );
1119 mapLocalMBNodes.insert( std::pair< Node, moab::EntityHandle >( elCentroid, eh ) );
1128 int* dofIDs =
new int[nP * nP];
1131 for(
int k = 0; k < nElements; k++ )
1133 const Face&
face = csMesh.faces[k];
1134 const NodeVector& nodes = csMesh.nodes;
1136 if(
face.edges.size() != 4 )
1138 _EXCEPTIONT(
"Mesh must only contain quadrilateral elements" );
1142 centroid.x = centroid.y = centroid.z = 0.0;
1143 for(
unsigned l = 0; l <
face.edges.size(); ++l )
1145 centroid.x += nodes[
face[l]].x;
1146 centroid.y += nodes[
face[l]].y;
1147 centroid.z += nodes[
face[l]].z;
1149 const double factor = 1.0 /
face.edges.size();
1150 centroid.x *= factor;
1151 centroid.y *= factor;
1152 centroid.z *= factor;
1154 bool locElem =
false;
1156 if( mapLocalMBNodes.find( centroid ) != mapLocalMBNodes.end() )
1159 current_eh = mapLocalMBNodes[centroid];
1162 for(
int j = 0; j < nP; j++ )
1164 for(
int i = 0; i < nP; i++ )
1179 const double& dAlpha = dG[i];
1180 const double& dBeta = dG[j];
1183 double dXc = nodes[
face[0]].x * ( 1.0 - dAlpha ) * ( 1.0 - dBeta ) +
1184 nodes[
face[1]].x * dAlpha * ( 1.0 - dBeta ) + nodes[
face[2]].x * dAlpha * dBeta +
1185 nodes[
face[3]].x * ( 1.0 - dAlpha ) * dBeta;
1187 double dYc = nodes[
face[0]].y * ( 1.0 - dAlpha ) * ( 1.0 - dBeta ) +
1188 nodes[
face[1]].y * dAlpha * ( 1.0 - dBeta ) + nodes[
face[2]].y * dAlpha * dBeta +
1189 nodes[
face[3]].y * ( 1.0 - dAlpha ) * dBeta;
1191 double dZc = nodes[
face[0]].z * ( 1.0 - dAlpha ) * ( 1.0 - dBeta ) +
1192 nodes[
face[1]].z * dAlpha * ( 1.0 - dBeta ) + nodes[
face[2]].z * dAlpha * dBeta +
1193 nodes[
face[3]].z * ( 1.0 - dAlpha ) * dBeta;
1195 double dR = sqrt( dXc * dXc + dYc * dYc + dZc * dZc );
1198 nodeGLL.x = dXc / dR;
1199 nodeGLL.y = dYc / dR;
1200 nodeGLL.z = dZc / dR;
1203 std::map< Node, int >::const_iterator iter = mapNodes.find( nodeGLL );
1204 if( iter == mapNodes.end() )
1207 int ixNode =
static_cast< int >( mapNodes.size() );
1208 mapNodes.insert( std::pair< Node, int >( nodeGLL, ixNode ) );
1209 dataGLLnodes[j][i][k] = ixNode + 1;
1213 dataGLLnodes[j][i][k] = iter->second + 1;
1216 dofIDs[j * nP + i] = dataGLLnodes[j][i][k];
1223 "Failed to tag_set_data for DoFs" );
1229 mapLocalMBNodes.clear();
1244 int nb_ghost_layers )
1246 if( nb_ghost_layers >= 1 ) gnomonic =
false;
1257 #ifdef MOAB_HAVE_MPI
1258 mbintx->set_parallel_comm( m_pcomm );
1268 #ifdef MOAB_HAVE_MPI
1274 "Can't create new set" );
1278 std::stringstream filename;
1279 filename <<
"covering" <<
rank <<
".h5m";
1281 std::stringstream targetFile;
1282 targetFile <<
"target" <<
rank <<
".h5m";
1292 "Can't create new set" );
1294 double tolerance = 1e-6, btolerance = 1e-3;
1302 for(
unsigned ie = 0; ie < targetVerts.
size(); ++ie )
1319 std::vector< moab::EntityHandle > leaf_elems;
1324 if( !leaf_elems.size() )
1332 std::vector< double > centroids( leaf_elems.size() * 3 );
1337 for(
size_t il = 0; il < leaf_elems.size(); ++il )
1339 const double* centroid = ¢roids[il * 3];
1340 const double locdist = std::pow( point[0] - centroid[0], 2 ) +
1341 std::pow( point[1] - centroid[1], 2 ) +
1342 std::pow( point[2] - centroid[2], 2 );
1344 if( locdist < dist )
1355 <<
": [Error] - Could not find a minimum distance within the leaf "
1357 << dist << std::endl;
1373 #ifdef MOAB_HAVE_MPI
1387 const bool outputEnabled = ( this->
rank == 0 );
1389 dbgprint.
set_prefix(
"[ComputeOverlapMesh]: " );
1409 bool concaveMeshA =
false, concaveMeshB =
false;
1414 "exact", concaveMeshA, concaveMeshB,
true,
false ) )
1415 MB_CHK_SET_ERR( MB_FAILURE,
"TempestRemap: cannot compute the intersection of meshes on the sphere" );
1422 if( outputEnabled )
dbgprint.printf( 0,
"Computing intersection mesh with the Kd-tree search algorithm" );
1424 "Can't compute the intersection of meshes on the sphere with kd-tree" );
1429 dbgprint.printf( 0,
"Computing intersection mesh with the advancing-front propagation algorithm" );
1431 "Can't compute the intersection of meshes on the sphere" );
1434 #ifdef MOAB_HAVE_MPI
1438 std::stringstream ffc, fft, ffo;
1439 ffc <<
"cover_" <<
rank <<
".h5m";
1440 fft <<
"target_" <<
rank <<
".h5m";
1441 ffo <<
"intx_" <<
rank <<
".h5m";
1454 std::map< int, int > loc_gid_to_lid_covsrc;
1455 std::vector< int > gids( covEnts.
size(), -1 );
1460 for(
unsigned ie = 0; ie < gids.size(); ++ie )
1462 assert( gids[ie] > 0 );
1463 loc_gid_to_lid_covsrc[gids[ie]] = ie;
1466 Range intxCov, intxCells;
1476 assert( srcParent >= 0 );
1477 intxCov.
insert( covEnts[loc_gid_to_lid_covsrc[srcParent]] );
1500 MB_CHK_ERR(
mb->get_connectivity( eh, conn, num_nodes ) );
1509 "Unable to find skin" );
1514 MB_CHK_ERR(
mb->get_connectivity( *it, conn, len,
false ) );
1515 for(
int ie = 0; ie < len; ++ie )
1517 std::vector< EntityHandle > adjacent_entities;
1519 for(
auto ent : adjacent_entities )
1520 notNeededCovCells.
erase( ent );
1525 std::string(
"sourcecoveragemesh_p" + std::to_string(
rank ) +
".h5m" ).c_str(),
1536 std::cout <<
" total participating elements in the covering set: " << intxCov.
size() <<
"\n";
1537 std::cout <<
" remove from coverage set elements that are not intersected: " << notNeededCovCells.
size()
1576 #ifdef MOAB_HAVE_MPI
1600 Range boundaryEdges;
1601 MB_CHK_ERR( skinner.find_skin( 0, this->m_target_entities,
false, boundaryEdges ) );
1605 Range boundaryCells;
1615 std::stringstream ffs;
1616 ffs <<
"boundaryCells_0" <<
rank <<
".h5m";
1623 std::set< int > targetBoundaryIds;
1629 "Can't get global id tag on target cell" );
1630 if( tid < 0 ) std::cout <<
" incorrect id for a target cell\n";
1631 targetBoundaryIds.insert( tid );
1637 std::set< int > affectedSourceCellsIds;
1638 Tag targetParentTag, sourceParentTag;
1641 for(
Range::iterator it = overlapCells.begin(); it != overlapCells.end(); ++it )
1644 int targetParentID, sourceParentID;
1646 if( targetBoundaryIds.find( targetParentID ) != targetBoundaryIds.end() )
1650 affectedSourceCellsIds.insert( sourceParentID );
1659 std::map< int, EntityHandle > affectedCovCellFromID;
1665 std::set< EntityHandle > affectedCovCells;
1670 for(
Range::iterator it = covCells.begin(); it != covCells.end(); ++it )
1675 if( affectedSourceCellsIds.find( covID ) != affectedSourceCellsIds.end() )
1678 affectedCovCellFromID[covID] = covCell;
1679 affectedCovCells.insert( covCell );
1690 std::map< int, std::set< EntityHandle > > overlapCellsForTask;
1693 std::set< EntityHandle > overlapCellsToSend;
1695 for(
Range::iterator it = overlapCells.begin(); it != overlapCells.end(); ++it )
1701 if( affectedSourceCellsIds.find( sourceParentID ) != affectedSourceCellsIds.end() )
1704 EntityHandle covCell = affectedCovCellFromID[sourceParentID];
1707 overlapCellsForTask[orgTask].insert( intxCell );
1709 overlapCellsToSend.insert( intxCell );
1718 for( std::set< EntityHandle >::iterator it = overlapCellsToSend.begin(); it != overlapCellsToSend.end(); ++it )
1724 if( maxEdges < nnodes ) maxEdges = nnodes;
1730 MPI_Allreduce( &maxEdges, &globalMaxEdges, 1, MPI_INT, MPI_MAX, m_pcomm->comm() );
1732 globalMaxEdges = maxEdges;
1735 if(
is_root ) std::cout <<
"maximum number of edges for polygons to send is " << globalMaxEdges <<
"\n";
1742 for( std::set< EntityHandle >::iterator it = overlapCellsToSend.begin(); it != overlapCellsToSend.end(); ++it )
1747 for( std::set< EntityHandle >::iterator it = affectedCovCells.begin(); it != affectedCovCells.end(); ++it )
1752 std::stringstream ffs2;
1754 ffs2 <<
"affectedCells_" << m_pcomm->rank() <<
".h5m";
1767 std::map< int, std::set< EntityHandle > > verticesOverlapForTask;
1769 std::set< EntityHandle > allVerticesToSend;
1770 std::map< EntityHandle, int > allVerticesToSendMap;
1772 int numOverlapCells = 0;
1773 for( std::map<
int, std::set< EntityHandle > >::iterator it = overlapCellsForTask.begin();
1774 it != overlapCellsForTask.end(); ++it )
1776 int sendToProc = it->first;
1777 const std::set< EntityHandle >& overlapCellsToSend2 = it->second;
1779 std::set< EntityHandle > vertices;
1780 for( std::set< EntityHandle >::iterator set_it = overlapCellsToSend2.begin();
1781 set_it != overlapCellsToSend2.end(); ++set_it )
1783 int nnodes_local = 0;
1786 for(
int k = 0; k < nnodes_local; k++ )
1787 vertices.insert( conn1[k] );
1789 verticesOverlapForTask[sendToProc] = vertices;
1790 numVerts += (int)vertices.size();
1791 numOverlapCells += (int)overlapCellsToSend2.size();
1792 allVerticesToSend.insert( vertices.begin(), vertices.end() );
1796 for( std::set< EntityHandle >::iterator vert_it = allVerticesToSend.begin(); vert_it != allVerticesToSend.end();
1800 allVerticesToSendMap[vert] = j;
1806 TLv.initialize( 2, 0, 0, 3, numVerts );
1807 TLv.enableWriteAccess();
1809 for( std::map<
int, std::set< EntityHandle > >::iterator it = verticesOverlapForTask.begin();
1810 it != verticesOverlapForTask.end(); ++it )
1812 int sendToProc = it->first;
1813 const std::set< EntityHandle >& vertices = it->second;
1815 for( std::set< EntityHandle >::iterator it2 = vertices.begin(); it2 != vertices.end(); ++it2, ++i )
1817 int n = TLv.get_n();
1818 TLv.vi_wr[2 * n] = sendToProc;
1820 int indexInAllVert = allVerticesToSendMap[v];
1821 TLv.vi_wr[2 * n + 1] = indexInAllVert;
1825 TLv.vr_wr[3 * n] = coords[0];
1826 TLv.vr_wr[3 * n + 1] = coords[1];
1827 TLv.vr_wr[3 * n + 2] = coords[2];
1833 int sizeTuple = 4 + globalMaxEdges;
1835 TLc.initialize( sizeTuple, 0, 0, 0,
1838 TLc.enableWriteAccess();
1840 for( std::map<
int, std::set< EntityHandle > >::iterator it = overlapCellsForTask.begin();
1841 it != overlapCellsForTask.end(); ++it )
1843 int sendToProc = it->first;
1844 const std::set< EntityHandle >& overlapCellsToSend2 = it->second;
1846 for( std::set< EntityHandle >::const_iterator it2 = overlapCellsToSend2.begin();
1847 it2 != overlapCellsToSend2.end(); ++it2 )
1850 int sourceParentID, targetParentID;
1853 int n = TLc.get_n();
1854 TLc.vi_wr[sizeTuple * n] = sendToProc;
1855 TLc.vi_wr[sizeTuple * n + 1] = sourceParentID;
1856 TLc.vi_wr[sizeTuple * n + 2] = targetParentID;
1860 TLc.vi_wr[sizeTuple * n + 3] = nnodes;
1861 for(
int i = 0; i < nnodes; i++ )
1863 int indexVertex = allVerticesToSendMap[conn[i]];
1865 if( -1 == indexVertex )
MB_CHK_SET_ERR( MB_FAILURE,
"Can't find vertex in range of vertices to send" );
1866 TLc.vi_wr[sizeTuple * n + 4 + i] = indexVertex;
1869 for(
int i = nnodes; i < globalMaxEdges; i++ )
1870 TLc.vi_wr[sizeTuple * n + 4 + i] = 0;
1879 std::stringstream ff1;
1880 ff1 <<
"TLc_" <<
rank <<
".txt";
1881 TLc.print_to_file( ff1.str().c_str() );
1882 std::stringstream ffv;
1883 ffv <<
"TLv_" <<
rank <<
".txt";
1884 TLv.print_to_file( ffv.str().c_str() );
1886 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, TLv, 0 );
1887 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, TLc, 0 );
1890 TLc.print_to_file( ff1.str().c_str() );
1891 TLv.print_to_file( ffv.str().c_str() );
1897 buffer.buffer_init( sizeTuple * TLc.get_n() * 2 );
1900 TLc.print_to_file( ff1.str().c_str() );
1911 std::map< int, std::map< int, int > > availVertexIndicesPerProcessor;
1912 int nv = TLv.get_n();
1913 for(
int i = 0; i < nv; i++ )
1916 int orgProc = TLv.vi_rd[2 * i];
1917 int indexVert = TLv.vi_rd[2 * i + 1];
1918 availVertexIndicesPerProcessor[orgProc][indexVert] = i;
1928 int n = TLc.get_n();
1929 std::map< int, int > currentProcsCount;
1933 std::map< int, std::set< int > > sourcesForTasks;
1937 int currentSourceID = TLc.vi_rd[sizeTuple * 0 + 1];
1938 int proc0 = TLc.vi_rd[sizeTuple * 0];
1939 currentProcsCount[proc0] = 1;
1941 for(
int i = 1; i < n; i++ )
1943 int proc = TLc.vi_rd[sizeTuple * i];
1944 int sourceID = TLc.vi_rd[sizeTuple * i + 1];
1945 if( sourceID == currentSourceID )
1947 if( currentProcsCount.find( proc ) == currentProcsCount.end() )
1949 currentProcsCount[proc] = 1;
1952 currentProcsCount[proc]++;
1954 if( sourceID != currentSourceID || ( ( n - 1 ) == i ) )
1958 if( currentProcsCount.size() > 1 )
1961 std::cout <<
" source element " << currentSourceID <<
" intersects with "
1962 << currentProcsCount.size() <<
" target partitions\n";
1963 for( std::map< int, int >::iterator it = currentProcsCount.begin(); it != currentProcsCount.end();
1966 int procID = it->first;
1967 int numOverCells = it->second;
1968 std::cout <<
" task:" << procID <<
" " << numOverCells <<
" cells\n";
1973 for( std::map< int, int >::iterator it1 = currentProcsCount.begin(); it1 != currentProcsCount.end();
1976 int proc1 = it1->first;
1977 sourcesForTasks[currentSourceID].insert( proc1 );
1978 for( std::map< int, int >::iterator it2 = currentProcsCount.begin();
1979 it2 != currentProcsCount.end(); ++it2 )
1981 int proc2 = it2->first;
1982 if( proc1 != proc2 ) sizeOfTLc2 += it2->second;
1987 if( sourceID != currentSourceID )
1989 currentSourceID = sourceID;
1990 currentProcsCount.clear();
1991 currentProcsCount[proc] = 1;
2000 std::cout <<
" need to initialize TLc2 with " << sizeOfTLc2 <<
" cells\n ";
2004 int sizeTuple2 = 5 + globalMaxEdges;
2007 TLc2.initialize( sizeTuple2, 0, 0, 0, sizeOfTLc2 );
2008 TLc2.enableWriteAccess();
2011 std::map< int, std::set< int > > verticesToSendForProc;
2013 for(
int i = 0; i < n; i++ )
2015 int sourceID = TLc.vi_rd[sizeTuple * i + 1];
2016 if( sourcesForTasks.find( sourceID ) != sourcesForTasks.end() )
2019 std::set< int > procs = sourcesForTasks[sourceID];
2020 if( procs.size() < 2 )
MB_CHK_SET_ERR( MB_FAILURE,
" not enough processes involved with a sourceID cell" );
2022 int orgProc = TLc.vi_rd[sizeTuple * i];
2025 std::map< int, int >& availableVerticesFromThisProc = availVertexIndicesPerProcessor[orgProc];
2026 for( std::set< int >::iterator setIt = procs.begin(); setIt != procs.end(); ++setIt )
2028 int procID = *setIt;
2031 if( procID != orgProc )
2034 int n2 = TLc2.get_n();
2035 if( n2 >= sizeOfTLc2 )
MB_CHK_SET_ERR( MB_FAILURE,
" memory overflow" );
2037 std::set< int >& indexVerticesInTLv = verticesToSendForProc[procID];
2038 TLc2.vi_wr[n2 * sizeTuple2] = procID;
2039 TLc2.vi_wr[n2 * sizeTuple2 + 1] = orgProc;
2040 TLc2.vi_wr[n2 * sizeTuple2 + 2] = sourceID;
2041 TLc2.vi_wr[n2 * sizeTuple2 + 3] = TLc.vi_rd[sizeTuple * i + 2];
2043 int nvert = TLc.vi_rd[sizeTuple * i + 3];
2044 TLc2.vi_wr[n2 * sizeTuple2 + 4] = nvert;
2049 for(
int j = 0; j < nvert; j++ )
2051 int vertexIndex = TLc.vi_rd[i * sizeTuple + 4 + j];
2053 if( availableVerticesFromThisProc.find( vertexIndex ) == availableVerticesFromThisProc.end() )
2055 MB_CHK_SET_ERR( MB_FAILURE,
" vertex index not available from processor" );
2057 TLc2.vi_wr[n2 * sizeTuple2 + 5 + j] = vertexIndex;
2058 int indexInTLv = availVertexIndicesPerProcessor[orgProc][vertexIndex];
2059 indexVerticesInTLv.insert( indexInTLv );
2062 for(
int j = nvert; j < globalMaxEdges; j++ )
2064 TLc2.vi_wr[n2 * sizeTuple2 + 5 + j] = 0;
2078 for( std::map<
int, std::set< int > >::iterator it = verticesToSendForProc.begin();
2079 it != verticesToSendForProc.end(); ++it )
2081 const std::set< int >& indexInTLvSet = it->second;
2082 numVerts2 += (int)indexInTLvSet.size();
2084 TLv2.initialize( 3, 0, 0, 3,
2086 TLv2.enableWriteAccess();
2087 for( std::map<
int, std::set< int > >::iterator it = verticesToSendForProc.begin();
2088 it != verticesToSendForProc.end(); ++it )
2090 int sendToProc = it->first;
2091 const std::set< int >& indexInTLvSet = it->second;
2093 for( std::set< int >::iterator itSet = indexInTLvSet.begin(); itSet != indexInTLvSet.end(); ++itSet )
2095 int indexInTLv = *itSet;
2096 int orgProc = TLv.vi_rd[2 * indexInTLv];
2097 int indexVertexInOrgProc = TLv.vi_rd[2 * indexInTLv + 1];
2098 int nv2 = TLv2.get_n();
2099 TLv2.vi_wr[3 * nv2] = sendToProc;
2100 TLv2.vi_wr[3 * nv2 + 1] = orgProc;
2101 TLv2.vi_wr[3 * nv2 + 2] = indexVertexInOrgProc;
2102 for(
int j = 0; j < 3; j++ )
2103 TLv2.vr_wr[3 * nv2 + j] =
2104 TLv.vr_rd[3 * indexInTLv + j];
2109 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, TLv2, 0 );
2110 ( m_pcomm->proc_config().crystal_router() )->gs_transfer( 1, TLc2, 0 );
2114 std::stringstream ff2;
2115 ff2 <<
"TLc2_" <<
rank <<
".txt";
2116 TLc2.print_to_file( ff2.str().c_str() );
2117 std::stringstream ffv2;
2118 ffv2 <<
"TLv2_" <<
rank <<
".txt";
2119 TLv2.print_to_file( ffv2.str().c_str() );
2128 int nvNew = TLv2.get_n();
2136 std::map< int, std::map< int, EntityHandle > > vertexPerProcAndIndex;
2137 for(
int i = 0; i < nvNew; i++ )
2139 int orgProc = TLv2.vi_rd[3 * i + 1];
2140 int indexInVert = TLv2.vi_rd[3 * i + 2];
2141 vertexPerProcAndIndex[orgProc][indexInVert] = newVerts[i];
2149 int ne = TLc2.get_n();
2150 for(
int i = 0; i < ne; i++ )
2152 int orgProc = TLc2.vi_rd[i * sizeTuple2 + 1];
2153 int sourceID = TLc2.vi_rd[i * sizeTuple2 + 2];
2154 int targetID = TLc2.vi_wr[i * sizeTuple2 + 3];
2155 int nve = TLc2.vi_wr[i * sizeTuple2 + 4];
2156 std::vector< EntityHandle > conn;
2158 for(
int j = 0; j < nve; j++ )
2160 int indexV = TLc2.vi_wr[i * sizeTuple2 + 5 + j];
2161 EntityHandle vh = vertexPerProcAndIndex[orgProc][indexV];
2166 newPolygons.insert( polyNew );
2178 std::stringstream ffs4;
2179 ffs4 <<
"extraIntxCells" <<
rank <<
".h5m";
2199 "Trouble creating GRID_IMASK tag" );
2208 "Trouble getting GRID_IMASK tag" );
2214 "Trouble getting GRID_IMASK tag" );
2223 "Trouble getting GRID_IMASK tag" );
2229 "Trouble getting GRID_IMASK tag" );