![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
#include "iMeshP.h"
#include "moab_mpi.h"
#include <iostream>
#include <algorithm>
#include <vector>
#include <sstream>
#include <cassert>
#include <cmath>
#include <map>
#include <cstring>
#include <cstdio>
#include <unistd.h>
Go to the source code of this file.
Classes | |
class | PartMap |
struct | EHARR< size > |
struct | VtxCopyData |
Defines | |
#define | STRINGIFY_(X) #X |
#define | STRINGIFY(X) STRINGIFY_( X ) |
#define | CHKERR |
#define | PCHECK |
#define | ASSERT(A) |
#define | RUN_TEST(A) run_test( &( A ), #A ) |
Functions | |
int | is_any_proc_error (int is_my_error) |
int | test_load (iMesh_Instance, iMeshP_PartitionHandle prtn, PartMap &map, int comm_size) |
Consistency check for parallel load. | |
int | test_get_partitions (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test partition query methods. | |
int | test_get_parts (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test part quyery methods. | |
int | test_get_by_type (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test query by entity type. | |
int | test_get_by_topo (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test query by entity topology. | |
int | test_part_id_handle (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test mapping from part id to part handle. | |
int | test_part_rank (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test get part rank. | |
int | test_get_neighbors (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test querying of part neighbors. | |
int | test_get_part_boundary (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test querying of part boundary entities. | |
int | test_part_boundary_iter (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test querying of part boundary entities. | |
int | test_get_adjacencies (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test adjacent entity query. | |
int | test_entity_iterator (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test entity iterators. | |
int | test_entity_owner (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test entity owner queries. | |
int | test_entity_status (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test entity status. | |
int | test_entity_copy_parts (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test information about entity copies for interface entities. | |
int | test_entity_copies (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test information about entity copies for interface entities. | |
int | test_create_ghost_ents (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test creation of ghost entities. | |
int | test_push_tag_data_iface (iMesh_Instance, iMeshP_PartitionHandle prtn, const PartMap &) |
Test commuinication of tag data. | |
int | test_push_tag_data_ghost (iMesh_Instance imesh, iMeshP_PartitionHandle prtn, const PartMap &) |
Test commuinication of tag data. | |
int | test_exchange_ents (iMesh_Instance imesh, iMeshP_PartitionHandle prtn, const PartMap &map) |
Test exchange entities. | |
int | create_mesh (const char *filename, int num_parts) |
Create mesh for use in parallel tests. | |
int | create_mesh_in_memory (int rank, int size, iMesh_Instance imesh, iMeshP_PartitionHandle &prtn, PartMap &map) |
int | vertex_tag (iMesh_Instance imesh, iBase_EntityHandle vertex, int &tag) |
get unique identifier for each vertex | |
int | get_local_parts (iMesh_Instance instance, iMeshP_PartitionHandle prtn, std::vector< iMeshP_PartHandle > &handles, std::vector< iMeshP_Part > *ids=0) |
static int | get_entities (iMesh_Instance imesh, iBase_EntitySetHandle set, iBase_EntityType type, iMesh_EntityTopology topo, std::vector< iBase_EntityHandle > &entities) |
static int | get_part_quads_and_verts (iMesh_Instance imesh, iMeshP_PartHandle part, std::vector< iBase_EntityHandle > &elems, std::vector< iBase_EntityHandle > &verts) |
static int | get_coords (iMesh_Instance imesh, const iBase_EntityHandle *verts, int num_verts, double *coords) |
int | run_test (int(*func)(iMesh_Instance, iMeshP_PartitionHandle, const PartMap &), const char *func_name) |
int | main (int argc, char *argv[]) |
static int | test_get_by_type_topo_all (iMesh_Instance imesh, iMeshP_PartitionHandle prtn, bool test_type, int num_parts) |
static int | test_get_by_type_topo_local (iMesh_Instance imesh, iMeshP_PartitionHandle prtn, bool test_type) |
static void | get_part_neighbors (int logical_part_id, int num_parts, int neighbors[5], int &num_neighbors) |
static int | interface_verts (iMesh_Instance imesh, iMeshP_PartitionHandle prtn, iMeshP_PartHandle local_part, iMeshP_Part other_part, const PartMap &map, std::vector< iBase_EntityHandle > &vtx_handles) |
static int | get_part_boundary_verts (iMesh_Instance imesh, iMeshP_PartitionHandle prtn, const PartMap &map, iMeshP_PartHandle part, std::vector< iBase_EntityHandle > &boundary) |
int | get_num_adj_quads (iMesh_Instance imesh, iBase_EntityHandle vtx, int &num) |
int | get_adj (iMesh_Instance imesh, iBase_EntityHandle ent, int type, std::vector< iBase_EntityHandle > &adj) |
int | get_boundary_vertices (iMesh_Instance imesh, std::vector< iBase_EntityHandle > &bdry) |
int | check_one_layer (iMesh_Instance imesh, iBase_EntityHandle vtx, const std::vector< iBase_EntityHandle > &sorted_vertices) |
int | get_num_adj_all (iMesh_Instance imesh, const std::vector< iBase_EntityHandle > &verts, std::vector< int > &num_local_adj, std::vector< int > &num_all_adj) |
int | test_push_tag_data_common (iMesh_Instance imesh, iMeshP_PartitionHandle prtn, int num_ghost_layers) |
Test commuinication of tag data. | |
Variables | |
const char *const | FILENAME = "iMeshP_test_file" |
#define ASSERT | ( | A | ) |
do \
{ \
if( is_any_proc_error( !( A ) ) ) \
{ \
int my_rank = 0; \
MPI_Comm_rank( MPI_COMM_WORLD, &my_rank ); \
if( 0 == my_rank ) \
std::cerr << "Failed assertion: " #A << std::endl << " at " __FILE__ ":" << __LINE__ << std::endl; \
return 1; \
} \
} while( false )
Definition at line 43 of file MOAB_iMeshP_unit_tests.cpp.
Referenced by test_create_ghost_ents(), test_entity_copies(), test_entity_copy_parts(), test_entity_owner(), test_entity_status(), test_exchange_ents(), test_get_by_type_topo_all(), test_get_by_type_topo_local(), test_get_partitions(), test_get_parts(), test_part_id_handle(), test_part_rank(), and test_push_tag_data_common().
#define CHKERR |
do \
{ \
if( ierr ) \
{ \
std::cerr << "Error code " << ierr << " at " << __FILE__ << ":" << __LINE__ << std::endl; \
return ierr; \
} \
} while( false )
Definition at line 25 of file MOAB_iMeshP_unit_tests.cpp.
Referenced by PartMap::build_map(), check_one_layer(), create_mesh(), create_mesh_in_memory(), get_boundary_vertices(), get_local_parts(), get_num_adj_all(), get_part_boundary_verts(), get_part_quads_and_verts(), interface_verts(), PartMap::part_from_coords(), run_test(), test_entity_copies(), test_entity_copy_parts(), test_entity_owner(), test_exchange_ents(), test_get_by_type_topo_all(), test_get_by_type_topo_local(), test_get_part_boundary(), test_load(), test_part_boundary_iter(), test_part_id_handle(), test_push_tag_data_common(), and vertex_tag().
#define PCHECK |
do \
{ \
ierr = is_any_proc_error( ierr ); \
CHKERR; \
} while( false )
Definition at line 35 of file MOAB_iMeshP_unit_tests.cpp.
Referenced by run_test(), test_create_ghost_ents(), test_entity_copies(), test_entity_copy_parts(), test_entity_owner(), test_entity_status(), test_exchange_ents(), test_get_by_topo(), test_get_by_type(), test_get_by_type_topo_all(), test_get_neighbors(), test_get_partitions(), test_get_parts(), test_load(), test_part_id_handle(), test_part_rank(), and test_push_tag_data_common().
Definition at line 390 of file MOAB_iMeshP_unit_tests.cpp.
Referenced by main().
#define STRINGIFY | ( | X | ) | STRINGIFY_( X ) |
Definition at line 18 of file MOAB_iMeshP_unit_tests.cpp.
#define STRINGIFY_ | ( | X | ) | #X |
Definition at line 17 of file MOAB_iMeshP_unit_tests.cpp.
int check_one_layer | ( | iMesh_Instance | imesh, |
iBase_EntityHandle | vtx, | ||
const std::vector< iBase_EntityHandle > & | sorted_vertices | ||
) |
Definition at line 2537 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, get_adj(), iBase_FACE, iBase_FAILURE, iBase_SUCCESS, and iBase_VERTEX.
Referenced by test_create_ghost_ents().
{
int ierr;
if( std::binary_search( sorted_vertices.begin(), sorted_vertices.end(), vtx ) ) return iBase_SUCCESS;
std::vector< iBase_EntityHandle > quads, verts;
ierr = get_adj( imesh, vtx, iBase_FACE, quads );CHKERR;
for( size_t i = 0; i < quads.size(); ++i )
{
verts.clear();
ierr = get_adj( imesh, quads[i], iBase_VERTEX, verts );CHKERR;
for( size_t j = 0; j < verts.size(); ++j )
{
if( std::binary_search( sorted_vertices.begin(), sorted_vertices.end(), verts[j] ) ) return iBase_SUCCESS;
}
}
return iBase_FAILURE;
}
int create_mesh | ( | const char * | filename, |
int | num_parts | ||
) |
Create mesh for use in parallel tests.
Definition at line 576 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, iBase_INTEGER, iBase_INTERLEAVED, iBase_SUCCESS, iBase_TAG_ALREADY_EXISTS, iMesh_addEntArrToSet, iMesh_createEntArr, iMesh_createTag, iMesh_createVtxArr, iMesh_dtor, iMesh_getRootSet, iMesh_getTagHandle, iMesh_getTagSizeValues, iMesh_getTagType, iMesh_newMesh, iMesh_QUADRILATERAL, iMesh_setIntArrData, iMeshP_createPart, iMeshP_createPartitionAll, iMeshP_saveAll, and root_set.
{
const char* tagname = "GLOBAL_ID";
int ierr;
iMesh_Instance imesh;
iMesh_newMesh( 0, &imesh, &ierr, 0 );CHKERR;
const int num_full_cols = 2 * ( num_parts / 2 );
const int need_half_cols = num_parts % 2;
const int num_cols = num_full_cols + 2 * need_half_cols;
const int num_vtx = 5 + 5 * num_cols - 4 * ( num_parts % 2 );
std::vector< EHARR< 5 > > vertices( num_cols + 1 );
std::vector< EHARR< 4 > > elements( num_cols );
std::vector< int > vertex_ids( num_vtx );
std::vector< iBase_EntityHandle > vertex_list( num_vtx );
for( int i = 0; i < num_vtx; ++i )
vertex_ids[i] = i + 1;
// create vertices
int vl_pos = 0;
for( int i = 0; i <= num_cols; ++i )
{
double coords[15] = { static_cast< double >( i ), 0, 0, static_cast< double >( i ), 1, 0,
static_cast< double >( i ), 2, 0, static_cast< double >( i ), 3, 0,
static_cast< double >( i ), 4, 0 };
iBase_EntityHandle* ptr = vertices[i];
const int n = ( num_full_cols == num_cols || i <= num_full_cols ) ? 5 : 3;
int junk1 = n, junk2 = n;
iMesh_createVtxArr( imesh, n, iBase_INTERLEAVED, coords, 3 * n, &ptr, &junk1, &junk2, &ierr );CHKERR;
assert( ptr == vertices[i] );
assert( junk1 == n );
assert( junk2 == n );
for( int j = 0; j < n; ++j )
vertex_list[vl_pos++] = vertices[i][j];
}
// create elements
for( int i = 0; i < num_cols; ++i )
{
iBase_EntityHandle conn[16];
for( int j = 0; j < 4; ++j )
{
conn[4 * j] = vertices[i][j];
conn[4 * j + 1] = vertices[i][j + 1];
conn[4 * j + 2] = vertices[i + 1][j + 1];
conn[4 * j + 3] = vertices[i + 1][j];
}
iBase_EntityHandle* ptr = elements[i];
const int n = ( i < num_full_cols ) ? 4 : 2;
int junk1 = n, junk2 = n, junk3 = n, junk4 = n;
int stat[4];
int* ptr2 = stat;
iMesh_createEntArr( imesh, iMesh_QUADRILATERAL, conn, 4 * n, &ptr, &junk1, &junk2, &ptr2, &junk3, &junk4,
&ierr );CHKERR;
assert( ptr == elements[i] );
assert( junk1 == n );
assert( junk2 == n );
assert( ptr2 == stat );
assert( junk3 == n );
assert( junk4 == n );
}
// create partition
iMeshP_PartitionHandle partition;
iMeshP_createPartitionAll( imesh, MPI_COMM_SELF, &partition, &ierr );CHKERR;
for( int i = 0; i < num_parts; ++i )
{
iMeshP_PartHandle part;
iMeshP_createPart( imesh, partition, &part, &ierr );CHKERR;
iBase_EntityHandle quads[] = { elements[2 * ( i / 2 )][2 * ( i % 2 )],
elements[2 * ( i / 2 ) + 1][2 * ( i % 2 )],
elements[2 * ( i / 2 )][2 * ( i % 2 ) + 1],
elements[2 * ( i / 2 ) + 1][2 * ( i % 2 ) + 1] };
iMesh_addEntArrToSet( imesh, quads, 4, part, &ierr );CHKERR;
}
// assign global ids to vertices
iBase_TagHandle id_tag = 0;
iMesh_getTagHandle( imesh, tagname, &id_tag, &ierr, strlen( tagname ) );
if( iBase_SUCCESS == ierr )
{
int tag_size, tag_type;
iMesh_getTagSizeValues( imesh, id_tag, &tag_size, &ierr );CHKERR;
if( tag_size != 1 ) return iBase_TAG_ALREADY_EXISTS;
iMesh_getTagType( imesh, id_tag, &tag_type, &ierr );CHKERR;
if( tag_type != iBase_INTEGER ) return iBase_TAG_ALREADY_EXISTS;
}
else
{
iMesh_createTag( imesh, tagname, 1, iBase_INTEGER, &id_tag, &ierr, strlen( tagname ) );CHKERR;
}
iMesh_setIntArrData( imesh, &vertex_list[0], num_vtx, id_tag, &vertex_ids[0], num_vtx, &ierr );CHKERR;
// write file
iBase_EntitySetHandle root_set;
iMesh_getRootSet( imesh, &root_set, &ierr );
iMeshP_saveAll( imesh, partition, root_set, filename, 0, &ierr, strlen( filename ), 0 );CHKERR;
iMesh_dtor( imesh, &ierr );CHKERR;
return 0;
}
int create_mesh_in_memory | ( | int | rank, |
int | size, | ||
iMesh_Instance | imesh, | ||
iMeshP_PartitionHandle & | prtn, | ||
PartMap & | map | ||
) |
Definition at line 679 of file MOAB_iMeshP_unit_tests.cpp.
References PartMap::build_map(), CHKERR, iBase_INTEGER, iBase_INTERLEAVED, iBase_SUCCESS, iBase_TAG_ALREADY_EXISTS, iMesh_addEntArrToSet, iMesh_createEntArr, iMesh_createTag, iMesh_createVtxArr, iMesh_getTagHandle, iMesh_getTagSizeValues, iMesh_getTagType, iMesh_QUADRILATERAL, iMesh_setIntArrData, iMeshP_createPart, iMeshP_createPartitionAll, iMeshP_syncMeshAll, and iMeshP_syncPartitionAll.
Referenced by run_test().
{
const char* tagname = "GLOBAL_ID";
int ierr;
const int num_cols = 2;
const int num_vtx = 9;
// we are on the top or botton row
int bottom = rank % 2; // 0 2
// 1 3
std::vector< EHARR< 3 > > vertices( 3 );
std::vector< EHARR< 2 > > elements( 2 ); // 4 elements per process
std::vector< int > vertex_ids( num_vtx );
std::vector< iBase_EntityHandle > vertex_list( num_vtx );
int start = 1 + 2 * bottom + 10 * ( rank / 2 );
for( int i = 0; i < 3; ++i )
for( int j = 0; j < 3; ++j )
{
vertex_ids[i + 3 * j] = start + i + 5 * j;
}
// create vertices
int vl_pos = 0;
int startI = 2 * ( rank / 2 ); // so it will be 0, 0, 2, 2, ...)
for( int i = 0; i <= 2; ++i )
{
double coords[9] = {
static_cast< double >( i + startI ), 2. * bottom, 0,
static_cast< double >( i + startI ), 1 + 2. * bottom, 0,
static_cast< double >( i + startI ), 2 + 2. * bottom, 0,
};
iBase_EntityHandle* ptr = vertices[i];
const int n = 3;
int junk1 = n, junk2 = n;
iMesh_createVtxArr( imesh, n, iBase_INTERLEAVED, coords, 3 * n, &ptr, &junk1, &junk2, &ierr );CHKERR;
assert( ptr == vertices[i] );
assert( junk1 == n );
assert( junk2 == n );
for( int j = 0; j < n; ++j )
vertex_list[vl_pos++] = vertices[i][j];
}
// create elements
for( int i = 0; i < num_cols; ++i )
{
iBase_EntityHandle conn[8];
for( int j = 0; j < 2; ++j )
{
conn[4 * j] = vertices[i][j];
conn[4 * j + 1] = vertices[i][j + 1];
conn[4 * j + 2] = vertices[i + 1][j + 1];
conn[4 * j + 3] = vertices[i + 1][j];
}
iBase_EntityHandle* ptr = elements[i];
const int n = 2;
int junk1 = n, junk2 = n, junk3 = n, junk4 = n;
int stat[4];
int* ptr2 = stat;
iMesh_createEntArr( imesh, iMesh_QUADRILATERAL, conn, 4 * n, &ptr, &junk1, &junk2, &ptr2, &junk3, &junk4,
&ierr );CHKERR;
assert( ptr == elements[i] );
assert( junk1 == n );
assert( junk2 == n );
assert( ptr2 == stat );
assert( junk3 == n );
assert( junk4 == n );
}
// create partition
iMeshP_createPartitionAll( imesh, MPI_COMM_WORLD, &partition, &ierr );CHKERR;
iMeshP_PartHandle part;
iMeshP_createPart( imesh, partition, &part, &ierr );CHKERR;
iBase_EntityHandle quads[] = { elements[0][0], elements[0][1], elements[1][0], elements[1][1] };
iMesh_addEntArrToSet( imesh, quads, 4, part, &ierr );CHKERR;
// assign global ids to vertices
iBase_TagHandle id_tag = 0;
iMesh_getTagHandle( imesh, tagname, &id_tag, &ierr, strlen( tagname ) );
if( iBase_SUCCESS == ierr )
{
int tag_size, tag_type;
iMesh_getTagSizeValues( imesh, id_tag, &tag_size, &ierr );CHKERR;
if( tag_size != 1 ) return iBase_TAG_ALREADY_EXISTS;
iMesh_getTagType( imesh, id_tag, &tag_type, &ierr );CHKERR;
if( tag_type != iBase_INTEGER ) return iBase_TAG_ALREADY_EXISTS;
}
else
{
iMesh_createTag( imesh, tagname, 1, iBase_INTEGER, &id_tag, &ierr, strlen( tagname ) );CHKERR;
}
iMesh_setIntArrData( imesh, &vertex_list[0], num_vtx, id_tag, &vertex_ids[0], num_vtx, &ierr );CHKERR;
// some mesh sync
iMeshP_syncPartitionAll( imesh, partition, &ierr );CHKERR;
iMeshP_syncMeshAll( imesh, partition, &ierr );CHKERR;
ierr = map.build_map( imesh, partition, num_parts );CHKERR;
return 0;
}
int get_adj | ( | iMesh_Instance | imesh, |
iBase_EntityHandle | ent, | ||
int | type, | ||
std::vector< iBase_EntityHandle > & | adj | ||
) |
Definition at line 2507 of file MOAB_iMeshP_unit_tests.cpp.
References iBase_SUCCESS, and iMesh_getEntAdj.
Referenced by check_one_layer().
{
iBase_EntityHandle* list = 0;
int ierr, num, junk = 0;
iMesh_getEntAdj( imesh, ent, type, &list, &junk, &num, &ierr );
if( iBase_SUCCESS == ierr )
{
std::copy( list, list + num, std::back_inserter( adj ) );
free( list );
}
return ierr;
}
int get_boundary_vertices | ( | iMesh_Instance | imesh, |
std::vector< iBase_EntityHandle > & | bdry | ||
) |
Definition at line 2521 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, get_entities(), get_num_adj_quads(), iBase_SUCCESS, iBase_VERTEX, iMesh_getRootSet, and iMesh_POINT.
Referenced by test_create_ghost_ents().
{
int ierr, n;
iBase_EntitySetHandle root;
iMesh_getRootSet( imesh, &root, &ierr );CHKERR;
std::vector< iBase_EntityHandle > all_verts;
ierr = get_entities( imesh, root, iBase_VERTEX, iMesh_POINT, all_verts );CHKERR;
bdry.clear();
for( size_t i = 0; i < all_verts.size(); ++i )
{
ierr = get_num_adj_quads( imesh, all_verts[i], n );CHKERR;
if( n != 4 ) bdry.push_back( all_verts[i] );
}
return iBase_SUCCESS;
}
static int get_coords | ( | iMesh_Instance | imesh, |
const iBase_EntityHandle * | verts, | ||
int | num_verts, | ||
double * | coords | ||
) | [static] |
Definition at line 372 of file MOAB_iMeshP_unit_tests.cpp.
References iBase_INTERLEAVED, iBase_SUCCESS, and iMesh_getVtxArrCoords.
Referenced by moab::Core::get_coords(), moab::Core::get_vertex_coordinates(), interface_verts(), moab::Core::list_entity(), and test_entity_owner().
{
double* junk1 = coords;
int junk2 = 3 * num_verts;
int junk3;
int ierr;
iMesh_getVtxArrCoords( imesh, verts, num_verts, iBase_INTERLEAVED, &junk1, &junk2, &junk3, &ierr );
if( iBase_SUCCESS != ierr ) return ierr;
assert( junk1 == coords );
assert( junk2 == 3 * num_verts );
assert( junk3 == 3 * num_verts );
return iBase_SUCCESS;
}
static int get_entities | ( | iMesh_Instance | imesh, |
iBase_EntitySetHandle | set, | ||
iBase_EntityType | type, | ||
iMesh_EntityTopology | topo, | ||
std::vector< iBase_EntityHandle > & | entities | ||
) | [static] |
Definition at line 329 of file MOAB_iMeshP_unit_tests.cpp.
References iMesh_getEntities, and size.
Referenced by get_boundary_vertices(), get_part_quads_and_verts(), test_entity_owner(), test_exchange_ents(), test_get_by_type_topo_all(), test_get_by_type_topo_local(), and test_push_tag_data_common().
{
iBase_EntityHandle* array = 0;
int junk = 0, size = 0, err;
iMesh_getEntities( imesh, set, type, topo, &array, &junk, &size, &err );
if( !err )
{
entities.clear();
entities.resize( size );
std::copy( array, array + size, entities.begin() );
free( array );
}
return err;
}
int get_local_parts | ( | iMesh_Instance | instance, |
iMeshP_PartitionHandle | prtn, | ||
std::vector< iMeshP_PartHandle > & | handles, | ||
std::vector< iMeshP_Part > * | ids = 0 |
||
) |
Definition at line 307 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, iBase_SUCCESS, iMeshP_getLocalParts, iMeshP_getPartIdsFromPartHandlesArr, and size.
Referenced by PartMap::build_map(), test_entity_copies(), test_entity_copy_parts(), test_entity_owner(), test_entity_status(), test_exchange_ents(), test_get_by_type_topo_local(), test_get_part_boundary(), and test_part_boundary_iter().
{
iMeshP_PartHandle* arr = 0;
int ierr, alloc = 0, size;
iMeshP_getLocalParts( instance, prtn, &arr, &alloc, &size, &ierr );CHKERR;
handles.resize( size );
std::copy( arr, arr + size, handles.begin() );
free( arr );
if( !ids ) return iBase_SUCCESS;
ids->resize( size );
alloc = size;
iMeshP_Part* ptr = &( *ids )[0];
iMeshP_getPartIdsFromPartHandlesArr( instance, prtn, &handles[0], handles.size(), &ptr, &alloc, &size, &ierr );CHKERR;
assert( size == (int)ids->size() );
assert( ptr == &( *ids )[0] );
return iBase_SUCCESS;
}
int get_num_adj_all | ( | iMesh_Instance | imesh, |
const std::vector< iBase_EntityHandle > & | verts, | ||
std::vector< int > & | num_local_adj, | ||
std::vector< int > & | num_all_adj | ||
) |
Definition at line 2560 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, get_num_adj_quads(), iBase_SUCCESS, size, and vertex_tag().
Referenced by test_create_ghost_ents().
{
int ierr, size;
MPI_Comm_size( MPI_COMM_WORLD, &size );
std::vector< int > vtx_tags( verts.size() );
num_local_adj.resize( verts.size() );
for( size_t i = 0; i < verts.size(); ++i )
{
ierr = get_num_adj_quads( imesh, verts[i], num_local_adj[i] );CHKERR;
ierr = vertex_tag( imesh, verts[i], vtx_tags[i] );CHKERR;
}
std::vector< int > counts( size ), displ( size );
int num_vtx = verts.size();
ierr = MPI_Allgather( &num_vtx, 1, MPI_INT, &counts[0], 1, MPI_INT, MPI_COMM_WORLD );CHKERR;
displ[0] = 0;
for( int i = 1; i < size; ++i )
displ[i] = displ[i - 1] + counts[i - 1];
int total = displ[size - 1] + counts[size - 1];
std::vector< int > all_tags( total ), all_adj_counts( total );
ierr = MPI_Allgatherv( &vtx_tags[0], vtx_tags.size(), MPI_INT, &all_tags[0], &counts[0], &displ[0], MPI_INT,
MPI_COMM_WORLD );CHKERR;
ierr = MPI_Allgatherv( &num_local_adj[0], num_local_adj.size(), MPI_INT, &all_adj_counts[0], &counts[0], &displ[0],
MPI_INT, MPI_COMM_WORLD );CHKERR;
num_all_adj.clear();
num_all_adj.resize( total, 0 );
for( int i = 0; i < total; ++i )
{
std::vector< int >::iterator it = std::find( vtx_tags.begin(), vtx_tags.end(), all_tags[i] );
if( it == vtx_tags.end() ) continue;
int idx = it - vtx_tags.begin();
num_all_adj[idx] += all_adj_counts[i];
}
return iBase_SUCCESS;
}
int get_num_adj_quads | ( | iMesh_Instance | imesh, |
iBase_EntityHandle | vtx, | ||
int & | num | ||
) |
Definition at line 2498 of file MOAB_iMeshP_unit_tests.cpp.
References iBase_FACE, iBase_SUCCESS, and iMesh_getEntAdj.
Referenced by get_boundary_vertices(), get_num_adj_all(), and test_create_ghost_ents().
{
iBase_EntityHandle* list = 0;
int ierr, junk = 0;
iMesh_getEntAdj( imesh, vtx, iBase_FACE, &list, &junk, &num, &ierr );
if( iBase_SUCCESS == ierr ) free( list );
return ierr;
}
static int get_part_boundary_verts | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | map, | ||
iMeshP_PartHandle | part, | ||
std::vector< iBase_EntityHandle > & | boundary | ||
) | [static] |
Definition at line 2072 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, get_part_neighbors(), PartMap::get_parts(), iBase_SUCCESS, iface, interface_verts(), and PartMap::part_from_coords().
Referenced by test_entity_status().
{
int ierr, logical_id;
ierr = map.part_from_coords( imesh, part, logical_id );CHKERR;
int neighbors[5], num_neighbors;
get_part_neighbors( logical_id, map.get_parts().size(), neighbors, num_neighbors );
for( int j = 0; j < num_neighbors; ++j )
{
std::vector< iBase_EntityHandle > iface;
ierr = interface_verts( imesh, prtn, part, neighbors[j], map, iface );CHKERR;
std::copy( iface.begin(), iface.end(), std::back_inserter( boundary ) );
}
std::sort( boundary.begin(), boundary.end() );
boundary.erase( std::unique( boundary.begin(), boundary.end() ), boundary.end() );
return iBase_SUCCESS;
}
static void get_part_neighbors | ( | int | logical_part_id, |
int | num_parts, | ||
int | neighbors[5], | ||
int & | num_neighbors | ||
) | [static] |
Definition at line 1190 of file MOAB_iMeshP_unit_tests.cpp.
Referenced by get_part_boundary_verts(), test_entity_copy_parts(), and test_get_neighbors().
{
num_neighbors = 0;
if( logical_part_id + 1 < num_parts ) neighbors[num_neighbors++] = logical_part_id + 1;
if( logical_part_id + 2 < num_parts ) neighbors[num_neighbors++] = logical_part_id + 2;
if( logical_part_id % 2 )
{
neighbors[num_neighbors++] = logical_part_id - 1;
if( logical_part_id > 2 )
{
neighbors[num_neighbors++] = logical_part_id - 3;
neighbors[num_neighbors++] = logical_part_id - 2;
}
}
else
{
if( logical_part_id + 3 < num_parts ) neighbors[num_neighbors++] = logical_part_id + 3;
if( logical_part_id > 1 )
{
neighbors[num_neighbors++] = logical_part_id - 1;
neighbors[num_neighbors++] = logical_part_id - 2;
}
}
}
static int get_part_quads_and_verts | ( | iMesh_Instance | imesh, |
iMeshP_PartHandle | part, | ||
std::vector< iBase_EntityHandle > & | elems, | ||
std::vector< iBase_EntityHandle > & | verts | ||
) | [static] |
Definition at line 348 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, get_entities(), iBase_FACE, iBase_SUCCESS, iBase_VERTEX, iMesh_getEntArrAdj, and iMesh_QUADRILATERAL.
Referenced by test_entity_copies(), test_entity_copy_parts(), and test_entity_status().
{
int ierr = get_entities( imesh, part, iBase_FACE, iMesh_QUADRILATERAL, elems );CHKERR;
verts.resize( 4 * elems.size() );
std::vector< int > junk( elems.size() + 1 );
int junk1 = verts.size(), count, junk2 = junk.size(), junk3;
iBase_EntityHandle* junk4 = &verts[0];
int* junk5 = &junk[0];
iMesh_getEntArrAdj( imesh, &elems[0], elems.size(), iBase_VERTEX, &junk4, &junk1, &count, &junk5, &junk2, &junk3,
&ierr );CHKERR;
assert( junk1 == (int)verts.size() );
assert( count == (int)( 4 * elems.size() ) );
assert( junk2 == (int)junk.size() );
assert( junk4 == &verts[0] );
assert( junk5 == &junk[0] );
std::sort( verts.begin(), verts.end() );
verts.erase( std::unique( verts.begin(), verts.end() ), verts.end() );
return iBase_SUCCESS;
}
static int interface_verts | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
iMeshP_PartHandle | local_part, | ||
iMeshP_Part | other_part, | ||
const PartMap & | map, | ||
std::vector< iBase_EntityHandle > & | vtx_handles | ||
) | [static] |
Definition at line 1388 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, get_coords(), iBase_FACE, iBase_FAILURE, iBase_SUCCESS, iBase_VERTEX, iMesh_getEntArrAdj, iMesh_getEntities, iMesh_QUADRILATERAL, iMeshP_getPartIdFromPartHandle, and PartMap::local_id_from_part_id().
Referenced by get_part_boundary_verts(), test_entity_copy_parts(), test_get_part_boundary(), and test_part_boundary_iter().
{
int ierr, rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
iMeshP_Part local_id;
iMeshP_getPartIdFromPartHandle( imesh, prtn, local_part, &local_id, &ierr );CHKERR;
const int local_logical = map.local_id_from_part_id( local_id );
const int other_logical = map.local_id_from_part_id( other_part );
// get grid of local vertices
iBase_EntityHandle verts[3][3];
const double xbase = ( local_id / 2 ) * 2;
const double ybase = ( local_id % 2 ) * 2;
// get quads in partition
iBase_EntityHandle quads[4], *ptr = quads;
int junk1 = 4, junk2;
iMesh_getEntities( imesh, local_part, iBase_FACE, iMesh_QUADRILATERAL, &ptr, &junk1, &junk2, &ierr );CHKERR;
assert( ptr == quads );
assert( junk1 == 4 );
assert( junk2 == 4 );
// get vertices in quads
iBase_EntityHandle conn[16];
int offsets[5], *off_ptr = offsets, junk3 = 5, junk4;
ptr = conn;
junk1 = 16;
iMesh_getEntArrAdj( imesh, quads, 4, iBase_VERTEX, &ptr, &junk1, &junk2, &off_ptr, &junk3, &junk4, &ierr );CHKERR;
assert( ptr == conn );
assert( junk1 == 16 );
assert( junk2 == 16 );
assert( off_ptr == offsets );
assert( junk3 == 5 );
assert( junk4 == 5 );
// make unique vertex list
std::sort( conn, conn + 16 );
const int num_vtx = std::unique( conn, conn + 16 ) - conn;
assert( 9 == num_vtx );
// get vertex coords
std::vector< double > coords( 27 );
ierr = get_coords( imesh, conn, 9, &coords[0] );CHKERR;
// use vertex coords to determine logical position
for( int i = 0; i < num_vtx; ++i )
{
int x = (int)round( coords[3 * i] - xbase );
int y = (int)round( coords[3 * i + 1] - ybase );
if( x < 0 || x > 2 || y < 0 || y > 2 )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " Invalid vertex coordinate: (" << coords[3 * i] << ", " << coords[3 * i + 1] << ", "
<< coords[3 * i + 2] << ")" << std::endl
<< " For logical partition " << local_id << std::endl;
return iBase_FAILURE;
}
verts[x][y] = conn[i];
}
if( local_logical % 2 )
{
switch( other_logical - local_logical )
{
case 0:
return iBase_FAILURE;
case 1: // upper right
vtx_handles.resize( 1 );
vtx_handles[0] = verts[2][0];
break;
case 2: // right
vtx_handles.resize( 3 );
std::copy( verts[2], verts[2] + 3, vtx_handles.begin() );
break;
case -1: // above
vtx_handles.resize( 3 );
vtx_handles[0] = verts[0][0];
vtx_handles[1] = verts[1][0];
vtx_handles[2] = verts[2][0];
break;
case -2: // left
vtx_handles.resize( 3 );
std::copy( verts[0], verts[0] + 3, vtx_handles.begin() );
break;
case -3: // upper left
vtx_handles.resize( 1 );
vtx_handles[0] = verts[0][0];
break;
default:
vtx_handles.clear();
break;
}
}
else
{
switch( other_logical - local_logical )
{
case 0:
return iBase_FAILURE;
case 1: // below
vtx_handles.resize( 3 );
vtx_handles[0] = verts[0][2];
vtx_handles[1] = verts[1][2];
vtx_handles[2] = verts[2][2];
break;
case 2: // right
vtx_handles.resize( 3 );
std::copy( verts[2], verts[2] + 3, vtx_handles.begin() );
break;
case 3: // lower right
vtx_handles.resize( 1 );
vtx_handles[0] = verts[2][2];
break;
case -1: // lower left
vtx_handles.resize( 1 );
vtx_handles[0] = verts[0][2];
break;
case -2: // left
vtx_handles.resize( 3 );
std::copy( verts[0], verts[0] + 3, vtx_handles.begin() );
break;
default:
vtx_handles.clear();
break;
}
}
return iBase_SUCCESS;
}
int is_any_proc_error | ( | int | is_my_error | ) |
Definition at line 57 of file MOAB_iMeshP_unit_tests.cpp.
Referenced by run_test().
{
int result;
int err = MPI_Allreduce( &is_my_error, &result, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD );
return err || result;
}
int main | ( | int | argc, |
char * | argv[] | ||
) |
Definition at line 462 of file MOAB_iMeshP_unit_tests.cpp.
References FILENAME, RUN_TEST, size, test_create_ghost_ents(), test_entity_copies(), test_entity_copy_parts(), test_entity_iterator(), test_entity_owner(), test_entity_status(), test_exchange_ents(), test_get_adjacencies(), test_get_by_topo(), test_get_by_type(), test_get_neighbors(), test_get_part_boundary(), test_get_partitions(), test_get_parts(), test_part_boundary_iter(), test_part_id_handle(), test_part_rank(), test_push_tag_data_ghost(), and test_push_tag_data_iface().
{
MPI_Init( &argc, &argv );
int size, rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
if( argc > 2 && !strcmp( argv[1], "-p" ) )
{
#if !defined( _MSC_VER ) && !defined( __MINGW32__ )
std::cout << "Processor " << rank << " of " << size << " with PID " << getpid() << std::endl;
std::cout.flush();
#endif
// loop forever on requested processor, giving the user time
// to attach a debugger. Once the debugger in attached, user
// can change 'pause'. E.g. on gdb do "set var pause = 0"
if( atoi( argv[2] ) == rank )
{
volatile int pause = 1;
while( pause )
;
}
MPI_Barrier( MPI_COMM_WORLD );
}
int num_errors = 0;
num_errors += RUN_TEST( test_get_partitions );
num_errors += RUN_TEST( test_get_parts );
num_errors += RUN_TEST( test_get_by_type );
num_errors += RUN_TEST( test_get_by_topo );
num_errors += RUN_TEST( test_part_id_handle );
num_errors += RUN_TEST( test_part_rank );
num_errors += RUN_TEST( test_get_neighbors );
num_errors += RUN_TEST( test_get_part_boundary );
num_errors += RUN_TEST( test_part_boundary_iter );
num_errors += RUN_TEST( test_get_adjacencies );
num_errors += RUN_TEST( test_entity_iterator );
num_errors += RUN_TEST( test_entity_owner );
num_errors += RUN_TEST( test_entity_status );
num_errors += RUN_TEST( test_entity_copy_parts );
num_errors += RUN_TEST( test_entity_copies );
num_errors += RUN_TEST( test_push_tag_data_iface );
num_errors += RUN_TEST( test_push_tag_data_ghost );
num_errors += RUN_TEST( test_create_ghost_ents );
num_errors += RUN_TEST( test_exchange_ents );
// wait until all procs are done before writing summary data
std::cout.flush();
MPI_Barrier( MPI_COMM_WORLD );
#ifdef MOAB_HAVE_HDF5
// clean up output file
if( rank == 0 ) remove( FILENAME );
#endif
if( rank == 0 )
{
if( !num_errors )
std::cout << "All tests passed" << std::endl;
else
std::cout << num_errors << " TESTS FAILED!" << std::endl;
}
MPI_Finalize();
return num_errors;
}
int run_test | ( | int(*)(iMesh_Instance, iMeshP_PartitionHandle, const PartMap &) | func, |
const char * | func_name | ||
) |
Definition at line 392 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, create_mesh(), create_mesh_in_memory(), FILENAME, iMesh_dtor, iMesh_newMesh, iMeshP_createPartitionAll, is_any_proc_error(), PCHECK, size, and test_load().
{
int rank, size, ierr;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
iMesh_Instance imesh;
iMesh_newMesh( 0, &imesh, &ierr, 0 );
PCHECK;
iMeshP_PartitionHandle prtn;
iMeshP_createPartitionAll( imesh, MPI_COMM_WORLD, &prtn, &ierr );
PCHECK;
PartMap map;
#ifdef MOAB_HAVE_HDF5
if( rank == 0 )
{
ierr = create_mesh( FILENAME, size );
}
MPI_Bcast( &ierr, 1, MPI_INT, 0, MPI_COMM_WORLD );
if( ierr )
{
if( rank == 0 )
{
std::cerr << "Failed to create input test file on root processor. Aborting." << std::endl;
}
abort();
}
ierr = test_load( imesh, prtn, map, size );
if( ierr )
{
if( rank == 0 )
{
std::cerr << "Failed to load input mesh." << std::endl
<< "Cannot run further tests." << std::endl
<< "ABORTING" << std::endl;
}
abort();
}
#else
// so we have MPI and no HDF5; in order to run the test we need to create the
// model in memory, and then call sync to resolve shared ents, as if it was read
ierr = create_mesh_in_memory( rank, size, imesh, prtn, map );
MPI_Bcast( &ierr, 1, MPI_INT, 0, MPI_COMM_WORLD );
if( ierr )
{
if( rank == 0 )
{
std::cerr << "Failed to create mesh. Aborting." << std::endl;
}
abort();
}
#endif
int result = ( *func )( imesh, prtn, map );
int is_err = is_any_proc_error( result );
if( rank == 0 )
{
if( is_err )
std::cout << func_name << " : FAILED!!" << std::endl;
else
std::cout << func_name << " : success" << std::endl;
}
iMesh_dtor( imesh, &ierr );CHKERR;
return is_err;
}
int test_create_ghost_ents | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | |||
) |
Test creation of ghost entities.
Test:
Definition at line 2607 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, check_one_layer(), get_boundary_vertices(), get_num_adj_all(), get_num_adj_quads(), iBase_FACE, iBase_SUCCESS, iBase_VERTEX, iMeshP_createGhostEntsAll, and PCHECK.
Referenced by main().
{
int ierr;
// get boundary vertices
std::vector< iBase_EntityHandle > bdry;
ierr = get_boundary_vertices( imesh, bdry );
PCHECK;
// get counts of adjacent entities
std::vector< int > num_local_adj, num_global_adj;
ierr = get_num_adj_all( imesh, bdry, num_local_adj, num_global_adj );
PCHECK;
// create one layer of ghost entities
iMeshP_createGhostEntsAll( imesh, prtn, iBase_FACE, iBase_VERTEX, 1, 0, &ierr );
PCHECK;
// check that each vertex has the correct number of adjacent entities
int num_incorrect = 0;
for( size_t i = 0; i < bdry.size(); ++i )
{
int n;
ierr = get_num_adj_quads( imesh, bdry[i], n );
if( iBase_SUCCESS != ierr || num_global_adj[i] != n ) ++num_incorrect;
}
ASSERT( 0 == num_incorrect );
// get new the new boundary
std::vector< iBase_EntityHandle > new_bdry;
ierr = get_boundary_vertices( imesh, new_bdry );
PCHECK;
// check that each vertex on the new boundary is separated by
// at most one layer from the old boundary
std::sort( bdry.begin(), bdry.end() );
num_incorrect = 0;
for( size_t i = 0; i < new_bdry.size(); ++i )
{
ierr = check_one_layer( imesh, new_bdry[i], bdry );
if( ierr ) ++num_incorrect;
}
ASSERT( 0 == num_incorrect );
// make another layer of ghost entiites
bdry.swap( new_bdry );
new_bdry.clear();
ierr = get_num_adj_all( imesh, bdry, num_local_adj, num_global_adj );
PCHECK;
iMeshP_createGhostEntsAll( imesh, prtn, iBase_FACE, iBase_VERTEX, 2, 0, &ierr );
PCHECK;
// check that each vertex has the correct number of adjacent entities
num_incorrect = 0;
for( size_t i = 0; i < bdry.size(); ++i )
{
int n;
ierr = get_num_adj_quads( imesh, bdry[i], n );
if( iBase_SUCCESS != ierr || num_global_adj[i] != n ) ++num_incorrect;
}
// check that each vertex on the new boundary is separated by
// at most one layer from the old boundary
std::sort( bdry.begin(), bdry.end() );
num_incorrect = 0;
for( size_t i = 0; i < new_bdry.size(); ++i )
{
ierr = check_one_layer( imesh, new_bdry[i], bdry );
if( ierr ) ++num_incorrect;
}
ASSERT( 0 == num_incorrect );
return iBase_SUCCESS;
}
int test_entity_copies | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | |||
) |
Test information about entity copies for interface entities.
Test:
Definition at line 2320 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, CHKERR, get_local_parts(), get_part_quads_and_verts(), VtxCopyData::handles, iBase_FAILURE, iBase_SUCCESS, iMeshP_getCopies, iMeshP_getCopyOnPart, iMeshP_getEntOwnerPart, iMeshP_getOwnerCopy, iMeshP_getPartIdsFromPartHandlesArr, VtxCopyData::parts, PCHECK, size, and vertex_tag().
Referenced by main().
{
int ierr, rank, size;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
// generate a unique ID for each vertex using the coordinates.
// see create_mesh(..): each vertex has integer coordinates (x,y,0)
// with x in [0,inf] and y in [0,4]
// then to an Allgatherv to exchange handles for each processor
// cast everything to iBase_EntityHandle so we can pack it all in one communication
MPI_Datatype tmp_type;
if( sizeof( iBase_EntityHandle ) == sizeof( unsigned ) )
tmp_type = MPI_UNSIGNED;
else if( sizeof( iBase_EntityHandle ) == sizeof( unsigned long ) )
tmp_type = MPI_UNSIGNED_LONG;
else if( sizeof( iBase_EntityHandle ) == sizeof( unsigned long long ) )
tmp_type = MPI_UNSIGNED_LONG_LONG;
else
return iBase_FAILURE;
const MPI_Datatype type = tmp_type; // make it const
// get local part handles
std::vector< iMeshP_PartHandle > parts;
ierr = get_local_parts( imesh, prtn, parts );
PCHECK;
std::vector< iMeshP_Part > part_ids( parts.size() );
iMeshP_Part* junk1 = &part_ids[0];
int junk2 = part_ids.size(), junk3;
iMeshP_getPartIdsFromPartHandlesArr( imesh, prtn, &parts[0], parts.size(), &junk1, &junk2, &junk3, &ierr );
PCHECK;
assert( junk1 == &part_ids[0] );
assert( junk2 == (int)part_ids.size() );
assert( junk3 == (int)parts.size() );
// build list of {vtx_id, part_id, handle} tuples to send
// also build list of local vertex handles
std::vector< iBase_EntityHandle > local_data, local_vertices;
for( size_t i = 0; i < parts.size(); ++i )
{
// get vertices
std::vector< iBase_EntityHandle > quads, verts;
ierr = get_part_quads_and_verts( imesh, parts[i], quads, verts );
if( ierr ) break;
// add all vertices to local_data
for( size_t j = 0; j < verts.size(); ++j )
{
int tag = 0;
ierr = vertex_tag( imesh, verts[j], tag );
if( ierr ) break;
long tmp_h = tag;
local_data.push_back( (iBase_EntityHandle)tmp_h );
tmp_h = part_ids[i];
local_data.push_back( (iBase_EntityHandle)tmp_h );
local_data.push_back( verts[j] );
}
if( ierr ) break;
std::copy( verts.begin(), verts.end(), std::back_inserter( local_vertices ) );
}
// build list of local vertices
std::sort( local_vertices.begin(), local_vertices.end() );
local_vertices.erase( std::unique( local_vertices.begin(), local_vertices.end() ), local_vertices.end() );
std::vector< int > local_vtx_tags( local_vertices.size() );CHKERR;
for( size_t i = 0; i < local_vertices.size(); ++i )
{
ierr = vertex_tag( imesh, local_vertices[i], local_vtx_tags[i] );
if( ierr ) break;
}
CHKERR;
// communicate data
std::vector< int > gcounts( size ), gdisp( size );
int local_data_size = local_data.size();
ierr = MPI_Allgather( &local_data_size, 1, MPI_INT, &gcounts[0], 1, MPI_INT, MPI_COMM_WORLD );CHKERR;
gdisp[0] = 0;
for( int i = 1; i < size; ++i )
gdisp[i] = gdisp[i - 1] + gcounts[i - 1];
std::vector< iBase_EntityHandle > global_data( gdisp[size - 1] + gcounts[size - 1] );
ierr = MPI_Allgatherv( &local_data[0], local_data_size, type, &global_data[0], &gcounts[0], &gdisp[0], type,
MPI_COMM_WORLD );CHKERR;
// arrange global data in a more useful way
std::map< int, VtxCopyData > vtx_sharing;
assert( global_data.size() % 3 == 0 );
for( size_t i = 0; i < global_data.size(); i += 3 )
{
int tag = (int)(size_t)global_data[i];
iMeshP_Part part = (iMeshP_Part)(size_t)global_data[i + 1];
iBase_EntityHandle handle = global_data[i + 2];
vtx_sharing[tag].parts.push_back( part );
vtx_sharing[tag].handles.push_back( handle );
}
// test iMeshP_getCopies for each local vertex
int num_error = 0, num_incorrect = 0, junk4;
for( size_t i = 0; i < local_vertices.size(); ++i )
{
int num_copies = -1;
// iMeshP_Part* part_ids = 0;
iMeshP_Part* ptr_part_ids = 0; // Use ptr_part_ids to avoid shadowing std::vector part_ids
iBase_EntityHandle* copies = 0;
junk2 = junk3 = junk4 = 0;
iMeshP_getCopies( imesh, prtn, local_vertices[i], &ptr_part_ids, &junk2, &num_copies, &copies, &junk3, &junk4,
&ierr );
if( iBase_SUCCESS != ierr )
{
++num_error;
continue;
}
assert( junk4 == num_copies );
VtxCopyData& expected = vtx_sharing[local_vtx_tags[i]];
if( num_copies != (int)expected.parts.size() )
++num_incorrect;
else
for( size_t j = 0; j < expected.parts.size(); ++j )
{
int idx = std::find( ptr_part_ids, ptr_part_ids + num_copies, expected.parts[j] ) - ptr_part_ids;
if( idx == num_copies || copies[idx] != expected.handles[j] )
{
++num_incorrect;
break;
}
}
free( ptr_part_ids );
free( copies );
}
ASSERT( 0 == num_error );
ASSERT( 0 == num_incorrect );
// test iMeshP_getCopyOnPart for each local vertex
num_error = num_incorrect = 0;
for( size_t i = 0; i < local_vertices.size(); ++i )
{
VtxCopyData& expected = vtx_sharing[local_vtx_tags[i]];
for( size_t j = 0; j < expected.parts.size(); ++j )
{
iBase_EntityHandle copy;
iMeshP_getCopyOnPart( imesh, prtn, local_vertices[i], expected.parts[j], ©, &ierr );
if( iBase_SUCCESS != ierr )
++num_error;
else if( expected.handles[j] != copy )
++num_incorrect;
}
}
ASSERT( 0 == num_error );
ASSERT( 0 == num_incorrect );
// test iMeshP_getOwnerCopy for each local vertex
num_error = num_incorrect = 0;
for( size_t i = 0; i < local_vertices.size(); ++i )
{
VtxCopyData& expected = vtx_sharing[local_vtx_tags[i]];
iMeshP_Part owner_id = 0;
iMeshP_getEntOwnerPart( imesh, prtn, local_vertices[i], &owner_id, &ierr );
if( iBase_SUCCESS != ierr ) continue; // not testing getEntOwnerPart here
size_t idx = std::find( expected.parts.begin(), expected.parts.end(), owner_id ) - expected.parts.begin();
if( idx == expected.parts.size() ) continue; // not testing getEntOwnerPart here
iMeshP_Part owner_id_2 = 0;
iBase_EntityHandle copy = 0;
iMeshP_getOwnerCopy( imesh, prtn, local_vertices[i], &owner_id_2, ©, &ierr );
if( iBase_SUCCESS != ierr )
++num_error;
else if( owner_id_2 != owner_id && copy != expected.handles[idx] )
++num_incorrect;
}
ASSERT( 0 == num_error );
ASSERT( 0 == num_incorrect );
return iBase_SUCCESS;
}
int test_entity_copy_parts | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | map | ||
) |
Test information about entity copies for interface entities.
Test:
Definition at line 2220 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, CHKERR, get_local_parts(), get_part_neighbors(), get_part_quads_and_verts(), PartMap::get_parts(), iBase_SUCCESS, iface, iMeshP_getCopyParts, iMeshP_getNumCopies, interface_verts(), PartMap::part_from_coords(), PartMap::part_id_from_local_id(), PCHECK, and size.
Referenced by main().
{
int ierr, rank, size;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
// get local part handles
std::vector< iMeshP_PartHandle > parts;
ierr = get_local_parts( imesh, prtn, parts );
PCHECK;
ASSERT( !parts.empty() );
// select a singe part to test
const iMeshP_PartHandle part = parts[0];
int logical_id;
ierr = map.part_from_coords( imesh, part, logical_id );CHKERR;
const iMeshP_Part part_id = map.part_id_from_local_id( logical_id );
// get vertices in part
std::vector< iBase_EntityHandle > quads, verts;
ierr = get_part_quads_and_verts( imesh, part, quads, verts );
PCHECK;
// get neighbors
int neighbors[5], num_neighbors;
get_part_neighbors( logical_id, map.get_parts().size(), neighbors, num_neighbors );
// build map of sharing data for each vertex
std::map< iBase_EntityHandle, std::vector< iMeshP_Part > > vert_sharing;
for( int j = 0; j < num_neighbors; ++j )
{
std::vector< iBase_EntityHandle > iface;
ierr = interface_verts( imesh, prtn, part, neighbors[j], map, iface );CHKERR;
for( size_t k = 0; k < iface.size(); ++k )
vert_sharing[iface[k]].push_back( map.part_id_from_local_id( neighbors[j] ) );
}
// test getNumCopies for each vertex
std::map< iBase_EntityHandle, std::vector< iMeshP_Part > >::iterator i;
int num_failed = 0, num_incorrect = 0;
for( i = vert_sharing.begin(); i != vert_sharing.end(); ++i )
{
int count;
iBase_EntityHandle vtx = i->first;
iMeshP_getNumCopies( imesh, prtn, vtx, &count, &ierr );
if( ierr )
++num_failed;
else if( (unsigned)count != i->second.size() + 1 ) // add one for the part we queried from
++num_incorrect;
}
ASSERT( 0 == num_failed );
ASSERT( 0 == num_incorrect );
// get getCopyParts for each vertex
num_failed = num_incorrect = 0;
for( i = vert_sharing.begin(); i != vert_sharing.end(); ++i )
{
iMeshP_Part* list = 0;
int junk = 0, count;
iMeshP_getCopyParts( imesh, prtn, i->first, &list, &junk, &count, &ierr );
if( iBase_SUCCESS != ierr )
{
++num_failed;
continue;
}
if( (unsigned)count != i->second.size() + 1 )
{ // add one for the part we queried from
++num_incorrect;
free( list );
continue;
}
std::vector< iMeshP_Part > expected( i->second );
expected.push_back( part_id );
std::sort( list, list + count );
std::sort( expected.begin(), expected.end() );
bool eq = std::equal( list, list + count, expected.begin() );
free( list );
if( !eq ) ++num_incorrect;
}
ASSERT( 0 == num_failed );
ASSERT( 0 == num_incorrect );
return iBase_SUCCESS;
}
int test_entity_iterator | ( | iMesh_Instance | , |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | |||
) |
Test entity iterators.
Test:
Definition at line 1852 of file MOAB_iMeshP_unit_tests.cpp.
References iBase_SUCCESS.
Referenced by main().
{
return iBase_SUCCESS;
}
int test_entity_owner | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | |||
) |
Test entity owner queries.
Test:
Definition at line 1865 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, CHKERR, get_coords(), get_entities(), get_local_parts(), iBase_FACE, iBase_FAILURE, iBase_SUCCESS, iBase_VERTEX, iMesh_getEntArrAdj, iMesh_QUADRILATERAL, iMeshP_getEntOwnerPart, iMeshP_getEntOwnerPartArr, iMeshP_isEntOwner, iMeshP_isEntOwnerArr, PCHECK, and size.
Referenced by main().
{
int ierr, rank, size;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
// get local part handles and part ids
std::vector< iMeshP_PartHandle > local_handles;
std::vector< iMeshP_Part > local_ids;
ierr = get_local_parts( imesh, prtn, local_handles, &local_ids );
PCHECK;
// test iMeshP_getEntOwnerPart for quads in each part
std::vector< iBase_EntityHandle > all_quads;
std::vector< iMeshP_Part > quad_owners;
int invalid_count = 0;
for( size_t i = 0; i < local_handles.size(); ++i )
{
std::vector< iBase_EntityHandle > quads;
ierr = get_entities( imesh, local_handles[0], iBase_FACE, iMesh_QUADRILATERAL, quads );
if( ierr ) break;
for( size_t j = 0; j < quads.size(); ++j )
{
all_quads.push_back( quads[j] );
quad_owners.push_back( local_ids[i] );
iMeshP_Part owner;
iMeshP_getEntOwnerPart( imesh, prtn, quads[j], &owner, &ierr );
if( iBase_SUCCESS != ierr ) break;
if( owner != local_ids[i] ) ++invalid_count;
}
if( iBase_SUCCESS != ierr ) break;
}
PCHECK;
ASSERT( 0 == invalid_count );
// test iMeshP_getEntOwnerPartArr for quads in each part
invalid_count = 0;
for( size_t i = 0; i < local_handles.size(); ++i )
{
std::vector< iBase_EntityHandle > quads;
ierr = get_entities( imesh, local_handles[0], iBase_FACE, iMesh_QUADRILATERAL, quads );
if( ierr ) break;
std::vector< iMeshP_Part > owners( quads.size() ), expected( quads.size(), local_ids[i] );
int junk = owners.size(), count;
iMeshP_Part* ptr = &owners[0];
iMeshP_getEntOwnerPartArr( imesh, prtn, &quads[0], quads.size(), &ptr, &junk, &count, &ierr );
if( ierr ) break;
assert( ptr == &owners[0] );
assert( junk == (int)owners.size() );
assert( count == (int)quads.size() );
if( owners != expected ) ++invalid_count;
}
PCHECK;
ASSERT( 0 == invalid_count );
// get all vertices
iBase_EntityHandle* vtx_arr = 0;
int junk1 = 0, num_vtx;
int *junk2 = 0, junk3 = 0, junk4;
iMesh_getEntArrAdj( imesh, &all_quads[0], all_quads.size(), iBase_VERTEX, &vtx_arr, &junk1, &num_vtx, &junk2,
&junk3, &junk4, &ierr );
PCHECK;
free( junk2 );
std::sort( vtx_arr, vtx_arr + num_vtx );
num_vtx = std::unique( vtx_arr, vtx_arr + num_vtx ) - vtx_arr;
std::vector< iBase_EntityHandle > all_verts( vtx_arr, vtx_arr + num_vtx );
free( vtx_arr );
// check consistency between iMeshP_getEntOwnerPart and iMeshP_getEntOwnerPartArr
// for all vertices
std::vector< iMeshP_Part > vert_owners( all_verts.size() );
junk1 = vert_owners.size();
iMeshP_Part* junk5 = &vert_owners[0];
iMeshP_getEntOwnerPartArr( imesh, prtn, &all_verts[0], all_verts.size(), &junk5, &junk1, &junk3, &ierr );
PCHECK;
assert( junk5 == &vert_owners[0] );
assert( junk1 == (int)vert_owners.size() );
assert( junk3 == (int)all_verts.size() );
invalid_count = 0;
for( size_t i = 0; i < all_verts.size(); ++i )
{
iMeshP_Part owner;
iMeshP_getEntOwnerPart( imesh, prtn, all_verts[i], &owner, &ierr );
if( iBase_SUCCESS != ierr || owner != vert_owners[i] ) ++invalid_count;
}
ASSERT( 0 == invalid_count );
// get lists for all entities
std::vector< iBase_EntityHandle > all_entities( all_verts );
std::copy( all_quads.begin(), all_quads.end(), std::back_inserter( all_entities ) );
std::vector< iMeshP_Part > all_owners( vert_owners );
std::copy( quad_owners.begin(), quad_owners.end(), std::back_inserter( all_owners ) );
// check consistency of iMeshP_isEntOwner for all entities
invalid_count = 0;
ierr = iBase_SUCCESS;
for( size_t i = 0; i < local_handles.size(); ++i )
{
for( size_t j = 0; ierr == iBase_SUCCESS && j < all_entities.size(); ++j )
{
int is_owner;
iMeshP_isEntOwner( imesh, prtn, local_handles[i], all_entities[j], &is_owner, &ierr );
if( ierr != iBase_SUCCESS ) break;
if( !is_owner == ( local_ids[i] == all_owners[j] ) ) ++invalid_count;
}
}
PCHECK;
ASSERT( 0 == invalid_count );
// check consistency of iMeshP_isEntOwnerArr for all entities
for( size_t i = 0; i < local_handles.size(); ++i )
{
std::vector< int > is_owner_list( all_entities.size() );
junk1 = is_owner_list.size();
int* junk6 = &is_owner_list[0];
iMeshP_isEntOwnerArr( imesh, prtn, local_handles[i], &all_entities[0], all_entities.size(), &junk6, &junk1,
&junk3, &ierr );
if( iBase_SUCCESS != ierr ) break;
assert( junk6 == &is_owner_list[0] );
assert( junk1 == (int)is_owner_list.size() );
assert( junk3 == (int)all_entities.size() );
invalid_count = 0;
for( size_t j = 0; j < all_entities.size(); ++j )
{
if( !( is_owner_list[j] ) == ( local_ids[0] == all_owners[j] ) ) ++invalid_count;
}
}
PCHECK;
ASSERT( 0 == invalid_count );
// check globally consistent owners for all vertices
// first communicate total number of vertex entries to be sent to root proc
int local_count = all_verts.size(), global_count = 0;
ierr = MPI_Reduce( &local_count, &global_count, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD );CHKERR;
// for each vertex, store { (x << 2) | y, owning part id }
std::vector< int > vtxdata( 2 * all_verts.size() );
std::vector< double > coords( 3 * all_verts.size() );
ierr = get_coords( imesh, &all_verts[0], all_verts.size(), &coords[0] );CHKERR;
for( size_t i = 0; i < all_verts.size(); ++i )
{
int x = (int)round( coords[3 * i] );
int y = (int)round( coords[3 * i + 1] );
vtxdata[2 * i] = ( x << 3 ) | y;
vtxdata[2 * i + 1] = vert_owners[i];
}
// collect all data on root procesor
std::vector< int > all_data( 2 * global_count );
std::vector< int > displ( size ), counts( size );
for( int i = 0; i < size; i++ )
{
counts[i] = vtxdata.size();
displ[i] = i * vtxdata.size();
}
// we could have used a simple gather, because all sequences are the same
ierr = MPI_Gatherv( &vtxdata[0], vtxdata.size(), MPI_INT, &all_data[0], &counts[0], &displ[0], MPI_INT, 0,
MPI_COMM_WORLD );CHKERR;
if( rank == 0 )
{
// map from vertex tag to indices into data
std::multimap< int, int > data_map;
for( int i = 0; i < global_count; ++i )
{
std::pair< int, int > p;
p.first = all_data[2 * i];
p.second = i;
data_map.insert( p );
}
// check consistent data for each vtx
std::multimap< int, int >::const_iterator a, b;
for( a = data_map.begin(); a != data_map.end(); a = b )
{
for( b = a; b != data_map.end() && a->first == b->first; ++b )
{
int idx1 = a->second;
int idx2 = b->second;
if( all_data[2 * idx1 + 1] == all_data[2 * idx2 + 1] ) continue;
ierr = iBase_FAILURE;
int proc1 = std::lower_bound( displ.begin(), displ.end(), 2 * idx1 ) - displ.begin();
if( displ[proc1] != 2 * idx1 ) ++proc1;
int proc2 = std::lower_bound( displ.begin(), displ.end(), 2 * idx2 ) - displ.begin();
if( displ[proc2] != 2 * idx2 ) ++proc2;
std::cerr << "Error at " __FILE__ ":" << __LINE__ << " : " << std::endl
<< " For vertex at (" << ( a->first >> 2 ) << ", " << ( a->first & 3 ) << ") :" << std::endl
<< " Processor " << proc1 << " has " << all_data[2 * idx1 + 1] << " as the owning part"
<< std::endl
<< " Processor " << proc2 << " has " << all_data[2 * idx2 + 1] << " as the owning part"
<< std::endl;
}
}
}
return ierr;
}
int test_entity_status | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | map | ||
) |
Test entity status.
Test:
Definition at line 2102 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, get_local_parts(), get_part_boundary_verts(), get_part_quads_and_verts(), iBase_SUCCESS, iMeshP_BOUNDARY, iMeshP_getEntStatus, iMeshP_getEntStatusArr, iMeshP_INTERNAL, PCHECK, and size.
Referenced by main().
{
int ierr, rank, size;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
// get local part handles
std::vector< iMeshP_PartHandle > parts;
ierr = get_local_parts( imesh, prtn, parts );
PCHECK;
// for each part
int num_quad_ent_incorrect = 0, num_quad_ent_error = 0;
int num_quad_arr_incorrect = 0, num_quad_arr_error = 0;
int num_vert_ent_incorrect = 0, num_vert_ent_error = 0;
int num_vert_arr_incorrect = 0, num_vert_arr_error = 0;
for( size_t i = 0; i < parts.size(); ++i )
{
const iMeshP_PartHandle part = parts[i];
// get quads and vertices
std::vector< iBase_EntityHandle > quads, verts;
ierr = get_part_quads_and_verts( imesh, part, quads, verts );
if( ierr ) break;
// check quad status (no ghosting yet)
for( size_t j = 0; j < quads.size(); ++j )
{
int status;
iMeshP_getEntStatus( imesh, prtn, part, quads[j], &status, &ierr );
if( ierr != iBase_SUCCESS )
{
++num_quad_ent_error;
ierr = iBase_SUCCESS;
continue;
}
if( status != iMeshP_INTERNAL ) ++num_quad_ent_incorrect;
}
// check quad status using iMeshP_getEntStatusArr
std::vector< int > stat_list( quads.size() );
int* junk1 = &stat_list[0];
int junk2 = stat_list.size(), count;
iMeshP_getEntStatusArr( imesh, prtn, part, &quads[0], quads.size(), &junk1, &junk2, &count, &ierr );
if( ierr != iBase_SUCCESS )
{
++num_quad_arr_error;
ierr = iBase_SUCCESS;
continue;
}
assert( junk1 == &stat_list[0] );
assert( junk2 == (int)stat_list.size() );
assert( count == (int)quads.size() );
for( size_t j = 0; j < quads.size(); ++j )
if( stat_list[j] != iMeshP_INTERNAL ) ++num_quad_arr_incorrect;
// figure out which vertices are on the boundary
std::vector< iBase_EntityHandle > boundary;
ierr = get_part_boundary_verts( imesh, prtn, map, part, boundary );
if( ierr ) break;
std::sort( boundary.begin(), boundary.end() );
// check vertex status (no ghosting yet)
for( size_t j = 0; j < verts.size(); ++j )
{
int status;
iMeshP_getEntStatus( imesh, prtn, part, verts[j], &status, &ierr );
if( ierr != iBase_SUCCESS )
{
++num_vert_ent_error;
ierr = iBase_SUCCESS;
continue;
}
bool on_boundary = std::binary_search( boundary.begin(), boundary.end(), verts[j] );
if( status != ( on_boundary ? iMeshP_BOUNDARY : iMeshP_INTERNAL ) ) ++num_vert_ent_incorrect;
}
// check vert status using iMeshP_getEntStatusArr
stat_list.resize( verts.size() );
junk1 = &stat_list[0];
junk2 = stat_list.size();
iMeshP_getEntStatusArr( imesh, prtn, part, &verts[0], verts.size(), &junk1, &junk2, &count, &ierr );
if( ierr != iBase_SUCCESS )
{
++num_vert_arr_error;
ierr = iBase_SUCCESS;
continue;
}
assert( junk1 == &stat_list[0] );
assert( junk2 == (int)stat_list.size() );
assert( count == (int)verts.size() );
for( size_t j = 0; j < verts.size(); ++j )
{
bool on_boundary = std::binary_search( boundary.begin(), boundary.end(), verts[j] );
if( stat_list[j] != ( on_boundary ? iMeshP_BOUNDARY : iMeshP_INTERNAL ) ) ++num_vert_arr_incorrect;
}
}
PCHECK; // check if loop interrupted by any internal errors
ASSERT( 0 == num_quad_ent_error );
ASSERT( 0 == num_quad_arr_error );
ASSERT( 0 == num_vert_ent_error );
ASSERT( 0 == num_vert_arr_error );
ASSERT( 0 == num_quad_ent_incorrect );
ASSERT( 0 == num_quad_arr_incorrect );
ASSERT( 0 == num_vert_ent_incorrect );
ASSERT( 0 == num_vert_arr_incorrect );
return iBase_SUCCESS;
}
int test_exchange_ents | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | map | ||
) |
Test exchange entities.
Test:
Definition at line 2679 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, CHKERR, get_entities(), get_local_parts(), PartMap::get_parts(), iBase_FACE, iBase_SUCCESS, iMesh_QUADRILATERAL, iMeshP_exchEntArrToPartsAll, PCHECK, and size.
Referenced by main().
{
int ierr, rank, size;
int num_err = 0;
iMeshP_RequestHandle request;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
std::vector< iBase_EntityHandle > all_elems;
std::vector< iMeshP_Part > all_ids;
std::vector< iBase_EntityHandle > quads;
// get local part handles and part ids
std::vector< iMeshP_PartHandle > local_handles;
std::vector< iMeshP_Part > local_ids;
ierr = get_local_parts( imesh, prtn, local_handles, &local_ids );
PCHECK;
// get loacal quads before exchange
quads.clear();
ierr = get_entities( imesh, local_handles[0], iBase_FACE, iMesh_QUADRILATERAL, quads );CHKERR;
int n_quads = quads.size();
// send all elements in local processor to all other processors
for( size_t i = 0; i < map.get_parts().size(); ++i )
{
if( map.get_parts()[i] == (unsigned int)rank ) continue; // skip own rank
for( int j = 0; j < n_quads; j++ )
{
all_elems.push_back( quads[j] );
all_ids.push_back( map.get_parts()[i] );
}
}
// exchange entities
iMeshP_exchEntArrToPartsAll( imesh, prtn, &all_elems[0], all_elems.size(), &all_ids[0], 0, 0, &request, &ierr );
if( iBase_SUCCESS != ierr ) ++num_err;
// get local quads after exchange
quads.clear();
ierr = get_entities( imesh, local_handles[0], iBase_FACE, iMesh_QUADRILATERAL, quads );CHKERR;
// # of elements should be # of quads * # of processors
ASSERT( quads.size() == (unsigned int)n_quads * size );
ASSERT( 0 == num_err );
return iBase_SUCCESS;
}
int test_get_adjacencies | ( | iMesh_Instance | , |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | |||
) |
Test adjacent entity query.
Test:
Definition at line 1841 of file MOAB_iMeshP_unit_tests.cpp.
References iBase_SUCCESS.
Referenced by main().
{
return iBase_SUCCESS;
}
int test_get_by_topo | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | map | ||
) |
Test query by entity topology.
Test:
Definition at line 1068 of file MOAB_iMeshP_unit_tests.cpp.
References PartMap::num_parts(), PCHECK, test_get_by_type_topo_all(), and test_get_by_type_topo_local().
Referenced by main().
{
int ierr;
ierr = test_get_by_type_topo_all( imesh, prtn, false, map.num_parts() );
PCHECK;
ierr = test_get_by_type_topo_local( imesh, prtn, false );
PCHECK;
return 0;
}
int test_get_by_type | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | map | ||
) |
Test query by entity type.
Test:
Definition at line 1050 of file MOAB_iMeshP_unit_tests.cpp.
References PartMap::num_parts(), PCHECK, test_get_by_type_topo_all(), and test_get_by_type_topo_local().
Referenced by main().
{
int ierr;
ierr = test_get_by_type_topo_all( imesh, prtn, true, map.num_parts() );
PCHECK;
ierr = test_get_by_type_topo_local( imesh, prtn, true );
PCHECK;
return 0;
}
static int test_get_by_type_topo_all | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
bool | test_type, | ||
int | num_parts | ||
) | [static] |
Definition at line 889 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, CHKERR, get_entities(), iBase_FACE, iBase_VERTEX, iMesh_addEntArrToSet, iMesh_createEntSet, iMesh_getRootSet, iMesh_POINT, iMesh_QUADRILATERAL, iMeshP_getNumOfTopoAll, iMeshP_getNumOfTypeAll, and PCHECK.
Referenced by test_get_by_topo(), and test_get_by_type().
{
// calculate number of quads and vertices in entire mesh
// from number of parts (see create_mesh(..) function.)
const int expected_global_quad_count = 4 * num_parts;
const int num_col = 2 * ( num_parts / 2 + num_parts % 2 );
const int expected_global_vtx_count = num_parts == 1 ? 9 : num_parts % 2 ? 1 + 5 * num_col : 5 + 5 * num_col;
// test getNumOf*All for root set
int ierr, count;
iBase_EntitySetHandle root;
iMesh_getRootSet( imesh, &root, &ierr );
if( test_type )
iMeshP_getNumOfTypeAll( imesh, prtn, root, iBase_VERTEX, &count, &ierr );
else
iMeshP_getNumOfTopoAll( imesh, prtn, root, iMesh_POINT, &count, &ierr );
PCHECK;
ASSERT( count == expected_global_vtx_count );
if( test_type )
iMeshP_getNumOfTypeAll( imesh, prtn, root, iBase_FACE, &count, &ierr );
else
iMeshP_getNumOfTopoAll( imesh, prtn, root, iMesh_QUADRILATERAL, &count, &ierr );
PCHECK;
ASSERT( count == expected_global_quad_count );
// create an entity set containing half of the quads
std::vector< iBase_EntityHandle > all_quads, half_quads;
ierr = get_entities( imesh, root, iBase_FACE, iMesh_QUADRILATERAL, all_quads );
assert( 0 == all_quads.size() % 2 );
half_quads.resize( all_quads.size() / 2 );
for( size_t i = 0; i < all_quads.size() / 2; ++i )
half_quads[i] = all_quads[2 * i];
iBase_EntitySetHandle set;
iMesh_createEntSet( imesh, 1, &set, &ierr );CHKERR;
iMesh_addEntArrToSet( imesh, &half_quads[0], half_quads.size(), set, &ierr );CHKERR;
// test getNumOf*All with defined set
if( test_type )
iMeshP_getNumOfTypeAll( imesh, prtn, set, iBase_VERTEX, &count, &ierr );
else
iMeshP_getNumOfTopoAll( imesh, prtn, set, iMesh_POINT, &count, &ierr );
PCHECK;
ASSERT( count == 0 );
if( test_type )
iMeshP_getNumOfTypeAll( imesh, prtn, set, iBase_FACE, &count, &ierr );
else
iMeshP_getNumOfTopoAll( imesh, prtn, set, iMesh_QUADRILATERAL, &count, &ierr );
PCHECK;
ASSERT( count == expected_global_quad_count / 2 );
return 0;
}
static int test_get_by_type_topo_local | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
bool | test_type | ||
) | [static] |
Definition at line 942 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, CHKERR, get_entities(), get_local_parts(), iBase_ALL_TYPES, iBase_FACE, iBase_SUCCESS, iBase_VERTEX, iMesh_addEntArrToSet, iMesh_ALL_TOPOLOGIES, iMesh_createEntSet, iMesh_getRootSet, iMesh_POINT, iMesh_QUADRILATERAL, iMeshP_getEntities, iMeshP_getNumOfTopo, and iMeshP_getNumOfType.
Referenced by test_get_by_topo(), and test_get_by_type().
{
int ierr;
iBase_EntitySetHandle root;
iMesh_getRootSet( imesh, &root, &ierr );
// select a single part
std::vector< iMeshP_PartHandle > parts;
ierr = get_local_parts( imesh, prtn, parts );CHKERR;
iMeshP_PartHandle part = parts.front();
// get the entities contained in the part
std::vector< iBase_EntityHandle > part_quads, part_all;
ierr = get_entities( imesh, part, iBase_FACE, iMesh_QUADRILATERAL, part_quads );CHKERR;
ierr = get_entities( imesh, part, iBase_ALL_TYPES, iMesh_ALL_TOPOLOGIES, part_all );CHKERR;
// compare local counts (using root set)
int count;
if( test_type )
iMeshP_getNumOfType( imesh, prtn, part, root, iBase_FACE, &count, &ierr );
else
iMeshP_getNumOfTopo( imesh, prtn, part, root, iMesh_QUADRILATERAL, &count, &ierr );CHKERR;
ASSERT( count == (int)part_quads.size() );
if( test_type )
iMeshP_getNumOfType( imesh, prtn, part, root, iBase_ALL_TYPES, &count, &ierr );
else
iMeshP_getNumOfTopo( imesh, prtn, part, root, iMesh_ALL_TOPOLOGIES, &count, &ierr );CHKERR;
ASSERT( count == (int)part_all.size() );
// compare local contents (using root set)
iBase_EntityHandle* ptr = 0;
int num_ent, junk1 = 0;
iMeshP_getEntities( imesh, prtn, part, root, test_type ? iBase_FACE : iBase_ALL_TYPES,
test_type ? iMesh_ALL_TOPOLOGIES : iMesh_QUADRILATERAL, &ptr, &junk1, &num_ent, &ierr );CHKERR;
std::vector< iBase_EntityHandle > act_quads( ptr, ptr + num_ent );
free( ptr );
junk1 = num_ent = 0;
ptr = 0;
iMeshP_getEntities( imesh, prtn, part, root, iBase_ALL_TYPES, iMesh_ALL_TOPOLOGIES, &ptr, &junk1, &num_ent, &ierr );CHKERR;
std::vector< iBase_EntityHandle > act_all( ptr, ptr + num_ent );
free( ptr );
std::sort( part_quads.begin(), part_quads.end() );
std::sort( part_all.begin(), part_all.end() );
std::sort( act_quads.begin(), act_quads.end() );
std::sort( act_all.begin(), act_all.end() );
ASSERT( part_quads == act_quads );
ASSERT( part_all == act_all );
// create an entity set containing half of the quads from the part
std::vector< iBase_EntityHandle > half_quads( part_quads.size() / 2 );
for( size_t i = 0; i < half_quads.size(); ++i )
half_quads[i] = part_quads[2 * i];
iBase_EntitySetHandle set;
iMesh_createEntSet( imesh, 1, &set, &ierr );CHKERR;
iMesh_addEntArrToSet( imesh, &half_quads[0], half_quads.size(), set, &ierr );CHKERR;
// check if there exists any quads not in the part that we
// can add to the set
std::vector< iBase_EntityHandle > all_quads, other_quads;
ierr = get_entities( imesh, root, iBase_FACE, iMesh_QUADRILATERAL, all_quads );CHKERR;
std::sort( all_quads.begin(), all_quads.end() );
std::sort( part_quads.begin(), part_quads.end() );
std::set_difference( all_quads.begin(), all_quads.end(), part_quads.begin(), part_quads.end(),
std::back_inserter( other_quads ) );
iMesh_addEntArrToSet( imesh, &other_quads[0], other_quads.size(), set, &ierr );CHKERR;
// compare local counts (using non-root set)
if( test_type )
iMeshP_getNumOfType( imesh, prtn, part, set, iBase_FACE, &count, &ierr );
else
iMeshP_getNumOfTopo( imesh, prtn, part, set, iMesh_QUADRILATERAL, &count, &ierr );CHKERR;
ASSERT( count == (int)half_quads.size() );
if( test_type )
iMeshP_getNumOfType( imesh, prtn, part, set, iBase_VERTEX, &count, &ierr );
else
iMeshP_getNumOfTopo( imesh, prtn, part, set, iMesh_POINT, &count, &ierr );CHKERR;
ASSERT( count == 0 );
// compare local contents (using non-root set)
junk1 = 0;
num_ent = 0;
ptr = 0;
iMeshP_getEntities( imesh, prtn, part, set, test_type ? iBase_FACE : iBase_ALL_TYPES,
test_type ? iMesh_ALL_TOPOLOGIES : iMesh_QUADRILATERAL, &ptr, &junk1, &num_ent, &ierr );CHKERR;
act_quads.resize( num_ent );
std::copy( ptr, ptr + num_ent, act_quads.begin() );
free( ptr );
std::sort( half_quads.begin(), half_quads.end() );
std::sort( act_quads.begin(), act_quads.end() );
ASSERT( act_quads == half_quads );
return iBase_SUCCESS;
}
int test_get_neighbors | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | map | ||
) |
Test querying of part neighbors.
Test:
Definition at line 1223 of file MOAB_iMeshP_unit_tests.cpp.
References get_part_neighbors(), iBase_FAILURE, iBase_VERTEX, iMeshP_getNumPartNbors, iMeshP_getNumPartNborsArr, iMeshP_getPartHandlesFromPartsIdsArr, iMeshP_getPartNbors, iMeshP_getPartNborsArr, PartMap::local_id_from_rank(), PartMap::num_parts(), PartMap::part_id_from_local_id(), PartMap::part_id_from_rank(), PCHECK, and size.
Referenced by main().
{
int ierr, rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
std::vector< iMeshP_Part > local_parts;
map.part_id_from_rank( rank, local_parts );
// get handles for local parts
std::vector< iMeshP_PartHandle > handles( local_parts.size() );
iMeshP_PartHandle* ptr = &handles[0];
int junk1 = handles.size(), junk2 = 0;
iMeshP_getPartHandlesFromPartsIdsArr( imesh, prtn, &local_parts[0], local_parts.size(), &ptr, &junk1, &junk2,
&ierr );
PCHECK;
assert( ptr == &handles[0] );
assert( junk2 == (int)handles.size() );
// get logical ids for local parts
std::vector< int > logical_ids;
map.local_id_from_rank( rank, logical_ids );
// get neighbors for each local part
std::vector< std::vector< iMeshP_Part > > neighbors( logical_ids.size() );
for( size_t i = 0; i < logical_ids.size(); ++i )
{
int logical_neighbors[5], num_neighbors;
get_part_neighbors( logical_ids[i], map.num_parts(), logical_neighbors, num_neighbors );
neighbors[i].resize( num_neighbors );
for( int j = 0; j < num_neighbors; ++j )
neighbors[i][j] = map.part_id_from_local_id( logical_neighbors[j] );
std::sort( neighbors[i].begin(), neighbors[i].end() );
}
// test iMeshP_getNumPartNbors
std::vector< iMeshP_Part > invalid, failed;
for( size_t i = 0; i < local_parts.size(); ++i )
{
int count;
iMeshP_getNumPartNbors( imesh, prtn, handles[i], iBase_VERTEX, &count, &ierr );
if( ierr )
failed.push_back( local_parts[i] );
else if( count != (int)neighbors[i].size() )
invalid.push_back( local_parts[i] );
}
if( !failed.empty() )
{
std::cerr << "Processor " << rank << ": iMeshP_getNumPartNbors failed for " << failed.size() << " parts."
<< std::endl;
ierr = iBase_FAILURE;
PCHECK;
}
if( !invalid.empty() )
{
std::cerr << "Processor " << rank << ": iMeshP_getNumPartNbors was incorrect for " << invalid.size()
<< " parts." << std::endl;
ierr = iBase_FAILURE;
PCHECK;
}
// test iMeshP_getPartNbors
ierr = 0;
for( size_t i = 0; i < local_parts.size(); ++i )
{
int count, junk = 0, another_count;
iMeshP_Part* list = 0;
iMeshP_getPartNbors( imesh, prtn, handles[i], iBase_VERTEX, &another_count, &list, &junk, &count, &ierr );
assert( count == another_count );
if( ierr )
failed.push_back( local_parts[i] );
else
{
std::sort( list, list + count );
std::vector< iMeshP_Part > cpy( list, list + count );
if( cpy != neighbors[i] ) invalid.push_back( local_parts[i] );
free( list );
}
}
if( !failed.empty() )
{
std::cerr << "Processor " << rank << ": iMeshP_getPartNbors failed for " << failed.size() << " parts."
<< std::endl;
ierr = iBase_FAILURE;
}
if( !invalid.empty() )
{
std::cerr << "Processor " << rank << ": iMeshP_getPartNbors was incorrect for " << invalid.size() << " parts."
<< std::endl;
ierr = iBase_FAILURE;
}
PCHECK;
// test iMeshP_getNumPartNborsArr
std::vector< int > count_vect( handles.size() );
int* count_arr = &count_vect[0];
junk1 = handles.size();
iMeshP_getNumPartNborsArr( imesh, prtn, &handles[0], handles.size(), iBase_VERTEX, &count_arr, &junk1, &junk2,
&ierr );
PCHECK;
assert( count_arr == &count_vect[0] );
assert( junk2 == (int)handles.size() );
for( size_t i = 0; i < local_parts.size(); ++i )
{
if( count_arr[i] != (int)neighbors[i].size() ) invalid.push_back( local_parts[i] );
}
if( !invalid.empty() )
{
std::cerr << "Processor " << rank << ": iMeshP_getNumPartNborsArr was incorrect for " << invalid.size()
<< " parts." << std::endl;
ierr = iBase_FAILURE;
}
PCHECK;
// test iMeshP_getPartNborsArr
iMeshP_Part* nbor_arr = 0;
junk1 = handles.size(), junk2 = 0;
int junk3 = 0, nbor_size;
iMeshP_getPartNborsArr( imesh, prtn, &handles[0], handles.size(), iBase_VERTEX, &count_arr, &junk1, &junk2,
&nbor_arr, &junk3, &nbor_size, &ierr );
PCHECK;
assert( count_arr == &count_vect[0] );
assert( junk2 == (int)handles.size() );
std::vector< iMeshP_Part > all_nbors( nbor_arr, nbor_arr + nbor_size );
free( nbor_arr );
std::vector< iMeshP_Part >::iterator j = all_nbors.begin();
bool bad_length = false;
for( size_t i = 0; i < local_parts.size(); ++i )
{
if( all_nbors.end() - j > count_arr[i] )
{
bad_length = true;
break;
}
if( count_arr[i] != (int)neighbors[i].size() )
{
invalid.push_back( local_parts[i] );
}
else
{
std::vector< iMeshP_Part >::iterator e = j + count_arr[i];
std::sort( j, e );
if( !std::equal( j, e, neighbors[i].begin() ) ) invalid.push_back( local_parts[i] );
}
}
if( bad_length )
{
std::cerr << "Processor " << rank << ": iMeshP_getPartNborsArr had inconsistent result array lengths."
<< std::endl;
ierr = iBase_FAILURE;
}
if( !invalid.empty() )
{
std::cerr << "Processor " << rank << ": iMeshP_getPartNborsArr was incorrect for " << invalid.size()
<< " parts." << std::endl;
ierr = iBase_FAILURE;
}
PCHECK;
return 0;
}
int test_get_part_boundary | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | map | ||
) |
Test querying of part boundary entities.
Test:
Definition at line 1532 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, error(), get_local_parts(), PartMap::get_parts(), iBase_FAILURE, iBase_SUCCESS, iBase_VERTEX, iMesh_POINT, iMeshP_ALL_PARTS, iMeshP_getNumPartBdryEnts, iMeshP_getPartBdryEnts, and interface_verts().
Referenced by main().
{
int ierr, rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
// get local part handles and part ids, and global part id list
std::vector< iMeshP_PartHandle > local_handles;
std::vector< iMeshP_Part > local_ids;
std::vector< iMeshP_Part > all_parts = map.get_parts();
std::map< iMeshP_PartHandle, std::vector< iBase_EntityHandle > > part_bdry;
ierr = get_local_parts( imesh, prtn, local_handles, &local_ids );CHKERR;
// for each combination of local part with any other part,
// check for valid function values.
std::vector< std::pair< iMeshP_Part, iMeshP_Part > > num_failed, num_error, list_failed, list_error, error;
for( size_t i = 0; i < local_handles.size(); ++i )
{
iMeshP_PartHandle local_handle = local_handles[i];
iMeshP_Part local_id = local_ids[i];
for( std::vector< iMeshP_Part >::iterator j = all_parts.begin(); j != all_parts.end(); ++j )
{
iMeshP_Part other_id = *j;
if( other_id == local_id ) continue;
std::pair< iMeshP_Part, iMeshP_Part > part_pair;
part_pair.first = local_id;
part_pair.second = other_id;
// get expected values
std::vector< iBase_EntityHandle > shared_verts;
ierr = interface_verts( imesh, prtn, local_handle, other_id, map, shared_verts );
if( ierr != iBase_SUCCESS )
{
error.push_back( part_pair );
continue;
}
std::sort( shared_verts.begin(), shared_verts.end() );
// test iMeshP_getNumPartBdryEnts
int count;
iMeshP_getNumPartBdryEnts( imesh, prtn, local_handle, iBase_VERTEX, iMesh_POINT, other_id, &count, &ierr );
if( iBase_SUCCESS != ierr )
num_error.push_back( part_pair );
else if( count != (int)shared_verts.size() )
num_failed.push_back( part_pair );
// test iMeshP_getPartBdryEnts
iBase_EntityHandle* ptr = 0;
int junk = 0;
iMeshP_getPartBdryEnts( imesh, prtn, local_handle, iBase_VERTEX, iMesh_POINT, other_id, &ptr, &junk, &count,
&ierr );
if( iBase_SUCCESS != ierr )
list_error.push_back( part_pair );
else
{
std::copy( ptr, ptr + count, std::back_inserter( part_bdry[local_handles[i]] ) );
std::sort( ptr, ptr + count );
if( (int)shared_verts.size() != count || !std::equal( shared_verts.begin(), shared_verts.end(), ptr ) )
list_failed.push_back( part_pair );
free( ptr );
}
}
}
if( !error.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " Internal error for " << error.size() << " part pairs." << std::endl;
ierr = iBase_FAILURE;
}
if( !num_error.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMeshP_getNumPartBdryEnts return error for " << num_error.size() << " part pairs." << std::endl;
ierr = iBase_FAILURE;
}
if( !list_error.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMeshP_getPartBdryEnts return error for " << list_error.size() << " part pairs." << std::endl;
ierr = iBase_FAILURE;
}
if( !num_failed.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMeshP_getNumPartBdryEnts return incorrect results for " << num_failed.size() << " part pairs."
<< std::endl;
ierr = iBase_FAILURE;
}
if( !list_failed.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMeshP_getPartBdryEnts return incorrect results for " << list_failed.size() << " part pairs."
<< std::endl;
ierr = iBase_FAILURE;
}
if( iBase_SUCCESS != ierr ) return ierr;
// test with iMeshP_ALL_PARTS
for( size_t i = 0; i < local_handles.size(); ++i )
{
std::vector< iBase_EntityHandle >& exp_bdry = part_bdry[local_handles[i]];
std::sort( exp_bdry.begin(), exp_bdry.end() );
exp_bdry.erase( std::unique( exp_bdry.begin(), exp_bdry.end() ), exp_bdry.end() );
std::pair< iMeshP_Part, iMeshP_Part > part_pair;
part_pair.first = local_ids[i];
part_pair.second = iMeshP_ALL_PARTS;
int num = 0;
iMeshP_getNumPartBdryEnts( imesh, prtn, local_handles[i], iBase_VERTEX, iMesh_POINT, iMeshP_ALL_PARTS, &num,
&ierr );
if( ierr )
num_error.push_back( part_pair );
else if( num != (int)exp_bdry.size() )
num_failed.push_back( part_pair );
iBase_EntityHandle* bdry = 0;
int junk = num = 0;
iMeshP_getPartBdryEnts( imesh, prtn, local_handles[i], iBase_VERTEX, iMesh_POINT, iMeshP_ALL_PARTS, &bdry,
&junk, &num, &ierr );
if( ierr )
list_error.push_back( part_pair );
else
{
std::sort( bdry, bdry + num );
if( num != (int)exp_bdry.size() || !std::equal( bdry, bdry + num, exp_bdry.begin() ) )
list_failed.push_back( part_pair );
free( bdry );
}
}
if( !num_error.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMeshP_getNumPartBdryEnts return error for " << num_error.size() << " part pairs." << std::endl;
ierr = iBase_FAILURE;
}
if( !list_error.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMeshP_getPartBdryEnts return error for " << list_error.size() << " part pairs." << std::endl;
ierr = iBase_FAILURE;
}
if( !num_failed.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMeshP_getNumPartBdryEnts return incorrect results for " << num_failed.size() << " part pairs."
<< std::endl;
ierr = iBase_FAILURE;
}
if( !list_failed.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMeshP_getPartBdryEnts return incorrect results for " << list_failed.size() << " part pairs."
<< std::endl;
ierr = iBase_FAILURE;
}
return ierr;
}
int test_get_partitions | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | |||
) |
Test partition query methods.
Test:
Definition at line 824 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, iMeshP_getNumPartitions, iMeshP_getPartitionComm, iMeshP_getPartitions, PCHECK, and size.
Referenced by main().
{
int ierr;
// test iMeshP_getPartitionCom
MPI_Comm comm = MPI_COMM_SELF;
iMeshP_getPartitionComm( imesh, prtn, &comm, &ierr );
PCHECK;
ASSERT( comm == MPI_COMM_WORLD );
// test iMeshP_getPartitions
iMeshP_PartitionHandle* array = 0;
int alloc = 0, size = -1;
iMeshP_getPartitions( imesh, &array, &alloc, &size, &ierr );
PCHECK;
ASSERT( array != 0 );
ASSERT( alloc == size );
ASSERT( size > 0 );
int idx = std::find( array, array + size, prtn ) - array;
free( array );
ASSERT( idx < size );
// test iMesP_getNumPartitions
int size2 = -1;
iMeshP_getNumPartitions( imesh, &size2, &ierr );
PCHECK;
ASSERT( size2 == size );
return 0;
}
int test_get_parts | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | map | ||
) |
Test part quyery methods.
Test:
Definition at line 861 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, PartMap::count_from_rank(), iBase_SUCCESS, iMeshP_getLocalParts, iMeshP_getNumGlobalParts, iMeshP_getNumLocalParts, PartMap::num_parts(), PCHECK, and size.
Referenced by main().
{
int size, rank, ierr;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
int num_part_g;
iMeshP_getNumGlobalParts( imesh, prtn, &num_part_g, &ierr );
PCHECK;
ASSERT( num_part_g == map.num_parts() );
int num_part_l;
iMeshP_getNumLocalParts( imesh, prtn, &num_part_l, &ierr );
PCHECK;
ASSERT( num_part_l == map.count_from_rank( rank ) );
std::vector< iMeshP_PartHandle > parts( num_part_l );
iMeshP_PartHandle* ptr = &parts[0];
int junk1 = num_part_l, count = -1;
iMeshP_getLocalParts( imesh, prtn, &ptr, &junk1, &count, &ierr );
PCHECK;
assert( ptr == &parts[0] );
assert( junk1 == num_part_l );
ASSERT( count == num_part_l );
return iBase_SUCCESS;
}
int test_load | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
PartMap & | map, | ||
int | comm_size | ||
) |
Consistency check for parallel load.
All other tests depend on this one.
Definition at line 803 of file MOAB_iMeshP_unit_tests.cpp.
References PartMap::build_map(), CHKERR, FILENAME, iBase_SUCCESS, iMesh_getRootSet, iMeshP_loadAll, PCHECK, and root_set.
Referenced by run_test().
{
int ierr;
iBase_EntitySetHandle root_set;
iMesh_getRootSet( imesh, &root_set, &ierr );
const char* opt = "moab:PARTITION=PARALLEL_PARTITION";
iMeshP_loadAll( imesh, prtn, root_set, FILENAME, opt, &ierr, strlen( FILENAME ), strlen( opt ) );
PCHECK;
ierr = map.build_map( imesh, prtn, proc_size );CHKERR;
return iBase_SUCCESS;
}
int test_part_boundary_iter | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | map | ||
) |
Test querying of part boundary entities.
Test:
Definition at line 1699 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, get_local_parts(), PartMap::get_parts(), iBase_FAILURE, iBase_SUCCESS, iBase_VERTEX, iMesh_endEntArrIter, iMesh_endEntIter, iMesh_getNextEntArrIter, iMesh_getNextEntIter, iMesh_POINT, iMeshP_initPartBdryEntArrIter, iMeshP_initPartBdryEntIter, and interface_verts().
Referenced by main().
{
int ierr, rank, has_data;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
// get local part handles and part ids, and global part id list
std::vector< iMeshP_PartHandle > local_handles;
std::vector< iMeshP_Part > local_ids;
std::vector< iMeshP_Part > all_parts = map.get_parts();
ierr = get_local_parts( imesh, prtn, local_handles, &local_ids );CHKERR;
std::vector< std::pair< iMeshP_Part, iMeshP_Part > > single_failed, single_error, single_step_error, array_failed,
array_error, array_step_error;
for( size_t i = 0; i < local_handles.size(); ++i )
{
iMeshP_PartHandle local_handle = local_handles[i];
iMeshP_Part local_id = local_ids[i];
for( std::vector< iMeshP_Part >::iterator j = all_parts.begin(); j != all_parts.end(); ++j )
{
iMeshP_Part other_id = *j;
if( other_id == local_id ) continue;
std::pair< iMeshP_Part, iMeshP_Part > part_pair;
part_pair.first = local_id;
part_pair.second = other_id;
// get expected values
std::vector< iBase_EntityHandle > shared_verts;
ierr = interface_verts( imesh, prtn, local_handle, other_id, map, shared_verts );
if( ierr != iBase_SUCCESS || 0 == shared_verts.size() ) continue;
std::sort( shared_verts.begin(), shared_verts.end() );
// test single entity iterator
iBase_EntityIterator siter;
iMeshP_initPartBdryEntIter( imesh, prtn, local_handle, iBase_VERTEX, iMesh_POINT, other_id, &siter, &ierr );
if( ierr != iBase_SUCCESS )
{
single_error.push_back( part_pair );
}
else
{
std::vector< iBase_EntityHandle > results;
for( ;; )
{
iBase_EntityHandle handle;
iMesh_getNextEntIter( imesh, siter, &handle, &has_data, &ierr );
if( ierr != iBase_SUCCESS )
{
single_step_error.push_back( part_pair );
break;
}
if( !has_data ) break;
results.push_back( handle );
}
std::sort( results.begin(), results.end() );
if( results.size() != shared_verts.size() ||
!std::equal( results.begin(), results.end(), shared_verts.begin() ) )
single_failed.push_back( part_pair );
}
iMesh_endEntIter( imesh, siter, &ierr );
// test array iterator
iBase_EntityArrIterator aiter;
iMeshP_initPartBdryEntArrIter( imesh, prtn, local_handle, iBase_VERTEX, iMesh_POINT, shared_verts.size(),
other_id, &aiter, &ierr );
if( ierr != iBase_SUCCESS )
{
array_error.push_back( part_pair );
iMesh_endEntArrIter( imesh, aiter, &ierr );
continue;
}
iBase_EntityHandle results[5], *ptr = results;
int junk = 5, count;
iMesh_getNextEntArrIter( imesh, aiter, &ptr, &junk, &count, &has_data, &ierr );
if( ierr != iBase_SUCCESS || !has_data )
{
array_step_error.push_back( part_pair );
iMesh_endEntArrIter( imesh, aiter, &ierr );
continue;
}
iMesh_endEntArrIter( imesh, aiter, &ierr );
assert( count <= 5 );
assert( ptr == results );
std::sort( ptr, ptr + count );
if( count != (int)shared_verts.size() || !std::equal( shared_verts.begin(), shared_verts.end(), results ) )
array_failed.push_back( part_pair );
}
}
if( !single_error.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMeshP_initPartBdryEntIter return error for " << single_error.size() << " part pairs."
<< std::endl;
ierr = iBase_FAILURE;
}
if( !single_step_error.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMesh_getNextEntIter return error for " << single_step_error.size() << " part pairs."
<< std::endl;
ierr = iBase_FAILURE;
}
if( !single_failed.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMeshP_initPartBdryEntIter iterator iterated over invalid entities for " << single_failed.size()
<< " part pairs." << std::endl;
ierr = iBase_FAILURE;
}
if( !array_error.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMeshP_initPartBdryEntArrIter return error for " << array_error.size() << " part pairs."
<< std::endl;
ierr = iBase_FAILURE;
}
if( !array_step_error.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMesh_getNextEntArrIter return error for " << array_step_error.size() << " part pairs."
<< std::endl;
ierr = iBase_FAILURE;
}
if( !array_failed.empty() )
{
std::cerr << "Processor " << rank << ": Error at " __FILE__ ":" << __LINE__ << std::endl
<< " iMeshP_initPartBdryEntArrIter iterator iterated over invalid entities for "
<< array_failed.size() << " part pairs." << std::endl;
ierr = iBase_FAILURE;
}
return ierr;
}
int test_part_id_handle | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | map | ||
) |
Test mapping from part id to part handle.
Test:
Test:
Definition at line 1086 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, CHKERR, iMeshP_getPartHandleFromPartId, iMeshP_getPartHandlesFromPartsIdsArr, iMeshP_getPartIdFromPartHandle, iMeshP_getPartIdsFromPartHandlesArr, PartMap::part_id_from_rank(), and PCHECK.
Referenced by main().
{
// get local part ids
int rank, ierr;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
std::vector< iMeshP_Part > ids;
map.part_id_from_rank( rank, ids );
// check single-part functions and build list of part handles
std::vector< iMeshP_PartHandle > handles( ids.size() );
size_t i;
for( i = 0; i < ids.size(); ++i )
{
iMeshP_getPartHandleFromPartId( imesh, prtn, ids[i], &handles[i], &ierr );CHKERR;
iMeshP_Part id;
iMeshP_getPartIdFromPartHandle( imesh, prtn, handles[i], &id, &ierr );CHKERR;
if( id != ids[i] ) break;
}
ASSERT( i == ids.size() );
// test iMeshP_getPartIdsFromPartHandlesArr
std::vector< iMeshP_Part > ids2( ids.size() );
int junk1 = ids.size(), junk2 = 0;
iMeshP_Part* ptr = &ids2[0];
iMeshP_getPartIdsFromPartHandlesArr( imesh, prtn, &handles[0], handles.size(), &ptr, &junk1, &junk2, &ierr );
PCHECK;
ASSERT( ptr == &ids2[0] );
ASSERT( junk2 == (int)ids2.size() );
ASSERT( ids == ids2 );
// test iMeshP_getPartHandlesFromPartsIdsArr
std::vector< iMeshP_PartHandle > handles2( handles.size() );
junk1 = handles.size();
junk2 = 0;
iMeshP_PartHandle* ptr2 = &handles2[0];
iMeshP_getPartHandlesFromPartsIdsArr( imesh, prtn, &ids[0], ids.size(), &ptr2, &junk1, &junk2, &ierr );
PCHECK;
ASSERT( ptr2 == &handles2[0] );
ASSERT( junk2 == (int)handles2.size() );
ASSERT( handles == handles2 );
return 0;
}
int test_part_rank | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | map | ||
) |
Test get part rank.
Tests:
Definition at line 1136 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, PartMap::get_parts(), PartMap::get_ranks(), iBase_FAILURE, iBase_SUCCESS, iMeshP_getRankOfPart, iMeshP_getRankOfPartArr, and PCHECK.
Referenced by main().
{
int ierr = 0, rank;
std::vector< iMeshP_Part > invalid, failed;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
// test iMeshP_getRankOfPart
for( size_t i = 0; i < map.get_parts().size(); ++i )
{
int pr;
iMeshP_getRankOfPart( imesh, prtn, map.get_parts()[i], &pr, &ierr );
if( iBase_SUCCESS != ierr )
failed.push_back( map.get_parts()[i] );
else if( pr != map.get_ranks()[i] )
invalid.push_back( map.get_parts()[i] );
}
if( !failed.empty() )
{
std::cerr << "Processor " << rank << ": iMeshP_getRankOfPart failed for " << failed.size() << " parts."
<< std::endl;
ierr = iBase_FAILURE;
}
if( !invalid.empty() )
{
std::cerr << "Processor " << rank << ": iMeshP_getRankOfPart was incorrect for " << invalid.size() << " parts."
<< std::endl;
ierr = iBase_FAILURE;
}
PCHECK;
// test iMeshP_getRankOfPartArr
std::vector< int > ranks( map.get_parts().size() );
int junk1 = ranks.size(), junk2, *ptr = &ranks[0];
iMeshP_getRankOfPartArr( imesh, prtn, &map.get_parts()[0], map.get_parts().size(), &ptr, &junk1, &junk2, &ierr );
PCHECK;
assert( ptr == &ranks[0] );
assert( junk1 == (int)ranks.size() );
ASSERT( junk2 == (int)ranks.size() );
for( size_t i = 0; i < map.get_parts().size(); ++i )
{
if( ranks[i] != map.get_ranks()[i] ) invalid.push_back( map.get_parts()[i] );
}
if( !invalid.empty() )
{
std::cerr << "Processor " << rank << ": iMeshP_getRankOfPartArr was incorrect for " << invalid.size()
<< " parts." << std::endl;
ierr = iBase_FAILURE;
}
PCHECK;
return 0;
}
int test_push_tag_data_common | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
int | num_ghost_layers | ||
) |
Test commuinication of tag data.
Test:
Definition at line 2736 of file MOAB_iMeshP_unit_tests.cpp.
References ASSERT, CHKERR, get_entities(), iBase_FACE, iBase_INTEGER, iBase_SUCCESS, iBase_VERTEX, iMesh_createTag, iMesh_getIntArrData, iMesh_getIntData, iMesh_getRootSet, iMesh_getTagHandle, iMesh_POINT, iMesh_setIntArrData, iMeshP_createGhostEntsAll, iMeshP_getEntOwnerPartArr, iMeshP_getNumCopies, iMeshP_getRankOfPartArr, iMeshP_pushTags, iMeshP_pushTagsEnt, and PCHECK.
Referenced by test_push_tag_data_ghost(), and test_push_tag_data_iface().
{
const char* src_name = "test_src";
const char* dst_name = "test_dst";
int ierr, rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
if( num_ghost_layers )
{
iMeshP_createGhostEntsAll( imesh, prtn, iBase_FACE, iBase_VERTEX, num_ghost_layers, 0, &ierr );
PCHECK;
}
iBase_TagHandle src_tag, dst_tag;
iMesh_createTag( imesh, src_name, 1, iBase_INTEGER, &src_tag, &ierr, strlen( src_name ) );CHKERR;
iMesh_createTag( imesh, dst_name, 1, iBase_INTEGER, &dst_tag, &ierr, strlen( dst_name ) );CHKERR;
iBase_EntitySetHandle root;
iMesh_getRootSet( imesh, &root, &ierr );CHKERR;
std::vector< iBase_EntityHandle > verts;
ierr = get_entities( imesh, root, iBase_VERTEX, iMesh_POINT, verts );CHKERR;
// test iMeshP_pushTags
// each processor writes its rank on all vertices
// after push, each vertex should be tagged with the rank of its owner
std::vector< int > tag_vals( verts.size(), rank );
iMesh_setIntArrData( imesh, &verts[0], verts.size(), src_tag, &tag_vals[0], tag_vals.size(), &ierr );CHKERR;
iMeshP_pushTags( imesh, prtn, src_tag, dst_tag, iBase_VERTEX, iMesh_POINT, &ierr );
PCHECK;
tag_vals.clear();
tag_vals.resize( verts.size(), -1 );
iBase_TagHandle id_tag;
iMesh_getTagHandle( imesh, "GLOBAL_ID", &id_tag, &ierr, strlen( "GLOBAL_ID" ) );
std::vector< int > ids( verts.size() );
int *junk1 = &ids[0], junk2 = ids.size(), junk3;
iMesh_getIntArrData( imesh, &verts[0], verts.size(), id_tag, &junk1, &junk2, &junk3, &ierr );
PCHECK;
int errcount = 0;
for( size_t i = 0; i < verts.size(); ++i )
{
iMesh_getIntData( imesh, verts[i], dst_tag, &tag_vals[i], &ierr );
if( ierr != iBase_SUCCESS )
{
std::cerr << "Rank " << rank << " : getIntData failed for vertex " << ids[i] << std::endl;
std::cerr.flush();
++errcount;
}
}
ASSERT( 0 == errcount );
// int *junk1 = &tag_vals[0], junk2 = tag_vals.size(), junk3;
// iMesh_getIntArrData( imesh, &verts[0], verts.size(), dst_tag, &junk1, &junk2, &junk3, &ierr
// ); PCHECK; assert( junk1 == &tag_vals[0] ); assert( junk2 == (int)tag_vals.size() ); assert(
// junk3 == (int)verts.size() );
std::vector< int > expected( verts.size() );
std::vector< iMeshP_Part > parts( verts.size() );
iMeshP_Part* junk4 = &parts[0];
junk2 = parts.size();
iMeshP_getEntOwnerPartArr( imesh, prtn, &verts[0], verts.size(), &junk4, &junk2, &junk3, &ierr );
PCHECK;
assert( junk4 == &parts[0] );
assert( junk2 == (int)parts.size() );
assert( junk3 == (int)verts.size() );
junk1 = &expected[0];
junk2 = expected.size();
iMeshP_getRankOfPartArr( imesh, prtn, &parts[0], parts.size(), &junk1, &junk2, &junk3, &ierr );
PCHECK;
assert( junk1 == &expected[0] );
assert( junk2 == (int)expected.size() );
assert( junk3 == (int)parts.size() );
ASSERT( tag_vals == expected );
// test iMeshP_pushTagsEnt
// write -1 on all vertices
// For each vertex owned by this processor and shared with more than
// two others, write the rank of the owning processor.
tag_vals.clear();
tag_vals.resize( verts.size(), -1 );
iMesh_setIntArrData( imesh, &verts[0], verts.size(), src_tag, &tag_vals[0], tag_vals.size(), &ierr );
PCHECK;
tag_vals.resize( verts.size(), -1 );
iMesh_setIntArrData( imesh, &verts[0], verts.size(), dst_tag, &tag_vals[0], tag_vals.size(), &ierr );
PCHECK;
std::vector< iBase_EntityHandle > some;
for( size_t i = 0; i < verts.size(); ++i )
{
int num;
iMeshP_getNumCopies( imesh, prtn, verts[i], &num, &ierr );
if( iBase_SUCCESS != ierr ) break;
if( num > 2 )
some.push_back( verts[i] );
else
expected[i] = -1;
}
tag_vals.clear();
tag_vals.resize( some.size(), rank );
iMesh_setIntArrData( imesh, &some[0], some.size(), src_tag, &tag_vals[0], tag_vals.size(), &ierr );
PCHECK;
iMeshP_pushTagsEnt( imesh, prtn, src_tag, dst_tag, &some[0], some.size(), &ierr );
PCHECK;
tag_vals.clear();
tag_vals.resize( verts.size(), -1 );
junk1 = &tag_vals[0];
junk2 = tag_vals.size();
iMesh_getIntArrData( imesh, &verts[0], verts.size(), dst_tag, &junk1, &junk2, &junk3, &ierr );CHKERR;
assert( junk1 == &tag_vals[0] );
assert( junk2 == (int)tag_vals.size() );
assert( junk3 == (int)verts.size() );
ASSERT( tag_vals == expected );
return iBase_SUCCESS;
}
int test_push_tag_data_ghost | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | |||
) |
Test commuinication of tag data.
Test:
Definition at line 2877 of file MOAB_iMeshP_unit_tests.cpp.
References test_push_tag_data_common().
Referenced by main().
{
return test_push_tag_data_common( imesh, prtn, 1 );
}
int test_push_tag_data_iface | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | prtn, | ||
const PartMap & | |||
) |
Test commuinication of tag data.
Test:
Definition at line 2866 of file MOAB_iMeshP_unit_tests.cpp.
References test_push_tag_data_common().
Referenced by main().
{
return test_push_tag_data_common( imesh, prtn, 0 );
}
int vertex_tag | ( | iMesh_Instance | imesh, |
iBase_EntityHandle | vertex, | ||
int & | tag | ||
) |
get unique identifier for each vertex
Definition at line 787 of file MOAB_iMeshP_unit_tests.cpp.
References CHKERR, and iMesh_getVtxCoord.
Referenced by get_num_adj_all(), and test_entity_copies().
{
int ierr;
double x, y, z;
iMesh_getVtxCoord( imesh, vertex, &x, &y, &z, &ierr );CHKERR;
int xc = (int)round( x );
int yc = (int)round( y );
tag = 5 * xc + yc + 1;
return ierr;
}
const char* const FILENAME = "iMeshP_test_file" |
Definition at line 19 of file MOAB_iMeshP_unit_tests.cpp.
Referenced by main(), run_test(), and test_load().