moab
|
00001 #include "moab/Core.hpp" 00002 #include "EdgeSizeSimpleImplicit.hpp" 00003 #include "SimplexTemplateRefiner.hpp" 00004 #include "MeshRefiner.hpp" 00005 #include "moab/Interface.hpp" 00006 #include "MBParallelConventions.h" 00007 00008 #ifdef USE_MPI 00009 #include "moab/ParallelComm.hpp" 00010 #include "moab_mpi.h" 00011 #endif // USE_MPI 00012 00013 #include <iostream> 00014 #include <sstream> 00015 #include <map> 00016 00017 #include "sys/time.h" 00018 00019 using namespace moab; 00020 00021 #define STRINGIFY_(A) #A 00022 #define STRINGIFY(A) STRINGIFY_(A) 00023 #ifdef MESHDIR 00024 std::string TestDir( STRINGIFY(MESHDIR) ); 00025 #else 00026 std::string TestDir( "./" ); 00027 #endif 00028 00029 int TestMeshRefiner( int argc, char* argv[] ) 00030 { 00031 int nprocs, rank; 00032 #ifdef USE_MPI 00033 MPI_Init( &argc, &argv ); 00034 MPI_Comm_size(MPI_COMM_WORLD, &nprocs); 00035 MPI_Comm_rank(MPI_COMM_WORLD, &rank); 00036 #else // USE_MPI 00037 nprocs = 1; 00038 rank = 0; 00039 #endif // USE_MPI 00040 //sleep(20); 00041 00042 // Create the input mesh and, if -new-mesh is specified, an output mesh 00043 std::string ifname = argc > 1 ? argv[1] : TestDir + "fourVolsBare.cub"; 00044 bool input_is_output, do_output = false; 00045 std::string output_filename; 00046 if ( argc > 2) { 00047 if (!strcmp( argv[2], "-new-mesh" )) input_is_output = true; 00048 else { 00049 do_output = true; 00050 output_filename = std::string(argv[2]); 00051 } 00052 } 00053 00054 Interface* imesh = new Core; // ( rank, nprocs ); 00055 Interface* omesh = input_is_output ? imesh : new Core; // ( rank, nprocs ); 00056 00057 #ifdef USE_MPI 00058 // Use an ParallelComm object to help set up the input mesh 00059 ParallelComm* ipcomm = new ParallelComm( imesh, MPI_COMM_WORLD ); 00060 //ReadParallel* readpar = new ReadParallel( imesh, ipcomm ); 00061 #endif // USE_MPI 00062 00063 EntityHandle set_handle; 00064 std::ostringstream parallel_options; 00065 #ifdef USE_MPI 00066 parallel_options 00067 << "PARALLEL=READ_DELETE" << ";" // NB: You can use BCAST_DELETE or READ_DELETE here. 00068 //<< "PARALLEL=BCAST_DELETE" << ";" // NB: You can use BCAST_DELETE or READ_DELETE here. 00069 << "PARTITION=MATERIAL_SET" << ";" 00070 << "PARTITION_DISTRIBUTE" << ";" 00071 << "PARALLEL_RESOLVE_SHARED_ENTS" << ";" 00072 << "CPUTIME"; 00073 #endif 00074 ErrorCode rval = imesh->create_meshset(MESHSET_SET, set_handle); 00075 if (MB_SUCCESS != rval) { 00076 std::cout << "Trouble creating set, exiting." << std::endl; 00077 return 1; 00078 } 00079 00080 rval = imesh->load_file( ifname.c_str(), &set_handle, parallel_options.str().c_str() ); 00081 if (MB_SUCCESS != rval) { 00082 std::cout << "Trouble reading mesh file " << ifname << ", exiting." << std::endl; 00083 return 1; 00084 } 00085 00086 // Print out what we have so far, one process at a time 00087 for ( int i = 0; i < nprocs; ++ i ) 00088 { 00089 MPI_Barrier( MPI_COMM_WORLD ); 00090 if ( i == rank ) 00091 { 00092 std::cout << "\n************** Rank: " << ( rank ) << " of: " << nprocs << "\n"; 00093 imesh->list_entities( 0, 0 ); 00094 std::cout << "**************\n\n"; 00095 } 00096 MPI_Barrier( MPI_COMM_WORLD ); 00097 } 00098 00099 // The refiner will need an implicit function to be used as an indicator function for subdivision: 00100 EdgeSizeSimpleImplicit* eval = new EdgeSizeSimpleImplicit(); 00101 eval->set_ratio( 2. ); 00102 // Refine the mesh 00103 MeshRefiner* mref = new MeshRefiner( imesh, omesh ); 00104 SimplexTemplateRefiner* eref = new SimplexTemplateRefiner; 00105 mref->set_entity_refiner( eref ); 00106 //mref->add_vertex_tag( tag_floatular ); 00107 //mref->add_vertex_tag( tag_intular ); 00108 // (We don't add tag_gid to the refiner's tag manager because it is special) 00109 eref->set_edge_size_evaluator( eval ); 00110 Range ents_to_refine; 00111 imesh->get_entities_by_type( set_handle, MBTET, ents_to_refine ); // refine just the tets 00112 //ents_to_refine.insert( set_handle ); // refine everything multiple times (because subsets are not disjoint) 00113 struct timeval tic, toc; 00114 gettimeofday( &tic, 0 ); 00115 mref->refine( ents_to_refine ); 00116 gettimeofday( &toc, 0 ); 00117 std::cout << "\nTime: " << ( (toc.tv_sec - tic.tv_sec) * 1000 + (toc.tv_usec - tic.tv_usec) / 1000. ) << " ms\n\n"; 00118 00119 if (do_output) { 00120 parallel_options.clear(); 00121 parallel_options << "PARALLEL=WRITE_PART"; 00122 omesh->write_file( output_filename.c_str(), NULL, parallel_options.str().c_str() ); 00123 } 00124 00125 // Print out the results, one process at a time 00126 #ifdef USE_MPI 00127 for ( int i = 0; i < nprocs; ++ i ) 00128 { 00129 MPI_Barrier( MPI_COMM_WORLD ); 00130 if ( i == rank ) 00131 { 00132 std::cout << "\n************** Rank: " << ( rank ) << " of: " << nprocs << "\n"; 00133 omesh->list_entities( 0, 0 ); 00134 std::cout << "**************\n\n"; 00135 } 00136 MPI_Barrier( MPI_COMM_WORLD ); 00137 } 00138 #else // USE_MPI 00139 omesh->list_entities( 0, 1 ); 00140 #endif // USE_MPI 00141 00142 // Clean up 00143 #ifdef USE_MPI 00144 //delete readpar; 00145 delete ipcomm; 00146 #endif // USE_MPI 00147 if ( omesh != imesh ) 00148 delete omesh; 00149 delete imesh; 00150 delete mref; // mref will delete eref 00151 00152 #ifdef USE_MPI 00153 MPI_Barrier( MPI_COMM_WORLD ); 00154 MPI_Finalize(); 00155 #endif // USE_MPI 00156 00157 return 0; 00158 } 00159 00160 int main( int argc, char* argv[] ) 00161 { 00162 return TestMeshRefiner( argc, argv ); 00163 }