MOAB: Mesh Oriented datABase  (version 5.4.1)
hireconst_test_parallel.cpp
Go to the documentation of this file.
00001 /*This unit test is for high order reconstruction capability, which could be used for mesh
00002  * refinement*/
00003 #include <iostream>
00004 #include <string>
00005 #include <sstream>
00006 #if defined( __MINGW32__ )
00007 #include <sys/time.h>
00008 #else
00009 #include <ctime>
00010 #endif
00011 
00012 #include <vector>
00013 #include <algorithm>
00014 #include "moab/Core.hpp"
00015 #include "moab/Range.hpp"
00016 #include "moab/CartVect.hpp"
00017 #include "moab/MeshTopoUtil.hpp"
00018 #include "moab/NestedRefine.hpp"
00019 #include "moab/DiscreteGeometry/HiReconstruction.hpp"
00020 #include "TestUtil.hpp"
00021 #include <cmath>
00022 
00023 #ifdef MOAB_HAVE_MPI
00024 #include "moab/ParallelComm.hpp"
00025 #include "MBParallelConventions.h"
00026 #include "ReadParallel.hpp"
00027 #include "moab/FileOptions.hpp"
00028 #include "MBTagConventions.hpp"
00029 #include "moab_mpi.h"
00030 #endif
00031 
00032 using namespace moab;
00033 
00034 #ifdef MOAB_HAVE_MPI
00035 std::string read_options;
00036 #endif
00037 
00038 #ifdef MOAB_HAVE_HDF5
00039 #undef MOAB_HAVE_HDF5
00040 #endif
00041 ErrorCode load_meshset_hirec( const char* infile,
00042                               Interface* mbimpl,
00043                               EntityHandle& meshset,
00044                               ParallelComm*& pc,
00045                               const int degree = 0,
00046                               const int dim    = 2 );
00047 ErrorCode test_mesh( const char* infile, const int degree, const bool interp, const int dim );
00048 
00049 void compute_linear_coords( const int nvpe, double* elemcoords, double* naturals, double* linearcoords );
00050 
00051 void usage()
00052 {
00053     std::cout << "usage: mpirun -np <number of processors> ./hireconst_test_parallel <mesh file> "
00054                  "-degree <degree> -interp <0=least square, 1=interpolation> -dim <mesh dimension>"
00055               << std::endl;
00056 }
00057 
00058 int main( int argc, char* argv[] )
00059 {
00060 #ifdef MOAB_HAVE_MPI
00061     MPI_Init( &argc, &argv );
00062     int nprocs, rank;
00063     MPI_Comm_size( MPI_COMM_WORLD, &nprocs );
00064     MPI_Comm_rank( MPI_COMM_WORLD, &rank );
00065 #endif
00066     int degree = 3, dim = 2;
00067     bool interp = false;
00068     ErrorCode error;
00069 
00070 #ifdef MOAB_HAVE_HDF5
00071     std::string infile = TestDir + "unittest/mbcslam/fine4.h5m";
00072 #else
00073     std::string infile = TestDir + "unittest/sphere_quads_20.vtk";
00074 #endif
00075 
00076     if( argc == 1 )
00077     {
00078         usage();
00079         std::cout << "Using default arguments: ./hireconst_test_parallel " << infile << " -degree 3 -interp 0 -dim 2"
00080                   << std::endl;
00081     }
00082     else
00083     {
00084         infile      = argv[1];
00085         bool hasdim = false;
00086 
00087         for( int i = 2; i < argc; ++i )
00088         {
00089             if( i + 1 != argc )
00090             {
00091                 if( std::string( argv[i] ) == "-degree" )
00092                 {
00093                     degree = atoi( argv[++i] );
00094                 }
00095                 else if( std::string( argv[i] ) == "-interp" )
00096                 {
00097                     interp = atoi( argv[++i] );
00098                 }
00099                 else if( std::string( argv[i] ) == "-dim" )
00100                 {
00101                     dim    = atoi( argv[++i] );
00102                     hasdim = true;
00103                 }
00104                 else
00105                 {
00106 #ifdef MOAB_HAVE_MPI
00107 
00108                     if( 0 == rank )
00109                     {
00110                         usage();
00111                     }
00112 
00113                     MPI_Finalize();
00114 #else
00115                     usage();
00116 #endif
00117                     return 0;
00118                 }
00119             }
00120         }
00121 
00122         if( !hasdim )
00123         {
00124 #ifdef MOAB_HAVE_MPI
00125 
00126             if( 0 == rank )
00127             {
00128                 std::cout << "Dimension of input mesh should be provided, positive and less than 3" << std::endl;
00129             }
00130 
00131 #else
00132             std::cout << "Dimension of input mesh should be provided, positive and less than 3" << std::endl;
00133 #endif
00134             return 0;
00135         }
00136 
00137         if( degree <= 0 || dim > 2 || dim <= 0 )
00138         {
00139 #ifdef MOAB_HAVE_MPI
00140 
00141             if( 0 == rank )
00142             {
00143                 std::cout << "Input degree should be positive number;\n";
00144                 std::cout << "Input dimesion should be positive and less than 3;" << std::endl;
00145             }
00146 
00147 #else
00148             std::cout << "Input degree should be positive number;\n";
00149             std::cout << "Input dimesion should be positive and less than 3;" << std::endl;
00150 #endif
00151             return 0;
00152         }
00153 
00154 #ifdef MOAB_HAVE_MPI
00155 
00156         if( 0 == rank )
00157         {
00158             std::cout << "Testing on " << infile << " with dimension " << dim << "\n";
00159             std::string opts = interp ? "interpolation" : "least square fitting";
00160             std::cout << "High order reconstruction with degree " << degree << " " << opts << std::endl;
00161         }
00162 
00163 #else
00164         std::cout << "Testing on " << infile << " with dimension " << dim << "\n";
00165         std::string opts = interp ? "interpolation" : "least square fitting";
00166         std::cout << "High order reconstruction with degree " << degree << " " << opts << std::endl;
00167 #endif
00168     }
00169 
00170     error = test_mesh( infile.c_str(), degree, interp, dim );MB_CHK_ERR( error );
00171 
00172 #ifdef MOAB_HAVE_MPI
00173     MPI_Finalize();
00174 #endif
00175 }
00176 
00177 ErrorCode load_meshset_hirec( const char* infile,
00178                               Interface* mbimpl,
00179                               EntityHandle& meshset,
00180                               ParallelComm*& pc,
00181                               const int degree,
00182                               const int dim )
00183 {
00184     ErrorCode error;
00185     error = mbimpl->create_meshset( moab::MESHSET_SET, meshset );MB_CHK_ERR( error );
00186 #ifdef MOAB_HAVE_MPI
00187     int nprocs, rank;
00188     MPI_Comm comm = MPI_COMM_WORLD;
00189     MPI_Comm_size( comm, &nprocs );
00190     MPI_Comm_rank( comm, &rank );
00191     EntityHandle partnset;
00192     error = mbimpl->create_meshset( moab::MESHSET_SET, partnset );MB_CHK_ERR( error );
00193 
00194     if( nprocs > 1 )
00195     {
00196         pc = moab::ParallelComm::get_pcomm( mbimpl, partnset, &comm );
00197     }
00198 
00199     if( nprocs > 1 )
00200     {
00201         int nghlayers           = degree > 0 ? HiReconstruction::estimate_num_ghost_layers( degree, true ) : 0;
00202         std::string part_method = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;";
00203 #ifndef MOAB_HAVE_HDF5
00204         part_method = "PARALLEL=BCAST_DELETE;PARTITION=TRIVIAL;";
00205 #endif
00206 
00207         if( nghlayers )
00208         {
00209             // get ghost layers
00210             if( dim == 2 )
00211             {
00212                 read_options = part_method + ";PARALLEL_RESOLVE_SHARED_ENTS;PARALLEL_GHOSTS=2.0.";
00213             }
00214             else if( dim == 1 )
00215             {
00216                 read_options = part_method + ";PARALLEL_RESOLVE_SHARED_ENTS;PARALLEL_GHOSTS=1.0.";
00217             }
00218             else
00219             {
00220                 MB_SET_ERR( MB_FAILURE, "unsupported dimension" );
00221             }
00222 
00223             read_options += (char)( '0' + nghlayers );
00224         }
00225         else
00226         {
00227             read_options = part_method + ";PARALLEL_RESOLVE_SHARED_ENTS;";
00228         }
00229 
00230         error = mbimpl->load_file( infile, &meshset, read_options.c_str() );MB_CHK_ERR( error );
00231     }
00232     else
00233     {
00234         error = mbimpl->load_file( infile, &meshset );MB_CHK_ERR( error );
00235     }
00236 
00237 #else
00238     assert( !pc && degree && dim );
00239     error = mbimpl->load_file( infile, &meshset );MB_CHK_ERR( error );
00240 #endif
00241     return error;
00242 }
00243 
00244 ErrorCode test_mesh( const char* infile, const int degree, const bool interp, const int dim )
00245 {
00246     Core moab;
00247     Interface* mbimpl = &moab;
00248     ParallelComm* pc  = NULL;
00249     EntityHandle meshset;
00250 #ifdef MOAB_HAVE_MPI
00251     int nprocs, rank;
00252     MPI_Comm comm = MPI_COMM_WORLD;
00253     MPI_Comm_size( comm, &nprocs );
00254     MPI_Comm_rank( comm, &rank );
00255 #endif
00256 
00257     ErrorCode error;
00258     // mesh will be loaded and communicator pc will be updated
00259     error = load_meshset_hirec( infile, mbimpl, meshset, pc, degree, dim );MB_CHK_ERR( error );
00260     // initialize
00261     HiReconstruction hirec( dynamic_cast< Core* >( mbimpl ), pc, meshset );
00262     Range elems, elems_owned;
00263     error = mbimpl->get_entities_by_dimension( meshset, dim, elems );MB_CHK_ERR( error );
00264     int nelems = elems.size();
00265 
00266 #ifdef MOAB_HAVE_MPI
00267 
00268     if( pc )
00269     {
00270         error = pc->filter_pstatus( elems, PSTATUS_GHOST, PSTATUS_NOT, -1, &elems_owned );MB_CHK_ERR( error );
00271     }
00272     else
00273     {
00274         elems_owned = elems;
00275     }
00276 
00277 #endif
00278 
00279 #ifdef MOAB_HAVE_MPI
00280     std::cout << "Mesh has " << nelems << " elements on Processor " << rank << " in total;";
00281     std::cout << elems_owned.size() << " of which are locally owned elements" << std::endl;
00282 #else
00283     std::cout << "Mesh has " << nelems << " elements" << std::endl;
00284 #endif
00285 
00286     // reconstruction
00287     if( dim == 2 )
00288     {
00289         error = hirec.reconstruct3D_surf_geom( degree, interp, false );MB_CHK_ERR( error );
00290     }
00291     else if( dim == 1 )
00292     {
00293         error = hirec.reconstruct3D_curve_geom( degree, interp, false );MB_CHK_ERR( error );
00294     }
00295 
00296 #ifdef MOAB_HAVE_MPI
00297     std::cout << "HiRec has been done on Processor " << rank << std::endl;
00298 #else
00299     std::cout << "HiRec has been done " << std::endl;
00300 #endif
00301     // fitting
00302     double mxdist = 0;
00303 
00304     for( Range::iterator ielem = elems_owned.begin(); ielem != elems_owned.end(); ++ielem )
00305     {
00306         int nvpe;
00307         const EntityHandle* conn;
00308         error = mbimpl->get_connectivity( *ielem, conn, nvpe );MB_CHK_ERR( error );
00309         double w = 1.0 / (double)nvpe;
00310         std::vector< double > naturalcoords2fit( nvpe, w );
00311         CartVect newcoords, linearcoords;
00312         error = hirec.hiproj_walf_in_element( *ielem, nvpe, 1, &( naturalcoords2fit[0] ), newcoords.array() );
00313 
00314         if( MB_FAILURE == error )
00315         {
00316             continue;
00317         }
00318 
00319         std::vector< double > coords( 3 * nvpe );
00320         error = mbimpl->get_coords( conn, nvpe, &( coords[0] ) );MB_CHK_ERR( error );
00321         compute_linear_coords( nvpe, &( coords[0] ), &( naturalcoords2fit[0] ), linearcoords.array() );
00322         CartVect nlcoords = newcoords - linearcoords;
00323         mxdist            = std::max( mxdist, nlcoords.length() );
00324         /*#ifdef MOAB_HAVE_MPI
00325             std::cout << "Error on element " << *ielem << " is " << nlcoords.length() << "on
00326         Processor " << rank << std::endl; #else std::cout << "Error on element " << *ielem << " is "
00327         << nlcoords.length() << std::endl; #endif*/
00328     }
00329 
00330 #ifdef MOAB_HAVE_MPI
00331     std::cout << "Maximum projection lift is " << mxdist << " on Processor " << rank << std::endl;
00332 #else
00333     std::cout << "Maximum projection lift is " << mxdist << std::endl;
00334 #endif
00335     return error;
00336 }
00337 
00338 void compute_linear_coords( const int nvpe, double* elemcoords, double* naturals, double* linearcoords )
00339 {
00340     assert( elemcoords && linearcoords );
00341 
00342     for( int i = 0; i < 3; ++i )
00343     {
00344         linearcoords[i] = 0;
00345 
00346         for( int j = 0; j < nvpe; ++j )
00347         {
00348             linearcoords[i] += naturals[j] * elemcoords[3 * j + i];
00349         }
00350     }
00351 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines