EpetraExt Package Browser (Single Doxygen Collection) Development
EpetraExt_DistArray.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines