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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "Ifpack_SerialTriDiMatrix.h"
00044 #include "Epetra_Util.h"
00045
00046
00047 Ifpack_SerialTriDiMatrix::Ifpack_SerialTriDiMatrix(bool set_object_label)
00048 : Epetra_CompObject(),
00049 Epetra_Object(-1, false),
00050 N_(0),
00051 A_Copied_(false),
00052 CV_(Copy),
00053 A_(0),
00054 UseTranspose_(false)
00055 {
00056 if (set_object_label) {
00057 SetLabel("Epetra::SerialTriDiMatrix");
00058 }
00059 }
00060
00061
00062 Ifpack_SerialTriDiMatrix::Ifpack_SerialTriDiMatrix(int NumRowCol,
00063 bool set_object_label)
00064 : Epetra_CompObject(),
00065 Epetra_Object(-1, false),
00066 N_(NumRowCol),
00067 A_Copied_(false),
00068 CV_(Copy),
00069 A_(0),
00070 UseTranspose_(false)
00071 {
00072 if (set_object_label) {
00073 SetLabel("Epetra::SerialTriDiMatrix");
00074 }
00075 if(NumRowCol < 0)
00076 throw ReportError("NumRows = " + toString(NumRowCol) + ". Should be >= 0", -1);
00077
00078 int errorcode = Shape(NumRowCol);
00079 if(errorcode != 0)
00080 throw ReportError("Shape returned non-zero value", errorcode);
00081 }
00082
00083
00084 Ifpack_SerialTriDiMatrix::Ifpack_SerialTriDiMatrix(Epetra_DataAccess CV_in, double* A_in,
00085 int NumRowCol,
00086 bool set_object_label)
00087 : Epetra_CompObject(),
00088 Epetra_Object(-1, false),
00089 N_(NumRowCol),
00090 A_Copied_(false),
00091 CV_(CV_in),
00092 A_(A_in),
00093 UseTranspose_(false)
00094 {
00095 if (set_object_label) {
00096 SetLabel("Epetra::SerialTriDiMatrix");
00097 }
00098 if(A_in == 0)
00099 throw ReportError("Null pointer passed as A parameter.", -3);
00100 if(NumRowCol < 0)
00101 throw ReportError("NumRowCol = " + toString(NumRowCol) + ". Should be >= 0", -1);
00102
00103 if (CV_in == Copy) {
00104 const int newsize = (N_ == 1) ? 1 : 4*(N_-1);
00105 if (newsize > 0) {
00106 A_ = new double[newsize];
00107 CopyMat(A_in, N_, A_, N_);
00108 A_Copied_ = true;
00109 DL_ = A_;
00110 D_ = DL_+(N_-1);
00111 DU_ = D_ + N_;
00112 DU2_ = DU_ + (N_-1);
00113 }
00114 else {
00115 A_ = 0;
00116 }
00117 }
00118 }
00119
00120 Ifpack_SerialTriDiMatrix::Ifpack_SerialTriDiMatrix(const Ifpack_SerialTriDiMatrix& Source)
00121 : Epetra_CompObject(Source),
00122 N_(Source.N_),
00123 LDA_(Source.LDA_),
00124 A_Copied_(false),
00125 CV_(Source.CV_),
00126 UseTranspose_(false)
00127 {
00128 SetLabel(Source.Label());
00129 if(CV_ == Copy) {
00130 const int newsize = (N_ == 1)? 1 : 4*(N_-1);
00131 if(newsize > 0) {
00132 A_ = new double[newsize];
00133 CopyMat(Source.A_, Source.N() , A_, N_);
00134 A_Copied_ = true;
00135 DL_ = A_;
00136 D_ = DL_+(N_-1);
00137 DU_ = D_ + N_;
00138 DU2_ = DU_ + (N_-1);
00139 }
00140 else {
00141 A_ = 0;
00142 }
00143 }
00144 }
00145
00146
00147 int Ifpack_SerialTriDiMatrix::Reshape(int NumRows, int NumCols) {
00148 if(NumRows < 0 || NumCols < 0)
00149 return(-1);
00150 if(NumRows != NumCols)
00151 return(-1);
00152
00153 double* A_tmp = 0;
00154 const int newsize = (N_ == 1)? 1 : 4*(N_-1);
00155 if(newsize > 0) {
00156
00157 A_tmp = new double[newsize];
00158 for (int k = 0; k < newsize; k++)
00159 A_tmp[k] = 0.0;
00160 if (A_ != 0)
00161 CopyMat(A_, N_, A_tmp, NumRows);
00162
00163 }
00164 CleanupData();
00165 N_ = NumCols;
00166 if(newsize > 0) {
00167 A_ = A_tmp;
00168 A_Copied_ = true;
00169 }
00170
00171 DL_ = A_;
00172 D_ = A_+(N_-1);
00173 DU_ = D_+N_;
00174 DU2_ = DU_+(N_-1);
00175
00176 return(0);
00177 }
00178
00179 int Ifpack_SerialTriDiMatrix::Shape(int NumRowCol) {
00180 if(NumRowCol < 0 || NumRowCol < 0)
00181 return(-1);
00182
00183 CleanupData();
00184 N_ = NumRowCol;
00185 LDA_ = N_;
00186 const int newsize = (N_ == 1)? 1 : 4*(N_-1);
00187 if(newsize > 0) {
00188 A_ = new double[newsize];
00189 for (int k = 0; k < newsize; k++)
00190 A_[k] = 0.0;
00191 A_Copied_ = true;
00192 }
00193
00194 DL_ = A_;
00195 D_ = A_+(N_-1);
00196 DU_ = D_+N_;
00197 DU2_ = DU_+(N_-1);
00198
00199 return(0);
00200 }
00201
00202 Ifpack_SerialTriDiMatrix::~Ifpack_SerialTriDiMatrix()
00203 {
00204
00205 CleanupData();
00206
00207 }
00208
00209 void Ifpack_SerialTriDiMatrix::CleanupData()
00210 {
00211 if (A_)
00212 delete [] A_;
00213 A_ = DL_ = D_ = DU_ = DU2_ = 0;
00214 A_Copied_ = false;
00215 N_ = 0;
00216 }
00217
00218 Ifpack_SerialTriDiMatrix& Ifpack_SerialTriDiMatrix::operator = (const Ifpack_SerialTriDiMatrix& Source) {
00219 if(this == &Source)
00220 return(*this);
00221 if((CV_ == View) && (Source.CV_ == View) && (A_ == Source.A_))
00222 return(*this);
00223
00224 if(std::strcmp(Label(), Source.Label()) != 0)
00225 throw ReportError("operator= type mismatch (lhs = " + std::string(Label()) +
00226 ", rhs = " + std::string(Source.Label()) + ").", -5);
00227
00228 if(Source.CV_ == View) {
00229 if(CV_ == Copy) {
00230 CleanupData();
00231 CV_ = View;
00232 }
00233 N_ = Source.N_;
00234 A_ = Source.A_;
00235 DL_ = Source.DL_;
00236 D_ = Source.D_;
00237 DU_ = Source.DU_;
00238 DU2_ = Source.DU2_;
00239 }
00240 else {
00241 if(CV_ == View) {
00242 CV_ = Copy;
00243 N_ = Source.N_;
00244 const int newsize = 4*N_ - 4;
00245 if(newsize > 0) {
00246 A_ = new double[newsize];
00247 DL_ = A_;
00248 D_ = A_+(N_-1);
00249 DU_ = D_+N_;
00250 DU2_ = DU_+(N_-1);
00251 A_Copied_ = true;
00252 }
00253 else {
00254 A_ = 0;
00255 DL_ = D_ = DU_ = DU2_ = 0;
00256 A_Copied_ = false;
00257 }
00258 }
00259 else {
00260 if(Source.N_ == N_) {
00261 N_ = Source.N_;
00262 }
00263 else {
00264 CleanupData();
00265 N_ = Source.N_;
00266 const int newsize = (N_ == 1)? 1 : 4*(N_-1);
00267 if(newsize > 0) {
00268 A_ = new double[newsize];
00269 DL_ = A_;
00270 D_ = A_+(N_-1);
00271 DU_ = D_+N_;
00272 DU2_ = DU_+(N_-1);
00273 A_Copied_ = true;
00274 }
00275 }
00276 }
00277 CopyMat(Source.A_, Source.N(), A_, N_);
00278 }
00279
00280 return(*this);
00281 }
00282
00283
00284
00285 bool Ifpack_SerialTriDiMatrix::operator==(const Ifpack_SerialTriDiMatrix& rhs) const
00286 {
00287 if (N_ != rhs.N_) return(false);
00288
00289 const double* A_tmp = A_;
00290 const double* rhsA = rhs.A_;
00291
00292 const int size = (N_ == 1)? 1 : 4*(N_-1);
00293
00294 for(int j=0; j<size; ++j) {
00295 if (std::abs(A_tmp[j] - rhsA[j]) > Epetra_MinDouble) {
00296 return(false);
00297 }
00298 }
00299
00300 return(true);
00301 }
00302
00303
00304 Ifpack_SerialTriDiMatrix& Ifpack_SerialTriDiMatrix::operator+= ( const Ifpack_SerialTriDiMatrix & Source) {
00305 if (N() != Source.N())
00306 throw ReportError("Column dimension of source = " + toString(Source.N()) +
00307 " is different than column dimension of target = " + toString(N()), -2);
00308
00309 CopyMat(Source.A(), Source.N(), A(), N(),true);
00310 return(*this);
00311 }
00312
00313 void Ifpack_SerialTriDiMatrix::CopyMat(const double* Source,
00314 int nrowcol,
00315 double* Target,
00316 int tN,
00317 bool add)
00318 {
00319 int lmax = EPETRA_MIN(nrowcol,tN);
00320 if (add) {
00321
00322 for(int j=0; j<lmax; ++j) {
00323 Target[(tN-1)+j] += Source[(nrowcol-1)+j];
00324 if(j<tN-1) {
00325 Target[j] += Source[j];
00326 Target[(tN-1)+tN + j] += Source[(nrowcol-1)+ nrowcol + j];
00327 }
00328 if(j<tN-2) Target[(tN-1)*2 + tN + j] += Source[ (nrowcol-1)*2 +nrowcol + j];
00329 }
00330 }
00331 else {
00332 for(int j=0; j<lmax; ++j) {
00333 Target[(tN-1)+j] = Source[(nrowcol-1)+j];
00334 if(j<tN-1) {
00335 Target[j] = Source[j];
00336 Target[(tN-1)+tN + j] = Source[(nrowcol-1)+ nrowcol + j];
00337 }
00338 if(j<tN-2) Target[(tN-1)*2 + tN + j] = Source[ (nrowcol-1)*2 +nrowcol + j];
00339 }
00340 }
00341 return;
00342 }
00343
00344 double Ifpack_SerialTriDiMatrix::NormOne() const {
00345 int i;
00346 double anorm = 0.0;
00347 double * ptr = A_;
00348 double sum=0.0;
00349
00350 const int size = (N_ == 1)? 1 : 4*(N_-1);
00351
00352 for (i=0; i<size; i++) sum += std::abs(*ptr++);
00353
00354 anorm = EPETRA_MAX(anorm, sum);
00355 UpdateFlops((double)size );
00356 return(anorm);
00357 }
00358
00359 double Ifpack_SerialTriDiMatrix::NormInf() const {
00360 return NormOne();
00361
00362 }
00363
00364 int Ifpack_SerialTriDiMatrix::Scale(double ScalarA) {
00365
00366 int i;
00367
00368 double * ptr = A_;
00369
00370 const int size = (N_ == 1)? 1 : 4*(N_-1);
00371
00372 for (i=0; i<size ; i++) { *ptr = ScalarA * (*ptr); ptr++; }
00373
00374 UpdateFlops((double)N_*(double)N_);
00375 return(0);
00376
00377 }
00378
00379
00380 int Ifpack_SerialTriDiMatrix::Multiply (char TransA, char TransB, double ScalarAB,
00381 const Ifpack_SerialTriDiMatrix& A_in,
00382 const Ifpack_SerialTriDiMatrix& B,
00383 double ScalarThis ) {
00384 throw ReportError("Ifpack_SerialTriDiMatrix::Multiply not implimented ",-2);
00385 return(-1);
00386
00387 }
00388
00389
00390
00391 int Ifpack_SerialTriDiMatrix::Random() {
00392
00393 Epetra_Util util;
00394 double* arrayPtr = A_;
00395 const int size = (N_ == 1)? 1 : 4*(N_-1);
00396 for(int j = 0; j < size ; j++) {
00397 *arrayPtr++ = util.RandomDouble();
00398 }
00399
00400 return(0);
00401 }
00402
00403 void Ifpack_SerialTriDiMatrix::Print(std::ostream& os) const {
00404 os <<" square format:"<<std::endl;
00405 if(! A_ ) {
00406 os <<" empty matrix "<<std::endl;
00407 return;
00408 }
00409 for(int i=0 ; i < N_ ; ++i) {
00410 for(int j=0 ; j < N_ ; ++j) {
00411 if ( j >= i-1 && j <= i+1) {
00412 os << (*this)(i,j)<<" ";
00413 }
00414 else
00415 os <<". ";
00416 }
00417 os << std::endl;
00418 }
00419 }