00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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();
00087 IsComputed_ = RHS.IsComputed();
00088
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);
00140
00141
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
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
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
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 }