MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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 }