[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