PlayaLinearOperatorImpl.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                 Playa: Programmable Linear Algebra
00005 //                 Copyright 2012 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #ifndef PLAYA_LINEAROPERATORIMPL_HPP
00043 #define PLAYA_LINEAROPERATORIMPL_HPP
00044 
00045 #include "PlayaDefs.hpp"
00046 #include "PlayaLinearOperatorDecl.hpp"
00047 #include "Teuchos_RefCountPtr.hpp"
00048 #include "PlayaVectorDecl.hpp"
00049 #include "PlayaVectorSpaceDecl.hpp"
00050 #include "PlayaInverseOperatorDecl.hpp"
00051 #include "PlayaSimpleTransposedOpDecl.hpp"
00052 #include "PlayaBlockOperatorBaseDecl.hpp"
00053 #include "PlayaVectorType.hpp"
00054 #include "PlayaOut.hpp"
00055 
00056 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00057 #include "PlayaVectorImpl.hpp"
00058 #endif
00059 
00060 
00061 
00062 using namespace Playa;
00063 using namespace Teuchos;
00064 
00065 
00066 template <class Scalar>
00067 class InverseOperator;
00068 
00069 
00070 //=======================================================================
00071 template <class Scalar>
00072 LinearOperator<Scalar>::LinearOperator() 
00073   : Handle<LinearOperatorBase<Scalar> >() {;}
00074 
00075 
00076 //=======================================================================
00077 template <class Scalar>
00078 LinearOperator<Scalar>::LinearOperator(const RCP<LinearOperatorBase<Scalar> >& smartPtr) 
00079   : Handle<LinearOperatorBase<Scalar> >(smartPtr)  {;}
00080 
00081 
00082 
00083 
00084 //=======================================================================
00085 template <class Scalar> inline 
00086 void LinearOperator<Scalar>::apply(const Vector<Scalar>& in,
00087   Vector<Scalar>& out) const
00088 {
00089   Tabs tab(0);
00090   PLAYA_MSG1(this->verb(), tab << "Operator=" << this->description()
00091     << ",  calling apply() function");
00092   Tabs tab1;
00093   
00094   if (this->verb() > 2)
00095   {
00096     Tabs tab2;
00097     Out::os() << tab2 << "input vector = " << in << std::endl;
00098   }
00099   else if (this->verb() > 1)
00100   {
00101     Tabs tab2;
00102     Out::os() << tab2 << "input vector = " << in.description() << std::endl;
00103   }
00104 
00105   /* the result vector might not be initialized. If it's null,
00106    * create a new vector in the range space */
00107   if (out.ptr().get()==0)
00108   {
00109     Tabs tab2;
00110     PLAYA_MSG3(this->verb(), tab2 << "allocating output vector");
00111     out = this->range().createMember();
00112   }
00113   else
00114   {
00115     Tabs tab2;
00116     PLAYA_MSG3(this->verb(), tab2 << "using preallocated output vector");
00117   }
00118 
00119   this->ptr()->apply(Teuchos::NO_TRANS, in, out);
00120 
00121   if (this->verb() > 2)
00122   {
00123     Tabs tab2;
00124     Out::os() << tab2 << "output vector = " << out << std::endl;
00125   }
00126   else if (this->verb() > 1)
00127   {
00128     Tabs tab2;
00129     Out::os() << tab2 << "output vector = " << out.description() << std::endl;
00130   }
00131 
00132   PLAYA_MSG1(this->verb(), tab << "Operator=" << this->description()
00133     << ",  done with apply() function");
00134   
00135 }
00136 
00137 
00138 
00139 
00140 //=======================================================================
00141 template <class Scalar> inline 
00142 void LinearOperator<Scalar>::applyTranspose(const Vector<Scalar>& in,
00143   Vector<Scalar>& out) const
00144 {
00145   Tabs tab(0);
00146   PLAYA_MSG1(this->verb(), tab << "Operator=" << this->description()
00147     << ",  calling applyTranspose() function");
00148   Tabs tab1;
00149   
00150   if (this->verb() > 2)
00151   {
00152     Tabs tab2;
00153     Out::os() << tab2 << "input vector = " << in << std::endl;
00154   }
00155   else if (this->verb() > 1)
00156   {
00157     Tabs tab2;
00158     Out::os() << tab2 << "input vector = " << in.description() << std::endl;
00159   }
00160 
00161 
00162   /* the result vector might not be initialized. If it's null,
00163    * create a new vector in the range space */
00164   if (out.ptr().get()==0)
00165   {
00166     Tabs tab2;
00167     PLAYA_MSG3(this->verb(), tab2 << "allocating output vector");
00168     out = this->domain().createMember();
00169   }
00170   else
00171   {
00172     Tabs tab2;
00173     PLAYA_MSG3(this->verb(), tab2 << "using preallocated output vector");
00174   }
00175 
00176   this->ptr()->apply(Teuchos::TRANS, in, out);
00177 
00178   
00179   
00180   if (this->verb() > 2)
00181   {
00182     Tabs tab2;
00183     Out::os() << tab2 << "output vector = " << out << std::endl;
00184   }
00185   else if (this->verb() > 1)
00186   {
00187     Tabs tab2;
00188     Out::os() << tab2 << "output vector = " << out.description() << std::endl;
00189   }
00190 
00191   PLAYA_MSG1(this->verb(), tab << "Operator=" << this->description()
00192     << ",  done with applyTranpose() function");
00193   
00194 }
00195 
00196 
00197 //=======================================================================
00198 template <class Scalar>
00199 RCP<Time>& LinearOperator<Scalar>::opTimer()
00200 {
00201   static RCP<Time> rtn 
00202     = TimeMonitor::getNewTimer("Low-level vector operations");
00203   return rtn;
00204 }
00205 
00206 //=======================================================================
00207 template <class Scalar>
00208 LinearOperator<Scalar> LinearOperator<Scalar>::transpose() const
00209 {
00210   LinearOperator<Scalar> op = transposedOperator(*this);
00211   return op;
00212 }
00213 
00214 
00215 
00216 
00217 
00218 //=======================================================================
00219 template <class Scalar>
00220 RCP<LoadableMatrix<Scalar> > LinearOperator<Scalar>::matrix()
00221 {
00222   RCP<LoadableMatrix<Scalar> > rtn 
00223     = rcp_dynamic_cast<LoadableMatrix<Scalar> >(this->ptr());
00224   return rtn;
00225 }
00226 
00227 //=======================================================================
00228 template <class Scalar>
00229 void LinearOperator<Scalar>::getRow(const int& row, 
00230   Teuchos::Array<int>& indices, 
00231   Teuchos::Array<Scalar>& values) const
00232 {
00233   const RowAccessibleOp<Scalar>* val = 
00234     dynamic_cast<const RowAccessibleOp<Scalar>* >(this->ptr().get());
00235   TEUCHOS_TEST_FOR_EXCEPTION(val == 0, std::runtime_error, 
00236     "Operator not row accessible; getRow() not defined.");
00237   val->getRow(row, indices, values);
00238 }
00239 
00240 //=============================================================================
00241 template <class Scalar>
00242 int LinearOperator<Scalar>::numBlockRows() const
00243 {
00244   const BlockOperatorBase<Scalar>* b = dynamic_cast<const BlockOperatorBase<Scalar>* >(this->ptr().get());
00245   if (b==0) return 1;
00246   return b->numBlockRows(); 
00247 }
00248 
00249 //=============================================================================
00250 template <class Scalar>
00251 int LinearOperator<Scalar>::numBlockCols() const
00252 {
00253   const BlockOperatorBase<Scalar>* b = dynamic_cast<const BlockOperatorBase<Scalar>* >(this->ptr().get());
00254   if (b==0) return 1;
00255   return b->numBlockCols(); 
00256 }
00257 
00258 
00259 //=============================================================================
00260 template <class Scalar>
00261 const VectorSpace<Scalar> 
00262 LinearOperator<Scalar>::range() const
00263 {return this->ptr()->range();}
00264   
00265 
00266 //=============================================================================
00267 template <class Scalar>
00268 void LinearOperator<Scalar>::setBlock(int i, int j, 
00269   const LinearOperator<Scalar>& sub) 
00270 {
00271   SetableBlockOperatorBase<Scalar>* b = 
00272     dynamic_cast<SetableBlockOperatorBase<Scalar>* >(this->ptr().get());
00273   
00274   TEUCHOS_TEST_FOR_EXCEPTION(b == 0, std::runtime_error, 
00275     "Can't call setBlock since operator not SetableBlockOperatorBase");
00276 
00277   b->setBlock(i, j, sub);
00278 } 
00279 
00280 
00281 
00282 //=============================================================================
00283 template <class Scalar>
00284 const  VectorSpace<Scalar> 
00285 LinearOperator<Scalar>::domain() const 
00286 {return this->ptr()->domain();}
00287 
00288 
00289 
00290 //=============================================================================
00291 template <class Scalar>
00292 LinearOperator<Scalar> LinearOperator<Scalar>::getBlock(const int &i, 
00293   const int &j) const 
00294 {
00295   const BlockOperatorBase<Scalar>* b = 
00296     dynamic_cast<const BlockOperatorBase<Scalar>* >(this->ptr().get());
00297   
00298   if (b==0)
00299   {
00300     TEUCHOS_TEST_FOR_EXCEPTION(i != 0 || j != 0, std::runtime_error, 
00301       "nonzero block index (" << i << "," << j << ") into "
00302       "non-block operator");
00303     return *this;
00304   }
00305   return b->getBlock(i, j);
00306 }
00307 
00308 
00309 //=============================================================================
00310 template <class Scalar>
00311 LinearOperator<Scalar> LinearOperator<Scalar>::getNonconstBlock(const int &i, 
00312   const int &j) 
00313 {
00314   BlockOperatorBase<Scalar>* b = 
00315     dynamic_cast<BlockOperatorBase<Scalar>* >(this->ptr().get());
00316   
00317   if (b==0)
00318   {
00319     TEUCHOS_TEST_FOR_EXCEPTION(i != 0 || j != 0, std::runtime_error, 
00320       "nonzero block index (" << i << "," << j << ") into "
00321       "non-block operator");
00322     return *this;
00323   }
00324   return b->getNonconstBlock(i, j);
00325 }
00326 
00327  
00328 
00329 //=============================================================================
00330 template <class Scalar>
00331 void LinearOperator<Scalar>::endBlockFill() 
00332 {
00333   SetableBlockOperatorBase<Scalar>* b = 
00334     dynamic_cast<SetableBlockOperatorBase<Scalar>* >(this->ptr().get());
00335   
00336   TEUCHOS_TEST_FOR_EXCEPTION(b == 0, std::runtime_error, 
00337     "Can't call endBlockFill because operator is not a SetableBlockOperator");
00338 
00339   
00340   b->endBlockFill();
00341 } 
00342 
00343 
00344 
00345 
00346 
00347 
00348 #endif

Site Contact