[MOAB-dev] commit/MOAB: 3 new changesets

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Thu Jul 25 10:24:00 CDT 2013


3 new commits in MOAB:

https://bitbucket.org/fathomteam/moab/commits/384684f17846/
Changeset:   384684f17846
Branch:      None
User:        danwu
Date:        2013-07-24 22:31:16
Summary:     Merged fathomteam/moab into master
Affected #:  2 files

diff --git a/doc/DG/styleguide.h b/doc/DG/styleguide.h
index e3cf6f9..3a13e45 100644
--- a/doc/DG/styleguide.h
+++ b/doc/DG/styleguide.h
@@ -61,7 +61,7 @@ subdirectories in the %MOAB source code, except when implementing a new algorith
      class using it. 
    - Any names introduced into the top-level MOAB namespace should be
      sufficiently unique to avoid conflicts with other code.  If you must 
-     introduce a class to the top-level Meshkit namespace, don't choose
+     introduce a class to the top-level MOAB namespace, don't choose
      an overly genereric name like \c Point3D .
  - Constants and Macros
    - Don't use a pre-processor macro where a const variable or an inline or
@@ -69,7 +69,7 @@ subdirectories in the %MOAB source code, except when implementing a new algorith
      There is absolutely benefit to the former over the later with modern 
      compilers.  Further, using  macros bypasses typechecking that the compiler
      would otherwise do for you and if used in headers, introduce names into
-     the global rather than Meshkit namespace.
+     the global rather than MOAB namespace.
    - Don't define constants that are already provided by standard libraries.
      For example, use \c M_PI as defined in \c math.h rather than defining
      your own constant.
@@ -80,8 +80,8 @@ top-level directory.  If you commit code that violates this principal, it should
 code to a compilable state, and your second priority to make sure "make check" runs without errors.
 
 Commits to the repository should also come with a non-trivial, useful, non-verbose log message.  Oftentimes the best way to generate
-this message is to run 'svn diff > diffs', and edit the diffs file to remove specific line changes but include a comment on 
-each file that changed.  Many times it is helpful to state that 'make check runs successfully' at the end of the log message.
+this message is to run 'commit -a', and include a comment on 
+each file that changed, then Ctrl+O to write out, followed by 'Enter' and Ctrl+X.  Many times it is helpful to state that 'make check runs successfully' at the end of the log message.
 Although it would be possible and many software projects do it, we prefer not to force successful execution of the test suite 
 before every commit.  Developers should make every effort to avoid having to impose this constraint, by running a make check
 before every commit.

diff --git a/doc/MetaData/metadata.h b/doc/MetaData/metadata.h
index 3bcd47e..e02c112 100644
--- a/doc/MetaData/metadata.h
+++ b/doc/MetaData/metadata.h
@@ -37,7 +37,7 @@ Several specific tools are often used in concert with MOAB and bear special ment
 
 The MOAB data model consists of the following basic types:
 - <B>Entity</B>: The basic elements of topology, e.g. vertex, edge, triangle, tetrahedron, etc.  MOAB represents all types in the finite element zoo, plus polygons and polyhedra.
-- <B>Entity Set</B>: An arbitrary collection of entities and other sets.  Sets can have parent/child relations with other sets, and these relations are distinct from “contains” relations.
+- <B>Entity %Set</B>: An arbitrary collection of entities and other sets.  Sets can have parent/child relations with other sets, and these relations are distinct from “contains” relations.
 - <B>Interface</B>: The interface object through which other entities are accessed, in the sense of object-oriented-programming.  iMesh refers to the interface as the “root” set.
 - <B>Tag</B>: A piece of data that can be assigned a distinct value to each entity and entity set, and to the interface itself.  Tags have a prescribed name, size in bytes, and data type; allowed data types are integer, double, entity handle, and byte or opaque.
 .
@@ -100,7 +100,7 @@ In the geometric model, each FACE is bounded by zero or more EDGEs; other topolo
 
 Geometric entities are sometimes assigned to application-specific groups.  These groups are represented using entity sets, tagged with a “GROUP” tag whose value equals the group id.  Group sets are “set”-type, and are not tracking sets.  These sets contain the sets corresponding to geometric entities contained in the groups in the geometric model, as well as any mesh entities assigned to the group.
 
-<H3> Sense </H3>
+- <B> Sense </B>
 
 A geometric face has a natural orientation, indicated by the direction of the normal to the face; similarly, edges have a natural orientation determined by the direction of the tangent.  When faces bound regions, or edges bound faces, they do so with a sense; if a region includes a face with forward sense, that means the face's natural normal direction points out of the volume.  If a face includes an edge with forward sense, that means that if one moves along the edge in the direction of its tangent, the material of the face is on the left hand side.  The sense of a face (edge) with respect to a region (face) it bounds is stored using tags on the face (edge).
 
@@ -194,10 +194,16 @@ By default, all field data stored with the mesh is read with the mesh, and store
 
 Indicates that no mesh should be read from the file.  This option is used in conjunction with the “variable=” option, to read variables and assign them as tags to a previously-read mesh.  If this option is used, applications should pass an entity set to the read function, which should contain the mesh previously read from the file.
 
-<H3>timestep=<step_number>[, ...] </H3>
+<H3>timestep=\<step_number\>[, ...] </H3>
 
 Read the time step number whose time value is equal to or greater than the specified time value, for the specified variable(s).  Tag names for the variable(s) will be formed by appending the time step number to the variable name.  Multiple time step values can be specified, separated from each other by commas.
 
+<H3>timeval=\<time_value\>[, ...]</H3>
+
+Read the time step number whose time value is equal to or greater than the specified time value, for the
+specified variable(s). Tag names for the variable(s) will be formed by appending the time step number
+to the variable name. Multiple time step values can be specified, separated from each other by commas.
+
 \ref md-contents "Top"
 
   \section meta-references References
@@ -246,19 +252,19 @@ CATEGORY/C*32.
 GEOM_SENSE_2/EH[2],
 GEOM_SENSE_N_ENTS/EH*N,
 GEOM_SENSE_N_SENSES/I*N</td>
-<td>Sets contain mesh owned by that entity; parent/child links to bounded/bounding entities in geometric model</td>
+<td>%Sets contain mesh owned by that entity; parent/child links to bounded/bounding entities in geometric model</td></tr><tr><td>Material type</td><td>S</td><td>MATERIAL_SET/I</td>
-<td>Set contains entities or sets assigned a common material type</td>
+<td>%Set contains entities or sets assigned a common material type</td></tr><tr><td>Boundary condition</td><td>S</td><td>DIRICHLET_SET/I, NEUMANN_SET/I</td>
-<td>Set contains entities or sets assigned a particular boundary condition; neumann sets usually contain edges (2D) or faces (3D)</td>
+<td>%Set contains entities or sets assigned a particular boundary condition; neumann sets usually contain edges (2D) or faces (3D)</td></tr><tr><td>Parallel mesh constructs</td>
@@ -393,6 +399,36 @@ GEOM_SENSE_N_SENSES/I*N</td><td>E,S</td><td>Rank of other processor sharing this entity/set </td></tr>
+<tr>
+<td>__PARALLEL_SHARED_HANDLES</td>
+<td>H*NP</td>
+<td>E,S</td>
+<td>Handles of this entity/set on sharing processors </td>
+</tr>
+<tr>
+<td>__PARALLEL_SHARED_PROCS</td>
+<td>I*NP</td>
+<td>E,S</td>
+<td>Ranks of other processors sharing this entity/set </td>
+</tr>
+<tr>
+<td>__PARALLEL_STATUS</td>
+<td>C*1</td>
+<td>E,S</td>
+<td>Bit-field indicating various parallel information </td>
+</tr>
+<tr>
+<td>SPECTRAL_ORDER</td>
+<td>I</td>
+<td>S</td>
+<td> Order of a spectral mesh </td>
+</tr>
+<tr>
+<td>SPECTRAL_VERTICES</td>
+<td>H*(O+1)^d</td>
+<td>E</td>
+<td> Vertices comprising a spectral element, ordered lexicographically; here, O=value of SPECTRAL_ORDER tag. </td>
+</tr></table>
 
 \ref md-contents "Top"
@@ -402,7 +438,7 @@ GEOM_SENSE_N_SENSES/I*N</td>
   \subsection table3 Table 3: Translation between CCMIO options and MOAB tags.
 <Table border="1"><tr>
