IFPACK  Development
 All Classes Files Functions Variables Enumerations Friends
Ifpack_DropFilter.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_DropFilter.h"
00045 #include "Epetra_ConfigDefs.h"
00046 #include "Epetra_RowMatrix.h"
00047 #include "Epetra_Comm.h"
00048 #include "Epetra_Map.h"
00049 #include "Epetra_MultiVector.h"
00050 #include "Epetra_Vector.h"
00051 
00052 //==============================================================================
00053 Ifpack_DropFilter::Ifpack_DropFilter(const Teuchos::RefCountPtr<Epetra_RowMatrix>& Matrix,
00054                      double DropTol) :
00055   A_(Matrix),
00056   DropTol_(DropTol),
00057   MaxNumEntries_(0),
00058   MaxNumEntriesA_(0),
00059   NumNonzeros_(0)
00060 {
00061   // use this filter only on serial matrices
00062   if (A_->Comm().NumProc() != 1) {
00063     cerr << "Ifpack_DropFilter can be used with Comm().NumProc() == 1" << endl;
00064     cerr << "only. This class is a tool for Ifpack_AdditiveSchwarz," << endl;
00065     cerr << "and it is not meant to be used otherwise." << endl;
00066     exit(EXIT_FAILURE);
00067   }
00068   
00069   if ((A_->NumMyRows() != A_->NumGlobalRows64()) ||
00070       (A_->NumMyRows() != A_->NumMyCols()))
00071     IFPACK_CHK_ERRV(-2);
00072 
00073   NumRows_ = A_->NumMyRows();
00074   MaxNumEntriesA_ = A_->MaxNumEntries();
00075 
00076   NumEntries_.resize(NumRows_);
00077   Indices_.resize(MaxNumEntriesA_);
00078   Values_.resize(MaxNumEntriesA_);
00079 
00080   std::vector<int>    Ind(MaxNumEntriesA_);
00081   std::vector<double> Val(MaxNumEntriesA_);
00082 
00083   for (int i = 0 ; i < NumRows_ ; ++i) {
00084     NumEntries_[i] = MaxNumEntriesA_;
00085     int Nnz;
00086     IFPACK_CHK_ERRV(ExtractMyRowCopy(i,MaxNumEntriesA_,Nnz,
00087                      &Val[0], &Ind[0]));
00088  
00089     NumEntries_[i] = Nnz;
00090     NumNonzeros_ += Nnz;
00091     if (Nnz > MaxNumEntries_)
00092       MaxNumEntries_ = Nnz;
00093   }
00094 
00095 }
00096 
00097 //==============================================================================
00098 int Ifpack_DropFilter::
00099 ExtractMyRowCopy(int MyRow, int Length, int & NumEntries, 
00100          double *Values, int * Indices) const
00101 {
00102   if (Length < NumEntries_[MyRow])
00103     IFPACK_CHK_ERR(-1);
00104 
00105   int Nnz;
00106 
00107   IFPACK_CHK_ERR(A_->ExtractMyRowCopy(MyRow,MaxNumEntriesA_,Nnz,
00108                      &Values_[0],&Indices_[0]));
00109 
00110   // loop over all nonzero elements of row MyRow,
00111   // and drop elements below specified threshold.
00112   // Also, add value to zero diagonal
00113   int count = 0;
00114   for (int i = 0 ; i < Nnz ; ++i) {
00115 
00116     // if element is above specified tol, add to the
00117     // user's defined arrays. Check that we are not
00118     // exceeding allocated space. Do not drop any diagonal entry.
00119     if ((Indices_[i] == MyRow) || (IFPACK_ABS(Values_[i]) >= DropTol_)) {
00120       if (count == Length)
00121     IFPACK_CHK_ERR(-1);
00122       Values[count] = Values_[i];
00123       Indices[count] = Indices_[i];
00124       count++;
00125     }
00126   }
00127 
00128   NumEntries = count;
00129   return(0);
00130 }
00131 
00132 //==============================================================================
00133 int Ifpack_DropFilter::
00134 ExtractDiagonalCopy(Epetra_Vector & Diagonal) const
00135 {
00136   IFPACK_CHK_ERR(A_->ExtractDiagonalCopy(Diagonal));
00137   return(0);
00138 }
00139 
00140 //==============================================================================
00141 int Ifpack_DropFilter::
00142 Multiply(bool TransA, const Epetra_MultiVector& X, 
00143      Epetra_MultiVector& Y) const
00144 {
00145   // NOTE: I suppose that the matrix has been localized,
00146   // hence all maps are trivial.
00147   int NumVectors = X.NumVectors();
00148   if (NumVectors != Y.NumVectors())
00149     IFPACK_CHK_ERR(-1);
00150 
00151   Y.PutScalar(0.0);
00152 
00153   std::vector<int> Indices(MaxNumEntries_);
00154   std::vector<double> Values(MaxNumEntries_);
00155 
00156   for (int i = 0 ; i < NumRows_ ; ++i) {
00157 
00158     int Nnz;
00159     ExtractMyRowCopy(i,MaxNumEntries_,Nnz,
00160              &Values[0], &Indices[0]);
00161     if (!TransA) {
00162       // no transpose first
00163       for (int j = 0 ; j < NumVectors ; ++j) {
00164     for (int k = 0 ; k < Nnz ; ++k) {
00165       Y[j][i] += Values[k] * X[j][Indices[k]];
00166     }
00167       }
00168     }
00169     else {
00170       // transpose here
00171       for (int j = 0 ; j < NumVectors ; ++j) {
00172     for (int k = 0 ; k < Nnz ; ++k) {
00173       Y[j][Indices[k]] += Values[k] * X[j][i];
00174     }
00175       }
00176     }
00177   }
00178 
00179   return(0);
00180 }
00181 
00182 //==============================================================================
00183 int Ifpack_DropFilter::
00184 Solve(bool Upper, bool Trans, bool UnitDiagonal, 
00185       const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
00186 {
00187   IFPACK_CHK_ERR(-99);
00188 }
00189 
00190 //==============================================================================
00191 int Ifpack_DropFilter::
00192 Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
00193 {
00194   int ierr = Multiply(UseTranspose(),X,Y);
00195   IFPACK_RETURN(ierr);
00196 }
00197 
00198 //==============================================================================
00199 int Ifpack_DropFilter::
00200 ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
00201 {
00202   IFPACK_CHK_ERR(-99);
00203 }
00204 
00205 //==============================================================================
00206 int Ifpack_DropFilter::InvRowSums(Epetra_Vector& x) const
00207 {
00208   IFPACK_CHK_ERR(-1);
00209 }
00210 
00211 //==============================================================================
00212 int Ifpack_DropFilter::InvColSums(Epetra_Vector& x) const
00213 {
00214   IFPACK_CHK_ERR(-1);
00215 }
 All Classes Files Functions Variables Enumerations Friends