6 #if defined( __MINGW32__ )
31 #define NOT_IMPLEMENTED 2
35 static void print_usage(
const char* name, std::ostream& stream )
37 stream <<
"Usage: " << name <<
" <options> <input_file> [<input_file2> ...]" << std::endl
38 <<
"Options: " << std::endl
39 <<
"\t-h - Print this help text and exit." << std::endl
40 <<
"\t-d - Dimension of the mesh." << std::endl
41 <<
"\t-n - Exact or a maximum number of levels for the hierarchy. Default 1." << std::endl
42 <<
"\t-L - Degree of refinement for each level. Pass an array or a number. It "
43 "is mandatory to pass dimension and num_levels before to use this option. If this flag "
44 "is not used, a default of deg 2 refinement is used. "
46 <<
"\t-V - Pass a desired volume (absolute) . This will generate a hierarchy "
47 "such that the maximum volume is reduced to the given amount approximately. The length "
48 "of the hierarchy can be constrained further if a maximum number of levels is passed. "
49 "It is mandatory to pass the dimension for this option. "
51 <<
"\t-q - Prints out the maximum volume of the mesh and exits the program. "
52 "This option can be used as a guide to volume constrainted mesh hierarchy later. "
54 <<
"\t-t - Print out the time taken to generate hierarchy." << std::endl
55 <<
"\t-s - Print out the mesh sizes of each level of the generated hierarchy." << std::endl
56 <<
"\t-o - Specify true for output files for the mesh levels of the hierarchy." << std::endl
59 <<
"\t-p[0|1|2] - Read in parallel[0], optionally also doing resolve_shared_ents (1) "
60 "and exchange_ghosts (2)"
76 bool parse_id_list(
const char*
string,
int dim,
int nval, std::vector< int >& results );
78 bool make_opts_string( std::vector< std::string > options, std::string& opts );
85 std::vector< int >& level_degs );
89 int main(
int argc,
char* argv[] )
91 int proc_id = 0, size = 1;
93 MPI_Init( &argc, &argv );
94 MPI_Comm_rank( MPI_COMM_WORLD, &proc_id );
95 MPI_Comm_size( MPI_COMM_WORLD, &size );
98 int num_levels = 0, dim = 0;
99 std::vector< int > level_degrees;
100 bool optimize =
false;
102 bool print_times =
false, print_size =
false,
output =
false;
103 bool parallel =
false, resolve_shared =
false, exchange_ghosts =
false;
104 bool printusage =
false, parselevels =
true;
105 bool qc_vol =
false, only_quality =
false;
112 if( !argv[i][0] && 0 == proc_id )
120 if( do_flag && argv[i][0] ==
'-' )
140 dim = atol( argv[i + 1] );
144 num_levels = atol( argv[i + 1] );
148 if( dim != 0 && num_levels != 0 )
150 parselevels =
parse_id_list( argv[i + 1], dim, num_levels, level_degrees );
161 cvol = strtod( argv[i + 1], NULL );
176 resolve_shared =
true;
177 if( argv[i][1] ==
'1' ) exchange_ghosts =
true;
182 switch( argv[i - 1][1] )
186 std::cerr <<
"Invalid option: " << argv[i] << std::endl;
199 if( infile.empty() && !printusage )
print_usage( argv[0], std::cerr );
205 resolve_shared =
true;
219 std::vector< std::string > read_opts, write_opts;
220 std::string read_options, write_options;
222 if( parallel && size > 1 )
224 read_opts.push_back(
"PARALLEL=READ_PART" );
225 read_opts.push_back(
"PARTITION=PARALLEL_PARTITION" );
226 if( resolve_shared ) read_opts.push_back(
"PARALLEL_RESOLVE_SHARED_ENTS" );
227 if( exchange_ghosts ) read_opts.push_back(
"PARALLEL_GHOSTS=3.0.1" );
245 std::cout <<
"READ OPTS=" << (
char*)read_options.c_str() << std::endl;
258 std::vector< EntityHandle > lsets;
269 MPI_Comm_rank( MPI_COMM_WORLD, &rank );
270 if( rank == 0 ) std::cout <<
"Maximum global volume = " << vmax << std::endl;
272 std::cout <<
"Maximum volume = " << vmax << std::endl;
287 if( num_levels == 0 ) num_levels = 1;
289 int* ldeg =
new int[num_levels];
291 if( level_degrees.empty() )
293 for(
int l = 0; l < num_levels; l++ )
298 for(
int l = 0; l < num_levels; l++ )
299 ldeg[l] = level_degrees[l];
302 std::cout <<
"Starting hierarchy generation" << std::endl;
304 std::cout <<
"opt = " << optimize << std::endl;
311 std::cout <<
"Finished hierarchy generation in " << uref->
timeall.
tm_total <<
" secs" << std::endl;
314 std::cout <<
"Time taken for refinement " << uref->
timeall.
tm_refine <<
" secs" << std::endl;
315 std::cout <<
"Time taken for resolving shared interface " << uref->
timeall.
tm_resolve <<
" secs"
320 std::cout <<
"Finished hierarchy generation " << std::endl;
324 Range all_ents, ents[4];
328 for(
int k = 0; k < 4; k++ )
331 std::cout << std::endl;
337 std::cout <<
"Mesh size for level 0"
338 <<
" :: nverts = " << ents[0].
size() <<
", nedges = " << ents[1].
size()
339 <<
", nfaces = " << ents[2].
size() <<
", ncells = " << ents[3].
size() <<
" :: Vmax = " << volume
343 std::cout <<
"Mesh size for level 0"
344 <<
" :: nverts = " << ents[0].
size() <<
", nedges = " << ents[1].
size()
345 <<
", nfaces = " << ents[2].
size() <<
", ncells = " << ents[3].
size() << std::endl;
347 for(
int l = 0; l < num_levels; l++ )
357 for(
int k = 0; k < 4; k++ )
367 std::cout <<
"Mesh size for level " << l + 1 <<
" :: nverts = " << ents[0].
size()
368 <<
", nedges = " << ents[1].
size() <<
", nfaces = " << ents[2].
size()
369 <<
", ncells = " << ents[3].
size() <<
" :: Vmax = " << volume << std::endl;
372 std::cout <<
"Mesh size for level " << l + 1 <<
" :: nverts = " << ents[0].
size()
373 <<
", nedges = " << ents[1].
size() <<
", nfaces = " << ents[2].
size()
374 <<
", ncells = " << ents[3].
size() << std::endl;
380 for(
int l = 0; l < num_levels; l++ )
382 std::string::size_type idx1 = infile.find_last_of(
"\\/" );
383 std::string::size_type idx2 = infile.find_last_of(
"." );
384 std::string file = infile.substr( idx1 + 1, idx2 - idx1 - 1 );
385 std::stringstream out;
387 out <<
"_ML_" << l + 1 <<
".h5m";
389 out <<
"_ML_" << l + 1 <<
".vtk";
390 file = file + out.str();
391 const char* output_file = file.c_str();
393 error =
mb->
write_file( output_file, 0,
";;PARALLEL=WRITE_PART", &lsets[l + 1], 1 );
427 std::vector< int >& level_degs )
434 int init_nl = num_levels;
442 double Vdesired = desired_vol;
444 double remV = vmax_global;
445 int degs[3][3] = { { 5, 3, 2 }, { 25, 9, 4 }, { 0, 27, 8 } };
447 if( dim == 1 || dim == 2 )
449 while( remV - Vdesired >= 0 )
451 try_x = degs[dim - 1][0];
452 if( ( remV / try_x - Vdesired ) >= 0 )
454 level_degs.push_back( 5 );
460 try_x = degs[dim - 1][1];
461 if( ( remV / try_x - Vdesired ) >= 0 )
463 level_degs.push_back( 3 );
469 try_x = degs[dim - 1][2];
470 if( ( remV / try_x - Vdesired ) >= 0 )
472 level_degs.push_back( 2 );
484 while( remV - Vdesired >= 0 )
486 try_x = degs[dim - 1][1];
487 if( ( remV / try_x - Vdesired ) >= 0 )
489 level_degs.push_back( 3 );
495 try_x = degs[dim - 1][2];
496 if( ( remV / try_x - Vdesired ) >= 0 )
498 level_degs.push_back( 2 );
508 if( init_nl != 0 && init_nl < num_levels )
510 for(
int i = level_degs.size(); i >= init_nl; i-- )
511 level_degs.pop_back();
512 num_levels = init_nl;
540 Range allents, owned;
549 MPI_Comm_size( MPI_COMM_WORLD, &size );
555 Range current = owned;
566 double vmax_local = 0;
573 if( volume > vmax_local ) vmax_local = volume;
577 double vmax_global = vmax_local;
579 mpi_err = MPI_Reduce( &vmax_local, &vmax_global, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD );
592 bool parse_id_list(
const char*
string,
int dim,
int nval, std::vector< int >& results )
595 char* mystr = strdup(
string );
596 for(
const char* ptr = strtok( mystr,
"," ); ptr; ptr = strtok( 0,
"," ) )
599 int val = strtol( ptr, &endptr, 0 );
601 if( dim == 1 || dim == 2 )
603 if( val != 2 && val != 3 && val != 5 )
605 std::cerr <<
"Not a valid degree for the passed dimension" << std::endl;
612 if( val != 2 && val != 3 )
614 std::cerr <<
"Not a valid degree for the passed dimension" << std::endl;
620 if( endptr == ptr || val <= 0 )
622 std::cerr <<
"Not a valid id: " << ptr << std::endl;
627 results.push_back( val );
630 if( (
int)results.size() < nval )
632 for(
int i = results.size(); i <= nval - 1; i++ )
633 results.push_back( results[0] );
635 else if( (
int)results.size() > nval )
637 for(
int i = results.size(); i > nval; i-- )
648 if( options.empty() )
return true;
651 std::vector< std::string >::const_iterator i;
652 char separator =
'\0';
653 const char* alt_separators =
";+,:\t\n";
654 for(
const char* sep_ptr = alt_separators; *sep_ptr; ++sep_ptr )
657 for( i = options.begin(); i != options.end(); ++i )
658 if( i->find( *sep_ptr, 0 ) != std::string::npos )
665 separator = *sep_ptr;
671 std::cerr <<
"Error: cannot find separator character for options string" << std::endl;
674 if( separator !=
';' )
683 for( ++i; i != options.end(); ++i )