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_RCMReordering.h"
00051
00052
00053 Ifpack_RCMReordering::
00054 Ifpack_RCMReordering() :
00055 RootNode_(0),
00056 NumMyRows_(0),
00057 IsComputed_(false)
00058 {
00059 }
00060
00061
00062 Ifpack_RCMReordering::
00063 Ifpack_RCMReordering(const Ifpack_RCMReordering& RHS) :
00064 RootNode_(RHS.RootNode()),
00065 NumMyRows_(RHS.NumMyRows()),
00066 IsComputed_(RHS.IsComputed())
00067 {
00068 Reorder_.resize(NumMyRows());
00069 InvReorder_.resize(NumMyRows());
00070 for (int i = 0 ; i < NumMyRows() ; ++i) {
00071 Reorder_[i] = RHS.Reorder(i);
00072 InvReorder_[i] = RHS.InvReorder(i);
00073 }
00074 }
00075
00076
00077 Ifpack_RCMReordering& Ifpack_RCMReordering::
00078 operator=(const Ifpack_RCMReordering& RHS)
00079 {
00080 if (this == &RHS) {
00081 return (*this);
00082 }
00083
00084 NumMyRows_ = RHS.NumMyRows();
00085 RootNode_ = RHS.RootNode();
00086 IsComputed_ = RHS.IsComputed();
00087
00088 Reorder_.resize(NumMyRows());
00089 InvReorder_.resize(NumMyRows());
00090 if (IsComputed()) {
00091 for (int i = 0 ; i < NumMyRows_ ; ++i) {
00092 Reorder_[i] = RHS.Reorder(i);
00093 InvReorder_[i] = RHS.InvReorder(i);
00094 }
00095 }
00096 return (*this);
00097 }
00098
00099
00100 int Ifpack_RCMReordering::
00101 SetParameter(const string Name, const int Value)
00102 {
00103 if (Name == "reorder: root node")
00104 RootNode_ = Value;
00105 return(0);
00106 }
00107
00108
00109 int Ifpack_RCMReordering::
00110 SetParameter(const string Name, const double Value)
00111 {
00112 return(0);
00113 }
00114
00115
00116 int Ifpack_RCMReordering::
00117 SetParameters(Teuchos::ParameterList& List)
00118 {
00119 RootNode_ = List.get("reorder: root node", RootNode_);
00120 return(0);
00121 }
00122
00123
00124 int Ifpack_RCMReordering::Compute(const Epetra_RowMatrix& Matrix)
00125 {
00126 Ifpack_Graph_Epetra_RowMatrix Graph(Teuchos::rcp(&Matrix,false));
00127
00128 IFPACK_CHK_ERR(Compute(Graph));
00129
00130 return(0);
00131 }
00132
00133
00134 int Ifpack_RCMReordering::Compute(const Ifpack_Graph& Graph)
00135 {
00136 IsComputed_ = false;
00137 NumMyRows_ = Graph.NumMyRows();
00138
00139 if ((RootNode_ < 0) || (RootNode_ >= NumMyRows_))
00140 RootNode_ = 0;
00141
00142 Reorder_.resize(NumMyRows_);
00143
00144
00145 if (!NumMyRows_) {
00146 InvReorder_.resize(NumMyRows_);
00147 IsComputed_ = true;
00148 return(0);
00149 }
00150
00151 for (int i = 0 ; i < NumMyRows_ ; ++i)
00152 Reorder_[i] = -1;
00153
00154 std::vector<int> tmp;
00155 tmp.push_back(RootNode_);
00156
00157 int count = NumMyRows_ - 1;
00158 int Length = Graph.MaxMyNumEntries();
00159 std::vector<int> Indices(Length);
00160
00161 Reorder_[RootNode_] = count;
00162 count--;
00163
00164
00165
00166 while (tmp.size()) {
00167
00168 std::vector<int> tmp2;
00169
00170
00171
00172 for (int i = 0 ; i < (int)tmp.size() ; ++i) {
00173 int NumEntries;
00174 IFPACK_CHK_ERR(Graph.ExtractMyRowCopy(tmp[i], Length,
00175 NumEntries, &Indices[0]));
00176
00177 if (Length > 1)
00178 std::sort(Indices.begin(), Indices.begin() + Length);
00179
00180 for (int j = 0 ; j < NumEntries ; ++j) {
00181 int col = Indices[j];
00182 if (col >= NumMyRows_)
00183 continue;
00184
00185 if (Reorder_[col] == -1) {
00186 Reorder_[col] = count;
00187 count--;
00188 if (col != tmp[i]) {
00189 tmp2.push_back(col);
00190 }
00191 }
00192 }
00193 }
00194
00195
00196
00197
00198
00199 if ((tmp2.size() == 0) && (count != -1)) {
00200 for (int i = 0 ; i < NumMyRows_ ; ++i)
00201 if (Reorder_[i] == -1) {
00202 tmp2.push_back(i);
00203 Reorder_[i] = count--;
00204 break;
00205 }
00206 }
00207
00208
00209 tmp = tmp2;
00210 }
00211
00212
00213 for (int i = 0 ; i < NumMyRows_ ; ++i) {
00214 if (Reorder_[i] == -1)
00215 IFPACK_CHK_ERR(-1);
00216 }
00217
00218
00219 InvReorder_.resize(NumMyRows_);
00220
00221 for (int i = 0 ; i < NumMyRows_ ; ++i)
00222 InvReorder_[i] = -1;
00223
00224 for (int i = 0 ; i < NumMyRows_ ; ++i)
00225 InvReorder_[Reorder_[i]] = i;
00226
00227 for (int i = 0 ; i < NumMyRows_ ; ++i) {
00228 if (InvReorder_[i] == -1)
00229 IFPACK_CHK_ERR(-1);
00230 }
00231
00232 IsComputed_ = true;
00233 return(0);
00234 }
00235
00236
00237 int Ifpack_RCMReordering::Reorder(const int i) const
00238 {
00239 #ifdef IFPACK_ABC
00240 if (!IsComputed())
00241 IFPACK_CHK_ERR(-1);
00242 if ((i < 0) || (i >= NumMyRows_))
00243 IFPACK_CHK_ERR(-1);
00244 #endif
00245
00246 return(Reorder_[i]);
00247 }
00248
00249
00250 int Ifpack_RCMReordering::InvReorder(const int i) const
00251 {
00252 #ifdef IFPACK_ABC
00253 if (!IsComputed())
00254 IFPACK_CHK_ERR(-1);
00255 if ((i < 0) || (i >= NumMyRows_))
00256 IFPACK_CHK_ERR(-1);
00257 #endif
00258
00259 return(InvReorder_[i]);
00260 }
00261
00262 int Ifpack_RCMReordering::P(const Epetra_MultiVector& Xorig,
00263 Epetra_MultiVector& X) const
00264 {
00265 int NumVectors = X.NumVectors();
00266
00267 for (int j = 0 ; j < NumVectors ; ++j) {
00268 for (int i = 0 ; i < NumMyRows_ ; ++i) {
00269 int np = Reorder_[i];
00270 X[j][np] = Xorig[j][i];
00271 }
00272 }
00273
00274 return(0);
00275 }
00276
00277
00278 int Ifpack_RCMReordering::Pinv(const Epetra_MultiVector& Xorig,
00279 Epetra_MultiVector& X) const
00280 {
00281 int NumVectors = X.NumVectors();
00282
00283 for (int j = 0 ; j < NumVectors ; ++j) {
00284 for (int i = 0 ; i < NumMyRows_ ; ++i) {
00285 int np = Reorder_[i];
00286 X[j][i] = Xorig[j][np];
00287 }
00288 }
00289
00290 return(0);
00291 }
00292
00293
00294 ostream& Ifpack_RCMReordering::Print(std::ostream& os) const
00295 {
00296 os << "*** Ifpack_RCMReordering" << endl << endl;
00297 if (!IsComputed())
00298 os << "*** Reordering not yet computed." << endl;
00299
00300 os << "*** Number of local rows = " << NumMyRows_ << endl;
00301 os << "*** Root node = " << RootNode_ << endl;
00302 os << endl;
00303 os << "Local Row\tReorder[i]\tInvReorder[i]" << endl;
00304 for (int i = 0 ; i < NumMyRows_ ; ++i) {
00305 os << '\t' << i << "\t\t" << Reorder_[i] << "\t\t" << InvReorder_[i] << endl;
00306 }
00307
00308 return(os);
00309 }