MOAB: Mesh Oriented datABase  (version 5.3.1)
structured3.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines