EpetraExt Package Browser (Single Doxygen Collection) Development
EpetraExt_DistArray.h
Go to the documentation of this file.
00001 /*
00002 //@HEADER
00003 // ***********************************************************************
00004 //
00005 //     EpetraExt: Epetra Extended - Linear Algebra Services Package
00006 //                 Copyright (2011) Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ***********************************************************************
00041 //@HEADER
00042 */
00043 
00044 #ifndef EPETRAEXT_DISTARRAY_H
00045 #define EPETRAEXT_DISTARRAY_H
00046 
00047 #include "EpetraExt_ConfigDefs.h"
00048 #include "EpetraExt_Exception.h"
00049 #include "Epetra_Map.h"
00050 #include "Epetra_DistObject.h"
00051 
00052 namespace EpetraExt 
00053 {
00084   template<class T>
00085   class DistArray : public Epetra_DistObject
00086   {
00087     public:
00088       // @{ \name Constructors and Destructors
00089 
00091       DistArray(const Epetra_Map& Map, const int RowSize) :
00092         Epetra_DistObject(Map)
00093       {
00094         // only Epetra_Map's with constant element size of 1 are allowed
00095         if (Map.MaxElementSize() != 1) 
00096           throw(Exception(__FILE__, __LINE__,
00097                           "Map.MaxElementSize() != 1"));
00098         if (!Map.ConstantElementSize()) 
00099           throw(Exception(__FILE__, __LINE__,
00100                           "Map.ConstantElementSize() != true"));
00101 
00102         MyLength_     = Map.NumMyElements();
00103         GlobalLength_ = Map.NumGlobalElements();
00104         RowSize_      = RowSize;
00105         count_        = 0;
00106         values_.resize(MyLength_ * RowSize_);
00107       }
00108 
00109       // @}
00110       // @{ \name Query methods
00111 
00113       inline int MyLength() const
00114       {
00115         return(MyLength_);
00116       }
00117 
00119       inline int GlobalLength() const
00120       {
00121         return(GlobalLength_);
00122       }
00123 
00125       inline int RowSize() const
00126       {
00127         return(RowSize_);
00128       }
00129 
00131       inline T& operator()(const int LEID, const int ID)
00132       {
00133         assert (ID <= RowSize_);
00134         return(values_[LEID * RowSize_ + ID]);
00135       }
00136 
00137       inline T& operator()(const int GEID, const int ID, const bool isLocal)
00138       {
00139         int LEID = Map().LID(GEID);
00140         assert (LEID != -1);
00141         assert (ID <= RowSize_);
00142         return(values_[LEID * RowSize_ + ID]);
00143       }
00144 
00146       void Print(std::ostream& os) const
00147       {
00148         os << "DistArray object, label   = " << this->Label() << std::endl;
00149         os << "Number of local elements  = " << Map().NumMyElements() << std::endl;
00150         os << "Number of global elements = " << Map().NumGlobalElements() << std::endl;
00151         os << std::endl;
00152 
00153         for (int iproc=0; iproc < Comm().NumProc(); iproc++) 
00154         {
00155           if (iproc == 0)
00156           {
00157             os << "GEID\t";
00158             for (int i = 0; i < RowSize(); ++i) os << "V\t";
00159             os << std::endl;
00160           }
00161 
00162           if (Comm().MyPID() == iproc) 
00163           {
00164             for (int i = 0; i < Map().NumMyElements(); ++i)
00165             {
00166               os << Map().GID(i) << '\t';
00167               for (int j = 0; j < RowSize_; ++j)
00168                 os << values_[i * RowSize_ + j] << '\t';
00169               os << std::endl;
00170             }
00171           }
00172         }
00173         os << std::endl;
00174       }
00175 
00176       int NextGID()
00177       {
00178         ++count_;
00179         if (count_ < Map().NumMyElements())
00180           return(Map().GID(count_));
00181         else
00182           return(-1);
00183       }
00184 
00185       int FirstGID()
00186       {
00187         count_ = 0;
00188         return(Map().GID(0));
00189       }
00190 
00192       const std::vector<T>& ExtractView() const
00193       {
00194         return(values_);
00195       }
00196 
00198       T* Values() 
00199       {
00200         return(&values_[0]);
00201       }
00202 
00204       const T* Values() const
00205       {
00206         return(&values_[0]);
00207       }
00208 
00209       // @}
00210     private:
00211       // @{ \name Epetra_DistObject methods
00212 
00213       virtual int CheckSizes(const Epetra_SrcDistObject& Source)
00214       {
00215         return(0);
00216       }
00217 
00218       virtual int CopyAndPermute(const Epetra_SrcDistObject& Source,
00219                                  int NumSameIDs,
00220                                  int NumPermuteIDs,
00221                                  int * PermuteToLIDs,
00222                                  int * PermuteFromLIDs,
00223                                  const Epetra_OffsetIndex * Indexor)
00224       {
00225         const DistArray& S = dynamic_cast<const DistArray&>(Source);
00226         const std::vector<T>& From = S.ExtractView();
00227 
00228         std::vector<T>& To = values_;
00229 
00230         //int * ToFirstPointInElementList = 0;
00231         //int * FromFirstPointInElementList = 0;
00232         //int * FromElementSizeList = 0;
00233 
00234         int j;
00235 
00236         int NumSameEntries;
00237 
00238         NumSameEntries = NumSameIDs;
00239 
00240         // Short circuit for the case where the source and target std::vector is the same.
00241         if (To==From) NumSameEntries = 0;
00242 
00243         // Do copy first
00244         if (NumSameIDs>0)
00245           if (To!=From) {
00246             for (j=0; j<NumSameEntries * RowSize_; j++)
00247             {
00248               To[j] = From[j];
00249             }
00250           }
00251 
00252         // Do local permutation next
00253         if (NumPermuteIDs>0) {
00254 
00255           for (j=0; j<NumPermuteIDs * RowSize_; j++) 
00256             To[PermuteToLIDs[j]] = From[PermuteFromLIDs[j]];
00257           // constant element size case
00258         }
00259 
00260         return(0);
00261       }
00262 
00263       virtual int PackAndPrepare(const Epetra_SrcDistObject& Source,
00264                                  int NumExportIDs,
00265                                  int* ExportLIDs,
00266                                  int& LenExports,
00267                                  char*& Exports,
00268                                  int& SizeOfPacket,
00269                                  int* Sizes,
00270                                  bool & VarSizes,
00271                                  Epetra_Distributor& Distor)
00272       {
00273         const DistArray& S = dynamic_cast<const DistArray&>(Source);
00274         const std::vector<T>& From = S.ExtractView();
00275 
00276         std::vector<T> To = values_;
00277 
00278         //int * FromFirstPointInElementList = 0;
00279         //int * FromElementSizeList = 0;
00280 
00281         SizeOfPacket = RowSize_ * sizeof(T); 
00282 
00283         if(NumExportIDs*SizeOfPacket>LenExports) {
00284           if (LenExports>0) delete [] Exports;
00285           LenExports = NumExportIDs*SizeOfPacket;
00286           Exports = new char[LenExports];
00287         }
00288 
00289         T* ptr;
00290 
00291         if (NumExportIDs>0) {
00292           ptr = (T*) Exports;
00293 
00294           // Point entry case
00295           for (int j=0; j<NumExportIDs; j++) 
00296             for (int k = 0; k < RowSize_ ; ++k)
00297               *ptr++ = From[ExportLIDs[j] * RowSize_ + k];
00298         }
00299 
00300         return(0);
00301       }
00302 
00303       virtual int UnpackAndCombine(const Epetra_SrcDistObject& Source,
00304                                    int NumImportIDs,
00305                                    int* ImportLIDs,
00306                                    int LenImports,
00307                                    char* Imports,
00308                                    int& SizeOfPacket,
00309                                    Epetra_Distributor& Distor,
00310                                    Epetra_CombineMode CombineMode,
00311                                    const Epetra_OffsetIndex * Indexor)
00312       {
00313         int j;
00314 
00315         if (CombineMode != Insert)
00316           EPETRA_CHK_ERR(-1); //Unsupported CombinedMode, will default to Zero
00317 
00318         std::cout << NumImportIDs << std::endl;
00319         if (NumImportIDs<=0) return(0);
00320 
00321         T* To = &values_[0];
00322         //int * ToFirstPointInElementList = 0;
00323         //int * ToElementSizeList = 0;
00324 
00325         T* ptr;
00326         // Unpack it...
00327 
00328         ptr = (T*) Imports;
00329 
00330         for (j=0; j<NumImportIDs; j++) 
00331           for (int k = 0; k < RowSize_ ; ++k)
00332             To[ImportLIDs[j] * RowSize_ + k] = *ptr++;
00333 
00334         return(0);
00335       }
00336 
00337       // @}
00338       // @{ \name Private data
00339       
00341       std::vector<T> values_;
00343       int MyLength_;
00345       int GlobalLength_;
00347       int RowSize_;
00348       int count_;
00349       int last_;
00350       // @}
00351   };
00352 
00353 } // namespace EpetraExt
00354 
00355 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines