Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
PartMap Class Reference
+ Collaboration diagram for PartMap:

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_PartsortedPartList
std::vector< int > partRanks
std::vector< int > partLocalIds
std::vector< int > localIdReverseMap

Detailed Description

Definition at line 232 of file MOAB_iMeshP_unit_tests.cpp.


Member Function Documentation

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< 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 )];
    }

Member Data Documentation

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]

List of all members.


The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines