![]() |
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().
{
return std::count( partRanks.begin(), partRanks.end(), rank );
}
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().