openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
SF_abstract_matrix.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // openCARP is an open cardiac electrophysiology simulator.
3 //
4 // Copyright (C) 2020 openCARP project
5 //
6 // This program is licensed under the openCARP Academic Public License (APL)
7 // v1.0: You can use and redistribute it and/or modify it in non-commercial
8 // academic environments under the terms of APL as published by the openCARP
9 // project v1.0, or (at your option) any later version. Commercial use requires
10 // a commercial license (info@opencarp.org).
11 //
12 // This program is distributed without any warranty; see the openCARP APL for
13 // more details.
14 //
15 // You should have received a copy of the openCARP APL along with this program
16 // and can find it online: http://www.opencarp.org/license
17 // ----------------------------------------------------------------------------
18 
19 #ifndef _SF_ABSTRACT_MATRIX_H
20 #define _SF_ABSTRACT_MATRIX_H
21 
22 #include <mpi.h>
23 
24 #include "SF_abstract_vector.h"
25 #include "SF_container.h"
26 #include "SF_globals.h"
27 #include "SF_parallel_layout.h"
28 
29 namespace SF {
30 
31 
43 template <class T, class S>
45 {
46  protected:
48  abstract_matrix() : mesh(NULL),
49  NRows(0),
50  NCols(0),
51  row_dpn(0),
52  col_dpn(0),
53  lsize(0),
54  start(0),
55  stop(0)
56  {
57  }
58 
61 
62  int NRows;
63  int NCols;
64  int row_dpn;
65  int col_dpn;
66 
67  int lsize;
68  int start;
69  int stop;
70 
71  public:
72 
74  virtual ~abstract_matrix() = default;
75 
86  virtual inline void init(T iNRows, T iNCols, T ilrows, T ilcols,
87  T loc_offset, T mxent)
88  {
89  this->NRows = iNRows;
90  this->NCols = iNCols;
91  this->lsize = ilrows;
92  this->start = loc_offset;
93  this->stop = this->start + this->lsize;
94  }
95 
105  inline void init(const meshdata<mesh_int_t, mesh_real_t> & imesh,
106  const T irow_dpn,
107  const T icol_dpn,
108  const T max_edges)
109  {
110  mesh = &imesh;
111  this->row_dpn = irow_dpn;
112  this->col_dpn = icol_dpn;
113 
114  int rank;
115  MPI_Comm_rank(mesh->comm, &rank);
116 
117  T M = mesh->pl.num_global_idx() * this->row_dpn;
118  T N = mesh->pl.num_global_idx() * this->col_dpn;
119  T m = mesh->pl.num_algebraic_idx() * this->row_dpn;
120  T n = mesh->pl.num_algebraic_idx() * this->col_dpn;
121 
122  T nmax = max_edges;
123  if(max_edges < 0) nmax = max_nodal_edgecount(*mesh);
124 
125  T loc_offset = mesh->pl.algebraic_layout()[rank]*this->row_dpn;
126 
127  init(M, N, m, n, loc_offset, nmax*this->col_dpn);
128  zero();
129  }
130 
137  {
138  return this->mesh;
139  }
140 
146  inline int dpn_row() const { return this->row_dpn; }
147 
153  inline int dpn_col() const { return this->col_dpn; }
154 
158  virtual void zero() = 0;
159 
166  virtual void mult(const abstract_vector<T,S> & x, abstract_vector<T,S> & b) const = 0;
167 
175  virtual void mult_LR(const abstract_vector<T, S>& L, const abstract_vector<T, S>& R) = 0;
176 
182  virtual void diag_add(const abstract_vector<T, S>& diag) = 0;
183 
189  virtual void get_diagonal(abstract_vector<T, S>& vec) const = 0;
190 
194  virtual void finish_assembly() = 0;
195 
201  virtual void scale(S s) = 0;
202 
210  virtual void add_scaled_matrix(const abstract_matrix<T, S>& A, const S s, const bool same_nnz) = 0;
211 
217  virtual void duplicate(const abstract_matrix<T,S>& M) = 0;
218 
229  virtual void set_values(const vector<T>& row_idx, const vector<T>& col_idx, const vector<S>& vals, bool add) = 0;
230 
241  virtual void set_values(const vector<T> & row_idx, const vector<T> & col_idx,
242  const S* vals, bool add) = 0;
243 
252  virtual void set_value(T row_idx, T col_idx, S val, bool add) = 0;
253 
264  inline void get_values(const vector<T> & row_idx, const vector<T> & col_idx,
265  vector<S> & values) const {
266  assert(row_idx.size() == col_idx.size() == values.size());
267 
268  for (int i = 0; i < row_idx.size(); i++)
269  values[i] = get_value(row_idx[i], col_idx[i]);
270  }
271 
280  virtual S get_value(SF_int row_idx, SF_int col_idx) const = 0;
281 
287  virtual void write(const char* filename) const = 0;
288 
289 
300  inline bool equals(const abstract_matrix<T,S> & rhs) const
301  {
302  if (NRows != rhs.NRows or NCols != rhs.NCols)
303  return false;
304 
305  bool equal = true;
306  for (size_t row = 0; row < NRows; row++)
307  for (size_t col = 0; col < NCols; col++)
308  if (fabs(get_value(row, col) - rhs.get_value(row, col)) > 0.0001)
309  equal = false;
310 
311  return equal;
312  }
313 
319  inline std::string to_string() const
320  {
321  std::ostringstream stream;
322  stream << "matrix (" << this->NRows << " x " << this->NCols << ") [\n";
323 
324  for (auto row = 0; row < this->NRows; row++) {
325  stream << " [";
326  for (auto col = 0; col < this->NCols; col++) {
327  if (col > 0) stream << ", ";
328  stream << get_value(row, col);
329  }
330  stream << "]\n";
331  }
332  stream << "]";
333 
334  return stream.str();
335  }
336 };
337 
338 } // namespace SF
339 
340 
341 
342 #endif // _SF_ABSTRACT_MATRIX_H
const vector< T > & algebraic_layout() const
Getter function for the global algebraic node layout.
virtual void add_scaled_matrix(const abstract_matrix< T, S > &A, const S s, const bool same_nnz)=0
Definition: dense_mat.hpp:34
virtual void mult_LR(const abstract_vector< T, S > &L, const abstract_vector< T, S > &R)=0
int start
start row index of local matrix portion
int NCols
global number of cols
MPI_Comm comm
the parallel mesh is defined on a MPI world
Definition: SF_container.h:392
virtual void init(T iNRows, T iNCols, T ilrows, T ilcols, T loc_offset, T mxent)
virtual void duplicate(const abstract_matrix< T, S > &M)=0
overlapping_layout< T > pl
nodal parallel layout
Definition: SF_container.h:417
int NRows
global number of rows
Basic containers.
int stop
stio row index of local matrix portion
virtual S get_value(SF_int row_idx, SF_int col_idx) const =0
virtual void scale(S s)=0
bool equals(const abstract_matrix< T, S > &rhs) const
int lsize
size of local matrix (#locally stored rows)
virtual ~abstract_matrix()=default
const meshdata< mesh_int_t, mesh_real_t > * mesh
pointer to the associated mesh
virtual void mult(const abstract_vector< T, S > &x, abstract_vector< T, S > &b) const =0
virtual void write(const char *filename) const =0
virtual void set_values(const vector< T > &row_idx, const vector< T > &col_idx, const vector< S > &vals, bool add)=0
void get_values(const vector< T > &row_idx, const vector< T > &col_idx, vector< S > &values) const
virtual void zero()=0
int max_nodal_edgecount(const meshdata< T, S > &mesh)
Compute the maximum number of node-to-node edges for a mesh.
Definition: SF_container.h:596
const meshdata< mesh_int_t, mesh_real_t > * mesh_ptr() const
virtual void diag_add(const abstract_vector< T, S > &diag)=0
size_t size() const
The current size of the vector.
Definition: SF_vector.h:104
virtual void get_diagonal(abstract_vector< T, S > &vec) const =0
size_t num_global_idx() const
Retrieve the global number of indices.
virtual void finish_assembly()=0
A vector storing arbitrary data.
Definition: SF_vector.h:42
virtual void set_value(T row_idx, T col_idx, S val, bool add)=0
Classes and algorithms related to the layout of distributed meshes.
void init(const meshdata< mesh_int_t, mesh_real_t > &imesh, const T irow_dpn, const T icol_dpn, const T max_edges)
std::int32_t SF_int
Use the general std::int32_t as int type.
Definition: SF_globals.h:37
size_t num_algebraic_idx() const
Retrieve the number of local algebraic indices.
std::string to_string() const