Epetra Package Browser (Single Doxygen Collection) Development
Epetra_FEVbrMatrix.cpp
Go to the documentation of this file.
00001 
00002 //@HEADER
00003 // ************************************************************************
00004 //
00005 //               Epetra: 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 #include <Epetra_ConfigDefs.h>
00044 #include <Epetra_FEVbrMatrix.h>
00045 #include <Epetra_BlockMap.h>
00046 #include <Epetra_Map.h>
00047 #include <Epetra_Import.h>
00048 #include <Epetra_Export.h>
00049 #include <Epetra_Vector.h>
00050 #include <Epetra_MultiVector.h>
00051 #include <Epetra_Comm.h>
00052 #include <Epetra_Distributor.h>
00053 #include <Epetra_Util.h>
00054 
00055 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES // FIXME
00056 // FIXME long long : whole file
00057 
00058 //----------------------------------------------------------------------------
00059 Epetra_FEVbrMatrix::Epetra_FEVbrMatrix(Epetra_DataAccess CV,
00060                const Epetra_BlockMap& rowMap,
00061                int *NumBlockEntriesPerRow,
00062                bool ignoreNonLocalEntries)
00063   : Epetra_VbrMatrix(CV, rowMap, NumBlockEntriesPerRow),
00064     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00065     numNonlocalBlockRows_(0),
00066     nonlocalBlockRows_(NULL),
00067     nonlocalBlockRowLengths_(NULL),
00068     nonlocalBlockRowAllocLengths_(NULL),
00069     nonlocalBlockCols_(NULL),
00070     nonlocalCoefs_(NULL),
00071     curRowOffset_(-1),
00072     curColOffset_(-1),
00073     curNumCols_(0),
00074     curCols_(NULL),
00075     curMode_(Add)
00076 {
00077 }
00078 
00079 //----------------------------------------------------------------------------
00080 Epetra_FEVbrMatrix::Epetra_FEVbrMatrix(Epetra_DataAccess CV,
00081                const Epetra_BlockMap& rowMap,
00082                int NumBlockEntriesPerRow,
00083                bool ignoreNonLocalEntries)
00084   : Epetra_VbrMatrix(CV, rowMap, NumBlockEntriesPerRow),
00085     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00086     numNonlocalBlockRows_(0),
00087     nonlocalBlockRows_(NULL),
00088     nonlocalBlockRowLengths_(NULL),
00089     nonlocalBlockRowAllocLengths_(NULL),
00090     nonlocalBlockCols_(NULL),
00091     nonlocalCoefs_(NULL),
00092     curRowOffset_(-1),
00093     curColOffset_(0),
00094     curNumCols_(0),
00095     curCols_(NULL),
00096     curMode_(Add)
00097 {
00098 }
00099 
00100 //----------------------------------------------------------------------------
00101 Epetra_FEVbrMatrix::Epetra_FEVbrMatrix(Epetra_DataAccess CV,
00102                const Epetra_BlockMap& rowMap,
00103                const Epetra_BlockMap& colMap,
00104                int *NumBlockEntriesPerRow,
00105                bool ignoreNonLocalEntries)
00106   : Epetra_VbrMatrix(CV, rowMap, colMap, NumBlockEntriesPerRow),
00107     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00108     numNonlocalBlockRows_(0),
00109     nonlocalBlockRows_(NULL),
00110     nonlocalBlockRowLengths_(NULL),
00111     nonlocalBlockRowAllocLengths_(NULL),
00112     nonlocalBlockCols_(NULL),
00113     nonlocalCoefs_(NULL),
00114     curRowOffset_(-1),
00115     curColOffset_(-1),
00116     curNumCols_(0),
00117     curCols_(NULL),
00118     curMode_(Add)
00119 {
00120 }
00121 
00122 //----------------------------------------------------------------------------
00123 Epetra_FEVbrMatrix::Epetra_FEVbrMatrix(Epetra_DataAccess CV,
00124                const Epetra_BlockMap& rowMap,
00125                const Epetra_BlockMap& colMap,
00126                int NumBlockEntriesPerRow,
00127                bool ignoreNonLocalEntries)
00128   : Epetra_VbrMatrix(CV, rowMap, colMap, NumBlockEntriesPerRow),
00129     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00130     numNonlocalBlockRows_(0),
00131     nonlocalBlockRows_(NULL),
00132     nonlocalBlockRowLengths_(NULL),
00133     nonlocalBlockRowAllocLengths_(NULL),
00134     nonlocalBlockCols_(NULL),
00135     nonlocalCoefs_(NULL),
00136     curRowOffset_(-1),
00137     curColOffset_(0),
00138     curNumCols_(0),
00139     curCols_(NULL),
00140     curMode_(Add)
00141 {
00142 }
00143 
00144 //----------------------------------------------------------------------------
00145 Epetra_FEVbrMatrix::Epetra_FEVbrMatrix(Epetra_DataAccess CV,
00146                const Epetra_CrsGraph& graph,
00147                bool ignoreNonLocalEntries)
00148   : Epetra_VbrMatrix(CV, graph),
00149     ignoreNonLocalEntries_(ignoreNonLocalEntries),
00150     numNonlocalBlockRows_(0),
00151     nonlocalBlockRows_(NULL),
00152     nonlocalBlockRowLengths_(NULL),
00153     nonlocalBlockRowAllocLengths_(NULL),
00154     nonlocalBlockCols_(NULL),
00155     nonlocalCoefs_(NULL),
00156     curRowOffset_(-1),
00157     curColOffset_(0),
00158     curNumCols_(0),
00159     curCols_(NULL),
00160     curMode_(Add)
00161 {
00162 }
00163 
00164 //----------------------------------------------------------------------------
00165 Epetra_FEVbrMatrix::Epetra_FEVbrMatrix(const Epetra_FEVbrMatrix& src)
00166   : Epetra_VbrMatrix(src),
00167     ignoreNonLocalEntries_(src.ignoreNonLocalEntries_),
00168     numNonlocalBlockRows_(0),
00169     nonlocalBlockRows_(NULL),
00170     nonlocalBlockRowLengths_(NULL),
00171     nonlocalBlockRowAllocLengths_(NULL),
00172     nonlocalBlockCols_(NULL),
00173     nonlocalCoefs_(NULL),
00174     curRowOffset_(-1),
00175     curColOffset_(0),
00176     curNumCols_(0),
00177     curCols_(NULL),
00178     curMode_(Add)
00179 {
00180   operator=(src);
00181 }
00182 
00183 //----------------------------------------------------------------------------
00184 Epetra_FEVbrMatrix& Epetra_FEVbrMatrix::operator=(const Epetra_FEVbrMatrix& src)
00185 {
00186   if (this == &src) {
00187     return( *this );
00188   }
00189 
00190   Epetra_VbrMatrix::operator=(src);
00191 
00192   numNonlocalBlockRows_ = src.numNonlocalBlockRows_;
00193 
00194   nonlocalBlockRows_ = new int[numNonlocalBlockRows_];
00195   nonlocalBlockRowLengths_ = new int[numNonlocalBlockRows_];
00196   nonlocalBlockRowAllocLengths_ = new int[numNonlocalBlockRows_];
00197   nonlocalBlockCols_ = new int*[numNonlocalBlockRows_];
00198   nonlocalCoefs_ = new Epetra_SerialDenseMatrix**[numNonlocalBlockRows_];
00199 
00200   for(int i=0; i<numNonlocalBlockRows_; ++i) {
00201     nonlocalBlockRows_[i] = src.nonlocalBlockRows_[i];
00202     nonlocalBlockRowLengths_[i] = src.nonlocalBlockRowLengths_[i];
00203     nonlocalBlockRowAllocLengths_[i] = src.nonlocalBlockRowAllocLengths_[i];
00204 
00205     for(int j=0; j<nonlocalBlockRowLengths_[i]; ++j) {
00206       nonlocalBlockCols_[i][j] = src.nonlocalBlockCols_[i][j];
00207 
00208       nonlocalCoefs_[i][j] = new Epetra_SerialDenseMatrix(*(src.nonlocalCoefs_[i][j]));
00209     }
00210   }
00211 
00212   return( *this );
00213 }
00214 
00215 //----------------------------------------------------------------------------
00216 Epetra_FEVbrMatrix::~Epetra_FEVbrMatrix()
00217 {
00218   destroyNonlocalData();
00219 }
00220 
00221 //----------------------------------------------------------------------------
00222 void Epetra_FEVbrMatrix::destroyNonlocalData()
00223 {
00224   for(int i=0; i<numNonlocalBlockRows_; ++i) {
00225     delete [] nonlocalBlockCols_[i];
00226     for(int j=0; j<nonlocalBlockRowLengths_[i]; ++j) {
00227       delete nonlocalCoefs_[i][j];
00228     }
00229     delete [] nonlocalCoefs_[i];
00230   }
00231 
00232   delete [] nonlocalCoefs_;
00233   delete [] nonlocalBlockCols_;
00234   delete [] nonlocalBlockRowAllocLengths_;
00235   delete [] nonlocalBlockRowLengths_;
00236   delete [] nonlocalBlockRows_;
00237 
00238   numNonlocalBlockRows_ = 0;
00239   nonlocalBlockRows_ = NULL;
00240   nonlocalBlockRowLengths_ = NULL;
00241   nonlocalBlockRowAllocLengths_ = NULL;
00242   nonlocalBlockCols_ = NULL;
00243   nonlocalCoefs_ = NULL;
00244 }
00245 
00246 //----------------------------------------------------------------------------
00247 int Epetra_FEVbrMatrix::PutScalar(double ScalarConstant)
00248 {
00249   for(int i=0; i<numNonlocalBlockRows_; ++i) {
00250     for(int j=0; j<nonlocalBlockRowLengths_[i]; ++j) {
00251       Epetra_SerialDenseMatrix& A = *(nonlocalCoefs_[i][j]);
00252       double* values = A.A();
00253       int lda = A.LDA();
00254       int n = A.N();
00255       for(int k=0; k<lda*n; ++k) {
00256   values[k] = ScalarConstant;
00257       }
00258     }
00259   }
00260 
00261   return( Epetra_VbrMatrix::PutScalar(ScalarConstant) );
00262 }
00263 
00264 //----------------------------------------------------------------------------
00265 
00266 int Epetra_FEVbrMatrix::GlobalAssemble(bool callFillComplete)
00267 {
00268   if(Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) {
00269     if(callFillComplete) {
00270       EPETRA_CHK_ERR(FillComplete());
00271     }
00272 
00273     return(0);
00274   }
00275 
00276   int i;
00277 
00278   //In this method we need to gather all the non-local (overlapping) data
00279   //that's been input on each processor, into the
00280   //non-overlapping distribution defined by the map that 'this' matrix was
00281   //constructed with.
00282 
00283   //Need to build a map that describes our nonlocal data.
00284 
00285   //First, create a list of the sizes (point-rows per block-row) of the
00286   //nonlocal rows we're holding.
00287   int* pointRowsPerNonlocalBlockRow = numNonlocalBlockRows_>0 ?
00288     new int[numNonlocalBlockRows_] : NULL;
00289 
00290   for(i=0; i<numNonlocalBlockRows_; ++i) {
00291     pointRowsPerNonlocalBlockRow[i] = nonlocalCoefs_[i][0]->M();
00292   }
00293 
00294   //We'll use the arbitrary distribution constructor of BlockMap.
00295 
00296   Epetra_BlockMap sourceMap(-1, numNonlocalBlockRows_, nonlocalBlockRows_, // CJ TODO FIXME long long
00297           pointRowsPerNonlocalBlockRow,
00298           RowMap().IndexBase(), RowMap().Comm());
00299 
00300   delete [] pointRowsPerNonlocalBlockRow;
00301 
00302   //If sourceMap has global size 0, then no nonlocal data exists and we can
00303   //skip most of this function.
00304   if(sourceMap.NumGlobalElements64() < 1) {
00305     if(callFillComplete) {
00306       EPETRA_CHK_ERR(FillComplete());
00307     }
00308     return(0);
00309   }
00310 
00311   //We also need to build a column-map, containing the columns in our
00312   //nonlocal data. To do that, create a list of all column-indices that
00313   //occur in our nonlocal rows.
00314 
00315   int numCols = 0, allocLen = 0;
00316   int* cols = NULL;
00317   int* pointColsPerBlockCol = NULL;
00318   int ptColAllocLen = 0;
00319   int insertPoint = -1;
00320 
00321   for(i=0; i<numNonlocalBlockRows_; ++i) {
00322     for(int j=0; j<nonlocalBlockRowLengths_[i]; ++j) {
00323       int col = nonlocalBlockCols_[i][j];
00324       int offset = Epetra_Util_binary_search(col, cols, numCols, insertPoint);
00325       if (offset < 0) {
00326   EPETRA_CHK_ERR( Epetra_Util_insert(col, insertPoint, cols,
00327              numCols, allocLen) );
00328   int tmpNumCols = numCols-1;
00329   EPETRA_CHK_ERR( Epetra_Util_insert(nonlocalCoefs_[i][j]->N(),
00330              insertPoint,
00331              pointColsPerBlockCol,
00332              tmpNumCols, ptColAllocLen) );
00333       }
00334     }
00335   }
00336 
00337   Epetra_BlockMap colMap(-1, numCols, cols, // CJ TODO FIXME long long
00338        pointColsPerBlockCol,
00339        RowMap().IndexBase(), RowMap().Comm());
00340 
00341   delete [] cols;
00342   delete [] pointColsPerBlockCol;
00343   numCols = 0;
00344   allocLen = 0;
00345 
00346   //now we need to create a matrix with sourceMap and colMap, and fill it with
00347   //our nonlocal data so we can then export it to the correct owning
00348   //processors.
00349 
00350   Epetra_VbrMatrix tempMat(Copy, sourceMap, colMap, nonlocalBlockRowLengths_);
00351 
00352 
00353   //Next we need to make sure the 'indices-are-global' attribute of tempMat's
00354   //graph is set to true, in case this processor doesn't end up calling the
00355   //InsertGlobalValues method...
00356 
00357   const Epetra_CrsGraph& graph = tempMat.Graph();
00358   Epetra_CrsGraph& nonconst_graph = const_cast<Epetra_CrsGraph&>(graph);
00359   nonconst_graph.SetIndicesAreGlobal(true);
00360 
00361   for(i=0; i<numNonlocalBlockRows_; ++i) {
00362     EPETRA_CHK_ERR( tempMat.BeginInsertGlobalValues(nonlocalBlockRows_[i],
00363                 nonlocalBlockRowLengths_[i],
00364                 nonlocalBlockCols_[i]) );
00365 
00366     for(int j=0; j<nonlocalBlockRowLengths_[i]; ++j) {
00367       Epetra_SerialDenseMatrix& subblock = *(nonlocalCoefs_[i][j]);
00368 
00369       EPETRA_CHK_ERR( tempMat.SubmitBlockEntry(subblock.A(),
00370                  subblock.LDA(),
00371                  subblock.M(),
00372                  subblock.N()) );
00373     }
00374 
00375     EPETRA_CHK_ERR( tempMat.EndSubmitEntries() );
00376   }
00377 
00378   //Now we need to call FillComplete on our temp matrix. We need to
00379   //pass a DomainMap and RangeMap, which are not the same as the RowMap
00380   //and ColMap that we constructed the matrix with.
00381   EPETRA_CHK_ERR(tempMat.FillComplete(DomainMap(), RangeMap()));
00382 
00383   //Finally, we're ready to create the exporter and export non-local data to
00384   //the appropriate owning processors.
00385 
00386   Epetra_Export exporter(tempMat.RowMap(), RowMap());
00387 
00388   EPETRA_CHK_ERR( Export(tempMat, exporter, Add) );
00389 
00390   if(callFillComplete) {
00391     EPETRA_CHK_ERR(FillComplete());
00392   }
00393 
00394   destroyNonlocalData();
00395 
00396   return(0);
00397 }
00398 
00399 //----------------------------------------------------------------------------
00400 int Epetra_FEVbrMatrix::InputNonlocalBlockEntry(double *values, int LDA,
00401             int NumRows, int NumCols)
00402 {
00403   if (curRowOffset_ < 0) {
00404     return(-1);
00405   }
00406 
00407   int insertPoint;
00408   int col = curCols_[curColOffset_++];
00409   int coloffset =
00410     Epetra_Util_binary_search(col, nonlocalBlockCols_[curRowOffset_],
00411             nonlocalBlockRowLengths_[curRowOffset_],
00412             insertPoint);
00413   if (coloffset < 0) return(-1);
00414 
00415   Epetra_SerialDenseMatrix*& subblock = nonlocalCoefs_[curRowOffset_][coloffset];
00416 
00417   if (subblock == NULL) {
00418     //For the construction of the serial dense matrix here, we choose Copy mode
00419     //in case the user deletes or reuses the Values array after this method is
00420     //called.
00421     subblock = new Epetra_SerialDenseMatrix(Copy, values, LDA, NumRows, NumCols);
00422 
00423     if (subblock == NULL) {
00424       return(-1);
00425     }
00426   }
00427   else {
00428     int nrows = subblock->M();
00429     int ncols = subblock->N();
00430     if (nrows != NumRows || ncols != NumCols) {
00431       return(-1);
00432     }
00433 
00434     int Target_LDA = subblock->LDA();
00435     int Source_LDA = LDA;
00436     double* tptr = subblock->A();
00437     double* sptr = values;
00438     if (curMode_ == Add) {
00439       for(int j=0; j<NumCols; ++j) {
00440         for(int i=0; i<NumRows; ++i) {
00441           tptr[i] += sptr[i];
00442         }
00443 
00444         tptr += Target_LDA;
00445         sptr += Source_LDA;
00446       }
00447     }
00448     else {
00449       for(int j=0; j<NumCols; ++j) {
00450         for(int i=0; i<NumRows; ++i) {
00451           tptr[i] = sptr[i];
00452         }
00453 
00454         tptr += Target_LDA;
00455         sptr += Source_LDA;
00456       }
00457     }
00458   }
00459 
00460   return(0);
00461 }
00462 
00463 //----------------------------------------------------------------------------
00464 int Epetra_FEVbrMatrix::InsertNonlocalRow(int row, int offset, int numCols)
00465 {
00466   //insert a new row in our list of nonlocal rows.
00467   //also insert new arrays to hold block-column-index information
00468 
00469   int alloc_len = numNonlocalBlockRows_;
00470   EPETRA_CHK_ERR( Epetra_Util_insert(row, offset, nonlocalBlockRows_,
00471              numNonlocalBlockRows_, alloc_len, 1) );
00472 
00473   int tmp1 = numNonlocalBlockRows_ - 1;
00474   int tmp2 = alloc_len - 1;
00475 
00476   EPETRA_CHK_ERR( Epetra_Util_insert(0, offset, nonlocalBlockRowLengths_,
00477              tmp1, tmp2, 1) );
00478 
00479   --tmp1;
00480   --tmp2;
00481   int initialAllocLen = numCols*2;
00482   EPETRA_CHK_ERR( Epetra_Util_insert(initialAllocLen, offset,
00483              nonlocalBlockRowAllocLengths_,
00484              tmp1, tmp2, 1) );
00485 
00486   int** newCols = new int*[numNonlocalBlockRows_];
00487   Epetra_SerialDenseMatrix*** newCoefs =
00488     new Epetra_SerialDenseMatrix**[numNonlocalBlockRows_];
00489 
00490   if (newCols == NULL || newCoefs == NULL) {
00491     return(-1);
00492   }
00493 
00494   newCols[offset] = new int[initialAllocLen];
00495   newCoefs[offset] = new Epetra_SerialDenseMatrix*[initialAllocLen];
00496 
00497   for(int j=0; j<initialAllocLen; ++j) {
00498     newCols[offset][j] = 0;
00499     newCoefs[offset][j] = (Epetra_SerialDenseMatrix*)NULL;
00500   }
00501 
00502   int index = 0;
00503   for(int i=0; i<numNonlocalBlockRows_-1; ++i) {
00504     if (i == offset) {
00505       ++index;
00506     }
00507 
00508     newCols[index] = nonlocalBlockCols_[i];
00509     newCoefs[index++] = nonlocalCoefs_[i];
00510   }
00511 
00512   delete [] nonlocalBlockCols_;
00513   delete [] nonlocalCoefs_;
00514 
00515   nonlocalBlockCols_ = newCols;
00516   nonlocalCoefs_ = newCoefs;
00517 
00518   return(0);
00519 }
00520 
00521 //--------------------------------------------------------------------------
00522 int Epetra_FEVbrMatrix::BeginInsertGlobalValues(int BlockRow,
00523             int NumBlockEntries,
00524             int * BlockIndices)
00525 {
00526   int myRow = LRID(BlockRow);
00527 
00528   if (myRow > -1) {
00529     return( Epetra_VbrMatrix::BeginInsertGlobalValues(BlockRow,
00530                    NumBlockEntries,
00531                    BlockIndices) );
00532   }
00533 
00534   return( SetupForNonlocalSubmits(BlockRow, NumBlockEntries,
00535           BlockIndices, false, Add) );
00536 }
00537 
00538 //--------------------------------------------------------------------------
00539 int Epetra_FEVbrMatrix::BeginReplaceGlobalValues(int BlockRow,
00540              int NumBlockEntries,
00541              int *BlockIndices)
00542 {
00543   int myRow = LRID(BlockRow);
00544 
00545   if (myRow > -1) {
00546     return( Epetra_VbrMatrix::BeginReplaceGlobalValues(BlockRow,
00547                    NumBlockEntries,
00548                    BlockIndices) );
00549   }
00550 
00551   return( SetupForNonlocalSubmits(BlockRow, NumBlockEntries,
00552           BlockIndices, false, Insert) );
00553 }
00554 
00555 //--------------------------------------------------------------------------
00556 int Epetra_FEVbrMatrix::BeginSumIntoGlobalValues(int BlockRow,
00557              int NumBlockEntries,
00558              int *BlockIndices)
00559 {
00560   int myRow = LRID(BlockRow);
00561 
00562   if (myRow > -1) {
00563     return( Epetra_VbrMatrix::BeginSumIntoGlobalValues(BlockRow,
00564                    NumBlockEntries,
00565                    BlockIndices) );
00566   }
00567 
00568   return( SetupForNonlocalSubmits(BlockRow, NumBlockEntries,
00569           BlockIndices, false, Add) );
00570 }
00571 
00572 //--------------------------------------------------------------------------
00573 int Epetra_FEVbrMatrix::SetupForNonlocalSubmits(int BlockRow,
00574             int NumBlockEntries,
00575             int * BlockIndices,
00576             bool indicesAreLocal,
00577             Epetra_CombineMode SubmitMode)
00578 {
00579   (void)indicesAreLocal;
00580   if (ignoreNonLocalEntries_) {
00581     curRowOffset_ = 0;
00582     return(0);
00583   }
00584 
00585   int insertPoint = -1;
00586 
00587   //find offset of this row in our list of nonlocal rows
00588   int rowoffset = Epetra_Util_binary_search(BlockRow, nonlocalBlockRows_,
00589               numNonlocalBlockRows_, insertPoint);
00590 
00591   //if this row is not already present, insert it
00592   if (rowoffset < 0) {
00593     EPETRA_CHK_ERR( InsertNonlocalRow(BlockRow, insertPoint, NumBlockEntries) );
00594     rowoffset = insertPoint;
00595   }
00596 
00597   //now insert each incoming block-column-index in this list of column-indices,
00598   //maintaining sortedness.
00599   for(int i=0; i<NumBlockEntries; ++i) {
00600     int col = BlockIndices[i];
00601     int coloffset = Epetra_Util_binary_search(col, nonlocalBlockCols_[rowoffset],
00602                nonlocalBlockRowLengths_[rowoffset],
00603                 insertPoint);
00604     if (coloffset < 0) {
00605       int tmp1 = nonlocalBlockRowLengths_[rowoffset];
00606       int tmp2 = nonlocalBlockRowAllocLengths_[rowoffset];
00607 
00608       EPETRA_CHK_ERR( Epetra_Util_insert(col, insertPoint,
00609            nonlocalBlockCols_[rowoffset],
00610           nonlocalBlockRowLengths_[rowoffset],
00611                 nonlocalBlockRowAllocLengths_[rowoffset]));
00612 
00613       EPETRA_CHK_ERR( Epetra_Util_insert((Epetra_SerialDenseMatrix*)NULL,
00614            insertPoint,
00615            nonlocalCoefs_[rowoffset],
00616            tmp1, tmp2) );
00617     }
00618   }
00619 
00620   curRowOffset_ = rowoffset;
00621   curColOffset_ = 0;
00622   curNumCols_ = NumBlockEntries;
00623   curCols_ = new int[NumBlockEntries];
00624   for(int j=0; j<NumBlockEntries; ++j) {
00625     curCols_[j] = BlockIndices[j];
00626   }
00627 
00628   curMode_ = SubmitMode;
00629 
00630   return(0);
00631 }
00632 
00633 //--------------------------------------------------------------------------
00634 int Epetra_FEVbrMatrix::SubmitBlockEntry(double *values,
00635            int LDA,
00636            int NumRows,
00637            int NumCols)
00638 {
00639   if (curRowOffset_ < 0) {
00640     EPETRA_CHK_ERR( Epetra_VbrMatrix::SubmitBlockEntry(values, LDA,
00641               NumRows, NumCols) );
00642   }
00643   else {
00644     if (ignoreNonLocalEntries_) {
00645       return(0);
00646     }
00647 
00648     EPETRA_CHK_ERR( InputNonlocalBlockEntry(values, LDA,
00649               NumRows, NumCols) );
00650   }
00651 
00652   return(0);
00653 }
00654 //--------------------------------------------------------------------------
00655 int Epetra_FEVbrMatrix::EndSubmitEntries()
00656 {
00657   if (curRowOffset_ < 0) {
00658     EPETRA_CHK_ERR( Epetra_VbrMatrix::EndSubmitEntries() );
00659   }
00660   else {
00661     curRowOffset_ = -1;
00662     curColOffset_ = -1;
00663     curNumCols_ = 0;
00664     delete [] curCols_;
00665   }
00666 
00667   return(0);
00668 }
00669 
00670 #endif // EPETRA_NO_32BIT_GLOBAL_INDICES
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines