![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
#include <iostream>
#include <moab/Core.hpp>
#include "moab/MergeMesh.hpp"
#include "moab/ProgOptions.hpp"
Go to the source code of this file.
Functions | |
int | main (int argc, char *argv[]) |
Variables | |
const char | BRIEF_DESC [] = "Merges mesh files or entities in a mesh file. Use available options as desired." |
std::ostringstream | LONG_DESC |
int main | ( | int | argc, |
char * | argv[] | ||
) |
Definition at line 17 of file merge.cpp.
References ProgOptions::addOpt(), BRIEF_DESC, dim, ErrorCode, moab::Core::get_entities_by_dimension(), moab::Core::get_error_string(), moab::Core::get_last_error(), input_file, moab::Core::load_mesh(), LONG_DESC, mb, MB_SUCCESS, moab::ParallelMergeMesh::merge(), moab::MergeMesh::merge_all(), moab::MergeMesh::merge_entities(), moab::MergeMesh::merge_using_integer_tag(), moab::Core::tag_get_handle(), and moab::Core::write_file().
{
#ifdef MOAB_HAVE_MPI
int myID = 0, numprocs = 1;
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &myID );
MPI_Comm_size( MPI_COMM_WORLD, &numprocs );
#endif
bool fsimple = true; // default
bool ffile = false; // parmerge
bool fall = false; // merge all
std::string mtag = ""; // tag based merge
std::string input_file, output_file;
double merge_tol = 1.0e-4;
LONG_DESC << "mbmerge tool has the ability to merge nodes in a mesh. For skin-based merge with "
"multiple"
"files parallel options is also supported."
<< std::endl
<< "If no method is specified, the default is simple merge. Simple merge case gets "
"all the skins available"
<< " in the mesh file and merges the nodes to obtain a conformal mesh. Options to "
"merge all duplicate nodes"
<< " and merging based on a specific tag on the nodes are also supported." << std::endl;
ProgOptions opts( LONG_DESC.str(), BRIEF_DESC );
opts.addOpt< void >( "all,a", "merge all including interior.", &fall );
opts.addOpt< std::string >( "mergetag name,t", "merge based on nodes that have a specific tag name assigned",
&mtag );
opts.addOpt< double >( "mergetolerance,e", "merge tolerance, default is 1e-4", &merge_tol );
opts.addOpt< void >( "simple,s", "simple merge, merge based on skins provided as in the input mesh (Default)",
&fsimple );
opts.addRequiredArg< std::string >( "input_file", "Input file to be merged", &input_file );
opts.addRequiredArg< std::string >( "output_file", "Output mesh file name with extension", &output_file );
#ifdef MOAB_HAVE_MPI
opts.addOpt< void >( "file,f",
"files based merge using skin for individual meshes. Input file is a file containing names"
"of mesh files to be merged (each on a different line). Only works with parallel build",
&ffile );
#endif
opts.parseCommandLine( argc, argv );
moab::Core* mb = new moab::Core();
moab::ErrorCode rval;
if( mtag != "" )
{
rval = mb->load_mesh( input_file.c_str() );
if( rval != moab::MB_SUCCESS )
{
std::cerr << "Error Opening Mesh File " << input_file << std::endl;
return 1;
}
else
{
std::cout << "Read input mesh file: " << input_file << std::endl;
}
int dim = 0;
moab::Range verts;
mb->get_entities_by_dimension( 0, dim, verts );
if( rval != moab::MB_SUCCESS )
{
std::cerr << "failed to get entities by dimension" << std::endl;
return 1;
}
Tag tag_for_merge;
rval = mb->tag_get_handle( mtag.c_str(), tag_for_merge );
if( rval != moab::MB_SUCCESS )
{
std::cerr << "unable to get tag: " << mtag << " specified" << std::endl;
return 1;
}
MergeMesh mm( mb );
rval = mm.merge_using_integer_tag( verts, tag_for_merge );
if( rval != moab::MB_SUCCESS )
{
std::cerr << "error in routine merge using integer tag" << std::endl;
return 1;
}
rval = mb->write_file( output_file.c_str() );
if( rval != moab::MB_SUCCESS )
{
std::cerr << "Error Writing Mesh File " << output_file << std::endl;
return 1;
}
else
{
std::cout << "Wrote output mesh file: " << output_file << std::endl;
}
}
else if( fall == true )
{
rval = mb->load_mesh( input_file.c_str() );
if( rval != moab::MB_SUCCESS )
{
std::cerr << "Error Opening Mesh File " << input_file << std::endl;
return 1;
}
else
{
std::cout << "Read input mesh file: " << input_file << std::endl;
}
MergeMesh mm( mb );
rval = mm.merge_all( 0, merge_tol ); // root set
if( rval != moab::MB_SUCCESS )
{
std::cerr << "error in merge_all routine" << std::endl;
return 1;
}
rval = mb->write_file( output_file.c_str() );
if( rval != moab::MB_SUCCESS )
{
std::cerr << "Error Writing Mesh File " << output_file << std::endl;
return 1;
}
else
{
std::cout << "Wrote output mesh file: " << output_file << std::endl;
}
}
else if( ffile == true )
{
/*
Parmerge
Takes multiple mesh files and merges them into a single output file.
This is a driver for ParallelMergeMesh
Does not currently work if #procs > #meshfiles
is text file containing each mesh file on a line
i.e.
/my/path/file1
/my/path/file2
...
/my/path/fileN
file is a single file where the entire mesh is written to
It must be of type ".h5m"
is the merging tolerance
Typical usage of:
mpirun -n <#procs> parmerge
*/
// Read in files from input files
// Round robin distribution of reading meshes
#ifdef MOAB_HAVE_MPI
std::ifstream file( input_file.c_str() );
if( file.is_open() )
{
std::string line;
int count = 0;
// Read each line
while( file.good() )
{
getline( file, line );
if( myID == count && line != "" )
{
// Read in the file
rval = mb->load_mesh( line.c_str() );
if( rval != moab::MB_SUCCESS )
{
std::cerr << "Error Opening Mesh File " << line << std::endl;
MPI_Abort( MPI_COMM_WORLD, 1 );
file.close();
return 1;
}
else
{
std::cout << "Read input mesh file: " << line << std::endl;
}
}
count = ( count + 1 ) % numprocs;
}
file.close();
}
else
{
std::cerr << "Error Opening Input File " << input_file << std::endl;
MPI_Abort( MPI_COMM_WORLD, 1 );
return 1;
}
// Get a pcomm object
moab::ParallelComm* pc = new moab::ParallelComm( mb, MPI_COMM_WORLD );
// Call the resolve parallel function
moab::ParallelMergeMesh pm( pc, merge_tol );
rval = pm.merge();
if( rval != moab::MB_SUCCESS )
{
std::cerr << "Merge Failed" << std::endl;
MPI_Abort( MPI_COMM_WORLD, 1 );
return 1;
}
// Write out the file
rval = mb->write_file( output_file.c_str(), 0, "PARALLEL=WRITE_PART" );
if( rval != moab::MB_SUCCESS )
{
std::cerr << "Writing output file failed. Code:";
// Temporary File error info.
std::cerr << mb->get_error_string( rval ) << std::endl;
std::string foo = "";
mb->get_last_error( foo );
std::cerr << "File Error: " << foo << std::endl;
return 1;
}
else if( myID == 0 )
{
std::cout << "Wrote output mesh file: " << output_file << std::endl;
}
// The barrier may be necessary to stop items from being deleted when needed
// But probably not necessary
MPI_Barrier( MPI_COMM_WORLD );
delete pc;
#endif
}
else if( fsimple == true )
{
rval = mb->load_mesh( input_file.c_str() );
if( rval != moab::MB_SUCCESS )
{
std::cerr << "Error Opening Mesh File " << input_file << std::endl;
return 1;
}
else
{
std::cout << "Read input mesh file: " << input_file << std::endl;
}
int dim = 3;
moab::Range ents;
mb->get_entities_by_dimension( 0, dim, ents );
if( rval != moab::MB_SUCCESS )
{
std::cerr << "error getting entities by dimension" << std::endl;
return 1;
}
MergeMesh mm( mb );
rval = mm.merge_entities( ents, merge_tol );
if( rval != moab::MB_SUCCESS )
{
std::cerr << "error in merge entities routine" << std::endl;
return 1;
}
rval = mb->write_file( output_file.c_str() );
if( rval != moab::MB_SUCCESS )
{
std::cerr << " Writing Mesh File " << output_file << std::endl;
return 1;
}
else
{
std::cout << "Wrote output mesh file: " << output_file << std::endl;
}
}
else
{
std::cerr << " Unhandled option " << std::endl;
return 1;
}
delete mb;
#ifdef MOAB_HAVE_MPI
MPI_Finalize();
#endif
return 0;
}
const char BRIEF_DESC[] = "Merges mesh files or entities in a mesh file. Use available options as desired." |