|
EpetraExt
Development
|
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 Epetra_CombineMode CombineMode = Zero) 00225 { 00226 const DistArray& S = dynamic_cast<const DistArray&>(Source); 00227 const std::vector<T>& From = S.ExtractView(); 00228 00229 std::vector<T>& To = values_; 00230 00231 //int * ToFirstPointInElementList = 0; 00232 //int * FromFirstPointInElementList = 0; 00233 //int * FromElementSizeList = 0; 00234 00235 int j; 00236 00237 int NumSameEntries; 00238 00239 NumSameEntries = NumSameIDs; 00240 00241 // Short circuit for the case where the source and target std::vector is the same. 00242 if (To==From) NumSameEntries = 0; 00243 00244 // Do copy first 00245 if (NumSameIDs>0) 00246 if (To!=From) { 00247 for (j=0; j<NumSameEntries * RowSize_; j++) 00248 { 00249 To[j] = From[j]; 00250 } 00251 } 00252 00253 // Do local permutation next 00254 if (NumPermuteIDs>0) { 00255 00256 for (j=0; j<NumPermuteIDs * RowSize_; j++) 00257 To[PermuteToLIDs[j]] = From[PermuteFromLIDs[j]]; 00258 // constant element size case 00259 } 00260 00261 return(0); 00262 } 00263 00264 virtual int PackAndPrepare(const Epetra_SrcDistObject& Source, 00265 int NumExportIDs, 00266 int* ExportLIDs, 00267 int& LenExports, 00268 char*& Exports, 00269 int& SizeOfPacket, 00270 int* Sizes, 00271 bool & VarSizes, 00272 Epetra_Distributor& Distor) 00273 { 00274 const DistArray& S = dynamic_cast<const DistArray&>(Source); 00275 const std::vector<T>& From = S.ExtractView(); 00276 00277 std::vector<T> To = values_; 00278 00279 //int * FromFirstPointInElementList = 0; 00280 //int * FromElementSizeList = 0; 00281 00282 SizeOfPacket = RowSize_ * sizeof(T); 00283 00284 if(NumExportIDs*SizeOfPacket>LenExports) { 00285 if (LenExports>0) delete [] Exports; 00286 LenExports = NumExportIDs*SizeOfPacket; 00287 Exports = new char[LenExports]; 00288 } 00289 00290 T* ptr; 00291 00292 if (NumExportIDs>0) { 00293 ptr = (T*) Exports; 00294 00295 // Point entry case 00296 for (int j=0; j<NumExportIDs; j++) 00297 for (int k = 0; k < RowSize_ ; ++k) 00298 *ptr++ = From[ExportLIDs[j] * RowSize_ + k]; 00299 } 00300 00301 return(0); 00302 } 00303 00304 virtual int UnpackAndCombine(const Epetra_SrcDistObject& Source, 00305 int NumImportIDs, 00306 int* ImportLIDs, 00307 int LenImports, 00308 char* Imports, 00309 int& SizeOfPacket, 00310 Epetra_Distributor& Distor, 00311 Epetra_CombineMode CombineMode, 00312 const Epetra_OffsetIndex * Indexor) 00313 { 00314 int j; 00315 00316 if (CombineMode != Insert) 00317 EPETRA_CHK_ERR(-1); //Unsupported CombinedMode, will default to Zero 00318 00319 std::cout << NumImportIDs << std::endl; 00320 if (NumImportIDs<=0) return(0); 00321 00322 T* To = &values_[0]; 00323 //int * ToFirstPointInElementList = 0; 00324 //int * ToElementSizeList = 0; 00325 00326 T* ptr; 00327 // Unpack it... 00328 00329 ptr = (T*) Imports; 00330 00331 for (j=0; j<NumImportIDs; j++) 00332 for (int k = 0; k < RowSize_ ; ++k) 00333 To[ImportLIDs[j] * RowSize_ + k] = *ptr++; 00334 00335 return(0); 00336 } 00337 00338 // @} 00339 // @{ \name Private data 00340 00342 std::vector<T> values_; 00344 int MyLength_; 00346 int GlobalLength_; 00348 int RowSize_; 00349 int count_; 00350 int last_; 00351 // @} 00352 }; 00353 00354 } // namespace EpetraExt 00355 00356 #endif
1.7.6.1