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
00046
00048 DistArray(const Epetra_Map& Map, const int RowSize) :
00049 Epetra_DistObject(Map)
00050 {
00051
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
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(ostream& os) const
00104 {
00105 os << "DistArray object, label = " << this->Label() << endl;
00106 os << "Number of local elements = " << Map().NumMyElements() << endl;
00107 os << "Number of global elements = " << Map().NumGlobalElements() << endl;
00108 os << 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 << 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 << endl;
00127 }
00128 }
00129 }
00130 os << 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 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
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 vector<T>& From = S.ExtractView();
00184
00185 vector<T>& To = values_;
00186
00187
00188
00189
00190
00191 int j;
00192
00193 int NumSameEntries;
00194
00195 NumSameEntries = NumSameIDs;
00196
00197
00198 if (To==From) NumSameEntries = 0;
00199
00200
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
00210 if (NumPermuteIDs>0) {
00211
00212 for (j=0; j<NumPermuteIDs * RowSize_; j++)
00213 To[PermuteToLIDs[j]] = From[PermuteFromLIDs[j]];
00214
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 vector<T>& From = S.ExtractView();
00232
00233 vector<T> To = values_;
00234
00235
00236
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
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);
00274
00275 cout << NumImportIDs << endl;
00276 if (NumImportIDs<=0) return(0);
00277
00278 T* To = &values_[0];
00279
00280
00281
00282 T* ptr;
00283
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
00296
00298 vector<T> values_;
00300 int MyLength_;
00302 int GlobalLength_;
00304 int RowSize_;
00305 int count_;
00306 int last_;
00307
00308 };
00309
00310 }
00311
00312 #endif