[MOAB-dev] r4864 - in MOAB/trunk: src src/moab test/parallel tools
tautges at mcs.anl.gov
tautges at mcs.anl.gov
Tue May 24 11:54:33 CDT 2011
Author: tautges
Date: 2011-05-24 11:54:31 -0500 (Tue, 24 May 2011)
New Revision: 4864
Modified:
MOAB/trunk/src/MergeMesh.cpp
MOAB/trunk/src/moab/MergeMesh.hpp
MOAB/trunk/test/parallel/parmerge.cpp
MOAB/trunk/tools/skin.cpp
Log:
Changes to merge higher-dimensional entities serially before doing parallel merge.
Also added a -l option to mbskin to list number of vertices and entities on skin.
Passes make check in serial and parallel.
Index: test/parallel/parmerge.cpp
===================================================================
--- test/parallel/parmerge.cpp (revision 4862)
+++ test/parallel/parmerge.cpp (working copy)
@@ -1,6 +1,6 @@
/* Parallel Merge Mesh Test
Nathan Bertram
- 1/31/11
+ 5/31/11
*/
#include "moab/ParallelMergeMesh.hpp"
@@ -16,37 +16,69 @@
#include <fstream>
#include <sstream>
+/*
+ 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
+
+ <inputfile> is text file containing each mesh file on a line
+ i.e.
+
+ /my/path/file1
+ /my/path/file2
+ ...
+ /my/path/fileN
+
+ <outputfile> file is a single file where the entire mesh is written to
+ It must be of type ".h5m"
+
+ <tolerance> is the merging tolerance
+
+ Typical usage of:
+ mpd &
+ mpirun -n <#procs> parmerge <inputfile> <outputfile> <tolerance>
+*/
int main(int argc, char * argv[])
{
+ //Check argument count
if(argc != 4){
std::cerr<<"Usage: "<<argv[0]<<" <inputfile> <outputfile> <tolerance>"<<std::endl;
return 1;
}
+ //Check the output file extension
+ std::string outfile(argv[2]);
+ if(outfile.compare(outfile.size()-4,4,".h5m")!=0){
+ std::cerr<<"Invalid Parallel Output File"<<std::endl;
+ return 1;
+ }
+ //Read in tolerance
+ double epsilon;
+ if(!(std::istringstream(argv[3])>>epsilon)){
+ std::cerr<<"Unable to parse tolerance"<<std::endl;
+ return 1;
+ }
+
//Initialize MPI
int numprocs, myID;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myID);
- //Read in tolerance
- double epsilon;
- if(!(std::istringstream(argv[3])>>epsilon)){
- std::cerr<<"Unable to parse epsilon. Exiting"<<std::endl;
- MPI_Abort(MPI_COMM_WORLD,1);
- return 1;
- }
-
//Read in files from input files
+ //Round robin distribution of reading meshes
moab::Core *mb = new moab::Core();
moab::ErrorCode rval;
std::ifstream file(argv[1]);
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;
@@ -78,12 +110,9 @@
}
//Write out the file
- std::stringstream np;
- np << numprocs;
- std::string outfile(argv[2]);
rval = mb->write_file(outfile.c_str() , 0,"PARALLEL=WRITE_PART");
if(rval != moab::MB_SUCCESS){
- std::cerr<<"Writing output file failed Code:";
+ 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);
Index: src/MergeMesh.cpp
===================================================================
--- src/MergeMesh.cpp (revision 4862)
+++ src/MergeMesh.cpp (working copy)
@@ -5,27 +5,30 @@
#include "moab/Range.hpp"
#include "moab/CartVect.hpp"
+#include <vector>
#include <algorithm>
#include <string>
#include <vector>
#include <cassert>
#include <iostream>
+#include <iomanip>
namespace moab {
moab::ErrorCode MergeMesh::merge_entities(moab::EntityHandle *elems,
- int elems_size,
- const double merge_tol,
- const int do_merge,
- const int update_sets,
- moab::Tag merge_tag)
+ int elems_size,
+ const double merge_tol,
+ const int do_merge,
+ const int update_sets,
+ moab::Tag merge_tag,
+ bool do_higher_dim)
{
mergeTol = merge_tol;
mergeTolSq = merge_tol*merge_tol;
moab::Range tmp_elems;
tmp_elems.insert( elems, elems + elems_size);
moab::ErrorCode result = merge_entities(tmp_elems, merge_tol, do_merge, update_sets,
- (moab::Tag)merge_tag);
+ (moab::Tag)merge_tag, do_higher_dim);
return result;
}
@@ -43,9 +46,15 @@
moab::ErrorCode MergeMesh::merge_entities(moab::Range &elems,
const double merge_tol,
const int do_merge,
- const int /*update_sets*/,
- moab::Tag merge_tag)
+ const int update_sets,
+ moab::Tag merge_tag,
+ bool merge_higher_dim)
{
+ //If merge_higher_dim is true, do_merge must also be true
+ if(merge_higher_dim && !do_merge){
+ return moab::MB_FAILURE;
+ }
+
mergeTol = merge_tol;
mergeTolSq = merge_tol*merge_tol;
@@ -73,27 +82,32 @@
// find matching vertices, mark them
result = find_merged_to(tree_root, mbMergeTag);
if (moab::MB_SUCCESS != result) return result;
-
+
// merge them if requested
if (do_merge) {
result = perform_merge(mbMergeTag);
if (moab::MB_SUCCESS != result) return result;
}
+
+ if(merge_higher_dim && deadEnts.size() != 0){
+ result = merge_higher_dimensions(elems);
+ if(moab::MB_SUCCESS != result) return result;
+ }
return moab::MB_SUCCESS;
}
moab::ErrorCode MergeMesh::perform_merge(moab::Tag merge_tag)
{
+ moab::ErrorCode result;
if (deadEnts.size()==0){
- std::cout << "\nWarning: Geometries don't have a common face; Nothing to merge" << std::endl;
+ if(printError)std::cout << "\nWarning: Geometries don't have a common face; Nothing to merge" << std::endl;
return moab::MB_SUCCESS; //nothing to merge carry on with the program
}
- if (mbImpl->type_from_handle(*deadEnts.rbegin()) != moab::MBVERTEX)
+ if (mbImpl->type_from_handle(*deadEnts.rbegin()) != moab::MBVERTEX)
return moab::MB_FAILURE;
-
std::vector<moab::EntityHandle> merge_tag_val(deadEnts.size());
- moab::ErrorCode result = mbImpl->tag_get_data(merge_tag, deadEnts, &merge_tag_val[0]);
+ result = mbImpl->tag_get_data(merge_tag, deadEnts, &merge_tag_val[0]);
if (moab::MB_SUCCESS != result) return result;
moab::Range::iterator rit;
@@ -101,10 +115,12 @@
for (rit = deadEnts.begin(), i = 0; rit != deadEnts.end(); rit++, i++) {
assert(merge_tag_val[i]);
result = mbImpl->merge_entities(merge_tag_val[i], *rit, false, false);
- if (moab::MB_SUCCESS != result) return result;
+ if (moab::MB_SUCCESS != result) {
+ return result;
+ }
}
-
- return mbImpl->delete_entities(deadEnts);
+ result = mbImpl->delete_entities(deadEnts);
+ return moab::MB_SUCCESS;
}
moab::ErrorCode MergeMesh::find_merged_to(moab::EntityHandle &tree_root,
@@ -186,7 +202,6 @@
inleaf_merged = true;}
else{
outleaf_merged = true;}
-
deadEnts.insert(to_ent);
}
@@ -206,4 +221,44 @@
return moab::MB_SUCCESS;
}
+
+//Determine which higher dimensional entities should be merged
+moab::ErrorCode MergeMesh::merge_higher_dimensions(moab::Range &elems)
+{
+ Range skinEnts, adj, matches, moreDeadEnts; moab::ErrorCode result;
+ moab::Skinner skinner(mbImpl);
+ //Go through each dimension
+ for(int dim = 1; dim <3; dim++){
+ skinEnts.clear();
+ moreDeadEnts.clear();
+ result = skinner.find_skin(elems, dim, skinEnts);
+ //Go through each skin entity and see if it shares adjacancies with another entity
+ for(moab::Range::iterator skinIt = skinEnts.begin(); skinIt != skinEnts.end(); skinIt++){
+ adj.clear();
+ //Get the adjacencies 1 dimension lower
+ result = mbImpl->get_adjacencies(&(*skinIt), 1, dim-1, true, adj);
+ if(result != moab::MB_SUCCESS) return result;
+ //See what other entities share these adjacencies
+ matches.clear();
+ result = mbImpl->get_adjacencies(adj, dim, true, matches, moab::Interface::INTERSECT);
+ if(result != moab::MB_SUCCESS) return result;
+ //If there is more than one entity, then we have some to merge and erase
+ if(matches.size() > 1){
+ for(moab::Range::iterator matchIt = matches.begin(); matchIt != matches.end(); matchIt++){
+ if(*matchIt != *skinIt){
+ moreDeadEnts.insert(*matchIt);
+ result = mbImpl->merge_entities(*skinIt, *matchIt, false, false);
+ if(result != moab::MB_SUCCESS) return result;
+ skinEnts.erase(*matchIt);
+ }
+ }
+ }
+ }
+ //Delete the entities
+ result = mbImpl->delete_entities(moreDeadEnts);
+ if(result != moab::MB_SUCCESS)return result;
+ }
+ return moab::MB_SUCCESS;
}
+
+}//End namespace moab
Index: src/moab/MergeMesh.hpp
===================================================================
--- src/moab/MergeMesh.hpp (revision 4862)
+++ src/moab/MergeMesh.hpp (working copy)
@@ -11,7 +11,7 @@
public:
/* \brief Constructor
*/
- MergeMesh(moab::Interface *mbImpl);
+ MergeMesh(moab::Interface *mbImpl, bool printErrorIn = true);
/* \brief Destructor
*/
@@ -24,14 +24,18 @@
const double merge_tol,
const int do_merge = true,
const int update_sets = false,
- moab::Tag merge_tag = 0);
+ moab::Tag merge_tag = 0,
+ bool do_higher_dim = true);
moab::ErrorCode merge_entities(moab::Range &elems,
const double merge_tol,
const int do_merge = true,
const int update_sets = false,
- moab::Tag merge_tag = 0);
+ moab::Tag merge_tag = 0,
+ bool do_higher_dim = true);
+ //Identify higher dimension to be merged
+ moab::ErrorCode merge_higher_dimensions(moab::Range &elems);
//- perform the actual merge
moab::ErrorCode perform_merge(moab::Tag merged_to);
@@ -54,11 +58,13 @@
//- entities which will go away after the merge
moab::Range deadEnts;
-
+
+ //Allow a warning to be suppressed when no merging is done
+ bool printError;
};
-inline MergeMesh::MergeMesh(Interface *impl)
- : mbImpl(impl)
+ inline MergeMesh::MergeMesh(Interface *impl, bool printErrorIn)
+ : mbImpl(impl), printError(printErrorIn)
{
}
Index: tools/skin.cpp
===================================================================
--- tools/skin.cpp (revision 4862)
+++ tools/skin.cpp (working copy)
@@ -67,7 +67,7 @@
str << "-m : consolidate duplicate vertices" << std::endl;
str << "-M <n> : consolidate duplicate vertices with specified tolerance. "
"(Default: min_edge_length/" << MIN_EDGE_LEN_DENOM << ")" << std::endl;
-
+ str << "-l : List total numbers of entities and vertices in skin." << std::endl;
exit(0);
}
@@ -82,6 +82,7 @@
bool use_vert_elem_adjs = false;
bool merge_vertices = false;
double merge_epsilon = -1;
+ bool list_skin = false;
const char* fixed_tag = DEFAULT_FIXED_TAG;
const char *input_file = 0, *output_file = 0;
@@ -100,6 +101,7 @@
case 'm': merge_vertices = true; break;
case '-': no_more_flags = true; break;
case 'h': usage( argv[0], true ); break;
+ case 'l': list_skin = true; break;
case 'b':
if (i == argc || 0 >= (block = strtol(argv[i],&endptr,0)) || *endptr) {
std::cerr << "Expected positive integer following '-b' flag" << std::endl;
@@ -268,6 +270,16 @@
return 3;
}
+ if (list_skin) {
+ Range skin_verts;
+ result = iface->get_adjacencies(boundary, 0, true, skin_verts, Interface::UNION);
+ std::cout << "Skin has ";
+ if (skin_ents.num_of_dimension(3))
+ std::cout << boundary.num_of_dimension(2) << " faces and ";
+ else if (skin_ents.num_of_dimension(2))
+ std::cout << boundary.num_of_dimension(1) << " edges and ";
+ std::cout << skin_verts.size() << " vertices." << std::endl;
+ }
if (write_tag) {
// get tag handle
Tag tag;
Modified: MOAB/trunk/src/MergeMesh.cpp
===================================================================
--- MOAB/trunk/src/MergeMesh.cpp 2011-05-24 15:44:38 UTC (rev 4863)
+++ MOAB/trunk/src/MergeMesh.cpp 2011-05-24 16:54:31 UTC (rev 4864)
@@ -5,27 +5,30 @@
#include "moab/Range.hpp"
#include "moab/CartVect.hpp"
+#include <vector>
#include <algorithm>
#include <string>
#include <vector>
#include <cassert>
#include <iostream>
+#include <iomanip>
namespace moab {
moab::ErrorCode MergeMesh::merge_entities(moab::EntityHandle *elems,
- int elems_size,
- const double merge_tol,
- const int do_merge,
- const int update_sets,
- moab::Tag merge_tag)
+ int elems_size,
+ const double merge_tol,
+ const int do_merge,
+ const int update_sets,
+ moab::Tag merge_tag,
+ bool do_higher_dim)
{
mergeTol = merge_tol;
mergeTolSq = merge_tol*merge_tol;
moab::Range tmp_elems;
tmp_elems.insert( elems, elems + elems_size);
moab::ErrorCode result = merge_entities(tmp_elems, merge_tol, do_merge, update_sets,
- (moab::Tag)merge_tag);
+ (moab::Tag)merge_tag, do_higher_dim);
return result;
}
@@ -43,9 +46,15 @@
moab::ErrorCode MergeMesh::merge_entities(moab::Range &elems,
const double merge_tol,
const int do_merge,
- const int /*update_sets*/,
- moab::Tag merge_tag)
+ const int update_sets,
+ moab::Tag merge_tag,
+ bool merge_higher_dim)
{
More information about the moab-dev
mailing list