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::RCP<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::RCP<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::RCP<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   setupDefaultObjectLabel();
00076 }
00077 
00078 template<class Scalar>
00079 void DefaultAddedLinearOp<Scalar>::initialize(
00080   const int                                                   numOps
00081   ,const Teuchos::RCP<const LinearOpBase<Scalar> >    Ops[]
00082   )
00083 {
00084 #ifdef TEUCHOS_DEBUG
00085   TEST_FOR_EXCEPT( numOps <= 0 || Ops == NULL );
00086 #endif
00087   Ops_.resize(numOps);
00088   for( int k = 0; k < numOps; ++k )
00089     Ops_[k].initialize(Ops[k]);
00090   validateOps();
00091   setupDefaultObjectLabel();
00092 }
00093 
00094 template<class Scalar>
00095 void DefaultAddedLinearOp<Scalar>::uninitialize()
00096 {
00097   Ops_.resize(0);
00098   setupDefaultObjectLabel();
00099 }
00100 
00101 // Overridden form AddedLinearOpBase
00102 
00103 template<class Scalar>
00104 int DefaultAddedLinearOp<Scalar>::numOps() const
00105 {
00106   return Ops_.size();
00107 }
00108 
00109 template<class Scalar>
00110 bool DefaultAddedLinearOp<Scalar>::opIsConst(const int k) const
00111 {
00112 #ifdef TEUCHOS_DEBUG
00113   TEST_FOR_EXCEPT( !( 0 <= k && k < numOps() ) );
00114 #endif
00115   return Ops_[k].isConst();
00116 }
00117 
00118 template<class Scalar>
00119 Teuchos::RCP<LinearOpBase<Scalar> >
00120 DefaultAddedLinearOp<Scalar>::getNonconstOp(const int k)
00121 {
00122 #ifdef TEUCHOS_DEBUG
00123   TEST_FOR_EXCEPT( !( 0 <= k && k < numOps() ) );
00124 #endif
00125   return Ops_[k].getNonconstObj();
00126 }
00127 
00128 template<class Scalar>
00129 Teuchos::RCP<const LinearOpBase<Scalar> >
00130 DefaultAddedLinearOp<Scalar>::getOp(const int k) const
00131 {
00132 #ifdef TEUCHOS_DEBUG
00133   TEST_FOR_EXCEPT( !( 0 <= k && k < numOps() ) );
00134 #endif
00135   return Ops_[k].getConstObj();
00136 }
00137 
00138 // Overridden from LinearOpBase
00139 
00140 template<class Scalar>
00141 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00142 DefaultAddedLinearOp<Scalar>::range() const
00143 {
00144   assertInitialized();
00145   return getOp(0)->range();
00146 }
00147 
00148 template<class Scalar>
00149 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00150 DefaultAddedLinearOp<Scalar>::domain() const
00151 {
00152   assertInitialized();
00153   return getOp(numOps()-1)->domain();
00154 }
00155 
00156 template<class Scalar>
00157 Teuchos::RCP<const LinearOpBase<Scalar> >
00158 DefaultAddedLinearOp<Scalar>::clone() const
00159 {
00160   return Teuchos::null; // Not supported yet but could be!
00161 }
00162 
00163 // Overridden from Teuchos::Describable
00164                                                 
00165 template<class Scalar>
00166 std::string DefaultAddedLinearOp<Scalar>::description() const
00167 {
00168   assertInitialized();
00169   std::ostringstream oss;
00170   oss << Teuchos::Describable::description() << "{numOps = "<<numOps()<<"}";
00171   return oss.str();
00172 }
00173 
00174 template<class Scalar>
00175 void DefaultAddedLinearOp<Scalar>::describe(
00176   Teuchos::FancyOStream                &out_arg
00177   ,const Teuchos::EVerbosityLevel      verbLevel
00178   ) const
00179 {
00180   typedef Teuchos::ScalarTraits<Scalar>  ST;
00181   using Teuchos::RCP;
00182   using Teuchos::FancyOStream;
00183   using Teuchos::OSTab;
00184   assertInitialized();
00185   RCP<FancyOStream> out = rcp(&out_arg,false);
00186   OSTab tab(out);
00187   const int numOps = Ops_.size();
00188   switch(verbLevel) {
00189     case Teuchos::VERB_DEFAULT:
00190     case Teuchos::VERB_LOW:
00191       *out << this->description() << std::endl;
00192       break;
00193     case Teuchos::VERB_MEDIUM:
00194     case Teuchos::VERB_HIGH:
00195     case Teuchos::VERB_EXTREME:
00196     {
00197       *out
00198         << Teuchos::Describable::description() << "{"
00199         << "rangeDim=" << this->range()->dim()
00200         << ",domainDim="<< this->domain()->dim() << "}\n";
00201       OSTab tab(out);
00202       *out
00203         <<  "numOps="<< numOps << std::endl
00204         <<  "Constituent LinearOpBase objects for M = Op[0]*...*Op[numOps-1]:\n";
00205       tab.incrTab();
00206       for( int k = 0; k < numOps; ++k ) {
00207         *out << "Op["<<k<<"] = " << Teuchos::describe(*getOp(k),verbLevel);
00208       }
00209       break;
00210     }
00211     default:
00212       TEST_FOR_EXCEPT(true); // Should never get here!
00213   }
00214 }
00215 
00216 // protected
00217 
00218 // Overridden from SingleScalarLinearOpBase
00219 
00220 template<class Scalar>
00221 bool DefaultAddedLinearOp<Scalar>::opSupported(ETransp M_trans) const
00222 {
00223   bool opSupported = true;
00224   for( int k = 0; k < static_cast<int>(Ops_.size()); ++k )
00225     if(!Thyra::opSupported(*getOp(k),M_trans)) opSupported = false;
00226   return opSupported;
00227   // ToDo: Cache these?
00228 }
00229 
00230 template<class Scalar>
00231 void DefaultAddedLinearOp<Scalar>::apply(
00232   const ETransp                     M_trans
00233   ,const MultiVectorBase<Scalar>    &X
00234   ,MultiVectorBase<Scalar>          *Y
00235   ,const Scalar                     alpha
00236   ,const Scalar                     beta
00237   ) const
00238 {
00239   typedef Teuchos::ScalarTraits<Scalar> ST;
00240 #ifdef TEUCHOS_DEBUG
00241   THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(
00242     "DefaultAddedLinearOp<Scalar>::apply(...)",*this,M_trans,X,Y
00243     );
00244 #endif // TEUCHOS_DEBUG  
00245   //
00246   // Y = alpha * op(M) * X + beta*Y
00247   //
00248   // =>
00249   //
00250   // Y = beta*Y + sum(alpha*op(Op[j])*X),j=0...numOps-1)
00251   //
00252   const int numOps = Ops_.size();
00253   for( int j = 0; j < numOps; ++j )
00254     Thyra::apply(*getOp(j),M_trans,X,Y,alpha,j==0?beta:ST::one());
00255 }
00256 
00257 
00258 // private
00259 
00260 
00261 template<class Scalar>
00262 void DefaultAddedLinearOp<Scalar>::validateOps()
00263 {
00264   typedef std::string s;
00265   using Teuchos::toString;
00266 #ifdef TEUCHOS_DEBUG
00267   try {
00268     const int numOps = Ops_.size();
00269     for( int k = 0; k < numOps; ++k ) {
00270       TEST_FOR_EXCEPT( Ops_[k]().get() == NULL );
00271       if( k > 0 ) {
00272         THYRA_ASSERT_LINEAR_OP_PLUS_LINEAR_OP_SPACES_NAMES(
00273           "DefaultMultipliedLinearOp<Scalar>::initialize(...)"
00274           ,*Ops_[0].getConstObj(),NOTRANS,("Ops[0]")
00275           ,*Ops_[k].getConstObj(),NOTRANS,("Ops["+toString(k)+"]")
00276           );
00277       }
00278     }
00279   }
00280   catch(...) {
00281     uninitialize();
00282     throw;
00283   }
00284 #endif
00285 }
00286 
00287 
00288 template<class Scalar>
00289 void DefaultAddedLinearOp<Scalar>::setupDefaultObjectLabel()
00290 {
00291   std::ostringstream label;
00292   const int numOps = Ops_.size();
00293   for( int k = 0; k < numOps; ++k ) {
00294     std::string Op_k_label = Ops_[k].getConstObj()->getObjectLabel();
00295     if (Op_k_label.length() == 0)
00296       Op_k_label = "ANYM";
00297     if (k > 0)
00298       label << "+";
00299     label << "("<<Op_k_label<<")";
00300   }
00301   this->setObjectLabel(label.str());
00302   validateOps();
00303 }
00304 
00305 
00306 } // end namespace Thyra
00307 
00308 
00309 template<class Scalar>
00310 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
00311 Thyra::nonconstAdd(
00312   const Teuchos::RCP<LinearOpBase<Scalar> >    &A
00313   ,const Teuchos::RCP<LinearOpBase<Scalar> >   &B
00314   )
00315 {
00316   using Teuchos::arrayArg;
00317   using Teuchos::RCP;
00318   return Teuchos::rcp(
00319     new DefaultAddedLinearOp<Scalar>(
00320       2
00321       ,arrayArg<RCP<LinearOpBase<Scalar> > >(A,B)()
00322       )
00323     );
00324 }
00325 
00326 template<class Scalar>
00327 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> >
00328 Thyra::add(
00329   const Teuchos::RCP<const LinearOpBase<Scalar> >    &A
00330   ,const Teuchos::RCP<const LinearOpBase<Scalar> >   &B
00331   )
00332 {
00333   using Teuchos::arrayArg;
00334   using Teuchos::RCP;
00335   return Teuchos::rcp(
00336     new DefaultAddedLinearOp<Scalar>(
00337       2
00338       ,arrayArg<RCP<const LinearOpBase<Scalar> > >(A,B)()
00339       )
00340     );
00341 }
00342 
00343 #endif  // THYRA_DEFAULT_ADDED_LINEAR_OP_HPP

Generated on Tue Oct 20 12:47:25 2009 for Thyra Package Browser (Single Doxygen Collection) by doxygen 1.4.7