MOAB: Mesh Oriented datABase  (version 5.4.1)
imoab_test.c
Go to the documentation of this file.
00001 #include "moab/MOABConfig.h"
00002 
00003 #ifdef MOAB_HAVE_MPI
00004 #include "moab_mpi.h"
00005 #endif
00006 
00007 #include "moab/iMOAB.h"
00008 #include <string.h>
00009 
00010 #define CHECKRC( rc, message )             \
00011     if( 0 != ( rc ) )                      \
00012     {                                      \
00013         printf( "Error: %s.\n", message ); \
00014         return 1;                          \
00015     }
00016 
00017 int main( int argc, char* argv[] )
00018 {
00019     /* Declarations */
00020     ErrCode rc;
00021     int nprocs = 1, rank = 0;
00022     char filen[1024] = "";
00023     int i, j, k;
00024 
00025     int irank = 0, num_tags_to_sync = 1;
00026     int* ranks;
00027 
00028     int appID, appDupID;
00029     iMOAB_AppID pid;
00030     iMOAB_AppID pidDup;
00031     int compid = 11, compdupid = 12;
00032 
00033     int num_global_vertices = 0, num_global_elements = 0, num_dimension = 0, num_parts = 0;
00034     int nverts[3], nelem[3], nblocks[3], nsbc[3], ndbc[3];
00035 
00036     iMOAB_GlobalID* vGlobalID;
00037     int* vranks;
00038     double* coords;
00039     int size_coords;
00040 
00041 #ifdef MOAB_HAVE_MPI
00042     const char* read_opts   = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS";
00043     int num_ghost_layers[1] = { 1 };
00044 #else
00045     const char* read_opts   = "";
00046     int num_ghost_layers[1] = { 0 };
00047 #endif
00048 
00049     iMOAB_GlobalID* gbIDs;
00050     int tagIndex[2];
00051     int entTypes[2]    = { 0, 1 }; /* first is on vertex, second is on elements; */
00052     int tagTypes[2]    = { DENSE_INTEGER, DENSE_DOUBLE };
00053     int num_components = 1;
00054 
00055     iMOAB_GlobalID *element_global_IDs, *block_IDs;
00056     int vertices_per_element, num_elements_in_block;
00057     int conn[27], nv, eindex;
00058 
00059     int* int_tag_vals;
00060     double* double_tag_vals;
00061 
00062     int local_index           = 0;  /* test element with local index 0 */
00063     int num_adjacent_elements = 10; /* we can have maximum 6 actually */
00064     iMOAB_LocalID adjacent_element_IDs[10], *element_connectivity, *local_element_ID;
00065     int size_conn, *element_ownership;
00066     iMOAB_GlobalID* global_element_ID;
00067 
00068     iMOAB_LocalID *vertBC_ID, *surfBC_ID;
00069     int *vertBC_value, *ref_surf, *bc_value;
00070 
00071     char *outputFile, *writeOptions;
00072 
00073 #ifdef MOAB_HAVE_MPI
00074     MPI_Comm comm;
00075     MPI_Init( &argc, &argv );
00076 
00077     comm = MPI_COMM_WORLD;
00078     MPI_Comm_size( comm, &nprocs );
00079     MPI_Comm_rank( comm, &rank );
00080 #endif
00081 
00082 #ifdef MOAB_HAVE_HDF5
00083     strcpy( filen, MOAB_MESH_DIR );
00084     strcat( filen, "unittest/io/p8ex1.h5m" );
00085 #endif
00086 
00087     if( argc > 1 ) strcpy( filen, argv[1] );
00088 
00089     if( !strlen( filen ) )
00090     {
00091         printf( "Invalid filename specified at command line.\n" );
00092         return 1;
00093     }
00094     /*
00095      * MOAB needs to be initialized; A MOAB instance will be created, and will be used by each
00096      * application in this framework. There is no parallel context yet.
00097      */
00098     rc = iMOAB_Initialize( argc, argv );
00099     CHECKRC( rc, "failed to initialize MOAB" );
00100 
00101     /*
00102      * Header information is cheap to retrieve from an hdf5 file; it can be called by each process
00103      * or can be called by one master task and broadcasted. The hdf5 file has to be in MOAB native
00104      * format, and has to be partitioned in advance. There should be at least as many partitions in
00105      * the file as number of tasks in the communicator.
00106      */
00107     rc = iMOAB_ReadHeaderInfo( filen, &num_global_vertices, &num_global_elements, &num_dimension, &num_parts );
00108     CHECKRC( rc, "failed to read header info" );
00109 
00110     if( 0 == rank )
00111     {
00112         printf( "file %s has %d vertices, %d elements, %d parts in partition\n", filen, num_global_vertices,
00113                 num_global_elements, num_parts );
00114     }
00115 
00116     pid    = &appID;
00117     pidDup = &appDupID;
00118 
00119     /*
00120      * Each application has to be registered once. A mesh set and a parallel communicator will be
00121      * associated with each application. A unique application id will be returned, and will be used
00122      * for all future mesh operations/queries.
00123      */
00124     rc = iMOAB_RegisterApplication( "MBAPP",
00125 #ifdef MOAB_HAVE_MPI
00126                                     &comm,
00127 #endif
00128                                     &compid, pid );
00129     CHECKRC( rc, "failed to register application" );
00130 
00131     rc = iMOAB_RegisterApplication( "MBDUPAPP",
00132 #ifdef MOAB_HAVE_MPI
00133                                     &comm,
00134 #endif
00135                                     &compdupid, pidDup );
00136     CHECKRC( rc, "failed to register duplicate application" );
00137 
00138     /*
00139      * Loading the mesh is a parallel IO operation. Ghost layers can be exchanged too, and default
00140      * MOAB sets are augmented with ghost elements. By convention, blocks correspond to MATERIAL_SET
00141      * sets, side sets with NEUMANN_SET sets, node sets with DIRICHLET_SET sets. Each element and
00142      * vertex entity should have a GLOBAL ID tag in the file, which will be available for visible
00143      * entities
00144      */
00145     rc = iMOAB_LoadMesh( pid, filen, read_opts, num_ghost_layers );
00146     CHECKRC( rc, "failed to load mesh" );
00147 
00148     rc = iMOAB_LoadMesh( pidDup, filen, read_opts, num_ghost_layers );
00149     CHECKRC( rc, "failed to load mesh" );
00150 
00151     rc = iMOAB_SetGlobalInfo( pid, &num_global_vertices, &num_global_elements );
00152     CHECKRC( rc, "failed to set global info" );
00153 
00154     /*
00155      * Each process in the communicator will have access to a local mesh instance, which will
00156      * contain the original cells in the local partition and ghost entities. Number of vertices,
00157      * primary cells, visible blocks, number of sidesets and nodesets boundary conditions will be
00158      * returned in size 3 arrays, for local, ghost and total numbers.
00159      */
00160     rc = iMOAB_GetMeshInfo( pid, nverts, nelem, nblocks, nsbc, ndbc );
00161     CHECKRC( rc, "failed to get mesh info" );
00162 
00163     vGlobalID = (iMOAB_GlobalID*)malloc( nverts[2] * sizeof( iMOAB_GlobalID ) );
00164     /*
00165      * All visible vertices have a unique global ID. All arrays are allocated by client.
00166      * Currently, global ID is a 32 bit integer, total number of visible vertices was returned by
00167      * iMOAB_GetMeshInfo
00168      */
00169     rc = iMOAB_GetVertexID( pid, &nverts[2], vGlobalID );
00170     CHECKRC( rc, "failed to get vertex id info" );
00171 
00172     vranks = (int*)malloc( nverts[2] * sizeof( int ) );
00173     /*
00174      * In MOAB terminology, a vertex can be owned, shared or ghost. An owned vertex will be
00175      * owned by the current process. A shared vertex appears at the interface between partitions, it
00176      * can be owned by another process, while a ghost vertex is owned by another process always. All
00177      * vertex arrays have a natural local order, in which the ghost vertices are at the end of the
00178      * arrays. The local index of the vertex will vary from 0 to number of visible vertices (in this
00179      * example nverts[2]-1)
00180      */
00181     rc = iMOAB_GetVertexOwnership( pid, &nverts[2], vranks );
00182     CHECKRC( rc, "failed to get vertex ranks" );
00183 
00184     coords      = (double*)malloc( 3 * nverts[2] * sizeof( double ) );
00185     size_coords = 3 * nverts[2];
00186     /*
00187      * Coordinates are returned interleaved, for all visible vertices. Size is dimension times
00188      * number of visible vertices
00189      */
00190     rc = iMOAB_GetVisibleVerticesCoordinates( pid, &size_coords, coords );
00191     CHECKRC( rc, "failed to get coordinates" );
00192 
00193     /*
00194      * Block IDs correspond to MATERIAL_SET tag values in hdf5 file
00195      * They also correspond to block IDs in a Cubit model.
00196      * Local visible blocks might contain ghost cells, owned by other
00197      * processes.
00198      * 
00199      * Inside MOAB, a block will correspond to a meshset with a MATERIAL_SET tag,
00200      * with value the block ID.
00201      * A MATERIAL_SET tag in moab if SPARSE and type INTEGER.
00202      */
00203     gbIDs = (iMOAB_GlobalID*)malloc( nblocks[2] * sizeof( iMOAB_GlobalID ) );
00204     rc    = iMOAB_GetBlockID( pid, &nblocks[2], gbIDs );
00205     CHECKRC( rc, "failed to get block info" );
00206 
00207     /*
00208      * The 2 tags used in this example exist in the file, already.
00209      * If a user needs a new tag, it can be defined with the same call as this one
00210      * this method, iMOAB_DefineTagStorage, will return a local index for the tag.
00211      * The name of the tag is case sensitive.
00212      * This method is collective.
00213      */
00214     rc = iMOAB_DefineTagStorage( pid, "INTFIELD", &tagTypes[0], &num_components, &tagIndex[0] );
00215     CHECKRC( rc, "failed to get tag INTFIELD " );
00216     rc = iMOAB_DefineTagStorage( pid, "DFIELD", &tagTypes[1], &num_components, &tagIndex[1] );
00217     CHECKRC( rc, "failed to get tag DFIELD " );
00218 
00219     /*
00220      * Synchronize one of the tags only, just to see what happens;
00221      * Tags are not exchanged for ghost entities by default. The user has to explicitly
00222      * synchronize them with a call like this one. The tags to synchronize are referenced by the
00223      * index returned at their "definition" with iMOAB_DefineTagStorage method.
00224      */
00225     rc = iMOAB_SynchronizeTags( pid, &num_tags_to_sync, &tagIndex[0], &tagTypes[0] );
00226     CHECKRC( rc, "failed to sync tag INTFIELD " );
00227 
00228     for( irank = 0; irank < nprocs; irank++ )
00229     {
00230         if( irank == rank )
00231         {
00232             /* printf some of the block info */
00233             printf( "on rank %d, there are \n"
00234                     "  %3d visible vertices of which  %3d local  %3d ghost \n"
00235                     "  %3d visible elements of which  %3d owned  %3d ghost \n"
00236                     "  %3d visible blocks\n"
00237                     "  %3d visible neumann BCs\n"
00238                     "  %3d visible dirichlet BCs\n",
00239                     rank, nverts[2], nverts[0], nverts[1], nelem[2], nelem[0], nelem[1], nblocks[2], nsbc[2], ndbc[2] );
00240 
00241             /* print some of the vertex id infos */
00242             printf( "on rank %d vertex info:\n", rank );
00243             for( i = 0; i < nverts[2]; i++ )
00244                 printf( " vertex local id: %3d, rank ID:%d  global ID: %3d  coords: %g, %g, %g\n", i, vranks[i],
00245                         vGlobalID[i], coords[3 * i], coords[3 * i + 1], coords[3 * i + 2] );
00246 
00247             element_global_IDs = (iMOAB_GlobalID*)malloc( nelem[2] * sizeof( iMOAB_GlobalID ) );
00248             block_IDs          = (iMOAB_GlobalID*)malloc( nelem[2] * sizeof( iMOAB_GlobalID ) );
00249             ranks              = (int*)malloc( nelem[2] * sizeof( int ) );
00250             /*
00251              * Visible elements info is available for all visible elements, with this call. Similar
00252              * information can be retrieved by looping over visible blocks
00253              */
00254             rc = iMOAB_GetVisibleElementsInfo( pid, &nelem[2], element_global_IDs, ranks, block_IDs );
00255             CHECKRC( rc, "failed to get all elem info" );
00256             for( i = 0; i < nelem[2]; i++ )
00257                 printf( " element local id: %3d,  global ID: %3d  rank:%d  block ID: %2d \n", i, element_global_IDs[i],
00258                         ranks[i], block_IDs[i] );
00259             free( element_global_IDs );
00260             free( ranks );
00261             free( block_IDs );
00262 
00263             /* Get first element connectivity */
00264             nv     = 27;
00265             eindex = 0;
00266             /*
00267              * Element connectivity can be retrieved for a single element. Local vertex indices are returned.
00268              */
00269             rc = iMOAB_GetElementConnectivity( pid, &eindex, &nv, conn );
00270             CHECKRC( rc, "failed to get first element connectivity" );
00271             printf( " conn for first element: \n" );
00272             for( i = 0; i < nv; i++ )
00273                 printf( " %3d", conn[i] );
00274             printf( "\n" );
00275 
00276             /*
00277              * Test neighbors:
00278              * Neighbor elements that share a face with current element can be determined with this
00279              * call Elements are identified by their local index
00280              */
00281             rc = iMOAB_GetNeighborElements( pid, &local_index, &num_adjacent_elements, adjacent_element_IDs );
00282             CHECKRC( rc, "failed to get first element neighbors" );
00283             printf( "  neighbors for first element:\n" );
00284             for( i = 0; i < num_adjacent_elements; i++ )
00285             {
00286                 printf( "  %4d", adjacent_element_IDs[i] );
00287             }
00288             printf( "\n" );
00289 
00290             for( i = 0; i < nblocks[2]; i++ )
00291             {
00292                 printf( " block index: %3d, block ID: %3d \n", i, gbIDs[i] );
00293                 /*
00294                  * Blocks should have the same type of primary elements. Number of elements in block
00295                  * and number of vertices per element are found with this call. The method refers
00296                  * only to the visible elements on the process. The block is identified with its
00297                  * block ID. Should it be identified with its local index in the list of visible
00298                  * blocks?
00299                  */
00300                 rc = iMOAB_GetBlockInfo( pid, &gbIDs[i], &vertices_per_element, &num_elements_in_block );
00301                 CHECKRC( rc, "failed to elem block info" );
00302                 printf( "    has %4d elements with %d vertices per element\n", num_elements_in_block,
00303                         vertices_per_element );
00304 
00305                 size_conn            = num_elements_in_block * vertices_per_element;
00306                 element_connectivity = (iMOAB_LocalID*)malloc( sizeof( iMOAB_LocalID ) * size_conn );
00307                 /*
00308                  * Connectivity for all elements in the block can be determined with this method.
00309                  * Vertices are identified by their local index (from 0 to number of visible
00310                  * vertices -1)
00311                  */
00312                 rc = iMOAB_GetBlockElementConnectivities( pid, &gbIDs[i], &size_conn, element_connectivity );
00313                 CHECKRC( rc, "failed to get block elem connectivity" );
00314                 element_ownership = (int*)malloc( sizeof( int ) * num_elements_in_block );
00315 
00316                 /*
00317                  * Each element is owned by a particular process. Ownership can be returned for all
00318                  * elements in a block with this call.
00319                  */
00320                 rc = iMOAB_GetElementOwnership( pid, &gbIDs[i], &num_elements_in_block, element_ownership );
00321                 CHECKRC( rc, "failed to get block elem ownership" );
00322                 global_element_ID = (iMOAB_GlobalID*)malloc( sizeof( iMOAB_GlobalID ) * num_elements_in_block );
00323                 local_element_ID  = (iMOAB_LocalID*)malloc( sizeof( iMOAB_LocalID ) * num_elements_in_block );
00324 
00325                 /*
00326                  * Global element IDs are determined with this call. Local indices within the
00327                  * process are returned too.
00328                  */
00329                 rc = iMOAB_GetElementID( pid, &gbIDs[i], &num_elements_in_block, global_element_ID, local_element_ID );
00330                 CHECKRC( rc, "failed to get block elem IDs" );
00331                 for( j = 0; j < num_elements_in_block; j++ )
00332                 {
00333                     printf( "  elem %3d owned by %d gid: %4d lid: %4d  -- ", j, element_ownership[j],
00334                             global_element_ID[j], local_element_ID[j] );
00335                     for( k = 0; k < vertices_per_element; k++ )
00336                         printf( " %5d", element_connectivity[j * vertices_per_element + k] );
00337                     printf( "\n" );
00338                 }
00339                 free( global_element_ID );
00340                 free( local_element_ID );
00341                 free( element_connectivity );
00342                 free( element_ownership );
00343             }
00344             /*
00345              * Query integer tag values on vertices.
00346              * this tag was synchronized (see iMOAB_SynchronizeTags above)
00347              * Being a dense tag, all visible vertices have a value.
00348              * As usual, the client allocates the returned array, which is filled with data with
00349              * this call (deep copy)
00350              */
00351             int_tag_vals = (int*)malloc( sizeof( int ) * nverts[2] ); /* for all visible vertices on the rank */
00352             rc           = iMOAB_GetIntTagStorage( pid, "INTFIELD", &nverts[2], &entTypes[0], int_tag_vals );
00353             CHECKRC( rc, "failed to get INTFIELD tag" );
00354             printf( "INTFIELD tag values:\n" );
00355             for( i = 0; i < nverts[2]; i++ )
00356             {
00357                 printf( " %4d", int_tag_vals[i] );
00358                 if( i % 20 == 19 ) printf( "\n" );
00359             }
00360             printf( "\n" );
00361             free( int_tag_vals );
00362 
00363             /*
00364              * Query double tag values on elements.
00365              * This tag was not synchronized, so ghost elements have a default value of 0.
00366              */
00367             double_tag_vals = (double*)malloc( sizeof( double ) * nelem[2] ); /* for all visible elements on the rank */
00368             rc              = iMOAB_GetDoubleTagStorage( pid, "DFIELD", &nelem[2], &entTypes[1], double_tag_vals );
00369             CHECKRC( rc, "failed to get DFIELD tag" );
00370             printf( "DFIELD tag values: (not exchanged) \n" );
00371             for( i = 0; i < nelem[2]; i++ )
00372             {
00373                 printf( " %f", double_tag_vals[i] );
00374                 if( i % 8 == 7 ) printf( "\n" );
00375             }
00376             printf( "\n" );
00377             free( double_tag_vals );
00378 
00379             /* query surface BCs */
00380             surfBC_ID = (iMOAB_LocalID*)malloc( sizeof( iMOAB_LocalID ) * nsbc[2] );
00381             ref_surf  = (int*)malloc( sizeof( int ) * nsbc[2] );
00382             bc_value  = (int*)malloc( sizeof( int ) * nsbc[2] );
00383             /*
00384              * Surface boundary condition information is returned for all visible Neumann conditions
00385              * the reference surfaces are indexed from 1 to 6 for hexahedrons, 1 to 4 to
00386              * tetrahedrons, in the MOAB canonical ordering convention
00387              */
00388             rc = iMOAB_GetPointerToSurfaceBC( pid, &nsbc[2], surfBC_ID, ref_surf, bc_value );
00389             CHECKRC( rc, "failed to get surf boundary conditions" );
00390             printf( " Surface boundary conditions:\n" );
00391             for( i = 0; i < nsbc[2]; i++ )
00392             {
00393                 printf( "  elem_localID %4d  side:%d  BC:%2d\n", surfBC_ID[i], ref_surf[i], bc_value[i] );
00394             }
00395             free( surfBC_ID );
00396             free( ref_surf );
00397             free( bc_value );
00398 
00399             /* Query vertex BCs */
00400             vertBC_ID    = (iMOAB_LocalID*)malloc( sizeof( iMOAB_LocalID ) * ndbc[2] );
00401             vertBC_value = (int*)malloc( sizeof( int ) * ndbc[2] );
00402             rc           = iMOAB_GetPointerToVertexBC( pid, &ndbc[2], vertBC_ID, vertBC_value );
00403             CHECKRC( rc, "failed to get vertex boundary conditions" );
00404             printf( "  Vertex boundary conditions:\n" );
00405             for( i = 0; i < ndbc[2]; i++ )
00406             {
00407                 printf( "   vertex %4d   BC:%2d\n", vertBC_ID[i], vertBC_value[i] );
00408             }
00409             free( vertBC_ID );
00410             free( vertBC_value );
00411         }
00412 #ifdef MOAB_HAVE_MPI
00413         MPI_Barrier( comm ); /* to avoid printing problems */
00414 #endif
00415     }
00416 
00417     /* free allocated data */
00418     free( coords );
00419     free( vGlobalID );
00420     free( vranks );
00421     outputFile = "fnew.h5m";
00422 #ifdef MOAB_HAVE_MPI
00423     writeOptions = "PARALLEL=WRITE_PART";
00424 #else
00425     writeOptions            = "";
00426 #endif
00427     /*
00428      * The file can be written in parallel, and it will contain additional tags defined by the user
00429      * we may extend the method to write only desired tags to the file
00430      */
00431     rc = iMOAB_WriteMesh( pid, outputFile, writeOptions );
00432     CHECKRC( rc, "failed to write output file" );
00433 
00434     /*
00435      * Deregistering application will delete all mesh entities associated with the application and
00436      * will free allocated tag storage.
00437      */
00438     rc = iMOAB_DeregisterApplication( pid );
00439     CHECKRC( rc, "failed to de-register application" );
00440 
00441     rc = iMOAB_DeregisterApplication( pidDup );
00442     CHECKRC( rc, "failed to de-register application" );
00443 
00444     /*
00445      * This method will delete MOAB instance
00446      */
00447     rc = iMOAB_Finalize();
00448     CHECKRC( rc, "failed to finalize MOAB" );
00449 #ifdef MOAB_HAVE_MPI
00450     MPI_Finalize();
00451 #endif
00452 
00453     return 0;
00454 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines