Epetra Package Browser (Single Doxygen Collection) Development
Epetra_IntVector.cpp
Go to the documentation of this file.
00001 
00002 //@HEADER
00003 // ************************************************************************
00004 // 
00005 //               Epetra: Linear Algebra Services Package 
00006 //                 Copyright 2001 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 #include "Epetra_IntVector.h"
00044 #include "Epetra_Map.h"
00045 #include "Epetra_Comm.h"
00046 //=============================================================================
00047 Epetra_IntVector::Epetra_IntVector(const Epetra_BlockMap& Map, bool zeroOut)
00048   : Epetra_DistObject(Map, "Epetra::IntVector"),
00049     Values_(0),
00050     UserAllocated_(false),
00051     Allocated_(false)
00052 {
00053   AllocateForCopy();
00054   if(zeroOut) PutValue(0); // Zero out values
00055 }
00056 //=============================================================================
00057 Epetra_IntVector::Epetra_IntVector(const Epetra_IntVector& Source)
00058   : Epetra_DistObject(Source),
00059     Values_(0),
00060     UserAllocated_(false),
00061     Allocated_(false)
00062 {
00063   AllocateForCopy();
00064   DoCopy(Source.Values_);
00065 }
00066 //=============================================================================
00067 Epetra_IntVector::Epetra_IntVector(Epetra_DataAccess CV, const Epetra_BlockMap& Map, int *V)
00068   : Epetra_DistObject(Map, "Epetra::IntVector"),
00069     Values_(0),
00070     UserAllocated_(false),
00071     Allocated_(false)
00072 {
00073   if (CV==Copy) {
00074     AllocateForCopy();
00075     DoCopy(V);
00076   }
00077   else {
00078     AllocateForView();
00079     DoView(V);
00080   }
00081 }
00082 //=========================================================================
00083 Epetra_IntVector::~Epetra_IntVector(){
00084 
00085 
00086  if (Allocated_ && (!UserAllocated_) && Values_!=0) delete [] Values_;
00087 }
00088 
00089 //=========================================================================
00090 int Epetra_IntVector::AllocateForCopy()
00091 {
00092   
00093   if (Allocated_) return(0);
00094     
00095   int myLength = MyLength();
00096   if (myLength>0)
00097     Values_ = new int[myLength];
00098   else
00099     Values_ = 0;
00100 
00101   Allocated_ = true;
00102   UserAllocated_ = false;
00103   return(0);
00104 }
00105 
00106 //=========================================================================
00107 int Epetra_IntVector::DoCopy(int * V)
00108 {
00109   int iend = MyLength();
00110   for (int i=0; i<iend; i++) Values_[i] = V[i];
00111 
00112   return(0);
00113 }
00114 //=========================================================================
00115 int Epetra_IntVector::AllocateForView()
00116 {
00117 
00118   Allocated_ = true;
00119   UserAllocated_ = true;
00120   
00121   return(0);
00122 }
00123 
00124 //=========================================================================
00125 int Epetra_IntVector::DoView(int * V)
00126 {
00127   
00128   Values_ = V;
00129 
00130   return(0);
00131 }
00132 //=============================================================================
00133 int Epetra_IntVector::ExtractCopy(int *V) const {
00134   
00135   int iend = MyLength();
00136   for (int i=0; i<iend; i++) V[i] = Values_[i];
00137   return(0);
00138 }
00139 
00140 //=============================================================================
00141 int Epetra_IntVector::ExtractView(int **V) const
00142 {
00143   *V = Values_;
00144   return(0);
00145 }
00146 
00147 //=============================================================================
00148 int Epetra_IntVector::PutValue(int Value) {
00149   int iend = MyLength();
00150   for (int i=0; i<iend; i++) Values_[i] = Value;
00151   return(0);
00152 }
00153 //=============================================================================
00154 int Epetra_IntVector::MaxValue() {
00155 
00156   int result = -2000000000; // Negative 2 billion is close to smallest 32 bit int
00157   int iend = MyLength();
00158   if (iend>0) result = Values_[0];
00159   for (int i=0; i<iend; i++) result = EPETRA_MAX(result, Values_[i]);
00160   int globalResult;
00161   this->Comm().MaxAll(&result, &globalResult, 1);
00162   return(globalResult);
00163 }
00164 //=============================================================================
00165 int Epetra_IntVector::MinValue() {
00166 
00167   int result = 2000000000; // 2 billion is close to largest 32 bit int
00168   int iend = MyLength();
00169   if (iend>0) result = Values_[0];
00170   for (int i=0; i<iend; i++) result = EPETRA_MIN(result, Values_[i]);
00171   int globalResult;
00172   this->Comm().MinAll(&result, &globalResult, 1);
00173   return(globalResult);
00174 }
00175 //========================================================================
00176 Epetra_IntVector& Epetra_IntVector::operator = (const Epetra_IntVector& V) {
00177   
00178 
00179   if (MyLength() != V.MyLength())
00180     throw ReportError("Length of IntVectors incompatible in Assign.  The this IntVector has MyLength = " + toString(MyLength())
00181           + ".  The V IntVector has MyLength = " + toString(V.MyLength()), -1);
00182   
00183   int iend = MyLength();
00184   for (int i=0; i<iend; i++) Values_[i] =V[i];
00185   return(*this);
00186 }
00187 
00188 void Epetra_IntVector::Print(ostream& os) const {
00189   int MyPID = Map().Comm().MyPID();
00190   int NumProc = Map().Comm().NumProc();
00191   
00192   for (int iproc=0; iproc < NumProc; iproc++) {
00193     if (MyPID==iproc) {
00194       int NumMyElements1 =Map(). NumMyElements();
00195       int MaxElementSize1 = Map().MaxElementSize();
00196       int * MyGlobalElements1 = Map().MyGlobalElements();
00197       int * FirstPointInElementList1;
00198       if (MaxElementSize1!=1) FirstPointInElementList1 = Map().FirstPointInElementList();
00199 
00200       if (MyPID==0) {
00201   os.width(8);
00202   os <<  "     MyPID"; os << "    ";
00203   os.width(12);
00204   if (MaxElementSize1==1)
00205     os <<  "GID  ";
00206   else
00207     os <<  "     GID/Point";
00208   os.width(20);
00209   os <<  "Value  ";
00210   os << endl;
00211       }
00212       for (int i=0; i < NumMyElements1; i++) {
00213   for (int ii=0; ii< Map().ElementSize(ii); ii++) {
00214     int iii;
00215     os.width(10);
00216     os <<  MyPID; os << "    ";
00217     os.width(10);
00218     if (MaxElementSize1==1) {
00219       os << MyGlobalElements1[i] << "    ";
00220       iii = i;
00221     }
00222     else {
00223       os <<  MyGlobalElements1[i]<< "/" << ii << "    ";
00224       iii = FirstPointInElementList1[i]+ii;
00225     }
00226         os.width(20);
00227         os <<  Values_[iii];
00228     os << endl;
00229   }
00230       }
00231       os << flush; 
00232     }
00233 
00234     // Do a few global ops to give I/O a chance to complete
00235     Map().Comm().Barrier();
00236     Map().Comm().Barrier();
00237     Map().Comm().Barrier();
00238   }
00239   return;
00240 }
00241 //=========================================================================
00242 int Epetra_IntVector::CheckSizes(const Epetra_SrcDistObject& Source)
00243 {
00244   (void)Source;
00245   return(0);
00246 }
00247 
00248 //=========================================================================
00249 int Epetra_IntVector::CopyAndPermute(const Epetra_SrcDistObject& Source,
00250                                      int NumSameIDs, 
00251                                      int NumPermuteIDs,
00252                                      int * PermuteToLIDs, 
00253                                      int *PermuteFromLIDs,
00254                                      const Epetra_OffsetIndex * Indexor)
00255 {
00256   (void)Indexor;
00257   const Epetra_IntVector & A = dynamic_cast<const Epetra_IntVector &>(Source);
00258 
00259   int * From;
00260   A.ExtractView(&From);
00261   int *To = Values_;
00262 
00263   int * ToFirstPointInElementList = 0;
00264   int * FromFirstPointInElementList = 0;
00265   int * FromElementSizeList = 0;
00266   int MaxElementSize = Map().MaxElementSize();
00267   bool ConstantElementSize = Map().ConstantElementSize();
00268 
00269   if (!ConstantElementSize) {
00270     ToFirstPointInElementList =   Map().FirstPointInElementList();
00271     FromFirstPointInElementList = A.Map().FirstPointInElementList();
00272     FromElementSizeList = A.Map().ElementSizeList();
00273   }
00274   int j, jj, jjj, k;
00275   
00276   int NumSameEntries;
00277 
00278   bool Case1 = false;
00279   bool Case2 = false;
00280   // bool Case3 = false;
00281 
00282   if (MaxElementSize==1) {
00283     Case1 = true;
00284     NumSameEntries = NumSameIDs;
00285   }
00286   else if (ConstantElementSize) {
00287     Case2 = true;
00288     NumSameEntries = NumSameIDs * MaxElementSize;
00289   }
00290   else {
00291     // Case3 = true;
00292     NumSameEntries = FromFirstPointInElementList[NumSameIDs];
00293   }
00294 
00295   // Short circuit for the case where the source and target vector is the same.
00296   if (To==From) NumSameEntries = 0;
00297   
00298   // Do copy first
00299   if (NumSameIDs>0)
00300     if (To!=From) {
00301   for (j=0; j<NumSameEntries; j++)
00302     To[j] = From[j];
00303     }
00304   // Do local permutation next
00305   if (NumPermuteIDs>0) {
00306   
00307     // Point entry case
00308     if (Case1) {
00309       
00310       for (j=0; j<NumPermuteIDs; j++) 
00311   To[PermuteToLIDs[j]] = From[PermuteFromLIDs[j]];
00312     }
00313     // constant element size case
00314     else if (Case2) {
00315       
00316       for (j=0; j<NumPermuteIDs; j++) {
00317   jj = MaxElementSize*PermuteToLIDs[j];
00318   jjj = MaxElementSize*PermuteFromLIDs[j];
00319     for (k=0; k<MaxElementSize; k++)
00320       To[jj+k] = From[jjj+k];
00321       }
00322     }
00323     
00324     // variable element size case
00325     else {
00326       
00327       for (j=0; j<NumPermuteIDs; j++) {
00328   jj = ToFirstPointInElementList[PermuteToLIDs[j]];
00329   jjj = FromFirstPointInElementList[PermuteFromLIDs[j]];
00330   int ElementSize = FromElementSizeList[PermuteFromLIDs[j]];
00331     for (k=0; k<ElementSize; k++)
00332       To[jj+k] = From[jjj+k];
00333       }
00334     }
00335   }
00336   return(0);
00337 }
00338 
00339 //=========================================================================
00340 int Epetra_IntVector::PackAndPrepare(const Epetra_SrcDistObject & Source,
00341                                      int NumExportIDs,
00342                                      int * ExportLIDs,
00343                                      int & LenExports,
00344                                      char * & Exports,
00345                                      int & SizeOfPacket,
00346                                      int * Sizes,
00347                                      bool & VarSizes,
00348                                      Epetra_Distributor & Distor)
00349 {
00350   (void)Sizes;
00351   (void)VarSizes;
00352   (void)Distor;
00353   const Epetra_IntVector & A = dynamic_cast<const Epetra_IntVector &>(Source);
00354 
00355   int j, jj, k;
00356 
00357   int  * From;
00358   A.ExtractView(&From);
00359   int MaxElementSize = Map().MaxElementSize();
00360   bool ConstantElementSize = Map().ConstantElementSize();
00361 
00362   int * FromFirstPointInElementList = 0;
00363   int * FromElementSizeList = 0;
00364 
00365   if (!ConstantElementSize) {
00366     FromFirstPointInElementList = A.Map().FirstPointInElementList();
00367     FromElementSizeList = A.Map().ElementSizeList();
00368   }
00369 
00370   SizeOfPacket = MaxElementSize * (int)sizeof(int); 
00371 
00372   if(NumExportIDs*SizeOfPacket>LenExports) {
00373     if (LenExports>0) delete [] Exports;
00374     LenExports = NumExportIDs*SizeOfPacket;
00375     Exports = new char[LenExports];
00376   }
00377 
00378   int * ptr;
00379 
00380   if (NumExportIDs>0) {
00381     ptr = (int *) Exports;
00382     
00383     // Point entry case
00384     if (MaxElementSize==1) for (j=0; j<NumExportIDs; j++) *ptr++ = From[ExportLIDs[j]];
00385 
00386     // constant element size case
00387     else if (ConstantElementSize) {
00388       
00389       for (j=0; j<NumExportIDs; j++) {
00390   jj = MaxElementSize*ExportLIDs[j];
00391     for (k=0; k<MaxElementSize; k++)
00392       *ptr++ = From[jj+k];
00393       }
00394     }
00395     
00396     // variable element size case
00397     else {
00398       
00399       SizeOfPacket = MaxElementSize;
00400       for (j=0; j<NumExportIDs; j++) {
00401   ptr = (int *) Exports + j*SizeOfPacket;
00402   jj = FromFirstPointInElementList[ExportLIDs[j]];
00403   int ElementSize = FromElementSizeList[ExportLIDs[j]];
00404     for (k=0; k<ElementSize; k++)
00405       *ptr++ = From[jj+k];
00406       }
00407     }
00408   }
00409 
00410   return(0);
00411 }
00412 
00413 //=========================================================================
00414 int Epetra_IntVector::UnpackAndCombine(const Epetra_SrcDistObject & Source,
00415                                        int NumImportIDs,
00416                                        int * ImportLIDs, 
00417                                        int LenImports, 
00418                                        char * Imports,
00419                                        int & SizeOfPacket, 
00420                                        Epetra_Distributor & Distor, 
00421                                        Epetra_CombineMode CombineMode,
00422                                        const Epetra_OffsetIndex * Indexor)
00423 {
00424   (void)Source;
00425   (void)LenImports;
00426   (void)Distor;
00427   (void)Indexor;
00428   int j, jj, k;
00429   
00430   if(    CombineMode != Add
00431       && CombineMode != Zero
00432       && CombineMode != Insert
00433       && CombineMode != Average
00434       && CombineMode != AbsMax )
00435     EPETRA_CHK_ERR(-1); //Unsupported CombinedMode, will default to Zero
00436 
00437   if (NumImportIDs<=0) return(0);
00438 
00439   int * To = Values_;
00440   int MaxElementSize = Map().MaxElementSize();
00441   bool ConstantElementSize = Map().ConstantElementSize();
00442 
00443   int * ToFirstPointInElementList = 0;
00444   int * ToElementSizeList = 0;
00445 
00446   if (!ConstantElementSize) {
00447     ToFirstPointInElementList = Map().FirstPointInElementList();
00448     ToElementSizeList = Map().ElementSizeList();
00449   }
00450   
00451   int * ptr;
00452   // Unpack it...
00453 
00454   ptr = (int *) Imports;
00455     
00456   // Point entry case
00457   if (MaxElementSize==1) {
00458       
00459       if (CombineMode==Add)
00460   for (j=0; j<NumImportIDs; j++) To[ImportLIDs[j]] += *ptr++; // Add to existing value
00461       else if(CombineMode==Insert)
00462   for (j=0; j<NumImportIDs; j++) To[ImportLIDs[j]] = *ptr++;
00463       else if(CombineMode==AbsMax)
00464         for (j=0; j<NumImportIDs; j++) {
00465     To[ImportLIDs[j]] = EPETRA_MAX( To[ImportLIDs[j]],std::abs(*ptr));
00466     ptr++;
00467   }
00468       // Note:  The following form of averaging is not a true average if more that one value is combined.
00469       //        This might be an issue in the future, but we leave this way for now.
00470       else if(CombineMode==Average)
00471   for (j=0; j<NumImportIDs; j++) {To[ImportLIDs[j]] += *ptr++; To[ImportLIDs[j]] /= 2;}
00472   }
00473 
00474   // constant element size case
00475 
00476   else if (ConstantElementSize) {
00477    
00478     if (CombineMode==Add) {
00479       for (j=0; j<NumImportIDs; j++) {
00480   jj = MaxElementSize*ImportLIDs[j];
00481     for (k=0; k<MaxElementSize; k++)
00482       To[jj+k] += *ptr++; // Add to existing value
00483       }
00484     }
00485     else if(CombineMode==Insert) {
00486       for (j=0; j<NumImportIDs; j++) {
00487   jj = MaxElementSize*ImportLIDs[j];
00488     for (k=0; k<MaxElementSize; k++)
00489       To[jj+k] = *ptr++;
00490       }
00491     }
00492     else if(CombineMode==AbsMax) {
00493       for (j=0; j<NumImportIDs; j++) {
00494   jj = MaxElementSize*ImportLIDs[j];
00495   for (k=0; k<MaxElementSize; k++) {
00496       To[jj+k] = EPETRA_MAX( To[jj+k], std::abs(*ptr));
00497       ptr++;
00498   }
00499       }
00500     }
00501     // Note:  The following form of averaging is not a true average if more that one value is combined.
00502     //        This might be an issue in the future, but we leave this way for now.
00503     else if(CombineMode==Average) {
00504       for (j=0; j<NumImportIDs; j++) {
00505   jj = MaxElementSize*ImportLIDs[j];
00506     for (k=0; k<MaxElementSize; k++)
00507       { To[jj+k] += *ptr++; To[jj+k] /= 2;}
00508       }
00509     }
00510   }
00511     
00512   // variable element size case
00513 
00514   else {
00515       
00516     SizeOfPacket = MaxElementSize;
00517 
00518     if (CombineMode==Add) {
00519       for (j=0; j<NumImportIDs; j++) {
00520   ptr = (int *) Imports + j*SizeOfPacket;
00521   jj = ToFirstPointInElementList[ImportLIDs[j]];
00522   int ElementSize = ToElementSizeList[ImportLIDs[j]];
00523     for (k=0; k<ElementSize; k++)
00524       To[jj+k] += *ptr++; // Add to existing value
00525       }
00526     }
00527     else  if(CombineMode==Insert){
00528       for (j=0; j<NumImportIDs; j++) {
00529   ptr = (int *) Imports + j*SizeOfPacket;
00530   jj = ToFirstPointInElementList[ImportLIDs[j]];
00531   int ElementSize = ToElementSizeList[ImportLIDs[j]];
00532     for (k=0; k<ElementSize; k++)
00533       To[jj+k] = *ptr++;
00534       }
00535     }
00536     else  if(CombineMode==AbsMax){
00537       for (j=0; j<NumImportIDs; j++) {
00538   ptr = (int *) Imports + j*SizeOfPacket;
00539   jj = ToFirstPointInElementList[ImportLIDs[j]];
00540   int ElementSize = ToElementSizeList[ImportLIDs[j]];
00541   for (k=0; k<ElementSize; k++) {
00542       To[jj+k] = EPETRA_MAX( To[jj+k], std::abs(*ptr));
00543       ptr++;
00544   }
00545       }
00546     }
00547     // Note:  The following form of averaging is not a true average if more that one value is combined.
00548     //        This might be an issue in the future, but we leave this way for now.
00549     else if(CombineMode==Average) {
00550       for (j=0; j<NumImportIDs; j++) {
00551   ptr = (int *) Imports + j*SizeOfPacket;
00552   jj = ToFirstPointInElementList[ImportLIDs[j]];
00553   int ElementSize = ToElementSizeList[ImportLIDs[j]];
00554     for (k=0; k<ElementSize; k++)
00555       { To[jj+k] += *ptr++; To[jj+k] /= 2;}
00556       }
00557     }
00558   }
00559   
00560   return(0);
00561 }
00562 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines