20 #ifndef MPICHEMPS2_CHEMPS2_H    21 #define MPICHEMPS2_CHEMPS2_H    25 #ifdef CHEMPS2_MPI_COMPILATION    31    #define MPI_CHEMPS2_MASTER   0    35    #define MPI_CHEMPS2_4D1AB    1    36    #define MPI_CHEMPS2_4D2AB    2    37    #define MPI_CHEMPS2_4I1AB    3    38    #define MPI_CHEMPS2_4I2AB    4    39    #define MPI_CHEMPS2_4F1AB    5    40    #define MPI_CHEMPS2_4F2AB    6    41    #define MPI_CHEMPS2_4G1AB    7    42    #define MPI_CHEMPS2_4G2AB    8    44    #define MPI_CHEMPS2_4D3ABCD  9    45    #define MPI_CHEMPS2_4D4ABCD  10    46    #define MPI_CHEMPS2_4I3ABCD  11    47    #define MPI_CHEMPS2_4I4ABCD  12    48    #define MPI_CHEMPS2_4F3ABCD  13    49    #define MPI_CHEMPS2_4F4ABCD  14    50    #define MPI_CHEMPS2_4G3ABCD  15    51    #define MPI_CHEMPS2_4G4ABCD  16    53    #define MPI_CHEMPS2_4E1      17    54    #define MPI_CHEMPS2_4E2      18    55    #define MPI_CHEMPS2_4H1      19    56    #define MPI_CHEMPS2_4H2      20    58    #define MPI_CHEMPS2_4E3A     21    59    #define MPI_CHEMPS2_4E3B     22    60    #define MPI_CHEMPS2_4E4A     23    61    #define MPI_CHEMPS2_4E4B     24    62    #define MPI_CHEMPS2_4H3A     25    63    #define MPI_CHEMPS2_4H3B     26    64    #define MPI_CHEMPS2_4H4A     27    65    #define MPI_CHEMPS2_4H4B     28    67    #define MPI_CHEMPS2_5A1      29    68    #define MPI_CHEMPS2_5A2      30    69    #define MPI_CHEMPS2_5A3      31    70    #define MPI_CHEMPS2_5A4      32    72    #define MPI_CHEMPS2_5B1      33    73    #define MPI_CHEMPS2_5B2      34    74    #define MPI_CHEMPS2_5B3      35    75    #define MPI_CHEMPS2_5B4      36    77    #define MPI_CHEMPS2_5C1      37    78    #define MPI_CHEMPS2_5C2      38    79    #define MPI_CHEMPS2_5C3      39    80    #define MPI_CHEMPS2_5C4      40    82    #define MPI_CHEMPS2_5D1      41    83    #define MPI_CHEMPS2_5D2      42    84    #define MPI_CHEMPS2_5D3      43    85    #define MPI_CHEMPS2_5D4      44    87    #define MPI_CHEMPS2_5E1      45    88    #define MPI_CHEMPS2_5E2      46    89    #define MPI_CHEMPS2_5E3      47    90    #define MPI_CHEMPS2_5E4      48    92    #define MPI_CHEMPS2_5F1      49    93    #define MPI_CHEMPS2_5F2      50    94    #define MPI_CHEMPS2_5F3      51    95    #define MPI_CHEMPS2_5F4      52    97    #define MPI_CHEMPS2_OFFSET   53   120             #ifdef CHEMPS2_MPI_COMPILATION   122                MPI_Comm_size( MPI_COMM_WORLD, &size );
   132             #ifdef CHEMPS2_MPI_COMPILATION   134                MPI_Comm_rank( MPI_COMM_WORLD, &rank );
   141          #ifdef CHEMPS2_MPI_COMPILATION   142          static void mpi_init(){
   145             MPI_Init( &zero, NULL );
   149          #ifdef CHEMPS2_MPI_COMPILATION   150          static void mpi_finalize(){
   156          #ifdef CHEMPS2_MPI_COMPILATION   157          static int owner_x(){ 
return MPI_CHEMPS2_MASTER; }
   161          #ifdef CHEMPS2_MPI_COMPILATION   166          static int owner_absigma(