-<th> Set Type</th>
+<th> %Set Type</th><th>CCMIO Construct</th><th>MOAB Tag Name, Type</th></tr>
@@ -576,6 +612,11 @@ size (for details on the partitioning method used, see the src/io/ReadNC.cpp sou
 Mesh is put into the entity set provided to the load_file function. This entity set is also annotated with
 various tags representing information read from the file. These tags are described in Table 5.
 
+Reading unstructured NC files in the HOMME format is also supported. Currently a trivial
+element-based partition is the only option for parallel reading. As the data is unstructured, it is necessary to have a connectivity file to define the vertex adjacencies. The default convention is to have a file called HommeMapping.nc in the same directory as the the variable data file. If this convention is not followed, the connectivity file can be specified with the option -O CONN=”/path/to/connectivity.nc”. An example of mbconvert using the parallel read capability is shown below:
+
+<B>  mpiexec -np 2 tools/mbconvert -O TRIVIAL_PARTITION -O DEBUG_IO=1 -o DEBUG_IO=9 -o PARALLEL=WRITE_PART /nfs2/hayes6/meshlab/homme_data/camrun.cam2.h0.0000-01-01-16200.nc output.h5m </B>
+
 Several other things to note about reading climate data files into MOAB:
 - Time-dependent variables: MOAB currently has no mechanism for time-dependent tags. Therefore, time-dependent variables are represented using one tag per timestep, with the tag name set as the variable name plus the timestep index. Thus, the first few timesteps for the variable TEMPERATURE would be represented in tags named TEMPERATURE0, TEMPERATURE1, etc.
 - Cell- and face-centered variables: The climate data reader currently does not do cell- and face-


https://bitbucket.org/fathomteam/moab/commits/8297fa523bb1/
Changeset:   8297fa523bb1
Branch:      None
User:        danwu
Date:        2013-07-25 00:09:54
Summary:     Move gather set stuff from Util to ReadUtilIface. Add new read option GATHER_SET[=rank], where rank specifies a processor on which to make the gather set. Update NCHelperHOMME and affected unit tests.

Affected #:  11 files

diff --git a/src/Core.cpp b/src/Core.cpp
index dfb9cf2..57ff342 100644
--- a/src/Core.cpp
+++ b/src/Core.cpp
@@ -44,7 +44,6 @@
 #include "moab/WriterIface.hpp"
 #include "moab/ScdInterface.hpp"
 #include "moab/SetIterator.hpp"
-#include "moab/Util.hpp"
 
 #include "BitTag.hpp"
 #include "DenseTag.hpp"
@@ -611,12 +610,19 @@ ErrorCode Core::serial_load_file( const char* file_name,
     get_entities_by_handle( 0, new_ents );
     new_ents = subtract( new_ents, initial_ents );
 
-    // The gather set entities should be excluded from the file set
+    // Check if gather set exists
     EntityHandle gather_set;
-    Range gather_ents;
-    rval = Util::gather_set_entities( this, gather_set, gather_ents );
-    if (MB_SUCCESS == rval)
-      new_ents = subtract( new_ents, gather_ents );
+    rval = mMBReadUtil->get_gather_set(gather_set);
+    if (MB_SUCCESS == rval) {
+      // Exclude gather set itself
+      new_ents.erase(gather_set);
+
+      // Exclude gather set entities
+      Range gather_ents;
+      rval = get_entities_by_handle(gather_set, gather_ents);
+      if (MB_SUCCESS == rval)
+        new_ents = subtract(new_ents, gather_ents);
+    }
 
     rval = add_entities( *file_set, new_ents );
   }

diff --git a/src/ReadUtil.cpp b/src/ReadUtil.cpp
index 11320ac..7aeb00c 100644
--- a/src/ReadUtil.cpp
+++ b/src/ReadUtil.cpp
@@ -46,7 +46,6 @@ ErrorCode ReadUtil::get_node_coords(
     std::vector<double*>& arrays,
     int sequence_size)
 {
-
   ErrorCode error;
   EntitySequence* seq = 0;
   
@@ -89,7 +88,6 @@ ErrorCode ReadUtil::get_element_connect(
     EntityHandle*& array,
     int sequence_size)
 {
-
   ErrorCode error;
   EntitySequence* seq;
   
@@ -122,7 +120,6 @@ ErrorCode ReadUtil::get_element_connect(
          * static_cast<ElementSequence*>(seq)->nodes_per_element();
 
   return error;
-  
 }
 
 ErrorCode ReadUtil::create_entity_sets( EntityID num_sets,
@@ -153,7 +150,6 @@ ErrorCode ReadUtil::create_entity_sets( EntityID num_sets,
   return MB_SUCCESS;
 }
 
-
 ErrorCode ReadUtil::update_adjacencies(
       const EntityHandle start_handle,
       const int number_elements,
@@ -178,8 +174,6 @@ ErrorCode ReadUtil::update_adjacencies(
   return MB_SUCCESS;
 }
 
-
-
 ErrorCode ReadUtil::report_error( const std::string& error )
 {
   if(mError)
@@ -188,7 +182,6 @@ ErrorCode ReadUtil::report_error( const std::string& error )
     return MB_FAILURE;
 }
 
-
 ErrorCode ReadUtil::report_error( const char* error, ... )
 {
   va_list args;
@@ -410,4 +403,45 @@ ErrorCode ReadUtil::assign_ids( Tag id_tag,
   return MB_SUCCESS;
 }
 
+ErrorCode ReadUtil::create_gather_set(EntityHandle& gather_set)
+{
+  ErrorCode rval = mMB->create_meshset(MESHSET_SET, gather_set);
+  if (MB_SUCCESS != rval)
+    return rval;
+
+  Tag gather_set_tag;
+  rval = mMB->tag_get_handle("GATHER_SET", 1, MB_TYPE_INTEGER, gather_set_tag, MB_TAG_CREAT | MB_TAG_SPARSE);
+  if (MB_SUCCESS != rval)
+    return rval;
+
+  int gather_val = 1;
+  rval = mMB->tag_set_data(gather_set_tag, &gather_set, 1, &gather_val);
+  if (MB_SUCCESS != rval)
+    return rval;
+
+  return MB_SUCCESS;
+}
+
+ErrorCode ReadUtil::get_gather_set(EntityHandle& gather_set)
+{
+  Tag gather_set_tag;
+  ErrorCode rval = mMB->tag_get_handle("GATHER_SET", 1, MB_TYPE_INTEGER, gather_set_tag, MB_TAG_SPARSE);
+  if (MB_SUCCESS != rval)
+    return rval;
+
+  int gather_val = 1;
+  void* vals[] = {&gather_val};
+  Range gather_sets;
+  rval = mMB->get_entities_by_type_and_tag(0, MBENTITYSET, &gather_set_tag, vals, 1, gather_sets);
+  if (MB_SUCCESS != rval)
+    return rval;
+
+  if (gather_sets.empty())
+    return MB_ENTITY_NOT_FOUND;
+
+  gather_set = gather_sets[0];
+
+  return MB_SUCCESS;
+}
+
 } // namespace moab

diff --git a/src/ReadUtil.hpp b/src/ReadUtil.hpp
index 796543b..0f33987 100644
--- a/src/ReadUtil.hpp
+++ b/src/ReadUtil.hpp
@@ -13,7 +13,6 @@
  * 
  */
 
-
 #ifndef MB_READ_UTIL_HPP
 #define MB_READ_UTIL_HPP
 
@@ -106,8 +105,15 @@ public:
 
 
   ErrorCode assign_ids( Tag id_tag, const Range& ents, int start = 0 );
+
   ErrorCode assign_ids( Tag id_tag, const EntityHandle* ents, 
                           size_t num_ents, int start = 0 );
+
+  //! Create a new gather set with tag GATHER_SET
+  ErrorCode create_gather_set(EntityHandle& gather_set);
+
+  //! Get entity handle of an existing gather set
+  ErrorCode get_gather_set(EntityHandle& gather_set);
 };
   
 } // namespace moab

diff --git a/src/Util.cpp b/src/Util.cpp
index 72684e6..d87bb65 100644
--- a/src/Util.cpp
+++ b/src/Util.cpp
@@ -44,7 +44,6 @@ namespace moab {
 
 void Util::normal(Interface* MB, EntityHandle handle, double& x, double& y, double& z)
 {
-
    // get connectivity
    const EntityHandle *connectivity;
    int number_nodes = 0;
@@ -77,6 +76,7 @@ void Util::normal(Interface* MB, EntityHandle handle, double& x, double& y, doub
      z /= mag;
    }
 }
+
 void Util::centroid(Interface *MB, EntityHandle handle, Coord &coord)
 {
    const EntityHandle *connectivity;
@@ -112,7 +112,6 @@ void Util::edge_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &
   double coords[2][3];
   const EntityHandle *connectivity;
 
-
   MB->get_connectivity(handle, connectivity, number_nodes,true);
   
   MB->type_from_handle(handle,type);
@@ -130,11 +129,7 @@ void Util::edge_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &
     coords_list[i].x = (coords[0][0] + coords[1][0])/2.0;
     coords_list[i].y = (coords[0][1] + coords[1][1])/2.0;
     coords_list[i].z = (coords[0][2] + coords[1][2])/2.0;
-
   }
-
-
-
 }
 */  
 
@@ -148,7 +143,6 @@ void Util::face_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &
   double node_coords[3];
   const EntityHandle *connectivity;
 
-
   MB->get_connectivity(handle, connectivity, number_nodes,true);
   
   MB->type_from_handle(handle,type);
@@ -174,36 +168,6 @@ void Util::face_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &
     coords_list[i].y/=(double)number_nodes_per_element;
     coords_list[i].z/=(double)number_nodes_per_element;
   }
-
 }
 */
-ErrorCode Util::gather_set(Interface * MB, EntityHandle & gather_set){
-  Tag gathersettag;
-  ErrorCode rval = MB->tag_get_handle("GATHER_SET", 1, MB_TYPE_INTEGER, gathersettag,
-       MB_TAG_SPARSE);
-  if (rval!=MB_SUCCESS)
-    return rval;
-
-  int gatherval = 1;
-  void *vals[] = {&gatherval};
-  Range gathersets;
-  rval = MB->get_entities_by_type_and_tag( 0, MBENTITYSET, &gathersettag,
-                                             vals, 1, gathersets );
-  if (rval!=MB_SUCCESS)
-    return rval;
-  if (gathersets.empty())
-    return MB_ENTITY_NOT_FOUND;
-  gather_set = gathersets[0];
-
-  return MB_SUCCESS;
-}
-
-ErrorCode Util::gather_set_entities(Interface * MB, EntityHandle & gather_set, Range & ents)
-{
-  ErrorCode rval = Util::gather_set(MB, gather_set);
-  if (rval!=MB_SUCCESS)
-    return rval;
-  rval = MB->get_entities_by_handle(gather_set, ents);
-  return rval;
-}
 } // namespace moab

