EpetraTSFOperator.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 /* ***********************************************************************
00003 // 
00004 //           TSFExtended: Trilinos Solver Framework Extended
00005 //                 Copyright (2004) 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 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // **********************************************************************/
00027  /* @HEADER@ */
00028 
00029 #include "TSFEpetraMatrix.hpp"
00030 #include "TSFEpetraVector.hpp"
00031 #include "TSFVectorSpaceDecl.hpp"  // changed from Impl
00032 #include "TSFVectorDecl.hpp"
00033 #include "TSFLinearOperatorDecl.hpp"  // changed from Impl
00034 #include "Teuchos_Array.hpp"
00035 #include "Teuchos_MPIComm.hpp"
00036 #include "TSFIfpackOperator.hpp"
00037 #include "TSFGenericLeftPreconditioner.hpp"
00038 #include "TSFGenericRightPreconditioner.hpp"
00039 #include "Teuchos_dyn_cast.hpp"
00040 #include "Teuchos_getConst.hpp"
00041 #include "EpetraTSFOperator.hpp"
00042 #include "Epetra_Comm.h"
00043 #include "Epetra_CrsMatrix.h"
00044 #include "Thyra_Config.h"
00045 
00046 #ifdef HAVE_THYRA_EPETRA
00047 #include "Thyra_EpetraThyraWrappers.hpp"
00048 #endif
00049 
00050 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00051 #include "TSFVectorImpl.hpp"
00052 #include "TSFLinearCombinationImpl.hpp"
00053 #include "TSFLinearOperatorImpl.hpp"
00054 #include "TSFLinearSolverImpl.hpp"
00055 #endif
00056 
00057 using namespace TSFExtended;
00058 using namespace Teuchos;
00059 using namespace Thyra;
00060 using namespace Epetra;
00061 
00062 Epetra_TSFOperator::Epetra_TSFOperator(const LinearOperator<double>& A,
00063                const LinearSolver<double>& solver)
00064   : A_(A), solver_(solver), useTranspose_(false), comm_(), domain_(), range_(),
00065     isNativeEpetra_(false), isCompoundEpetra_(false), label_(A.description())
00066 {
00067   const EpetraMatrix* em = dynamic_cast<const EpetraMatrix*>(A.ptr().get());
00068   const EpetraVectorSpace* ed = dynamic_cast<const EpetraVectorSpace*>(A.domain().ptr().get());
00069   const EpetraVectorSpace* er = dynamic_cast<const EpetraVectorSpace*>(A.range().ptr().get());
00070 
00071   if (em)
00072     {
00073       isNativeEpetra_ = true;
00074       const Epetra_CrsMatrix* crs = em->crsMatrix();
00075       domain_ = rcp(new Epetra_Map(crs->OperatorDomainMap()));
00076       range_ = rcp(new Epetra_Map(crs->OperatorRangeMap()));
00077       useTranspose_ = crs->UseTranspose();
00078       comm_ = rcp(crs->Comm().Clone());
00079     }
00080   else if (er != 0 && ed != 0)
00081     {
00082       domain_ = ed->epetraMap();
00083       range_ = er->epetraMap();
00084       comm_ = rcp(domain_->Comm().Clone());
00085       isCompoundEpetra_ = true;
00086     }
00087   else
00088     {
00089       TEST_FOR_EXCEPT(true);
00090     }
00091 }
00092 
00093 
00094 int Epetra_TSFOperator::Apply(const Epetra_MultiVector& in, Epetra_MultiVector& out) const
00095 {
00096   if (isNativeEpetra_)
00097     {
00098       const EpetraMatrix* em = dynamic_cast<const EpetraMatrix*>(A_.ptr().get());
00099       return em->crsMatrix()->Multiply(useTranspose_, in, out);
00100     }
00101   else if (isCompoundEpetra_)
00102     {
00103       const Epetra_Vector* cevIn = dynamic_cast<const Epetra_Vector*>(&in);
00104       Epetra_Vector* evIn = const_cast<Epetra_Vector*>(cevIn);
00105       Epetra_Vector* evOut = dynamic_cast<Epetra_Vector*>(&out);
00106       TEST_FOR_EXCEPTION(evIn==0, std::runtime_error, "Epetra_TSFOperator::Apply "
00107        "cannot deal with multivectors");
00108       TEST_FOR_EXCEPTION(evOut==0, std::runtime_error, "Epetra_TSFOperator::Apply "
00109        "cannot deal with multivectors");
00110 
00111       const EpetraVectorSpace* ed 
00112   = dynamic_cast<const EpetraVectorSpace*>(A_.domain().ptr().get());
00113       const EpetraVectorSpace* er 
00114   = dynamic_cast<const EpetraVectorSpace*>(A_.range().ptr().get());
00115       TEST_FOR_EXCEPTION(er == 0 || ed==0, std::runtime_error, 
00116        "this should never happen, because we have found "
00117        "Epetra domain and range in the ctor");
00118 
00119       RCP<Thyra::VectorBase<double> > vpIn 
00120   = rcp(new EpetraVector(rcp(ed, false), 
00121              rcp(evIn, false)));
00122       RCP<Thyra::VectorBase<double> > vpOut 
00123   = rcp(new EpetraVector(rcp(er, false), 
00124              rcp(evOut, false)));
00125       Vector<double> vIn = vpIn;
00126       Vector<double> vOut = vpOut;
00127 
00128       A_.apply(vIn, vOut);
00129       out = EpetraVector::getConcrete(vOut);
00130       return 0;
00131     }
00132   else
00133     {
00134       TEST_FOR_EXCEPT(true);
00135       return -1; // -Wall
00136     }
00137 }
00138 
00139 int Epetra_TSFOperator::ApplyInverse(const Epetra_MultiVector& in, Epetra_MultiVector& out) const
00140 {
00141   
00142   TEST_FOR_EXCEPTION(solver_.ptr().get()==0, std::runtime_error,
00143          "no solver provided for Epetra_TSFOperator::ApplyInverse");
00144   TEST_FOR_EXCEPTION(!isNativeEpetra_ && !isCompoundEpetra_, std::runtime_error,
00145          "Epetra_TSFOperator::ApplyInverse expects either "
00146          "a native epetra operator or a compound operator with "
00147          "Epetra domain and range spaces");
00148   const Epetra_Vector* cevIn = dynamic_cast<const Epetra_Vector*>(&in);
00149   Epetra_Vector* evIn = const_cast<Epetra_Vector*>(cevIn);
00150   Epetra_Vector* evOut = dynamic_cast<Epetra_Vector*>(&out);
00151 
00152   TEST_FOR_EXCEPTION(evIn==0, std::runtime_error, "Epetra_TSFOperator::Apply "
00153          "cannot deal with multivectors");
00154   TEST_FOR_EXCEPTION(evOut==0, std::runtime_error, "Epetra_TSFOperator::Apply "
00155          "cannot deal with multivectors");
00156 
00157   const EpetraVectorSpace* ed 
00158     = dynamic_cast<const EpetraVectorSpace*>(A_.range().ptr().get());
00159   const EpetraVectorSpace* er 
00160     = dynamic_cast<const EpetraVectorSpace*>(A_.domain().ptr().get());
00161 
00162   RCP<Thyra::VectorBase<double> > vpIn 
00163     = rcp(new EpetraVector(rcp(ed, false), 
00164          rcp(evIn, false)));
00165   RCP<Thyra::VectorBase<double> > vpOut 
00166     = rcp(new EpetraVector(rcp(er, false), 
00167          rcp(evOut, false)));
00168   Vector<double> vIn = vpIn;
00169   Vector<double> vOut = vpOut;
00170   
00171   SolverState<double> state = solver_.solve(A_, vIn, vOut);
00172 
00173   if (state.finalState() == SolveCrashed) return -1;
00174   else if (state.finalState() == SolveFailedToConverge) return -2;
00175   else out = EpetraVector::getConcrete(vOut);
00176 
00177   return 0;
00178 }
00179 
00180 
00181 
00182 
00183 double Epetra_TSFOperator::NormInf() const 
00184 {
00185   TEST_FOR_EXCEPT(true);
00186   return -1; // -Wall
00187 }
00188 
00189 const char* Epetra_TSFOperator::Label() const 
00190 {
00191   return label_.c_str();
00192 }

Site Contact