Go to the documentation of this file.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 #include "TSFMLOperator.hpp"
00030 #include "Teuchos_Array.hpp"
00031 #include "Teuchos_MPIComm.hpp"
00032 #include "TSFEpetraVector.hpp"
00033
00034
00035
00036 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00037 #include "TSFVectorImpl.hpp"
00038 #include "TSFLinearOperatorImpl.hpp"
00039 #endif
00040
00041 using namespace TSFExtended;
00042 using namespace Teuchos;
00043
00044 MLOperator::MLOperator(
00045 const LinearOperator<double>& op,
00046 const ParameterList& mlParams)
00047 : mlPrec_(),
00048 domain_(op.domain().ptr()),
00049 range_(op.range().ptr())
00050 {
00051 Epetra_CrsMatrix& A = EpetraMatrix::getConcrete(op);
00052
00053
00054 mlPrec_ = rcp(new ML_Epetra::MultiLevelPreconditioner(A, mlParams));
00055 }
00056
00057
00058 void MLOperator::generalApply(const Thyra::EOpTransp M_trans,
00059 const Thyra::VectorBase<double>& x,
00060 Thyra::VectorBase<double>* y,
00061 const double alpha,
00062 const double beta) const
00063 {
00064
00065 const EpetraVector* epIn = dynamic_cast<const EpetraVector*>(&x);
00066 TEST_FOR_EXCEPTION(epIn == 0, std::runtime_error,
00067 "IfpackOperator apply: input vector is "
00068 "not an EpetraVector");
00069
00070 const Epetra_Vector* in = epIn->epetraVec().get();
00071
00072 EpetraVector* epy = dynamic_cast<EpetraVector*>(y);
00073 TEST_FOR_EXCEPTION(epy == 0, std::runtime_error,
00074 "IfpackOperator apply: output vector is "
00075 "not an EpetraVector");
00076
00077 Epetra_Vector* yy = epy->epetraVec().get();
00078
00079
00080
00081 RCP<Thyra::VectorBase<double> > tsfOut;
00082 Epetra_Vector* tmp;
00083
00084 if (beta!=0.0)
00085 {
00086 tsfOut = createMember(y->space());
00087 EpetraVector* ep = dynamic_cast<EpetraVector*>(tsfOut.get());
00088 tmp = ep->epetraVec().get();
00089 }
00090 else
00091 {
00092 tmp = yy;
00093 }
00094
00095
00096 int ierr;
00097
00098
00099 if (M_trans==NOTRANS)
00100 {
00101 ierr = mlPrec_->ApplyInverse(*in, *tmp);
00102 }
00103 else
00104 {
00105 TEST_FOR_EXCEPTION(M_trans != NOTRANS, std::runtime_error,
00106 "ML preconditioner does not support transposes");
00107 }
00108
00109
00110 if (beta != 0.0)
00111 {
00112
00113 yy->Update(alpha, *tmp, beta);
00114 }
00115 else if (alpha != 1.0)
00116 {
00117
00118
00119
00120 tmp->Scale(alpha);
00121 }
00122
00123
00124 }
00125