blob: 14e40762e84a3d3f5b46e082aadf187c616c2118 [file] [log] [blame]
//@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 <Box.hpp>
/** \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