MOAB: Mesh Oriented datABase  (version 5.5.0)
PartMap Class Reference

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

◆ build_map()

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.

2887 {
2888  int ierr, rank, size;
2889  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
2890  MPI_Comm_size( MPI_COMM_WORLD, &size );
2891 
2892  // get local parts
2893  std::vector< iMeshP_PartHandle > local_parts;
2894  std::vector< iMeshP_Part > imesh_ids;
2895  ierr = get_local_parts( imesh, prtn, local_parts, &imesh_ids );CHKERR;
2896 
2897  // get logical ids for local parts
2898  std::vector< int > local_ids( local_parts.size() );
2899  for( size_t i = 0; i < local_parts.size(); ++i )
2900  {
2901  ierr = part_from_coords( imesh, local_parts[i], local_ids[i] );CHKERR;
2902  }
2903 
2904  // get total number of parts
2905  int num_global = 0, num_local = local_parts.size();
2906  ierr = MPI_Allreduce( &num_local, &num_global, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );CHKERR;
2907  if( num_global != num_expected_parts )
2908  {
2909  std::cerr << "Invalid/unexpected global part count at " __FILE__ ":" << __LINE__ << " (proc " << rank
2910  << "): " << std::endl
2911  << " Expected: " << num_expected_parts << std::endl
2912  << " Actual: " << num_global << std::endl;
2913  return 1;
2914  }
2915 
2916  // get counts and displacements for Allgatherv calls
2917  std::vector< int > dspls( size ), counts( size );
2918  ierr = MPI_Allgather( &num_local, 1, MPI_INT, &counts[0], 1, MPI_INT, MPI_COMM_WORLD );CHKERR;
2919  dspls[0] = 0;
2920  for( int i = 1; i < size; ++i )
2921  dspls[i] = dspls[i - 1] + counts[i - 1];
2922 
2923  // gather iMeshP_Part list from each processor
2924  std::vector< unsigned > global_part_ids( num_expected_parts );
2925  assert( sizeof( iMeshP_Part ) == sizeof( int ) );
2926  ierr = MPI_Allgatherv( &imesh_ids[0], num_local, MPI_UNSIGNED, &global_part_ids[0], &counts[0], &dspls[0],
2927  MPI_UNSIGNED, MPI_COMM_WORLD );CHKERR;
2928 
2929  // gather local ids from each processor
2930  std::vector< int > global_id_list( num_expected_parts );
2931  ierr = MPI_Allgatherv( &local_ids[0], num_local, MPI_INT, &global_id_list[0], &counts[0], &dspls[0], MPI_INT,
2933 
2934  // build owner list
2935  std::vector< int > global_owners( num_expected_parts );
2936  for( int i = 0; i < size; ++i )
2937  for( int j = 0; j < counts[i]; ++j )
2938  global_owners[dspls[i] + j] = i;
2939 
2940  // populate member lists
2941  sortedPartList = global_part_ids;
2942  std::sort( sortedPartList.begin(), sortedPartList.end() );
2943  partLocalIds.resize( num_expected_parts );
2944  partRanks.resize( num_expected_parts );
2945  for( int i = 0; i < num_expected_parts; ++i )
2946  {
2947  int idx = std::lower_bound( sortedPartList.begin(), sortedPartList.end(), global_part_ids[i] ) -
2948  sortedPartList.begin();
2949  partLocalIds[idx] = global_id_list[i];
2950  partRanks[idx] = global_owners[i];
2951  }
2952 
2953  // do some consistency checking
2954  if( std::unique( sortedPartList.begin(), sortedPartList.end() ) != sortedPartList.end() )
2955  {
2956  if( rank == 0 )
2957  {
2958  std::cerr << "ERROR: Duplicate iMeshP_Part values detected at " __FILE__ ":" << __LINE__ << std::endl;
2959  }
2960  return 1;
2961  }
2962 
2963  // build revesre local id map and check for duplicates
2964  localIdReverseMap.clear();
2965  localIdReverseMap.resize( num_expected_parts, -1 );
2966  for( int i = 0; i < num_expected_parts; ++i )
2967  {
2968  int idx = partLocalIds[i];
2969  if( localIdReverseMap[idx] != -1 )
2970  {
2971  if( rank == 0 )
2972  {
2973  std::cerr << "ERROR: Part mesh has been duplicated in multiple parts." << std::endl
2974  << " Detected at " __FILE__ ":" << __LINE__ << std::endl
2975  << " See PartMap::part_from_coords" << std::endl;
2976  }
2977  return 1;
2978  }
2979  if( idx >= num_expected_parts )
2980  {
2981  if( rank == 0 )
2982  {
2983  std::cerr << "ERROR: Part mesh invalid/incorrect mesh." << std::endl
2984  << " Detected at " __FILE__ ":" << __LINE__ << std::endl
2985  << " See PartMap::part_from_coords" << std::endl;
2986  }
2987  return 1;
2988  }
2989 
2990  localIdReverseMap[idx] = i;
2991  }
2992 
2993  return 0;
2994 }

References CHKERR, get_local_parts(), ierr, localIdReverseMap, MPI_COMM_WORLD, part_from_coords(), partLocalIds, partRanks, rank, size, and sortedPartList.

Referenced by create_mesh_in_memory(), and test_load().

◆ count_from_rank()

int PartMap::count_from_rank ( int  rank) const
inline

Definition at line 260 of file MOAB_iMeshP_unit_tests.cpp.

261  {
262  return std::count( partRanks.begin(), partRanks.end(), rank );
263  }

References partRanks, and rank.

Referenced by test_get_parts().

◆ get_parts()

const std::vector< iMeshP_Part >& PartMap::get_parts ( ) const
inline

◆ get_ranks()

const std::vector< int >& PartMap::get_ranks ( ) const
inline

Definition at line 274 of file MOAB_iMeshP_unit_tests.cpp.

275  {
276  return partRanks;
277  }

References partRanks.

Referenced by test_part_rank().

◆ idx_from_local_id()

int PartMap::idx_from_local_id ( int  id) const
inlineprivate

Definition at line 288 of file MOAB_iMeshP_unit_tests.cpp.

289  {
290  return localIdReverseMap[id];
291  }

References localIdReverseMap.

Referenced by part_id_from_local_id(), and rank_from_local_id().

◆ idx_from_part_id()

int PartMap::idx_from_part_id ( iMeshP_Part  id) const
inlineprivate

Definition at line 284 of file MOAB_iMeshP_unit_tests.cpp.

285  {
286  return std::lower_bound( sortedPartList.begin(), sortedPartList.end(), id ) - sortedPartList.begin();
287  }

References sortedPartList.

Referenced by local_id_from_part_id(), and rank_from_part_id().

◆ local_id_from_part_id()

int PartMap::local_id_from_part_id ( iMeshP_Part  part) const
inline

Definition at line 245 of file MOAB_iMeshP_unit_tests.cpp.

246  {
247  return partLocalIds[idx_from_part_id( part )];
248  }

References idx_from_part_id(), and partLocalIds.

Referenced by interface_verts().

◆ local_id_from_rank()

void PartMap::local_id_from_rank ( int  rank,
std::vector< int > &  ids 
) const

Definition at line 3002 of file MOAB_iMeshP_unit_tests.cpp.

3003 {
3004  for( size_t i = 0; i < sortedPartList.size(); ++i )
3005  if( partRanks[i] == rank ) ids.push_back( partLocalIds[i] );
3006 }

References partLocalIds, partRanks, rank, and sortedPartList.

Referenced by test_get_neighbors().

◆ num_parts()

int PartMap::num_parts ( ) const
inline

Definition at line 235 of file MOAB_iMeshP_unit_tests.cpp.

236  {
237  return sortedPartList.size();
238  }

References sortedPartList.

Referenced by test_get_by_topo(), test_get_by_type(), test_get_neighbors(), and test_get_parts().

◆ part_from_coords()

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.

3009 {
3010  int ierr, rank;
3011  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
3012 
3013  // get elements
3014  const int num_elem = 4;
3015  iBase_EntityHandle array[num_elem];
3016  iBase_EntityHandle* ptr = array;
3017  int junk1 = num_elem, n = -1;
3018  iMesh_getEntities( imesh, part, iBase_FACE, iMesh_QUADRILATERAL, &ptr, &junk1, &n, &ierr );CHKERR;
3019  assert( ptr == array );
3020  assert( junk1 == num_elem );
3021  if( n != num_elem )
3022  {
3023  std::cerr << "Internal error at " __FILE__ ":" << __LINE__ << " (proc " << rank
3024  << "): Expected all parts to have " << num_elem << " elements. Found one with " << n << std::endl;
3025  return 1;
3026  }
3027 
3028  // get vertices
3029  iBase_EntityHandle adj_array[4 * num_elem];
3030  int junk2, junk3, offset_array[5];
3031  ptr = adj_array;
3032  junk1 = sizeof( adj_array ) / sizeof( adj_array[0] );
3033  junk2 = sizeof( offset_array ) / sizeof( offset_array[0] );
3034  int* ptr2 = offset_array;
3035  iMesh_getEntArrAdj( imesh, array, num_elem, iBase_VERTEX, &ptr, &junk1, &n, &ptr2, &junk2, &junk3, &ierr );CHKERR;
3036  assert( ptr == adj_array );
3037  assert( ptr2 == offset_array );
3038  assert( junk1 == sizeof( adj_array ) / sizeof( adj_array[0] ) );
3039  assert( junk2 == sizeof( offset_array ) / sizeof( offset_array[0] ) );
3040  assert( n == 4 * num_elem );
3041  assert( offset_array[0] == 0 );
3042  for( int i = 1; i < junk3; ++i )
3043  assert( offset_array[i] - offset_array[i - 1] == 4 );
3044 
3045  // find center vertex
3047  bool all_match;
3048  for( int i = 0; i < 4; ++i )
3049  {
3050  vtx = adj_array[i];
3051  all_match = true;
3052  for( int j = 1; j < 4; ++j )
3053  {
3054  iBase_EntityHandle* mvtx = adj_array + 4 * j;
3055  int k;
3056  for( k = 0; k < 4; ++k )
3057  if( mvtx[k] == vtx ) break;
3058  if( k == 4 ) all_match = false;
3059  }
3060  if( all_match ) break;
3061  }
3062  assert( all_match );
3063 
3064  // get center vertex coordinates
3065  double x, y, z;
3066  iMesh_getVtxCoord( imesh, vtx, &x, &y, &z, &ierr );CHKERR;
3067  assert( 0.0 == z );
3068  const int xi = ( (int)round( x ) - 1 ) / 2;
3069  const int yi = ( (int)round( y ) - 1 ) / 2;
3070  assert( xi >= 0 );
3071  assert( yi >= 0 );
3072  assert( fabs( x - 2 * xi - 1 ) < 1e-12 );
3073  assert( fabs( y - 2 * yi - 1 ) < 1e-12 );
3074 
3075  id = 2 * xi + yi;
3076  return 0;
3077 }

References CHKERR, iBase_FACE, iBase_VERTEX, ierr, iMesh_getEntArrAdj, iMesh_getEntities, iMesh_getVtxCoord, iMesh_QUADRILATERAL, MPI_COMM_WORLD, rank, and vtx().

Referenced by build_map(), get_part_boundary_verts(), and test_entity_copy_parts().

◆ part_id_from_local_id()

iMeshP_Part PartMap::part_id_from_local_id ( int  local_id) const
inline

Definition at line 240 of file MOAB_iMeshP_unit_tests.cpp.

241  {
242  return sortedPartList[idx_from_local_id( local_id )];
243  }

References idx_from_local_id(), and sortedPartList.

Referenced by test_entity_copy_parts(), and test_get_neighbors().

◆ part_id_from_rank()

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.

2997 {
2998  for( size_t i = 0; i < sortedPartList.size(); ++i )
2999  if( partRanks[i] == rank ) parts.push_back( sortedPartList[i] );
3000 }

References partRanks, rank, and sortedPartList.

Referenced by test_get_neighbors(), and test_part_id_handle().

◆ rank_from_local_id()

int PartMap::rank_from_local_id ( int  id) const
inline

Definition at line 255 of file MOAB_iMeshP_unit_tests.cpp.

256  {
257  return partRanks[idx_from_local_id( id )];
258  }

References idx_from_local_id(), and partRanks.

◆ rank_from_part_id()

int PartMap::rank_from_part_id ( iMeshP_Part  part) const
inline

Definition at line 250 of file MOAB_iMeshP_unit_tests.cpp.

251  {
252  return partRanks[idx_from_part_id( part )];
253  }

References idx_from_part_id(), and partRanks.

Member Data Documentation

◆ localIdReverseMap

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().

◆ partLocalIds

std::vector< int > PartMap::partLocalIds
private

◆ partRanks

std::vector< int > PartMap::partRanks
private

◆ sortedPartList

std::vector< iMeshP_Part > PartMap::sortedPartList
private

The documentation for this class was generated from the following file: