git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@14919 f3b2605a-c512-4ea7-a41b-209d697bcdaa
211 lines
7.0 KiB
C++
211 lines
7.0 KiB
C++
/*
|
|
//@HEADER
|
|
// ************************************************************************
|
|
//
|
|
// Kokkos v. 2.0
|
|
// Copyright (2014) Sandia Corporation
|
|
//
|
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
|
// the U.S. Government retains certain rights in this software.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are
|
|
// met:
|
|
//
|
|
// 1. Redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
//
|
|
// 2. Redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
//
|
|
// 3. Neither the name of the Corporation nor the names of the
|
|
// contributors may be used to endorse or promote products derived from
|
|
// this software without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
|
|
//
|
|
// ************************************************************************
|
|
//@HEADER
|
|
*/
|
|
|
|
#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:
|
|
/** \brief Default bounds to one layer of ghosting */
|
|
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:
|
|
/** \brief Default bounds to one layer of ghosting */
|
|
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:
|
|
/** \brief Quadratic mesh: even ordinates have two layers,
|
|
* odd ordinates have one layer.
|
|
*/
|
|
virtual
|
|
void apply( const BoxType & box_global ,
|
|
const BoxType & box_part ,
|
|
BoxType & box_interior ,
|
|
BoxType & box_use ) const ;
|
|
|
|
virtual ~BoxBoundsQuadratic() {}
|
|
BoxBoundsQuadratic() {}
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
/* Partition box into part_boxes.size() sub-boxes */
|
|
|
|
void box_partition_rcb( const BoxType & root_box ,
|
|
std::vector<BoxType> & part_boxes );
|
|
|
|
//----------------------------------------------------------------------------
|
|
/* Determine local id layout and communication maps for partitioned boxes.
|
|
*
|
|
* Local ids are layed out as follows:
|
|
* { [ owned-interior ids not sent ] ,
|
|
* [ owned-boundary ids to be sent to other processes ] ,
|
|
* [ received ids from processor ( my_part + 1 ) % part_count ]
|
|
* [ received ids from processor ( my_part + 2 ) % part_count ]
|
|
* [ received ids from processor ( my_part + 3 ) % part_count ]
|
|
* ... };
|
|
*
|
|
* This layout allows
|
|
* (1) received data to be copied into a contiguous block of memory
|
|
* (2) send data to be extracted from a contiguous block of memory.
|
|
*/
|
|
void box_partition_maps(
|
|
const BoxType & root_box , // [in] Global box
|
|
const std::vector<BoxType> & part_boxes , // [in] Partitioned boxes
|
|
const BoxBounds & use_boxes , // [in] Ghost boundaries
|
|
const size_t my_part , // [in] My local part
|
|
BoxType & my_use_box , // [out] My used box with ghost
|
|
std::vector<size_t> & my_use_id_map , // [out] Local ordering map
|
|
size_t & my_count_interior , // [out] How many interior
|
|
size_t & my_count_owned , // [out] How many owned
|
|
size_t & my_count_uses , // [out] How may used
|
|
std::vector<size_t> & my_part_counts , // [out] Partitioning of my_use_id_map
|
|
std::vector<std::vector<size_t> > & my_send_map ); // [out] Send id map
|
|
|
|
/* Mapping of cartesian coordinate to local id */
|
|
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 /* #ifndef BOXMESHPARTITION_HPP */
|
|
|