00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
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
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;
00161 }
00162
00163
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);
00213 }
00214 }
00215
00216
00217
00218
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
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
00247
00248
00249
00250
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
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 }
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