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