Thyra Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_EpetraLinearOp.cpp
Go to the documentation of this file.
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 
27 namespace 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;
78  rowMatrix_ = Teuchos::rcp_dynamic_cast<Epetra_RowMatrix>(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;
119  rowMatrix_ = Teuchos::rcp_dynamic_cast<Epetra_RowMatrix>(op_);
120  opTrans_ = opTrans;
121  applyAs_ = applyAs;
122  adjointSupport_ = adjointSupport;
123  range_ = l_spmdRange;
124  domain_ = l_spmdDomain;
125 
126 }
127 
128 
129 void 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;
156  opTrans_ = NOTRANS;
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 
252 std::string EpetraLinearOp::description() const
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 
320 bool EpetraLinearOp::opSupportedImpl(EOpTransp M_trans) const
321 {
322  if (!isFullyInitialized_)
323  return false;
324  return ( M_trans == NOTRANS
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
344  THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(
345  "EpetraLinearOp::euclideanApply(...)", *this, M_trans, X_in, Y_inout
346  );
349  Exceptions::OpNotSupported,
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
402  THYRA_FUNC_TIME_MONITOR_DIFF(
403  "Thyra::EpetraLinearOp::euclideanApply: Apply(beta==0): Apply",
404  ApplyApply);
405  op_->Apply( *X, *Y );
406  }
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.
446  THYRA_FUNC_TIME_MONITOR_DIFF(
447  "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Apply",
448  Apply2);
449  op_->Apply( *X, T );
450  }
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,
470  Teuchos::rcp(&Teuchos::getConst(T),false),
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 
504 void EpetraLinearOp::scaleLeftImpl(const VectorBase<double> &row_scaling_in)
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 
513 void EpetraLinearOp::scaleRightImpl(const VectorBase<double> &col_scaling_in)
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 {
573  return Teuchos::rcp_dynamic_cast<const SpmdVectorSpaceBase<double> >(
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 {
586  return Teuchos::rcp_dynamic_cast<const SpmdVectorSpaceBase<double> >(
587  create_VectorSpace(Teuchos::rcp(&op->OperatorRangeMap(),false))
588  );
589  // ToDo: What about the transpose argument???, test this!!!
590 }
591 
592 // private
593 
594 
595 const 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 
603 const 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 
610 void EpetraLinearOp::computeAbsRowSum(Epetra_Vector & x) const
611 {
613 
614  RCP<Epetra_CrsMatrix> crsMatrix
615  = Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(rowMatrix_);
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()) {
629  TEUCHOS_TEST_FOR_EXCEPTION(is_null(crsMatrix),
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 
671 Thyra::nonconstEpetraLinearOp()
672 {
673  return Teuchos::rcp(new EpetraLinearOp());
674 }
675 
676 
678 Thyra::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 
696 Thyra::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 
714 Thyra::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 
733 Thyra::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 
753 Thyra::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 }
RCP< const SpmdVectorSpaceBase< double > > spmdDomain() const
Return a smart pointer to the SpmdVectorSpaceBase object for the domain.
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...
virtual RCP< const SpmdVectorSpaceBase< double > > allocateDomain(const RCP< Epetra_Operator > &op, EOpTransp op_trans) const
Allocate the domain space of the operator.
virtual bool supportsScaleRightImpl() const
std::string typeName(const T &t)
const std::string toString(const EAdjointEpetraOp adjointEpetraOp)
bool is_null(const boost::shared_ptr< T > &p)
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< const VectorSpaceBase< double > > create_VectorSpace(const RCP< const Epetra_Map > &epetra_map)
Create an VectorSpaceBase object given an Epetra_Map object.
virtual bool supportsScaleLeftImpl() const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
const T & getConst(T &t)
T * get() const
RCP< const SpmdVectorSpaceBase< double > > domain_
std::string description() const
basic_OSTab< char > OSTab
void getEpetraOpView(const Ptr< RCP< const Epetra_Operator > > &epetraOp, const Ptr< EOpTransp > &epetraOpTransp, const Ptr< EApplyEpetraOpAs > &epetraOpApplyAs, const Ptr< EAdjointEpetraOp > &epetraOpAdjointSupport) const
RCP< const SpmdVectorSpaceBase< double > > range_
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.
Apply using Epetra_Operator::ApplyInverse(...)
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.
virtual void scaleLeftImpl(const VectorBase< double > &row_scaling)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
EAdjointEpetraOp adjointSupport_
EAdjointEpetraOp
Determine if adjoints are supported on Epetra_Opeator or not.
EpetraLinearOp()
Construct to uninitialized.
void setFullyInitialized(bool isFullyInitialized=true)
Set to fully initialized.
void getNonconstEpetraOpView(const Ptr< RCP< Epetra_Operator > > &epetraOp, const Ptr< EOpTransp > &epetraOpTransp, const Ptr< EApplyEpetraOpAs > &epetraOpApplyAs, const Ptr< EAdjointEpetraOp > &epetraOpAdjointSupport)
void computeAbsRowSum(Epetra_Vector &rowStatVec_in) const
Compute the absolute row sum for this matrix.
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.
const Epetra_Map & getRangeMap() const
virtual std::string description() const
RCP< const VectorSpaceBase< double > > range() const
RCP< const VectorSpaceBase< double > > domain() const
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< double > &X, const Ptr< MultiVectorBase< double > > &Y, const double alpha, const double beta) const
void describe(FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
TEUCHOSCORE_LIB_DLL_EXPORT bool includesVerbLevel(const EVerbosityLevel verbLevel, const EVerbosityLevel requestedVerbLevel, const bool isDefaultLevel=false)
TypeTo as(const TypeFrom &t)
bool nonnull(const boost::shared_ptr< T > &p)
basic_FancyOStream< char > FancyOStream
EApplyEpetraOpAs
Determine how the apply an Epetra_Operator as a linear operator.
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.
const Epetra_Map & getDomainMap() const
#define TEUCHOS_ASSERT(assertion_test)
virtual void getRowStatImpl(const RowStatLinearOpBaseUtils::ERowStat rowStat, const Ptr< VectorBase< double > > &rowStatVec) const
virtual RCP< const SpmdVectorSpaceBase< double > > allocateRange(const RCP< Epetra_Operator > &op, EOpTransp op_trans) const
Allocate the range space of the operator.
bool opSupportedImpl(EOpTransp M_trans) const
Apply using Epetra_Operator::Apply(...)
virtual void scaleRightImpl(const VectorBase< double > &col_scaling)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
RCP< Epetra_Operator > op_
RCP< const LinearOpBase< double > > clone() const
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
RCP< Epetra_RowMatrix > rowMatrix_
RCP< Epetra_Operator > epetra_op()