|
EpetraExt Development
|
00001 #ifndef EPETRAEXT_DISTARRAY_H 00002 #define EPETRAEXT_DISTARRAY_H 00003 00004 #include "EpetraExt_ConfigDefs.h" 00005 #include "EpetraExt_Exception.h" 00006 #include "Epetra_Map.h" 00007 #include "Epetra_DistObject.h" 00008 00009 namespace EpetraExt 00010 { 00041 template<class T> 00042 class DistArray : public Epetra_DistObject 00043 { 00044 public: 00045 // @{ \name Constructors and Destructors 00046 00048 DistArray(const Epetra_Map& Map, const int RowSize) : 00049 Epetra_DistObject(Map) 00050 { 00051 // only Epetra_Map's with constant element size of 1 are allowed 00052 if (Map.MaxElementSize() != 1) 00053 throw(Exception(__FILE__, __LINE__, 00054 "Map.MaxElementSize() != 1")); 00055 if (!Map.ConstantElementSize()) 00056 throw(Exception(__FILE__, __LINE__, 00057 "Map.ConstantElementSize() != true")); 00058 00059 MyLength_ = Map.NumMyElements(); 00060 GlobalLength_ = Map.NumGlobalElements(); 00061 RowSize_ = RowSize; 00062 count_ = 0; 00063 values_.resize(MyLength_ * RowSize_); 00064 } 00065 00066 // @} 00067 // @{ \name Query methods 00068 00070 inline int MyLength() const 00071 { 00072 return(MyLength_); 00073 } 00074 00076 inline int GlobalLength() const 00077 { 00078 return(GlobalLength_); 00079 } 00080 00082 inline int RowSize() const 00083 { 00084 return(RowSize_); 00085 } 00086 00088 inline T& operator()(const int LEID, const int ID) 00089 { 00090 assert (ID <= RowSize_); 00091 return(values_[LEID * RowSize_ + ID]); 00092 } 00093 00094 inline T& operator()(const int GEID, const int ID, const bool isLocal) 00095 { 00096 int LEID = Map().LID(GEID); 00097 assert (LEID != -1); 00098 assert (ID <= RowSize_); 00099 return(values_[LEID * RowSize_ + ID]); 00100 } 00101 00103 void Print(std::ostream& os) const 00104 { 00105 os << "DistArray object, label = " << this->Label() << std::endl; 00106 os << "Number of local elements = " << Map().NumMyElements() << std::endl; 00107 os << "Number of global elements = " << Map().NumGlobalElements() << std::endl; 00108 os << std::endl; 00109 00110 for (int iproc=0; iproc < Comm().NumProc(); iproc++) 00111 { 00112 if (iproc == 0) 00113 { 00114 os << "GEID\t"; 00115 for (int i = 0; i < RowSize(); ++i) os << "V\t"; 00116 os << std::endl; 00117 } 00118 00119 if (Comm().MyPID() == iproc) 00120 { 00121 for (int i = 0; i < Map().NumMyElements(); ++i) 00122 { 00123 os << Map().GID(i) << '\t'; 00124 for (int j = 0; j < RowSize_; ++j) 00125 os << values_[i * RowSize_ + j] << '\t'; 00126 os << std::endl; 00127 } 00128 } 00129 } 00130 os << std::endl; 00131 } 00132 00133 int NextGID() 00134 { 00135 ++count_; 00136 if (count_ < Map().NumMyElements()) 00137 return(Map().GID(count_)); 00138 else 00139 return(-1); 00140 } 00141 00142 int FirstGID() 00143 { 00144 count_ = 0; 00145 return(Map().GID(0)); 00146 } 00147 00149 const std::vector<T>& ExtractView() const 00150 { 00151 return(values_); 00152 } 00153 00155 T* Values() 00156 { 00157 return(&values_[0]); 00158 } 00159 00161 const T* Values() const 00162 { 00163 return(&values_[0]); 00164 } 00165 00166 // @} 00167 private: 00168 // @{ \name Epetra_DistObject methods 00169 00170 virtual int CheckSizes(const Epetra_SrcDistObject& Source) 00171 { 00172 return(0); 00173 } 00174 00175 virtual int CopyAndPermute(const Epetra_SrcDistObject& Source, 00176 int NumSameIDs, 00177 int NumPermuteIDs, 00178 int * PermuteToLIDs, 00179 int * PermuteFromLIDs, 00180 const Epetra_OffsetIndex * Indexor) 00181 { 00182 const DistArray& S = dynamic_cast<const DistArray&>(Source); 00183 const std::vector<T>& From = S.ExtractView(); 00184 00185 std::vector<T>& To = values_; 00186 00187 //int * ToFirstPointInElementList = 0; 00188 //int * FromFirstPointInElementList = 0; 00189 //int * FromElementSizeList = 0; 00190 00191 int j; 00192 00193 int NumSameEntries; 00194 00195 NumSameEntries = NumSameIDs; 00196 00197 // Short circuit for the case where the source and target std::vector is the same. 00198 if (To==From) NumSameEntries = 0; 00199 00200 // Do copy first 00201 if (NumSameIDs>0) 00202 if (To!=From) { 00203 for (j=0; j<NumSameEntries * RowSize_; j++) 00204 { 00205 To[j] = From[j]; 00206 } 00207 } 00208 00209 // Do local permutation next 00210 if (NumPermuteIDs>0) { 00211 00212 for (j=0; j<NumPermuteIDs * RowSize_; j++) 00213 To[PermuteToLIDs[j]] = From[PermuteFromLIDs[j]]; 00214 // constant element size case 00215 } 00216 00217 return(0); 00218 } 00219 00220 virtual int PackAndPrepare(const Epetra_SrcDistObject& Source, 00221 int NumExportIDs, 00222 int* ExportLIDs, 00223 int& LenExports, 00224 char*& Exports, 00225 int& SizeOfPacket, 00226 int* Sizes, 00227 bool & VarSizes, 00228 Epetra_Distributor& Distor) 00229 { 00230 const DistArray& S = dynamic_cast<const DistArray&>(Source); 00231 const std::vector<T>& From = S.ExtractView(); 00232 00233 std::vector<T> To = values_; 00234 00235 //int * FromFirstPointInElementList = 0; 00236 //int * FromElementSizeList = 0; 00237 00238 SizeOfPacket = RowSize_ * sizeof(T); 00239 00240 if(NumExportIDs*SizeOfPacket>LenExports) { 00241 if (LenExports>0) delete [] Exports; 00242 LenExports = NumExportIDs*SizeOfPacket; 00243 Exports = new char[LenExports]; 00244 } 00245 00246 T* ptr; 00247 00248 if (NumExportIDs>0) { 00249 ptr = (T*) Exports; 00250 00251 // Point entry case 00252 for (int j=0; j<NumExportIDs; j++) 00253 for (int k = 0; k < RowSize_ ; ++k) 00254 *ptr++ = From[ExportLIDs[j] * RowSize_ + k]; 00255 } 00256 00257 return(0); 00258 } 00259 00260 virtual int UnpackAndCombine(const Epetra_SrcDistObject& Source, 00261 int NumImportIDs, 00262 int* ImportLIDs, 00263 int LenImports, 00264 char* Imports, 00265 int& SizeOfPacket, 00266 Epetra_Distributor& Distor, 00267 Epetra_CombineMode CombineMode, 00268 const Epetra_OffsetIndex * Indexor) 00269 { 00270 int j; 00271 00272 if (CombineMode != Insert) 00273 EPETRA_CHK_ERR(-1); //Unsupported CombinedMode, will default to Zero 00274 00275 std::cout << NumImportIDs << std::endl; 00276 if (NumImportIDs<=0) return(0); 00277 00278 T* To = &values_[0]; 00279 //int * ToFirstPointInElementList = 0; 00280 //int * ToElementSizeList = 0; 00281 00282 T* ptr; 00283 // Unpack it... 00284 00285 ptr = (T*) Imports; 00286 00287 for (j=0; j<NumImportIDs; j++) 00288 for (int k = 0; k < RowSize_ ; ++k) 00289 To[ImportLIDs[j] * RowSize_ + k] = *ptr++; 00290 00291 return(0); 00292 } 00293 00294 // @} 00295 // @{ \name Private data 00296 00298 std::vector<T> values_; 00300 int MyLength_; 00302 int GlobalLength_; 00304 int RowSize_; 00305 int count_; 00306 int last_; 00307 // @} 00308 }; 00309 00310 } // namespace EpetraExt 00311 00312 #endif
1.7.4