TSFLinearOperatorImpl.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 TSFLINEAROPERATORIMPL_HPP
00030 #define TSFLINEAROPERATORIMPL_HPP
00031 
00032 #include "SundanceDefs.hpp"
00033 #include "TSFLinearOperatorDecl.hpp"
00034 #include "Teuchos_RefCountPtr.hpp"
00035 #include "TSFVectorDecl.hpp"
00036 #include "TSFVectorSpaceDecl.hpp"
00037 #include "TSFInverseOperatorDecl.hpp"
00038 #include "TSFSimpleTransposedOpDecl.hpp"
00039 #include "TSFBlockOperatorBaseDecl.hpp"
00040 #include "TSFVectorType.hpp"
00041 #include "SundanceOut.hpp"
00042 
00043 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00044 #include "TSFVectorImpl.hpp"
00045 #endif
00046 
00047 
00048 
00049 using namespace TSFExtended;
00050 using namespace Teuchos;
00051 using namespace Sundance;
00052 
00053 template <class Scalar>
00054 class InverseOperator;
00055 
00056 
00057 //=======================================================================
00058 template <class Scalar>
00059 LinearOperator<Scalar>::LinearOperator() 
00060   : Handle<Thyra::LinearOpBase<Scalar> >(), verb_(0) {;}
00061 
00062 
00063 //=======================================================================
00064 template <class Scalar>
00065 LinearOperator<Scalar>::LinearOperator(const RCP<Thyra::LinearOpBase<Scalar> >& smartPtr) 
00066   : Handle<Thyra::LinearOpBase<Scalar> >(smartPtr), verb_(0) {;}
00067 
00068 
00069 
00070 
00071 //=======================================================================
00072 template <class Scalar> inline 
00073 void LinearOperator<Scalar>::apply(const Vector<Scalar>& in,
00074   Vector<Scalar>& out,
00075   const Scalar& alpha,
00076   const Scalar& beta) const
00077 {
00078   Tabs tab(0);
00079   SUNDANCE_MSG1(this->verb(), tab << "Operator=" << this->description()
00080     << ",  calling apply() function");
00081   Tabs tab1;
00082   SUNDANCE_MSG1(this->verb(), tab1 << "alpha=" << alpha);
00083   SUNDANCE_MSG1(this->verb(), tab1 << "beta=" << beta);
00084   
00085   if (this->verb() > 2)
00086   {
00087     Tabs tab2;
00088     Out::os() << tab2 << "input vector = " << in << std::endl;
00089   }
00090   else if (this->verb() > 1)
00091   {
00092     Tabs tab2;
00093     Out::os() << tab2 << "input vector = " << in.description() << std::endl;
00094   }
00095 
00096   /* the result vector might not be initialized. If it's null,
00097    * create a new vector in the range space */
00098   if (out.ptr().get()==0)
00099   {
00100     Tabs tab2;
00101     SUNDANCE_MSG3(this->verb(), tab2 << "allocating output vector");
00102     out = this->range().createMember();
00103   }
00104   else
00105   {
00106     Tabs tab2;
00107     SUNDANCE_MSG3(this->verb(), tab2 << "using preallocated output vector");
00108   }
00109 
00110   this->ptr()->apply(Thyra::NOTRANS, *(in.ptr().ptr()),
00111     out.ptr().ptr(), alpha, beta);
00112 
00113   
00114   
00115   if (this->verb() > 2)
00116   {
00117     Tabs tab2;
00118     Out::os() << tab2 << "output vector = " << out << std::endl;
00119   }
00120   else if (this->verb() > 1)
00121   {
00122     Tabs tab2;
00123     Out::os() << tab2 << "output vector = " << out.description() << std::endl;
00124   }
00125 
00126   SUNDANCE_MSG1(this->verb(), tab << "Operator=" << this->description()
00127     << ",  done with apply() function");
00128   
00129 }
00130 
00131 
00132 
00133 
00134 //=======================================================================
00135 template <class Scalar> inline 
00136 void LinearOperator<Scalar>::applyTranspose(const Vector<Scalar>& in,
00137   Vector<Scalar>& out,
00138   const Scalar& alpha,
00139   const Scalar& beta) const
00140 {
00141   Tabs tab(0);
00142   SUNDANCE_MSG1(this->verb(), tab << "Operator=" << this->description()
00143     << ",  calling applyTranspose() function");
00144   Tabs tab1;
00145   SUNDANCE_MSG1(this->verb(), tab1 << "alpha=" << alpha);
00146   SUNDANCE_MSG1(this->verb(), tab1 << "beta=" << beta);
00147   
00148   if (this->verb() > 2)
00149   {
00150     Tabs tab2;
00151     Out::os() << tab2 << "input vector = " << in << std::endl;
00152   }
00153   else if (this->verb() > 1)
00154   {
00155     Tabs tab2;
00156     Out::os() << tab2 << "input vector = " << in.description() << std::endl;
00157   }
00158 
00159 
00160   /* the result vector might not be initialized. If it's null,
00161    * create a new vector in the range space */
00162   if (out.ptr().get()==0)
00163   {
00164     Tabs tab2;
00165     SUNDANCE_MSG3(this->verb(), tab2 << "allocating output vector");
00166     out = this->domain().createMember();
00167   }
00168   else
00169   {
00170     Tabs tab2;
00171     SUNDANCE_MSG3(this->verb(), tab2 << "using preallocated output vector");
00172   }
00173 
00174   this->ptr()->apply(Thyra::TRANS, *(in.ptr().ptr()),
00175     out.ptr().ptr(), alpha, beta);
00176 
00177   
00178   
00179   if (this->verb() > 2)
00180   {
00181     Tabs tab2;
00182     Out::os() << tab2 << "output vector = " << out << std::endl;
00183   }
00184   else if (this->verb() > 1)
00185   {
00186     Tabs tab2;
00187     Out::os() << tab2 << "output vector = " << out.description() << std::endl;
00188   }
00189 
00190   SUNDANCE_MSG1(this->verb(), tab << "Operator=" << this->description()
00191     << ",  done with applyTranpose() function");
00192   
00193 }
00194 
00195 
00196 //=======================================================================
00197 template <class Scalar>
00198 RCP<Time>& LinearOperator<Scalar>::opTimer()
00199 {
00200   static RCP<Time> rtn 
00201     = TimeMonitor::getNewTimer("Low-level vector operations");
00202   return rtn;
00203 }
00204 
00205 //=======================================================================
00206 template <class Scalar>
00207 LinearOperator<Scalar> LinearOperator<Scalar>::transpose() const
00208 {
00209   LinearOperator<Scalar> op = transposedOperator(*this);
00210   return op;
00211 }
00212 
00213 
00214 
00215 
00216 
00217 //=======================================================================
00218 template <class Scalar>
00219 RCP<LoadableMatrix<Scalar> > LinearOperator<Scalar>::matrix()
00220 {
00221   RCP<LoadableMatrix<Scalar> > rtn 
00222     = rcp_dynamic_cast<LoadableMatrix<Scalar> >(this->ptr());
00223   return rtn;
00224 }
00225 
00226 //=======================================================================
00227 template <class Scalar>
00228 void LinearOperator<Scalar>::getRow(const int& row, 
00229   Teuchos::Array<int>& indices, 
00230   Teuchos::Array<Scalar>& values) const
00231 {
00232   const RowAccessibleOp<Scalar>* val = 
00233     dynamic_cast<const RowAccessibleOp<Scalar>* >(this->ptr().get());
00234   TEST_FOR_EXCEPTION(val == 0, std::runtime_error, 
00235     "Operator not row accessible; getRow() not defined.");
00236   val->getRow(row, indices, values);
00237 }
00238 
00239 //=============================================================================
00240 template <class Scalar>
00241 int LinearOperator<Scalar>::numBlockRows() const
00242 {
00243   const BlockOperatorBase<Scalar>* b = dynamic_cast<const BlockOperatorBase<Scalar>* >(this->ptr().get());
00244   if (b==0) return 1;
00245   return b->numBlockRows(); 
00246 }
00247 
00248 //=============================================================================
00249 template <class Scalar>
00250 int LinearOperator<Scalar>::numBlockCols() const
00251 {
00252   const BlockOperatorBase<Scalar>* b = dynamic_cast<const BlockOperatorBase<Scalar>* >(this->ptr().get());
00253   if (b==0) return 1;
00254   return b->numBlockCols(); 
00255 }
00256 
00257 
00258 //=============================================================================
00259 template <class Scalar>
00260 const VectorSpace<Scalar> 
00261 LinearOperator<Scalar>::range() const
00262 {return this->ptr()->range();}
00263   
00264 
00265 //=============================================================================
00266 template <class Scalar>
00267 void LinearOperator<Scalar>::setBlock(int i, int j, 
00268   const LinearOperator<Scalar>& sub) 
00269 {
00270   SetableBlockOperatorBase<Scalar>* b = 
00271     dynamic_cast<SetableBlockOperatorBase<Scalar>* >(this->ptr().get());
00272   
00273   TEST_FOR_EXCEPTION(b == 0, std::runtime_error, 
00274     "Can't call setBlock since operator not SetableBlockOperatorBase");
00275 
00276   b->setBlock(i, j, sub);
00277 } 
00278 
00279 
00280 
00281 //=============================================================================
00282 template <class Scalar>
00283 const  VectorSpace<Scalar> 
00284 LinearOperator<Scalar>::domain() const 
00285 {return this->ptr()->domain();}
00286 
00287 
00288 
00289 //=============================================================================
00290 template <class Scalar>
00291 LinearOperator<Scalar> LinearOperator<Scalar>::getBlock(const int &i, 
00292   const int &j) const 
00293 {
00294   const BlockOperatorBase<Scalar>* b = 
00295     dynamic_cast<const BlockOperatorBase<Scalar>* >(this->ptr().get());
00296   
00297   if (b==0)
00298   {
00299     TEST_FOR_EXCEPTION(i != 0 || j != 0, std::runtime_error, 
00300       "nonzero block index (" << i << "," << j << ") into "
00301       "non-block operator");
00302     return *this;
00303   }
00304   return b->getBlock(i, j);
00305 }
00306 
00307 
00308 //=============================================================================
00309 template <class Scalar>
00310 LinearOperator<Scalar> LinearOperator<Scalar>::getNonconstBlock(const int &i, 
00311   const int &j) 
00312 {
00313   BlockOperatorBase<Scalar>* b = 
00314     dynamic_cast<BlockOperatorBase<Scalar>* >(this->ptr().get());
00315   
00316   if (b==0)
00317   {
00318     TEST_FOR_EXCEPTION(i != 0 || j != 0, std::runtime_error, 
00319       "nonzero block index (" << i << "," << j << ") into "
00320       "non-block operator");
00321     return *this;
00322   }
00323   return b->getNonconstBlock(i, j);
00324 }
00325 
00326  
00327 
00328 //=============================================================================
00329 template <class Scalar>
00330 void LinearOperator<Scalar>::endBlockFill() 
00331 {
00332   SetableBlockOperatorBase<Scalar>* b = 
00333     dynamic_cast<SetableBlockOperatorBase<Scalar>* >(this->ptr().get());
00334   
00335   TEST_FOR_EXCEPTION(b == 0, std::runtime_error, 
00336     "Can't call endBlockFill because operator is not a SetableBlockOperator");
00337 
00338   
00339   b->endBlockFill();
00340 } 
00341 
00342 
00343 
00344 
00345 
00346 
00347 #endif

Site Contact