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  mutable std::set<T> boundary_idxs;
73 
75  virtual ~abstract_matrix() = default;
76 
87  virtual inline void init(T iNRows, T iNCols, T ilrows, T ilcols,
88  T loc_offset, T mxent)
89  {
90  this->NRows = iNRows;
91  this->NCols = iNCols;
92  this->lsize = ilrows;
93  this->start = loc_offset;
94  this->stop = this->start + this->lsize;
95  }
96 
106  inline void init(const meshdata<mesh_int_t, mesh_real_t> & imesh,
107  const T irow_dpn,
108  const T icol_dpn,
109  const T max_edges)
110  {
111  mesh = &imesh;
112  this->row_dpn = irow_dpn;
113  this->col_dpn = icol_dpn;
114 
115  int rank;
116  MPI_Comm_rank(mesh->comm, &rank);
117 
118  T M = mesh->pl.num_global_idx() * this->row_dpn;
119  T N = mesh->pl.num_global_idx() * this->col_dpn;
120  T m = mesh->pl.num_algebraic_idx() * this->row_dpn;
121  T n = mesh->pl.num_algebraic_idx() * this->col_dpn;
122 
123  T nmax = max_edges;
124  if(max_edges < 0) nmax = max_nodal_edgecount(*mesh);
125 
126  T loc_offset = mesh->pl.algebraic_layout()[rank]*this->row_dpn;
127 
128  init(M, N, m, n, loc_offset, nmax*this->col_dpn);
129  zero();
130  }
131 
138  {
139  return this->mesh;
140  }
141 
147  inline int dpn_row() const { return this->row_dpn; }
148 
154  inline int dpn_col() const { return this->col_dpn; }
155 
159  virtual void zero() = 0;
160 
167  virtual void mult(const abstract_vector<T,S> & x, abstract_vector<T,S> & b) const = 0;
168 
176  virtual void mult_LR(const abstract_vector<T, S>& L, const abstract_vector<T, S>& R) = 0;
177 
183  virtual void diag_add(const abstract_vector<T, S>& diag) = 0;
184 
190  virtual void get_diagonal(abstract_vector<T, S>& vec) const = 0;
191 
195  virtual void finish_assembly() = 0;
196 
202  virtual void scale(S s) = 0;
203 
211  virtual void add_scaled_matrix(const abstract_matrix<T, S>& A, const S s, const bool same_nnz) = 0;
212 
218  virtual void duplicate(const abstract_matrix<T,S>& M) = 0;
219 
230  virtual void set_values(const vector<T>& row_idx, const vector<T>& col_idx, const vector<S>& vals, bool add) = 0;
231 
242  virtual void set_values(const vector<T> & row_idx, const vector<T> & col_idx,
243  const S* vals, bool add) = 0;
244 
253  virtual void set_value(T row_idx, T col_idx, S val, bool add) = 0;
254 
265  inline void get_values(const vector<T> & row_idx, const vector<T> & col_idx,
266  vector<S> & values) const {
267  assert(row_idx.size() == col_idx.size() == values.size());
268 
269  for (int i = 0; i < row_idx.size(); i++)
270  values[i] = get_value(row_idx[i], col_idx[i]);
271  }
272 
281  virtual S get_value(SF_int row_idx, SF_int col_idx) const = 0;
282 
288  virtual void write(const char* filename) const = 0;
289 
290 
301  inline bool equals(const abstract_matrix<T,S> & rhs) const
302  {
303  if (NRows != rhs.NRows or NCols != rhs.NCols)
304  return false;
305 
306  bool equal = true;
307  for (size_t row = 0; row < NRows; row++)
308  for (size_t col = 0; col < NCols; col++)
309  if (fabs(get_value(row, col) - rhs.get_value(row, col)) > 0.0001)
310  equal = false;
311 
312  return equal;
313  }
314 
320  inline std::string to_string() const
321  {
322  std::ostringstream stream;
323  stream << "matrix (" << this->NRows << " x " << this->NCols << ") [\n";
324 
325  for (auto row = 0; row < this->NRows; row++) {
326  stream << " [";
327  for (auto col = 0; col < this->NCols; col++) {
328  if (col > 0) stream << ", ";
329  stream << get_value(row, col);
330  }
331  stream << "]\n";
332  }
333  stream << "]";
334 
335  return stream.str();
336  }
337 };
338 
339 } // namespace SF
340 
341 
342 
343 #endif // _SF_ABSTRACT_MATRIX_H
Basic containers.
std::int32_t SF_int
Use the general std::int32_t as int type.
Definition: SF_globals.h:37
Classes and algorithms related to the layout of distributed meshes.
virtual void set_values(const vector< T > &row_idx, const vector< T > &col_idx, const S *vals, bool add)=0
std::string to_string() const
const meshdata< mesh_int_t, mesh_real_t > * mesh_ptr() const
virtual void mult(const abstract_vector< T, S > &x, abstract_vector< T, S > &b) const =0
virtual void scale(S s)=0
void get_values(const vector< T > &row_idx, const vector< T > &col_idx, vector< S > &values) const
virtual void finish_assembly()=0
int NRows
global number of rows
virtual void zero()=0
std::set< T > boundary_idxs
int lsize
size of local matrix (#locally stored rows)
virtual void get_diagonal(abstract_vector< T, S > &vec) const =0
int stop
stio row index of local matrix portion
int NCols
global number of cols
virtual void mult_LR(const abstract_vector< T, S > &L, const abstract_vector< T, S > &R)=0
virtual void init(T iNRows, T iNCols, T ilrows, T ilcols, T loc_offset, T mxent)
virtual void set_values(const vector< T > &row_idx, const vector< T > &col_idx, const vector< S > &vals, bool add)=0
void init(const meshdata< mesh_int_t, mesh_real_t > &imesh, const T irow_dpn, const T icol_dpn, const T max_edges)
virtual S get_value(SF_int row_idx, SF_int col_idx) const =0
virtual void duplicate(const abstract_matrix< T, S > &M)=0
virtual void set_value(T row_idx, T col_idx, S val, bool add)=0
int start
start row index of local matrix portion
virtual void add_scaled_matrix(const abstract_matrix< T, S > &A, const S s, const bool same_nnz)=0
virtual void write(const char *filename) const =0
const meshdata< mesh_int_t, mesh_real_t > * mesh
pointer to the associated mesh
virtual ~abstract_matrix()=default
virtual void diag_add(const abstract_vector< T, S > &diag)=0
bool equals(const abstract_matrix< T, S > &rhs) const
overlapping_layout< T > pl
nodal parallel layout
Definition: SF_container.h:429
MPI_Comm comm
the parallel mesh is defined on a MPI world
Definition: SF_container.h:404
A vector storing arbitrary data.
Definition: SF_vector.h:43
size_t size() const
The current size of the vector.
Definition: SF_vector.h:104
Definition: dense_mat.hpp:34
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:608