42 #ifndef THYRA_DEFAULT_MULTIPLIED_LINEAR_OP_DEF_HPP 43 #define THYRA_DEFAULT_MULTIPLIED_LINEAR_OP_DEF_HPP 45 #include "Thyra_DefaultMultipliedLinearOp_decl.hpp" 46 #include "Thyra_AssertOp.hpp" 55 template<
class Scalar>
57 void DefaultMultipliedLinearOp<Scalar>::assertInitialized()
const 60 TEUCHOS_TEST_FOR_EXCEPT( !( numOps() > 0 ) );
65 template<
class Scalar>
67 std::string DefaultMultipliedLinearOp<Scalar>::getClassName()
const 69 return Teuchos::Describable::description();
73 template<
class Scalar>
75 Ordinal DefaultMultipliedLinearOp<Scalar>::getRangeDim()
const 77 return (numOps() > 0 ? this->range()->dim() : 0);
81 template<
class Scalar>
83 Ordinal DefaultMultipliedLinearOp<Scalar>::getDomainDim()
const 85 return (numOps() > 0 ? this->domain()->dim() : 0);
92 template<
class Scalar>
97 template<
class Scalar>
101 const int nOps = Ops.size();
103 for(
int k = 0; k < nOps; ++k )
104 Ops_[k].initialize(Ops[k]);
106 setupDefaultObjectLabel();
110 template<
class Scalar>
114 const int nOps = Ops.size();
116 for(
int k = 0; k < nOps; ++k )
117 Ops_[k].initialize(Ops[k]);
119 setupDefaultObjectLabel();
123 template<
class Scalar>
127 setupDefaultObjectLabel();
134 template<
class Scalar>
141 template<
class Scalar>
145 TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= k && k < numOps() ) );
147 return Ops_[k].isConst();
151 template<
class Scalar>
152 RCP<LinearOpBase<Scalar> >
156 TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= k && k < numOps() ) );
158 return Ops_[k].getNonconstObj();
162 template<
class Scalar>
163 RCP<const LinearOpBase<Scalar> >
167 TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= k && k < numOps() ) );
176 template<
class Scalar>
177 RCP< const VectorSpaceBase<Scalar> >
181 return getOp(0)->range();
183 return Teuchos::null;
187 template<
class Scalar>
188 RCP< const VectorSpaceBase<Scalar> >
192 return getOp(numOps()-1)->domain();
194 return Teuchos::null;
198 template<
class Scalar>
199 RCP<const LinearOpBase<Scalar> >
202 return Teuchos::null;
209 template<
class Scalar>
212 std::ostringstream oss;
213 oss << getClassName() <<
"{numOps="<<numOps()
214 <<
",rangeDim=" << getRangeDim()
215 <<
",domainDim="<< getDomainDim() <<
"}";
219 template<
class Scalar>
221 Teuchos::FancyOStream &out_arg,
222 const Teuchos::EVerbosityLevel verbLevel
225 using Teuchos::FancyOStream;
226 using Teuchos::OSTab;
227 RCP<FancyOStream> out = rcp(&out_arg,
false);
229 const int nOps = Ops_.size();
231 case Teuchos::VERB_DEFAULT:
232 case Teuchos::VERB_LOW:
233 *out << this->description() << std::endl;
235 case Teuchos::VERB_MEDIUM:
236 case Teuchos::VERB_HIGH:
237 case Teuchos::VERB_EXTREME:
239 *out << this->description() << std::endl;
242 <<
"Constituent LinearOpBase objects for M = Op[0]*...*Op[numOps-1]:\n";
244 for(
int k = 0; k < nOps; ++k ) {
245 *out <<
"Op["<<k<<
"] = " << Teuchos::describe(*getOp(k),verbLevel);
250 TEUCHOS_TEST_FOR_EXCEPT(
true);
261 template<
class Scalar>
264 bool overallOpSupported =
true;
265 for(
int k = 0; k < static_cast<int>(Ops_.size()); ++k )
266 if(!Thyra::opSupported(*getOp(k),M_trans)) overallOpSupported =
false;
267 return overallOpSupported;
272 template<
class Scalar>
281 using Teuchos::rcpFromPtr;
282 using Teuchos::rcpFromRef;
285 getClassName()+
"::apply(...)", *
this, M_trans, X, &*Y
287 #endif // TEUCHOS_DEBUG 288 const int nOps = Ops_.size();
296 RCP<MultiVectorBase<Scalar> > T_kp1, T_k;
297 for(
int k = nOps-1; k >= 0; --k ) {
298 RCP<MultiVectorBase<Scalar> > Y_k;
299 RCP<const MultiVectorBase<Scalar> > X_k;
300 if(k==0) Y_k = rcpFromPtr(Y);
else Y_k = T_k = createMembers(getOp(k)->range(), m);
301 if(k==nOps-1) X_k = rcpFromRef(X);
else X_k = T_kp1;
303 Thyra::apply(*getOp(k), M_trans, *X_k, Y_k.ptr());
305 Thyra::apply(*getOp(k), M_trans, *X_k, Y_k.ptr(), alpha, beta);
315 RCP<MultiVectorBase<Scalar> > T_km1, T_k;
316 for(
int k = 0; k <= nOps-1; ++k ) {
317 RCP<MultiVectorBase<Scalar> > Y_k;
318 RCP<const MultiVectorBase<Scalar> > X_k;
319 if(k==nOps-1) Y_k = rcpFromPtr(Y);
else Y_k = T_k = createMembers(getOp(k)->domain(), m);
320 if(k==0) X_k = rcpFromRef(X);
else X_k = T_km1;
322 Thyra::apply(*getOp(k), M_trans, *X_k, Y_k.ptr());
324 Thyra::apply(*getOp(k), M_trans, *X_k, Y_k.ptr(), alpha, beta);
334 template<
class Scalar>
340 const int nOps = Ops_.size();
341 for(
int k = 0; k < nOps; ++k ) {
342 TEUCHOS_TEST_FOR_EXCEPT( Ops_[k]().
get() == NULL );
345 getClassName()+
"::initialize(...)" 360 template<
class Scalar>
361 void DefaultMultipliedLinearOp<Scalar>::setupDefaultObjectLabel()
363 std::ostringstream label;
364 const int nOps = Ops_.size();
365 for(
int k = 0; k < nOps; ++k ) {
366 std::string Op_k_label = Ops_[k]->getObjectLabel();
367 if (Op_k_label.length() == 0)
371 label <<
"("<<Op_k_label<<
")";
373 this->setObjectLabel(label.str());
385 template<
class Scalar>
386 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
387 Thyra::nonconstMultiply(
388 const RCP<LinearOpBase<Scalar> > &A,
389 const RCP<LinearOpBase<Scalar> > &B,
390 const std::string &M_label
393 using Teuchos::tuple;
394 RCP<DefaultMultipliedLinearOp<Scalar> > multOp =
395 defaultMultipliedLinearOp<Scalar>(tuple(A, B)());
397 multOp->setObjectLabel(M_label);
402 template<
class Scalar>
403 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> >
405 const RCP<
const LinearOpBase<Scalar> > &A,
406 const RCP<
const LinearOpBase<Scalar> > &B,
407 const std::string &M_label
410 using Teuchos::tuple;
411 RCP<DefaultMultipliedLinearOp<Scalar> > multOp =
412 defaultMultipliedLinearOp<Scalar>(tuple(A, B)());
414 multOp->setObjectLabel(M_label);
419 template<
class Scalar>
420 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> >
422 const RCP<
const LinearOpBase<Scalar> > &A,
423 const RCP<
const LinearOpBase<Scalar> > &B,
424 const RCP<
const LinearOpBase<Scalar> > &C,
425 const std::string &M_label
428 using Teuchos::tuple;
429 RCP<DefaultMultipliedLinearOp<Scalar> > multOp =
430 defaultMultipliedLinearOp<Scalar>(tuple(A, B, C)());
432 multOp->setObjectLabel(M_label);
444 #define THYRA_DEFAULT_MULTIPLIED_LINEAR_OP_INSTANT(SCALAR) \ 446 template class DefaultMultipliedLinearOp<SCALAR >; \ 448 template RCP<LinearOpBase<SCALAR > > \ 450 const RCP<LinearOpBase<SCALAR > > &A, \ 451 const RCP<LinearOpBase<SCALAR > > &B, \ 452 const std::string &M_label \ 455 template RCP<const LinearOpBase<SCALAR > > \ 457 const RCP<const LinearOpBase<SCALAR > > &A, \ 458 const RCP<const LinearOpBase<SCALAR > > &B, \ 459 const std::string &M_label \ 462 template RCP<const LinearOpBase<SCALAR > > \ 464 const RCP<const LinearOpBase<SCALAR > > &A, \ 465 const RCP<const LinearOpBase<SCALAR > > &B, \ 466 const RCP<const LinearOpBase<SCALAR > > &C, \ 467 const std::string &M_label \ 471 #endif // THYRA_DEFAULT_MULTIPLIED_LINEAR_OP_DEF_HPP RCP< const LinearOpBase< Scalar > > clone() const
#define THYRA_ASSERT_LINEAR_OP_TIMES_LINEAR_OP_SPACES_NAMES(FUNC_NAME, M1, M1_T, M1_N, M2, M2_T, M2_N)
Assert that a linear operator multiplication matches up.
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
RCP< const VectorSpaceBase< Scalar > > range() const
Returns this->getOp(0).range() if <t>this->numOps() > 0 and returns Teuchos::null otherwise...
#define THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(FUNC_NAME, M, M_T, X, Y)
This is a very useful macro that should be used to validate that the spaces for the multi-vector vers...
bool opSupportedImpl(EOpTransp M_trans) const
Returns true only if all constituent operators support M_trans.
DefaultMultipliedLinearOp()
Constructs to uninitialized.
Use the non-transposed operator.
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
void uninitialize()
Set to uninitialized.
RCP< const LinearOpBase< Scalar > > getOp(const int k) const
void initialize(const ArrayView< const RCP< LinearOpBase< Scalar > > > &Ops)
Initialize given a list of non-const linear operators.
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
Interface for a collection of column vectors called a multi-vector.
RCP< const VectorSpaceBase< Scalar > > domain() const
Returns this->getOp(this->numOps()-1).domain() if <t>this->numOps() > 0 and returns Teuchos::null oth...
RCP< LinearOpBase< Scalar > > getNonconstOp(const int k)
Concrete composite LinearOpBase subclass that creates an implicitly multiplied linear operator out of...
Base class for all linear operators.
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Prints the details about the constituent linear operators.
bool opIsConst(const int k) const
std::string description() const
Prints just the name DefaultMultipliedLinearOp along with the overall dimensions and the number of co...
const char * toString(EConj conj)
Return a string name for a EOpTransp value. `*.