00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "EpetraExt_MultiMpiComm.h"
00032
00033 namespace EpetraExt {
00034
00035 MultiMpiComm::MultiMpiComm(MPI_Comm globalMpiComm, int subDomainProcs, int numTimeSteps_) :
00036 EpetraExt::MultiComm(Teuchos::rcp(new Epetra_MpiComm(globalMpiComm))),
00037 subComm(0)
00038 {
00039
00040
00041
00042 int ierrmpi, size, rank;
00043 ierrmpi = MPI_Comm_size(globalMpiComm, &size);
00044 ierrmpi = MPI_Comm_rank(globalMpiComm, &rank);
00045
00046 if (size % subDomainProcs != 0) {cout<<"ERROR: num subDomainProcs "<< subDomainProcs
00047 << " does not divide into num total procs " << size << endl; exit(-1);}
00048
00049 numSubDomains = size / subDomainProcs;
00050
00051
00052 MPI_Comm split_MPI_Comm;
00053 subDomainRank = rank/subDomainProcs;
00054 ierrmpi = MPI_Comm_split(globalMpiComm, subDomainRank, rank, &split_MPI_Comm);
00055
00056
00057 subComm = new Epetra_MpiComm(split_MPI_Comm);
00058
00059
00060 ResetNumTimeSteps(numTimeSteps_);
00061
00062 if (numTimeSteps_ > 0)
00063 cout << "Processor " << rank << " is on subdomain " << subDomainRank
00064 << " and owns " << numTimeStepsOnDomain << " time steps, starting with "
00065 << firstTimeStepOnDomain << endl;
00066 else
00067 cout << "Processor " << rank << " is on subdomain " << subDomainRank << endl;
00068 }
00069
00070
00071
00072 MultiMpiComm::MultiMpiComm(const Epetra_MpiComm& EpetraMpiComm_, int numTimeSteps_) :
00073 EpetraExt::MultiComm(Teuchos::rcp(new Epetra_MpiComm(EpetraMpiComm_))),
00074 subComm(0)
00075 {
00076
00077 numSubDomains = 1;
00078 subDomainRank = 0;
00079 numTimeSteps = numTimeSteps_;
00080 numTimeStepsOnDomain = numTimeSteps_;
00081 firstTimeStepOnDomain = 0;
00082
00083 subComm = new Epetra_MpiComm(EpetraMpiComm_);
00084 }
00085
00086
00087 MultiMpiComm::MultiMpiComm(const MultiMpiComm &MMC ) :
00088 EpetraExt::MultiComm(Teuchos::rcp(new Epetra_MpiComm(dynamic_cast<const Epetra_MpiComm&>(MMC)))),
00089 subComm(new Epetra_MpiComm(*(MMC.subComm)))
00090 {
00091 numSubDomains = MMC.numSubDomains;
00092 subDomainRank = MMC.subDomainRank;
00093 numTimeSteps = MMC.numTimeSteps;
00094 numTimeStepsOnDomain = MMC.numTimeStepsOnDomain;
00095 firstTimeStepOnDomain = MMC.firstTimeStepOnDomain;
00096 }
00097
00098 MultiMpiComm::~MultiMpiComm()
00099 {
00100 delete subComm;
00101 }
00102
00103 void MultiMpiComm::ResetNumTimeSteps(int numTimeSteps_)
00104 {
00105 numTimeSteps = numTimeSteps_;
00106
00107
00108 if (numTimeSteps > 0) {
00109
00110 numTimeStepsOnDomain = numTimeSteps / numSubDomains;
00111 firstTimeStepOnDomain = numTimeStepsOnDomain * subDomainRank;
00112
00113
00114 int remainder = numTimeSteps % numSubDomains;
00115 if (subDomainRank < remainder) {
00116 numTimeStepsOnDomain++;
00117 firstTimeStepOnDomain += subDomainRank;
00118 }
00119 else firstTimeStepOnDomain += remainder;
00120 }
00121 else {
00122 numTimeStepsOnDomain = -1;
00123 firstTimeStepOnDomain = -1;
00124 }
00125 }
00126
00127 }