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

Generated on Thu Sep 18 12:37:57 2008 for Epetra Package Browser (Single Doxygen Collection) by doxygen 1.3.9.1