00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef _DomainCoupler_h_
00015 #define _DomainCoupler_h_
00016
00017 #include <mpi.h>
00018
00019 #include "PicoNames.h"
00020 #include "SubDomain.h"
00021
00022 #include <map>
00023 #include <cassert>
00024
00025
00026 namespace pico {
00027 class DomainCoupler;
00028 }
00029
00030
00031 class pico::DomainCoupler{
00032
00033
00034
00035
00036
00037
00038
00039
00040 public:
00041 DomainCoupler(MPI_Comm pComm):_pComm(pComm){assert(_pComm != MPI_COMM_NULL);}
00042 ~DomainCoupler(){}
00043
00044
00045 void registerSubDomain(const pico::SolvType& type, const double lo[3],
00046 const double up[3], const double& maxElemSize);
00047 void registerSubDomain(const pico::SolvType& type, const double * const coor,
00048 const int& nodes, const double& maxElemSize);
00049
00050
00051 void prepareCommunicationsIntra(const pico::SolvType& type);
00052 void exchangeSubdomainDataIntra(const pico::SolvType& type);
00053 void prepareCommunicationsInter();
00054
00055
00056 template <typename T>
00057 void registerSendBuffer(const pico::SolvType& type, T* const start, int size);
00058
00059
00060 template <typename RT>
00061 RT* recvBuffer(const pico::SolvType& type, const RT& notUsed);
00062 template <typename T>
00063 int recvBufferSize(const pico::SolvType& type);
00064
00065
00066 template <typename Iterator>
00067 void relevantSubDomainNumbers(Iterator domainNumbers, int t, char *tch);
00068
00069
00070 private:
00071 DomainCoupler(const DomainCoupler &);
00072 const DomainCoupler & operator=(const DomainCoupler &);
00073
00074 private:
00075 void gatherSubDomains();
00076 void relevantSubDomainsInter();
00077 void relevantSubDomainsIntra(const pico::SolvType& type);
00078 void exchangeBufferSizesIntra(const pico::SolvType& type);
00079
00080 private:
00081 typedef std::map<int, SubDomain *> _SubDomainCont;
00082 typedef _SubDomainCont::iterator _SubDomainIt;
00083
00084
00085 _SubDomainCont _subDomains[2];
00086
00087 _SubDomainCont _relevSubDomainsInter[2];
00088 _SubDomainCont _relevSubDomainsIntra[2];
00089
00090 MPI_Comm _pComm;
00091 };
00092
00093
00094
00095 namespace pico {
00096
00097 template <typename Iterator>
00098 void DomainCoupler::relevantSubDomainNumbers(Iterator domainNumbers, int t, char *tch)
00099 {
00100 std::string commT(tch);
00101 _SubDomainIt it, ite;
00102
00103 if (commT== "Inter") {
00104 it = _relevSubDomainsInter[t].begin();
00105 ite = _relevSubDomainsInter[t].end();
00106 } else if (commT=="Intra") {
00107 it = _relevSubDomainsIntra[t].begin();
00108 ite = _relevSubDomainsIntra[t].end();
00109 } else
00110 return;
00111
00112 for ( ; it!=ite; ++it) *(domainNumbers++) = it->first;
00113
00114 return;
00115 }
00116
00117
00118 template <typename T>
00119 void DomainCoupler::registerSendBuffer(const pico::SolvType& type,
00120 T* const start, int size)
00121 {
00122 int rank;
00123 MPI_Comm_rank(_pComm, &rank);
00124
00125 _SubDomainIt it, ite=_subDomains[type].end();
00126
00127 it = _subDomains[type].find(rank);
00128 if (it==ite) return;
00129
00130 SubDomain* myDomain = it->second;
00131
00132 size_t unit = sizeof(T);
00133 size *= unit;
00134
00135 char *startCh = reinterpret_cast<char *>(start);
00136
00137 myDomain->registerSendBuffer(startCh, size);
00138
00139 return;
00140 }
00141
00142
00143 template <typename RT>
00144 RT* DomainCoupler::recvBuffer(const pico::SolvType& type, const RT& notUsed)
00145 {
00146
00147 char *tmp=NULL;
00148 int rank;
00149 MPI_Comm_rank(_pComm, &rank);
00150
00151 _SubDomainIt it, ite=_subDomains[type].end();
00152 it = _subDomains[type].find(rank);
00153 if (it==ite) return NULL;
00154 SubDomain* myDomain = it->second;
00155
00156 tmp = myDomain->recvBuffer();
00157
00158 RT *tmpRT = reinterpret_cast<RT *>(tmp);
00159
00160 return tmpRT;
00161 }
00162
00163
00164 template <typename T>
00165 int DomainCoupler::recvBufferSize(const pico::SolvType& type)
00166 {
00167 int tmp=0, rank;
00168 MPI_Comm_rank(_pComm, &rank);
00169
00170 _SubDomainIt it, ite=_subDomains[type].end();
00171 it = _subDomains[type].find(rank);
00172 if (it==ite) return tmp;
00173 SubDomain* myDomain = it->second;
00174
00175 tmp = myDomain->recvBufferSize();
00176
00177 size_t unit = sizeof(T);
00178 tmp /= unit;
00179
00180 return tmp;
00181 }
00182 }
00183
00184
00185 #endif
00186
00187