diff --git a/src/io/NCHelperHOMME.cpp b/src/io/NCHelperHOMME.cpp
index e320e57..d6659eb 100644
--- a/src/io/NCHelperHOMME.cpp
+++ b/src/io/NCHelperHOMME.cpp
@@ -251,6 +251,7 @@ ErrorCode NCHelperHOMME::create_mesh(ScdInterface* scdi, const FileOptions& opts
   ParallelComm*& myPcomm = _readNC->myPcomm;
 #endif
   bool& spectralMesh = _readNC->spectralMesh;
+  int& gatherSetRank = _readNC->gatherSetRank;
 
   // need to get/read connectivity data before creating elements
   std::string conn_fname;
@@ -329,14 +330,16 @@ ErrorCode NCHelperHOMME::create_mesh(ScdInterface* scdi, const FileOptions& opts
     tmp_conn[4 * i + 3] = tmp_conn2[i + 3 * num_quads];
   }
 
-  // need to know whether we'll be creating gather mesh later, to make sure we allocate enough space
+  // Need to know whether we'll be creating gather mesh later, to make sure we allocate enough space
   // in one shot
-  bool create_gathers = true;
+  bool create_gathers = false;
+  int proc_rank = 0;
 #ifdef USE_MPI
   if (isParallel)
-    if (myPcomm->proc_config().proc_rank() != 0)
-      create_gathers = false;
+    proc_rank = myPcomm->proc_config().proc_rank();
 #endif
+  if (proc_rank == gatherSetRank)
+    create_gathers = true;
 
   // compute the number of local quads, accounting for coarse or fine representation
   // spectral_unit is the # fine quads per coarse quad, or spectralOrder^2
@@ -466,11 +469,9 @@ ErrorCode NCHelperHOMME::create_mesh(ScdInterface* scdi, const FileOptions& opts
   rval = mbImpl->tag_set_data(sporder, &file_set, 1, &_spectralOrder);
   ERRORR(rval, "Couldn't set value for spectral order tag.");
 
-#ifdef USE_MPI
-  if (isParallel && myPcomm->proc_config().proc_rank() == 0) {
-#endif
+  if (create_gathers) {
     EntityHandle gather_set;
-    rval = mbImpl->create_meshset(MESHSET_SET, gather_set);
+    rval = _readNC->readMeshIface->create_gather_set(gather_set);
     ERRORR(rval, "Trouble creating gather set.");
 
     // create vertices
@@ -524,18 +525,7 @@ ErrorCode NCHelperHOMME::create_mesh(ScdInterface* scdi, const FileOptions& opts
       conn_arr[i] += start_vertex - 1; // connectivity array is shifted by where the gather verts start
     rval = mbImpl->add_entities(gather_set, gather_quads);
     ERRORR(rval, "Couldn't add quads to gather set.");
-
-    Tag gathersettag;
-    rval = mbImpl->tag_get_handle("GATHER_SET", 1, MB_TYPE_INTEGER, gathersettag,
-				  MB_TAG_CREAT | MB_TAG_SPARSE);
-    ERRORR(rval, "Couldn't create gather set tag.");
-    int gatherval = 1;
-    rval = mbImpl->tag_set_data(gathersettag, &gather_set, 1, &gatherval);
-    ERRORR(rval, "Couldn't set value for gather set tag.");
-
-#ifdef USE_MPI
   }
-#endif
 
   return MB_SUCCESS;
 }

diff --git a/src/io/ReadNC.cpp b/src/io/ReadNC.cpp
index cf301df..385781f 100644
--- a/src/io/ReadNC.cpp
+++ b/src/io/ReadNC.cpp
@@ -35,9 +35,9 @@ ReadNC::ReadNC(Interface* impl) :
   mbImpl(impl), CPU_WORD_SIZE(-1), IO_WORD_SIZE(-1), fileId(-1), tMin(-1), tMax(-1), iDim(-1), jDim(-1), tDim(-1), iCDim(-1),
   jCDim(-1), numUnLim(-1), mGlobalIdTag(0), mpFileIdTag(NULL), dbgOut(stderr), isParallel(false), partMethod(-1),
 #ifdef USE_MPI
-  myPcomm(NULL), 
+  myPcomm(NULL),
 #endif
-  noMesh(false), noVars(false), spectralMesh(false), myHelper(NULL)
+  noMesh(false), noVars(false), spectralMesh(false), gatherSetRank(-1), myHelper(NULL)
 {
   assert(impl != NULL);
 
@@ -240,7 +240,7 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
 
   return MB_SUCCESS;
 }
-    
+
 ErrorCode ReadNC::parse_options(const FileOptions& opts, std::vector<std::string>& var_names, std::vector<int>& tstep_nums,
                                 std::vector<double>& tstep_vals) {
   int tmpval;
@@ -285,6 +285,12 @@ ErrorCode ReadNC::parse_options(const FileOptions& opts, std::vector<std::string
     }
   }
 
+  rval = opts.get_int_option("GATHER_SET", 0, gatherSetRank);
+  if (MB_TYPE_OUT_OF_RANGE == rval) {
+    readMeshIface->report_error("Invalid value for GATHER_SET option");
+    return rval;
+  }
+
 #ifdef USE_MPI
   //TODO handle options better
   //rval = opts.get_option("PARTITION", partitionTagName);

diff --git a/src/io/ReadNC.hpp b/src/io/ReadNC.hpp
index 3e44e5a..abe690f 100644
--- a/src/io/ReadNC.hpp
+++ b/src/io/ReadNC.hpp
@@ -319,6 +319,7 @@ private:
   bool noVars;
   bool spectralMesh;
   std::string partitionTagName;
+  int gatherSetRank;
 
   //! Helper class instance
   NCHelper* myHelper;

diff --git a/src/moab/ReadUtilIface.hpp b/src/moab/ReadUtilIface.hpp
index 230fc97..6b0779e 100644
--- a/src/moab/ReadUtilIface.hpp
+++ b/src/moab/ReadUtilIface.hpp
@@ -13,11 +13,9 @@
  * 
  */
 
-
 #ifndef MOAB_READ_UTIL_IFACE_HPP
 #define MOAB_READ_UTIL_IFACE_HPP
 
-
 #include <vector>
 #include <string>
 #include "moab/Types.hpp"
@@ -94,7 +92,7 @@ public:
   virtual ErrorCode gather_related_ents(Range &partition,
                                         Range &related_ents,
                                         EntityHandle *file_set = NULL) = 0;
-  
+
   virtual ErrorCode create_entity_sets(
     EntityID num_sets,
     const unsigned* set_flags,
@@ -118,8 +116,6 @@ public:
     const EntityHandle* conn_array
     ) = 0;
 
-
-  
   /**\brief Re-order incomming element connectivity
    *
    * Permute the connectivity of each element such that the node
@@ -155,12 +151,18 @@ public:
     //! Assign sequential IDS to entities in range and store IDs in tag
   virtual ErrorCode assign_ids( Tag id_tag, const Range& ents, 
                                   int start = 0 ) = 0;
-  
+
     //! Assign to each entity in an array the ID that is its position
     //! in the array plus the value of 'start'.  For any non-zero handles
     //! in the array, store the ID value in the passed tag.
   virtual ErrorCode assign_ids( Tag id_tag, const EntityHandle* ents, 
                                   size_t num_ents, int start = 0 ) = 0;
+
+  //! Create a new gather set with tag GATHER_SET
+  virtual ErrorCode create_gather_set(EntityHandle& gather_set) = 0;
+
+  //! Get entity handle of an existing gather set
+  virtual ErrorCode get_gather_set(EntityHandle& gather_set) = 0;
 };
 
 inline 

diff --git a/src/moab/Util.hpp b/src/moab/Util.hpp
index 25064f4..9cdd169 100644
--- a/src/moab/Util.hpp
+++ b/src/moab/Util.hpp
@@ -30,7 +30,6 @@ struct  Coord
   double z;
 };
 
-
 /** \class Util
  *
  * \brief Utility functions for normal and centroid for entities
@@ -38,17 +37,14 @@ struct  Coord
 class Util
 {
 public:
-
    
   static void normal(Interface* MB, EntityHandle handle, double& x, double& y, double& z);
 
   static void centroid(Interface *MB, EntityHandle handle,Coord &coord);
- // static void edge_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &coords_list);
 
-  //static void face_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &coords_list);
-  static ErrorCode gather_set(Interface * MB, EntityHandle & gather_set);
+  //static void edge_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &coords_list);
 
-  static ErrorCode gather_set_entities(Interface * MB, EntityHandle & gather_set, Range & ents);
+  //static void face_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &coords_list);
 
 private:
 

diff --git a/test/io/read_ucd_nc.cpp b/test/io/read_ucd_nc.cpp
index a468ad2..f2aed36 100644
--- a/test/io/read_ucd_nc.cpp
+++ b/test/io/read_ucd_nc.cpp
@@ -1,6 +1,6 @@
 #include "TestUtil.hpp"
 #include "moab/Core.hpp"
-#include "moab/Util.hpp"
+#include "moab/ReadUtilIface.hpp"
 
 using namespace moab;
 
@@ -80,6 +80,8 @@ void test_read_onevar()
   CHECK_ERR(rval);
 
   opts += std::string(";VARIABLE=T");
+  // Create gather set
+  opts += std::string(";GATHER_SET=");
   rval = mb.load_file(example, NULL, opts.c_str());
   CHECK_ERR(rval);
 
@@ -91,7 +93,7 @@ void test_read_onevar()
   rval = mb.tag_get_handle("T1", 26, MB_TYPE_DOUBLE, Ttag1);
   CHECK_ERR(rval);
 
-  // Check values of tag T0 (first level) at some strategically chosen places below
+  // Check values of tag T0 at some strategically chosen places below
   int procs = 1;
 #ifdef USE_MPI
   ParallelComm* pcomm = ParallelComm::get_pcomm(&mb, 0);
@@ -100,25 +102,36 @@ void test_read_onevar()
 
   // Make check runs this test in one processor
   if (1 == procs) {
+    // Get vertices
     Range verts;
     rval = mb.get_entities_by_type(0, MBVERTEX, verts);
     CHECK_ERR(rval);
-    CHECK_EQUAL((size_t)6916, verts.size());
+    CHECK_EQUAL((size_t)6916, verts.size()); // Gather set vertices included
 
-    // Remove from vertices the gather set entities
+    // Get gather set
     EntityHandle gather_set;
+    ReadUtilIface* readUtilIface;
+    mb.query_interface(readUtilIface);
+    rval = readUtilIface->get_gather_set(gather_set);
+    CHECK_ERR(rval);
+
+    // Get gather set entities
     Range gather_ents;
-    rval = Util::gather_set_entities(&mb, gather_set, gather_ents);
+    rval = mb.get_entities_by_handle(gather_set, gather_ents);
     CHECK_ERR(rval);
+
+    // Remove gather set vertices
     verts = subtract(verts, gather_ents);
-    CHECK_EQUAL((size_t)3458, verts.size());
+    CHECK_EQUAL((size_t)3458, verts.size()); // Gather set vertices excluded
 
+    // Get all values of tag T0
     int count;
     void* Tbuf;
     rval = mb.tag_iterate(Ttag0, verts.begin(), verts.end(), count, Tbuf);
     CHECK_ERR(rval);
     CHECK_EQUAL((size_t)count, verts.size());
 
+    // Check first level values at some vertices
     const double eps = 0.0001;
     double* data = (double*) Tbuf;
     CHECK_REAL_EQUAL(233.1136, data[0 * 26], eps); // First vert

diff --git a/test/parallel/ucdtrvpart.cpp b/test/parallel/ucdtrvpart.cpp
index abf52c5..17b478f 100644
--- a/test/parallel/ucdtrvpart.cpp
+++ b/test/parallel/ucdtrvpart.cpp
@@ -3,7 +3,7 @@
 #include "moab/ParallelComm.hpp"
 #include "moab/ProgOptions.hpp"
 #include "MBParallelConventions.h"
-#include "moab/Util.hpp"
+#include "moab/ReadUtilIface.hpp"
 
 using namespace moab;
 
@@ -34,8 +34,6 @@ int main(int argc, char* argv[])
 
 void test_read_parallel_ucd_trivial()
 {
-  // Disable spectral mesh for the time being, it is not ready yet
-  //partition_method = std::string(";PARTITION_METHOD=TRIVIAL_PARTITION;SPECTRAL_MESH;PARALLEL_RESOLVE_SHARED_ENTS");
   partition_method = std::string(";PARTITION_METHOD=TRIVIAL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS");
   test_read_parallel(3458, true);
 }
@@ -56,10 +54,14 @@ void test_read_parallel(int num_verts, bool test_nb_nodes)
   CHECK_ERR(rval);
 
   std::string opt = std::string("PARALLEL=READ_PART") + partition_method;
+  // Create gather set in processor 0
+  opt += std::string(";GATHER_SET=0");
   rval = mb.load_file(example, &file_set, opt.c_str());
   CHECK_ERR(rval);
 
   ParallelComm* pcomm = ParallelComm::get_pcomm(&mb, 0);
+  int procs = pcomm->proc_config().proc_size();
+  int rank = pcomm->proc_config().proc_rank();
 
   rval = pcomm->check_all_shared_handles();
   CHECK_ERR(rval);
@@ -68,23 +70,57 @@ void test_read_parallel(int num_verts, bool test_nb_nodes)
   Range verts;
   rval = mb.get_entities_by_type(0, MBVERTEX, verts);
   CHECK_ERR(rval);
+
+  int my_num = verts.size();
+  if (test_nb_nodes && 2 == procs) {
+    if (0 == rank)
+      CHECK_EQUAL(5283, my_num); // Gather set vertices included
+    else if (1 == rank)
+      CHECK_EQUAL(1825, my_num); // Not owned vertices included
+  }
+
   rval = pcomm->filter_pstatus(verts, PSTATUS_NOT_OWNED, PSTATUS_NOT);
   CHECK_ERR(rval);
 
-  int rank = pcomm->proc_config().proc_rank();
+  my_num = verts.size();
+  if (test_nb_nodes && 2 == procs) {
+    if (0 == rank)
+      CHECK_EQUAL(5283, my_num); // Gather set vertices included
+    else if (1 == rank)
+      CHECK_EQUAL(1633, my_num); // Not owned vertices excluded
+  }
+
   if (0 == rank) {
-    // Remove from verts the gather set ents
+    // Get gather set
     EntityHandle gather_set;
-    Range gth_ents;
-    rval = Util::gather_set_entities(&mb, gather_set, gth_ents);
+    ReadUtilIface* readUtilIface;
+    rval = mb.query_interface(readUtilIface);
+    CHECK_ERR(rval);
+    rval = readUtilIface->get_gather_set(gather_set);
+    CHECK_ERR(rval);
+
+    // Get gather set entities
+    Range gather_ents;
+    rval = mb.get_entities_by_handle(gather_set, gather_ents);
     CHECK_ERR(rval);
-    verts = subtract(verts, gth_ents);
+
+    // Remove gather set vertices in processor 0
+    verts = subtract(verts, gather_ents);
+  }
+
+  my_num = verts.size();
+  if (test_nb_nodes && 2 == procs) {
+    if (0 == rank)
+      CHECK_EQUAL(1825, my_num); // Gather set vertices excluded
+    else if (1 == rank)
+      CHECK_EQUAL(1633, my_num); // Not owned vertices excluded
   }
 
-  int my_num = verts.size(), total_verts;
   std::cout << "proc: " << rank << " verts:" << my_num << "\n";
+
+  int total_verts;
   MPI_Reduce(&my_num, &total_verts, 1, MPI_INTEGER, MPI_SUM, 0, pcomm->proc_config().proc_comm());
-  
+
   if (0 == rank) {
     std::cout << "total vertices: " << total_verts << "\n";
     if (test_nb_nodes)
@@ -109,7 +145,9 @@ void test_multiple_loads_of_same_file()
   rval = mb.load_file(example, &file_set, opts.c_str());
   CHECK_ERR(rval);
 
-  opts="PARALLEL=READ_PART;PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;PARTITION_METHOD=TRIVIAL_PARTITION;VARIABLE=";
+  opts = "PARALLEL=READ_PART;PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;PARTITION_METHOD=TRIVIAL_PARTITION;VARIABLE=";
+  // Create gather set in processor 1
+  opts += std::string(";GATHER_SET=1");
   rval = mb.load_file(example, &file_set, opts.c_str());
   CHECK_ERR(rval);
 
@@ -120,6 +158,7 @@ void test_multiple_loads_of_same_file()
   // Check values of tag T0 (first level) at some strategically chosen places below
   ParallelComm* pcomm = ParallelComm::get_pcomm(&mb, 0);
   int procs = pcomm->proc_config().proc_size();
+  int rank = pcomm->proc_config().proc_rank();
 
   // Make check runs this test in two processors
   if (2 == procs) {
@@ -127,16 +166,35 @@ void test_multiple_loads_of_same_file()
     rval = mb.get_entities_by_type(0, MBVERTEX, verts);
     CHECK_ERR(rval);
 
-    int rank = pcomm->proc_config().proc_rank();
-    if (0 == rank) {
-      // Remove from verts the gather set ents
+    int my_num = verts.size();
+    if (0 == rank)
+      CHECK_EQUAL(1825, my_num);
+    else if (1 == rank)
+      CHECK_EQUAL(5283, my_num); // Gather set vertices included; Not owned vertices included
+
+    if (1 == rank) {
+      // Get gather set
       EntityHandle gather_set;
-      Range gth_ents;
-      rval = Util::gather_set_entities(&mb, gather_set, gth_ents);
+      ReadUtilIface* readUtilIface;
+      rval = mb.query_interface(readUtilIface);
+      CHECK_ERR(rval);
+      rval = readUtilIface->get_gather_set(gather_set);
+      CHECK_ERR(rval);
+
+      // Get gather set entities
+      Range gather_ents;
+      rval = mb.get_entities_by_handle(gather_set, gather_ents);
       CHECK_ERR(rval);
-      verts = subtract(verts, gth_ents);
+
+      // Remove gather set vertices in processor 1
+      verts = subtract(verts, gather_ents);
     }
-    CHECK_EQUAL((size_t)1825, verts.size());
+
+    my_num = verts.size();
+    if (0 == rank)
+      CHECK_EQUAL(1825, my_num);
+    else if (1 == rank)
+      CHECK_EQUAL(1825, my_num); // Gather set vertices excluded; Not owned vertices included
 
     Tag Ttag0;
     rval = mb.tag_get_handle("T0", 26, MB_TYPE_DOUBLE, Ttag0, MB_TAG_DENSE);
@@ -146,7 +204,7 @@ void test_multiple_loads_of_same_file()
     void* Tbuf;
     rval = mb.tag_iterate(Ttag0, verts.begin(), verts.end(), count, Tbuf);
     CHECK_ERR(rval);
-    CHECK_EQUAL((size_t)count, verts.size());
+    CHECK_EQUAL(count, my_num);
 
     const double eps = 0.0001;
     double* data = (double*) Tbuf;


https://bitbucket.org/fathomteam/moab/commits/1d3b4027ad26/
Changeset:   1d3b4027ad26
Branch:      master
User:        danwu
Date:        2013-07-25 17:23:52
Summary:     Merged in danwu/moab (pull request #9)

New read option for gather set, to be tested by updated ParGAL tests.
Affected #:  11 files

diff --git a/src/Core.cpp b/src/Core.cpp
index dfb9cf2..57ff342 100644
--- a/src/Core.cpp
+++ b/src/Core.cpp
@@ -44,7 +44,6 @@
 #include "moab/WriterIface.hpp"
 #include "moab/ScdInterface.hpp"
 #include "moab/SetIterator.hpp"
-#include "moab/Util.hpp"
 
 #include "BitTag.hpp"
 #include "DenseTag.hpp"
@@ -611,12 +610,19 @@ ErrorCode Core::serial_load_file( const char* file_name,
     get_entities_by_handle( 0, new_ents );
     new_ents = subtract( new_ents, initial_ents );
 
-    // The gather set entities should be excluded from the file set
+    // Check if gather set exists
     EntityHandle gather_set;
-    Range gather_ents;
-    rval = Util::gather_set_entities( this, gather_set, gather_ents );
-    if (MB_SUCCESS == rval)
-      new_ents = subtract( new_ents, gather_ents );
+    rval = mMBReadUtil->get_gather_set(gather_set);
+    if (MB_SUCCESS == rval) {
+      // Exclude gather set itself
+      new_ents.erase(gather_set);
+
+      // Exclude gather set entities
+      Range gather_ents;
+      rval = get_entities_by_handle(gather_set, gather_ents);
+      if (MB_SUCCESS == rval)
+        new_ents = subtract(new_ents, gather_ents);
+    }
 
     rval = add_entities( *file_set, new_ents );
   }

diff --git a/src/ReadUtil.cpp b/src/ReadUtil.cpp
index 11320ac..7aeb00c 100644
--- a/src/ReadUtil.cpp
+++ b/src/ReadUtil.cpp
@@ -46,7 +46,6 @@ ErrorCode ReadUtil::get_node_coords(
     std::vector<double*>& arrays,
     int sequence_size)
 {
-
   ErrorCode error;
   EntitySequence* seq = 0;
   
@@ -89,7 +88,6 @@ ErrorCode ReadUtil::get_element_connect(
     EntityHandle*& array,
     int sequence_size)
 {
-
   ErrorCode error;
   EntitySequence* seq;
   
@@ -122,7 +120,6 @@ ErrorCode ReadUtil::get_element_connect(
          * static_cast<ElementSequence*>(seq)->nodes_per_element();
 
   return error;
-  
 }
 
 ErrorCode ReadUtil::create_entity_sets( EntityID num_sets,
@@ -153,7 +150,6 @@ ErrorCode ReadUtil::create_entity_sets( EntityID num_sets,
   return MB_SUCCESS;
 }
 
-
 ErrorCode ReadUtil::update_adjacencies(
       const EntityHandle start_handle,
       const int number_elements,
@@ -178,8 +174,6 @@ ErrorCode ReadUtil::update_adjacencies(
   return MB_SUCCESS;
 }
 
-
-
 ErrorCode ReadUtil::report_error( const std::string& error )
 {
   if(mError)
@@ -188,7 +182,6 @@ ErrorCode ReadUtil::report_error( const std::string& error )
     return MB_FAILURE;
 }
 
-
 ErrorCode ReadUtil::report_error( const char* error, ... )
 {
   va_list args;
@@ -410,4 +403,45 @@ ErrorCode ReadUtil::assign_ids( Tag id_tag,
   return MB_SUCCESS;
 }
 
+ErrorCode ReadUtil::create_gather_set(EntityHandle& gather_set)
+{
+  ErrorCode rval = mMB->create_meshset(MESHSET_SET, gather_set);
+  if (MB_SUCCESS != rval)
+    return rval;
+
+  Tag gather_set_tag;
+  rval = mMB->tag_get_handle("GATHER_SET", 1, MB_TYPE_INTEGER, gather_set_tag, MB_TAG_CREAT | MB_TAG_SPARSE);
+  if (MB_SUCCESS != rval)
+    return rval;
+
+  int gather_val = 1;
+  rval = mMB->tag_set_data(gather_set_tag, &gather_set, 1, &gather_val);
+  if (MB_SUCCESS != rval)
+    return rval;
+
+  return MB_SUCCESS;
+}
+
+ErrorCode ReadUtil::get_gather_set(EntityHandle& gather_set)
+{
+  Tag gather_set_tag;
+  ErrorCode rval = mMB->tag_get_handle("GATHER_SET", 1, MB_TYPE_INTEGER, gather_set_tag, MB_TAG_SPARSE);
+  if (MB_SUCCESS != rval)
+    return rval;
+
+  int gather_val = 1;
+  void* vals[] = {&gather_val};
+  Range gather_sets;
+  rval = mMB->get_entities_by_type_and_tag(0, MBENTITYSET, &gather_set_tag, vals, 1, gather_sets);
+  if (MB_SUCCESS != rval)
+    return rval;
+
+  if (gather_sets.empty())
+    return MB_ENTITY_NOT_FOUND;
+
+  gather_set = gather_sets[0];
+
+  return MB_SUCCESS;
+}
+
 } // namespace moab

diff --git a/src/ReadUtil.hpp b/src/ReadUtil.hpp
index 796543b..0f33987 100644
--- a/src/ReadUtil.hpp
+++ b/src/ReadUtil.hpp
@@ -13,7 +13,6 @@
  * 
  */
 
-
 #ifndef MB_READ_UTIL_HPP
 #define MB_READ_UTIL_HPP
 
@@ -106,8 +105,15 @@ public:
 
 
   ErrorCode assign_ids( Tag id_tag, const Range& ents, int start = 0 );
+
   ErrorCode assign_ids( Tag id_tag, const EntityHandle* ents, 
                           size_t num_ents, int start = 0 );
+
+  //! Create a new gather set with tag GATHER_SET
+  ErrorCode create_gather_set(EntityHandle& gather_set);
+
+  //! Get entity handle of an existing gather set
+  ErrorCode get_gather_set(EntityHandle& gather_set);
 };
   
 } // namespace moab

diff --git a/src/Util.cpp b/src/Util.cpp
index 72684e6..d87bb65 100644
--- a/src/Util.cpp
+++ b/src/Util.cpp
@@ -44,7 +44,6 @@ namespace moab {
 
 void Util::normal(Interface* MB, EntityHandle handle, double& x, double& y, double& z)
 {
-
    // get connectivity
    const EntityHandle *connectivity;
    int number_nodes = 0;
@@ -77,6 +76,7 @@ void Util::normal(Interface* MB, EntityHandle handle, double& x, double& y, doub
      z /= mag;
    }
 }
+
 void Util::centroid(Interface *MB, EntityHandle handle, Coord &coord)
 {
    const EntityHandle *connectivity;
@@ -112,7 +112,6 @@ void Util::edge_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &
   double coords[2][3];
   const EntityHandle *connectivity;
 
-
   MB->get_connectivity(handle, connectivity, number_nodes,true);
   
   MB->type_from_handle(handle,type);
@@ -130,11 +129,7 @@ void Util::edge_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &
     coords_list[i].x = (coords[0][0] + coords[1][0])/2.0;
     coords_list[i].y = (coords[0][1] + coords[1][1])/2.0;
     coords_list[i].z = (coords[0][2] + coords[1][2])/2.0;
-
   }
-
-
-
 }
 */  
 
@@ -148,7 +143,6 @@ void Util::face_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &
   double node_coords[3];
   const EntityHandle *connectivity;
 
-
   MB->get_connectivity(handle, connectivity, number_nodes,true);
   
   MB->type_from_handle(handle,type);
@@ -174,36 +168,6 @@ void Util::face_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &
     coords_list[i].y/=(double)number_nodes_per_element;
     coords_list[i].z/=(double)number_nodes_per_element;
   }
