moab
moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer > Class Template Reference

#include <element_tree.hpp>

List of all members.

Public Types

typedef _Entity_handles Entity_handles
typedef _Box Box
typedef _Moab Moab
typedef _Parametrizer Parametrizer
typedef Entity_handles::value_type Entity_handle

Public Member Functions

 Element_tree (Entity_handles &_entities, Moab &_moab, Box &_bounding_box, Parametrizer &_entity_contains)
 Element_tree (Self &s)
template<typename Vector , typename Result >
Result & find (const Vector &point, Result &result) const

Private Types

typedef Element_tree
< _Entity_handles, _Box, _Moab,
_Parametrizer > 
Self
typedef std::pair< Box,
Entity_handle
Leaf_element
typedef _element_tree::_Node
< Entity_handles, std::vector
< Leaf_element > > 
Node
typedef
common_tree::_Element_data
< Box, std::bitset< NUM_DIM
*MAX_ITERATIONS *2 > > 
Element_data
typedef std::vector< NodeNodes
typedef
std::tr1::unordered_map
< Entity_handle, Element_data
Element_map
typedef std::vector< typename
Element_map::iterator > 
Element_list
typedef
_element_tree::_Partition_data
< Box
Partition_data

Private Member Functions

template<typename Iterator , typename Split_data >
void compute_split (Iterator &begin, Iterator &end, Split_data &split_data, bool iteration=false)
template<typename Split_data >
bool update_split_line (Split_data &data) const
template<typename Iterator , typename Split_data , typename Directions >
void determine_split (Iterator &begin, Iterator &end, Split_data &data, const Directions &directions)
template<typename Iterator , typename Node_index , typename Directions , typename Partition_data >
void build_tree (Iterator begin, Iterator end, const Node_index node, const Directions &directions, Partition_data &_data, int &depth, const bool is_middle=false)
template<typename Vector , typename Node_index , typename Result >
Result & _find_point (const Vector &point, const Node_index &index, Result &result) const

Private Attributes

const Entity_handlesentity_handles_
Nodes tree_
Moabmoab
Box bounding_box
Parametrizer entity_contains

Detailed Description

template<typename _Entity_handles, typename _Box, typename _Moab, typename _Parametrizer>
class moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >

Definition at line 206 of file element_tree.hpp.


Member Typedef Documentation

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef _Box moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Box

Definition at line 211 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef common_tree::_Element_data< Box, std::bitset<NUM_DIM*MAX_ITERATIONS*2> > moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Element_data [private]

Definition at line 227 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef std::vector< typename Element_map::iterator> moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Element_list [private]

Definition at line 233 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef std::tr1::unordered_map< Entity_handle, Element_data> moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Element_map [private]

Definition at line 231 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef Entity_handles::value_type moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Entity_handle

Definition at line 214 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef _Entity_handles moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Entity_handles

Definition at line 210 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef std::pair< Box, Entity_handle> moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Leaf_element [private]

Definition at line 222 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef _Moab moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Moab

Definition at line 212 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef _element_tree::_Node< Entity_handles, std::vector< Leaf_element> > moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Node [private]

Definition at line 223 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef std::vector< Node> moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Nodes [private]

Definition at line 228 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef _Parametrizer moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Parametrizer

Definition at line 213 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef _element_tree::_Partition_data< Box> moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Partition_data [private]

Definition at line 234 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
typedef Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer> moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Self [private]

Definition at line 221 of file element_tree.hpp.


Constructor & Destructor Documentation

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Element_tree ( Entity_handles _entities,
Moab _moab,
Box _bounding_box,
Parametrizer _entity_contains 
) [inline]

Definition at line 238 of file element_tree.hpp.

                                          : 
    entity_handles_( _entities), tree_(), moab( _moab), 
    bounding_box( _bounding_box), entity_contains( _entity_contains){
    tree_.reserve( _entities.size());
    Element_map element_map( _entities.size());
    Partition_data _data;
    common_tree::construct_element_map( entity_handles_, element_map, 
                        _data.bounding_box, moab);
    bounding_box = _data.bounding_box;
    _bounding_box = bounding_box;
    Element_list element_ordering( element_map.size());
    std::size_t index = 0;
    for(typename Element_map::iterator i = element_map.begin(); 
                      i != element_map.end(); ++i, ++index){
        element_ordering[ index] = i;
    }
    //We only build nonempty trees
    if( element_ordering.size()){ 
        //initially all bits are set
        std::bitset< 3> directions( 7);
        tree_.push_back( Node());
        int depth = 0;
        build_tree( element_ordering.begin(), 
                element_ordering.end(),
                0, directions, _data, depth);
        std::cout << "depth: " << depth << std::endl; 
    }
}
template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::Element_tree ( Self s) [inline]

Definition at line 269 of file element_tree.hpp.

                       : entity_handles_( s.entity_handles_), 
             tree_( s.tree_), moab( s.moab), 
             bounding_box( s.bounding_box){}

Member Function Documentation

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
template<typename Vector , typename Node_index , typename Result >
Result& moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::_find_point ( const Vector &  point,
const Node_index &  index,
Result &  result 
) const [inline, private]

Definition at line 520 of file element_tree.hpp.

                                   {
    typedef typename Node::Entities::const_iterator Entity_iterator;
    typedef typename std::pair< bool, Vector> Return_type;
    const Node & node = tree_[ index];
    if( node.leaf()){
        //check each node
        for( Entity_iterator i = node.entities.begin(); 
                     i != node.entities.end(); ++i){
            if( common_tree::box_contains_point( i->first, point)){
                Return_type r = entity_contains( moab, 
                                     i->second, 
                                 point);
                if( r.first){ result = 
                    std::make_pair( i->second, r.second);
                }
                return result;
            }
        }
        return Result(0, point);
    }
    if( point[ node.dim] < node.left_line){
        return _find_point( point, node.left_, result);
    }else if( point[ node.dim] > node.right_line){
        return _find_point( point, node.right_, result);
    } else {
        Entity_handle middle =  _find_point( point, 
                            node.middle_, result);
        if( middle != 0){ return result; }
        if( point[ node.dim] < node.split){ 
            return _find_point( point, node.left_, result); 
        }
        return  _find_point( point, node.right_, result);
    }
}
template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
template<typename Iterator , typename Node_index , typename Directions , typename Partition_data >
void moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::build_tree ( Iterator  begin,
Iterator  end,
const Node_index  node,
const Directions &  directions,
Partition_data _data,
int &  depth,
const bool  is_middle = false 
) [inline, private]

Definition at line 443 of file element_tree.hpp.

                                      {
    std::size_t number_elements = std::distance(begin, end);
    if ( depth < MAX_DEPTH && 
        number_elements > ELEMENTS_PER_LEAF && 
        (!is_middle || directions.any())){
        determine_split( begin, end,  _data, directions);
        //count_sort( begin, end, _data);
        std::sort( begin, end,
             _element_tree::Iterator_comparator< Iterator>());
        //update the tree
        tree_[ node] = _data;
        Iterator middle_begin( begin+_data.left());
        Iterator middle_end( middle_begin+_data.middle());
        std::vector< int> depths(3, depth);
        //left subtree
        if( _data.left()>0){
            Partition_data data( _data);
            tree_.push_back( Node());
            tree_[ node].children[ 0] = tree_.size()-1;
            correct_bounding_box( _data, data.bounding_box, 0);
            Directions new_directions( directions);
            const bool axis_is_very_small = 
             (data.bounding_box.max[ _data.dim] - 
                data.bounding_box.min[ _data.dim] < EPSILON);
            new_directions.set( _data.dim, axis_is_very_small); 
            build_tree( begin, middle_begin, 
                    tree_[ node].children[ 0], 
                    new_directions, data, ++depths[ 0],
                    is_middle);
        }
        //middle subtree
        if( _data.middle()>0){
            Partition_data data( _data);
            tree_.push_back( Node());
            tree_[ node].children[ 1] = tree_.size()-1;
            correct_bounding_box( _data, data.bounding_box, 1);
            //force the middle subtree to split
            //in a different direction from this one
            Directions new_directions( directions);
            new_directions.flip( tree_[node].dim);
            bool axis_is_very_small = 
             (data.bounding_box.max[ _data.dim] - 
                data.bounding_box.min[ _data.dim] < EPSILON);
            new_directions.set( _data.dim, axis_is_very_small); 
            build_tree( middle_begin, middle_end,
                    tree_[ node].children[ 1], 
                    new_directions, data, 
                    ++depths[ 1], true);
        }
        //right subtree
        if( _data.right()>0){
            Partition_data data( _data);
            tree_.push_back( Node());
            tree_[ node].children[ 2] = tree_.size()-1;
            correct_bounding_box( _data, data.bounding_box, 2);
            Directions new_directions( directions);
            const bool axis_is_very_small = 
             (data.bounding_box.max[ _data.dim] - 
                data.bounding_box.min[ _data.dim] < EPSILON);
            new_directions.set( _data.dim, axis_is_very_small); 

            build_tree( middle_end, end, tree_[ node].children[ 2],
                    directions, data, ++depths[ 2], is_middle);
        }
        depth = *std::max_element(depths.begin(), depths.end());
    }
    if( tree_[ node].leaf()){
        common_tree::assign_entities(tree_[ node].entities, begin, end);
    }
}
template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
template<typename Iterator , typename Split_data >
void moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::compute_split ( Iterator &  begin,
Iterator &  end,
Split_data &  split_data,
bool  iteration = false 
) [inline, private]

