MOAB: Mesh Oriented datABase
(version 5.4.1)
|
#include "moab/Core.hpp"
#include "moab/CartVect.hpp"
#include "moab/AdaptiveKDTree.hpp"
#include "moab/GeomUtil.hpp"
#include "Internals.hpp"
#include "moab/Range.hpp"
#include "moab/FileOptions.hpp"
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <limits>
#include <sstream>
#include <cstdlib>
#include <ctime>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
Go to the source code of this file.
Functions | |
std::string | clock_to_string (clock_t t) |
std::string | mem_to_string (unsigned long mem) |
void | build_tree (Interface *interface, const Range &elems, FileOptions &opts) |
void | build_grid (Interface *iface, const double dims[3]) |
void | delete_existing_tree (Interface *interface) |
void | print_stats (Interface *interface) |
void | tag_elements (Interface *interface) |
void | tag_vertices (Interface *interface) |
void | write_tree_blocks (Interface *interface, const char *file) |
static void | usage (bool err=true) |
static int | parseint (int &i, int argc, char *argv[]) |
static void | parsedims (int &i, int argc, char *argv[], double dims[3]) |
int | main (int argc, char *argv[]) |
static int | hash_handle (EntityHandle handle) |
Variables | |
const int | MAX_TAG_VALUE = 32 |
const char * | TAG_NAME = "TREE_CELL" |
void build_grid | ( | Interface * | iface, |
const double | dims[3] | ||
) |
Definition at line 386 of file kd_tree_tool.cpp.
References moab::AdaptiveKDTreeIter::box_max(), moab::AdaptiveKDTreeIter::box_min(), moab::AdaptiveKDTree::Plane::coord, moab::Tree::create_root(), moab::AdaptiveKDTreeIter::depth(), ErrorCode, moab::Tree::get_max_depth(), moab::AdaptiveKDTree::get_tree_iterator(), MB_ENTITY_NOT_FOUND, MB_SUCCESS, moab::AdaptiveKDTree::Plane::norm, moab::AdaptiveKDTree::split_leaf(), and moab::AdaptiveKDTreeIter::step().
Referenced by main().
{ ErrorCode rval; EntityHandle root = 0; AdaptiveKDTree tool( interface ); AdaptiveKDTreeIter iter; AdaptiveKDTree::Plane plane; double min[3] = { -0.5 * dims[0], -0.5 * dims[1], -0.5 * dims[2] }; double max[3] = { 0.5 * dims[0], 0.5 * dims[1], 0.5 * dims[2] }; rval = tool.create_root( min, max, root ); if( MB_SUCCESS != rval || !root ) { std::cerr << "Failed to create tree root." << std::endl; exit( 4 ); } rval = tool.get_tree_iterator( root, iter ); if( MB_SUCCESS != rval ) { std::cerr << "Failed to get tree iterator." << std::endl; } do { while( iter.depth() < tool.get_max_depth() ) { plane.norm = iter.depth() % 3; plane.coord = 0.5 * ( iter.box_min()[plane.norm] + iter.box_max()[plane.norm] ); rval = tool.split_leaf( iter, plane ); if( MB_SUCCESS != rval ) { std::cerr << "Failed to split tree leaf at depth " << iter.depth() << std::endl; exit( 4 ); } } } while( ( rval = iter.step() ) == MB_SUCCESS ); if( rval != MB_ENTITY_NOT_FOUND ) { std::cerr << "Error stepping KDTree iterator." << std::endl; exit( 4 ); } }
void build_tree | ( | Interface * | interface, |
const Range & | elems, | ||
FileOptions & | opts | ||
) |
Definition at line 373 of file kd_tree_tool.cpp.
References moab::Range::empty().
{ EntityHandle root = 0; if( elems.empty() ) { std::cerr << "No elements from which to build tree." << std::endl; exit( 4 ); } AdaptiveKDTree tool( interface, elems, &root, &opts ); }
std::string clock_to_string | ( | clock_t | t | ) |
Definition at line 431 of file kd_tree_tool.cpp.
References buffer, and moab::unit().
Referenced by main().
{ char unit[5] = "s"; char buffer[256]; double dt = t / (double)CLOCKS_PER_SEC; // if (dt > 300) { // dt /= 60; // strcpy( unit, "min" ); //} // if (dt > 300) { // dt /= 60; // strcpy( unit, "hr" ); //} // if (dt > 100) { // dt /= 24; // strcpy( unit, "days" ); //} sprintf( buffer, "%0.2f%s", dt, unit ); return buffer; }
void delete_existing_tree | ( | Interface * | interface | ) |
Definition at line 354 of file kd_tree_tool.cpp.
References moab::Range::begin(), moab::Range::clear(), moab::Range::empty(), moab::Range::end(), moab::Tree::find_all_trees(), and moab::AdaptiveKDTree::reset_tree().
Referenced by main().
{ Range trees; AdaptiveKDTree tool( interface ); tool.find_all_trees( trees ); if( !trees.empty() ) std::cout << "Destroying existing tree(s) contained in file" << std::endl; for( Range::iterator i = trees.begin(); i != trees.end(); ++i ) tool.reset_tree(); trees.clear(); tool.find_all_trees( trees ); if( !trees.empty() ) { std::cerr << "Failed to destroy existing trees. Aborting" << std::endl; exit( 5 ); } }
static int hash_handle | ( | EntityHandle | handle | ) | [static] |
Definition at line 452 of file kd_tree_tool.cpp.
References moab::ID_FROM_HANDLE(), and MAX_TAG_VALUE.
Referenced by tag_elements(), tag_vertices(), and write_tree_blocks().
{ EntityID h = ID_FROM_HANDLE( handle ); return (int)( ( h * 13 + 7 ) % MAX_TAG_VALUE ) + 1; }
int main | ( | int | argc, |
char * | argv[] | ||
) |
Definition at line 155 of file kd_tree_tool.cpp.
References build_grid(), build_time, build_tree(), clock_to_string(), delete_existing_tree(), moab::Range::empty(), ErrorCode, moab::Tree::find_all_trees(), input_file, load_time, MB_SUCCESS, moab::Range::merge(), parsedims(), parseint(), moab::AdaptiveKDTree::print(), moab::Range::size(), moab::AdaptiveKDTree::SUBDIVISION, moab::AdaptiveKDTree::SUBDIVISION_SNAP, tag_elements(), tag_time(), tag_vertices(), usage, moab::AdaptiveKDTree::VERTEX_MEDIAN, moab::AdaptiveKDTree::VERTEX_SAMPLE, and write_tree_blocks().
{ bool surf_elems = false, vol_elems = false; const char* input_file = 0; const char* output_file = 0; const char* tree_file = 0; std::ostringstream options; bool tag_elems = false; clock_t load_time, build_time, stat_time, tag_time, write_time, block_time; bool make_grid = false; double dims[3]; for( int i = 1; i < argc; ++i ) { if( argv[i][0] != '-' ) { if( !input_file ) input_file = argv[i]; else if( !output_file ) output_file = argv[i]; else usage(); continue; } if( !argv[i][1] || argv[i][2] ) usage(); switch( argv[i][1] ) { case '2': surf_elems = true; break; case '3': vol_elems = true; break; case 'S': options << "MESHSET_FLAGS=" << MESHSET_ORDERED << ";"; break; case 's': break; case 'd': options << "MAX_DEPTH=" << parseint( i, argc, argv ) << ";"; break; case 'n': options << "MAX_PER_LEAF=" << parseint( i, argc, argv ) << ";"; break; case 'u': options << "CANDIDATE_PLANE_SET=" << AdaptiveKDTree::SUBDIVISION << ";"; break; case 'p': options << "CANDIDATE_PLANE_SET=" << AdaptiveKDTree::SUBDIVISION_SNAP << ";"; break; case 'm': options << "CANDIDATE_PLANE_SET=" << AdaptiveKDTree::VERTEX_MEDIAN << ";"; break; case 'v': options << "CANDIDATE_PLANE_SET=" << AdaptiveKDTree::VERTEX_SAMPLE << ";"; break; case 'N': options << "SPLITS_PER_DIR=" << parseint( i, argc, argv ) << ";"; break; case 't': tag_elems = true; break; case 'T': tree_file = argv[++i]; break; case 'G': make_grid = true; parsedims( i, argc, argv, dims ); break; case 'h': usage( false ); break; default: usage(); } } // this test relies on not cleaning up trees options << "CLEAN_UP=false;"; if( make_grid != !output_file ) usage(); // default to both if( !surf_elems && !vol_elems ) surf_elems = vol_elems = true; ErrorCode rval; Core moab_core; Interface* interface = &moab_core; FileOptions opts( options.str().c_str() ); if( make_grid ) { load_time = 0; output_file = input_file; input_file = 0; build_time = clock(); build_grid( interface, dims ); build_time = clock() - build_time; } else { load_time = clock(); rval = interface->load_mesh( input_file ); if( MB_SUCCESS != rval ) { std::cerr << "Error reading file: " << input_file << std::endl; exit( 2 ); } load_time = clock() - load_time; delete_existing_tree( interface ); std::cout << "Building tree..." << std::endl; build_time = clock(); Range elems; if( !surf_elems ) { interface->get_entities_by_dimension( 0, 3, elems ); } else { interface->get_entities_by_dimension( 0, 2, elems ); if( vol_elems ) { Range tmp; interface->get_entities_by_dimension( 0, 3, tmp ); elems.merge( tmp ); } } build_tree( interface, elems, opts ); build_time = clock() - build_time; } std::cout << "Calculating stats..." << std::endl; AdaptiveKDTree tool( interface ); Range range; tool.find_all_trees( range ); if( range.size() != 1 ) { if( range.empty() ) std::cerr << "Internal error: Failed to retreive tree." << std::endl; else std::cerr << "Internal error: Multiple tree roots." << std::endl; exit( 5 ); } tool.print(); stat_time = clock() - build_time; if( tag_elems ) { std::cout << "Tagging tree..." << std::endl; tag_elements( interface ); tag_vertices( interface ); } tag_time = clock() - stat_time; std::cout << "Writing file... "; std::cout.flush(); rval = interface->write_mesh( output_file ); if( MB_SUCCESS != rval ) { std::cerr << "Error writing file: " << output_file << std::endl; exit( 3 ); } write_time = clock() - tag_time; std::cout << "Wrote " << output_file << std::endl; if( tree_file ) { std::cout << "Writing tree block rep..."; std::cout.flush(); write_tree_blocks( interface, tree_file ); std::cout << "Wrote " << tree_file << std::endl; } block_time = clock() - write_time; std::cout << "Times: " << " Load" << " Build" << " Stats" << " Write"; if( tag_elems ) std::cout << "Tag Sets"; if( tree_file ) std::cout << "Block "; std::cout << std::endl; std::cout << " " << std::setw( 8 ) << clock_to_string( load_time ) << std::setw( 8 ) << clock_to_string( build_time ) << std::setw( 8 ) << clock_to_string( stat_time ) << std::setw( 8 ) << clock_to_string( write_time ); if( tag_elems ) std::cout << std::setw( 8 ) << clock_to_string( tag_time ); if( tree_file ) std::cout << std::setw( 8 ) << clock_to_string( block_time ); std::cout << std::endl; return 0; }
std::string mem_to_string | ( | unsigned long | mem | ) |
Definition at line 360 of file obb_tree_tool.cpp.
References buffer, and moab::unit().
{ char unit[3] = "B"; if( mem > 9 * 1024 ) { mem = ( mem + 512 ) / 1024; strcpy( unit, "kB" ); } if( mem > 9 * 1024 ) { mem = ( mem + 512 ) / 1024; strcpy( unit, "MB" ); } if( mem > 9 * 1024 ) { mem = ( mem + 512 ) / 1024; strcpy( unit, "GB" ); } char buffer[256]; sprintf( buffer, "%lu %s", mem, unit ); return buffer; }
static void parsedims | ( | int & | i, |
int | argc, | ||
char * | argv[], | ||
double | dims[3] | ||
) | [static] |
Definition at line 116 of file kd_tree_tool.cpp.
References moab::error(), and usage.
Referenced by main().
{ char* end; ++i; if( i == argc ) { std::cerr << "Expected value following '" << argv[i - 1] << "'" << std::endl; usage(); } dims[0] = strtod( argv[i], &end ); if( *end == '\0' ) { dims[2] = dims[1] = dims[0]; return; } else if( *end != 'x' && *end != 'X' ) goto error; ++end; dims[1] = strtod( end, &end ); if( *end == '\0' ) { dims[2] = dims[1]; return; } else if( *end != 'x' && *end != 'X' ) goto error; ++end; dims[2] = strtod( end, &end ); if( *end != '\0' ) goto error; return; error: std::cerr << "Invaild dimension specification." << std::endl; usage(); }
static int parseint | ( | int & | i, |
int | argc, | ||
char * | argv[] | ||
) | [static] |
Definition at line 96 of file kd_tree_tool.cpp.
References usage.
Referenced by main().
{ char* end; ++i; if( i == argc ) { std::cerr << "Expected value following '" << argv[i - 1] << "'" << std::endl; usage(); } int result = strtol( argv[i], &end, 0 ); if( result < 0 || *end ) { std::cerr << "Expected positive integer following '" << argv[i - 1] << "'" << std::endl; usage(); } return result; }
void print_stats | ( | Interface * | interface | ) |
Definition at line 410 of file obb_tree_tool.cpp.
References moab::Range::begin(), moab::Range::end(), moab::Range::erase(), ErrorCode, moab::Interface::estimated_memory_use(), moab::Interface::get_entities_by_type(), moab::Interface::get_number_entities_by_type(), get_root(), moab::Range::insert(), MB_SUCCESS, MBENTITYSET, MBTRI, MBVERTEX, moab::mem_to_string(), memory_use(), moab::Range::merge(), and moab::OrientedBoxTreeTool::stats().
{ EntityHandle root; Range range; ErrorCode rval; rval = get_root( interface, root ); if( MB_SUCCESS != rval ) { std::cerr << "Internal error: Failed to retrieve root." << std::endl; exit( 5 ); } OrientedBoxTreeTool tool( interface ); Range tree_sets, triangles, verts; // interface->get_child_meshsets( root, tree_sets, 0 ); interface->get_entities_by_type( 0, MBENTITYSET, tree_sets ); tree_sets.erase( tree_sets.begin(), Range::lower_bound( tree_sets.begin(), tree_sets.end(), root ) ); interface->get_entities_by_type( 0, MBTRI, triangles ); interface->get_entities_by_type( 0, MBVERTEX, verts ); triangles.merge( verts ); tree_sets.insert( root ); unsigned long long set_used, set_amortized, set_store_used, set_store_amortized, set_tag_used, set_tag_amortized, tri_used, tri_amortized; interface->estimated_memory_use( tree_sets, &set_used, &set_amortized, &set_store_used, &set_store_amortized, 0, 0, 0, 0, &set_tag_used, &set_tag_amortized ); interface->estimated_memory_use( triangles, &tri_used, &tri_amortized ); int num_tri = 0; interface->get_number_entities_by_type( 0, MBTRI, num_tri ); tool.stats( root, std::cout ); unsigned long long real_rss, real_vsize; memory_use( real_vsize, real_rss ); printf( "------------------------------------------------------------------\n" ); printf( "\nmemory: used amortized\n" ); printf( " ---------- ----------\n" ); printf( "triangles %10s %10s\n", mem_to_string( tri_used ).c_str(), mem_to_string( tri_amortized ).c_str() ); printf( "sets (total)%10s %10s\n", mem_to_string( set_used ).c_str(), mem_to_string( set_amortized ).c_str() ); printf( "sets %10s %10s\n", mem_to_string( set_store_used ).c_str(), mem_to_string( set_store_amortized ).c_str() ); printf( "set tags %10s %10s\n", mem_to_string( set_tag_used ).c_str(), mem_to_string( set_tag_amortized ).c_str() ); printf( "total real %10s %10s\n", mem_to_string( real_rss ).c_str(), mem_to_string( real_vsize ).c_str() ); printf( "------------------------------------------------------------------\n" ); }
void tag_elements | ( | Interface * | interface | ) |
Definition at line 458 of file kd_tree_tool.cpp.
References moab::Range::begin(), moab::Range::clear(), moab::Range::empty(), moab::Tree::find_all_trees(), moab::Interface::get_entities_by_handle(), moab::AdaptiveKDTree::get_tree_iterator(), moab::AdaptiveKDTreeIter::handle(), hash_handle(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, moab::Range::size(), moab::AdaptiveKDTreeIter::step(), moab::Interface::tag_get_handle(), TAG_NAME, and moab::Interface::tag_set_data().
Referenced by main().
{ EntityHandle root; Range range; AdaptiveKDTree tool( moab ); tool.find_all_trees( range ); if( range.size() != 1 ) { if( range.empty() ) std::cerr << "Internal error: Failed to retreive tree." << std::endl; else std::cerr << "Internal error: Multiple tree roots." << std::endl; exit( 5 ); } root = *range.begin(); range.clear(); Tag tag; int zero = 0; moab->tag_get_handle( TAG_NAME, 1, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_CREAT, &zero ); AdaptiveKDTreeIter iter; tool.get_tree_iterator( root, iter ); std::vector< int > tag_vals; do { range.clear(); moab->get_entities_by_handle( iter.handle(), range ); tag_vals.clear(); tag_vals.resize( range.size(), hash_handle( iter.handle() ) ); moab->tag_set_data( tag, range, &tag_vals[0] ); } while( MB_SUCCESS == iter.step() ); }
void tag_vertices | ( | Interface * | interface | ) |
Definition at line 495 of file kd_tree_tool.cpp.
References moab::CartVect::array(), moab::Range::begin(), moab::AdaptiveKDTreeIter::box_max(), moab::AdaptiveKDTreeIter::box_min(), moab::GeomUtil::box_point_overlap(), moab::Range::clear(), moab::Range::empty(), moab::Tree::find_all_trees(), moab::Interface::get_adjacencies(), moab::Interface::get_coords(), moab::Interface::get_entities_by_handle(), moab::AdaptiveKDTree::get_tree_iterator(), moab::AdaptiveKDTreeIter::handle(), hash_handle(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, moab::Range::size(), moab::AdaptiveKDTreeIter::step(), moab::Interface::tag_get_handle(), TAG_NAME, moab::Interface::tag_set_data(), and moab::Interface::UNION.
Referenced by main().
{ EntityHandle root; Range range; AdaptiveKDTree tool( moab ); tool.find_all_trees( range ); if( range.size() != 1 ) { if( range.empty() ) std::cerr << "Internal error: Failed to retreive tree." << std::endl; else std::cerr << "Internal error: Multiple tree roots." << std::endl; exit( 5 ); } root = *range.begin(); range.clear(); Tag tag; int zero = 0; moab->tag_get_handle( TAG_NAME, 1, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_CREAT, &zero ); AdaptiveKDTreeIter iter; tool.get_tree_iterator( root, iter ); do { range.clear(); moab->get_entities_by_handle( iter.handle(), range ); int tag_val = hash_handle( iter.handle() ); Range verts; moab->get_adjacencies( range, 0, false, verts, Interface::UNION ); for( Range::iterator i = verts.begin(); i != verts.end(); ++i ) { CartVect coords; moab->get_coords( &*i, 1, coords.array() ); if( GeomUtil::box_point_overlap( CartVect( iter.box_min() ), CartVect( iter.box_max() ), coords, 1e-7 ) ) moab->tag_set_data( tag, &*i, 1, &tag_val ); } } while( MB_SUCCESS == iter.step() ); }
static void usage | ( | bool | err = true | ) | [static] |
Definition at line 37 of file kd_tree_tool.cpp.
{ std::ostream& s = err ? std::cerr : std::cout; s << "kd_tree_tool [-d <int>] [-2|-3] [-n <int>] [-u|-p|-m|-v] [-N <int>] [-s|-S] <input file> " "<output file>" << std::endl << "kd_tree_tool [-d <int>] -G <dims> [-s|-S] <output file>" << std::endl << "kd_tree_tool [-h]" << std::endl; if( !err ) { s << "Tool to build adaptive kd-Tree" << std::endl; s << " -d <int> Specify maximum depth for tree. Default: 30" << std::endl << " -n <int> Specify maximum entities per leaf. Default: 6" << std::endl << " -2 Build tree from surface elements. Default: yes" << std::endl << " -3 Build tree from volume elements. Default: yes" << std::endl << " -u Use 'SUBDIVISION' scheme for tree construction" << std::endl << " -p Use 'SUBDIVISION_SNAP' tree construction algorithm." << std::endl << " -m Use 'VERTEX_MEDIAN' tree construction algorithm." << std::endl << " -v Use 'VERTEX_SAMPLE' tree construction algorithm." << std::endl << " -N <int> Specify candidate split planes per axis. Default: 3" << std::endl << " -t Tag elements will tree cell number." << std::endl << " -T Write tree boxes to file." << std::endl << " -G <dims> Generate grid - no input elements. Dims must be " << std::endl << " HxWxD or H." << std::endl << " -s Use range-based sets for tree nodes" << std::endl << " -S Use vector-based sets for tree nodes" << std::endl << std::endl; } exit( err ); }
void write_tree_blocks | ( | Interface * | interface, |
const char * | file | ||
) |
Definition at line 539 of file kd_tree_tool.cpp.
References moab::Range::begin(), moab::AdaptiveKDTreeIter::box_max(), moab::AdaptiveKDTreeIter::box_min(), moab::Range::clear(), moab::Core::create_element(), moab::Core::create_vertex(), moab::Range::empty(), moab::Tree::find_all_trees(), moab::AdaptiveKDTree::get_tree_iterator(), moab::AdaptiveKDTreeIter::handle(), hash_handle(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, MBHEX, moab::Range::size(), moab::AdaptiveKDTreeIter::step(), moab::Core::tag_get_handle(), TAG_NAME, moab::Core::tag_set_data(), and moab::Core::write_mesh().
Referenced by main().
{ EntityHandle root; Range range; AdaptiveKDTree tool( interface ); tool.find_all_trees( range ); if( range.size() != 1 ) { if( range.empty() ) std::cerr << "Internal error: Failed to retreive tree." << std::endl; else std::cerr << "Internal error: Multiple tree roots." << std::endl; exit( 5 ); } root = *range.begin(); range.clear(); Core moab2; Tag tag; int zero = 0; moab2.tag_get_handle( TAG_NAME, 1, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_CREAT, &zero ); AdaptiveKDTreeIter iter; tool.get_tree_iterator( root, iter ); do { double x1 = iter.box_min()[0]; double y1 = iter.box_min()[1]; double z1 = iter.box_min()[2]; double x2 = iter.box_max()[0]; double y2 = iter.box_max()[1]; double z2 = iter.box_max()[2]; double coords[24] = { x1, y1, z1, x2, y1, z1, x2, y2, z1, x1, y2, z1, x1, y1, z2, x2, y1, z2, x2, y2, z2, x1, y2, z2 }; EntityHandle verts[8], elem; for( int i = 0; i < 8; ++i ) moab2.create_vertex( coords + 3 * i, verts[i] ); moab2.create_element( MBHEX, verts, 8, elem ); int tag_val = hash_handle( iter.handle() ); moab2.tag_set_data( tag, &elem, 1, &tag_val ); } while( MB_SUCCESS == iter.step() ); moab2.write_mesh( file ); }
const int MAX_TAG_VALUE = 32 |
Definition at line 23 of file kd_tree_tool.cpp.
Referenced by hash_handle().
const char* TAG_NAME = "TREE_CELL" |
Definition at line 24 of file kd_tree_tool.cpp.