Thyra_DefaultAddedLinearOp.hpp

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_DefaultScaledAdjointLinearOp.hpp"
00034 #include "Thyra_AssertOp.hpp"
00035 #include "Teuchos_Utils.hpp"
00036 
00037 namespace Thyra {
00038 
00039 // Constructors/initializers/accessors
00040 
00041 template<class Scalar>
00042 DefaultAddedLinearOp<Scalar>::DefaultAddedLinearOp()
00043 {}
00044 
00045 template<class Scalar>
00046 DefaultAddedLinearOp<Scalar>::DefaultAddedLinearOp(
00047   const int                                                   numOps
00048   ,const RCP<LinearOpBase<Scalar> >          Ops[]
00049   )
00050 {
00051   initialize(numOps,Ops);
00052 }
00053 
00054 template<class Scalar>
00055 DefaultAddedLinearOp<Scalar>::DefaultAddedLinearOp(
00056   const int                                                   numOps
00057   ,const RCP<const LinearOpBase<Scalar> >    Ops[]
00058   )
00059 {
00060   initialize(numOps,Ops);
00061 }
00062 
00063 template<class Scalar>
00064 void DefaultAddedLinearOp<Scalar>::initialize(
00065   const int                                                   numOps
00066   ,const RCP<LinearOpBase<Scalar> >          Ops[]
00067   )
00068 {
00069 #ifdef TEUCHOS_DEBUG
00070   TEST_FOR_EXCEPT( numOps <= 0 || Ops == NULL );
00071 #endif
00072   Ops_.resize(numOps);
00073   for( int k = 0; k < numOps; ++k )
00074     Ops_[k].initialize(Ops[k]);
00075   validateOps();
00076   setupDefaultObjectLabel();
00077 }
00078 
00079 template<class Scalar>
00080 void DefaultAddedLinearOp<Scalar>::initialize(
00081   const int                                                   numOps
00082   ,const RCP<const LinearOpBase<Scalar> >    Ops[]
00083   )
00084 {
00085 #ifdef TEUCHOS_DEBUG
00086   TEST_FOR_EXCEPT( numOps <= 0 || Ops == NULL );
00087 #endif
00088   Ops_.resize(numOps);
00089   for( int k = 0; k < numOps; ++k )
00090     Ops_[k].initialize(Ops[k]);
00091   validateOps();
00092   setupDefaultObjectLabel();
00093 }
00094 
00095 template<class Scalar>
00096 void DefaultAddedLinearOp<Scalar>::uninitialize()
00097 {
00098   Ops_.resize(0);
00099   setupDefaultObjectLabel();
00100 }
00101 
00102 // Overridden form AddedLinearOpBase
00103 
00104 template<class Scalar>
00105 int DefaultAddedLinearOp<Scalar>::numOps() const
00106 {
00107   return Ops_.size();
00108 }
00109 
00110 template<class Scalar>
00111 bool DefaultAddedLinearOp<Scalar>::opIsConst(const int k) const
00112 {
00113 #ifdef TEUCHOS_DEBUG
00114   TEST_FOR_EXCEPT( !( 0 <= k && k < numOps() ) );
00115 #endif
00116   return Ops_[k].isConst();
00117 }
00118 
00119 template<class Scalar>
00120 Teuchos::RCP<LinearOpBase<Scalar> >
00121 DefaultAddedLinearOp<Scalar>::getNonconstOp(const int k)
00122 {
00123 #ifdef TEUCHOS_DEBUG
00124   TEST_FOR_EXCEPT( !( 0 <= k && k < numOps() ) );
00125 #endif
00126   return Ops_[k].getNonconstObj();
00127 }
00128 
00129 template<class Scalar>
00130 Teuchos::RCP<const LinearOpBase<Scalar> >
00131 DefaultAddedLinearOp<Scalar>::getOp(const int k) const
00132 {
00133 #ifdef TEUCHOS_DEBUG
00134   TEST_FOR_EXCEPT( !( 0 <= k && k < numOps() ) );
00135 #endif
00136   return Ops_[k];
00137 }
00138 
00139 // Overridden from LinearOpBase
00140 
00141 template<class Scalar>
00142 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00143 DefaultAddedLinearOp<Scalar>::range() const
00144 {
00145   assertInitialized();
00146   return getOp(0)->range();
00147 }
00148 
00149 template<class Scalar>
00150 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00151 DefaultAddedLinearOp<Scalar>::domain() const
00152 {
00153   assertInitialized();
00154   return getOp(numOps()-1)->domain();
00155 }
00156 
00157 template<class Scalar>
00158 Teuchos::RCP<const LinearOpBase<Scalar> >
00159 DefaultAddedLinearOp<Scalar>::clone() const
00160 {
00161   return Teuchos::null; // Not supported yet but could be!
00162 }
00163 
00164 // Overridden from Teuchos::Describable
00165                                                 
00166 template<class Scalar>
00167 std::string DefaultAddedLinearOp<Scalar>::description() const
00168 {
00169   assertInitialized();
00170   std::ostringstream oss;
00171   oss << Teuchos::Describable::description() << "{numOps = "<<numOps()<<"}";
00172   return oss.str();
00173 }
00174 
00175 template<class Scalar>
00176 void DefaultAddedLinearOp<Scalar>::describe(
00177   Teuchos::FancyOStream                &out_arg
00178   ,const Teuchos::EVerbosityLevel      verbLevel
00179   ) const
00180 {
00181   typedef Teuchos::ScalarTraits<Scalar>  ST;
00182   using Teuchos::RCP;
00183   using Teuchos::FancyOStream;
00184   using Teuchos::OSTab;
00185   assertInitialized();
00186   RCP<FancyOStream> out = rcp(&out_arg,false);
00187   OSTab tab(out);
00188   const int numOps = Ops_.size();
00189   switch(verbLevel) {
00190     case Teuchos::VERB_DEFAULT:
00191     case Teuchos::VERB_LOW:
00192       *out << this->description() << std::endl;
00193       break;
00194     case Teuchos::VERB_MEDIUM:
00195     case Teuchos::VERB_HIGH:
00196     case Teuchos::VERB_EXTREME:
00197     {
00198       *out
00199         << Teuchos::Describable::description() << "{"
00200         << "rangeDim=" << this->range()->dim()
00201         << ",domainDim="<< this->domain()->dim() << "}\n";
00202       OSTab tab(out);
00203       *out
00204         <<  "numOps="<< numOps << std::endl
00205         <<  "Constituent LinearOpBase objects for M = Op[0]*...*Op[numOps-1]:\n";
00206       tab.incrTab();
00207       for( int k = 0; k < numOps; ++k ) {
00208         *out << "Op["<<k<<"] = " << Teuchos::describe(*getOp(k),verbLevel);
00209       }
00210       break;
00211     }
00212     default:
00213       TEST_FOR_EXCEPT(true); // Should never get here!
00214   }
00215 }
00216 
00217 // protected
00218 
00219 // Overridden from SingleScalarLinearOpBase
00220 
00221 template<class Scalar>
00222 bool DefaultAddedLinearOp<Scalar>::opSupported(EOpTransp M_trans) const
00223 {
00224   bool opSupported = true;
00225   for( int k = 0; k < static_cast<int>(Ops_.size()); ++k )
00226     if(!Thyra::opSupported(*getOp(k),M_trans)) opSupported = false;
00227   return opSupported;
00228   // ToDo: Cache these?
00229 }
00230 
00231 template<class Scalar>
00232 void DefaultAddedLinearOp<Scalar>::apply(
00233   const EOpTransp                     M_trans
00234   ,const MultiVectorBase<Scalar>    &X
00235   ,MultiVectorBase<Scalar>          *Y
00236   ,const Scalar                     alpha
00237   ,const Scalar                     beta
00238   ) const
00239 {
00240   typedef Teuchos::ScalarTraits<Scalar> ST;
00241 #ifdef TEUCHOS_DEBUG
00242   THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(
00243     "DefaultAddedLinearOp<Scalar>::apply(...)",*this,M_trans,X,Y
00244     );
00245 #endif // TEUCHOS_DEBUG  
00246   //
00247   // Y = alpha * op(M) * X + beta*Y
00248   //
00249   // =>
00250   //
00251   // Y = beta*Y + sum(alpha*op(Op[j])*X),j=0...numOps-1)
00252   //
00253   const int numOps = Ops_.size();
00254   for( int j = 0; j < numOps; ++j )
00255     Thyra::apply(*getOp(j),M_trans,X,Y,alpha,j==0?beta:ST::one());
00256 }
00257 
00258 
00259 // private
00260 
00261 
00262 template<class Scalar>
00263 void DefaultAddedLinearOp<Scalar>::validateOps()
00264 {
00265   typedef std::string s;
00266   using Teuchos::toString;
00267 #ifdef TEUCHOS_DEBUG
00268   try {
00269     const int numOps = Ops_.size();
00270     for( int k = 0; k < numOps; ++k ) {
00271       TEST_FOR_EXCEPT( Ops_[k]().get() == NULL );
00272       if( k > 0 ) {
00273         THYRA_ASSERT_LINEAR_OP_PLUS_LINEAR_OP_SPACES_NAMES(
00274           "DefaultMultipliedLinearOp<Scalar>::initialize(...)"
00275           ,*Ops_[0], NOTRANS, ("Ops[0]")
00276           ,*Ops_[k], NOTRANS, ("Ops["+toString(k)+"]")
00277           );
00278       }
00279     }
00280   }
00281   catch(...) {
00282     uninitialize();
00283     throw;
00284   }
00285 #endif
00286 }
00287 
00288 
00289 template<class Scalar>
00290 void DefaultAddedLinearOp<Scalar>::setupDefaultObjectLabel()
00291 {
00292   std::ostringstream label;
00293   const int numOps = Ops_.size();
00294   for( int k = 0; k < numOps; ++k ) {
00295     std::string Op_k_label = Ops_[k]->getObjectLabel();
00296     if (Op_k_label.length() == 0)
00297       Op_k_label = "ANYM";
00298     if (k > 0)
00299       label << "+";
00300     label << "("<<Op_k_label<<")";
00301   }
00302   this->setObjectLabel(label.str());
00303   validateOps();
00304 }
00305 
00306 
00307 } // end namespace Thyra
00308 
00309 
00310 template<class Scalar>
00311 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
00312 Thyra::nonconstAdd(
00313   const RCP<LinearOpBase<Scalar> > &A,
00314   const RCP<LinearOpBase<Scalar> > &B,
00315   const std::string &label
00316   )
00317 {
00318   using Teuchos::arrayArg;
00319   RCP<LinearOpBase<Scalar> >
00320     alo = Teuchos::rcp(
00321       new DefaultAddedLinearOp<Scalar>(
00322         2
00323         ,arrayArg<RCP<LinearOpBase<Scalar> > >(A,B)()
00324         )
00325       );
00326   if (label.length())
00327     alo->setObjectLabel(label);
00328   return alo;
00329 }
00330 
00331 
00332 template<class Scalar>
00333 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> >
00334 Thyra::add(
00335   const RCP<const LinearOpBase<Scalar> > &A,
00336   const RCP<const LinearOpBase<Scalar> > &B,
00337   const std::string &label
00338   )
00339 {
00340   using Teuchos::arrayArg;
00341   RCP<LinearOpBase<Scalar> >
00342     alo = Teuchos::rcp(
00343       new DefaultAddedLinearOp<Scalar>(
00344         2
00345         ,arrayArg<RCP<const LinearOpBase<Scalar> > >(A,B)()
00346         )
00347       );
00348   if (label.length())
00349     alo->setObjectLabel(label);
00350   return alo;
00351 }
00352 
00353 
00354 template<class Scalar>
00355 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
00356 Thyra::nonconstSubtract(
00357   const RCP<LinearOpBase<Scalar> > &A,
00358   const RCP<LinearOpBase<Scalar> > &B,
00359   const std::string &label
00360   )
00361 {
00362   typedef ScalarTraits<Scalar> ST;
00363   using Teuchos::arrayArg;
00364   RCP<LinearOpBase<Scalar> >
00365     alo = Teuchos::rcp(
00366       new DefaultAddedLinearOp<Scalar>(
00367         2,
00368         arrayArg<RCP<LinearOpBase<Scalar> > >(
00369           A, scale<Scalar>(-ST::one(),B) )()
00370         )
00371       );
00372   if (label.length())
00373     alo->setObjectLabel(label);
00374   return alo;
00375 }
00376 
00377 
00378 template<class Scalar>
00379 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> >
00380 Thyra::subtract(
00381   const RCP<const LinearOpBase<Scalar> > &A,
00382   const RCP<const LinearOpBase<Scalar> > &B,
00383   const std::string &label
00384   )
00385 {
00386   typedef ScalarTraits<Scalar> ST;
00387   using Teuchos::arrayArg;
00388   RCP<LinearOpBase<Scalar> >
00389     alo = Teuchos::rcp(
00390       new DefaultAddedLinearOp<Scalar>(
00391         2,
00392         arrayArg<RCP<const LinearOpBase<Scalar> > >(
00393           A, scale<Scalar>(-ST::one(),B) )()
00394         )
00395       );
00396   if (label.length())
00397     alo->setObjectLabel(label);
00398   return alo;
00399 }
00400 
00401 
00402 
00403 #endif  // THYRA_DEFAULT_ADDED_LINEAR_OP_HPP

Generated on Wed May 12 21:26:53 2010 for Thyra Operator/Vector Support by  doxygen 1.4.7