Definition at line 277 of file element_tree.hpp.

                                                           {
    typedef typename Iterator::value_type::value_type Map_value_type;
    typedef typename Map_value_type::second_type::second_type Bitset;
    //we will update the left/right line
    double & left_line = split_data.left_line;
    double & right_line = split_data.right_line;
    double & split = split_data.split;
    const int & dim = split_data.dim;
    #ifdef ELEMENT_TREE_DEBUG
    std::cout << std::endl; 
    std::cout << "-------------------" << std::endl; 
    std::cout << "dim: " << dim << " split: " << split << std::endl;
    std::cout << "bounding_box min: "; 
    print_vector( split_data.bounding_box.min); 
    std::cout << "bounding_box max: "; 
    print_vector( split_data.bounding_box.max);
    #endif
    //for each elt determine if left/middle/right
    for(Iterator i = begin; i != end; ++i){
        const Box & box =  (*i)->second.first;
        Bitset & bits =  (*i)->second.second;
        //will be 0 if on left, will be 1 if in the middle
        //and 2 if on the right;
        const bool on_left = (box.max[ dim] < split);
        const bool on_right = (box.min[ dim] > split);
        const bool in_middle = !on_left && !on_right;
        //set the corresponding bits in the bit vector
        // looks like: [x_1 = 00 | x_2 = 00 | .. | z_1 = 00 | z_2 = 00]
        // two bits, left = 00, middle = 01, right = 10
        const int index = 4*dim + 2*iteration;
        if( on_left){ split_data.sizes[ 0]++; }
        else if(in_middle){
            split_data.sizes[ 1]++;
            bits.set( index, 1);
            left_line  = std::min( left_line,  box.min[ dim]);
            right_line = std::max( right_line, box.max[ dim]);
        }else if( on_right){
            bits.set( index+1, 1);
            split_data.sizes[ 2]++;
        }
    }
    #ifdef ELEMENT_TREE_DEBUG
    std::size_t _count = std::accumulate( split_data.sizes.begin(), 
                          split_data.sizes.end(), 0);
    std::size_t total = std::distance( begin, end);
    if( total != _count ){
        std::cout << total << "vs. " <<  _count << std::endl;

    }
    std::cout <<  " left_line: " << left_line;
    std::cout <<  " right_line: " << right_line << std::endl;
    std::cout << "co/mputed partition size: ";
    print_vector( split_data.sizes);
    std::cout << "-------------------" << std::endl; 
    #endif
}
template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
template<typename Iterator , typename Split_data , typename Directions >
void moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::determine_split ( Iterator &  begin,
Iterator &  end,
Split_data &  data,
const Directions &  directions 
) [inline, private]

