FEI  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fei_AztecDMSR_Matrix.hpp
1 /*
2 // @HEADER
3 // ************************************************************************
4 // FEI: Finite Element Interface to Linear Solvers
5 // Copyright (2005) Sandia Corporation.
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the
8 // U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Alan Williams (william@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 */
42 
43 #ifndef _AztecDMSR_Matrix_h_
44 #define _AztecDMSR_Matrix_h_
45 
46 #ifdef HAVE_FEI_AZTECOO
47 
48 
49 //
50 // This class is a wrapper for the Aztec DMSR matrix data structure.
51 //
52 // Important usage notes:
53 //
54 // * The 'oneBased' argument to the constructor indicates whether the
55 // matrix should use 1-based indices (row numbers and column indices) in
56 // the input and output arguments to its interfaces (e.g., getRow),
57 // with the exception of the update list -- keep reading.
58 // 'oneBased' should be 1 for 1-based indices, 0 for 0-based.
59 // Here's the confusing part -- the update list should contain 0-based
60 // indices, regardless of the value of 'oneBased'. That's because the
61 // update list gets used internally by Aztec functions that only work
62 // in 0-based numbers.
63 //
64 // * The 'rowLengths' array, input argument to the configure function,
65 // must contain the lengths of each row, *NOT* including the
66 // coefficient on the diagonal.
67 //
68 #include <az_aztec.h>
69 #include <fei_SharedPtr.hpp>
70 #include <fei_Aztec_Map.hpp>
71 #include "fei_iostream.hpp"
72 #include "fei_fstream.hpp"
73 #include "fei_sstream.hpp"
74 
75 namespace fei_trilinos {
76 
77 class Aztec_LSVector;
78 
79 class AztecDMSR_Matrix {
80 
81  public:
82  // Constructor.
83  AztecDMSR_Matrix(fei::SharedPtr<Aztec_Map> map);
84 
85  //Copy constructor
86  AztecDMSR_Matrix(const AztecDMSR_Matrix& src);
87 
88  virtual ~AztecDMSR_Matrix ();
89 
90  // Mathematical functions.
91  void matvec(const Aztec_LSVector& x, Aztec_LSVector& y) const;
92 
93  void put(double s);
94  void getDiagonal(Aztec_LSVector& diagVector) const;
95 
96  fei::SharedPtr<Aztec_Map> getAztec_Map() const {return(amap_);};
97 
98  int rowLength(int row) const;
99 
100  // ... to read matrix.
101  void getRow(int row, int& length, double *coefs, int *colInd) const;
102  void getRow(int row, int& length, double *coefs) const;
103  void getRow(int row, int& length, int *colInd) const;
104 
106  int setDiagEntry(int row, double value);
107 
109  double getDiagEntry(int row) const;
110 
111  // ... to write matrix.
112  int putRow(int row, int len, const double *coefs,
113  const int *colInd);
114 
115  int sumIntoRow(int numRows, const int* rows,
116  int numCols, const int* cols,
117  const double* const* coefs);
118 
119  int sumIntoRow(int row, int len, const double *coefs,
120  const int *colInd);
121 
122  int addScaledMatrix(double scalar, const AztecDMSR_Matrix& source);
123 
124  void scale(double scalar);
125 
128  int getOffDiagRowPointers(int row, int*& colIndices, double*& coefs,
129  int& offDiagRowLength);
130 
131  void allocate(int *rowLengths);
132 
133  //inform about structure, including column-indices, so that val and bindx
134  //can be allocated *and* so that bindx can be populated.
135  void allocate(int *rowLengths, const int* const* colIndices);
136 
137  //inform that data fill is complete, so AZ_transform can be called.
138  void fillComplete();
139 
140  bool isFilled() const {return(isFilled_);};
141  void setFilled(bool flag) {isFilled_ = flag;};
142  bool isAllocated() const {return(isAllocated_);};
143  void setAllocated(bool flag) {isAllocated_ = flag;};
144 
145  void copyStructure(AztecDMSR_Matrix& source);
146 
147  bool readFromFile(const char *filename);
148  bool writeToFile(const char *fileName) const;
149  bool rowMax() const {return true;};
150  double rowMax(int row) const;
151 
152  int getNumNonZeros() {return(nnzeros_);};
153 
154  double* getBeginPointer() { return val; }
155 
156  int getOffset(int row, int col)
157  {
158  int localRow;
159  if (!amap_->inUpdate(row,localRow)){
160  std::ostringstream oss;
161  oss << "row "<<row<<" not found";
162  std::string str = oss.str();
163  throw std::runtime_error(str.c_str());
164  }
165 
166  if (row == col) return localRow;
167 
168  int* row_ptr = &bindx[bindx[localRow]];
169  int* end_row = &bindx[bindx[localRow+1]];
170 
171  int col_offset = 0;
172  for(; row_ptr != end_row; ++row_ptr) {
173  if (amap_->getTransformedEqn(*row_ptr) == col) break;
174  ++col_offset;
175  }
176  if (row_ptr == end_row){
177  FEI_OSTRINGSTREAM osstr;
178  osstr << "Col "<<col << " not found for row "<<row;
179  throw std::runtime_error(osstr.str());
180  }
181  return bindx[localRow] + col_offset;
182  }
183 
184  //Aztec-specific functions:
185 
186  AZ_MATRIX* getAZ_MATRIX_PTR() {return(Amat_);};
187 
188  private:
189  void messageAbort(const char* mesg);
190  int insert(int item, int offset, int* list, int& len, int allocLen);
191  int insert(double item, int offset, double* list, int& len, int allocLen);
192  void expand_array(int*& array, int& arraylen, int newlen);
193  void expand_array(double*& array, int& arraylen, int newlen);
194 
195  bool isFilled_;
196  bool isAllocated_;
197 
198  int localOffset_;
199  int localSize_;
200 
202 
203  AZ_MATRIX* Amat_;
204 
205  bool arraysAllocated_;
206  double *val;
207  int *bindx;
208  int *rowLengths_;
209  int nnzeros_; //val and bindx are of length nnzeros_+1
210 
211  int N_update_;
212 
213  int* tmp_array_;
214  int tmp_array_len_;
215  double* dtmp_array_;
216  int dtmp_array_len_;
217 
218  bool azTransformed_;
219 };
220 
221 }//namespace fei_trilinos
222 
223 #endif //HAVE_FEI_AZTECOO
224 
225 #endif