00001 #include "BlockDiagOperator.h"
00002
00003 #include "Epetra_Comm.h"
00004
00005
00006
00007
00008 BlockDiagOperator::BlockDiagOperator(Epetra_CrsMatrix* AA)
00009 : A(AA),
00010 _useTranspose(false)
00011 {
00012 _NumMyRows = A->NumMyRows();
00013 _diag = new int[_NumMyRows];
00014 _temp = new double[_NumMyRows];
00015
00016 int* Indices = 0;
00017 double* Values = 0;
00018 int NumEntries;
00019
00020 for (int i=0; i<_NumMyRows; i++) {
00021 assert(A->ExtractMyRowView(i, NumEntries, Values, Indices) >= 0);
00022 _diag[i] = -1;
00023 for (int j=0; j<NumEntries; j++) {
00024 if (i == Indices[j]) {
00025 _diag[i] = j;
00026 break;
00027 }
00028 }
00029 }
00030 }
00031
00032 BlockDiagOperator::~BlockDiagOperator() {
00033 delete[] _diag;
00034 delete[] _temp;
00035 }
00036
00037 int BlockDiagOperator::SetUseTranspose(bool UseTranspose) {
00038 int ierr = 0;
00039 _useTranspose = UseTranspose;
00040 return(ierr);
00041 }
00042
00043 int BlockDiagOperator::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const {
00044 int ierr = 1;
00045 cout << "Not implemented yet !!!!!!!!!!" << endl;
00046 return(ierr);
00047 }
00048
00049 int BlockDiagOperator::ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const {
00050 int ierr = 0;
00051 double* Xvalues = 0;
00052 double* Yvalues = 0;
00053 int i = 0;
00054 int j = 0;
00055 int* Indices = 0;
00056 double* Values = 0;
00057 int NumEntries = 0;
00058 double tsum;
00059 int start = 0;
00060 double diag = 0;
00061
00062 for (int index=0; index<X.NumVectors(); index++) {
00063
00064 Xvalues = X[index];
00065 Yvalues = Y[index];
00066
00067
00068 for (i=0; i<_NumMyRows; i++) {
00069 assert(A->ExtractMyRowView(i, NumEntries, Values, Indices) >= 0);
00070 tsum = 0;
00071 for (j=0; j<_diag[i]; j++) {
00072 tsum += *Values++ * _temp[*Indices++];
00073 }
00074 _temp[i] = (Xvalues[i] - tsum) / *Values;
00075 }
00076
00077
00078 for (i = _NumMyRows - 1; i >= 0; i --) {
00079 assert(A->ExtractMyRowView(i, NumEntries, Values, Indices) >= 0);
00080 tsum = 0;
00081 start = _diag[i];
00082 Values += start;
00083 diag = *Values++;
00084 Indices += ++start;
00085 for (j=start; j<NumEntries; j++) {
00086 tsum += *Values++ * Yvalues[*Indices++];
00087 }
00088 Yvalues[i] = _temp[i] - tsum / diag;
00089 }
00090 }
00091
00092 return(ierr);
00093 }
00094
00095 double BlockDiagOperator::NormInf() const {
00096 cout << "Not implemented yet !!!!!!!!!!" << endl;
00097 return(1);
00098 }
00099
00100 const char* BlockDiagOperator::Label() const {
00101 return "Block Diagonal Operator";
00102 }
00103
00104 bool BlockDiagOperator::UseTranspose() const {
00105 return(false);
00106 }
00107
00108 bool BlockDiagOperator::HasNormInf() const {
00109 return(false);
00110 }
00111
00112 const Epetra_Comm& BlockDiagOperator::Comm() const {
00113 return(A->Comm());
00114 }
00115
00116 const Epetra_Map& BlockDiagOperator::OperatorDomainMap() const {
00117 return(A->DomainMap());
00118 }
00119
00120 const Epetra_Map& BlockDiagOperator::OperatorRangeMap() const {
00121 return(A->RangeMap());
00122 }