Definition at line 372 of file element_tree.hpp.

                                            { 
    typedef typename Iterator::value_type Pair;
    typedef typename Pair::value_type Map_value_type;
    typedef typename Map_value_type::second_type::second_type Bitset;
    typedef typename Map_value_type::second_type::first_type Box;
    typedef typename std::map< std::size_t, Split_data> Splits;
    typedef typename Splits::value_type Split;  
    typedef _element_tree::Split_comparator< Split> Comparator;
    Splits splits;
    for (std::size_t dir = 0; dir < directions.size(); ++dir){
        if( directions.test( dir)){
            Split_data split_data( data.bounding_box, dir);
            compute_split( begin, end, split_data);
            splits.insert( std::make_pair(2*dir, split_data));
            if( update_split_line( split_data)){
                compute_split( begin, end, split_data, true);
                splits.insert( std::make_pair( 2*dir+1,
                                   split_data) );
            }
        }
    }
    Split best = *std::min_element( splits.begin(), splits.end(), 
                    Comparator());
    #ifdef ELEMENT_TREE_DEBUG
    std::cout << "best: " << Comparator().split_objective( best) << " ";
    print_vector( best.second.sizes);
    #endif 
    const int dir = best.first/2;
    const int iter = best.first%2;
    double & left_rightline = best.second.left_rightline= 
                        best.second.bounding_box.min[ dir];
    double & right_leftline = best.second.right_leftline = 
                    best.second.bounding_box.max[ dir];
    Bitset mask( 0);
    mask.flip( 4*dir+2*iter).flip( 4*dir+2*iter+1);
    for(Iterator i = begin; i != end; ++i){
        Bitset & bits = (*i)->second.second;
        const Box & box =  (*i)->second.first;
        //replace 12 bits with just two.
        bits &= mask;
        bits >>= 4*dir+2*iter;
        //if box is labeled left/right but properly contained 
        //in the middle, move the element into the middle.
        //we can shrink the size of left/right
        switch( bits.to_ulong()){
            case 0:
                if ( box.max[ dir] > best.second.left_line){ 
                    left_rightline = std::max( 
                        left_rightline, box.max[ dir]);
                }
                break;
            case 2:
                if ( box.min[ dir] < best.second.right_line){ 
                    right_leftline = std::min( 
                        right_leftline, box.max[ dir]);
                }
                break;
        }
    }
    data = best.second;
}
template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
template<typename Vector , typename Result >
Result& moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::find ( const Vector &  point,
Result &  result 
) const [inline]

Definition at line 560 of file element_tree.hpp.

                                                          {
    typedef typename Vector::const_iterator Point_iterator;
    typedef typename Box::Pair Pair; 
    typedef typename Pair::first_type Box_iterator;
    return  _find_point( point, 0, result);
}
template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
template<typename Split_data >
bool moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::update_split_line ( Split_data &  data) const [inline, private]

Definition at line 336 of file element_tree.hpp.

                                                {
    const int max = 2*(data.sizes[ 2]>data.sizes[ 0]);
    const int min = 2*(1-(max==2));
    bool one_side_empty = data.sizes[ max]==0 || data.sizes[ min]==0;
    double balance_ratio = data.sizes[ max] - data.sizes[ min];
    //if ( !one_side_empty && balance_ratio < .05*total){ return false; }
    if( !one_side_empty){
        //if we have some imbalance on left/right 
        //try to fix the situation 
        balance_ratio /= data.sizes[ max];
        data.split += (max-1)*balance_ratio*(data.split/2.0);
    }else{
        //if the (left) side is empty move the split line just past the 
        //extent of the (left) line of the middle box.
        //if middle encompasses everything then wiggle 
        //the split line a bit and hope for the best..
        const double left_distance = 
                    std::abs(data.left_line-data.split);    
            const double right_distance = 
                    std::abs(data.right_line-data.split);
        if( (data.sizes[ 0] == 0) && (data.sizes[ 2] != 0)){
            data.split += right_distance;
        }else if (data.sizes[ 2]==0 && data.sizes[ 0] != 0){
            data.split -= left_distance;
        }else{
            data.split *=1.05;
        }
    }
    data.left_line = data.right_line = data.split;
    data.sizes.assign( data.sizes.size(), 0);
    return true;
}

Member Data Documentation

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
Box moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::bounding_box [private]

Definition at line 576 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
Parametrizer moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::entity_contains [private]

Definition at line 577 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
const Entity_handles& moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::entity_handles_ [private]

Definition at line 573 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
Moab& moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::moab [private]

Definition at line 575 of file element_tree.hpp.

template<typename _Entity_handles , typename _Box , typename _Moab , typename _Parametrizer >
Nodes moab::Element_tree< _Entity_handles, _Box, _Moab, _Parametrizer >::tree_ [private]

Definition at line 574 of file element_tree.hpp.


The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines