IFPACK  Development
 All Classes Files Functions Variables Enumerations Friends
Ifpack_TriDiContainer.cpp
00001 /*@HEADER
00002 // ***********************************************************************
00003 //
00004 //       Ifpack: Object-Oriented Algebraic Preconditioner Package
00005 //                 Copyright (2002) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 //@HEADER
00041 */
00042 
00043 #include "Ifpack_ConfigDefs.h"
00044 #include "Ifpack_TriDiContainer.h"
00045 #include "Epetra_RowMatrix.h"
00046 
00047 //==============================================================================
00048 int Ifpack_TriDiContainer::NumRows() const
00049 {
00050   return(NumRows_);
00051 }
00052 
00053 //==============================================================================
00054 int Ifpack_TriDiContainer::Initialize()
00055 {
00056   
00057   IsInitialized_ = false;
00058 
00059   IFPACK_CHK_ERR(LHS_.Reshape(NumRows_,NumVectors_));
00060   IFPACK_CHK_ERR(RHS_.Reshape(NumRows_,NumVectors_));
00061   IFPACK_CHK_ERR(ID_.Reshape(NumRows_,NumVectors_));
00062   IFPACK_CHK_ERR(Matrix_.Reshape(NumRows_,NumRows_));
00063 
00064   // zero out matrix elements
00065   // for (int i = 0 ; i < NumRows_ ; ++i)
00066   //   for (int j = 0 ; j < NumRows_ ; ++j)
00067   //     Matrix_(i,j) = 0.0;
00068 
00069   if(Matrix_.A() == NULL ) Matrix_.Shape(NumRows_);
00070   int size = (NumRows_ == 1) ? 1 : 4*(NumRows_ -1);
00071   memset(Matrix_.A(),0,sizeof(double)*size);
00072 
00073   // zero out vector elements
00074   for (int i = 0 ; i < NumRows_ ; ++i)
00075     for (int j = 0 ; j < NumVectors_ ; ++j) {
00076       LHS_(i,j) = 0.0;
00077       RHS_(i,j) = 0.0;
00078     }
00079 
00080   // Set to -1 ID_'s
00081   for (int i = 0 ; i < NumRows_ ; ++i)
00082     ID_(i) = -1;  
00083 
00084   if (NumRows_ != 0) {
00085     IFPACK_CHK_ERR(Solver_.SetMatrix(Matrix_));
00086     IFPACK_CHK_ERR(Solver_.SetVectors(LHS_,RHS_));
00087   }
00088 
00089   IsInitialized_ = true;
00090   return(0);
00091   
00092 }
00093 
00094 //==============================================================================
00095 double& Ifpack_TriDiContainer::LHS(const int i, const int Vector)
00096 {
00097   return(LHS_.A()[Vector * NumRows_ + i]);
00098 }
00099   
00100 //==============================================================================
00101 double& Ifpack_TriDiContainer::RHS(const int i, const int Vector)
00102 {
00103   return(RHS_.A()[Vector * NumRows_ + i]);
00104 }
00105 
00106 //==============================================================================
00107 int Ifpack_TriDiContainer::
00108 SetMatrixElement(const int row, const int col, const double value)
00109 {
00110   if (IsInitialized() == false)
00111     IFPACK_CHK_ERR(Initialize());
00112 
00113   if ((row < 0) || (row >= NumRows())) {
00114     IFPACK_CHK_ERR(-2); // not in range
00115   }
00116 
00117   if ((col < 0) || (col >= NumRows())) {
00118     IFPACK_CHK_ERR(-2); // not in range
00119   }
00120 
00121   Matrix_(row, col) = value;
00122 
00123   return(0);
00124 
00125 }
00126 
00127 //==============================================================================
00128 int Ifpack_TriDiContainer::ApplyInverse()
00129 {
00130 
00131   if (!IsComputed()) {
00132     IFPACK_CHK_ERR(-1);
00133   }
00134   
00135   if (NumRows_ != 0)
00136     IFPACK_CHK_ERR(Solver_.Solve());
00137 
00138 #ifdef IFPACK_FLOPCOUNTERS
00139   ApplyInverseFlops_ += 2.0 * NumVectors_ * NumRows_ * NumRows_;
00140 #endif
00141   return(0);
00142 }
00143 
00144 //==============================================================================
00145 int& Ifpack_TriDiContainer::ID(const int i)
00146 {
00147   return(ID_[i]);
00148 }
00149 
00150 //==============================================================================
00151 // FIXME: optimize performances of this guy...
00152 int Ifpack_TriDiContainer::Extract(const Epetra_RowMatrix& Matrix_in)
00153 {
00154 
00155   for (int j = 0 ; j < NumRows_ ; ++j) {
00156     // be sure that the user has set all the ID's
00157     if (ID(j) == -1)
00158       IFPACK_CHK_ERR(-2);
00159     // be sure that all are local indices
00160     if (ID(j) > Matrix_in.NumMyRows())
00161       IFPACK_CHK_ERR(-2);
00162   }
00163 
00164   // allocate storage to extract matrix rows.
00165   int Length = Matrix_in.MaxNumEntries();
00166   std::vector<double> Values;
00167   Values.resize(Length);
00168   std::vector<int> Indices;
00169   Indices.resize(Length);
00170 
00171   for (int j = 0 ; j < NumRows_ ; ++j) {
00172 
00173     int LRID = ID(j);
00174 
00175     int NumEntries;
00176 
00177     int ierr = 
00178       Matrix_in.ExtractMyRowCopy(LRID, Length, NumEntries, 
00179                   &Values[0], &Indices[0]);
00180     IFPACK_CHK_ERR(ierr);
00181 
00182     for (int k = 0 ; k < NumEntries ; ++k) {
00183 
00184       int LCID = Indices[k];
00185 
00186       // skip off-processor elements
00187       if (LCID >= Matrix_in.NumMyRows()) 
00188     continue;
00189 
00190       // for local column IDs, look for each ID in the list
00191       // of columns hosted by this object
00192       // FIXME: use STL
00193       int jj = -1;
00194       for (int kk = 0 ; kk < NumRows_ ; ++kk)
00195     if (ID(kk) == LCID)
00196       jj = kk;
00197 
00198       if (jj != -1)
00199     SetMatrixElement(j,jj,Values[k]);
00200 
00201     }
00202   }
00203 
00204   return(0);
00205 }
00206 
00207 //==============================================================================
00208 int Ifpack_TriDiContainer::Compute(const Epetra_RowMatrix& Matrix_in)
00209 {
00210   IsComputed_ = false;
00211   if (IsInitialized() == false) {
00212     IFPACK_CHK_ERR(Initialize());
00213   }
00214 
00215   if (KeepNonFactoredMatrix_)
00216     NonFactoredMatrix_ = Matrix_;
00217 
00218   // extract local rows and columns
00219   IFPACK_CHK_ERR(Extract(Matrix_in));
00220 
00221   if (KeepNonFactoredMatrix_)
00222     NonFactoredMatrix_ = Matrix_;
00223 
00224   // factorize the matrix using LAPACK
00225   if (NumRows_ != 0)
00226     IFPACK_CHK_ERR(Solver_.Factor());
00227 
00228   Label_ = "Ifpack_TriDiContainer";
00229 
00230   // not sure of count
00231 #ifdef IFPACK_FLOPCOUNTERS
00232   ComputeFlops_ += 4.0 * NumRows_ * NumRows_ * NumRows_ / 3;
00233 #endif
00234   IsComputed_ = true;
00235 
00236   return(0);
00237 }
00238 
00239 //==============================================================================
00240  int Ifpack_TriDiContainer::Apply()
00241  {
00242    IFPACK_CHK_ERR(-300);
00243    //   if (IsComputed() == false)
00244    //     IFPACK_CHK_ERR(-3);
00245 
00246    //   if (KeepNonFactoredMatrix_) {
00247    //     IFPACK_CHK_ERR(RHS_.Multiply('N','N', 1.0,NonFactoredMatrix_,LHS_,0.0));
00248    //   }
00249    //   else
00250    //     IFPACK_CHK_ERR(RHS_.Multiply('N','N', 1.0,Matrix_,LHS_,0.0));
00251 
00252    // #ifdef IFPACK_FLOPCOUNTERS
00253    //   ApplyFlops_ += 2 * NumRows_ * NumRows_;
00254    // #endif
00255    return(0);
00256  }
00257 
00258 //==============================================================================
00259 ostream& Ifpack_TriDiContainer::Print(ostream & os) const
00260 {
00261     os << "================================================================================" << endl;
00262   os << "Ifpack_TriDiContainer" << endl;
00263   os << "Number of rows          = " << NumRows() << endl;
00264   os << "Number of vectors       = " << NumVectors() << endl;
00265   os << "IsInitialized()         = " << IsInitialized() << endl;
00266   os << "IsComputed()            = " << IsComputed() << endl;
00267 #ifdef IFPACK_FLOPCOUNTERS
00268   os << "Flops in Compute()      = " << ComputeFlops() << endl; 
00269   os << "Flops in ApplyInverse() = " << ApplyInverseFlops() << endl; 
00270 #endif
00271   os << "================================================================================" << endl;
00272   os << endl;
00273 
00274   return(os);
00275 }
 All Classes Files Functions Variables Enumerations Friends