All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
Xpetra_EpetraMultiVector.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //             Xpetra: A linear algebra interface package
00006 //                  Copyright 2012 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact
00039 //                    Jeremie Gaidamour (jngaida@sandia.gov)
00040 //                    Jonathan Hu       (jhu@sandia.gov)
00041 //                    Ray Tuminaro      (rstumin@sandia.gov)
00042 //
00043 // ***********************************************************************
00044 //
00045 // @HEADER
00046 #include "Xpetra_EpetraMultiVector.hpp"
00047 
00048 #include "Xpetra_EpetraImport.hpp" 
00049 #include "Xpetra_EpetraExport.hpp" 
00050 #include "Xpetra_Exceptions.hpp" 
00051 
00052 namespace Xpetra {
00053 
00054   EpetraMultiVector::EpetraMultiVector(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &map, const Teuchos::ArrayView< const Teuchos::ArrayView< const Scalar > > &ArrayOfPtrs, size_t NumVectors) {
00055     //TODO: input argument 'NumVectors' is not necessary in both Xpetra and Tpetra interface. Should it be removed?
00056 
00057     const std::string tfecfFuncName("MultiVector(ArrayOfPtrs)");
00058     TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(NumVectors < 1 || NumVectors != Teuchos::as<size_t>(ArrayOfPtrs.size()), std::runtime_error,
00059                                           ": ArrayOfPtrs.size() must be strictly positive and as large as ArrayOfPtrs.");
00060     
00061 #ifdef HAVE_XPETRA_DEBUG
00062     // This cannot be tested by Epetra itself
00063     {
00064       size_t localLength = map->getNodeNumElements();
00065       for(int j=0; j<ArrayOfPtrs.size(); j++) {
00066         TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(Teuchos::as<size_t>(ArrayOfPtrs[j].size()) != localLength, std::runtime_error,
00067                                               ": ArrayOfPtrs[" << j << "].size() (== " << ArrayOfPtrs[j].size() << 
00068                                               ") is not equal to getLocalLength() (== " << localLength);
00069         
00070       }
00071     }
00072 #endif
00073 
00074     // Convert Teuchos::ArrayView< const Teuchos::ArrayView< const Scalar > > to double**
00075     Array<const double*> arrayOfRawPtrs(ArrayOfPtrs.size());
00076     for(int i=0; i<ArrayOfPtrs.size(); i++) {
00077       arrayOfRawPtrs[i] = ArrayOfPtrs[i].getRawPtr();
00078     }
00079     double** rawArrayOfRawPtrs = const_cast<double**>(arrayOfRawPtrs.getRawPtr()); // This const_cast should be fine, because Epetra_DataAccess=Copy.
00080 
00081     vec_ = Teuchos::rcp(new Epetra_MultiVector(Copy, toEpetra(map), rawArrayOfRawPtrs, NumVectors));
00082   }
00083 
00084   Teuchos::ArrayRCP<const double> EpetraMultiVector::getData(size_t j) const { 
00085     XPETRA_MONITOR("EpetraMultiVector::getData");
00086 
00087     double ** arrayOfPointers;
00088       
00089     vec_->ExtractView(&arrayOfPointers);
00090      
00091     double * data = arrayOfPointers[j];
00092     int localLength = vec_->MyLength();
00093       
00094     return ArrayRCP<double>(data, 0, localLength, false); // not ownership
00095   }
00096 
00097   Teuchos::ArrayRCP<double> EpetraMultiVector::getDataNonConst(size_t j) { 
00098     XPETRA_MONITOR("EpetraMultiVector::getDataNonConst");
00099 
00100     double ** arrayOfPointers;
00101       
00102     vec_->ExtractView(&arrayOfPointers);
00103      
00104     double * data = arrayOfPointers[j];
00105     int localLength = vec_->MyLength();
00106       
00107     return ArrayRCP<double>(data, 0, localLength, false); // not ownership
00108   }
00109 
00110   void EpetraMultiVector::dot(const MultiVector<double,int,int> &A, const Teuchos::ArrayView<double> &dots) const { 
00111     XPETRA_MONITOR("EpetraMultiVector::dot");
00112 
00113     XPETRA_DYNAMIC_CAST(const EpetraMultiVector, A, eA, "This Xpetra::EpetraMultiVector method only accept Xpetra::EpetraMultiVector as input arguments.");
00114     vec_->Dot(*eA.getEpetra_MultiVector(), dots.getRawPtr());
00115   }
00116 
00117   void EpetraMultiVector::norm1(const Teuchos::ArrayView< Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const { XPETRA_MONITOR("EpetraMultiVector::norm1"); vec_->Norm1(norms.getRawPtr()); }
00118   
00119   void EpetraMultiVector::norm2(const Teuchos::ArrayView< Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const { XPETRA_MONITOR("EpetraMultiVector::norm2"); vec_->Norm2(norms.getRawPtr()); }
00120   
00121   void EpetraMultiVector::normInf(const Teuchos::ArrayView< Teuchos::ScalarTraits< Scalar >::magnitudeType > &norms) const { XPETRA_MONITOR("EpetraMultiVector::normInf"); vec_->NormInf(norms.getRawPtr()); }
00122 
00123   void EpetraMultiVector::normWeighted(const MultiVector<double,int,int> &weights, const Teuchos::ArrayView<Teuchos::ScalarTraits<double>::magnitudeType> &norms) const { 
00124     XPETRA_MONITOR("EpetraMultiVector::normWeighted");
00125 
00126     XPETRA_DYNAMIC_CAST(const EpetraMultiVector, weights, eWeights, "This Xpetra::EpetraMultiVector method only accept Xpetra::EpetraMultiVector as input arguments.");
00127     vec_->NormWeighted(*eWeights.getEpetra_MultiVector(), norms.getRawPtr()); 
00128   }
00129 
00130   void EpetraMultiVector::meanValue(const Teuchos::ArrayView<double> &means) const { XPETRA_MONITOR("EpetraMultiVector::meanValue"); vec_->MeanValue(means.getRawPtr()); } //TODO: modify ArrayView size ??
00131 
00132   std::string EpetraMultiVector::description() const {  
00133     XPETRA_MONITOR("EpetraMultiVector::description");
00134     TEUCHOS_TEST_FOR_EXCEPTION(1, Xpetra::Exceptions::NotImplemented, "TODO");
00135     return "TODO"; 
00136   }
00137 
00138   void EpetraMultiVector::describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const { 
00139     XPETRA_MONITOR("EpetraMultiVector::describe");
00140     vec_->Print(out);
00141   }
00142 
00143   void EpetraMultiVector::doImport(const DistObject<double, int, int> &source, const Import<int, int> &importer, CombineMode CM) {
00144     XPETRA_MONITOR("EpetraMultiVector::doImport");
00145 
00146     XPETRA_DYNAMIC_CAST(const EpetraMultiVector, source, tSource, "Xpetra::EpetraMultiVector::doImport only accept Xpetra::EpetraMultiVector as input arguments.");
00147     XPETRA_DYNAMIC_CAST(const EpetraImport, importer, tImporter, "Xpetra::EpetraMultiVector::doImport only accept Xpetra::EpetraImport as input arguments.");
00148 
00149     RCP<Epetra_MultiVector> v = tSource.getEpetra_MultiVector();
00150     int err = this->getEpetra_MultiVector()->Import(*v, *tImporter.getEpetra_Import(), toEpetra(CM));
00151     TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, "Catch error code returned by Epetra.");
00152   }
00153 
00154   void EpetraMultiVector::doExport(const DistObject<double, int, int> &dest, const Import<int, int>& importer, CombineMode CM) {
00155     XPETRA_MONITOR("EpetraMultiVector::doExport");
00156       
00157     XPETRA_DYNAMIC_CAST(const EpetraMultiVector, dest, tDest, "Xpetra::EpetraMultiVector::doImport only accept Xpetra::EpetraMultiVector as input arguments.");
00158     XPETRA_DYNAMIC_CAST(const EpetraImport, importer, tImporter, "Xpetra::EpetraMultiVector::doImport only accept Xpetra::EpetraImport as input arguments.");
00159 
00160     RCP<Epetra_MultiVector> v = tDest.getEpetra_MultiVector();
00161     int err = this->getEpetra_MultiVector()->Export(*v, *tImporter.getEpetra_Import(), toEpetra(CM)); 
00162     TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, "Catch error code returned by Epetra.");
00163   }
00164 
00165   void EpetraMultiVector::doImport(const DistObject<double,int,int> &source, const Export<int, int>& exporter, CombineMode CM) {
00166     XPETRA_MONITOR("EpetraMultiVector::doImport");
00167       
00168     XPETRA_DYNAMIC_CAST(const EpetraMultiVector, source, tSource, "Xpetra::EpetraMultiVector::doImport only accept Xpetra::EpetraMultiVector as input arguments.");
00169     XPETRA_DYNAMIC_CAST(const EpetraExport, exporter, tExporter, "Xpetra::EpetraMultiVector::doImport only accept Xpetra::EpetraImport as input arguments.");
00170 
00171     RCP<Epetra_MultiVector> v = tSource.getEpetra_MultiVector();
00172     int err = this->getEpetra_MultiVector()->Import(*v, *tExporter.getEpetra_Export(), toEpetra(CM));
00173     TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, "Catch error code returned by Epetra.");
00174   }
00175 
00176   void EpetraMultiVector::doExport(const DistObject<double, int, int> &dest, const Export<int, int>& exporter, CombineMode CM) {
00177     XPETRA_MONITOR("EpetraMultiVector::doExport");
00178       
00179     XPETRA_DYNAMIC_CAST(const EpetraMultiVector, dest, tDest, "Xpetra::EpetraMultiVector::doImport only accept Xpetra::EpetraMultiVector as input arguments.");
00180     XPETRA_DYNAMIC_CAST(const EpetraExport, exporter, tExporter, "Xpetra::EpetraMultiVector::doImport only accept Xpetra::EpetraImport as input arguments.");
00181 
00182     RCP<Epetra_MultiVector> v = tDest.getEpetra_MultiVector();
00183     int err = this->getEpetra_MultiVector()->Export(*v, *tExporter.getEpetra_Export(), toEpetra(CM)); 
00184     TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, "Catch error code returned by Epetra.");
00185   }
00186 
00187   // TODO: move that elsewhere
00188   const Epetra_MultiVector & toEpetra(const MultiVector<double, int, int> & x) {
00189     XPETRA_DYNAMIC_CAST(const EpetraMultiVector, x, tX, "toEpetra");
00190     return *tX.getEpetra_MultiVector();
00191   }
00192 
00193   Epetra_MultiVector & toEpetra(MultiVector<double, int, int> & x) {
00194     XPETRA_DYNAMIC_CAST(      EpetraMultiVector, x, tX, "toEpetra");
00195     return *tX.getEpetra_MultiVector();
00196   }
00197   //
00198 
00199 
00200 } // namespace Xpetra
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines