MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include "moab/Core.hpp" 00002 #include "moab/ParallelComm.hpp" 00003 #include "moab/ScdInterface.hpp" 00004 #include "moab/HomXform.hpp" 00005 #include "moab/ProgOptions.hpp" 00006 #include "MBTagConventions.hpp" 00007 #include "TestUtil.hpp" 00008 #include <string> 00009 #include <iomanip> 00010 #include <iostream> 00011 #include <cassert> 00012 00013 using namespace moab; 00014 00015 // Number of cells in each direction: 00016 int NC; 00017 00018 /* This mesh creates a box that is NCxNCxNC in global dimension, partitioned among processors 00019 * automatically using ScdInterface's SQIJK algorithm. It checks to make sure there are enough 00020 * procs to support this partition method. After mesh creation, shared vertex resolution is done, 00021 * then ghost exchange is done. 00022 */ 00023 const int ITERS = 50; 00024 00025 void create_parallel_mesh(); 00026 00027 int main( int argc, char* argv[] ) 00028 { 00029 MPI_Init( &argc, &argv ); 00030 00031 ProgOptions po; 00032 po.addOpt< int >( "int,i", "Number of intervals on a side" ); 00033 po.parseCommandLine( argc, argv ); 00034 if( !po.getOpt( "int", &NC ) ) NC = 4; 00035 00036 int err = RUN_TEST( create_parallel_mesh ); 00037 00038 MPI_Finalize(); 00039 return err; 00040 } 00041 00042 void create_parallel_mesh() 00043 { 00044 Core mbint; 00045 ParallelComm pc( &mbint, MPI_COMM_WORLD ); 00046 ScdInterface* scdi; 00047 ErrorCode rval = mbint.query_interface( scdi );CHECK_ERR( rval ); 00048 // pc.set_debug_verbosity(2); 00049 00050 // create a structured mesh in parallel 00051 ScdBox* new_box; 00052 ScdParData par_data; 00053 par_data.pComm = &pc; 00054 par_data.gDims[0] = par_data.gDims[1] = par_data.gDims[2] = 0; 00055 par_data.gDims[3] = par_data.gDims[4] = par_data.gDims[5] = NC; 00056 if( ( par_data.gDims[3] - par_data.gDims[0] ) * ( par_data.gDims[3] - par_data.gDims[0] ) * 00057 ( par_data.gDims[3] - par_data.gDims[0] ) < 00058 (int)pc.size() ) 00059 { 00060 std::cerr << "Too few processors for this number of elements." << std::endl;CHECK_ERR( MB_FAILURE ); 00061 } 00062 00063 par_data.partMethod = ScdParData::SQIJK; 00064 00065 // timing data 00066 double times[5]; // tstart, tvert, tnonvert, tghost, titer; 00067 times[0] = MPI_Wtime(); 00068 rval = scdi->construct_box( HomCoord(), HomCoord(), NULL, 0, // no vertex positions 00069 new_box, NULL, // not locally periodic 00070 &par_data, true, 00071 false ); // assign global ids, don't resolve shared verts 00072 CHECK_ERR( rval ); 00073 00074 // get global id tag 00075 Tag tag = mbint.globalId_tag(); 00076 00077 // resolve shared verts 00078 std::cout << "Resolving shared ents..." << std::endl; 00079 rval = pc.resolve_shared_ents( new_box->box_set(), -1, 0, &tag );CHECK_ERR( rval ); 00080 times[1] = MPI_Wtime(); 00081 00082 std::cout << "Exchanging ghost cells..." << std::endl; 00083 rval = pc.exchange_ghost_cells( -1, -1, 0, 0, true, true );CHECK_ERR( rval ); 00084 times[2] = MPI_Wtime(); 00085 00086 // pc.list_entities(0,-1); 00087 00088 rval = pc.exchange_ghost_cells( -1, 0, 1, 0, true ); 00089 if( MB_SUCCESS != rval ) 00090 { 00091 std::string err; 00092 mbint.get_last_error( err ); 00093 std::cerr << "Error: proc " << pc.rank() << ": " << err << std::endl; 00094 } 00095 CHECK_ERR( rval ); 00096 times[3] = MPI_Wtime(); 00097 00098 // pc.list_entities(0,-1); 00099 00100 // Create a tag, used in exchange_tags 00101 int def_val = 1.0; 00102 rval = mbint.tag_get_handle( "test_tag", 1, MB_TYPE_DOUBLE, tag, MB_TAG_DENSE | MB_TAG_EXCL, &def_val );CHECK_ERR( rval ); 00103 00104 Range empty_range; 00105 if( !pc.rank() ) std::cout << "Exchanging tags: "; 00106 for( int i = 0; i < ITERS; i++ ) 00107 { 00108 if( !pc.rank() ) std::cout << i << ";"; 00109 pc.exchange_tags( tag, empty_range );CHECK_ERR( rval ); 00110 } 00111 if( !pc.rank() ) std::cout << std::endl; 00112 times[4] = MPI_Wtime(); 00113 00114 for( int i = 4; i >= 1; i-- ) 00115 times[i] -= times[i - 1]; 00116 00117 double tottimes[5] = { 0.0 }; 00118 MPI_Reduce( times + 1, tottimes + 1, 4, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD ); 00119 00120 if( !pc.rank() ) 00121 std::cout << "Times: " << std::endl 00122 << "Create: " << times[1] << std::endl 00123 << "Resolve verts: " << times[2] << std::endl 00124 << "Resolve non-verts: " << times[3] << std::endl 00125 << "Exchange ghosts: " << times[4] << std::endl; 00126 }