Thyra Version of the Day
Loading...
Searching...
No Matches
Thyra_EpetraLinearOp.cpp
1// @HEADER
2// *****************************************************************************
3// Thyra: Interfaces and Support for Abstract Numerical Algorithms
4//
5// Copyright 2004 NTESS and the Thyra contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include "Thyra_EpetraLinearOp.hpp"
12#include "Thyra_SpmdMultiVectorBase.hpp"
13#include "Thyra_MultiVectorStdOps.hpp"
14#include "Thyra_AssertOp.hpp"
15#include "Teuchos_dyn_cast.hpp"
16#include "Teuchos_Assert.hpp"
17#include "Teuchos_getConst.hpp"
18#include "Teuchos_as.hpp"
19#include "Teuchos_TimeMonitor.hpp"
20
21#include "Epetra_Map.h"
22#include "Epetra_Vector.h"
23#include "Epetra_Operator.h"
24#include "Epetra_CrsMatrix.h" // Printing and absolute row sums only!
25
26
27namespace Thyra {
28
29
30// Constructors / initializers / accessors
31
32
34 :isFullyInitialized_(false),
35 opTrans_(NOTRANS),
36 applyAs_(EPETRA_OP_APPLY_APPLY),
37 adjointSupport_(EPETRA_OP_ADJOINT_UNSUPPORTED)
38{}
39
40
42 const RCP<Epetra_Operator> &op,
43 EOpTransp opTrans,
44 EApplyEpetraOpAs applyAs,
45 EAdjointEpetraOp adjointSupport,
46 const RCP< const VectorSpaceBase<double> > &range_in,
47 const RCP< const VectorSpaceBase<double> > &domain_in
48 )
49{
50
51 using Teuchos::rcp_dynamic_cast;
52 typedef SpmdVectorSpaceBase<double> SPMDVSB;
53
54 // Validate input, allocate spaces, validate ...
55#ifdef TEUCHOS_DEBUG
56 TEUCHOS_TEST_FOR_EXCEPTION( is_null(op), std::invalid_argument,
57 "Thyra::EpetraLinearOp::initialize(...): Error!" );
58 // ToDo: Validate spmdRange, spmdDomain against op maps!
59#endif
60
61 RCP<const SPMDVSB> l_spmdRange;
62 if(!is_null(range_in))
63 l_spmdRange = rcp_dynamic_cast<const SPMDVSB>(range_in,true);
64 else
65 l_spmdRange = ( applyAs==EPETRA_OP_APPLY_APPLY
66 ? allocateRange(op,opTrans) : allocateDomain(op,opTrans) );
67
68 RCP<const SPMDVSB> l_spmdDomain;
69 if(!is_null(domain_in))
70 l_spmdDomain = rcp_dynamic_cast<const SPMDVSB>(domain_in,true);
71 else
72 l_spmdDomain = ( applyAs==EPETRA_OP_APPLY_APPLY
73 ? allocateDomain(op,opTrans) : allocateRange(op,opTrans) );
74
75 // Set data (no exceptions should be thrown now)
76 isFullyInitialized_ = true;
77 op_ = op;
79 opTrans_ = opTrans;
80 applyAs_ = applyAs;
81 adjointSupport_ = adjointSupport;
82 range_ = l_spmdRange;
83 domain_ = l_spmdDomain;
84
85}
86
87
89 const RCP<const VectorSpaceBase<double> > &range_in,
90 const RCP<const VectorSpaceBase<double> > &domain_in,
91 const RCP<Epetra_Operator> &op,
92 EOpTransp opTrans,
93 EApplyEpetraOpAs applyAs,
94 EAdjointEpetraOp adjointSupport
95 )
96{
97
98 using Teuchos::rcp_dynamic_cast;
99 typedef SpmdVectorSpaceBase<double> SPMDVSB;
100
101 // Validate input, allocate spaces, validate ...
102#ifdef TEUCHOS_DEBUG
103 TEUCHOS_TEST_FOR_EXCEPTION( is_null(range_in), std::invalid_argument,
104 "Thyra::EpetraLinearOp::partiallyInitialize(...): Error!" );
105 TEUCHOS_TEST_FOR_EXCEPTION( is_null(domain_in), std::invalid_argument,
106 "Thyra::EpetraLinearOp::partiallyInitialize(...): Error!" );
107 TEUCHOS_TEST_FOR_EXCEPTION( is_null(op), std::invalid_argument,
108 "Thyra::EpetraLinearOp::partiallyInitialize(...): Error!" );
109#endif
110
112 l_spmdRange = rcp_dynamic_cast<const SPMDVSB>(range_in,true);
114 l_spmdDomain = rcp_dynamic_cast<const SPMDVSB>(domain_in,true);
115
116 // Set data (no exceptions should be thrown now)
117 isFullyInitialized_ = false;
118 op_ = op;
120 opTrans_ = opTrans;
121 applyAs_ = applyAs;
122 adjointSupport_ = adjointSupport;
123 range_ = l_spmdRange;
124 domain_ = l_spmdDomain;
125
126}
127
128
129void EpetraLinearOp::setFullyInitialized(bool /* isFullyInitialized */)
130{
131 // ToDo: Validate that everything matches up!
132 isFullyInitialized_ = true;
133}
134
135
138 EOpTransp *opTrans,
139 EApplyEpetraOpAs *applyAs,
140 EAdjointEpetraOp *adjointSupport,
141 RCP<const VectorSpaceBase<double> > *range_out,
142 RCP<const VectorSpaceBase<double> > *domain_out
143 )
144{
145
146 if(op) *op = op_;
147 if(opTrans) *opTrans = opTrans_;
148 if(applyAs) *applyAs = applyAs_;
149 if(adjointSupport) *adjointSupport = adjointSupport_;
150 if(range_out) *range_out = range_;
151 if(domain_out) *domain_out = domain_;
152
153 isFullyInitialized_ = false;
154 op_ = Teuchos::null;
155 rowMatrix_ = Teuchos::null;
156 opTrans_ = NOTRANS;
157 applyAs_ = EPETRA_OP_APPLY_APPLY;
158 adjointSupport_ = EPETRA_OP_ADJOINT_SUPPORTED;
159 range_ = Teuchos::null;
160 domain_ = Teuchos::null;
161
162}
163
164
167{
168 return range_;
169}
170
171
174{
175 return domain_;
176}
177
178
181{
182 return op_;
183}
184
185
188{
189 return op_;
190}
191
192
193// Overridden from EpetraLinearOpBase
194
195
197 const Ptr<RCP<Epetra_Operator> > &epetraOp,
198 const Ptr<EOpTransp> &epetraOpTransp,
199 const Ptr<EApplyEpetraOpAs> &epetraOpApplyAs,
200 const Ptr<EAdjointEpetraOp> &epetraOpAdjointSupport
201 )
202{
203 *epetraOp = op_;
204 *epetraOpTransp = opTrans_;
205 *epetraOpApplyAs = applyAs_;
206 *epetraOpAdjointSupport = adjointSupport_;
207}
208
209
211 const Ptr<RCP<const Epetra_Operator> > &epetraOp,
212 const Ptr<EOpTransp> &epetraOpTransp,
213 const Ptr<EApplyEpetraOpAs> &epetraOpApplyAs,
214 const Ptr<EAdjointEpetraOp> &epetraOpAdjointSupport
215 ) const
216{
217 *epetraOp = op_;
218 *epetraOpTransp = opTrans_;
219 *epetraOpApplyAs = applyAs_;
220 *epetraOpAdjointSupport = adjointSupport_;
221}
222
223
224// Overridden from LinearOpBase
225
226
229{
230 return range_;
231}
232
233
236{
237 return domain_;
238}
239
240
243{
244 assert(0); // ToDo: Implement when needed
245 return Teuchos::null;
246}
247
248
249// Overridden from Teuchos::Describable
250
251
253{
254 std::ostringstream oss;
255 oss << Teuchos::Describable::description() << "{";
256 if(op_.get()) {
257 oss << "op=\'"<<typeName(*op_)<<"\'";
258 oss << ",rangeDim="<<this->range()->dim();
259 oss << ",domainDim="<<this->domain()->dim();
260 }
261 else {
262 oss << "op=NULL";
263 }
264 oss << "}";
265 return oss.str();
266}
267
268
270 FancyOStream &out,
271 const Teuchos::EVerbosityLevel verbLevel
272 ) const
273{
275 using Teuchos::as;
276 using Teuchos::rcp_dynamic_cast;
277 using Teuchos::OSTab;
278 using Teuchos::describe;
279 OSTab tab(out);
280 if ( as<int>(verbLevel) == as<int>(Teuchos::VERB_LOW) || is_null(op_)) {
281 out << this->description() << std::endl;
282 }
283 else if (includesVerbLevel(verbLevel,Teuchos::VERB_MEDIUM)) {
284 out
286 << "{"
287 << "rangeDim=" << this->range()->dim()
288 << ",domainDim=" << this->domain()->dim()
289 << "}\n";
290 OSTab tab2(out);
291 if (op_.get()) {
292 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
293 out << "opTrans="<<toString(opTrans_)<<"\n";
294 out << "applyAs="<<toString(applyAs_)<<"\n";
295 out << "adjointSupport="<<toString(adjointSupport_)<<"\n";
296 out << "op="<<typeName(*op_)<<"\n";
297 }
298 if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_EXTREME) ) {
299 OSTab tab3(out);
301 csr_op = rcp_dynamic_cast<const Epetra_CrsMatrix>(op_);
302 if (!is_null(csr_op)) {
303 csr_op->Print(out);
304 }
305 }
306 }
307 else {
308 out << "op=NULL"<<"\n";
309 }
310 }
311}
312
313
314// protected
315
316
317// Protected member functions overridden from LinearOpBase
318
319
321{
322 if (!isFullyInitialized_)
323 return false;
324 return ( M_trans == NOTRANS
325 ? true : adjointSupport_==EPETRA_OP_ADJOINT_SUPPORTED );
326}
327
328
330 const EOpTransp M_trans,
331 const MultiVectorBase<double> &X_in,
332 const Ptr<MultiVectorBase<double> > &Y_inout,
333 const double alpha,
334 const double beta
335 ) const
336{
337
338 THYRA_FUNC_TIME_MONITOR("Thyra::EpetraLinearOp::euclideanApply");
339
340 const EOpTransp real_M_trans = real_trans(M_trans);
341
342#ifdef TEUCHOS_DEBUG
343 TEUCHOS_TEST_FOR_EXCEPT(!isFullyInitialized_);
345 "EpetraLinearOp::euclideanApply(...)", *this, M_trans, X_in, Y_inout
346 );
348 real_M_trans==TRANS && adjointSupport_==EPETRA_OP_ADJOINT_UNSUPPORTED,
350 "EpetraLinearOp::apply(...): *this was informed that adjoints "
351 "are not supported when initialized."
352 );
353#endif
354
355 const RCP<const VectorSpaceBase<double> > XY_domain = X_in.domain();
356 const int numCols = XY_domain->dim();
357
358 //
359 // Get Epetra_MultiVector objects for the arguments
360 //
361 // 2007/08/18: rabartl: Note: After profiling, I found that calling the more
362 // general functions get_Epetra_MultiVector(...) was too slow. These
363 // functions must ensure that memory is being remembered efficiently and the
364 // use of extra data with the RCP and other things is slow.
365 //
368 {
369 THYRA_FUNC_TIME_MONITOR_DIFF(
370 "Thyra::EpetraLinearOp::euclideanApply: Convert MultiVectors", MultiVectors);
371 // X
373 real_M_trans==NOTRANS ? getDomainMap() : getRangeMap(), X_in );
374 // Y
375 if( beta == 0 ) {
377 real_M_trans==NOTRANS ? getRangeMap() : getDomainMap(), *Y_inout );
378 }
379 }
380
381 //
382 // Set the operator mode
383 //
384
385 /* We need to save the transpose state here, and then reset it after
386 * application. The reason for this is that if we later apply the
387 * operator outside Thyra (in Aztec, for instance), it will remember
388 * the transpose flag set here. */
389 bool oldState = op_->UseTranspose();
390 op_->SetUseTranspose(
391 real_trans(trans_trans(opTrans_,M_trans)) == NOTRANS ? false : true );
392
393 //
394 // Perform the apply operation
395 //
396 {
397 THYRA_FUNC_TIME_MONITOR_DIFF(
398 "Thyra::EpetraLinearOp::euclideanApply: Apply", Apply);
399 if( beta == 0.0 ) {
400 // Y = M * X
401 if( applyAs_ == EPETRA_OP_APPLY_APPLY ) {
402 THYRA_FUNC_TIME_MONITOR_DIFF(
403 "Thyra::EpetraLinearOp::euclideanApply: Apply(beta==0): Apply",
404 ApplyApply);
405 op_->Apply( *X, *Y );
406 }
407 else if( applyAs_ == EPETRA_OP_APPLY_APPLY_INVERSE ) {
408 THYRA_FUNC_TIME_MONITOR_DIFF(
409 "Thyra::EpetraLinearOp::euclideanApply: Apply(beta==0): ApplyInverse",
410 ApplyApplyInverse);
411 op_->ApplyInverse( *X, *Y );
412 }
413 else {
414#ifdef TEUCHOS_DEBUG
416#endif
417 }
418 // Y = alpha * Y
419 if( alpha != 1.0 ) {
420 THYRA_FUNC_TIME_MONITOR_DIFF(
421 "Thyra::EpetraLinearOp::euclideanApply: Apply(beta==0): Scale Y",
422 Scale);
423 Y->Scale(alpha);
424 }
425 }
426 else { // beta != 0.0
427 // Y_inout = beta * Y_inout
428 if(beta != 0.0) {
429 THYRA_FUNC_TIME_MONITOR_DIFF(
430 "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Scale Y",
431 Scale);
432 scale( beta, Y_inout );
433 }
434 else {
435 THYRA_FUNC_TIME_MONITOR_DIFF(
436 "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Y=0",
437 Apply2);
438 assign( Y_inout, 0.0 );
439 }
440 // T = M * X
441 Epetra_MultiVector T(op_->OperatorRangeMap(), numCols, false);
442 // NOTE: Above, op_->OperatorRange() will be right for either
443 // non-transpose or transpose because we have already set the
444 // UseTranspose flag correctly.
445 if( applyAs_ == EPETRA_OP_APPLY_APPLY ) {
446 THYRA_FUNC_TIME_MONITOR_DIFF(
447 "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Apply",
448 Apply2);
449 op_->Apply( *X, T );
450 }
451 else if( applyAs_ == EPETRA_OP_APPLY_APPLY_INVERSE ) {
452 THYRA_FUNC_TIME_MONITOR_DIFF(
453 "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): ApplyInverse",
454 ApplyInverse);
455 op_->ApplyInverse( *X, T );
456 }
457 else {
458#ifdef TEUCHOS_DEBUG
460#endif
461 }
462 // Y_inout += alpha * T
463 {
464 THYRA_FUNC_TIME_MONITOR_DIFF(
465 "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Update Y",
466 Update);
467 update(
468 alpha,
471 Y_inout->range(),
472 XY_domain
473 ),
474 Y_inout
475 );
476 }
477 }
478 }
479
480 // Reset the transpose state
481 op_->SetUseTranspose(oldState);
482
483 // 2009/04/14: ToDo: This will not reset the transpose flag correctly if an
484 // exception is thrown!
485
486}
487
488
489// Protected member functions overridden from ScaledLinearOpBase
490
491
493{
494 return nonnull(rowMatrix_);
495}
496
497
499{
500 return nonnull(rowMatrix_);
501}
502
503
505{
506 using Teuchos::rcpFromRef;
507 const RCP<const Epetra_Vector> row_scaling =
508 get_Epetra_Vector(getRangeMap(), rcpFromRef(row_scaling_in));
509 rowMatrix_->LeftScale(*row_scaling);
510}
511
512
514{
515 using Teuchos::rcpFromRef;
516 const RCP<const Epetra_Vector> col_scaling =
517 get_Epetra_Vector(getDomainMap(), rcpFromRef(col_scaling_in));
518 rowMatrix_->RightScale(*col_scaling);
519}
520
521
522// Protected member functions overridden from RowStatLinearOpBase
523
524
526 const RowStatLinearOpBaseUtils::ERowStat rowStat) const
527{
528 if (is_null(rowMatrix_)) {
529 return false;
530 }
531 switch (rowStat) {
532 case RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM:
533 case RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM:
534 return true;
535 default:
537 }
539}
540
541
543 const RowStatLinearOpBaseUtils::ERowStat rowStat,
544 const Ptr<VectorBase<double> > &rowStatVec_in
545 ) const
546{
547 using Teuchos::rcpFromPtr;
548 const RCP<Epetra_Vector> rowStatVec =
549 get_Epetra_Vector(getRangeMap(), rcpFromPtr(rowStatVec_in));
550 switch (rowStat) {
551 case RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM:
552 rowMatrix_->InvRowSums(*rowStatVec);
553 break;
554 case RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM:
555 // compute absolute row sum
556 computeAbsRowSum(*rowStatVec);
557 break;
558 default:
560 }
561}
562
563
564// Allocators for domain and range spaces
565
566
569 const RCP<Epetra_Operator> &op,
570 EOpTransp /* op_trans */
571 ) const
572{
574 create_VectorSpace(Teuchos::rcp(&op->OperatorDomainMap(),false))
575 );
576 // ToDo: What about the transpose argument???, test this!!!
577}
578
579
582 const RCP<Epetra_Operator> &op,
583 EOpTransp /* op_trans */
584 ) const
585{
587 create_VectorSpace(Teuchos::rcp(&op->OperatorRangeMap(),false))
588 );
589 // ToDo: What about the transpose argument???, test this!!!
590}
591
592// private
593
594
595const Epetra_Map& EpetraLinearOp::getRangeMap() const
596{
597 return ( applyAs_ == EPETRA_OP_APPLY_APPLY
598 ? op_->OperatorRangeMap() : op_->OperatorDomainMap() );
599 // ToDo: What about the transpose argument???, test this!!!
600}
601
602
603const Epetra_Map& EpetraLinearOp::getDomainMap() const
604{
605 return ( applyAs_ == EPETRA_OP_APPLY_APPLY
606 ? op_->OperatorDomainMap() : op_->OperatorRangeMap() );
607 // ToDo: What about the transpose argument???, test this!!!
608}
609
610void EpetraLinearOp::computeAbsRowSum(Epetra_Vector & x) const
611{
612 TEUCHOS_ASSERT(!is_null(rowMatrix_));
613
614 RCP<Epetra_CrsMatrix> crsMatrix
616
618 Exceptions::OpNotSupported,
619 "EpetraLinearOp::computeAbsRowSum(...): wrapped matrix must be of type "
620 "Epetra_CrsMatrix for this method. Other operator types are not supported."
621 );
622
623 //
624 // Put inverse of the sum of absolute values of the ith row of A in x[i].
625 // (this is a modified copy of Epetra_CrsMatrix::InvRowSums)
626 //
627
628 if (crsMatrix->Filled()) {
630 std::invalid_argument,
631 "EpetraLinearOp::computeAbsRowSum(...): Epetra_CrsMatrix must be filled"
632 );
633 }
634 int i, j;
635 x.PutScalar(0.0); // Make sure we sum into a vector of zeros.
636 double * xp = (double*)x.Values();
637 if (crsMatrix->Graph().RangeMap().SameAs(x.Map()) && crsMatrix->Exporter() != 0) {
638 Epetra_Vector x_tmp(crsMatrix->RowMap());
639 x_tmp.PutScalar(0.0);
640 double * x_tmp_p = (double*)x_tmp.Values();
641 for (i=0; i < crsMatrix->NumMyRows(); i++) {
642 int NumEntries = 0;
643 double * RowValues = 0;
644 crsMatrix->ExtractMyRowView(i,NumEntries,RowValues);
645 for (j=0; j < NumEntries; j++) x_tmp_p[i] += std::abs(RowValues[j]);
646 }
647 TEUCHOS_TEST_FOR_EXCEPT(0!=x.Export(x_tmp, *crsMatrix->Exporter(), Add)); //Export partial row sums to x.
648 }
649 else if (crsMatrix->Graph().RowMap().SameAs(x.Map())) {
650 for (i=0; i < crsMatrix->NumMyRows(); i++) {
651 int NumEntries = 0;
652 double * RowValues = 0;
653 crsMatrix->ExtractMyRowView(i,NumEntries,RowValues);
654 double scale = 0.0;
655 for (j=0; j < NumEntries; j++) scale += std::abs(RowValues[j]);
656 xp[i] = scale;
657 }
658 }
659 else { // x.Map different than both crsMatrix->Graph().RowMap() and crsMatrix->Graph().RangeMap()
660 TEUCHOS_TEST_FOR_EXCEPT(true); // The map of x must be the RowMap or RangeMap of A.
661 }
662}
663
664} // end namespace Thyra
665
666
667// Nonmembers
668
669
671Thyra::nonconstEpetraLinearOp()
672{
673 return Teuchos::rcp(new EpetraLinearOp());
674}
675
676
678Thyra::partialNonconstEpetraLinearOp(
679 const RCP<const VectorSpaceBase<double> > &range,
680 const RCP<const VectorSpaceBase<double> > &domain,
681 const RCP<Epetra_Operator> &op,
682 EOpTransp opTrans,
683 EApplyEpetraOpAs applyAs,
684 EAdjointEpetraOp adjointSupport
685 )
686{
687 RCP<EpetraLinearOp> thyraEpetraOp = Teuchos::rcp(new EpetraLinearOp());
688 thyraEpetraOp->partiallyInitialize(
689 range, domain,op,opTrans, applyAs, adjointSupport
690 );
691 return thyraEpetraOp;
692}
693
694
696Thyra::nonconstEpetraLinearOp(
697 const RCP<Epetra_Operator> &op,
698 EOpTransp opTrans,
699 EApplyEpetraOpAs applyAs,
700 EAdjointEpetraOp adjointSupport,
701 const RCP< const VectorSpaceBase<double> > &range,
702 const RCP< const VectorSpaceBase<double> > &domain
703 )
704{
705 RCP<EpetraLinearOp> thyraEpetraOp = Teuchos::rcp(new EpetraLinearOp());
706 thyraEpetraOp->initialize(
707 op,opTrans, applyAs, adjointSupport, range, domain
708 );
709 return thyraEpetraOp;
710}
711
712
714Thyra::epetraLinearOp(
715 const RCP<const Epetra_Operator> &op,
716 EOpTransp opTrans,
717 EApplyEpetraOpAs applyAs,
718 EAdjointEpetraOp adjointSupport,
719 const RCP<const VectorSpaceBase<double> > &range,
720 const RCP<const VectorSpaceBase<double> > &domain
721 )
722{
723 RCP<EpetraLinearOp> thyraEpetraOp = Teuchos::rcp(new EpetraLinearOp());
724 thyraEpetraOp->initialize(
725 Teuchos::rcp_const_cast<Epetra_Operator>(op), // Safe cast due to return type!
726 opTrans, applyAs, adjointSupport, range, domain
727 );
728 return thyraEpetraOp;
729}
730
731
733Thyra::nonconstEpetraLinearOp(
734 const RCP<Epetra_Operator> &op,
735 const std::string &label,
736 EOpTransp opTrans,
737 EApplyEpetraOpAs applyAs,
738 EAdjointEpetraOp adjointSupport,
739 const RCP<const VectorSpaceBase<double> > &range,
740 const RCP<const VectorSpaceBase<double> > &domain
741 )
742{
743 RCP<EpetraLinearOp> thyraEpetraOp = Teuchos::rcp(new EpetraLinearOp());
744 thyraEpetraOp->initialize(
745 op,opTrans, applyAs, adjointSupport, range, domain
746 );
747 thyraEpetraOp->setObjectLabel(label);
748 return thyraEpetraOp;
749}
750
751
753Thyra::epetraLinearOp(
754 const RCP<const Epetra_Operator> &op,
755 const std::string &label,
756 EOpTransp opTrans,
757 EApplyEpetraOpAs applyAs,
758 EAdjointEpetraOp adjointSupport,
759 const RCP< const SpmdVectorSpaceBase<double> > &range,
760 const RCP< const SpmdVectorSpaceBase<double> > &domain
761 )
762{
763 RCP<EpetraLinearOp> thyraEpetraOp = Teuchos::rcp(new EpetraLinearOp());
764 thyraEpetraOp->initialize(
765 Teuchos::rcp_const_cast<Epetra_Operator>(op), // Safe cast due to return type!
766 opTrans, applyAs, adjointSupport, range, domain
767 );
768 thyraEpetraOp->setObjectLabel(label);
769 return thyraEpetraOp;
770}
const Epetra_BlockMap & Map() const
int Export(const Epetra_SrcDistObject &A, const Epetra_Import &Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor=0)
double * Values() const
int PutScalar(double ScalarConstant)
virtual std::string description() const
T * get() const
RCP< const SpmdVectorSpaceBase< double > > spmdDomain() const
Return a smart pointer to the SpmdVectorSpaceBase object for the domain.
std::string description() const
virtual void scaleLeftImpl(const VectorBase< double > &row_scaling)
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< double > &X, const Ptr< MultiVectorBase< double > > &Y, const double alpha, const double beta) const
virtual void scaleRightImpl(const VectorBase< double > &col_scaling)
void getNonconstEpetraOpView(const Ptr< RCP< Epetra_Operator > > &epetraOp, const Ptr< EOpTransp > &epetraOpTransp, const Ptr< EApplyEpetraOpAs > &epetraOpApplyAs, const Ptr< EAdjointEpetraOp > &epetraOpAdjointSupport)
void getEpetraOpView(const Ptr< RCP< const Epetra_Operator > > &epetraOp, const Ptr< EOpTransp > &epetraOpTransp, const Ptr< EApplyEpetraOpAs > &epetraOpApplyAs, const Ptr< EAdjointEpetraOp > &epetraOpAdjointSupport) const
void uninitialize(RCP< Epetra_Operator > *op=NULL, EOpTransp *opTrans=NULL, EApplyEpetraOpAs *applyAs=NULL, EAdjointEpetraOp *adjointSupport=NULL, RCP< const VectorSpaceBase< double > > *range=NULL, RCP< const VectorSpaceBase< double > > *domain=NULL)
Set to uninitialized and optionally return the current state.
EpetraLinearOp()
Construct to uninitialized.
virtual bool supportsScaleRightImpl() const
void setFullyInitialized(bool isFullyInitialized=true)
Set to fully initialized.
virtual void getRowStatImpl(const RowStatLinearOpBaseUtils::ERowStat rowStat, const Ptr< VectorBase< double > > &rowStatVec) const
void describe(FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual RCP< const SpmdVectorSpaceBase< double > > allocateRange(const RCP< Epetra_Operator > &op, EOpTransp op_trans) const
Allocate the range space of the operator.
void initialize(const RCP< Epetra_Operator > &op, EOpTransp opTrans=NOTRANS, EApplyEpetraOpAs applyAs=EPETRA_OP_APPLY_APPLY, EAdjointEpetraOp adjointSupport=EPETRA_OP_ADJOINT_SUPPORTED, const RCP< const VectorSpaceBase< double > > &range=Teuchos::null, const RCP< const VectorSpaceBase< double > > &domain=Teuchos::null)
Fully initialize.
RCP< const LinearOpBase< double > > clone() const
void partiallyInitialize(const RCP< const VectorSpaceBase< double > > &range, const RCP< const VectorSpaceBase< double > > &domain, const RCP< Epetra_Operator > &op, EOpTransp opTrans=NOTRANS, EApplyEpetraOpAs applyAs=EPETRA_OP_APPLY_APPLY, EAdjointEpetraOp adjointSupport=EPETRA_OP_ADJOINT_SUPPORTED)
Partially initialize.
RCP< const SpmdVectorSpaceBase< double > > spmdRange() const
Return a smart pointer to the SpmdVectorSpaceBase object for the range.
virtual bool rowStatIsSupportedImpl(const RowStatLinearOpBaseUtils::ERowStat rowStat) const
RCP< Epetra_Operator > epetra_op()
virtual RCP< const SpmdVectorSpaceBase< double > > allocateDomain(const RCP< Epetra_Operator > &op, EOpTransp op_trans) const
Allocate the domain space of the operator.
bool opSupportedImpl(EOpTransp M_trans) const
RCP< const VectorSpaceBase< double > > range() const
virtual bool supportsScaleLeftImpl() const
RCP< const VectorSpaceBase< double > > domain() const
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
Interface for a collection of column vectors called a multi-vector.
Base abstract VectorSpaceBase class for all SPMD-based vector spaces.
Abstract interface for finite-dimensional dense vectors.
Abstract interface for objects that represent a space for vectors.
EApplyEpetraOpAs
Determine how the apply an Epetra_Operator as a linear operator.
RCP< MultiVectorBase< double > > create_MultiVector(const RCP< Epetra_MultiVector > &epetra_mv, const RCP< const VectorSpaceBase< double > > &range=Teuchos::null, const RCP< const VectorSpaceBase< double > > &domain=Teuchos::null)
Create a non-const MultiVectorBase object from a non-const Epetra_MultiVector object.
RCP< const VectorSpaceBase< double > > create_VectorSpace(const RCP< const Epetra_Map > &epetra_map)
Create an VectorSpaceBase object given an Epetra_Map object.
RCP< Epetra_Vector > get_Epetra_Vector(const Epetra_Map &map, const RCP< VectorBase< double > > &v)
Get a non-const Epetra_Vector view from a non-const VectorBase object if possible.
RCP< Epetra_MultiVector > get_Epetra_MultiVector(const Epetra_Map &map, const RCP< MultiVectorBase< double > > &mv)
Get a non-const Epetra_MultiVector view from a non-const MultiVectorBase object if possible.
EAdjointEpetraOp
Determine if adjoints are supported on Epetra_Opeator or not.
@ EPETRA_OP_APPLY_APPLY
Apply using Epetra_Operator::Apply(...)
@ EPETRA_OP_APPLY_APPLY_INVERSE
Apply using Epetra_Operator::ApplyInverse(...)
@ EPETRA_OP_ADJOINT_UNSUPPORTED
Adjoint not supported.
@ EPETRA_OP_ADJOINT_SUPPORTED
Adjoint supported.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
bool is_null(const std::shared_ptr< T > &p)
#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...
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
const char * toString(EConj conj)
Return a string name for a EOpTransp value. `*.
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
EOpTransp trans_trans(EOpTransp trans1, EOpTransp trans2)
Combine two transpose arguments.
@ TRANS
Use the transposed operator.
@ NOTRANS
Use the non-transposed operator.
TypeTo as(const TypeFrom &t)
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
const T & getConst(T &t)
T_To & dyn_cast(T_From &from)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
TEUCHOSCORE_LIB_DLL_EXPORT bool includesVerbLevel(const EVerbosityLevel verbLevel, const EVerbosityLevel requestedVerbLevel, const bool isDefaultLevel=false)