//@HEADER // ************************************************************************ // // MiniFE: Simple Finite Element Assembly and Solve // Copyright (2006-2013) Sandia Corporation // // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive // license for use of this work by or on behalf of the U.S. Government. // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA // // ************************************************************************ //@HEADER #ifndef _BoxPartition_hpp_ #define _BoxPartition_hpp_ #include /** \brief Recursively split a box into (up-ip) sub-boxes */ void box_partition( int ip , int up , int axis , const Box& box , Box* p_box ); /** \brief Partition a { [ix,jx) X [iy,jy) X [iz,jz) } box. * * Use recursive coordinate bisection to partition a box * into np disjoint sub-boxes. Allocate (via malloc) and * populate the sub-boxes, mapping the local (x,y,z) to * a local ordinal, and mappings for the send-recv messages * to update the ghost cells. * * usage: * * my_nx = pbox[my_p][0][1] - pbox[my_p][0][0] ; * my_ny = pbox[my_p][1][1] - pbox[my_p][1][0] ; * my_nz = pbox[my_p][2][1] - pbox[my_p][2][0] ; * * for ( x = -ghost ; x < my_nx + ghost ; ++x ) { * for ( y = -ghost ; y < my_ny + ghost ; ++y ) { * for ( z = -ghost ; z < my_nz + ghost ; ++z ) { * const int x_global = x + pbox[my_p][0][0] ; * const int y_global = y + pbox[my_p][1][0] ; * const int z_global = z + pbox[my_p][2][0] ; * * const int local_ordinal = * box_map_local( pbox[my_p], ghost, map_local_id, x, y, z ); * * if ( 0 <= local_ordinal ) { * } * } * * for ( i = 1 ; i < np ; ++i ) { * const int recv_processor = ( my_p + i ) % np ; * const int recv_ordinal_begin = map_recv_pc[i]; * const int recv_ordinal_end = map_recv_pc[i+1]; * } * * for ( i = 1 ; i < np ; ++i ) { * const int send_processor = ( my_p + i ) % np ; * const int send_map_begin = map_send_pc[i]; * const int send_map_end = map_send_pc[i+1]; * for ( j = send_map_begin ; j < send_map_end ; ++j ) { * send_ordinal = map_send_id[j] ; * } * } */ void box_partition_rcb( const int np /**< [in] Number of partitions */ , const int my_p /**< [in] My partition rank */ , const Box& root_box /**< [in] 3D Box to partition */ , const int ghost /**< [in] Ghost cell boundary */ , Box* pbox /**< [out] Partition's 3D boxes */ , int ** map_local_id /**< [out] Map local cells */ , int ** map_recv_pc /**< [out] Receive spans per processor */ , int ** map_send_pc /**< [out] Send prefix counts per processor */ , int ** map_send_id /**< [out] Send message ordinals */ ); /* \brief Map a local (x,y,z) to a local ordinal. */ int box_map_local( const Box& box_local , const int ghost , const int map_local_id[] , const int local_x , const int local_y , const int local_z ); #endif