const int index1, 
const int index2){ 
   167             assert( index1 <= index2 );
   168             return ( 1 + index1 + (index2*(index2+1))/2 ) % 
mpi_size();
   172          #ifdef CHEMPS2_MPI_COMPILATION   178          static int owner_cdf(
const int L, 
const int index1, 
const int index2){ 
   179             assert( index1 <= index2 );
   180             return ( 1 + (L*(L+1))/2 + index1 + (index2*(index2+1))/2 ) % 
mpi_size();
   184          #ifdef CHEMPS2_MPI_COMPILATION   189          static int owner_q(
const int L, 
const int index){ 
   190             return ( 1 + L*(L+1) + index ) % 
mpi_size();
   194          #ifdef CHEMPS2_MPI_COMPILATION   201          static int owner_3rdm_diagram(
const int L, 
const int index1, 
const int index2, 
const int index3){ 
   202             assert( index1 <= index2 );
   203             assert( index2 <= index3 );
   204             return ( 1 + L*(L+1) + index1 + (index2*(index2+1))/2 + (index3*(index3+1)*(index3+2))/6 ) % 
mpi_size();
   208          #ifdef CHEMPS2_MPI_COMPILATION   211          static int owner_1cd2d3eh(){ 
return MPI_CHEMPS2_MASTER; }
   214          #ifdef CHEMPS2_MPI_COMPILATION   219          static int owner_specific_diagram(
const int L, 
const int macro){
   220             return (macro + L*(L+2)) % 
mpi_size();
   224          #ifdef CHEMPS2_MPI_COMPILATION   229          static int owner_specific_excitation(
const int L, 
const int excitation){
   230             return (MPI_CHEMPS2_OFFSET + L*(L+2) + excitation) % 
mpi_size();
   234          #ifdef CHEMPS2_MPI_COMPILATION   238          static void broadcast_tensor(
Tensor * 
object, 
int ROOT){
   239             int arraysize = 
object->gKappa2index(object->
gNKappa());
   240             MPI_Bcast(object->
gStorage(), arraysize, MPI_DOUBLE, ROOT, MPI_COMM_WORLD);
   244          #ifdef CHEMPS2_MPI_COMPILATION   249          static void broadcast_array_double(
double * array, 
int length, 
int ROOT){
   250             MPI_Bcast(array, length, MPI_DOUBLE, ROOT, MPI_COMM_WORLD);
   254          #ifdef CHEMPS2_MPI_COMPILATION   259          static void broadcast_array_int(
int * array, 
int length, 
int ROOT){
   260             MPI_Bcast(array, length, MPI_INT, ROOT, MPI_COMM_WORLD);
   264          #ifdef CHEMPS2_MPI_COMPILATION   268          static bool all_booleans_equal(
const bool mybool){
   269             int my_value = ( mybool ) ? 1 : 0 ;
   271             MPI_Allreduce(&my_value, &tot_value, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
   276          #ifdef CHEMPS2_MPI_COMPILATION   282          static void sendreceive_tensor(
Tensor * 
object, 
int SENDER, 
int RECEIVER, 
int tag){
   283             if ( SENDER != RECEIVER ){
   285                if ( SENDER == MPIRANK ){
   286                   int arraysize = 
object->gKappa2index(object->
gNKappa());
   287                   MPI_Send(object->
gStorage(), arraysize, MPI_DOUBLE, RECEIVER, tag, MPI_COMM_WORLD);
   289                if ( RECEIVER == MPIRANK ){
   290                   int arraysize = 
object->gKappa2index(object->
gNKappa());
   291                   MPI_Recv(object->
gStorage(), arraysize, MPI_DOUBLE, SENDER, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
   297          #ifdef CHEMPS2_MPI_COMPILATION   303          static void reduce_array_double(
double * vec_in, 
double * vec_out, 
int size, 
int ROOT){
   304             MPI_Reduce(vec_in, vec_out, size, MPI_DOUBLE, MPI_SUM, ROOT, MPI_COMM_WORLD);
   308          #ifdef CHEMPS2_MPI_COMPILATION   313          static void allreduce_array_double(
double * vec_in, 
double * vec_out, 
int size){
   314             MPI_Allreduce(vec_in, vec_out, size, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
 
virtual ~MPIchemps2()
Destructor. 
static int mpi_rank()
Get the rank of this MPI process. 
static int mpi_size()
Get the number of MPI processes. 
virtual double * gStorage()=0
Get the pointer to the storage. 
virtual int gNKappa() const =0
Get the number of tensor blocks.