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::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
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
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;
00158 }
00159
00160
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);
00211 }
00212 }
00213
00214
00215
00216
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
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
00240
00241
00242
00243
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
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 }
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