[MOAB-dev] r3033 - MOAB/trunk

kraftche at mcs.anl.gov kraftche at mcs.anl.gov
Mon Jul 20 18:23:19 CDT 2009


Author: kraftche
Date: 2009-07-20 18:23:19 -0500 (Mon, 20 Jul 2009)
New Revision: 3033

Modified:
   MOAB/trunk/MBCN.cpp
   MOAB/trunk/MBCN.hpp
   MOAB/trunk/MBSkinner.cpp
Log:
Fix bug: Skinner can't skin edges (e.g. find end vertices of a chain of edges.)

Add new version of MBCN::SubEntityVertexIndices that is a little faster than 
 the old one (avoids coping data) as a compromise for removing the
 direct access to MBCN internals that was broken in the skinner.

Add unit tests for skinning edges, faces, and regions (three separate tests.)



Modified: MOAB/trunk/MBCN.cpp
===================================================================
--- MOAB/trunk/MBCN.cpp	2009-07-20 18:58:58 UTC (rev 3032)
+++ MOAB/trunk/MBCN.cpp	2009-07-20 23:23:19 UTC (rev 3033)
@@ -47,6 +47,11 @@
     MBDimensionPair(MBMAXTYPE, MBMAXTYPE)
 };
 
+short MBCN::increasingInts[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
+                                10,11,12,13,14,15,16,17,18,19,
+                                20,21,22,23,24,25,26,27,28,29,
+                                30,31,32,33,34,35,36,37,38,39 };
+
   //! set the basis of the numbering system; may or may not do things besides setting the
 //! member variable
 void MBCN::SetBasis(const int in_basis) 

Modified: MOAB/trunk/MBCN.hpp
===================================================================
--- MOAB/trunk/MBCN.hpp	2009-07-20 18:58:58 UTC (rev 3032)
+++ MOAB/trunk/MBCN.hpp	2009-07-20 23:23:19 UTC (rev 3033)
@@ -66,6 +66,8 @@
 //! switch the basis
   static void SwitchBasis(const int old_basis, const int new_basis);
   
+  static short increasingInts[];
+  
 public:
 
   enum { MAX_NODES_PER_ELEMENT = 27 };
@@ -176,6 +178,17 @@
                                      const int sub_index,
                                      int sub_entity_conn[]);
   
+  //! return the vertex indices of the specified sub-entity.
+  //! \param this_type Type of entity for which sub-entity connectivity is being queried
+  //! \param sub_dimension Dimension of sub-entity
+  //! \param sub_index Index of sub-entity
+  //! \param num_sub_ent_vertices the number of vertices in the sub-entity
+  static const short* SubEntityVertexIndices( const MBEntityType this_type, 
+                                              const int sub_dimension,
+                                              const int sub_index,
+                                              MBEntityType& sub_type,
+                                              int& num_sub_ent_vertices );
+  
   //! return the node indices of the specified sub-entity.
   //! \param this_topo            The topology of the queried element type
   //! \param num_nodes            The number of nodes in the queried element type.
@@ -468,6 +481,25 @@
           (Dimension(this_type) == sub_dimension && 0 == index ? this_type :
           mConnectivityMap[this_type][sub_dimension-1].target_type[index]));
 }
+
+inline const short* MBCN::SubEntityVertexIndices( const MBEntityType this_type, 
+                                                  const int sub_dimension,
+                                                  const int index,
+                                                  MBEntityType& sub_type,
+                                                  int& n ) 
+{
+  if (sub_dimension == 0) {
+    n = 1;
+    sub_type = MBVERTEX;
+    return increasingInts + index;
+  }
+  else {
+    const MBCN::ConnMap& map = mConnectivityMap[this_type][sub_dimension-1];
+    sub_type = map.target_type[index];
+    n = map.num_corners_per_sub_element[index];
+    return map.conn[index];
+  }
+}
   
   //! return the connectivity of the specified sub-entity.
 inline void MBCN::SubEntityVertexIndices(const MBEntityType this_type, 
@@ -475,11 +507,10 @@
                                          const int index,
                                          int sub_entity_conn[]) 
 {
-  for (int i = 0; i < VerticesPerEntity(SubEntityType(this_type, sub_dimension, index)); i++)
-    sub_entity_conn[i] = (MBVERTEX == this_type && 0 == sub_dimension && 
-                          0 == index) ? 0 : 
-      (0 == sub_dimension ? index :
-      mConnectivityMap[this_type][sub_dimension-1].conn[index][i]);
+  MBEntityType type;
+  int n;
+  const short* indices = SubEntityVertexIndices( this_type, sub_dimension, index, type, n );
+  std::copy( indices, indices+n, sub_entity_conn );
 }
 
 inline bool MBCN::HasMidEdgeNodes(const MBEntityType this_type, 

Modified: MOAB/trunk/MBSkinner.cpp
===================================================================
--- MOAB/trunk/MBSkinner.cpp	2009-07-20 18:58:58 UTC (rev 3032)
+++ MOAB/trunk/MBSkinner.cpp	2009-07-20 23:23:19 UTC (rev 3033)
@@ -90,7 +90,8 @@
       result = thisMB->tag_set_data(mDeletableMBTag, &(*iter), 1, &bit);
       assert(MB_SUCCESS == result);
         // add adjacency information too
-      add_adjacency(*iter);
+      if (TYPE_FROM_HANDLE(*iter) != MBVERTEX)
+        add_adjacency(*iter);
     }
   }
 }
@@ -265,47 +266,39 @@
 
   MBRange::const_iterator iter, end_iter;
   end_iter = source_entities.end();
-  const MBEntityHandle *tmp_conn, *conn;
+  const MBEntityHandle *conn;
   MBEntityHandle match;
 
   direction direct;
   MBErrorCode result;
     // assume we'll never have more than 32 vertices on a facet (checked
     // with assert later)
-  static MBEntityHandle sub_conn[32];
-  static std::vector<MBEntityHandle> tmp_conn_vec;
-  int num_nodes;
+  MBEntityHandle sub_conn[32];
+  std::vector<MBEntityHandle> tmp_conn_vec;
+  int num_nodes, num_sub_nodes, num_sides;
+  const short *sub_indices;
+  MBEntityType sub_type;
 
   // for each source entity
   for(iter = source_entities.begin(); iter != end_iter; ++iter)
   {
     // get the connectivity of this entity
-    result = thisMB->get_connectivity(*iter, tmp_conn, num_nodes, false);
-    if (MB_SUCCESS == result)
-      conn = tmp_conn;
-    else {
-        // that didn't work, possibly because it's a structured mesh
-        // which doesn't store connectivity explicitly; use a connect
-        // vector instead
-      tmp_conn_vec.clear();
-      result = thisMB->get_connectivity(&(*iter), 1, tmp_conn_vec, false);
-      if (MB_SUCCESS != result) return MB_FAILURE;
-      conn = &tmp_conn_vec[0];
-      num_nodes = tmp_conn_vec.size();
-    }
+    result = thisMB->get_connectivity(*iter, conn, num_nodes, false, &tmp_conn_vec);
+    if (MB_SUCCESS != result)
+      return result;
     
     type = thisMB->type_from_handle(*iter);
     MBRange::iterator seek_iter;
     MBRange dum_elems, dum_sub_elems;
     
     // get connectivity of each n-1 dimension entity
-    const struct MBCN::ConnMap* conn_map = &(MBCN::mConnectivityMap[type][mTargetDim-1]);
-    for(int i=0; i<conn_map->num_sub_elements; i++)
+    num_sides = MBCN::NumSubEntities( type, mTargetDim );
+    for(int i=0; i<num_sides; i++)
     {
-      int num_sub_nodes = conn_map->num_corners_per_sub_element[i];
+      sub_indices = MBCN::SubEntityVertexIndices( type, mTargetDim, i, sub_type, num_sub_nodes );
       assert(num_sub_nodes <= 32);
       for(int j=0; j<num_sub_nodes; j++)
-        sub_conn[j] = conn[conn_map->conn[i][j]];
+        sub_conn[j] = conn[sub_indices[j]];
       
       if (use_adjs) {
         dum_elems.clear();
@@ -365,8 +358,8 @@
         
           // see if we can match this connectivity with
           // an existing entity
-        find_match( conn_map->target_type[i], sub_conn, num_sub_nodes, match, direct );
-  
+        find_match( sub_type, sub_conn, num_sub_nodes, match, direct );
+        
           // if there is no match, create a new entity
         if(match == 0)
         {
@@ -437,6 +430,12 @@
 {
   match = 0;
 
+  if (type == MBVERTEX) {
+    match = *conn;
+    direct = FORWARD;
+    return;
+  }
+
   const MBEntityHandle *iter = std::min_element(conn, conn+num_nodes);
 
   std::vector<MBEntityHandle> *adj = NULL;
@@ -646,13 +645,17 @@
   end_iter = boundary.end();
 
   std::vector<MBEntityHandle> conn;
-  static MBEntityHandle sub_conn[32];
+  static MBEntityHandle sub_conn[2];
   MBEntityHandle match;
 
   MBRange edge_list;
   MBRange boundary_nodes;
   MBSkinner::direction direct;
   
+  MBEntityType sub_type;
+  int num_edge, num_sub_ent_vert;
+  const short* edge_verts;
+  
   // now, process each entity in the boundary
 
   for(iter = boundary.begin(); iter != end_iter; ++iter)
@@ -670,16 +673,18 @@
     
     // get connectivity of each n-1 dimension entity (edge in this case)
     const struct MBCN::ConnMap* conn_map = &(MBCN::mConnectivityMap[type][0]);
-    for(int i=0; i<conn_map->num_sub_elements; i++)
+    num_edge = MBCN::NumSubEntities( type, 1 );
+    for(int i=0; i<num_edge; i++)
     {
+      edge_verts = MBCN::SubEntityVertexIndices( type, 1, i, sub_type, num_sub_ent_vert );
+      assert( sub_type == MBEDGE && num_sub_ent_vert == 2 );
+      sub_conn[0] = conn[edge_verts[0]];
+      sub_conn[1] = conn[edge_verts[1]];
       int num_sub_nodes = conn_map->num_corners_per_sub_element[i];
-      assert(num_sub_nodes <= 32);
-      for(int j=0; j<num_sub_nodes; j++)
-        sub_conn[j] = conn[conn_map->conn[i][j]];
       
       // see if we can match this connectivity with
       // an existing entity
-      find_match( conn_map->target_type[i], sub_conn, num_sub_nodes, match, direct );
+      find_match( MBEDGE, sub_conn, num_sub_nodes, match, direct );
   
       // if there is no match, create a new entity
       if(match == 0)



More information about the moab-dev mailing list