MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include <string> 00002 #include <iomanip> 00003 #include <iostream> 00004 #include <cassert> 00005 00006 #include "moab/Core.hpp" 00007 #include "moab/ParallelComm.hpp" 00008 #include "moab/HomXform.hpp" 00009 #include "MBParallelConventions.h" 00010 #include "MBTagConventions.hpp" 00011 00012 using namespace moab; 00013 00014 // Number of cells in each direction: 00015 // const int NC = 2; 00016 00017 const int NI = 2; 00018 const int NJ = 2; 00019 const int NK = 1; 00020 00021 // Number of processes: 00022 // const int NPROCS = 4; 00023 00024 // Domain size: 00025 // const double DSIZE = 10.0; 00026 00027 // MOAB objects: 00028 Interface* mbint = NULL; 00029 ParallelComm* mbpc = NULL; 00030 00031 // Local domain starting and ending hex indexes: 00032 int is, js, ks; 00033 int ie, je, ke; 00034 00035 // Obvious: 00036 int rank; 00037 int size; 00038 00039 void set_local_domain_bounds(); 00040 void create_hexes_and_verts(); 00041 void resolve_and_exchange(); 00042 void error( ErrorCode err ); 00043 00044 int main( int argc, char* argv[] ) 00045 { 00046 MPI_Init( &argc, &argv ); 00047 MPI_Comm_rank( MPI_COMM_WORLD, &rank ); 00048 MPI_Comm_size( MPI_COMM_WORLD, &size ); 00049 if( size != 4 && size != 2 ) 00050 { 00051 std::cerr << "Run this with 2 or 4 processes\n"; 00052 MPI_Finalize(); 00053 exit( 1 ); 00054 } 00055 00056 mbint = new Core(); 00057 mbpc = new ParallelComm( mbint, MPI_COMM_WORLD ); 00058 00059 set_local_domain_bounds(); 00060 create_hexes_and_verts(); 00061 resolve_and_exchange(); 00062 00063 delete mbpc; // ParallelComm instance should be deleted before MOAB instance is deleted 00064 delete mbint; 00065 00066 MPI_Finalize(); 00067 return 0; 00068 } 00069 00070 void set_local_domain_bounds() 00071 { 00072 switch( size ) 00073 { 00074 case 2: 00075 switch( rank ) 00076 { 00077 case 0: 00078 is = 0; 00079 ie = NI / 2; 00080 js = 0; 00081 je = NJ; 00082 ks = 0; 00083 ke = NK; 00084 break; 00085 case 1: 00086 is = NI / 2; 00087 ie = NI; 00088 js = 0; 00089 je = NJ; 00090 ks = 0; 00091 ke = NK; 00092 break; 00093 } 00094 break; 00095 00096 case 4: 00097 switch( rank ) 00098 { 00099 case 0: 00100 is = 0; 00101 ie = NI / 2; 00102 js = 0; 00103 je = NJ / 2; 00104 ks = 0; 00105 ke = NK; 00106 break; 00107 case 1: 00108 is = NI / 2; 00109 ie = NI; 00110 js = 0; 00111 je = NJ / 2; 00112 ks = 0; 00113 ke = NK; 00114 break; 00115 case 2: 00116 is = 0; 00117 ie = NI / 2; 00118 js = NJ / 2; 00119 je = NJ; 00120 ks = 0; 00121 ke = NK; 00122 break; 00123 case 3: 00124 is = NI / 2; 00125 ie = NI; 00126 js = NJ / 2; 00127 je = NJ; 00128 ks = 0; 00129 ke = NK; 00130 break; 00131 } 00132 break; 00133 00134 default: 00135 std::cerr << "Run this with 4 processes\n"; 00136 exit( 1 ); 00137 } 00138 } 00139 00140 void create_hexes_and_verts() 00141 { 00142 Core* mbcore = dynamic_cast< Core* >( mbint ); 00143 HomCoord coord_min( 0, 0, 0 ); 00144 HomCoord coord_max( ie - is, je - js, ke - ks ); 00145 EntitySequence* vertex_seq = NULL; 00146 EntitySequence* cell_seq = NULL; 00147 EntityHandle vs, cs; 00148 00149 error( mbcore->create_scd_sequence( coord_min, coord_max, MBVERTEX, 1, vs, vertex_seq ) ); 00150 error( mbcore->create_scd_sequence( coord_min, coord_max, MBHEX, 1, cs, cell_seq ) ); 00151 00152 HomCoord p1( 0, 0, 0 ); 00153 HomCoord p2( 1, 0, 0 ); 00154 HomCoord p3( 0, 1, 0 ); 00155 00156 error( mbcore->add_vsequence( vertex_seq, cell_seq, p1, p1, p2, p2, p3, p3 ) ); 00157 00158 // Set global id's: 00159 int gid; 00160 Tag global_id_tag = mbint->globalId_tag(); 00161 EntityHandle handle = vs; 00162 int i, j, k; 00163 00164 ErrorCode err; 00165 00166 for( k = ks; k < ke + 1; k++ ) 00167 for( j = js; j < je + 1; j++ ) 00168 for( i = is; i < ie + 1; i++ ) 00169 { 00170 gid = 1 + i + j * ( NI + 1 ) + k * ( NI + 1 ) * ( NJ + 1 ); 00171 err = mbint->tag_set_data( global_id_tag, &handle, 1, &gid ); 00172 if( err != MB_SUCCESS ) 00173 { 00174 exit( 1 ); 00175 } 00176 handle++; 00177 } 00178 00179 handle = cs; 00180 for( k = ks; k < ke; k++ ) 00181 for( j = js; j < je; j++ ) 00182 for( i = is; i < ie; i++ ) 00183 { 00184 gid = 1 + i + j * NI + k * NI * NJ; 00185 error( mbint->tag_set_data( global_id_tag, &handle, 1, &gid ) ); 00186 handle++; 00187 } 00188 } 00189 00190 void resolve_and_exchange() 00191 { 00192 EntityHandle entity_set; 00193 00194 // Create the entity set: 00195 error( mbint->create_meshset( MESHSET_SET, entity_set ) ); 00196 00197 // Get a list of hexes: 00198 Range range; 00199 error( mbint->get_entities_by_type( 0, MBHEX, range ) ); 00200 00201 // Add entities to the entity set: 00202 error( mbint->add_entities( entity_set, range ) ); 00203 00204 // Add the MATERIAL_SET tag to the entity set: 00205 Tag tag; 00206 error( mbint->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, tag ) ); 00207 error( mbint->tag_set_data( tag, &entity_set, 1, &rank ) ); 00208 00209 // Set up partition sets. This is where MOAB is actually told what 00210 // entities each process owns: 00211 error( mbint->get_entities_by_type_and_tag( 0, MBENTITYSET, &tag, NULL, 1, mbpc->partition_sets() ) ); 00212 00213 // Finally, determine which entites are shared and exchange the 00214 // ghosted entities: 00215 error( mbpc->resolve_shared_ents( 0, -1, -1 ) ); 00216 error( mbpc->exchange_ghost_cells( -1, 0, 1, 0, true ) ); 00217 } 00218 00219 void error( ErrorCode err ) 00220 { 00221 if( err != MB_SUCCESS ) 00222 { 00223 std::cerr << "Error: MOAB function failed\n"; 00224 assert( 0 ); 00225 } 00226 }