28 std::vector< EntityHandle >& VerticesSubEdges,
30 std::vector< EntityHandle >& chainVertices,
31 std::vector< int >& polygonIds,
34 int numEdges = (int)subEdges.size();
38 chainVertices.push_back( currentVertex );
40 std::vector< EntityHandle > chain;
41 std::vector< int > markedEdge( numEdges, 0 );
43 for(
int i = 0; i < numEdges; i++ )
45 for(
int j = 0; j < numEdges; j++ )
47 if( 0 != markedEdge[j] )
continue;
48 if( VerticesSubEdges[j * 2] == currentVertex )
50 currentVertex = VerticesSubEdges[j * 2 + 1];
51 chainVertices.push_back( currentVertex );
52 chain.push_back( subEdges[j] );
56 if( VerticesSubEdges[j * 2 + 1] == currentVertex )
58 currentVertex = VerticesSubEdges[j * 2];
59 chainVertices.push_back( currentVertex );
60 chain.push_back( subEdges[j] );
66 if( (
int)chain.size() == numEdges && currentVertex == endVertex )
71 for(
int j = 0; j < (int)chain.size(); j++ )
74 std::vector< EntityHandle > intxPolys;
79 polygonIds.push_back( global_id );
90 Tag parentTag, otherParentTag;
111 std::cout <<
" number of original input edges:" << initialEdges.
size() <<
"\n";
120 std::cout <<
" number of intx edges:" << intxEdges.
size() <<
"\n";
124 std::vector< int > parentGids( parentCells.
size() );
127 std::map< int, double > initAreas;
129 std::vector< double > coords( 3 * 20 );
133 std::map< int, double > recoveredAreas;
134 std::map< int, EntityHandle > mapFromGIDToParent;
135 std::map< int, std::vector< EntityHandle > > mapFromParentGIDToIntxCells;
145 int parentID = parentGids[i];
146 initAreas[parentID] = area;
147 recoveredAreas[parentID] = 0.;
148 mapFromGIDToParent[parentID] = parentCell;
149 mapFromParentGIDToIntxCells[parentID];
161 recoveredAreas[parentID] += intx_area;
162 mapFromParentGIDToIntxCells[parentID].push_back( cell );
164 int recovered = 0, notRecovered = 0;
166 for(
size_t j = 0; j < parentGids.size(); j++ )
168 int parentID = parentGids[j];
170 double areaDiff = initAreas[parentID] - recoveredAreas[parentID];
172 double numIntxcells =
static_cast< double >( mapFromParentGIDToIntxCells[parentID].size() );
174 if( fabs( areaDiff ) < areaTolerance )
182 std::cout <<
"recovered initial cells: " << recovered <<
" vs:" << notRecovered <<
" not recovered \n";
184 Range recoverableEdges;
188 int recoveredEdges = 0;
190 int identity_edges = 0;
191 std::map< EntityHandle, std::vector< EntityHandle > > mapEdges;
199 mapEdges[initialEdge].push_back( initialEdge );
202 double numSubEdges = 1.;
213 adjPolys =
subtract( adjPolys, parentCells );
223 Range initialAdjCells;
225 if( initialAdjCells.
size() == 0 )
MB_CHK_SET_ERR( MB_FAILURE,
"no adjacent initial cells" );
228 if( adjRecoveredInitialCell.
size() == 0 )
229 MB_CHK_SET_ERR( MB_FAILURE,
"no adjacent initial cells that are recovered" );
231 EntityHandle recoveredCell = adjRecoveredInitialCell[0];
235 int cellGlobalId = 0;
238 std::vector< EntityHandle >& listIntxCells = mapFromParentGIDToIntxCells[cellGlobalId];
239 std::vector< EntityHandle > candidateEdges;
248 rval =
mb->
get_coords( connEdge, numVerts, verticesOriginal[0].array() );
MB_CHK_SET_ERR( rval,
"can't get coordinates of vertices of initial edge" );
250 int gnomonicPlane = 0;
257 angle_robust( verticesOriginal[0], verticesOriginal[1] );
259 double recoveredLength = 0.;
260 std::vector< EntityHandle > VerticesSubEdges;
261 for(
size_t i = 0; i < candidateEdges.size(); i++ )
268 rval =
mb->
get_coords( connEdge2, numVerts, verticesSubEdge[0].array() );
MB_CHK_SET_ERR( rval,
"can't get coordinates of vertices of initial edge" );
271 for(
int j = 0; j < 2 && onEdge; j++ )
276 double areaAbs = fabs(
IntxUtils::area2D( &coords2D[0], &coords2D[2], &coords2D[4] ) );
278 if( areaAbs > 1.e-14 ) onEdge =
false;
282 double subEdgeLen =
angle_robust( verticesSubEdge[0], verticesSubEdge[1] );
283 recoveredLength += subEdgeLen;
284 mapEdges[initialEdge].push_back( subedge );
285 VerticesSubEdges.push_back( connEdge2[0] );
286 VerticesSubEdges.push_back( connEdge2[1] );
289 double fraction = recoveredLength / edgeLength;
291 double numSubEdge = double( mapEdges[initialEdge].size() );
300 if( fabs( edgeLength - recoveredLength ) < 1.e-10 || rval ==
MB_SUCCESS )
305 std::vector< EntityHandle >& listSubEdges = mapEdges[initialEdge];
306 double newCheckLength = 0;
311 rval =
mb->
get_coords( conn2, numVerts2, vertices[0].array() );
MB_CHK_SET_ERR( rval,
"can't get coordinates of vertices of initial edge" );
312 double length2 =
angle_robust( vertices[0], vertices[1] );
313 std::cout << std::setprecision( 14 );
314 std::cout <<
" initial edge:" <<
mb->
id_from_handle( initialEdge ) <<
" v: " << conn2[0] <<
", " << conn2[1]
315 <<
" len: " << length2 <<
"\n";
316 for(
size_t j = 0; j < listSubEdges.size(); j++ )
320 rval =
mb->
get_coords( conn2, numVerts2, vertices[0].array() );
MB_CHK_SET_ERR( rval,
"can't get coordinates of vertices of subedge" );
322 newCheckLength += length2;
323 std::cout <<
" sub edge:" <<
mb->
id_from_handle( subEdge ) <<
" v: " << conn2[0] <<
", " << conn2[1]
324 <<
" len: " << length2 <<
"\n";
326 std::cout <<
" edge length:" << edgeLength <<
" newCheckLength:" << newCheckLength
327 <<
" diff:" << edgeLength - newCheckLength <<
" fraction:" << fraction
328 <<
" subedges:" << numSubEdge <<
"\n";
330 std::cout << std::setprecision( 7 );
334 std::cout <<
" recoveredEdges:" << recoveredEdges <<
" identity edges:" << identity_edges
335 <<
" unrecovered edges:" << unrecovered <<
"\n";
339 #ifdef MOAB_HAVE_PNETCDF
341 ErrorCode Intx2MeshEdges::write_edge_map_parallel(
const char* fileName )
345 int ncell_dimid, max_edge_dimid, max_sub_edge_dimid, max_sub_edgeP1_dimid;
349 if( ( retval = ncmpi_create( parcomm->comm(), fileName, NC_CLOBBER | NC_64BIT_DATA, MPI_INFO_NULL, &ncid ) ) )
355 num_cells_local = (int)polys.
size();
359 MPI_Allreduce( &num_cells_local, &num_cells, 1, MPI_INTEGER, MPI_SUM, parcomm->comm() );
361 if( ( retval = ncmpi_def_dim( ncid,
"num_cells", num_cells, &ncell_dimid ) ) ) ERR( retval );
364 std::vector< int > global_ids_polys( num_cells_local );
367 std::copy( global_ids_polys.rbegin(), global_ids_polys.rend(),
range_inserter( localGidCells ) );
370 int max_edge = -1, max_sub_edge = -1, max_subedge1 = -1;
372 for(
auto it = polys.
begin(); it != polys.
end(); ++it )
378 if( max_edge < nv ) max_edge = nv;
382 MPI_Allreduce( &max_edge, &max_edgeg, 1, MPI_INTEGER, MPI_MAX, parcomm->comm() );
383 if( ( retval = ncmpi_def_dim( ncid,
"max_edges", max_edgeg, &max_edge_dimid ) ) ) ERR( retval );
384 max_edge = max_edgeg;
387 int nsb = (int)mapit->second.size();
388 if( max_sub_edge < nsb ) max_sub_edge = nsb;
390 int max_sub_edgeg = 0;
392 MPI_Allreduce( &max_sub_edge, &max_sub_edgeg, 1, MPI_INTEGER, MPI_MAX, parcomm->comm() );
393 if( ( retval = ncmpi_def_dim( ncid,
"max_sub_edges", max_sub_edgeg, &max_sub_edge_dimid ) ) ) ERR( retval );
394 max_sub_edge = max_sub_edgeg;
395 max_subedge1 = max_sub_edge + 1;
396 if( ( retval = ncmpi_def_dim( ncid,
"max_sub_edges1", max_subedge1, &max_sub_edgeP1_dimid ) ) ) ERR( retval );
400 dimids_nbs[0] = ncell_dimid;
401 dimids_nbs[1] = max_edge_dimid;
403 if( ( retval = ncmpi_def_var( ncid,
"nb_sub_edge", NC_INT, 2, dimids_nbs, &varid_nsub ) ) ) ERR( retval );
405 int dimids_cell_assoc[3];
406 dimids_cell_assoc[0] = ncell_dimid;
407 dimids_cell_assoc[1] = max_edge_dimid;
408 dimids_cell_assoc[2] = max_sub_edge_dimid;
409 int varid_cell_assoc;
410 if( ( retval = ncmpi_def_var( ncid,
"cells_assoc", NC_INT, 3, dimids_cell_assoc, &varid_cell_assoc ) ) )
413 dimids_cell_assoc[2] = max_sub_edgeP1_dimid;
414 int varid_lat, varid_lon;
415 if( ( retval = ncmpi_def_var( ncid,
"lat_sub_edge", NC_DOUBLE, 3, dimids_cell_assoc, &varid_lat ) ) ) ERR( retval );
416 if( ( retval = ncmpi_def_var( ncid,
"lon_sub_edge", NC_DOUBLE, 3, dimids_cell_assoc, &varid_lon ) ) ) ERR( retval );
418 ncmpi_enddef( ncid );
425 std::vector< int > nb_sub_edge_per_edge( num_cells_local * max_edge, -9999 );
426 std::vector< int > cells_assoc_per_edge( num_cells_local * max_edge * max_sub_edge, -9999 );
428 std::vector< double > latvals( num_cells_local * max_edge * max_subedge1, -9999 );
429 std::vector< double > lonvals( num_cells_local * max_edge * max_subedge1, -9999 );
436 int indexGidPoly = localGidCells.
index( gidPoly );
441 for(
int i = 0; i < nv; i++ )
445 v[1] = conn[( i + 1 ) % nv];
451 nb_sub_edge_per_edge[indexGidPoly * max_edge + i] = (int)poly_assoc.size();
453 std::vector< CartVect > coords( vertexEdges.size() );
454 rval =
mb->
get_coords( &vertexEdges[0], vertexEdges.size(), &( coords[0][0] ) );
MB_CHK_SET_ERR( rval,
"can't get coordinates" );
456 std::vector< double > latv( vertexEdges.size() ), lonv( vertexEdges.size() );
457 for(
int j = 0; j < (int)vertexEdges.size(); j++ )
467 bool reverse =
false;
468 if( v[0] == edgeconn[1] ) reverse =
true;
472 int sizep = (int)poly_assoc.size();
473 for(
int j = 0; j < sizep; j++ )
475 cells_assoc_per_edge[indexGidPoly * max_edge * max_sub_edge + i * max_sub_edge + j] =
476 poly_assoc[sizep - 1 - j];
478 sizep = (int)vertexEdges.size();
479 for(
int j = 0; j < sizep; j++ )
481 latvals[indexGidPoly * max_edge * max_subedge1 + i * max_subedge1 + j] = latv[sizep - 1 - j];
482 lonvals[indexGidPoly * max_edge * max_subedge1 + i * max_subedge1 + j] = lonv[sizep - 1 - j];
488 for(
int j = 0; j < (int)poly_assoc.size(); j++ )
490 cells_assoc_per_edge[indexGidPoly * max_edge * max_sub_edge + i * max_sub_edge + j] = poly_assoc[j];
492 for(
int j = 0; j < (int)vertexEdges.size(); j++ )
494 latvals[indexGidPoly * max_edge * max_subedge1 + i * max_subedge1 + j] = latv[j];
495 lonvals[indexGidPoly * max_edge * max_subedge1 + i * max_subedge1 + j] = lonv[j];
502 size_t nb_writes = localGidCells.
psize();
503 std::vector< int > requests( nb_writes * 4 );
504 std::vector< int > statuss( nb_writes * 4 );
506 size_t indexInArray1 = 0;
507 size_t indexInArray2 = 0;
508 size_t indexInArray3 = 0;
510 for( Range::pair_iterator pair_iter = localGidCells.
pair_begin(); pair_iter != localGidCells.
pair_end();
515 MPI_Offset write_start[3], write_count[3];
516 write_start[0] =
static_cast< MPI_Offset
>( starth - 1 );
517 write_start[1] =
static_cast< MPI_Offset
>( 0 );
518 write_start[2] =
static_cast< MPI_Offset
>( 0 );
519 write_count[0] =
static_cast< MPI_Offset
>( endh - starth + 1 );
520 write_count[1] =
static_cast< MPI_Offset
>( max_edge );
521 write_count[2] =
static_cast< MPI_Offset
>( max_sub_edge );
523 if( ( retval = ncmpi_iput_vara_int( ncid, varid_nsub, write_start, write_count,
524 &nb_sub_edge_per_edge[indexInArray1], &requests[idxReq++] ) ) )
526 indexInArray1 += ( endh - starth + 1 ) * max_edge;
528 if( ( retval = ncmpi_iput_vara_int( ncid, varid_cell_assoc, write_start, write_count,
529 &cells_assoc_per_edge[indexInArray2], &requests[idxReq++] ) ) )
531 indexInArray2 += ( endh - starth + 1 ) * max_edge * max_sub_edge;
533 write_count[2] = max_subedge1;
535 if( ( retval = ncmpi_iput_vara_double( ncid, varid_lat, write_start, write_count,
536 &latvals[indexInArray3], &requests[idxReq++] ) ) )
539 if( ( retval = ncmpi_iput_vara_double( ncid, varid_lon, write_start, write_count,
540 &lonvals[indexInArray3], &requests[idxReq++] ) ) )
543 indexInArray3 += ( endh - starth + 1 ) * max_edge * max_subedge1;
546 if( ( retval = ncmpi_wait_all( ncid, requests.size(), &requests[0], &statuss[0] ) ) ) ERR( retval );
547 if( ( retval = ncmpi_close( ncid ) ) ) ERR( retval );
553 #ifdef MOAB_HAVE_NETCDF
554 ErrorCode Intx2MeshEdges::write_edge_map(
const char* filename )
562 int ncell_dimid, max_edge_dimid, max_sub_edge_dimid, max_sub_edgeP1_dimid;
564 if( ( retval = nc_create( filename, NC_CLASSIC_MODEL | NC_CLOBBER, &ncid ) ) ) ERRN( retval );
568 num_cells = (int)polys.size();
570 if( ( retval = nc_def_dim( ncid,
"num_cells", num_cells, &ncell_dimid ) ) ) ERRN( retval );
574 int max_edge = -1, max_sub_edge = -1, max_subedge1 = -1;
576 for(
auto it = polys.begin(); it != polys.end(); ++it )
582 if( max_edge < nv ) max_edge = nv;
584 if( ( retval = nc_def_dim( ncid,
"max_edges", max_edge, &max_edge_dimid ) ) ) ERRN( retval );
588 int nsb = (int)mapit->second.size();
589 if( max_sub_edge < nsb ) max_sub_edge = nsb;
591 if( ( retval = nc_def_dim( ncid,
"max_sub_edges", max_sub_edge, &max_sub_edge_dimid ) ) ) ERRN( retval );
592 max_subedge1 = max_sub_edge + 1;
593 if( ( retval = nc_def_dim( ncid,
"max_sub_edges1", max_subedge1, &max_sub_edgeP1_dimid ) ) ) ERRN( retval );
597 dimids_nbs[0] = ncell_dimid;
598 dimids_nbs[1] = max_edge_dimid;
600 if( ( retval = nc_def_var( ncid,
"nb_sub_edge", NC_INT, 2, dimids_nbs, &varid_nsub ) ) ) ERRN( retval );
602 int dimids_cell_assoc[3];
603 dimids_cell_assoc[0] = ncell_dimid;
604 dimids_cell_assoc[1] = max_edge_dimid;
605 dimids_cell_assoc[2] = max_sub_edge_dimid;
606 int varid_cell_assoc;
607 if( ( retval = nc_def_var( ncid,
"cells_assoc", NC_INT, 3, dimids_cell_assoc, &varid_cell_assoc ) ) )
610 dimids_cell_assoc[2] = max_sub_edgeP1_dimid;
611 int varid_lat, varid_lon;
612 if( ( retval = nc_def_var( ncid,
"lat_sub_edge", NC_DOUBLE, 3, dimids_cell_assoc, &varid_lat ) ) ) ERRN( retval );
613 if( ( retval = nc_def_var( ncid,
"lon_sub_edge", NC_DOUBLE, 3, dimids_cell_assoc, &varid_lon ) ) ) ERRN( retval );
617 std::vector< int > nb_sub_edge_per_edge( num_cells * max_edge, -9999 );
618 std::vector< int > cells_assoc_per_edge( num_cells * max_edge * max_sub_edge, -9999 );
620 std::vector< double > latvals( num_cells * max_edge * max_subedge1, -9999 );
621 std::vector< double > lonvals( num_cells * max_edge * max_subedge1, -9999 );
631 for(
int i = 0; i < nv; i++ )
635 v[1] = conn[( i + 1 ) % nv];
641 nb_sub_edge_per_edge[( gidPoly - 1 ) * max_edge + i] = (
int)poly_assoc.size();
643 std::vector< CartVect > coords( vertexEdges.size() );
644 rval =
mb->
get_coords( &vertexEdges[0], vertexEdges.size(), &( coords[0][0] ) );
MB_CHK_SET_ERR( rval,
"can't get coordinates" );
646 std::vector< double > latv( vertexEdges.size() ), lonv( vertexEdges.size() );
647 for(
int j = 0; j < (int)vertexEdges.size(); j++ )
657 bool reverse =
false;
658 if( v[0] == edgeconn[1] ) reverse =
true;
662 int sizep = (int)poly_assoc.size();
663 for(
int j = 0; j < sizep; j++ )
665 cells_assoc_per_edge[( gidPoly - 1 ) * max_edge * max_sub_edge + i * max_sub_edge + j] =
666 poly_assoc[sizep - 1 - j];
668 sizep = (int)vertexEdges.size();
669 for(
int j = 0; j < sizep; j++ )
671 latvals[( gidPoly - 1 ) * max_edge * max_subedge1 + i * max_subedge1 + j] = latv[sizep - 1 - j];
672 lonvals[( gidPoly - 1 ) * max_edge * max_subedge1 + i * max_subedge1 + j] = lonv[sizep - 1 - j];
678 for(
int j = 0; j < (int)poly_assoc.size(); j++ )
680 cells_assoc_per_edge[( gidPoly - 1 ) * max_edge * max_sub_edge + i * max_sub_edge + j] =
683 for(
int j = 0; j < (int)vertexEdges.size(); j++ )
685 latvals[( gidPoly - 1 ) * max_edge * max_subedge1 + i * max_subedge1 + j] = latv[j];
686 lonvals[( gidPoly - 1 ) * max_edge * max_subedge1 + i * max_subedge1 + j] = lonv[j];
692 if( ( retval = nc_put_var_int( ncid, varid_nsub, &nb_sub_edge_per_edge[0] ) ) ) ERRN( retval );
694 if( ( retval = nc_put_var_int( ncid, varid_cell_assoc, &cells_assoc_per_edge[0] ) ) ) ERRN( retval );
696 if( ( retval = nc_put_var_double( ncid, varid_lat, &latvals[0] ) ) ) ERRN( retval );
698 if( ( retval = nc_put_var_double( ncid, varid_lon, &lonvals[0] ) ) ) ERRN( retval );
700 if( ( retval = nc_close( ncid ) ) ) ERRN( retval );