IFPACK  Development
 All Classes Files Functions Variables Enumerations Friends
Ifpack_AMDReordering.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 "Teuchos_ParameterList.hpp"
00045 #include "Teuchos_RefCountPtr.hpp"
00046 #include "Epetra_MultiVector.h"
00047 #include "Ifpack_Graph.h"
00048 #include "Epetra_RowMatrix.h"
00049 #include "Ifpack_Graph_Epetra_RowMatrix.h"
00050 #include "Ifpack_AMDReordering.h"
00051 
00052 extern "C" {
00053 #include <amesos_amd.h>
00054 }
00055 
00056 //==============================================================================
00057 Ifpack_AMDReordering::
00058 Ifpack_AMDReordering() :
00059   NumMyRows_(0),
00060   IsComputed_(false)
00061 {
00062 }
00063 
00064 //==============================================================================
00065 Ifpack_AMDReordering::
00066 Ifpack_AMDReordering(const Ifpack_AMDReordering& RHS) :
00067   NumMyRows_(RHS.NumMyRows()),
00068   IsComputed_(RHS.IsComputed())
00069 {
00070   Reorder_.resize(NumMyRows());
00071   InvReorder_.resize(NumMyRows());
00072   for (int i = 0 ; i < NumMyRows() ; ++i) {
00073     Reorder_[i] = RHS.Reorder(i);
00074     InvReorder_[i] = RHS.InvReorder(i);
00075   }
00076 }
00077 
00078 //==============================================================================
00079 Ifpack_AMDReordering& Ifpack_AMDReordering::
00080 operator=(const Ifpack_AMDReordering& RHS)
00081 {
00082   if (this == &RHS) {
00083     return (*this);
00084   }
00085 
00086   NumMyRows_ = RHS.NumMyRows(); // set number of local rows
00087   IsComputed_ = RHS.IsComputed();
00088   // resize vectors, and copy values from RHS
00089   Reorder_.resize(NumMyRows()); 
00090   InvReorder_.resize(NumMyRows());
00091   if (IsComputed()) {
00092     for (int i = 0 ; i < NumMyRows_ ; ++i) {
00093       Reorder_[i] = RHS.Reorder(i);
00094       InvReorder_[i] = RHS.InvReorder(i);
00095     }
00096   }
00097   return (*this);
00098 }
00099 
00100 //==============================================================================
00101 int Ifpack_AMDReordering::
00102 SetParameter(const string Name, const int Value)
00103 {
00104   return(0);
00105 }
00106 
00107 //==============================================================================
00108 int Ifpack_AMDReordering::
00109 SetParameter(const string Name, const double Value)
00110 {
00111   return(0);
00112 }
00113 
00114 //==============================================================================
00115 int Ifpack_AMDReordering::
00116 SetParameters(Teuchos::ParameterList& List)
00117 {
00118   return(0);
00119 }
00120 
00121 //==============================================================================
00122 int Ifpack_AMDReordering::Compute(const Epetra_RowMatrix& Matrix)
00123 {
00124   Ifpack_Graph_Epetra_RowMatrix Graph(Teuchos::rcp(&Matrix,false));
00125 
00126   IFPACK_CHK_ERR(Compute(Graph));
00127 
00128   return(0);
00129 }
00130 
00131 //==============================================================================
00132 int Ifpack_AMDReordering::Compute(const Ifpack_Graph& Graph)
00133 {
00134   IsComputed_ = false;
00135   NumMyRows_ = Graph.NumMyRows();
00136   int NumNz = Graph.NumMyNonzeros();
00137   
00138   if (NumMyRows_ == 0)
00139     IFPACK_CHK_ERR(-1); // strange graph this one
00140   
00141   // Extract CRS format
00142   std::vector<int> ia(NumMyRows_+1,0);
00143   std::vector<int> ja(NumNz);
00144   int cnt;
00145   for( int i = 0; i < NumMyRows_; ++i )
00146   {
00147     int * tmpP = &ja[ia[i]];
00148     Graph.ExtractMyRowCopy( i, NumNz-ia[i], cnt, tmpP );
00149     ia[i+1] = ia[i] + cnt;
00150   }
00151 
00152   // Trim down to local only
00153   std::vector<int> iat(NumMyRows_+1);
00154   std::vector<int> jat(NumNz);
00155   int loc = 0;
00156   for( int i = 0; i < NumMyRows_; ++i )
00157   {
00158     iat[i] = loc;
00159     for( int j = ia[i]; j < ia[i+1]; ++j )
00160     {
00161       if( ja[j] < NumMyRows_ )
00162         jat[loc++] = ja[j];
00163       else
00164     break;
00165     }
00166   }
00167   iat[NumMyRows_] = loc;
00168 
00169   // Compute AMD permutation
00170   Reorder_.resize(NumMyRows_);
00171   std::vector<double> info(AMD_INFO);
00172 
00173   amesos_amd_order( NumMyRows_, &iat[0], &jat[0], &Reorder_[0], NULL, &info[0] );
00174 
00175   if( info[AMD_STATUS] == AMD_INVALID )
00176     cout << "AMD ORDERING: Invalid!!!!\n";
00177 
00178   // Build inverse reorder (will be used by ExtractMyRowCopy() 
00179   InvReorder_.resize(NumMyRows_);
00180 
00181   for (int i = 0 ; i < NumMyRows_ ; ++i)
00182     InvReorder_[i] = -1;
00183 
00184   for (int i = 0 ; i < NumMyRows_ ; ++i)
00185     InvReorder_[Reorder_[i]] = i;
00186 
00187   for (int i = 0 ; i < NumMyRows_ ; ++i) {
00188     if (InvReorder_[i] == -1)
00189       IFPACK_CHK_ERR(-1);
00190   }
00191 
00192   IsComputed_ = true;
00193   return(0);
00194 }
00195 
00196 //==============================================================================
00197 int Ifpack_AMDReordering::Reorder(const int i) const
00198 {
00199 #ifdef IFPACK_ABC
00200   if (!IsComputed())
00201     IFPACK_CHK_ERR(-1);
00202   if ((i < 0) || (i >= NumMyRows_))
00203     IFPACK_CHK_ERR(-1);
00204 #endif
00205 
00206   return(Reorder_[i]);
00207 }
00208 
00209 //==============================================================================
00210 int Ifpack_AMDReordering::InvReorder(const int i) const
00211 {
00212 #ifdef IFPACK_ABC
00213   if (!IsComputed())
00214     IFPACK_CHK_ERR(-1);
00215   if ((i < 0) || (i >= NumMyRows_))
00216     IFPACK_CHK_ERR(-1);
00217 #endif
00218 
00219   return(InvReorder_[i]);
00220 }
00221 //==============================================================================
00222 int Ifpack_AMDReordering::P(const Epetra_MultiVector& Xorig,
00223                 Epetra_MultiVector& X) const
00224 {  
00225   int NumVectors = X.NumVectors();
00226 
00227   for (int j = 0 ; j < NumVectors ; ++j) {
00228     for (int i = 0 ; i < NumMyRows_ ; ++i) {
00229       int np = Reorder_[i];
00230       X[j][np] = Xorig[j][i];
00231     }
00232   }
00233 
00234   return(0);
00235 }
00236 
00237 //==============================================================================
00238 int Ifpack_AMDReordering::Pinv(const Epetra_MultiVector& Xorig,
00239                    Epetra_MultiVector& X) const
00240 {
00241   int NumVectors = X.NumVectors();
00242 
00243   for (int j = 0 ; j < NumVectors ; ++j) {
00244     for (int i = 0 ; i < NumMyRows_ ; ++i) {
00245       int np = Reorder_[i];
00246       X[j][i] = Xorig[j][np];
00247     }
00248   }
00249 
00250   return(0);
00251 }
00252 
00253 //==============================================================================
00254 ostream& Ifpack_AMDReordering::Print(std::ostream& os) const
00255 {
00256   os << "*** Ifpack_AMDReordering" << endl << endl;
00257   if (!IsComputed())
00258     os << "*** Reordering not yet computed." << endl;
00259   
00260   os << "*** Number of local rows = " << NumMyRows_ << endl;
00261   os << endl;
00262   os << "Local Row\tReorder[i]\tInvReorder[i]" << endl;
00263   for (int i = 0 ; i < NumMyRows_ ; ++i) {
00264     os << '\t' << i << "\t\t" << Reorder_[i] << "\t\t" << InvReorder_[i] << endl;
00265   }
00266    
00267   return(os);
00268 }
 All Classes Files Functions Variables Enumerations Friends