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
00044
00045
00046 #include <Teuchos_Array.hpp>
00047 #include "Xpetra_EpetraCrsMatrix.hpp"
00048
00049 namespace Xpetra {
00050
00051 EpetraCrsMatrix::EpetraCrsMatrix(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &rowMap, size_t maxNumEntriesPerRow, ProfileType pftype, const Teuchos::RCP< Teuchos::ParameterList > &plist)
00052 : mtx_(Teuchos::rcp(new Epetra_CrsMatrix(Copy, toEpetra(rowMap), maxNumEntriesPerRow, toEpetra(pftype)))) { }
00053
00054 EpetraCrsMatrix::EpetraCrsMatrix(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &rowMap, const ArrayRCP< const size_t > &NumEntriesPerRowToAlloc, ProfileType pftype, const Teuchos::RCP< Teuchos::ParameterList > &plist) {
00055 Teuchos::Array<int> numEntriesPerRowToAlloc(NumEntriesPerRowToAlloc.begin(), NumEntriesPerRowToAlloc.end());
00056 mtx_ = Teuchos::rcp(new Epetra_CrsMatrix(Copy, toEpetra(rowMap), numEntriesPerRowToAlloc.getRawPtr(), toEpetra(pftype)));
00057 }
00058
00059 EpetraCrsMatrix::EpetraCrsMatrix(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &rowMap, const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &colMap, size_t maxNumEntriesPerRow, ProfileType pftype, const Teuchos::RCP< Teuchos::ParameterList > &plist)
00060 : mtx_(Teuchos::rcp(new Epetra_CrsMatrix(Copy, toEpetra(rowMap), toEpetra(colMap), maxNumEntriesPerRow, toEpetra(pftype)))) { }
00061
00062 EpetraCrsMatrix::EpetraCrsMatrix(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &rowMap, const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &colMap, const ArrayRCP< const size_t > &NumEntriesPerRowToAlloc, ProfileType pftype, const Teuchos::RCP< Teuchos::ParameterList > &plist) {
00063 Teuchos::Array<int> numEntriesPerRowToAlloc(NumEntriesPerRowToAlloc.begin(), NumEntriesPerRowToAlloc.end());
00064 mtx_ = Teuchos::rcp(new Epetra_CrsMatrix(Copy, toEpetra(rowMap), toEpetra(colMap), numEntriesPerRowToAlloc.getRawPtr(), toEpetra(pftype)));
00065 }
00066
00067 EpetraCrsMatrix::EpetraCrsMatrix(const Teuchos::RCP< const CrsGraph< LocalOrdinal, GlobalOrdinal, Node, LocalMatOps > > &graph, const Teuchos::RCP< Teuchos::ParameterList > &plist)
00068 : mtx_(Teuchos::rcp(new Epetra_CrsMatrix(Copy, toEpetra(graph)))) { }
00069
00070 void EpetraCrsMatrix::insertGlobalValues(int globalRow, const ArrayView<const int> &cols, const ArrayView<const double> &vals) {
00071 XPETRA_MONITOR("EpetraCrsMatrix::insertGlobalValues");
00072 XPETRA_ERR_CHECK(mtx_->InsertGlobalValues(globalRow, vals.size(), vals.getRawPtr(), cols.getRawPtr()));
00073 }
00074
00075 void EpetraCrsMatrix::insertLocalValues(int localRow, const ArrayView<const int> &cols, const ArrayView<const double> &vals) {
00076 XPETRA_MONITOR("EpetraCrsMatrix::insertLocalValues");
00077 XPETRA_ERR_CHECK(mtx_->InsertMyValues(localRow, vals.size(), vals.getRawPtr(), cols.getRawPtr()));
00078 }
00079
00080
00081 void EpetraCrsMatrix::getLocalRowCopy(int LocalRow, const ArrayView<int> &Indices, const ArrayView<double> &Values, size_t &NumEntries) const {
00082 XPETRA_MONITOR("EpetraCrsMatrix::getLocalRowCopy");
00083
00084 int numEntries=-1;
00085 XPETRA_ERR_CHECK(mtx_->ExtractMyRowCopy(LocalRow, Indices.size(), numEntries, Values.getRawPtr(), Indices.getRawPtr()));
00086 NumEntries = numEntries;
00087 }
00088
00089 void EpetraCrsMatrix::getGlobalRowView(int GlobalRow, ArrayView<const int> &indices, ArrayView<const double> &values) const {
00090 XPETRA_MONITOR("EpetraCrsMatrix::getGlobalRowView");
00091
00092 int numEntries;
00093 double * eValues;
00094 int * eIndices;
00095
00096 XPETRA_ERR_CHECK(mtx_->ExtractGlobalRowView(GlobalRow, numEntries, eValues, eIndices));
00097 if (numEntries == 0) { eValues = NULL; eIndices = NULL; }
00098
00099 indices = ArrayView<const int>(eIndices, numEntries);
00100 values = ArrayView<const double>(eValues, numEntries);
00101 }
00102
00103 void EpetraCrsMatrix::getLocalRowView(int LocalRow, ArrayView<const int> &indices, ArrayView<const double> &values) const {
00104 XPETRA_MONITOR("EpetraCrsMatrix::getLocalRowView");
00105
00106 int numEntries;
00107 double * eValues;
00108 int * eIndices;
00109
00110 XPETRA_ERR_CHECK(mtx_->ExtractMyRowView(LocalRow, numEntries, eValues, eIndices));
00111 if (numEntries == 0) { eValues = NULL; eIndices = NULL; }
00112
00113 indices = ArrayView<const int>(eIndices, numEntries);
00114 values = ArrayView<const double>(eValues, numEntries);
00115 }
00116
00117 void EpetraCrsMatrix::apply(const MultiVector<double,int,int> & X, MultiVector<double,int,int> &Y, Teuchos::ETransp mode, double alpha, double beta) const {
00118 XPETRA_MONITOR("EpetraCrsMatrix::apply");
00119
00120
00121
00122 XPETRA_DYNAMIC_CAST(const EpetraMultiVector, X, eX, "Xpetra::EpetraCrsMatrix->apply() only accept Xpetra::EpetraMultiVector as input arguments.");
00123 XPETRA_DYNAMIC_CAST( EpetraMultiVector, Y, eY, "Xpetra::EpetraCrsMatrix->apply() only accept Xpetra::EpetraMultiVector as input arguments.");
00124
00125 TEUCHOS_TEST_FOR_EXCEPTION((mode != Teuchos::NO_TRANS) && (mode != Teuchos::TRANS), Xpetra::Exceptions::NotImplemented, "Xpetra::EpetraCrsMatrix->apply() only accept mode == NO_TRANS or mode == TRANS");
00126 bool eTrans = toEpetra(mode);
00127
00128
00129 TEUCHOS_TEST_FOR_EXCEPTION(mtx_->UseTranspose(), Xpetra::Exceptions::NotImplemented, "An exception is throw to let you know that Xpetra::EpetraCrsMatrix->apply() do not take into account the UseTranspose() parameter of Epetra_CrsMatrix.");
00130
00131 RCP<Epetra_MultiVector> epY = eY.getEpetra_MultiVector();
00132
00133
00134 RCP<Epetra_MultiVector> tmp = Teuchos::rcp(new Epetra_MultiVector(*epY));
00135 tmp->PutScalar(0.0);
00136 XPETRA_ERR_CHECK(mtx_->Multiply(eTrans, *eX.getEpetra_MultiVector(), *tmp));
00137
00138
00139 XPETRA_ERR_CHECK(eY.getEpetra_MultiVector()->Update(alpha,*tmp,beta));
00140 }
00141
00142 std::string EpetraCrsMatrix::description() const {
00143 XPETRA_MONITOR("EpetraCrsMatrix::description");
00144
00145
00146 std::ostringstream oss;
00147
00148 if (isFillComplete()) {
00149 oss << "{status = fill complete"
00150 << ", global rows = " << getGlobalNumRows()
00151 << ", global cols = " << getGlobalNumCols()
00152 << ", global num entries = " << getGlobalNumEntries()
00153 << "}";
00154 }
00155 else {
00156 oss << "{status = fill not complete"
00157 << ", global rows = " << getGlobalNumRows()
00158 << "}";
00159 }
00160 return oss.str();
00161
00162 }
00163
00164 void EpetraCrsMatrix::describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const {
00165 XPETRA_MONITOR("EpetraCrsMatrix::describe");
00166
00167
00168 using std::endl;
00169 using std::setw;
00170 using Teuchos::VERB_DEFAULT;
00171 using Teuchos::VERB_NONE;
00172 using Teuchos::VERB_LOW;
00173 using Teuchos::VERB_MEDIUM;
00174 using Teuchos::VERB_HIGH;
00175 using Teuchos::VERB_EXTREME;
00176 Teuchos::EVerbosityLevel vl = verbLevel;
00177 if (vl == VERB_DEFAULT) vl = VERB_LOW;
00178 RCP<const Comm<int> > comm = this->getComm();
00179 const int myImageID = comm->getRank(),
00180 numImages = comm->getSize();
00181 size_t width = 1;
00182 for (size_t dec=10; dec<getGlobalNumRows(); dec *= 10) {
00183 ++width;
00184 }
00185 width = std::max<size_t>(width,11) + 2;
00186 Teuchos::OSTab tab(out);
00187
00188
00189
00190
00191
00192
00193
00194 if (vl != VERB_NONE) {
00195 if (myImageID == 0) out << this->description() << std::endl;
00196
00197 if (isFillComplete() && myImageID == 0) {
00198 out << "Global number of diagonals = " << getGlobalNumDiags() << std::endl;
00199 out << "Global max number of entries = " << getGlobalMaxNumRowEntries() << std::endl;
00200 }
00201
00202 if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
00203 if (myImageID == 0) out << "\nRow map: " << std::endl;
00204 getRowMap()->describe(out,vl);
00205
00206 if (getColMap() != null) {
00207 if (getColMap() == getRowMap()) {
00208 if (myImageID == 0) out << "\nColumn map is row map.";
00209 }
00210 else {
00211 if (myImageID == 0) out << "\nColumn map: " << std::endl;
00212 getColMap()->describe(out,vl);
00213 }
00214 }
00215 if (getDomainMap() != null) {
00216 if (getDomainMap() == getRowMap()) {
00217 if (myImageID == 0) out << "\nDomain map is row map.";
00218 }
00219 else if (getDomainMap() == getColMap()) {
00220 if (myImageID == 0) out << "\nDomain map is row map.";
00221 }
00222 else {
00223 if (myImageID == 0) out << "\nDomain map: " << std::endl;
00224 getDomainMap()->describe(out,vl);
00225 }
00226 }
00227 if (getRangeMap() != null) {
00228 if (getRangeMap() == getDomainMap()) {
00229 if (myImageID == 0) out << "\nRange map is domain map." << std::endl;
00230 }
00231 else if (getRangeMap() == getRowMap()) {
00232 if (myImageID == 0) out << "\nRange map is row map." << std::endl;
00233 }
00234 else {
00235 if (myImageID == 0) out << "\nRange map: " << std::endl;
00236 getRangeMap()->describe(out,vl);
00237 }
00238 }
00239 if (myImageID == 0) out << std::endl;
00240 }
00241
00242 if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
00243 for (int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
00244 if (myImageID == imageCtr) {
00245 out << "Node ID = " << imageCtr << std::endl;
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 out << "Node number of entries = " << getNodeNumEntries() << std::endl;
00259 if (isFillComplete()) {
00260 out << "Node number of diagonals = " << getNodeNumDiags() << std::endl;
00261 }
00262 out << "Node max number of entries = " << getNodeMaxNumRowEntries() << std::endl;
00263 }
00264 comm->barrier();
00265 comm->barrier();
00266 comm->barrier();
00267 }
00268 }
00269
00270 if (vl == VERB_HIGH || vl == VERB_EXTREME) {
00271 for (int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
00272 if (myImageID == imageCtr) {
00273 out << std::setw(width) << "Node ID"
00274 << std::setw(width) << "Global Row"
00275 << std::setw(width) << "Num Entries";
00276 if (vl == VERB_EXTREME) {
00277 out << std::setw(width) << "(Index,Value)";
00278 }
00279 out << std::endl;
00280 for (size_t r=0; r < getNodeNumRows(); ++r) {
00281 const size_t nE = getNumEntriesInLocalRow(r);
00282 GlobalOrdinal gid = getRowMap()->getGlobalElement(r);
00283 out << std::setw(width) << myImageID
00284 << std::setw(width) << gid
00285 << std::setw(width) << nE;
00286 if (vl == VERB_EXTREME) {
00287 if (isGloballyIndexed()) {
00288 ArrayView<const GlobalOrdinal> rowinds;
00289 ArrayView<const Scalar> rowvals;
00290 getGlobalRowView(gid,rowinds,rowvals);
00291 for (size_t j=0; j < nE; ++j) {
00292 out << " (" << rowinds[j]
00293 << ", " << rowvals[j]
00294 << ") ";
00295 }
00296 }
00297 else if (isLocallyIndexed()) {
00298 ArrayView<const LocalOrdinal> rowinds;
00299 ArrayView<const Scalar> rowvals;
00300 getLocalRowView(r,rowinds,rowvals);
00301 for (size_t j=0; j < nE; ++j) {
00302 out << " (" << getColMap()->getGlobalElement(rowinds[j])
00303 << ", " << rowvals[j]
00304 << ") ";
00305 }
00306 }
00307 }
00308 out << std::endl;
00309 }
00310 }
00311 comm->barrier();
00312 comm->barrier();
00313 comm->barrier();
00314 }
00315 }
00316 }
00317
00318 }
00319
00320
00321 void EpetraCrsMatrix::doImport(const DistObject<char, int, int> &source,
00322 const Import<int, int> &importer, CombineMode CM) {
00323 XPETRA_MONITOR("EpetraCrsMatrix::doImport");
00324
00325 XPETRA_DYNAMIC_CAST(const EpetraCrsMatrix, source, tSource, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraCrsMatrix as input arguments.");
00326 XPETRA_DYNAMIC_CAST(const EpetraImport, importer, tImporter, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraImport as input arguments.");
00327
00328 RCP<const Epetra_CrsMatrix> v = tSource.getEpetra_CrsMatrix();
00329 int err = mtx_->Import(*v, *tImporter.getEpetra_Import(), toEpetra(CM));
00330 TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, "Catch error code returned by Epetra.");
00331 }
00332
00333 void EpetraCrsMatrix::doExport(const DistObject<char, int, int> &dest,
00334 const Import<int, int>& importer, CombineMode CM) {
00335 XPETRA_MONITOR("EpetraCrsMatrix::doExport");
00336
00337 XPETRA_DYNAMIC_CAST(const EpetraCrsMatrix, dest, tDest, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraCrsMatrix as input arguments.");
00338 XPETRA_DYNAMIC_CAST(const EpetraImport, importer, tImporter, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraImport as input arguments.");
00339
00340 RCP<const Epetra_CrsMatrix> v = tDest.getEpetra_CrsMatrix();
00341 int err = mtx_->Export(*v, *tImporter.getEpetra_Import(), toEpetra(CM));
00342 TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, "Catch error code returned by Epetra.");
00343 }
00344
00345 void EpetraCrsMatrix::doImport(const DistObject<char, int, int> &source,
00346 const Export<int, int>& exporter, CombineMode CM) {
00347 XPETRA_MONITOR("EpetraCrsMatrix::doImport");
00348
00349 XPETRA_DYNAMIC_CAST(const EpetraCrsMatrix, source, tSource, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraCrsMatrix as input arguments.");
00350 XPETRA_DYNAMIC_CAST(const EpetraExport, exporter, tExporter, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraImport as input arguments.");
00351
00352 RCP<const Epetra_CrsMatrix> v = tSource.getEpetra_CrsMatrix();
00353 int err = mtx_->Import(*v, *tExporter.getEpetra_Export(), toEpetra(CM));
00354 TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, "Catch error code returned by Epetra.");
00355
00356 }
00357
00358 void EpetraCrsMatrix::doExport(const DistObject<char, int, int> &dest,
00359 const Export<int, int>& exporter, CombineMode CM) {
00360 XPETRA_MONITOR("EpetraCrsMatrix::doExport");
00361
00362 XPETRA_DYNAMIC_CAST(const EpetraCrsMatrix, dest, tDest, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraCrsMatrix as input arguments.");
00363 XPETRA_DYNAMIC_CAST(const EpetraExport, exporter, tExporter, "Xpetra::EpetraCrsMatrix::doImport only accept Xpetra::EpetraImport as input arguments.");
00364
00365 RCP<const Epetra_CrsMatrix> v = tDest.getEpetra_CrsMatrix();
00366 int err = mtx_->Export(*v, *tExporter.getEpetra_Export(), toEpetra(CM));
00367 TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, "Catch error code returned by Epetra.");
00368 }
00369
00370 void EpetraCrsMatrix::fillComplete(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &domainMap,
00371 const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &rangeMap,
00372 const RCP< ParameterList > ¶ms) {
00373 XPETRA_MONITOR("EpetraCrsMatrix::fillComplete");
00374 bool doOptimizeStorage = true;
00375 if (params != null && params->get("Optimize Storage",true) == false) doOptimizeStorage = false;
00376 mtx_->FillComplete(toEpetra(domainMap), toEpetra(rangeMap), doOptimizeStorage);
00377 }
00378
00379 void EpetraCrsMatrix::fillComplete(const RCP< ParameterList > ¶ms) {
00380 XPETRA_MONITOR("EpetraCrsMatrix::fillComplete");
00381 bool doOptimizeStorage = true;
00382 if (params != null && params->get("Optimize Storage",true) == false) doOptimizeStorage = false;
00383 mtx_->FillComplete(doOptimizeStorage);
00384 }
00385
00386 }