Epetra_BasicDirectory.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_BasicDirectory.h"
00031 #include "Epetra_BlockMap.h"
00032 #include "Epetra_Map.h"
00033 #include "Epetra_Comm.h"
00034 #include "Epetra_Distributor.h"
00035 #include "Epetra_Util.h"
00036 
00037 //==============================================================================
00038 // Epetra_BasicDirectory constructor for a Epetra_BlockMap object
00039 Epetra_BasicDirectory::Epetra_BasicDirectory(const Epetra_BlockMap & Map)
00040   : DirectoryMap_(0),
00041     ProcList_(0),
00042     ProcListLists_(0),
00043     ProcListLens_(0),
00044     numProcLists_(0),
00045     entryOnMultipleProcs_(false),
00046     LocalIndexList_(0),
00047     SizeList_(0),
00048     SizeIsConst_(true),
00049     AllMinGIDs_(0)
00050 {
00051   // Test for simple cases
00052 
00053   // Uniprocessor and local map cases (Nothing to set up)
00054 
00055   if (!(Map.DistributedGlobal())) return;
00056 
00057   // Linear Map case
00058 
00059   else if (Map.LinearMap()) {
00060 
00061     // Build a list of the Minimum global ids for all processors on each processor.
00062     // Since the map is linear, we know that all GIDs are contiguous on each processor
00063     // and can be found using the MinGIDs.
00064 
00065     int NumProc = Map.Comm().NumProc();
00066     AllMinGIDs_ = new int[NumProc+1];
00067     int MinMyGID = Map.MinMyGID();
00068     Map.Comm().GatherAll(&MinMyGID, AllMinGIDs_, 1);
00069     AllMinGIDs_[NumProc] = 1 + Map.MaxAllGID(); // Set max cap
00070   }
00071 
00072   // General case.  Need to build a directory via calls to communication functions
00073   else {
00074     
00075     int flag = Generate(Map);
00076     assert(flag==0);
00077   }
00078 }
00079 
00080 //==============================================================================
00081 // Epetra_BasicDirectory copy constructor
00082 Epetra_BasicDirectory::Epetra_BasicDirectory(const Epetra_BasicDirectory & Directory)
00083   : DirectoryMap_(0),
00084     ProcList_(0),
00085     ProcListLists_(0),
00086     ProcListLens_(0),
00087     numProcLists_(0),
00088     entryOnMultipleProcs_(false),
00089     LocalIndexList_(0),
00090     SizeList_(0),
00091     SizeIsConst_(Directory.SizeIsConst_),
00092     AllMinGIDs_(0)
00093 {
00094   if (Directory.DirectoryMap_!=0) DirectoryMap_ = new Epetra_Map(Directory.DirectoryMap());
00095 
00096   int Dir_NumMyElements = DirectoryMap_->NumMyElements();
00097 
00098   if (Directory.ProcList_!=0) {
00099     ProcList_ = new int[Dir_NumMyElements];
00100     for (int i=0; i<Dir_NumMyElements; i++) ProcList_[i] = Directory.ProcList_[i];
00101   }
00102   if (Directory.LocalIndexList_!=0) {
00103     LocalIndexList_ = new int[Dir_NumMyElements];
00104     for (int i=0; i<Dir_NumMyElements; i++) LocalIndexList_[i] = Directory.LocalIndexList_[i];
00105     }
00106   if (Directory.SizeList_!=0) {
00107     SizeList_ = new int[Dir_NumMyElements];
00108     for (int i=0; i<Dir_NumMyElements; i++) SizeList_[i] = Directory.SizeList_[i];
00109     }
00110   if (Directory.AllMinGIDs_!=0) {
00111     int NumProc = DirectoryMap_->Comm().NumProc();
00112     AllMinGIDs_ = new int[NumProc+1];
00113     for (int i=0; i<NumProc+1; i++) AllMinGIDs_[i] = Directory.AllMinGIDs_[i];
00114     }
00115 
00116   if (Directory.numProcLists_ > 0) {
00117     int num = Directory.numProcLists_;
00118     ProcListLens_ = new int[num];
00119     ProcListLists_ = new int*[num];
00120     numProcLists_ = num;
00121 
00122     for(int i=0; i<num; ++i) {
00123       int len = Directory.ProcListLens_[i];
00124       ProcListLens_[i] = len;
00125 
00126       if (len > 0) {
00127   ProcListLists_[i] = new int[len];
00128   const int* dir_list = Directory.ProcListLists_[i];
00129   for(int j=0; j<len; ++j) {
00130     ProcListLists_[i][j] = dir_list[j];
00131   }
00132       }
00133       else ProcListLists_[i] = 0;
00134     }
00135   }
00136 
00137   entryOnMultipleProcs_ = Directory.entryOnMultipleProcs_;
00138 }
00139 
00140 //==============================================================================
00141 // Epetra_BasicDirectory destructor 
00142 Epetra_BasicDirectory::~Epetra_BasicDirectory()
00143 {
00144   if (numProcLists_>0) {
00145     for(int i=0; i<numProcLists_; ++i) {
00146       if (ProcListLens_[i] > 0) delete [] ProcListLists_[i];
00147     }
00148     delete [] ProcListLists_; ProcListLists_ = 0;
00149     delete [] ProcListLens_;  ProcListLens_ = 0;
00150     numProcLists_ = 0;
00151   }
00152 
00153   if( DirectoryMap_ != 0 ) delete DirectoryMap_;
00154   if( ProcList_ != 0 ) delete [] ProcList_;
00155   if( LocalIndexList_ != 0 ) delete [] LocalIndexList_;
00156   if( SizeList_ != 0 ) delete [] SizeList_;
00157   if( AllMinGIDs_ != 0 ) delete [] AllMinGIDs_;
00158 
00159   DirectoryMap_ = 0;
00160   ProcList_ = 0 ;
00161   LocalIndexList_ = 0;
00162   SizeList_ = 0;
00163   AllMinGIDs_ = 0;
00164 }
00165 
00166 //==============================================================================
00167 void Epetra_BasicDirectory::create_ProcListArrays()
00168 {
00169   numProcLists_ = DirectoryMap_->NumMyElements();
00170   ProcListLens_ = new int[numProcLists_];
00171   ProcListLists_ = new int*[numProcLists_];
00172 
00173   for(int i=0; i<numProcLists_; ++i) {
00174     ProcListLens_[i] = 0;
00175     ProcListLists_[i] = 0;
00176   }
00177 }
00178 
00179 //==============================================================================
00180 void Epetra_BasicDirectory::addProcToList(int proc, int LID)
00181 {
00182   int insertPoint = -1;
00183   int index = Epetra_Util_binary_search(proc, ProcListLists_[LID],
00184             ProcListLens_[LID], insertPoint);
00185   if (index < 0) {
00186     int tmp = ProcListLens_[LID];
00187     Epetra_Util_insert(proc, insertPoint, ProcListLists_[LID],
00188            ProcListLens_[LID], tmp, 1);
00189   }
00190 }
00191 
00192 //==============================================================================
00193 // Generate: Generates Directory Tables
00194 int Epetra_BasicDirectory::Generate(const Epetra_BlockMap& Map)
00195 {
00196   int i;
00197   SizeIsConst_ = Map.ConstantElementSize();
00198   int MinAllGID = Map.MinAllGID();
00199   int MaxAllGID = Map.MaxAllGID();
00200   // DirectoryMap will have a range of elements from the minimum to the maximum
00201   // GID of the user map, and an IndexBase of MinAllGID from the user map
00202   int Dir_NumGlobalElements = MaxAllGID - MinAllGID + 1;
00203 
00204   // Create a uniform linear map to contain the directory
00205   DirectoryMap_ = new Epetra_Map( Dir_NumGlobalElements, MinAllGID, Map.Comm() );
00206 
00207   int Dir_NumMyElements = DirectoryMap_->NumMyElements(); // Get NumMyElements
00208 
00209 
00210 
00211   // Allocate Processor list and Local Index List.  Initialize to -1s.
00212 
00213   if (Dir_NumMyElements>0) {
00214     ProcList_ = new int[ Dir_NumMyElements ];
00215     LocalIndexList_ = new int[ Dir_NumMyElements ];
00216     if (!SizeIsConst_) SizeList_ = new int[ Dir_NumMyElements ];
00217     // Initialize values to -1 in case the user global element list does
00218     // fill all IDs from MinAllGID to MaxAllGID (e.g., allows global indices to be 
00219     // all even integers.
00220     for (i=0; i<Dir_NumMyElements; i++) {
00221       ProcList_[i] = -1;
00222       LocalIndexList_[i] = -1;
00223       if (!SizeIsConst_) SizeList_[i] = -1;
00224     }
00225   }
00226 
00227   
00228   // Get list of processors owning the directory entries for the Map GIDs
00229 
00230   int MyPID = Map.Comm().MyPID();
00231 
00232   int Map_NumMyElements = Map.NumMyElements();
00233   int * send_procs = 0;
00234   if (Map_NumMyElements>0) send_procs = new int[Map_NumMyElements];
00235   int * Map_MyGlobalElements = Map.MyGlobalElements();
00236 
00237   EPETRA_CHK_ERR(DirectoryMap_->RemoteIDList(Map_NumMyElements,
00238                Map_MyGlobalElements, 
00239                send_procs, 0));
00240 
00241   bool det_flag = true;
00242 
00243   int num_recvs=0;
00244     
00245   Epetra_Distributor * Distor = Map.Comm().CreateDistributor();
00246 
00247   EPETRA_CHK_ERR(Distor->CreateFromSends( Map_NumMyElements, send_procs, det_flag, num_recvs ));
00248 
00249   if (Map_NumMyElements>0) delete [] send_procs;
00250 
00251   int * export_elements = 0;
00252   char * c_import_elements = 0;
00253   int * import_elements = 0;
00254   int len_import_elements = 0;
00255   int * ElementSizeList = 0;
00256 
00257   int packetSize = 3; // Assume we will send GIDs, PIDs and LIDs (will increase to 4 if also sending sizes)
00258   if (!SizeIsConst_) packetSize++; // Must send element size info also
00259  
00260   if (Map_NumMyElements>0) {
00261     if (!SizeIsConst_) ElementSizeList = Map.ElementSizeList();
00262     export_elements = new int[ packetSize * Map_NumMyElements ];
00263     int * ptr = export_elements;
00264     for( i = 0; i < Map_NumMyElements; i++ )
00265       {
00266   *ptr++ = Map_MyGlobalElements[i];
00267   *ptr++ = MyPID;
00268   *ptr++ = i;
00269   if (!SizeIsConst_) *ptr++ = ElementSizeList[i];
00270       }
00271   }
00272 
00273   //if (num_recvs>0) import_elements = new int[ packetSize * num_recvs ];
00274   //for (i=0; i< packetSize*num_recvs; i++) import_elements[i] = 0;
00275 
00276   EPETRA_CHK_ERR(Distor->Do(reinterpret_cast<char *> (export_elements), 
00277           packetSize * (int)sizeof( int ),
00278           len_import_elements,
00279           c_import_elements ));
00280 
00281   import_elements = reinterpret_cast<int *>(c_import_elements);
00282   
00283   //bool MYPID = (Map.Comm().MyPID()==0);
00284   int curr_LID;
00285   //if (MYPID) cout << "Processor " << Map.Comm().MyPID()<< "  num_recvs = "<< num_recvs << endl << flush;
00286   int * ptr = import_elements;
00287   for( i = 0; i < num_recvs; i++ )
00288   {
00289     curr_LID = DirectoryMap_->LID(*ptr++); // Convert incoming GID to Directory LID
00290     //if (MYPID) cout << " Receive ID = " << i << "  GID = " << import_elements[3*i] << "  LID = " << curr_LID << endl << flush;
00291     assert(curr_LID !=-1); // Internal error
00292     int proc = *ptr++;
00293     if (ProcList_[curr_LID] >= 0) {
00294       if (ProcList_[curr_LID] != proc) {
00295   if (numProcLists_ < 1) {
00296     create_ProcListArrays();
00297   }
00298 
00299   addProcToList(ProcList_[curr_LID], curr_LID);
00300   addProcToList(proc, curr_LID);
00301 
00302   //leave the lowest-numbered proc in ProcList_[curr_LID].
00303   ProcList_[curr_LID] = ProcListLists_[curr_LID][0];
00304       }
00305     }
00306     else {
00307       ProcList_[curr_LID] = proc;
00308     }
00309     LocalIndexList_[ curr_LID ] = *ptr++;
00310     if (!SizeIsConst_) SizeList_[ curr_LID ] = *ptr++;
00311   }
00312 
00313   int localval, globalval;
00314   localval = numProcLists_;
00315   DirectoryMap_->Comm().MaxAll(&localval, &globalval, 1);
00316   entryOnMultipleProcs_ = globalval > 0 ? true : false;
00317 
00318   if (len_import_elements!=0) delete [] c_import_elements;
00319   if (export_elements!=0) delete [] export_elements;
00320   
00321   delete Distor;
00322   return(0);
00323 }
00324 
00325 //==============================================================================
00326 bool Epetra_BasicDirectory::GIDsAllUniquelyOwned() const
00327 {
00328   return( !entryOnMultipleProcs_ );
00329 }
00330 
00331 //==============================================================================
00332 // GetDirectoryEntries: Get non-local GID references ( procID and localID )
00333 //      Space should already be allocated for Procs and
00334 //          LocalEntries.
00335 int Epetra_BasicDirectory::GetDirectoryEntries( const Epetra_BlockMap& Map,
00336             const int NumEntries,
00337             const int * GlobalEntries,
00338             int * Procs,
00339             int * LocalEntries,
00340             int * EntrySizes,
00341             bool high_rank_sharing_procs) const
00342 {
00343   int ierr = 0;
00344   int j;
00345   int i;
00346   int MyPID = Map.Comm().MyPID();
00347   int NumProc = Map.Comm().NumProc();
00348   int n_over_p = Map.NumGlobalElements() / NumProc;
00349 
00350   // Test for simple cases
00351 
00352   // Uniprocessor and local map cases
00353 
00354   if (!Map.DistributedGlobal()) {
00355     int ElementSize = 0;
00356     int * ElementSizeList = 0;
00357     bool ConstantElementSize = Map.ConstantElementSize();
00358     if (ConstantElementSize)
00359       ElementSize = Map.MaxElementSize();
00360     else
00361       ElementSizeList = Map.ElementSizeList();
00362     for (i=0; i<NumEntries; i++) {
00363       int LID = Map.LID(GlobalEntries[i]); // Get LID
00364       // Procs[i] will be MyPID, or -1 if the GID is not owned by this map
00365       if (LID==-1) {
00366   Procs[i] = -1; 
00367   ierr = 1; // Send warning error back that one of the GIDs is not part of this map
00368       }
00369       else Procs[i] = MyPID;
00370 
00371       // Put LID in return array if needed
00372       if (LocalEntries!=0) LocalEntries[i] = LID;
00373       
00374       // Fill EntrySizes if needed
00375       if (EntrySizes!=0) {
00376   if (ConstantElementSize)
00377     EntrySizes[i] = ElementSize;
00378   else if (LID>-1) 
00379     EntrySizes[i] = ElementSizeList[LID];
00380   else
00381     EntrySizes[i] = 0;
00382       }
00383     }
00384     EPETRA_CHK_ERR(ierr);
00385     return(0);
00386   }
00387 
00388   // Linear Map case
00389   if (Map.LinearMap()) {
00390     
00391     int MinAllGID = Map.MinAllGID(); // Get Min of all GID
00392     int MaxAllGID = Map.MaxAllGID(); // Get Max of all GID
00393     for (i=0; i<NumEntries; i++) {
00394       int LID = -1; // Assume not found
00395       int Proc = -1;
00396       int GID = GlobalEntries[i];
00397       if (GID<MinAllGID) ierr = 1;
00398       else if (GID>MaxAllGID) ierr = 1;
00399       else {
00400   // Guess uniform distribution and start a little above it
00401   int Proc1 = EPETRA_MIN(GID/EPETRA_MAX(n_over_p,1) + 2, NumProc-1);
00402   bool found = false;
00403   while (Proc1 >= 0 && Proc1< NumProc) {
00404     if (AllMinGIDs_[Proc1]<=GID) {
00405       if (GID <AllMinGIDs_[Proc1+1]) {
00406       found = true;
00407       break;
00408       }
00409       else Proc1++;
00410     }
00411     else Proc1--;
00412   }
00413   if (found) {
00414     Proc = Proc1;
00415     LID = GID - AllMinGIDs_[Proc];
00416   }
00417       }
00418       Procs[i] = Proc;
00419       if (LocalEntries!=0) LocalEntries[i] = LID;
00420     }
00421     if (EntrySizes!=0) {
00422       if (Map.ConstantElementSize()) {
00423   int ElementSize = Map.MaxElementSize();
00424   for (i=0; i<NumEntries; i++) EntrySizes[i] = ElementSize;
00425       }
00426       else {
00427   int * ElementSizeList = Map.ElementSizeList(); // We know this exists
00428   
00429   
00430   Epetra_Distributor * Size_Distor = Map.Comm().CreateDistributor();
00431   
00432   int Size_num_sends;
00433   int * Size_send_gids = 0;
00434   int * Size_send_procs = 0;
00435 
00436   
00437   EPETRA_CHK_ERR(Size_Distor->CreateFromRecvs( NumEntries, GlobalEntries, Procs, true,
00438                    Size_num_sends, Size_send_gids, Size_send_procs ));
00439   
00440   int * Size_exports = 0;
00441   char * c_Size_imports = 0;
00442   int * Size_imports = 0;
00443   if (Size_num_sends>0) {
00444     Size_exports = new int[ 2 * Size_num_sends ];
00445     for( i = 0; i < Size_num_sends; i++ )
00446       {
00447         int Size_curr_GID = Size_send_gids[i];
00448         int Size_curr_LID = Map.LID(Size_curr_GID);
00449         assert(Size_curr_LID!=-1); // Internal error 
00450         Size_exports[2*i] = Size_curr_GID;
00451         int Size_curr_size = ElementSizeList[Size_curr_LID];
00452         Size_exports[2*i+1] = Size_curr_size;
00453       }
00454   }
00455   
00456         int len_Size_imports = 0;
00457   EPETRA_CHK_ERR(Size_Distor->Do( reinterpret_cast<char*> (Size_exports),
00458                                         2 * (int)sizeof( int ),
00459                                         len_Size_imports,
00460                                         c_Size_imports));
00461   Size_imports = reinterpret_cast<int*>(c_Size_imports);
00462   
00463   for( i = 0; i < NumEntries; i++ )
00464     {
00465 
00466       // Need to change !!!!
00467       //bool found = false;
00468       int Size_curr_LID = Size_imports[2*i];
00469       for( j = 0; j < NumEntries; j++ )
00470         if( Size_curr_LID == GlobalEntries[j] )
00471     {
00472       EntrySizes[j] = Size_imports[2*i+1];
00473       // found = true;
00474       break;
00475     }
00476       //  if (!found) cout << "Internal error:  Epetra_BasicDirectory::GetDirectoryEntries: Global Index " << curr_LID
00477       //       << " not on processor " << MyPID << endl; abort();
00478     }
00479   
00480   if( Size_send_gids != 0 ) delete [] Size_send_gids;
00481   if( Size_send_procs != 0 ) delete [] Size_send_procs;
00482   
00483   if( len_Size_imports != 0 ) delete [] c_Size_imports;
00484   if( Size_exports != 0 ) delete [] Size_exports;
00485   
00486   delete Size_Distor;
00487       }
00488     }
00489     EPETRA_CHK_ERR(ierr);
00490     return(0);
00491   }
00492 
00493   // General case (need to set up an actual directory structure)
00494   
00495   int PacketSize = 2; // We will send at least the GID and PID.  Might also send LID and Size info
00496   bool DoSizes = false;
00497   if (EntrySizes!=0) {
00498     if (Map.ConstantElementSize()) {
00499       int ElementSize = Map.MaxElementSize();
00500   for (i=0; i<NumEntries; i++) EntrySizes[i] = ElementSize;
00501     }
00502     else {
00503       DoSizes = true;
00504       PacketSize++; // Sending Size info
00505     }
00506   }
00507 
00508   bool DoLIDs = (LocalEntries!=0); // Do LIDs?
00509   if (DoLIDs) PacketSize++; // Sending LIDs also
00510 
00511   
00512   Epetra_Distributor * Distor = DirectoryMap_->Comm().CreateDistributor();
00513   
00514   
00515   int * dir_procs = 0;
00516   if (NumEntries>0) dir_procs = new int[ NumEntries ];
00517   
00518   // Get directory locations for the requested list of entries
00519   DirectoryMap_->RemoteIDList(NumEntries, GlobalEntries, dir_procs, 0);
00520 
00521   //Check for unfound GlobalEntries and set corresponding Procs to -1
00522   int NumMissing = 0;
00523   {for( i = 0; i < NumEntries; ++i )
00524     if( dir_procs[i] == -1 )
00525     {
00526       Procs[i] = -1;
00527       if (DoLIDs) LocalEntries[i] = -1;
00528       ++NumMissing;
00529   }}
00530 
00531   int num_sends;
00532   int * send_gids = 0;
00533   int * send_procs = 0;
00534   
00535   EPETRA_CHK_ERR(Distor->CreateFromRecvs( NumEntries, GlobalEntries, dir_procs, true,
00536              num_sends, send_gids, send_procs));
00537 
00538   if (NumEntries>0) delete [] dir_procs;
00539 
00540 
00541   int curr_LID;
00542   int * exports = 0;
00543   char * c_imports = 0;
00544   int * imports = 0;
00545   int len_imports = 0;
00546   if (num_sends>0) {
00547     exports = new int[ PacketSize * num_sends ];
00548     int * ptr = exports;
00549     for( i = 0; i < num_sends; i++ )
00550       {
00551   int curr_GID = send_gids[i];
00552   *ptr++ = curr_GID;
00553   curr_LID = DirectoryMap_->LID(curr_GID);
00554   assert(curr_LID!=-1); // Internal error 
00555   if (high_rank_sharing_procs==false) {
00556     *ptr++ = ProcList_[ curr_LID ];
00557   }
00558   else {
00559     //high_rank_sharing_procs==true means that if multiple procs share a
00560     //GID, we want to use the proc with highest rank rather than the
00561     //proc with lowest rank.
00562     if (numProcLists_ > 0) {
00563       int num = ProcListLens_[curr_LID];
00564       if (num > 1) {
00565         *ptr++ = ProcListLists_[curr_LID][num-1];
00566       }
00567       else {
00568         *ptr++ = ProcList_[ curr_LID ];
00569       }
00570     }
00571     else {
00572       *ptr++ = ProcList_[ curr_LID ];
00573     }
00574   }
00575 
00576   if (DoLIDs) *ptr++ = LocalIndexList_[curr_LID];
00577   if (DoSizes) *ptr++ = SizeList_[curr_LID];
00578       }
00579   }
00580 
00581   int NumRecv = NumEntries - NumMissing;
00582   EPETRA_CHK_ERR(Distor->Do(reinterpret_cast<char*> (exports),
00583                             PacketSize * (int)sizeof( int ),
00584                             len_imports,
00585                             c_imports));
00586   imports = reinterpret_cast<int*>(c_imports);
00587 
00588   //create a sorted copy of the GlobalEntries array, along with a companion
00589   //array that will allow us to put result arrays (Procs, LocalEntries &
00590   //EntrySizes) in the same order as the unsorted GlobalEntries array
00591   int* sortedGE = new int[NumEntries*2];
00592   int* offsets = sortedGE+NumEntries;
00593   for(i=0; i<NumEntries; ++i) {
00594     offsets[i] = i;
00595   }
00596 
00597   memcpy(sortedGE, GlobalEntries, NumEntries*sizeof(int));
00598   Epetra_Util Utils;
00599   Utils.Sort(true, NumEntries, sortedGE, 0, 0, 1, &offsets);
00600 
00601   int * ptr = imports;
00602   int insertPoint; //insertPoint won't be used, but is argument to binary_search
00603 
00604   for( i = 0; i < NumRecv; i++ ) {
00605     curr_LID = *ptr++;
00606     j = Epetra_Util_binary_search(curr_LID, sortedGE, NumEntries, insertPoint);
00607     if (j > -1) {
00608       Procs[offsets[j]] = *ptr++;
00609       if (DoLIDs) LocalEntries[offsets[j]] = *ptr++;
00610       if (DoSizes) EntrySizes[offsets[j]] = *ptr++;
00611     }
00612   }
00613 
00614   delete [] sortedGE;
00615 
00616   if( send_gids ) delete [] send_gids;
00617   if( send_procs ) delete [] send_procs;
00618   
00619   if( len_imports ) delete [] c_imports;
00620   if( exports ) delete [] exports;
00621 
00622   delete Distor;
00623   return(0);
00624 }
00625 
00626 //==============================================================================
00627 void Epetra_BasicDirectory::Print( ostream & os) const {
00628   
00629   int MyPID;
00630   if( DirectoryMap_ != 0 ) {;
00631     MyPID = DirectoryMap_->Comm().MyPID();
00632     os << MyPID << " Epetra_BasicDirectory Object: "
00633       << DirectoryMap_->NumMyElements() << endl;
00634     for( int i = 0; i < DirectoryMap_->NumMyElements(); i++ ) {
00635       os << " " << i << " " << ProcList_[i] << " "
00636    << LocalIndexList_[i];
00637       if (!SizeIsConst_)
00638   os  << " " <<  SizeList_[i];
00639       os << endl;
00640       os << endl;
00641     }
00642   }
00643   else
00644   {
00645     cout << "Epetra_BasicDirectory not setup<<<<<<" << endl;
00646   }
00647 
00648   return;
00649 }
00650 
00651 //--------------------------------------------------------------------------------
00652 Epetra_BasicDirectory& Epetra_BasicDirectory::operator=(const Epetra_BasicDirectory& src)
00653 {
00654   (void)src;
00655   //not currently supported
00656   bool throw_error = true;
00657   if (throw_error) {
00658     std::cerr << std::endl
00659         << "Epetra_BasicDirectory::operator= not supported."
00660         << std::endl;
00661     throw -1;
00662   }
00663   return( *this );
00664 }

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