[MOAB-dev] r1720 - MOAB/trunk
kraftche at mcs.anl.gov
kraftche at mcs.anl.gov
Fri Mar 28 16:09:10 CDT 2008
Author: kraftche
Date: 2008-03-28 16:09:10 -0500 (Fri, 28 Mar 2008)
New Revision: 1720
Modified:
MOAB/trunk/MBCore.cpp
MOAB/trunk/MBCore.hpp
MOAB/trunk/MBTest.cpp
Log:
Provide special case implementation for range-based get_adjacencies
when (to_dimension == 0 && op == UNION). Reduces kD-tree build time
by 85%.
Modified: MOAB/trunk/MBCore.cpp
===================================================================
--- MOAB/trunk/MBCore.cpp 2008-03-28 20:06:44 UTC (rev 1719)
+++ MOAB/trunk/MBCore.cpp 2008-03-28 21:09:10 UTC (rev 1720)
@@ -996,7 +996,72 @@
return get_adjacencies(tmp_from_entities, to_dimension, create_if_missing,
adj_entities, operation_type);
}
+
+MBErrorCode MBCore::get_vertices( const MBRange& from_entities,
+ MBRange& adj_entities )
+{
+ const size_t DEFAULT_MAX_BLOCKS_SIZE = 4000;
+ const size_t MAX_OUTER_ITERATIONS = 100;
+
+ std::vector<MBEntityHandle> temp_vec, storage;
+ std::vector<MBEntityHandle>::const_iterator ti;
+ MBErrorCode result = MB_SUCCESS, tmp_result;
+ MBRange::const_iterator i = from_entities.begin();
+ MBRange::iterator ins;
+ const MBEntityHandle* conn;
+ int conn_len;
+
+ // Just copy any vertices from the input range into the output
+ size_t remaining = from_entities.size();
+ for (; i != from_entities.end() && TYPE_FROM_HANDLE(*i) == MBVERTEX; ++i)
+ --remaining;
+ adj_entities.merge( from_entities.begin(), i );
+ // How many entities to work with at once? 2000 or so shouldn't require
+ // too much memory, but don't iterate in outer loop more than a
+ // 1000 times (make it bigger if many input entiites.)
+ const size_t block_size = std::max( DEFAULT_MAX_BLOCKS_SIZE, remaining/MAX_OUTER_ITERATIONS );
+ while (remaining > 0) {
+ const size_t count = remaining > block_size ? block_size : remaining;
+ remaining -= count;
+ temp_vec.clear();
+ for (size_t j = 0; j < count; ++i, ++j) {
+ tmp_result = get_connectivity( *i, conn, conn_len, false, &storage );
+ if (MB_SUCCESS != tmp_result) {
+ result = tmp_result;
+ continue;
+ }
+
+ if (TYPE_FROM_HANDLE(*i) == MBPOLYHEDRON) {
+ storage.clear();
+ tmp_result = get_connectivity( conn, conn_len, storage );
+ if (MB_SUCCESS != tmp_result) {
+ result = tmp_result;
+ continue;
+ }
+ conn_len = storage.size();
+ conn = &storage[0];
+ }
+
+ const size_t oldsize = temp_vec.size();
+ temp_vec.resize( oldsize + conn_len );
+ memcpy( &temp_vec[oldsize], conn, sizeof(MBEntityHandle)*conn_len );
+ }
+
+ std::sort( temp_vec.begin(), temp_vec.end() );
+ ins = adj_entities.begin();
+ ti = temp_vec.begin();
+ while (ti != temp_vec.end()) {
+ MBEntityHandle first = *ti;
+ MBEntityHandle second = *ti;
+ for (++ti; ti != temp_vec.end() && (*ti - second <= 1); ++ti)
+ second = *ti;
+ ins = adj_entities.insert( ins, first, second );
+ }
+ }
+ return result;
+}
+
MBErrorCode MBCore::get_adjacencies(const MBRange &from_entities,
const int to_dimension,
const bool create_if_missing,
@@ -1009,6 +1074,11 @@
if(from_entities.size() == 0)
return MB_SUCCESS;
+ // special case for getting all vertices
+ if (to_dimension == 0 && operation_type == MBInterface::UNION) {
+ return get_vertices( from_entities, adj_entities );
+ }
+
MBRange temp_range;
std::vector<MBEntityHandle> temp_vec;
MBErrorCode result = MB_SUCCESS, tmp_result;
Modified: MOAB/trunk/MBCore.hpp
===================================================================
--- MOAB/trunk/MBCore.hpp 2008-03-28 20:06:44 UTC (rev 1719)
+++ MOAB/trunk/MBCore.hpp 2008-03-28 21:09:10 UTC (rev 1720)
@@ -276,6 +276,16 @@
MBRange &adj_entities,
const int operation_type = MBInterface::INTERSECT);
+ /**\brief Get all vertices for input entities
+ *
+ * Special case of get_adjacencies where to_dimension == 0
+ * and operation_type == MBInterface::UNION.
+ *\Note This is not a variation of get_connectivity because
+ * the behavior is different for polyhedra.
+ */
+ virtual MBErrorCode get_vertices( const MBRange& from_entities,
+ MBRange& vertices );
+
//! Adds adjacencies
/** \param from_handle entities
\param both_ways add the adjacency information to both the
Modified: MOAB/trunk/MBTest.cpp
===================================================================
--- MOAB/trunk/MBTest.cpp 2008-03-28 20:06:44 UTC (rev 1719)
+++ MOAB/trunk/MBTest.cpp 2008-03-28 21:09:10 UTC (rev 1720)
@@ -663,6 +663,69 @@
return MB_SUCCESS;
}
+MBErrorCode mb_adjacent_vertex_test( MBInterface* mb )
+{
+ MBErrorCode rval;
+ MBRange hexes, expt_vert, got_vert, some_hexes;
+ MBRange::const_iterator i, j;
+ int n;
+
+ // get all hexes
+ rval = mb->get_entities_by_type( 0, MBHEX, hexes );
+ if (rval != MB_SUCCESS)
+ return rval;
+ if (hexes.empty()) // can't do test if no elements
+ return MB_FAILURE;
+
+ // get every third hex and its vertices
+ n = 0;
+ for (i = hexes.begin(); i != hexes.end(); ++i) {
+ if (++n % 3)
+ continue;
+ some_hexes.insert( *i );
+ const MBEntityHandle* conn;
+ int len;
+ rval = mb->get_connectivity( *i, conn, len );
+ if (MB_SUCCESS != rval)
+ return rval;
+ for (int k = 0; k < len; ++k)
+ expt_vert.insert( conn[k] );
+ }
+
+ // use get_adjacencies to get vertices
+ rval = mb->get_adjacencies( some_hexes, 0, false, got_vert, MBInterface::UNION );
+ if (MB_SUCCESS != rval) {
+ std::cout << "get_adjacencies failed with error code " << rval << std::endl;
+ return rval;
+ }
+
+ i = expt_vert.begin();
+ j = got_vert.begin();
+ while (i != expt_vert.end() && j != got_vert.end()) {
+ if (*i < *j) {
+ std::cout << "Result missing vertex: " << *i << std::endl;
+ return MB_FAILURE;
+ }
+ else if (*j < *i) {
+ std::cout << "Result contains extra vertex: " << *j << std::endl;
+ return MB_FAILURE;
+ }
+ ++i;
+ ++j;
+ }
+
+ if (i != expt_vert.end()) {
+ std::cout << "Result missing vertex: " << *i << std::endl;
+ return MB_FAILURE;
+ }
+ else if (j != got_vert.end()) {
+ std::cout << "Result contains extra vertex: " << *j << std::endl;
+ return MB_FAILURE;
+ }
+
+ return MB_SUCCESS;
+}
+
MBErrorCode mb_adjacencies_test(MBInterface *mb)
{
// this test does the following:
@@ -5780,6 +5843,7 @@
cout << "\n\nMB TEST PROGRAM:\n\n";
+ RUN_TEST( mb_adjacent_vertex_test );
RUN_TEST( mb_adjacencies_test );
RUN_TEST( mb_vertex_coordinate_test );
RUN_TEST( mb_vertex_tag_test );
More information about the moab-dev
mailing list