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 "Ifpack_OverlapSolveObject.h"
00030 #include "Epetra_Comm.h"
00031 #include "Epetra_Map.h"
00032 #include "Epetra_CrsGraph.h"
00033 #include "Epetra_CrsMatrix.h"
00034 #include "Epetra_Vector.h"
00035 #include "Epetra_MultiVector.h"
00036 #include "Epetra_Flops.h"
00037
00038
00039 Ifpack_OverlapSolveObject::Ifpack_OverlapSolveObject(char * Label, const Epetra_Comm & Comm)
00040 : Label_(Label),
00041 L_(0),
00042 UseLTrans_(false),
00043 D_(0),
00044 U_(0),
00045 UseUTrans_(false),
00046 UseTranspose_(false),
00047 Comm_(Comm),
00048 Condest_(-1.0),
00049 OverlapMode_(Zero)
00050 {
00051 }
00052
00053
00054 Ifpack_OverlapSolveObject::Ifpack_OverlapSolveObject(const Ifpack_OverlapSolveObject & Source)
00055 : Label_(Source.Label_),
00056 L_(Source.L_),
00057 UseLTrans_(Source.UseLTrans_),
00058 D_(Source.D_),
00059 U_(Source.U_),
00060 UseUTrans_(Source.UseUTrans_),
00061 UseTranspose_(Source.UseTranspose_),
00062 Comm_(Source.Comm_),
00063 Condest_(Source.Condest_),
00064 OverlapMode_(Source.OverlapMode_)
00065 {
00066 }
00067
00068 Ifpack_OverlapSolveObject::~Ifpack_OverlapSolveObject(){
00069 }
00070
00071
00072 int Ifpack_OverlapSolveObject::Solve(bool Trans, const Epetra_MultiVector& X,
00073 Epetra_MultiVector& Y) const {
00074
00075
00076
00077
00078
00079 Epetra_MultiVector * X1 = 0;
00080 Epetra_MultiVector * Y1 = 0;
00081 EPETRA_CHK_ERR(SetupXY(Trans, X, Y, X1, Y1));
00082
00083 bool Upper = true;
00084 bool Lower = false;
00085 bool UnitDiagonal = true;
00086
00087 if (!Trans) {
00088
00089 EPETRA_CHK_ERR(L_->Solve(Lower, Trans, UnitDiagonal, *X1, *Y1));
00090 EPETRA_CHK_ERR(Y1->Multiply(1.0, *D_, *Y1, 0.0));
00091 EPETRA_CHK_ERR(U_->Solve(Upper, Trans, UnitDiagonal, *Y1, *Y1));
00092 if (L_->Exporter()!=0) {EPETRA_CHK_ERR(Y.Export(*Y1,*L_->Exporter(), OverlapMode_));}
00093 }
00094 else {
00095 EPETRA_CHK_ERR(U_->Solve(Upper, Trans, UnitDiagonal, *X1, *Y1));
00096 EPETRA_CHK_ERR(Y1->Multiply(1.0, *D_, *Y1, 0.0));
00097 EPETRA_CHK_ERR(L_->Solve(Lower, Trans, UnitDiagonal, *Y1, *Y1));
00098 if (U_->Importer()!=0) {EPETRA_CHK_ERR(Y.Export(*Y1,*U_->Importer(), OverlapMode_));}
00099 }
00100
00101 return(0);
00102 }
00103
00104 int Ifpack_OverlapSolveObject::Multiply(bool Trans, const Epetra_MultiVector& X,
00105 Epetra_MultiVector& Y) const {
00106
00107
00108
00109
00110
00111 Epetra_MultiVector * X1 = 0;
00112 Epetra_MultiVector * Y1 = 0;
00113 EPETRA_CHK_ERR(SetupXY(Trans, X, Y, X1, Y1));
00114
00115 if (!Trans) {
00116 EPETRA_CHK_ERR(U_->Multiply(Trans, *X1, *Y1));
00117 EPETRA_CHK_ERR(Y1->Update(1.0, *X1, 1.0));
00118 EPETRA_CHK_ERR(Y1->ReciprocalMultiply(1.0, *D_, *Y1, 0.0));
00119 Epetra_MultiVector Y1temp(*Y1);
00120 EPETRA_CHK_ERR(L_->Multiply(Trans, Y1temp, *Y1));
00121 EPETRA_CHK_ERR(Y1->Update(1.0, Y1temp, 1.0));
00122 if (L_->Exporter()!=0) {EPETRA_CHK_ERR(Y.Export(*Y1,*L_->Exporter(), OverlapMode_));}
00123 }
00124 else {
00125
00126 EPETRA_CHK_ERR(L_->Multiply(Trans, *X1, *Y1));
00127 EPETRA_CHK_ERR(Y1->Update(1.0, *X1, 1.0));
00128 EPETRA_CHK_ERR(Y1->ReciprocalMultiply(1.0, *D_, *Y1, 0.0));
00129 Epetra_MultiVector Y1temp(*Y1);
00130 EPETRA_CHK_ERR(U_->Multiply(Trans, Y1temp, *Y1));
00131 EPETRA_CHK_ERR(Y1->Update(1.0, Y1temp, 1.0));
00132 if (L_->Exporter()!=0) {EPETRA_CHK_ERR(Y.Export(*Y1,*L_->Exporter(), OverlapMode_));}
00133 }
00134 return(0);
00135 }
00136
00137 int Ifpack_OverlapSolveObject::SetupXY(bool Trans,
00138 const Epetra_MultiVector& Xin, const Epetra_MultiVector& Yin,
00139 Epetra_MultiVector * & Xout, Epetra_MultiVector * & Yout) const {
00140
00141
00142
00143 if (Xin.NumVectors()!=Yin.NumVectors()) EPETRA_CHK_ERR(-1);
00144
00145
00146 Xout = (Epetra_MultiVector *) &Xin;
00147 Yout = (Epetra_MultiVector *) &Yin;
00148 return(0);
00149 }
00150
00151 int Ifpack_OverlapSolveObject::Condest(bool Trans, double & ConditionNumberEstimate) const {
00152
00153 if (Condest_>=0.0) {
00154 ConditionNumberEstimate = Condest_;
00155 return(0);
00156 }
00157
00158 Epetra_Vector Ones(U_->DomainMap());
00159 Epetra_Vector OnesResult(L_->RangeMap());
00160 Ones.PutScalar(1.0);
00161
00162 EPETRA_CHK_ERR(Solve(Trans, Ones, OnesResult));
00163 EPETRA_CHK_ERR(OnesResult.Abs(OnesResult));
00164 EPETRA_CHK_ERR(OnesResult.MaxValue(&ConditionNumberEstimate));
00165 Condest_ = ConditionNumberEstimate;
00166 return(0);
00167 }