TSFInverseOperatorImpl.hpp
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 #ifndef TSFINVERSEOPERATOR_IMPL_HPP
00030 #define TSFINVERSEOPERATOR_IMPL_HPP
00031 
00032 #include "SundanceDefs.hpp"
00033 #include "SundanceTabs.hpp"
00034 #include "TSFSolverState.hpp"
00035 #include "TSFInverseOperatorDecl.hpp"
00036 #include "Thyra_VectorStdOps.hpp"
00037 #include "Thyra_VectorSpaceBase.hpp"
00038 
00039 #include "Teuchos_RefCountPtr.hpp"
00040 
00041 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00042 #include "TSFSimpleTransposedOpImpl.hpp"
00043 #endif
00044 
00045 
00046 namespace TSFExtended
00047 {
00048 using Teuchos::RCP;
00049 
00050 /*
00051  * Ctor with a linear operator and a solver specified.
00052  */
00053 template <class Scalar> inline
00054 InverseOperator<Scalar>::InverseOperator(const LinearOperator<Scalar>& op, 
00055   const LinearSolver<Scalar>& solver)
00056   : op_(op), solver_(solver) {;}
00057 
00058 
00059 /* 
00060  * Compute alpha*M*x + beta*y, where M=*this.
00061  * @param M_trans specifies whether the operator is transposed:
00062  *                op(M) = M, for M_trans == NOTRANS
00063  *                op(M) = M', for M_trans == TRANS
00064  * @param x       vector of length this->domain()->dim()
00065  * @param y       vector of length this->range()->dim()
00066  * @param alpha   scalar multiplying M*x (default is 1.0)
00067  * @param beta    scalar multiplying y (default is 0.0)
00068  */
00069 template <class Scalar> inline
00070 void InverseOperator<Scalar>::generalApply(
00071   const Thyra::EOpTransp            M_trans
00072   ,const Thyra::VectorBase<Scalar>    &x
00073   ,Thyra::VectorBase<Scalar>          *y
00074   ,const Scalar            alpha 
00075   ,const Scalar            beta  
00076   ) const 
00077 {
00078   
00079   Tabs tab(0);
00080   SUNDANCE_MSG2(this->verb(), tab << "InverseOperator::generalApply()");
00081 
00082   TEST_FOR_EXCEPTION(dynamic_cast<Thyra::ZeroLinearOpBase<Scalar>* >(op_.ptr().get()) != 0, std::runtime_error,
00083     "InverseOperator<Scalar>::apply() called on a ZeroOperator.");
00084   TEST_FOR_EXCEPTION(op_.domain().dim() != op_.range().dim(), std::runtime_error,
00085     "InverseOperator<Scalar>::apply() called on a non-square operator.");
00086 
00087   if (alpha==Teuchos::ScalarTraits<Scalar>::zero())
00088   {
00089     Ptr<VectorBase<Scalar> > yp(y);
00090     Vt_S(yp, beta);
00091   }
00092   else
00093   {
00094     Vector<Scalar> temp = createMember(*(x.space()));
00095     Vector<Scalar> result;
00096     assign(temp.ptr().ptr(), x);
00097     SolverState<Scalar> haveSoln;
00098     if (M_trans==Thyra::NOTRANS)
00099     {
00100       haveSoln = solver_.solve(op_, temp, result);
00101     }
00102     else
00103     {
00104       haveSoln = solver_.solve(op_.transpose(), temp, result);
00105     }
00106     TEST_FOR_EXCEPTION(haveSoln.finalState() != SolveConverged, 
00107       std::runtime_error,
00108       "InverseOperator<Scalar>::apply() " 
00109       << haveSoln.stateDescription());
00110     Vt_S(result.ptr().ptr(), alpha);
00111     Ptr<VectorBase<Scalar> > yp(y);
00112     V_StVpV(yp, beta, *y, *(result.ptr()));
00113   }      
00114   SUNDANCE_MSG2(this->verb(), tab << "done InverseOperator::generalApply()");
00115 }
00116 
00117 
00118 /** 
00119  * Return the domain of the operator. 
00120  */
00121 template <class Scalar> inline
00122 RCP<const Thyra::VectorSpaceBase<Scalar> > 
00123 InverseOperator<Scalar>::domain() const 
00124 {return op_.ptr()->domain();}
00125     
00126 
00127 /** 
00128  * Return the range of the operator. 
00129  */
00130 template <class Scalar> inline
00131 RCP<const Thyra::VectorSpaceBase<Scalar> >
00132 InverseOperator<Scalar>::range() const 
00133 {return op_.ptr()->range();}
00134 
00135 
00136 template <class Scalar> 
00137 void InverseOperator<Scalar>::print(std::ostream& os) const
00138 {
00139   Tabs tab(0);
00140   os << tab << "InverseOperator[" << std::endl;
00141   Tabs tab1;
00142   os << tab1 << "op=" << op_ << std::endl;
00143   os << tab << "]" << std::endl;
00144 }
00145 
00146 
00147 template <class Scalar> 
00148 LinearOperator<Scalar> 
00149 inverse(const LinearOperator<Scalar>& op, 
00150   const LinearSolver<Scalar>& solver)
00151 {
00152   RCP<LinearOpBase<Scalar> > rtn 
00153     = rcp(new InverseOperator<Scalar>(op, solver));
00154   return rtn;
00155 }
00156 
00157 }
00158 
00159 #endif

Site Contact