Thyra_DefaultAddedLinearOp.hpp

Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //    Thyra: Interfaces and Support for Abstract Numerical Algorithms
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 THYRA_DEFAULT_ADDED_LINEAR_OP_HPP
00030 #define THYRA_DEFAULT_ADDED_LINEAR_OP_HPP
00031 
00032 #include "Thyra_DefaultAddedLinearOpDecl.hpp"
00033 #include "Thyra_AssertOp.hpp"
00034 #include "Teuchos_Utils.hpp"
00035 
00036 namespace Thyra {
00037 
00038 // Constructors/initializers/accessors
00039 
00040 template<class Scalar>
00041 DefaultAddedLinearOp<Scalar>::DefaultAddedLinearOp()
00042 {}
00043 
00044 template<class Scalar>
00045 DefaultAddedLinearOp<Scalar>::DefaultAddedLinearOp(
00046   const int                                                   numOps
00047   ,const Teuchos::RefCountPtr<LinearOpBase<Scalar> >          Ops[]
00048   )
00049 {
00050   initialize(numOps,Ops);
00051 }
00052 
00053 template<class Scalar>
00054 DefaultAddedLinearOp<Scalar>::DefaultAddedLinearOp(
00055   const int                                                   numOps
00056   ,const Teuchos::RefCountPtr<const LinearOpBase<Scalar> >    Ops[]
00057   )
00058 {
00059   initialize(numOps,Ops);
00060 }
00061 
00062 template<class Scalar>
00063 void DefaultAddedLinearOp<Scalar>::initialize(
00064   const int                                                   numOps
00065   ,const Teuchos::RefCountPtr<LinearOpBase<Scalar> >          Ops[]
00066   )
00067 {
00068 #ifdef TEUCHOS_DEBUG
00069   TEST_FOR_EXCEPT( numOps <= 0 || Ops == NULL );
00070 #endif
00071   Ops_.resize(numOps);
00072   for( int k = 0; k < numOps; ++k )
00073     Ops_[k].initialize(Ops[k]);
00074   validateOps();
00075 }
00076 
00077 template<class Scalar>
00078 void DefaultAddedLinearOp<Scalar>::initialize(
00079   const int                                                   numOps
00080   ,const Teuchos::RefCountPtr<const LinearOpBase<Scalar> >    Ops[]
00081   )
00082 {
00083 #ifdef TEUCHOS_DEBUG
00084   TEST_FOR_EXCEPT( numOps <= 0 || Ops == NULL );
00085 #endif
00086   Ops_.resize(numOps);
00087   for( int k = 0; k < numOps; ++k )
00088     Ops_[k].initialize(Ops[k]);
00089   validateOps();
00090 }
00091 
00092 template<class Scalar>
00093 void DefaultAddedLinearOp<Scalar>::uninitialize()
00094 {
00095   Ops_.resize(0);
00096 }
00097 
00098 // Overridden form AddedLinearOpBase
00099 
00100 template<class Scalar>
00101 int DefaultAddedLinearOp<Scalar>::numOps() const
00102 {
00103   return Ops_.size();
00104 }
00105 
00106 template<class Scalar>
00107 bool DefaultAddedLinearOp<Scalar>::opIsConst(const int k) const
00108 {
00109 #ifdef TEUCHOS_DEBUG
00110   TEST_FOR_EXCEPT( !( 0 <= k && k < numOps() ) );
00111 #endif
00112   return Ops_[k].isConst();
00113 }
00114 
00115 template<class Scalar>
00116 Teuchos::RefCountPtr<LinearOpBase<Scalar> >
00117 DefaultAddedLinearOp<Scalar>::getNonconstOp(const int k)
00118 {
00119 #ifdef TEUCHOS_DEBUG
00120   TEST_FOR_EXCEPT( !( 0 <= k && k < numOps() ) );
00121 #endif
00122   return Ops_[k].getNonconstObj();
00123 }
00124 
00125 template<class Scalar>
00126 Teuchos::RefCountPtr<const LinearOpBase<Scalar> >
00127 DefaultAddedLinearOp<Scalar>::getOp(const int k) const
00128 {
00129 #ifdef TEUCHOS_DEBUG
00130   TEST_FOR_EXCEPT( !( 0 <= k && k < numOps() ) );
00131 #endif
00132   return Ops_[k].getConstObj();
00133 }
00134 
00135 // Overridden from LinearOpBase
00136 
00137 template<class Scalar>
00138 Teuchos::RefCountPtr< const VectorSpaceBase<Scalar> >
00139 DefaultAddedLinearOp<Scalar>::range() const
00140 {
00141   assertInitialized();
00142   return getOp(0)->range();
00143 }
00144 
00145 template<class Scalar>
00146 Teuchos::RefCountPtr< const VectorSpaceBase<Scalar> >
00147 DefaultAddedLinearOp<Scalar>::domain() const
00148 {
00149   assertInitialized();
00150   return getOp(numOps()-1)->domain();
00151 }
00152 
00153 template<class Scalar>
00154 Teuchos::RefCountPtr<const LinearOpBase<Scalar> >
00155 DefaultAddedLinearOp<Scalar>::clone() const
00156 {
00157   return Teuchos::null; // Not supported yet but could be!
00158 }
00159 
00160 // Overridden from Teuchos::Describable
00161                                                 
00162 template<class Scalar>
00163 std::string DefaultAddedLinearOp<Scalar>::description() const
00164 {
00165   assertInitialized();
00166   typedef Teuchos::ScalarTraits<Scalar>  ST;
00167   std::ostringstream oss;
00168   oss << "Thyra::DefaultAddedLinearOp<" << ST::name() << ">{numOps = "<<numOps()<<"}";
00169   return oss.str();
00170 }
00171 
00172 template<class Scalar>
00173 void DefaultAddedLinearOp<Scalar>::describe(
00174   Teuchos::FancyOStream                &out_arg
00175   ,const Teuchos::EVerbosityLevel      verbLevel
00176   ) const
00177 {
00178   typedef Teuchos::ScalarTraits<Scalar>  ST;
00179   using Teuchos::RefCountPtr;
00180   using Teuchos::FancyOStream;
00181   using Teuchos::OSTab;
00182   assertInitialized();
00183   RefCountPtr<FancyOStream> out = rcp(&out_arg,false);
00184   OSTab tab(out);
00185   const int numOps = Ops_.size();
00186   switch(verbLevel) {
00187     case Teuchos::VERB_DEFAULT:
00188     case Teuchos::VERB_LOW:
00189       *out << this->description() << std::endl;
00190       break;
00191     case Teuchos::VERB_MEDIUM:
00192     case Teuchos::VERB_HIGH:
00193     case Teuchos::VERB_EXTREME:
00194     {
00195       *out
00196         << "Thyra::DefaultAddedLinearOp<" << ST::name() << ">{"
00197         << "rangeDim=" << this->range()->dim()
00198         << ",domainDim="<< this->domain()->dim() << "}\n";
00199       OSTab tab(out);
00200       *out
00201         <<  "numOps="<< numOps << std::endl
00202         <<  "Constituent LinearOpBase objects for M = Op[0]*...*Op[numOps-1]:\n";
00203       tab.incrTab();
00204       for( int k = 0; k < numOps; ++k ) {
00205         *out << "Op["<<k<<"] =\n" << Teuchos::describe(*getOp(k),verbLevel);
00206       }
00207       break;
00208     }
00209     default:
00210       TEST_FOR_EXCEPT(true); // Should never get here!
00211   }
00212 }
00213 
00214 // protected
00215 
00216 // Overridden from SingleScalarLinearOpBase
00217 
00218 template<class Scalar>
00219 bool DefaultAddedLinearOp<Scalar>::opSupported(ETransp M_trans) const
00220 {
00221   bool opSupported = true;
00222   for( int k = 0; k < static_cast<int>(Ops_.size()); ++k )
00223     if(!Thyra::opSupported(*getOp(k),M_trans)) opSupported = false;
00224   return opSupported;
00225   // ToDo: Cache these?
00226 }
00227 
00228 template<class Scalar>
00229 void DefaultAddedLinearOp<Scalar>::apply(
00230   const ETransp                     M_trans
00231   ,const MultiVectorBase<Scalar>    &X
00232   ,MultiVectorBase<Scalar>          *Y
00233   ,const Scalar                     alpha
00234   ,const Scalar                     beta
00235   ) const
00236 {
00237   typedef Teuchos::ScalarTraits<Scalar> ST;
00238   //
00239   // Y = alpha * op(M) * X + beta*Y
00240   //
00241   // =>
00242   //
00243   // Y = beta*Y + sum(alpha*op(Op[j])*X),j=0...numOps-1)
00244   //
00245   const int numOps = Ops_.size();
00246   for( int j = 0; j < numOps; ++j )
00247     Thyra::apply(*getOp(j),M_trans,X,Y,alpha,j==0?beta:ST::one());
00248 }
00249 
00250 // private
00251 
00252 template<class Scalar>
00253 void DefaultAddedLinearOp<Scalar>::validateOps()
00254 {
00255   typedef std::string s;
00256   using Teuchos::toString;
00257 #ifdef TEUCHOS_DEBUG
00258   try {
00259     const int numOps = Ops_.size();
00260     for( int k = 0; k < numOps; ++k ) {
00261       TEST_FOR_EXCEPT( Ops_[k]().get() == NULL );
00262       if( k > 0 ) {
00263         THYRA_ASSERT_VEC_SPACES_NAMES(
00264           "DefaultAddedLinearOp<Scalar>::initialize(...)"
00265           ,*Ops_[k]()->range(),("(*Ops["+toString(k)+"]->range())")
00266           ,*Ops_[0]()->range(),"(*Ops[0]->range())"
00267           );
00268         THYRA_ASSERT_VEC_SPACES_NAMES(
00269           "DefaultAddedLinearOp<Scalar>::initialize(...)"
00270           ,*Ops_[k]()->domain(),("(*Ops["+toString(k)+"]->domain())")
00271           ,*Ops_[0]()->domain(),"(*Ops[0]->domain())"
00272           );
00273       }
00274     }
00275   }
00276   catch(...) {
00277     uninitialize();
00278     throw;
00279   }
00280 #endif
00281 }
00282 
00283 } // end namespace Thyra
00284 
00285 template<class Scalar>
00286 Teuchos::RefCountPtr<Thyra::LinearOpBase<Scalar> >
00287 Thyra::nonconstAdd(
00288   const Teuchos::RefCountPtr<LinearOpBase<Scalar> >    &A
00289   ,const Teuchos::RefCountPtr<LinearOpBase<Scalar> >   &B
00290   )
00291 {
00292   using Teuchos::arrayArg;
00293   using Teuchos::RefCountPtr;
00294   return Teuchos::rcp(
00295     new DefaultAddedLinearOp<Scalar>(
00296       2
00297       ,arrayArg<RefCountPtr<LinearOpBase<Scalar> > >(A,B)()
00298       )
00299     );
00300 }
00301 
00302 template<class Scalar>
00303 Teuchos::RefCountPtr<const Thyra::LinearOpBase<Scalar> >
00304 Thyra::add(
00305   const Teuchos::RefCountPtr<const LinearOpBase<Scalar> >    &A
00306   ,const Teuchos::RefCountPtr<const LinearOpBase<Scalar> >   &B
00307   )
00308 {
00309   using Teuchos::arrayArg;
00310   using Teuchos::RefCountPtr;
00311   return Teuchos::rcp(
00312     new DefaultAddedLinearOp<Scalar>(
00313       2
00314       ,arrayArg<RefCountPtr<const LinearOpBase<Scalar> > >(A,B)()
00315       )
00316     );
00317 }
00318 
00319 #endif  // THYRA_DEFAULT_ADDED_LINEAR_OP_HPP

Generated on Thu Sep 18 12:33:02 2008 for Thyra Package Browser (Single Doxygen Collection) by doxygen 1.3.9.1