-
 }
 */
-ErrorCode Util::gather_set(Interface * MB, EntityHandle & gather_set){
-  Tag gathersettag;
-  ErrorCode rval = MB->tag_get_handle("GATHER_SET", 1, MB_TYPE_INTEGER, gathersettag,
-       MB_TAG_SPARSE);
-  if (rval!=MB_SUCCESS)
-    return rval;
-
-  int gatherval = 1;
-  void *vals[] = {&gatherval};
-  Range gathersets;
-  rval = MB->get_entities_by_type_and_tag( 0, MBENTITYSET, &gathersettag,
-                                             vals, 1, gathersets );
-  if (rval!=MB_SUCCESS)
-    return rval;
-  if (gathersets.empty())
-    return MB_ENTITY_NOT_FOUND;
-  gather_set = gathersets[0];
-
-  return MB_SUCCESS;
-}
-
-ErrorCode Util::gather_set_entities(Interface * MB, EntityHandle & gather_set, Range & ents)
-{
-  ErrorCode rval = Util::gather_set(MB, gather_set);
-  if (rval!=MB_SUCCESS)
-    return rval;
-  rval = MB->get_entities_by_handle(gather_set, ents);
-  return rval;
-}
 } // namespace moab

diff --git a/src/io/NCHelperHOMME.cpp b/src/io/NCHelperHOMME.cpp
index e320e57..d6659eb 100644
--- a/src/io/NCHelperHOMME.cpp
+++ b/src/io/NCHelperHOMME.cpp
@@ -251,6 +251,7 @@ ErrorCode NCHelperHOMME::create_mesh(ScdInterface* scdi, const FileOptions& opts
   ParallelComm*& myPcomm = _readNC->myPcomm;
 #endif
   bool& spectralMesh = _readNC->spectralMesh;
+  int& gatherSetRank = _readNC->gatherSetRank;
 
   // need to get/read connectivity data before creating elements
   std::string conn_fname;
@@ -329,14 +330,16 @@ ErrorCode NCHelperHOMME::create_mesh(ScdInterface* scdi, const FileOptions& opts
     tmp_conn[4 * i + 3] = tmp_conn2[i + 3 * num_quads];
   }
 
-  // need to know whether we'll be creating gather mesh later, to make sure we allocate enough space
+  // Need to know whether we'll be creating gather mesh later, to make sure we allocate enough space
   // in one shot
-  bool create_gathers = true;
+  bool create_gathers = false;
+  int proc_rank = 0;
 #ifdef USE_MPI
   if (isParallel)
-    if (myPcomm->proc_config().proc_rank() != 0)
-      create_gathers = false;
+    proc_rank = myPcomm->proc_config().proc_rank();
 #endif
+  if (proc_rank == gatherSetRank)
+    create_gathers = true;
 
   // compute the number of local quads, accounting for coarse or fine representation
   // spectral_unit is the # fine quads per coarse quad, or spectralOrder^2
@@ -466,11 +469,9 @@ ErrorCode NCHelperHOMME::create_mesh(ScdInterface* scdi, const FileOptions& opts
   rval = mbImpl->tag_set_data(sporder, &file_set, 1, &_spectralOrder);
   ERRORR(rval, "Couldn't set value for spectral order tag.");
 
-#ifdef USE_MPI
-  if (isParallel && myPcomm->proc_config().proc_rank() == 0) {
-#endif
+  if (create_gathers) {
     EntityHandle gather_set;
-    rval = mbImpl->create_meshset(MESHSET_SET, gather_set);
+    rval = _readNC->readMeshIface->create_gather_set(gather_set);
     ERRORR(rval, "Trouble creating gather set.");
 
     // create vertices
@@ -524,18 +525,7 @@ ErrorCode NCHelperHOMME::create_mesh(ScdInterface* scdi, const FileOptions& opts
       conn_arr[i] += start_vertex - 1; // connectivity array is shifted by where the gather verts start
     rval = mbImpl->add_entities(gather_set, gather_quads);
     ERRORR(rval, "Couldn't add quads to gather set.");
-
-    Tag gathersettag;
-    rval = mbImpl->tag_get_handle("GATHER_SET", 1, MB_TYPE_INTEGER, gathersettag,
-				  MB_TAG_CREAT | MB_TAG_SPARSE);
-    ERRORR(rval, "Couldn't create gather set tag.");
-    int gatherval = 1;
-    rval = mbImpl->tag_set_data(gathersettag, &gather_set, 1, &gatherval);
-    ERRORR(rval, "Couldn't set value for gather set tag.");
-
-#ifdef USE_MPI
   }
-#endif
 
   return MB_SUCCESS;
 }

diff --git a/src/io/ReadNC.cpp b/src/io/ReadNC.cpp
index cf301df..385781f 100644
--- a/src/io/ReadNC.cpp
+++ b/src/io/ReadNC.cpp
@@ -35,9 +35,9 @@ ReadNC::ReadNC(Interface* impl) :
   mbImpl(impl), CPU_WORD_SIZE(-1), IO_WORD_SIZE(-1), fileId(-1), tMin(-1), tMax(-1), iDim(-1), jDim(-1), tDim(-1), iCDim(-1),
   jCDim(-1), numUnLim(-1), mGlobalIdTag(0), mpFileIdTag(NULL), dbgOut(stderr), isParallel(false), partMethod(-1),
 #ifdef USE_MPI
-  myPcomm(NULL), 
+  myPcomm(NULL),
 #endif
-  noMesh(false), noVars(false), spectralMesh(false), myHelper(NULL)
+  noMesh(false), noVars(false), spectralMesh(false), gatherSetRank(-1), myHelper(NULL)
 {
   assert(impl != NULL);
 
@@ -240,7 +240,7 @@ ErrorCode ReadNC::load_file(const char* file_name, const EntityHandle* file_set,
 
   return MB_SUCCESS;
 }
-    
+
 ErrorCode ReadNC::parse_options(const FileOptions& opts, std::vector<std::string>& var_names, std::vector<int>& tstep_nums,
                                 std::vector<double>& tstep_vals) {
   int tmpval;
@@ -285,6 +285,12 @@ ErrorCode ReadNC::parse_options(const FileOptions& opts, std::vector<std::string
     }
   }
 
+  rval = opts.get_int_option("GATHER_SET", 0, gatherSetRank);
+  if (MB_TYPE_OUT_OF_RANGE == rval) {
+    readMeshIface->report_error("Invalid value for GATHER_SET option");
+    return rval;
+  }
+
 #ifdef USE_MPI
   //TODO handle options better
   //rval = opts.get_option("PARTITION", partitionTagName);

diff --git a/src/io/ReadNC.hpp b/src/io/ReadNC.hpp
index 3e44e5a..abe690f 100644
--- a/src/io/ReadNC.hpp
+++ b/src/io/ReadNC.hpp
@@ -319,6 +319,7 @@ private:
   bool noVars;
   bool spectralMesh;
   std::string partitionTagName;
+  int gatherSetRank;
 
   //! Helper class instance
   NCHelper* myHelper;

diff --git a/src/moab/ReadUtilIface.hpp b/src/moab/ReadUtilIface.hpp
index 230fc97..6b0779e 100644
--- a/src/moab/ReadUtilIface.hpp
+++ b/src/moab/ReadUtilIface.hpp
@@ -13,11 +13,9 @@
  * 
  */
 
-
 #ifndef MOAB_READ_UTIL_IFACE_HPP
 #define MOAB_READ_UTIL_IFACE_HPP
 
-
 #include <vector>
 #include <string>
 #include "moab/Types.hpp"
@@ -94,7 +92,7 @@ public:
   virtual ErrorCode gather_related_ents(Range &partition,
                                         Range &related_ents,
                                         EntityHandle *file_set = NULL) = 0;
-  
+
   virtual ErrorCode create_entity_sets(
     EntityID num_sets,
     const unsigned* set_flags,
@@ -118,8 +116,6 @@ public:
     const EntityHandle* conn_array
     ) = 0;
 
-
-  
   /**\brief Re-order incomming element connectivity
    *
    * Permute the connectivity of each element such that the node
@@ -155,12 +151,18 @@ public:
     //! Assign sequential IDS to entities in range and store IDs in tag
   virtual ErrorCode assign_ids( Tag id_tag, const Range& ents, 
                                   int start = 0 ) = 0;
-  
+
     //! Assign to each entity in an array the ID that is its position
     //! in the array plus the value of 'start'.  For any non-zero handles
     //! in the array, store the ID value in the passed tag.
   virtual ErrorCode assign_ids( Tag id_tag, const EntityHandle* ents, 
                                   size_t num_ents, int start = 0 ) = 0;
+
+  //! Create a new gather set with tag GATHER_SET
+  virtual ErrorCode create_gather_set(EntityHandle& gather_set) = 0;
+
+  //! Get entity handle of an existing gather set
+  virtual ErrorCode get_gather_set(EntityHandle& gather_set) = 0;
 };
 
 inline 

diff --git a/src/moab/Util.hpp b/src/moab/Util.hpp
index 25064f4..9cdd169 100644
--- a/src/moab/Util.hpp
+++ b/src/moab/Util.hpp
@@ -30,7 +30,6 @@ struct  Coord
   double z;
 };
 
-
 /** \class Util
  *
  * \brief Utility functions for normal and centroid for entities
@@ -38,17 +37,14 @@ struct  Coord
 class Util
 {
 public:
-
    
   static void normal(Interface* MB, EntityHandle handle, double& x, double& y, double& z);
 
   static void centroid(Interface *MB, EntityHandle handle,Coord &coord);
- // static void edge_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &coords_list);
 
-  //static void face_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &coords_list);
-  static ErrorCode gather_set(Interface * MB, EntityHandle & gather_set);
+  //static void edge_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &coords_list);
 
-  static ErrorCode gather_set_entities(Interface * MB, EntityHandle & gather_set, Range & ents);
+  //static void face_centers(Interface *MB, EntityHandle handle, std::vector<Coord> &coords_list);
 
 private:
 

diff --git a/test/io/read_ucd_nc.cpp b/test/io/read_ucd_nc.cpp
index a468ad2..f2aed36 100644
--- a/test/io/read_ucd_nc.cpp
+++ b/test/io/read_ucd_nc.cpp
@@ -1,6 +1,6 @@
 #include "TestUtil.hpp"
 #include "moab/Core.hpp"
-#include "moab/Util.hpp"
+#include "moab/ReadUtilIface.hpp"
 
 using namespace moab;
 
@@ -80,6 +80,8 @@ void test_read_onevar()
   CHECK_ERR(rval);
 
   opts += std::string(";VARIABLE=T");
+  // Create gather set
+  opts += std::string(";GATHER_SET=");
   rval = mb.load_file(example, NULL, opts.c_str());
   CHECK_ERR(rval);
 
@@ -91,7 +93,7 @@ void test_read_onevar()
   rval = mb.tag_get_handle("T1", 26, MB_TYPE_DOUBLE, Ttag1);
   CHECK_ERR(rval);
 
-  // Check values of tag T0 (first level) at some strategically chosen places below
+  // Check values of tag T0 at some strategically chosen places below
   int procs = 1;
 #ifdef USE_MPI
   ParallelComm* pcomm = ParallelComm::get_pcomm(&mb, 0);
@@ -100,25 +102,36 @@ void test_read_onevar()
 
   // Make check runs this test in one processor
   if (1 == procs) {
+    // Get vertices
     Range verts;
     rval = mb.get_entities_by_type(0, MBVERTEX, verts);
     CHECK_ERR(rval);
-    CHECK_EQUAL((size_t)6916, verts.size());
+    CHECK_EQUAL((size_t)6916, verts.size()); // Gather set vertices included
 
-    // Remove from vertices the gather set entities
+    // Get gather set
     EntityHandle gather_set;
+    ReadUtilIface* readUtilIface;
+    mb.query_interface(readUtilIface);
+    rval = readUtilIface->get_gather_set(gather_set);
+    CHECK_ERR(rval);
+
+    // Get gather set entities
     Range gather_ents;
-    rval = Util::gather_set_entities(&mb, gather_set, gather_ents);
+    rval = mb.get_entities_by_handle(gather_set, gather_ents);
     CHECK_ERR(rval);
+
+    // Remove gather set vertices
     verts = subtract(verts, gather_ents);
-    CHECK_EQUAL((size_t)3458, verts.size());
+    CHECK_EQUAL((size_t)3458, verts.size()); // Gather set vertices excluded
 
+    // Get all values of tag T0
     int count;
     void* Tbuf;
     rval = mb.tag_iterate(Ttag0, verts.begin(), verts.end(), count, Tbuf);
     CHECK_ERR(rval);
     CHECK_EQUAL((size_t)count, verts.size());
 
+    // Check first level values at some vertices
     const double eps = 0.0001;
     double* data = (double*) Tbuf;
     CHECK_REAL_EQUAL(233.1136, data[0 * 26], eps); // First vert

diff --git a/test/parallel/ucdtrvpart.cpp b/test/parallel/ucdtrvpart.cpp
index abf52c5..17b478f 100644
--- a/test/parallel/ucdtrvpart.cpp
+++ b/test/parallel/ucdtrvpart.cpp
@@ -3,7 +3,7 @@
 #include "moab/ParallelComm.hpp"
 #include "moab/ProgOptions.hpp"
 #include "MBParallelConventions.h"
-#include "moab/Util.hpp"
+#include "moab/ReadUtilIface.hpp"
 
 using namespace moab;
 
@@ -34,8 +34,6 @@ int main(int argc, char* argv[])
 
 void test_read_parallel_ucd_trivial()
 {
-  // Disable spectral mesh for the time being, it is not ready yet
-  //partition_method = std::string(";PARTITION_METHOD=TRIVIAL_PARTITION;SPECTRAL_MESH;PARALLEL_RESOLVE_SHARED_ENTS");
   partition_method = std::string(";PARTITION_METHOD=TRIVIAL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS");
   test_read_parallel(3458, true);
 }
@@ -56,10 +54,14 @@ void test_read_parallel(int num_verts, bool test_nb_nodes)
   CHECK_ERR(rval);
 
   std::string opt = std::string("PARALLEL=READ_PART") + partition_method;
+  // Create gather set in processor 0
+  opt += std::string(";GATHER_SET=0");
   rval = mb.load_file(example, &file_set, opt.c_str());
   CHECK_ERR(rval);
 
   ParallelComm* pcomm = ParallelComm::get_pcomm(&mb, 0);
+  int procs = pcomm->proc_config().proc_size();
+  int rank = pcomm->proc_config().proc_rank();
 
   rval = pcomm->check_all_shared_handles();
   CHECK_ERR(rval);
@@ -68,23 +70,57 @@ void test_read_parallel(int num_verts, bool test_nb_nodes)
   Range verts;
   rval = mb.get_entities_by_type(0, MBVERTEX, verts);
   CHECK_ERR(rval);
+
+  int my_num = verts.size();
+  if (test_nb_nodes && 2 == procs) {
+    if (0 == rank)
+      CHECK_EQUAL(5283, my_num); // Gather set vertices included
+    else if (1 == rank)
+      CHECK_EQUAL(1825, my_num); // Not owned vertices included
+  }
+
   rval = pcomm->filter_pstatus(verts, PSTATUS_NOT_OWNED, PSTATUS_NOT);
   CHECK_ERR(rval);
 
-  int rank = pcomm->proc_config().proc_rank();
+  my_num = verts.size();
+  if (test_nb_nodes && 2 == procs) {
+    if (0 == rank)
+      CHECK_EQUAL(5283, my_num); // Gather set vertices included
+    else if (1 == rank)
+      CHECK_EQUAL(1633, my_num); // Not owned vertices excluded
+  }
+
   if (0 == rank) {
-    // Remove from verts the gather set ents
+    // Get gather set
     EntityHandle gather_set;
-    Range gth_ents;
-    rval = Util::gather_set_entities(&mb, gather_set, gth_ents);
+    ReadUtilIface* readUtilIface;
+    rval = mb.query_interface(readUtilIface);
+    CHECK_ERR(rval);
+    rval = readUtilIface->get_gather_set(gather_set);
+    CHECK_ERR(rval);
+
+    // Get gather set entities
+    Range gather_ents;
+    rval = mb.get_entities_by_handle(gather_set, gather_ents);
     CHECK_ERR(rval);
-    verts = subtract(verts, gth_ents);
+
+    // Remove gather set vertices in processor 0
+    verts = subtract(verts, gather_ents);
+  }
+
+  my_num = verts.size();
+  if (test_nb_nodes && 2 == procs) {
+    if (0 == rank)
+      CHECK_EQUAL(1825, my_num); // Gather set vertices excluded
+    else if (1 == rank)
+      CHECK_EQUAL(1633, my_num); // Not owned vertices excluded
   }
 
-  int my_num = verts.size(), total_verts;
   std::cout << "proc: " << rank << " verts:" << my_num << "\n";
+
+  int total_verts;
   MPI_Reduce(&my_num, &total_verts, 1, MPI_INTEGER, MPI_SUM, 0, pcomm->proc_config().proc_comm());
-  
+
   if (0 == rank) {
     std::cout << "total vertices: " << total_verts << "\n";
     if (test_nb_nodes)
@@ -109,7 +145,9 @@ void test_multiple_loads_of_same_file()
   rval = mb.load_file(example, &file_set, opts.c_str());
   CHECK_ERR(rval);
 
-  opts="PARALLEL=READ_PART;PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;PARTITION_METHOD=TRIVIAL_PARTITION;VARIABLE=";
+  opts = "PARALLEL=READ_PART;PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;PARTITION_METHOD=TRIVIAL_PARTITION;VARIABLE=";
+  // Create gather set in processor 1
+  opts += std::string(";GATHER_SET=1");
   rval = mb.load_file(example, &file_set, opts.c_str());
   CHECK_ERR(rval);
 
@@ -120,6 +158,7 @@ void test_multiple_loads_of_same_file()
   // Check values of tag T0 (first level) at some strategically chosen places below
   ParallelComm* pcomm = ParallelComm::get_pcomm(&mb, 0);
   int procs = pcomm->proc_config().proc_size();
+  int rank = pcomm->proc_config().proc_rank();
 
   // Make check runs this test in two processors
   if (2 == procs) {
@@ -127,16 +166,35 @@ void test_multiple_loads_of_same_file()
     rval = mb.get_entities_by_type(0, MBVERTEX, verts);
     CHECK_ERR(rval);
 
-    int rank = pcomm->proc_config().proc_rank();
-    if (0 == rank) {
-      // Remove from verts the gather set ents
+    int my_num = verts.size();
+    if (0 == rank)
+      CHECK_EQUAL(1825, my_num);
+    else if (1 == rank)
+      CHECK_EQUAL(5283, my_num); // Gather set vertices included; Not owned vertices included
+
+    if (1 == rank) {
+      // Get gather set
       EntityHandle gather_set;
-      Range gth_ents;
-      rval = Util::gather_set_entities(&mb, gather_set, gth_ents);
+      ReadUtilIface* readUtilIface;
+      rval = mb.query_interface(readUtilIface);
+      CHECK_ERR(rval);
+      rval = readUtilIface->get_gather_set(gather_set);
+      CHECK_ERR(rval);
+
+      // Get gather set entities
+      Range gather_ents;
+      rval = mb.get_entities_by_handle(gather_set, gather_ents);
       CHECK_ERR(rval);
-      verts = subtract(verts, gth_ents);
+
+      // Remove gather set vertices in processor 1
+      verts = subtract(verts, gather_ents);
     }
-    CHECK_EQUAL((size_t)1825, verts.size());
+
+    my_num = verts.size();
+    if (0 == rank)
+      CHECK_EQUAL(1825, my_num);
+    else if (1 == rank)
+      CHECK_EQUAL(1825, my_num); // Gather set vertices excluded; Not owned vertices included
 
     Tag Ttag0;
     rval = mb.tag_get_handle("T0", 26, MB_TYPE_DOUBLE, Ttag0, MB_TAG_DENSE);
@@ -146,7 +204,7 @@ void test_multiple_loads_of_same_file()
     void* Tbuf;
     rval = mb.tag_iterate(Ttag0, verts.begin(), verts.end(), count, Tbuf);
     CHECK_ERR(rval);
-    CHECK_EQUAL((size_t)count, verts.size());
+    CHECK_EQUAL(count, my_num);
 
     const double eps = 0.0001;
     double* data = (double*) Tbuf;

Repository URL: https://bitbucket.org/fathomteam/moab/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.


More information about the moab-dev mailing list