HermesCommon  3.0
epetra.cpp
Go to the documentation of this file.
1 // This file is part of HermesCommon
2 //
3 // Copyright (c) 2009 hp-FEM group at the University of Nevada, Reno (UNR).
4 // Email: hpfem-group@unr.edu, home page: http://www.hpfem.org/.
5 //
6 // Hermes2D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published
8 // by the Free Software Foundation; either version 2 of the License,
9 // or (at your option) any later version.
10 //
11 // Hermes2D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with Hermes2D; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "config.h"
23 #ifdef HAVE_EPETRA
24 #include "epetra.h"
25 #include "callstack.h"
26 
27 namespace Hermes
28 {
29  namespace Algebra
30  {
32  static Epetra_SerialComm seq_comm;
33 
34  template<typename Scalar>
35  EpetraMatrix<Scalar>::EpetraMatrix()
36  {
37  this->mat = nullptr;
38  this->mat_im = nullptr;
39  this->grph = nullptr;
40  this->std_map = nullptr;
41  this->owner = true;
42  }
43 
44  template<typename Scalar>
45  EpetraMatrix<Scalar>::EpetraMatrix(const EpetraMatrix<Scalar> &op) : SparseMatrix<Scalar>(op)
46  {
47  this->mat = new Epetra_CrsMatrix(*op.mat);
48  if (op.mat_im)
49  this->mat_im = new Epetra_CrsMatrix(*op.mat_im);
50  else
51  this->mat_im = nullptr;
52 
53  assert(mat != nullptr);
54  this->grph = new Epetra_CrsGraph(this->mat->Graph());
55  this->std_map = new Epetra_BlockMap(this->grph->Map());
56  this->owner = true;
57  }
58 
59  template<typename Scalar>
60  EpetraMatrix<Scalar>::EpetraMatrix(Epetra_RowMatrix &op)
61  {
62  this->mat = dynamic_cast<Epetra_CrsMatrix*>(&op);
63  assert(mat != nullptr);
64 
65  this->size = this->mat->NumGlobalRows();
66  this->grph = const_cast<Epetra_CrsGraph*>(&this->mat->Graph());
67  this->std_map = const_cast<Epetra_BlockMap*>(&this->grph->Map());
68  this->owner = false;
69  }
70 
71  template<typename Scalar>
72  EpetraMatrix<Scalar>::~EpetraMatrix()
73  {
74  free();
75  }
76 
77  template<typename Scalar>
78  void EpetraMatrix<Scalar>::prealloc(unsigned int n)
79  {
80  this->size = n;
81  // alloc trilinos structs
82  std_map = new Epetra_Map(n, 0, seq_comm);
83  grph = new Epetra_CrsGraph(Copy, *std_map, 0);
84  mat = new Epetra_CrsMatrix(Copy, *grph);
86  mat_im = new Epetra_CrsMatrix(Copy, *grph);
87  }
88 
89  template<typename Scalar>
90  void EpetraMatrix<Scalar>::pre_add_ij(unsigned int row, unsigned int col)
91  {
92  int col_to_pass = col;
93  grph->InsertGlobalIndices(row, 1, &col_to_pass);
94  }
95 
96  template<>
98  {
99  mat->FillComplete();
100  }
101 
102  template<>
104  {
105  mat->FillComplete();
106  mat_im->FillComplete();
107  }
108 
109  template<typename Scalar>
111  {
112  // create the matrix
113  grph->FillComplete();
114  if (mat)
115  delete mat;
116  mat = new Epetra_CrsMatrix(Copy, *grph);
117 
119  {
120  if (mat_im)
121  delete mat_im;
122  mat_im = new Epetra_CrsMatrix(Copy, *grph);
123  }
124  }
125 
126  template<>
128  {
129  if (owner)
130  {
131  delete mat; mat = nullptr;
132  delete grph; grph = nullptr;
133  delete std_map; std_map = nullptr;
134  }
135  }
136 
137  template<>
139  {
140  if (owner)
141  {
142  delete mat; mat = nullptr;
143  delete mat_im; mat_im = nullptr;
144  delete grph; grph = nullptr;
145  delete std_map; std_map = nullptr;
146  }
147  }
148 
149  template<typename Scalar>
150  Scalar EpetraMatrix<Scalar>::get(unsigned int m, unsigned int n) const
151  {
152  int n_entries = mat->NumGlobalEntries(m);
153  std::vector<double> vals(n_entries);
154  std::vector<int> idxs(n_entries);
155  mat->ExtractGlobalRowCopy(m, n_entries, n_entries, &vals[0], &idxs[0]);
156  for (int i = 0; i < n_entries; i++)
157  if (idxs[i] == (int)n)
158  return vals[i];
159  return 0.0;
160  }
161 
162  template<typename Scalar>
163  int EpetraMatrix<Scalar>::get_num_row_entries(unsigned int row)
164  {
165  return mat->NumGlobalEntries(row);
166  }
167 
168  template<typename Scalar>
169  void EpetraMatrix<Scalar>::extract_row_copy(unsigned int row, unsigned int len, unsigned int &n_entries, double *vals, unsigned int *idxs)
170  {
171  int* idxs_to_pass = malloc_with_check<EpetraMatrix<Scalar>, int>(len, this);
172  for (unsigned int i = 0; i < len; i++)
173  idxs_to_pass[i] = idxs[i];
174  int n_entries_to_pass = n_entries;
175  mat->ExtractGlobalRowCopy(row, len, n_entries_to_pass, vals, idxs_to_pass);
176  free_with_check(idxs_to_pass);
177  }
178 
179  template<>
181  {
182  mat->PutScalar(0.0);
183  }
184 
185  template<>
187  {
188  mat->PutScalar(0.0);
189  mat_im->PutScalar(0.0);
190  }
191 
192  template<>
193  void EpetraMatrix<double>::add(unsigned int m, unsigned int n, double v)
194  {
195  if (v != 0.0)
196  { // ignore zero values
197  int n_to_pass = n;
198 #pragma omp critical (EpetraMatrixAdd)
199  {
200  int ierr = mat->SumIntoMyValues(m, 1, &v, &n_to_pass);
201  if (ierr != 0)
202  throw Hermes::Exceptions::Exception("Failed to insert into Epetra matrix");
203  }
204  }
205  }
206 
207  template<>
208  void EpetraMatrix<std::complex<double> >::add(unsigned int m, unsigned int n, std::complex<double> v)
209  {
210  if (v != 0.0)
211  { // ignore zero values
212  double v_r = std::real<double>(v);
213  int n_to_pass = n;
214  int ierr = mat->SumIntoMyValues(m, 1, &v_r, &n_to_pass);
215  if (ierr != 0) throw Hermes::Exceptions::Exception("Failed to insert into Epetra matrix");
216  assert(ierr == 0);
217  double v_i = std::imag<double>(v);
218  ierr = mat_im->SumIntoMyValues(m, 1, &v_i, &n_to_pass);
219  assert(ierr == 0);
220  }
221  }
222 
223  template<>
224  void EpetraMatrix<std::complex<double> >::multiply_with_vector(std::complex<double>* vector_in, std::complex<double>*& vector_out, bool vector_out_initialized) const
225  {
226  SparseMatrix<std::complex<double> >::multiply_with_vector(vector_in, vector_out, vector_out_initialized);
227  }
228 
229  template<>
230  void EpetraMatrix<double>::multiply_with_vector(double* vector_in, double*& vector_out, bool vector_out_initialized) const
231  {
232  Epetra_Vector x(View, mat->OperatorDomainMap(), vector_in);
233  Epetra_Vector y(mat->OperatorRangeMap());
234  mat->Multiply(false, x, y);
235  y.ExtractCopy(vector_out);
236  }
237 
238  template<typename Scalar>
239  void EpetraMatrix<Scalar>::add(unsigned int m, unsigned int n, Scalar *mat, int *rows, int *cols, const int size)
240  {
241  for (unsigned int i = 0; i < m; i++) // rows
242  for (unsigned int j = 0; j < n; j++) // cols
243  if (rows[i] >= 0 && cols[j] >= 0) // not Dir. dofs.
244  add(rows[i], cols[j], mat[i * size + j]);
245  }
246 
247  template<>
249  {
250  mat->Scale(value);
251  }
252 
253  template<>
254  void EpetraMatrix<std::complex<double> >::multiply_with_Scalar(std::complex<double> value)
255  {
256  // TODO
257  }
258 
259  template<typename Scalar>
261  {
262  EpetraMatrix<Scalar>* ep_mat = dynamic_cast<EpetraMatrix<Scalar>*>(mat);
263  assert(ep_mat);
264 
265  EpetraExt::MatrixMatrix::Add(*ep_mat->mat, false, 1.0, *this->mat, 1.0);
266  if (this->mat_im && ep_mat->mat_im)
267  EpetraExt::MatrixMatrix::Add(*ep_mat->mat_im, false, 1.0, *this->mat_im, 1.0);
268  }
269 
270  template<>
271  void EpetraMatrix<double>::export_to_file(const char *filename, const char *var_name, MatrixExportFormat fmt, char* number_format)
272  {
273  FILE* file;
274  switch (fmt)
275  {
276  case EXPORT_FORMAT_MATLAB_SIMPLE:
278  file = fopen(filename, "w");
279  EpetraExt::RowMatrixToHandle(file, *this->mat);
280  fclose(file);
281  default:
282  throw Exceptions::MethodNotImplementedException("EpetraMatrix<double>::export_to_file");
283  }
284  }
285 
286  template<>
287  void EpetraMatrix<std::complex<double> >::export_to_file(const char *filename, const char *var_name, MatrixExportFormat fmt, char* number_format)
288  {
289  throw Exceptions::MethodNotImplementedException("EpetraMatrix<double>::export_to_file");
290  }
291 
292  template<typename Scalar>
293  unsigned int EpetraMatrix<Scalar>::get_matrix_size() const
294  {
295  return this->size;
296  }
297 
298  template<typename Scalar>
300  {
301  return mat->NumGlobalNonzeros() / ((double)this->size*this->size);
302  }
303 
304  template<typename Scalar>
305  unsigned int EpetraMatrix<Scalar>::get_nnz() const
306  {
307  return mat->NumGlobalNonzeros();
308  }
309 
310  template<typename Scalar>
312  {
313  this->std_map = nullptr;
314  this->vec = nullptr;
315  this->vec_im = nullptr;
316  this->size = 0;
317  this->owner = true;
318  }
319 
320  template<typename Scalar>
321  EpetraVector<Scalar>::EpetraVector(const Epetra_Vector &v)
322  {
323  this->vec = (Epetra_Vector *)&v;
324  this->vec_im = nullptr;
325  this->std_map = (Epetra_BlockMap *)&v.Map();
326  this->size = v.MyLength();
327  this->owner = false;
328  }
329 
330  template<typename Scalar>
331  EpetraVector<Scalar>::~EpetraVector()
332  {
333  if (owner) free();
334  }
335 
336  template<typename Scalar>
337  void EpetraVector<Scalar>::alloc(unsigned int n)
338  {
339  if (this->owner)
340  {
341  free();
342  this->size = n;
343  std_map = new Epetra_Map(this->size, 0, seq_comm);
344  vec = new Epetra_Vector(*std_map);
345  vec_im = new Epetra_Vector(*std_map);
346  }
347  else
348  assert(this->get_size() == n);
349  zero();
350  }
351 
352  template<typename Scalar>
354  {
355  for (unsigned int i = 0; i < this->size; i++) (*vec)[i] = 0.0;
356  if (vec_im)
357  for (unsigned int i = 0; i < this->size; i++) (*vec_im)[i] = 0.0;
358  }
359 
360  template<typename Scalar>
362  {
363  for (unsigned int i = 0; i < this->size; i++)
364  (*vec)[i] *= -1.;
365  for (unsigned int i = 0; i < this->size; i++)
366  (*vec_im)[i] *= -1.;
367  return this;
368  }
369 
370  template<typename Scalar>
372  {
373  EpetraVector<Scalar>* new_vector = new EpetraVector<Scalar>();
374  new_vector->size = this->get_size();
375 
376  new_vector->vec = new Epetra_Vector(*this->vec);
377  new_vector->std_map = new Epetra_BlockMap(*this->std_map);
378  new_vector->vec_im = new Epetra_Vector(*this->vec_im);
379 
380  return new_vector;
381  }
382 
383  template<typename Scalar>
385  {
386  if (this->owner)
387  {
388  delete std_map; std_map = nullptr;
389  delete vec; vec = nullptr;
390  delete vec_im; vec_im = nullptr;
391  this->size = 0;
392  }
393  }
394 
395  template<>
396  void EpetraVector<double>::set(unsigned int idx, double y)
397  {
398  (*vec)[idx] = y;
399  }
400 
401  template<>
402  void EpetraVector<std::complex<double> >::set(unsigned int idx, std::complex<double> y)
403  {
404  (*vec)[idx] = std::real(y);
405  (*vec_im)[idx] = std::imag(y);
406  }
407 
408  template<>
409  void EpetraVector<double>::add(unsigned int idx, double y)
410  {
411  (*vec)[idx] += y;
412  }
413 
414  template<>
415  void EpetraVector<std::complex<double> >::add(unsigned int idx, std::complex<double> y)
416  {
417  (*vec)[idx] += std::real(y);
418  (*vec_im)[idx] += std::imag(y);
419  }
420 
421  template<typename Scalar>
422  void EpetraVector<Scalar>::add(unsigned int n, unsigned int *idx, Scalar *y)
423  {
424  for (unsigned int i = 0; i < n; i++)
425  add(idx[i], y[i]);
426  }
427 
428  template<typename Scalar>
429  Scalar EpetraVector<Scalar>::get(unsigned int idx) const
430  {
431  return (*vec)[idx];
432  }
433 
434  template<typename Scalar>
435  void EpetraVector<Scalar>::extract(Scalar *v) const
436  {
438  vec->ExtractCopy((double *)v);
439  }
440 
441  template<typename Scalar>
442  void EpetraVector<Scalar>::export_to_file(const char *filename, const char *var_name, MatrixExportFormat fmt, char* number_format)
443  {
444  switch (fmt)
445  {
447  EpetraExt::VectorToMatrixMarketFile(filename, *this->vec);
448  return;
450  case EXPORT_FORMAT_MATLAB_SIMPLE:
452  EpetraExt::VectorToMatlabFile(filename, *this->vec);
453  return;
454  }
455  }
456 
457  template class HERMES_API EpetraMatrix < double > ;
458  template class HERMES_API EpetraMatrix < std::complex<double> > ;
459  template class HERMES_API EpetraVector < double > ;
460  template class HERMES_API EpetraVector < std::complex<double> > ;
461  }
462 }
463 #endif
General namespace for the Hermes library.
virtual void free()
free the memory associated with stiffness matrix
virtual void finish()
Finish manipulation with matrix (called before solving)
virtual void free()
free the memory
Definition: epetra.cpp:384
Exception interface Basically a std::exception, but with a constructor with string and with print_msg...
Definition: exceptions.h:49
General (abstract) vector representation in Hermes.
virtual void zero()
Zero the vector.
Definition: epetra.cpp:353
virtual void add(unsigned int m, unsigned int n, Scalar v)
virtual Scalar get(unsigned int m, unsigned int n) const
Definition: epetra.cpp:150
General (abstract) sparse matrix representation in Hermes.
virtual void alloc()
allocate the memory for stiffness matrix
Definition: epetra.cpp:110
MatrixExportFormat
Format of file matrix and vector output.
virtual void alloc(unsigned int ndofs)
Definition: epetra.cpp:337
Plain ascii file lines contains row column and value.
virtual void set(unsigned int idx, Scalar y)
virtual Scalar get(unsigned int idx) const
Definition: epetra.cpp:429
virtual void prealloc(unsigned int n)
Definition: epetra.cpp:78
File containing functionality for investigating call stack.
virtual void add_sparse_matrix(SparseMatrix< Scalar > *mat)
Definition: epetra.cpp:260
virtual double get_fill_in() const
Get fill-in.
Definition: epetra.cpp:299
virtual void pre_add_ij(unsigned int row, unsigned int col)
Definition: epetra.cpp:90
Epetra_Vector * vec_im
Imaginary part of the vector, vec holds the real part.
Definition: epetra.h:134
virtual Vector< Scalar > * change_sign()
Multiply by minus one.
Definition: epetra.cpp:361
virtual void add(unsigned int idx, Scalar y)
EpetraMatrix and EpetraVector storage classes for Amesos, AztecOO, ... .
virtual void extract(Scalar *v) const
Definition: epetra.cpp:435
Epetra_CrsMatrix * mat_im
Imaginary part of the matrix, mat holds the real part.
Definition: epetra.h:98
Vector< Scalar > * duplicate() const
Duplicates a matrix (including allocation).
Definition: epetra.cpp:371
virtual void zero()
Zero the matrix.
virtual unsigned int get_nnz() const
Definition: epetra.cpp:305
Matrix Market which can be read by pysparse library.
virtual void multiply_with_Scalar(Scalar value)
Multiply with a Scalar.
virtual void multiply_with_vector(Scalar *vector_in, Scalar *&vector_out, bool vector_out_initialized=false) const
Multiply with a vector.
virtual void export_to_file(const char *filename, const char *var_name, MatrixExportFormat fmt, char *number_format="%lf")
Method is not overriden and should be.
Definition: exceptions.h:212
unsigned int size
size of vector
Definition: vector.h:111
virtual void export_to_file(const char *filename, const char *var_name, MatrixExportFormat fmt, char *number_format="%lf")
Definition: epetra.cpp:442