#ifndef BOXMESHPARTITION_HPP
#define BOXMESHPARTITION_HPP
#include <cstddef>
#include <utility>
#include <vector>
#include <iostream>
struct BoxType {
size_t data[3][2] ;
typedef size_t range_type[2] ;
inline
const range_type & operator[]( size_t i ) const { return data[i]; }
inline
range_type & operator[]( size_t i ) { return data[i]; }
inline
bool operator == ( const BoxType & rhs ) const
{
return data[0][0] == rhs.data[0][0] && data[0][1] == rhs.data[0][1] &&
data[1][0] == rhs.data[1][0] && data[1][1] == rhs.data[2][1] &&
data[2][0] == rhs.data[2][0] && data[2][1] == rhs.data[2][1] ;
}
inline
bool operator != ( const BoxType & rhs ) const
{
return data[0][0] != rhs.data[0][0] || data[0][1] != rhs.data[0][1] ||
data[1][0] != rhs.data[1][0] || data[1][1] != rhs.data[1][1] ||
data[2][0] != rhs.data[2][0] || data[2][1] != rhs.data[2][1] ;
}
};
inline
size_t count( const BoxType & b )
{
size_t n = 1 ;
for ( size_t i = 0 ; i < 3 ; ++i ) {
n *= b[i][1] > b[i][0] ? b[i][1] - b[i][0] : 0 ;
}
return n ;
}
inline
bool contain( const BoxType & b , size_t i , size_t j , size_t k )
{
return b[0][0] <= i && i < b[0][1] &&
b[1][0] <= j && j < b[1][1] &&
b[2][0] <= k && k < b[2][1] ;
}
inline
BoxType intersect( const BoxType & x , const BoxType & y )
{
BoxType z ;
for ( size_t i = 0 ; i < 3 ; ++i ) {
z[i][0] = std::max( x[i][0] , y[i][0] );
z[i][1] = std::min( x[i][1] , y[i][1] );
}
return z ;
}
inline
std::ostream & operator << ( std::ostream & s , const BoxType & box )
{
s << "{ "
<< box[0][0] << " " << box[0][1] << " , "
<< box[1][0] << " " << box[1][1] << " , "
<< box[2][0] << " " << box[2][1] << " }" ;
return s ;
}
class BoxBounds {
public:
virtual
void apply( const BoxType & box_global ,
const BoxType & box_part ,
BoxType & box_interior ,
BoxType & box_use ) const = 0 ;
virtual ~BoxBounds() {}
BoxBounds() {}
};
class BoxBoundsLinear : public BoxBounds
{
public:
virtual
void apply( const BoxType & box_global ,
const BoxType & box_part ,
BoxType & box_interior ,
BoxType & box_use ) const ;
virtual ~BoxBoundsLinear() {}
BoxBoundsLinear() {}
};
class BoxBoundsQuadratic : public BoxBounds {
public:
virtual
void apply( const BoxType & box_global ,
const BoxType & box_part ,
BoxType & box_interior ,
BoxType & box_use ) const ;
virtual ~BoxBoundsQuadratic() {}
BoxBoundsQuadratic() {}
};
void box_partition_rcb( const BoxType & root_box ,
std::vector<BoxType> & part_boxes );
void box_partition_maps(
const BoxType & root_box , const std::vector<BoxType> & part_boxes , const BoxBounds & use_boxes , const size_t my_part , BoxType & my_use_box , std::vector<size_t> & my_use_id_map , size_t & my_count_interior , size_t & my_count_owned , size_t & my_count_uses , std::vector<size_t> & my_part_counts , std::vector<std::vector<size_t> > & my_send_map );
size_t box_map_id( const BoxType & my_use_box ,
const std::vector<size_t> & my_use_id_map ,
const size_t global_i ,
const size_t global_j ,
const size_t global_k );
#endif