moab
test_mesh_refiner.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines