Stratimikos Version of the Day
Loading...
Searching...
No Matches
BelosThyraAdapter.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Stratimikos: Thyra-based strategies for linear solvers
4//
5// Copyright 2006 NTESS and the Stratimikos contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
20#ifndef BELOS_THYRA_ADAPTER_HPP
21#define BELOS_THYRA_ADAPTER_HPP
22
23#include "Stratimikos_Config.h"
24#include "BelosConfigDefs.hpp"
27#include "Thyra_DefaultProductMultiVector_decl.hpp"
28#include "Thyra_TpetraThyraWrappers_decl.hpp"
29
30#include <Thyra_DetachedMultiVectorView.hpp>
31#include <Thyra_MultiVectorBase.hpp>
32#include <Thyra_MultiVectorStdOps.hpp>
33#ifdef HAVE_BELOS_TSQR
34# include <Thyra_TsqrAdaptor.hpp>
35#endif // HAVE_BELOS_TSQR
36
37#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
38#include "BelosMultiVecTraits_Tpetra.hpp"
39#include "Thyra_DefaultProductMultiVector.hpp"
40#include "Thyra_DefaultProductVectorSpace.hpp"
41#endif
42
43#ifdef HAVE_STRATIMIKOS_BELOS_TIMERS
44# include <Teuchos_TimeMonitor.hpp>
45
46# define STRATIMIKOS_TIME_MONITOR(NAME) \
47 Teuchos::TimeMonitor tM(*Teuchos::TimeMonitor::getNewTimer(std::string(NAME)))
48
49#else
50
51# define STRATIMIKOS_TIME_MONITOR(NAME)
52
53#endif
54
55namespace Belos {
56
58 //
59 // Implementation of the Belos::MultiVecTraits for Thyra::MultiVectorBase
60 //
62
69 template<class ScalarType>
70 class MultiVecTraits< ScalarType, Thyra::MultiVectorBase<ScalarType> >
71 {
72 private:
73 typedef Thyra::MultiVectorBase<ScalarType> TMVB;
74 typedef Teuchos::ScalarTraits<ScalarType> ST;
75 typedef typename ST::magnitudeType magType;
76#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
77 using TpMap = Tpetra::Map<Tpetra::MultiVector<>::local_ordinal_type,
78 Tpetra::MultiVector<>::global_ordinal_type,
79 Tpetra::MultiVector<>::node_type>;
80 using TpMV = Tpetra::MultiVector<ScalarType, Tpetra::MultiVector<>::local_ordinal_type,
81 Tpetra::MultiVector<>::global_ordinal_type,
82 Tpetra::MultiVector<>::node_type>;
83 using Extraction = Thyra::TpetraOperatorVectorExtraction<ScalarType,
84 Tpetra::MultiVector<>::local_ordinal_type,
85 Tpetra::MultiVector<>::global_ordinal_type,
86 Tpetra::MultiVector<>::node_type>;
87
88 private:
89 static Teuchos::RCP<TMVB> BuildProductMultiVectorMaybe(Teuchos::RCP<const TMVB> &mv_rcp, const int numvecs) {
90 auto pmv_rcp = Teuchos::rcp_dynamic_cast<const Thyra::DefaultProductMultiVector<ScalarType>>(mv_rcp);
91 if (!pmv_rcp.is_null()) {
92 auto ps = Teuchos::rcp_dynamic_cast<const Thyra::DefaultProductVectorSpace<ScalarType>>(pmv_rcp->range());
93 const int numBlocks = ps->numBlocks();
94 Teuchos::Array<Teuchos::RCP<Thyra::MultiVectorBase<ScalarType>>> multiVecs;
95 for (int k = 0; k < numBlocks; ++k) {
96 auto vs = ps->getBlock(k);
97 Teuchos::RCP<const TpMap> map = Extraction::getTpetraMap(vs);
98 if (map.is_null())
99 break;
100 auto tp_mv = impl::getMultiVectorFromPool<ScalarType>(map, numvecs);
101 auto thy_mv = createMultiVector(tp_mv, vs);
102 multiVecs.push_back(thy_mv);
103 }
104 if (multiVecs.size() == numBlocks)
105 return Thyra::defaultProductMultiVector<ScalarType>(ps, multiVecs);
106 }
107 return Teuchos::null;
108 }
109#endif
110
111 public:
112
115
120 static Teuchos::RCP<TMVB> Clone( const TMVB& mv, const int numvecs )
121 {
122 Teuchos::RCP<TMVB> c;
123#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
124 auto mv_rcp = Teuchos::rcpFromRef(mv);
125 try {
126 Teuchos::RCP<const TpMV> X = Extraction::getConstTpetraMultiVector(mv_rcp);
127 auto X_copy = ::Belos::MultiVecTraits<ScalarType, TpMV>::Clone(*X, numvecs);
128 c = Thyra::createMultiVector(X_copy);
129 } catch (std::logic_error&)
130#endif
131 {
132#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
133 c = BuildProductMultiVectorMaybe(mv_rcp, numvecs);
134 if (c.is_null())
135#endif
136 {
137 c = Thyra::createMembers(mv.range(), numvecs);
138 }
139 }
140 return c;
141 }
142
147 static Teuchos::RCP<TMVB> CloneCopy( const TMVB& mv )
148 {
149 Teuchos::RCP< TMVB > cc;
150#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
151 auto mv_rcp = Teuchos::rcpFromRef(mv);
152 try {
153 Teuchos::RCP<const TpMV> X = Extraction::getConstTpetraMultiVector(mv_rcp);
155 cc = Thyra::createMultiVector(X_copy);
156 } catch (std::logic_error&)
157#endif
158 {
159 int numvecs = mv.domain()->dim();
160 // create the new multivector
161#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
162 cc = BuildProductMultiVectorMaybe(mv_rcp, numvecs);
163 if (cc.is_null())
164#endif
165 {
166 cc = Thyra::createMembers(mv.range(), numvecs);
167 }
168 // copy the data from the source multivector to the new multivector
169 Thyra::assign(cc.ptr(), mv);
170 }
171 return cc;
172 }
173
179 static Teuchos::RCP<TMVB> CloneCopy( const TMVB& mv, const std::vector<int>& index )
180 {
181 Teuchos::RCP<TMVB> cc;
182#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
183 auto mv_rcp = Teuchos::rcpFromRef(mv);
184 try {
185 Teuchos::RCP<const TpMV> X = Extraction::getConstTpetraMultiVector(mv_rcp);
187 cc = Thyra::createMultiVector(X_copy);
188 } catch (std::logic_error&)
189#endif
190 {
191 int numvecs = index.size();
192 // create the new multivector
193#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
194 cc = BuildProductMultiVectorMaybe(mv_rcp, numvecs);
195 if (cc.is_null())
196#endif
197 {
198 cc = Thyra::createMembers(mv.range(), numvecs);
199 }
200 // create a view to the relevant part of the source multivector
201 Teuchos::RCP<const TMVB> view = mv.subView(index);
202 // copy the data from the relevant view to the new multivector
203 Thyra::assign(cc.ptr(), *view);
204 }
205 return cc;
206 }
207
208 static Teuchos::RCP<TMVB>
209 CloneCopy (const TMVB& mv, const Teuchos::Range1D& index)
210 {
211 Teuchos::RCP<TMVB> cc;
212#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
213 auto mv_rcp = Teuchos::rcpFromRef(mv);
214 try {
215 Teuchos::RCP<const TpMV> X = Extraction::getConstTpetraMultiVector(mv_rcp);
217 cc = Thyra::createMultiVector(X_copy);
218 } catch (std::logic_error&)
219#endif
220 {
221 const int numVecs = index.size();
222 // Create the new multivector
223#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
224 cc = BuildProductMultiVectorMaybe(mv_rcp, numVecs);
225 if (cc.is_null())
226#endif
227 {
228 cc = Thyra::createMembers(mv.range(), numVecs);
229 }
230 // Create a view to the relevant part of the source multivector
231 Teuchos::RCP<const TMVB> view = mv.subView (index);
232 // Copy the data from the view to the new multivector.
233 Thyra::assign (cc.ptr(), *view);
234 }
235 return cc;
236 }
237
243 static Teuchos::RCP<TMVB> CloneViewNonConst( TMVB& mv, const std::vector<int>& index )
244 {
245 int numvecs = index.size();
246
247 // We do not assume that the indices are sorted, nor do we check that
248 // index.size() > 0. This code is fail-safe, in the sense that a zero
249 // length index std::vector will pass the error on the Thyra.
250
251 // Thyra has two ways to create an indexed View:
252 // * contiguous (via a range of columns)
253 // * indexed (via a std::vector of column indices)
254 // The former is significantly more efficient than the latter, in terms of
255 // computations performed with/against the created view.
256 // We will therefore check to see if the given indices are contiguous, and
257 // if so, we will use the contiguous view creation method.
258
259 int lb = index[0];
260 bool contig = true;
261 for (int i=0; i<numvecs; i++) {
262 if (lb+i != index[i]) contig = false;
263 }
264
265 Teuchos::RCP< TMVB > cc;
266 if (contig) {
267 const Thyra::Range1D rng(lb,lb+numvecs-1);
268 // create a contiguous view to the relevant part of the source multivector
269 cc = mv.subView(rng);
270 }
271 else {
272 // create an indexed view to the relevant part of the source multivector
273 cc = mv.subView(index);
274 }
275 return cc;
276 }
277
278 static Teuchos::RCP<TMVB>
279 CloneViewNonConst (TMVB& mv, const Teuchos::Range1D& index)
280 {
281 // We let Thyra be responsible for checking that the index range
282 // is nonempty.
283 //
284 // Create and return a contiguous view to the relevant part of
285 // the source multivector.
286 return mv.subView (index);
287 }
288
289
295 static Teuchos::RCP<const TMVB> CloneView( const TMVB& mv, const std::vector<int>& index )
296 {
297 int numvecs = index.size();
298
299 // We do not assume that the indices are sorted, nor do we check that
300 // index.size() > 0. This code is fail-safe, in the sense that a zero
301 // length index std::vector will pass the error on the Thyra.
302
303 // Thyra has two ways to create an indexed View:
304 // * contiguous (via a range of columns)
305 // * indexed (via a std::vector of column indices)
306 // The former is significantly more efficient than the latter, in terms of
307 // computations performed with/against the created view.
308 // We will therefore check to see if the given indices are contiguous, and
309 // if so, we will use the contiguous view creation method.
310
311 int lb = index[0];
312 bool contig = true;
313 for (int i=0; i<numvecs; i++) {
314 if (lb+i != index[i]) contig = false;
315 }
316
317 Teuchos::RCP< const TMVB > cc;
318 if (contig) {
319 const Thyra::Range1D rng(lb,lb+numvecs-1);
320 // create a contiguous view to the relevant part of the source multivector
321 cc = mv.subView(rng);
322 }
323 else {
324 // create an indexed view to the relevant part of the source multivector
325 cc = mv.subView(index);
326 }
327 return cc;
328 }
329
330 static Teuchos::RCP<const TMVB>
331 CloneView (const TMVB& mv, const Teuchos::Range1D& index)
332 {
333 // We let Thyra be responsible for checking that the index range
334 // is nonempty.
335 //
336 // Create and return a contiguous view to the relevant part of
337 // the source multivector.
338 return mv.subView (index);
339 }
340
342
345
347 static ptrdiff_t GetGlobalLength( const TMVB& mv ) {
348 return Teuchos::as<ptrdiff_t>(mv.range()->dim());
349 }
350
352 static int GetNumberVecs( const TMVB& mv )
353 { return mv.domain()->dim(); }
354
356
359
362 static void MvTimesMatAddMv( const ScalarType alpha, const TMVB& A,
363 const Teuchos::SerialDenseMatrix<int,ScalarType>& B,
364 const ScalarType beta, TMVB& mv )
365 {
366 using Teuchos::arrayView; using Teuchos::arcpFromArrayView;
367 STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvTimesMatAddMv");
368
369 const int m = B.numRows();
370 const int n = B.numCols();
371 // Check if B is 1-by-1, in which case we can just call MvAddMv()
372 if ((m == 1) && (n == 1)) {
373 using Teuchos::tuple; using Teuchos::ptrInArg; using Teuchos::inoutArg;
374 const ScalarType alphaNew = alpha * B(0, 0);
375 Thyra::linear_combination<ScalarType>(tuple(alphaNew)(), tuple(ptrInArg(A))(), beta, inoutArg(mv));
376 } else {
377 // perform the operation via A: mv <- alpha*A*B_thyra + beta*mv
378 auto vs = A.domain();
379 // Create a view of the B object!
380 Teuchos::RCP< const TMVB >
381 B_thyra = vs->createCachedMembersView(
383 0, m, 0, n,
384 arcpFromArrayView(arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
385 )
386 );
387 Thyra::apply<ScalarType>(A, Thyra::NOTRANS, *B_thyra, Teuchos::outArg(mv), alpha, beta);
388 }
389 }
390
393 static void MvAddMv( const ScalarType alpha, const TMVB& A,
394 const ScalarType beta, const TMVB& B, TMVB& mv )
395 {
396 using Teuchos::tuple; using Teuchos::ptrInArg; using Teuchos::inoutArg;
397 STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvAddMv");
398
399 Thyra::linear_combination<ScalarType>(
400 tuple(alpha, beta)(), tuple(ptrInArg(A), ptrInArg(B))(), Teuchos::ScalarTraits<ScalarType>::zero(), inoutArg(mv));
401 }
402
405 static void MvScale ( TMVB& mv, const ScalarType alpha )
406 {
407 STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvScale");
408
409 Thyra::scale(alpha, Teuchos::inoutArg(mv));
410 }
411
414 static void MvScale (TMVB& mv, const std::vector<ScalarType>& alpha)
415 {
416 STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvScale");
417
418 for (unsigned int i=0; i<alpha.size(); i++) {
419 Thyra::scale<ScalarType> (alpha[i], mv.col(i).ptr());
420 }
421 }
422
425 static void MvTransMv( const ScalarType alpha, const TMVB& A, const TMVB& mv,
426 Teuchos::SerialDenseMatrix<int,ScalarType>& B )
427 {
428 using Teuchos::arrayView; using Teuchos::arcpFromArrayView;
429 STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvTransMv");
430
431 // Create a multivector to hold the result (m by n)
432 int m = A.domain()->dim();
433 int n = mv.domain()->dim();
434 auto vs = A.domain();
435 // Create a view of the B object!
436 Teuchos::RCP< TMVB >
437 B_thyra = vs->createCachedMembersView(
439 0, m, 0, n,
440 arcpFromArrayView(arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
441 ),
442 false
443 );
444 Thyra::apply<ScalarType>(A, Thyra::CONJTRANS, mv, B_thyra.ptr(), alpha);
445 }
446
450 static void MvDot( const TMVB& mv, const TMVB& A, std::vector<ScalarType>& b )
451 {
452 STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvDot");
453
454 Thyra::dots(mv, A, Teuchos::arrayViewFromVector(b));
455 }
456
458
461
465 static void MvNorm( const TMVB& mv, std::vector<magType>& normvec,
466 NormType type = TwoNorm ) {
467 STRATIMIKOS_TIME_MONITOR("Belos::MVT::MvNorm");
468
469 if(type == TwoNorm)
470 Thyra::norms_2(mv, Teuchos::arrayViewFromVector(normvec));
471 else if(type == OneNorm)
472 Thyra::norms_1(mv, Teuchos::arrayViewFromVector(normvec));
473 else if(type == InfNorm)
474 Thyra::norms_inf(mv, Teuchos::arrayViewFromVector(normvec));
475 else
476 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument,
477 "Belos::MultiVecTraits::MvNorm (Thyra specialization): "
478 "invalid norm type. Must be either TwoNorm, OneNorm or InfNorm");
479 }
480
482
485
488 static void SetBlock( const TMVB& A, const std::vector<int>& index, TMVB& mv )
489 {
490 // Extract the "numvecs" columns of mv indicated by the index std::vector.
491 int numvecs = index.size();
492 std::vector<int> indexA(numvecs);
493 int numAcols = A.domain()->dim();
494 for (int i=0; i<numvecs; i++) {
495 indexA[i] = i;
496 }
497 // Thyra::assign requires that both arguments have the same number of
498 // vectors. Enforce this, by shrinking one to match the other.
499 if ( numAcols < numvecs ) {
500 // A does not have enough columns to satisfy index_plus. Shrink
501 // index_plus.
502 numvecs = numAcols;
503 }
504 else if ( numAcols > numvecs ) {
505 numAcols = numvecs;
506 indexA.resize( numAcols );
507 }
508 // create a view to the relevant part of the source multivector
509 Teuchos::RCP< const TMVB > relsource = A.subView(indexA);
510 // create a view to the relevant part of the destination multivector
511 Teuchos::RCP< TMVB > reldest = mv.subView(index);
512 // copy the data to the destination multivector subview
513 Thyra::assign(reldest.ptr(), *relsource);
514 }
515
516 static void
517 SetBlock (const TMVB& A, const Teuchos::Range1D& index, TMVB& mv)
518 {
519 const int numColsA = A.domain()->dim();
520 const int numColsMv = mv.domain()->dim();
521 // 'index' indexes into mv; it's the index set of the target.
522 const bool validIndex = index.lbound() >= 0 && index.ubound() < numColsMv;
523 // We can't take more columns out of A than A has.
524 const bool validSource = index.size() <= numColsA;
525
526 if (! validIndex || ! validSource)
527 {
528 std::ostringstream os;
529 os << "Belos::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar> "
530 ">::SetBlock(A, [" << index.lbound() << ", " << index.ubound()
531 << "], mv): ";
532 TEUCHOS_TEST_FOR_EXCEPTION(index.lbound() < 0, std::invalid_argument,
533 os.str() << "Range lower bound must be nonnegative.");
534 TEUCHOS_TEST_FOR_EXCEPTION(index.ubound() >= numColsMv, std::invalid_argument,
535 os.str() << "Range upper bound must be less than "
536 "the number of columns " << numColsA << " in the "
537 "'mv' output argument.");
538 TEUCHOS_TEST_FOR_EXCEPTION(index.size() > numColsA, std::invalid_argument,
539 os.str() << "Range must have no more elements than"
540 " the number of columns " << numColsA << " in the "
541 "'A' input argument.");
542 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Should never get here!");
543 }
544
545 // View of the relevant column(s) of the target multivector mv.
546 // We avoid view creation overhead by only creating a view if
547 // the index range is different than [0, (# columns in mv) - 1].
548 Teuchos::RCP<TMVB> mv_view;
549 if (index.lbound() == 0 && index.ubound()+1 == numColsMv)
550 mv_view = Teuchos::rcpFromRef (mv); // Non-const, non-owning RCP
551 else
552 mv_view = mv.subView (index);
553
554 // View of the relevant column(s) of the source multivector A.
555 // If A has fewer columns than mv_view, then create a view of
556 // the first index.size() columns of A.
557 Teuchos::RCP<const TMVB> A_view;
558 if (index.size() == numColsA)
559 A_view = Teuchos::rcpFromRef (A); // Const, non-owning RCP
560 else
561 A_view = A.subView (Teuchos::Range1D(0, index.size()-1));
562
563 // Copy the data to the destination multivector.
564 Thyra::assign(mv_view.ptr(), *A_view);
565 }
566
567 static void
568 Assign (const TMVB& A, TMVB& mv)
569 {
570 STRATIMIKOS_TIME_MONITOR("Belos::MVT::Assign");
571
572 const int numColsA = A.domain()->dim();
573 const int numColsMv = mv.domain()->dim();
574 if (numColsA > numColsMv)
575 {
576 std::ostringstream os;
577 os << "Belos::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar>"
578 " >::Assign(A, mv): ";
579 TEUCHOS_TEST_FOR_EXCEPTION(numColsA > numColsMv, std::invalid_argument,
580 os.str() << "Input multivector 'A' has "
581 << numColsA << " columns, but output multivector "
582 "'mv' has only " << numColsMv << " columns.");
583 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Should never get here!");
584 }
585 // Copy the data to the destination multivector.
586 if (numColsA == numColsMv) {
587 Thyra::assign (Teuchos::outArg (mv), A);
588 } else {
589 Teuchos::RCP<TMVB> mv_view =
590 CloneViewNonConst (mv, Teuchos::Range1D(0, numColsA-1));
591 Thyra::assign (mv_view.ptr(), A);
592 }
593 }
594
597 static void MvRandom( TMVB& mv )
598 {
599 // Thyra::randomize generates via a uniform distribution on [l,u]
600 // We will use this to generate on [-1,1]
601 Thyra::randomize<ScalarType>(
602 -Teuchos::ScalarTraits<ScalarType>::one(),
603 Teuchos::ScalarTraits<ScalarType>::one(),
604 Teuchos::outArg(mv));
605 }
606
608 static void
609 MvInit (TMVB& mv, ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero())
610 {
611 Thyra::assign (Teuchos::outArg (mv), alpha);
612 }
613
615
618
621 static void MvPrint( const TMVB& mv, std::ostream& os )
622 { os << describe(mv,Teuchos::VERB_EXTREME); }
623
625
626#ifdef HAVE_BELOS_TSQR
632 typedef Thyra::TsqrAdaptor< ScalarType > tsqr_adaptor_type;
633#endif // HAVE_BELOS_TSQR
634 };
635
637 //
638 // Implementation of the Belos::OperatorTraits for Thyra::LinearOpBase
639 //
641
649 template<class ScalarType>
650 class OperatorTraits <ScalarType,
651 Thyra::MultiVectorBase<ScalarType>,
652 Thyra::LinearOpBase<ScalarType> >
653 {
654 private:
655 typedef Thyra::MultiVectorBase<ScalarType> TMVB;
656 typedef Thyra::LinearOpBase<ScalarType> TLOB;
657
658 public:
674 static void
675 Apply (const TLOB& Op,
676 const TMVB& x,
677 TMVB& y,
678 ETrans trans = NOTRANS)
679 {
680 Thyra::EOpTransp whichOp;
681
682 // We don't check here whether the operator implements the
683 // requested operation. Call HasApplyTranspose() to check.
684 // Thyra::LinearOpBase implementations are not required to
685 // implement NOTRANS. However, Belos needs NOTRANS
686 // (obviously!), so we assume that Op implements NOTRANS.
687 if (trans == NOTRANS)
688 whichOp = Thyra::NOTRANS;
689 else if (trans == TRANS)
690 whichOp = Thyra::TRANS;
691 else if (trans == CONJTRANS)
692 whichOp = Thyra::CONJTRANS;
693 else
694 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument,
695 "Belos::OperatorTraits::Apply (Thyra specialization): "
696 "'trans' argument must be neither NOTRANS=" << NOTRANS
697 << ", TRANS=" << TRANS << ", or CONJTRANS=" << CONJTRANS
698 << ", but instead has an invalid value of " << trans << ".");
699 Thyra::apply<ScalarType>(Op, whichOp, x, Teuchos::outArg(y));
700 }
701
703 static bool HasApplyTranspose (const TLOB& Op)
704 {
705 typedef Teuchos::ScalarTraits<ScalarType> STS;
706
707 // Thyra::LinearOpBase's interface lets you check whether the
708 // operator implements any of all four possible combinations of
709 // conjugation and transpose. Belos only needs transpose
710 // (TRANS) if the operator is real; in that case, Apply() does
711 // the same thing with trans = CONJTRANS or TRANS. If the
712 // operator is complex, Belos needs both transpose and conjugate
713 // transpose (CONJTRANS) if the operator is complex.
714 return Op.opSupported (Thyra::TRANS) &&
715 (! STS::isComplex || Op.opSupported (Thyra::CONJTRANS));
716 }
717 };
718
719} // end of Belos namespace
720
721#endif
722// end of file BELOS_THYRA_ADAPTER_HPP
static void MvPrint(const TMVB &mv, std::ostream &os)
Print the mv multi-std::vector to the os output stream.
static void SetBlock(const TMVB &A, const std::vector< int > &index, TMVB &mv)
Copy the vectors in A to a set of vectors in mv indicated by the indices given in index.
static void MvAddMv(const ScalarType alpha, const TMVB &A, const ScalarType beta, const TMVB &B, TMVB &mv)
Replace mv with .
static int GetNumberVecs(const TMVB &mv)
Obtain the number of vectors in mv.
static Teuchos::RCP< TMVB > CloneCopy(const TMVB &mv)
Creates a new MultiVectorBase and copies contents of mv into the new std::vector (deep copy).
static ptrdiff_t GetGlobalLength(const TMVB &mv)
Obtain the std::vector length of mv.
static void MvDot(const TMVB &mv, const TMVB &A, std::vector< ScalarType > &b)
Compute a std::vector b where the components are the individual dot-products of the i-th columns of A...
static Teuchos::RCP< TMVB > CloneCopy(const TMVB &mv, const std::vector< int > &index)
Creates a new MultiVectorBase and copies the selected contents of mv into the new std::vector (deep c...
static Teuchos::RCP< TMVB > CloneViewNonConst(TMVB &mv, const std::vector< int > &index)
Creates a new MultiVectorBase that shares the selected contents of mv (shallow copy).
static Teuchos::RCP< TMVB > Clone(const TMVB &mv, const int numvecs)
Creates a new empty MultiVectorBase containing numvecs columns.
static Teuchos::RCP< const TMVB > CloneView(const TMVB &mv, const std::vector< int > &index)
Creates a new const MultiVectorBase that shares the selected contents of mv (shallow copy).
static void MvScale(TMVB &mv, const ScalarType alpha)
Scale each element of the vectors in *this with alpha.
static void MvTransMv(const ScalarType alpha, const TMVB &A, const TMVB &mv, Teuchos::SerialDenseMatrix< int, ScalarType > &B)
Compute a dense matrix B through the matrix-matrix multiply .
static void MvScale(TMVB &mv, const std::vector< ScalarType > &alpha)
Scale each element of the i-th vector in *this with alpha[i].
static void MvTimesMatAddMv(const ScalarType alpha, const TMVB &A, const Teuchos::SerialDenseMatrix< int, ScalarType > &B, const ScalarType beta, TMVB &mv)
Update mv with .
static void MvRandom(TMVB &mv)
Replace the vectors in mv with random vectors.
static void MvNorm(const TMVB &mv, std::vector< magType > &normvec, NormType type=TwoNorm)
Compute the 2-norm of each individual std::vector of mv. Upon return, normvec[i] holds the value of ,...
static void MvInit(TMVB &mv, ScalarType alpha=Teuchos::ScalarTraits< ScalarType >::zero())
Replace each element of the vectors in mv with alpha.
static Teuchos::RCP< MV > CloneCopy(const MV &mv)
static Teuchos::RCP< MV > Clone(const MV &mv, const int numvecs)
static Teuchos::RCP< const MV > CloneView(const MV &mv, const std::vector< int > &index)
static Teuchos::RCP< MV > CloneViewNonConst(MV &mv, const std::vector< int > &index)
static void SetBlock(const MV &A, const std::vector< int > &index, MV &mv)
static void Assign(const MV &A, MV &mv)
static bool HasApplyTranspose(const TLOB &Op)
Whether the operator implements applying the transpose.
static void Apply(const TLOB &Op, const TMVB &x, TMVB &y, ETrans trans=NOTRANS)
Apply Op to x, storing the result in y.
Stub adaptor from Thyra::MultiVectorBase to TSQR.

Generated for Stratimikos by doxygen 1.9.8