Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
Public Member Functions | |
int | num_parts () const |
iMeshP_Part | part_id_from_local_id (int local_id) const |
int | local_id_from_part_id (iMeshP_Part part) const |
int | rank_from_part_id (iMeshP_Part part) const |
int | rank_from_local_id (int id) const |
int | count_from_rank (int rank) const |
void | part_id_from_rank (int rank, std::vector< iMeshP_Part > &parts) const |
void | local_id_from_rank (int rank, std::vector< int > &ids) const |
const std::vector< iMeshP_Part > & | get_parts () const |
const std::vector< int > & | get_ranks () const |
int | build_map (iMesh_Instance imesh, iMeshP_PartitionHandle partition, int num_expected_parts) |
Static Public Member Functions | |
static int | part_from_coords (iMesh_Instance imesh, iMeshP_PartHandle part, int &id_out) |
Private Member Functions | |
int | idx_from_part_id (iMeshP_Part id) const |
int | idx_from_local_id (int id) const |
Private Attributes | |
std::vector< iMeshP_Part > | sortedPartList |
std::vector< int > | partRanks |
std::vector< int > | partLocalIds |
std::vector< int > | localIdReverseMap |
Definition at line 232 of file MOAB_iMeshP_unit_tests.cpp.
int PartMap::build_map | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | partition, | ||
int | num_expected_parts | ||
) |
Definition at line 2886 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, get_local_parts(), localIdReverseMap, part_from_coords(), partLocalIds, partRanks, size, and sortedPartList.
Referenced by create_mesh_in_memory(), and test_load().
{ int ierr, rank, size; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); MPI_Comm_size( MPI_COMM_WORLD, &size ); // get local parts std::vector< iMeshP_PartHandle > local_parts; std::vector< iMeshP_Part > imesh_ids; ierr = get_local_parts( imesh, prtn, local_parts, &imesh_ids );CHKERR; // get logical ids for local parts std::vector< int > local_ids( local_parts.size() ); for( size_t i = 0; i < local_parts.size(); ++i ) { ierr = part_from_coords( imesh, local_parts[i], local_ids[i] );CHKERR; } // get total number of parts int num_global = 0, num_local = local_parts.size(); ierr = MPI_Allreduce( &num_local, &num_global, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );CHKERR; if( num_global != num_expected_parts ) { std::cerr << "Invalid/unexpected global part count at " __FILE__ ":" << __LINE__ << " (proc " << rank << "): " << std::endl << " Expected: " << num_expected_parts << std::endl << " Actual: " << num_global << std::endl; return 1; } // get counts and displacements for Allgatherv calls std::vector< int > dspls( size ), counts( size ); ierr = MPI_Allgather( &num_local, 1, MPI_INT, &counts[0], 1, MPI_INT, MPI_COMM_WORLD );CHKERR; dspls[0] = 0; for( int i = 1; i < size; ++i ) dspls[i] = dspls[i - 1] + counts[i - 1]; // gather iMeshP_Part list from each processor std::vector< unsigned > global_part_ids( num_expected_parts ); assert( sizeof( iMeshP_Part ) == sizeof( int ) ); ierr = MPI_Allgatherv( &imesh_ids[0], num_local, MPI_UNSIGNED, &global_part_ids[0], &counts[0], &dspls[0], MPI_UNSIGNED, MPI_COMM_WORLD );CHKERR; // gather local ids from each processor std::vector< int > global_id_list( num_expected_parts ); ierr = MPI_Allgatherv( &local_ids[0], num_local, MPI_INT, &global_id_list[0], &counts[0], &dspls[0], MPI_INT, MPI_COMM_WORLD );CHKERR; // build owner list std::vector< int > global_owners( num_expected_parts ); for( int i = 0; i < size; ++i ) for( int j = 0; j < counts[i]; ++j ) global_owners[dspls[i] + j] = i; // populate member lists sortedPartList = global_part_ids; std::sort( sortedPartList.begin(), sortedPartList.end() ); partLocalIds.resize( num_expected_parts ); partRanks.resize( num_expected_parts ); for( int i = 0; i < num_expected_parts; ++i ) { int idx = std::lower_bound( sortedPartList.begin(), sortedPartList.end(), global_part_ids[i] ) - sortedPartList.begin(); partLocalIds[idx] = global_id_list[i]; partRanks[idx] = global_owners[i]; } // do some consistency checking if( std::unique( sortedPartList.begin(), sortedPartList.end() ) != sortedPartList.end() ) { if( rank == 0 ) { std::cerr << "ERROR: Duplicate iMeshP_Part values detected at " __FILE__ ":" << __LINE__ << std::endl; } return 1; } // build revesre local id map and check for duplicates localIdReverseMap.clear(); localIdReverseMap.resize( num_expected_parts, -1 ); for( int i = 0; i < num_expected_parts; ++i ) { int idx = partLocalIds[i]; if( localIdReverseMap[idx] != -1 ) { if( rank == 0 ) { std::cerr << "ERROR: Part mesh has been duplicated in multiple parts." << std::endl << " Detected at " __FILE__ ":" << __LINE__ << std::endl << " See PartMap::part_from_coords" << std::endl; } return 1; } if( idx >= num_expected_parts ) { if( rank == 0 ) { std::cerr << "ERROR: Part mesh invalid/incorrect mesh." << std::endl << " Detected at " __FILE__ ":" << __LINE__ << std::endl << " See PartMap::part_from_coords" << std::endl; } return 1; } localIdReverseMap[idx] = i; } return 0; }
int PartMap::count_from_rank | ( | int | rank | ) | const [inline] |
Definition at line 260 of file MOAB_iMeshP_unit_tests.cpp.
References partRanks.
Referenced by test_get_parts().
const std::vector< iMeshP_Part >& PartMap::get_parts | ( | ) | const [inline] |
Definition at line 269 of file MOAB_iMeshP_unit_tests.cpp.
References sortedPartList.
Referenced by get_part_boundary_verts(), test_entity_copy_parts(), test_exchange_ents(), test_get_part_boundary(), test_part_boundary_iter(), and test_part_rank().
{ return sortedPartList; }
const std::vector< int >& PartMap::get_ranks | ( | ) | const [inline] |
Definition at line 274 of file MOAB_iMeshP_unit_tests.cpp.
References partRanks.
Referenced by test_part_rank().
{ return partRanks; }
int PartMap::idx_from_local_id | ( | int | id | ) | const [inline, private] |
Definition at line 288 of file MOAB_iMeshP_unit_tests.cpp.
References localIdReverseMap.
Referenced by part_id_from_local_id(), and rank_from_local_id().
{ return localIdReverseMap[id]; }
int PartMap::idx_from_part_id | ( | iMeshP_Part | id | ) | const [inline, private] |
Definition at line 284 of file MOAB_iMeshP_unit_tests.cpp.
References sortedPartList.
Referenced by local_id_from_part_id(), and rank_from_part_id().
{ return std::lower_bound( sortedPartList.begin(), sortedPartList.end(), id ) - sortedPartList.begin(); }
int PartMap::local_id_from_part_id | ( | iMeshP_Part | part | ) | const [inline] |
Definition at line 245 of file MOAB_iMeshP_unit_tests.cpp.
References idx_from_part_id(), and partLocalIds.
Referenced by interface_verts().
{ return partLocalIds[idx_from_part_id( part )]; }
void PartMap::local_id_from_rank | ( | int | rank, |
std::vector< int > & | ids | ||
) | const |
Definition at line 3002 of file MOAB_iMeshP_unit_tests.cpp.
References partLocalIds, partRanks, and sortedPartList.
Referenced by test_get_neighbors().
{ for( size_t i = 0; i < sortedPartList.size(); ++i ) if( partRanks[i] == rank ) ids.push_back( partLocalIds[i] ); }
int PartMap::num_parts | ( | ) | const [inline] |
Definition at line 235 of file MOAB_iMeshP_unit_tests.cpp.
References sortedPartList.
Referenced by test_get_by_topo(), test_get_by_type(), test_get_neighbors(), and test_get_parts().
{ return sortedPartList.size(); }
int PartMap::part_from_coords | ( | iMesh_Instance | imesh, |
iMeshP_PartHandle | part, | ||
int & | id_out | ||
) | [static] |
Definition at line 3008 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, iBase_FACE, iBase_VERTEX, iMesh_getEntArrAdj, iMesh_getEntities, iMesh_getVtxCoord, and iMesh_QUADRILATERAL.
Referenced by build_map(), get_part_boundary_verts(), and test_entity_copy_parts().
{ int ierr, rank; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); // get elements const int num_elem = 4; iBase_EntityHandle array[num_elem]; iBase_EntityHandle* ptr = array; int junk1 = num_elem, n = -1; iMesh_getEntities( imesh, part, iBase_FACE, iMesh_QUADRILATERAL, &ptr, &junk1, &n, &ierr );CHKERR; assert( ptr == array ); assert( junk1 == num_elem ); if( n != num_elem ) { std::cerr << "Internal error at " __FILE__ ":" << __LINE__ << " (proc " << rank << "): Expected all parts to have " << num_elem << " elements. Found one with " << n << std::endl; return 1; } // get vertices iBase_EntityHandle adj_array[4 * num_elem]; int junk2, junk3, offset_array[5]; ptr = adj_array; junk1 = sizeof( adj_array ) / sizeof( adj_array[0] ); junk2 = sizeof( offset_array ) / sizeof( offset_array[0] ); int* ptr2 = offset_array; iMesh_getEntArrAdj( imesh, array, num_elem, iBase_VERTEX, &ptr, &junk1, &n, &ptr2, &junk2, &junk3, &ierr );CHKERR; assert( ptr == adj_array ); assert( ptr2 == offset_array ); assert( junk1 == sizeof( adj_array ) / sizeof( adj_array[0] ) ); assert( junk2 == sizeof( offset_array ) / sizeof( offset_array[0] ) ); assert( n == 4 * num_elem ); assert( offset_array[0] == 0 ); for( int i = 1; i < junk3; ++i ) assert( offset_array[i] - offset_array[i - 1] == 4 ); // find center vertex iBase_EntityHandle vtx; bool all_match; for( int i = 0; i < 4; ++i ) { vtx = adj_array[i]; all_match = true; for( int j = 1; j < 4; ++j ) { iBase_EntityHandle* mvtx = adj_array + 4 * j; int k; for( k = 0; k < 4; ++k ) if( mvtx[k] == vtx ) break; if( k == 4 ) all_match = false; } if( all_match ) break; } assert( all_match ); // get center vertex coordinates double x, y, z; iMesh_getVtxCoord( imesh, vtx, &x, &y, &z, &ierr );CHKERR; assert( 0.0 == z ); const int xi = ( (int)round( x ) - 1 ) / 2; const int yi = ( (int)round( y ) - 1 ) / 2; assert( xi >= 0 ); assert( yi >= 0 ); assert( fabs( x - 2 * xi - 1 ) < 1e-12 ); assert( fabs( y - 2 * yi - 1 ) < 1e-12 ); id = 2 * xi + yi; return 0; }
iMeshP_Part PartMap::part_id_from_local_id | ( | int | local_id | ) | const [inline] |
Definition at line 240 of file MOAB_iMeshP_unit_tests.cpp.
References idx_from_local_id(), and sortedPartList.
Referenced by test_entity_copy_parts(), and test_get_neighbors().
{ return sortedPartList[idx_from_local_id( local_id )]; }
void PartMap::part_id_from_rank | ( | int | rank, |
std::vector< iMeshP_Part > & | parts | ||
) | const |
Definition at line 2996 of file MOAB_iMeshP_unit_tests.cpp.
References partRanks, and sortedPartList.
Referenced by test_get_neighbors(), and test_part_id_handle().
{ for( size_t i = 0; i < sortedPartList.size(); ++i ) if( partRanks[i] == rank ) parts.push_back( sortedPartList[i] ); }
int PartMap::rank_from_local_id | ( | int | id | ) | const [inline] |
Definition at line 255 of file MOAB_iMeshP_unit_tests.cpp.
References idx_from_local_id(), and partRanks.
{ return partRanks[idx_from_local_id( id )]; }
int PartMap::rank_from_part_id | ( | iMeshP_Part | part | ) | const [inline] |
Definition at line 250 of file MOAB_iMeshP_unit_tests.cpp.
References idx_from_part_id(), and partRanks.
{ return partRanks[idx_from_part_id( part )]; }
std::vector< int > PartMap::localIdReverseMap [private] |
Definition at line 296 of file MOAB_iMeshP_unit_tests.cpp.
Referenced by build_map(), and idx_from_local_id().
std::vector< int > PartMap::partLocalIds [private] |
Definition at line 295 of file MOAB_iMeshP_unit_tests.cpp.
Referenced by build_map(), local_id_from_part_id(), and local_id_from_rank().
std::vector< int > PartMap::partRanks [private] |
Definition at line 294 of file MOAB_iMeshP_unit_tests.cpp.
Referenced by build_map(), count_from_rank(), get_ranks(), local_id_from_rank(), part_id_from_rank(), rank_from_local_id(), and rank_from_part_id().
std::vector< iMeshP_Part > PartMap::sortedPartList [private] |
Definition at line 293 of file MOAB_iMeshP_unit_tests.cpp.
Referenced by build_map(), get_parts(), idx_from_part_id(), local_id_from_rank(), num_parts(), part_id_from_local_id(), and part_id_from_rank().