sum_of_matrices.h
Go to the documentation of this file.
1 // LIC// ====================================================================
2 // LIC// This file forms part of oomph-lib, the object-oriented,
3 // LIC// multi-physics finite-element library, available
4 // LIC// at http://www.oomph-lib.org.
5 // LIC//
6 // LIC// Copyright (C) 2006-2023 Matthias Heil and Andrew Hazel
7 // LIC//
8 // LIC// This library is free software; you can redistribute it and/or
9 // LIC// modify it under the terms of the GNU Lesser General Public
10 // LIC// License as published by the Free Software Foundation; either
11 // LIC// version 2.1 of the License, or (at your option) any later version.
12 // LIC//
13 // LIC// This library is distributed in the hope that it will be useful,
14 // LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // LIC// Lesser General Public License for more details.
17 // LIC//
18 // LIC// You should have received a copy of the GNU Lesser General Public
19 // LIC// License along with this library; if not, write to the Free Software
20 // LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // LIC// 02110-1301 USA.
22 // LIC//
23 // LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 // LIC//
25 // LIC//====================================================================
26 #ifndef OOMPH_SUM_OF_MATRICES_H
27 #define OOMPH_SUM_OF_MATRICES_H
28 
29 
30 #include "mesh.h"
31 #include "matrices.h"
32 #include "Vector.h"
33 #include "oomph_utilities.h"
34 
35 #include <map>
36 
37 
38 namespace oomph
39 {
40  using namespace StringConversion;
41 
42  // =================================================================
43  /// Class to store bi-directional lookup between added matrix row/col
44  /// numbers to main matrix (SumOfMatrix) row/col numbers.
45  // =================================================================
47  {
48  public:
49  /// Default constructor
51 
52  /// Real constructor: construct lookup from node numbers in mesh and
53  /// global equation numbers. Useful for the case when the main matrix is
54  /// a Jacobian and the added matrix is a contribution only on a certain
55  /// mesh.
56  AddedMainNumberingLookup(const Mesh* mesh_pt, const unsigned& dof_index)
57  {
58  this->build(mesh_pt, dof_index);
59  }
60 
61  /// Construct lookup schemes from int array (HLib's format for this
62  /// data).
63  AddedMainNumberingLookup(const int* lookup_array, const unsigned& length)
64  {
65  this->build(lookup_array, length);
66  }
67 
68  /// Destructor
70 
71  /// Given a main matrix row/col number get the equivalent row/col
72  /// in the added matrix. Throw an error if not found.
73  unsigned main_to_added(const int& main) const
74  {
75  int result = unsafe_main_to_added(main);
76 #ifdef PARANOID
77  // If it's -1 then we failed to find it:
78  if (result == -1)
79  {
80  std::string err = "Main matrix row/col number " + to_string(main) +
81  " not found in lookup.";
82  throw OomphLibError(
83  err, OOMPH_EXCEPTION_LOCATION, OOMPH_CURRENT_FUNCTION);
84  }
85 
86  if (result < 0)
87  {
88  std::string err = "Something crazy went wrong here.";
89  throw OomphLibError(
90  err, OOMPH_EXCEPTION_LOCATION, OOMPH_CURRENT_FUNCTION);
91  }
92 #endif
93 
94  return unsigned(result);
95  }
96 
97  /// Given a main matrix row/col number get the equivalent row/col
98  /// in the added matrix. Return -1 if not found.
99  int unsafe_main_to_added(const int& main) const
100  {
101  // Find the entry
102  std::map<unsigned, unsigned>::const_iterator it =
103  Main_to_added_mapping.find(unsigned(main));
104 
105  // Check the entry existed, it not then return -1.
106  if (it == main_to_added_mapping_pt()->end())
107  {
108  return -1;
109  }
110  else
111  {
112  return it->second;
113  }
114  }
115 
116  /// Given a row/col number in the added matrix return the equivalent
117  /// row/col number in the main matrix.
118  unsigned added_to_main(const unsigned& added) const
119  {
120  return Added_to_main_mapping[added];
121  }
122 
123  /// Construct the lookup schemes given a mesh and the degree of freedom
124  /// to lookup main equation numbers for.
125  void build(const Mesh* mesh_pt, const unsigned& dof_index)
126  {
127  construct_added_to_main_mapping(mesh_pt, dof_index);
128  construct_reverse_mapping();
129  }
130 
131  /// Construct lookup schemes from int array (HLib's format for this
132  /// data).
133  void build(const int* lookup_array, const unsigned& length)
134  {
135 #ifdef PARANOID
136  // Check for negative entries just in case (since it's an integer
137  // array).
138  for (unsigned j = 0; j < length; j++)
139  {
140  if (lookup_array[j] < 0)
141  {
142  std::string err = "negative entry in lookup array!";
143  throw OomphLibError(
144  err, OOMPH_EXCEPTION_LOCATION, OOMPH_CURRENT_FUNCTION);
145  }
146  }
147 #endif
148 
149  // Copy array into mapping and generate the inverse lookup
150  Added_to_main_mapping.assign(lookup_array, lookup_array + length);
151  construct_reverse_mapping();
152  }
153 
154  /// Construct lookup using node vector
155  void build(const Vector<const Node*>& bem_lookup, const unsigned& dof_index)
156  {
157  const unsigned ni = bem_lookup.size();
158  Added_to_main_mapping.assign(ni, -1);
159 
160  for (unsigned i = 0; i < ni; i++)
161  {
162  Added_to_main_mapping[i] = bem_lookup[i]->eqn_number(dof_index);
163  }
164 
165  construct_reverse_mapping();
166  }
167 
168  /// Construct an identity map (mostly for testing).
169  void build_identity_map(const unsigned& n)
170  {
171  Added_to_main_mapping.assign(n, 0);
172  for (unsigned j = 0; j < n; j++)
173  {
174  Added_to_main_mapping[j] = j;
175  }
176  construct_reverse_mapping();
177  }
178 
179 
180  // Access functions
181  // ============================================================
182 
183  /// Const access function for mapping.
185  {
186  return &Added_to_main_mapping;
187  }
188 
189  /// Const access function for mapping.
190  const std::map<unsigned, unsigned>* main_to_added_mapping_pt() const
191  {
192  return &Main_to_added_mapping;
193  }
194 
195  private:
196  /// Set up the lookup from added matrix row/col to main matrix.
198  const unsigned& dof_index)
199  {
200  // Basically just copy from the node data.
201  Added_to_main_mapping.resize(mesh_pt->nnode());
202  for (unsigned nd = 0, nnode = mesh_pt->nnode(); nd < nnode; nd++)
203  {
204  Added_to_main_mapping[nd] = mesh_pt->node_pt(nd)->eqn_number(dof_index);
205  }
206  }
207 
208  /// Set up the main to added mapping using the added to main mapping.
210  {
211 #ifdef PARANOID
212  if (Added_to_main_mapping.size() == 0)
213  {
214  std::ostringstream error_msg;
215  error_msg << "Must set up Added_to_main_mapping first.";
216  throw OomphLibError(
217  error_msg.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
218  }
219 #endif
220 
221  // Clear old data
222  Main_to_added_mapping.clear();
223 
224  // Copy from Added_to_main_mapping with order reversed.
225  for (unsigned j = 0; j < Added_to_main_mapping.size(); j++)
226  {
227  Main_to_added_mapping.insert(
228  std::make_pair(Added_to_main_mapping[j], j));
229  }
230  }
231 
232  /// Mapping from added matrix row/col numbers to main matrix row/col
233  /// numbers.
235 
236  /// Mapping from main matrix row/col numbers to added matrix row/col
237  /// numbers. Note that we cannot use a vector here because the main
238  /// matrix rows/cols mapped onto are probably not contiguous. Access
239  /// times are O(log N) so if you need to iterate over all elements then
240  /// use the pointer access functions and use stl iterators properly.
241  std::map<unsigned, unsigned> Main_to_added_mapping;
242 
243  /// Inaccessible copy constructor
245 
246  /// Inaccessible assignment operator
247  void operator=(const AddedMainNumberingLookup& dummy) = delete;
248  };
249 
250 
251  //======================================================================
252  /// Class for a matrix of the form M = S + G + H + ... where S is the main
253  /// matrix and G,H etc. are matrices of size S or smaller. This may be useful
254  /// if, for example, G,H etc. are subblocks of M that must be stored in a
255  /// different format to S.
256 
257  /// Maps mut be provided which gives a map from the rows/cols of the main
258  /// matrix to the rows/cols of each of the added matrices.
259  //======================================================================
261  public Matrix<double, SumOfMatrices>
262  {
263  private:
264  /// Pointer to the matrix which we are adding the others to
266 
267  /// List of pointers to the matrices that are added to the main matrix
269 
270  /// List of maps between row numbers of the main matrix and the
271  /// added matrices.
273 
274  /// List of maps between col numbers of the main matrix and the
275  /// added matrices.
277 
278  /// Should we delete the sub matrices when destructor is called?
280 
281  /// Should we delete the main matrix when destructor is called?
282  /// Default is no.
284 
285  public:
286  /// Default constructor
288  : Main_matrix_pt(0),
289  Added_matrix_pt(0),
290  Row_map_pt(0),
291  Col_map_pt(0),
292  Should_delete_added_matrix(0),
293  Should_delete_main_matrix(0)
294  {
295  }
296 
297  /// Constructor taking a pointer to the main matrix as input.
299  : Main_matrix_pt(main_matrix_pt),
300  Added_matrix_pt(0),
301  Row_map_pt(0),
302  Col_map_pt(0),
303  Should_delete_added_matrix(0),
304  Should_delete_main_matrix(0)
305  {
306  }
307 
308  /// Broken copy constructor
309  SumOfMatrices(const SumOfMatrices& matrix) = delete;
310 
311  /// Broken assignment operator
312  void operator=(const SumOfMatrices&) = delete;
313 
314  /// Destructor: delete matrices as instructed by
315  /// Should_delete_added_matrix vector and Should_delete_main_matrix.
317  {
318  for (unsigned i_matrix = 0; i_matrix < Added_matrix_pt.size(); i_matrix++)
319  {
320  if (Should_delete_added_matrix[i_matrix] == 1)
321  {
322  delete Added_matrix_pt[i_matrix];
323  }
324  }
325 
326  if (Should_delete_main_matrix)
327  {
328  delete Main_matrix_pt;
329  }
330  }
331 
332  /// Access to the main matrix
334  {
335  return Main_matrix_pt;
336  }
338  {
339  return Main_matrix_pt;
340  }
341 
342  /// Set the main matrix to be deleted by the destructor of the
343  /// SumOfMatrices (default is to not delete it).
345  {
346  Should_delete_main_matrix = true;
347  }
348 
349 
350  /// Output the "bottom right" entry regardless of it being
351  /// zero or not (this allows automatic detection of matrix size in
352  /// e.g. matlab, python).
353  void output_bottom_right_zero_helper(std::ostream& outfile) const
354  {
355  int last_row = this->nrow() - 1;
356  int last_col = this->ncol() - 1;
357 
358  double last_value = operator()(last_row, last_col);
359 
360  if (last_value == 0.0)
361  {
362  outfile << last_row << " " << last_col << " " << 0.0 << std::endl;
363  }
364  }
365 
366 
367  /// Output the matrix in sparse format. Note that this is going to be
368  /// slow because we have to check every entry of every matrix for non-zeros.
369  void sparse_indexed_output_helper(std::ostream& outfile) const
370  {
371  for (unsigned long i = 0; i < nrow(); i++)
372  {
373  for (unsigned long j = 0; j < ncol(); j++)
374  {
375  double entry = operator()(i, j);
376  // Output if non-zero entry
377  if (entry != 0.0)
378  {
379  outfile << i << " " << j << " " << entry << std::endl;
380  }
381  }
382  }
383  }
384 
385 
386  /// Get a list of row/col indices and total entry for non-zeros in
387  /// the matrix. e.g. for use as input to other matrix classes. Warning this
388  /// is SLOW! for sparse matrices.
390  Vector<int>& col,
391  Vector<double>& values)
392  {
393  row.clear();
394  col.clear();
395  values.clear();
396 
397  for (int i = 0; i < int(nrow()); i++)
398  {
399  for (int j = 0; j < int(ncol()); j++)
400  {
401  double entry = operator()(i, j);
402  // Output if non-zero entry
403  if (entry != 0.0)
404  {
405  row.push_back(i);
406  col.push_back(j);
407  values.push_back(entry);
408  }
409  }
410  }
411  }
412 
413  /// Add a new matrix to the sum by giving a matrix pointer and a
414  /// mapping from the main matrix numbering to the added matrix's numbering.
415  void add_matrix(DoubleMatrixBase* added_matrix_pt_in,
416  const AddedMainNumberingLookup* main_to_added_rows_pt,
417  const AddedMainNumberingLookup* main_to_added_cols_pt,
418  bool should_delete_matrix = false)
419  {
420 #ifdef PARANOID
421  // Check that row mapping has correct size
422  if (main_to_added_rows_pt->main_to_added_mapping_pt()->size() >
423  added_matrix_pt_in->nrow())
424  {
425  throw OomphLibError(
426  "Row mapping size should be less than or equal to nrow (less than if "
427  "it is a sparse matrix and there are some empty rows).",
428  OOMPH_CURRENT_FUNCTION,
429  OOMPH_EXCEPTION_LOCATION);
430  }
431 
432  // Check that col mapping has correct size
433  if (main_to_added_cols_pt->main_to_added_mapping_pt()->size() >
434  added_matrix_pt_in->ncol())
435  {
436  throw OomphLibError(
437  "Col mapping size should be less than or equal to ncol (less than if "
438  "it is a sparse matrix and there are some empty cols).",
439  OOMPH_CURRENT_FUNCTION,
440  OOMPH_EXCEPTION_LOCATION);
441  }
442 #endif
443 #ifdef RANGE_CHECKING
444  // Check that all entries in the row mapping are "in range" for the
445  // main matrix.
446  const Vector<unsigned>* rowmap_pt =
447  main_to_added_rows_pt->added_to_main_mapping_pt();
448  unsigned max_row =
449  *std::max_element(rowmap_pt->begin(), rowmap_pt->end());
450  if (max_row > main_matrix_pt()->nrow())
451  {
452  std::string err =
453  "Trying to add a matrix with a mapping which specifices";
454  err += " a max row of " + to_string(max_row) + " but the main matrix ";
455  err += "only has " + to_string(main_matrix_pt()->nrow()) + " rows!";
456  throw OomphLibError(
457  err, OOMPH_EXCEPTION_LOCATION, OOMPH_CURRENT_FUNCTION);
458  }
459 
460  // Check that all entries in the row mapping are "in range" for the
461  // main matrix.
462  const Vector<unsigned>* colmap_pt =
463  main_to_added_cols_pt->added_to_main_mapping_pt();
464  unsigned max_col =
465  *std::max_element(colmap_pt->begin(), colmap_pt->end());
466  if (max_col > main_matrix_pt()->ncol())
467  {
468  std::string err =
469  "Trying to add a matrix with a mapping which specifices";
470  err += " a max col of " + to_string(max_col) + " but the main matrix ";
471  err += "only has " + to_string(main_matrix_pt()->ncol()) + " cols!";
472  throw OomphLibError(
473  err, OOMPH_EXCEPTION_LOCATION, OOMPH_CURRENT_FUNCTION);
474  }
475 #endif
476 
477  Added_matrix_pt.push_back(added_matrix_pt_in);
478  Row_map_pt.push_back(main_to_added_rows_pt);
479  Col_map_pt.push_back(main_to_added_cols_pt);
480  Should_delete_added_matrix.push_back(unsigned(should_delete_matrix));
481  }
482 
483  /// Access function for ith added matrix (main matrix not included in
484  /// numbering).
485  inline DoubleMatrixBase* added_matrix_pt(const unsigned& i) const
486  {
487  return Added_matrix_pt[i];
488  }
489 
490  /// Access to the maps
491  const AddedMainNumberingLookup* row_map_pt(const unsigned& i) const
492  {
493  return Row_map_pt[i];
494  }
495  const AddedMainNumberingLookup* col_map_pt(const unsigned& i) const
496  {
497  return Col_map_pt[i];
498  }
499 
500  /// Return the number of rows of the main matrix.
501  inline unsigned long nrow() const
502  {
503 #ifdef PARANOID
504  if (Main_matrix_pt == 0)
505  {
506  throw OomphLibError("Main_matrix_pt not set",
507  OOMPH_CURRENT_FUNCTION,
508  OOMPH_EXCEPTION_LOCATION);
509  }
510 #endif
511  return Main_matrix_pt->nrow();
512  }
513 
514  /// Return the number of columns of the main matrix.
515  inline unsigned long ncol() const
516  {
517 #ifdef PARANOID
518  if (Main_matrix_pt == 0)
519  {
520  throw OomphLibError("Main_matrix_pt not set",
521  OOMPH_CURRENT_FUNCTION,
522  OOMPH_EXCEPTION_LOCATION);
523  }
524 #endif
525  return Main_matrix_pt->ncol();
526  }
527 
528  /// Return the number of added matrices in the sum
529  inline unsigned n_added_matrix() const
530  {
531  return Added_matrix_pt.size();
532  }
533 
534  /// Multiply: just call multiply on each of the matrices and add up
535  /// the results (with appropriate bookeeping of the relative positions).
536  void multiply(const DoubleVector& x, DoubleVector& soln) const;
537 
538  /// Broken operator() because it does not make sense to return
539  /// anything by reference.
540  double& entry(const unsigned long& i, const unsigned long& j) const
541  {
542  throw OomphLibError(
543  "Broken write to entry: it does not make sense to write to a sum, you "
544  "must write to one of the component matrices.",
545  OOMPH_CURRENT_FUNCTION,
546  OOMPH_EXCEPTION_LOCATION);
547  }
548 
549  /// Access function to get the total value of entries in position
550  /// (i,j). Warning: this way of getting entries is far too slow to use
551  /// inside of loops.
552  double operator()(const unsigned long& i, const unsigned long& j) const
553  {
554  // Get contributions from all matrices
555  double sum = main_matrix_pt()->operator()(i, j);
556  for (unsigned i_matrix = 0; i_matrix < n_added_matrix(); i_matrix++)
557  {
558  int li = Row_map_pt[i_matrix]->unsafe_main_to_added(i);
559  int lj = Col_map_pt[i_matrix]->unsafe_main_to_added(j);
560 
561  // If the added matrix contributes to this entry then add it
562  if ((li != -1) && (lj != -1))
563  {
564  sum += added_matrix_pt(i_matrix)->operator()(li, lj);
565  }
566  }
567 
568  return sum;
569  }
570 
571  /// Dummy overload of a pure virtual function. I'm not sure how best
572  /// to implement this and I don't think I need it.
573  virtual void multiply_transpose(const DoubleVector& x,
574  DoubleVector& soln) const
575  {
576  std::ostringstream error_msg;
577  error_msg << "Function not yet implemented.";
578  throw OomphLibError(
579  error_msg.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
580 
581  // Possible implementations (not really thought through):
582  // - just call multiply transpose on submatrices?
583  // - do something funny with switching row and column maps?
584  }
585  };
586 
587 
588 } // namespace oomph
589 #endif
cstr elem_len * i
Definition: cfortran.h:603
Class to store bi-directional lookup between added matrix row/col numbers to main matrix (SumOfMatrix...
AddedMainNumberingLookup(const Mesh *mesh_pt, const unsigned &dof_index)
Real constructor: construct lookup from node numbers in mesh and global equation numbers....
const Vector< unsigned > * added_to_main_mapping_pt() const
Const access function for mapping.
unsigned main_to_added(const int &main) const
Given a main matrix row/col number get the equivalent row/col in the added matrix....
AddedMainNumberingLookup()
Default constructor.
void construct_reverse_mapping()
Set up the main to added mapping using the added to main mapping.
AddedMainNumberingLookup(const int *lookup_array, const unsigned &length)
Construct lookup schemes from int array (HLib's format for this data).
unsigned added_to_main(const unsigned &added) const
Given a row/col number in the added matrix return the equivalent row/col number in the main matrix.
Vector< unsigned > Added_to_main_mapping
Mapping from added matrix row/col numbers to main matrix row/col numbers.
AddedMainNumberingLookup(const AddedMainNumberingLookup &dummy)=delete
Inaccessible copy constructor.
int unsafe_main_to_added(const int &main) const
Given a main matrix row/col number get the equivalent row/col in the added matrix....
void build(const Mesh *mesh_pt, const unsigned &dof_index)
Construct the lookup schemes given a mesh and the degree of freedom to lookup main equation numbers f...
void operator=(const AddedMainNumberingLookup &dummy)=delete
Inaccessible assignment operator.
void build_identity_map(const unsigned &n)
Construct an identity map (mostly for testing).
void construct_added_to_main_mapping(const Mesh *mesh_pt, const unsigned &dof_index)
Set up the lookup from added matrix row/col to main matrix.
const std::map< unsigned, unsigned > * main_to_added_mapping_pt() const
Const access function for mapping.
void build(const Vector< const Node * > &bem_lookup, const unsigned &dof_index)
Construct lookup using node vector.
std::map< unsigned, unsigned > Main_to_added_mapping
Mapping from main matrix row/col numbers to added matrix row/col numbers. Note that we cannot use a v...
void build(const int *lookup_array, const unsigned &length)
Construct lookup schemes from int array (HLib's format for this data).
long & eqn_number(const unsigned &i)
Return the equation number of the i-th stored variable.
Definition: nodes.h:367
Abstract base class for matrices of doubles – adds abstract interfaces for solving,...
Definition: matrices.h:261
virtual unsigned long ncol() const =0
Return the number of columns of the matrix.
virtual unsigned long nrow() const =0
Return the number of rows of the matrix.
A vector in the mathematical sense, initially developed for linear algebra type applications....
Definition: double_vector.h:58
Abstract base class for matrices, templated by the type of object that is stored in them and the type...
Definition: matrices.h:74
A general mesh class.
Definition: mesh.h:67
unsigned long nnode() const
Return number of nodes in the mesh.
Definition: mesh.h:596
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Definition: mesh.h:436
An OomphLibError object which should be thrown when an run-time error is encountered....
Class for a matrix of the form M = S + G + H + ... where S is the main matrix and G,...
virtual void multiply_transpose(const DoubleVector &x, DoubleVector &soln) const
Dummy overload of a pure virtual function. I'm not sure how best to implement this and I don't think ...
SumOfMatrices(const SumOfMatrices &matrix)=delete
Broken copy constructor.
void output_bottom_right_zero_helper(std::ostream &outfile) const
Output the "bottom right" entry regardless of it being zero or not (this allows automatic detection o...
SumOfMatrices(DoubleMatrixBase *main_matrix_pt)
Constructor taking a pointer to the main matrix as input.
unsigned n_added_matrix() const
Return the number of added matrices in the sum.
DoubleMatrixBase * added_matrix_pt(const unsigned &i) const
Access function for ith added matrix (main matrix not included in numbering).
const AddedMainNumberingLookup * row_map_pt(const unsigned &i) const
Access to the maps.
unsigned long nrow() const
Return the number of rows of the main matrix.
SumOfMatrices()
Default constructor.
Vector< DoubleMatrixBase * > Added_matrix_pt
List of pointers to the matrices that are added to the main matrix.
Vector< const AddedMainNumberingLookup * > Col_map_pt
List of maps between col numbers of the main matrix and the added matrices.
double & entry(const unsigned long &i, const unsigned long &j) const
Broken operator() because it does not make sense to return anything by reference.
void set_delete_main_matrix()
Set the main matrix to be deleted by the destructor of the SumOfMatrices (default is to not delete it...
const DoubleMatrixBase * main_matrix_pt() const
Access to the main matrix.
double operator()(const unsigned long &i, const unsigned long &j) const
Access function to get the total value of entries in position (i,j). Warning: this way of getting ent...
void add_matrix(DoubleMatrixBase *added_matrix_pt_in, const AddedMainNumberingLookup *main_to_added_rows_pt, const AddedMainNumberingLookup *main_to_added_cols_pt, bool should_delete_matrix=false)
Add a new matrix to the sum by giving a matrix pointer and a mapping from the main matrix numbering t...
void operator=(const SumOfMatrices &)=delete
Broken assignment operator.
Vector< const AddedMainNumberingLookup * > Row_map_pt
List of maps between row numbers of the main matrix and the added matrices.
Vector< unsigned > Should_delete_added_matrix
Should we delete the sub matrices when destructor is called?
void get_as_indices(Vector< int > &row, Vector< int > &col, Vector< double > &values)
Get a list of row/col indices and total entry for non-zeros in the matrix. e.g. for use as input to o...
const AddedMainNumberingLookup * col_map_pt(const unsigned &i) const
unsigned long ncol() const
Return the number of columns of the main matrix.
bool Should_delete_main_matrix
Should we delete the main matrix when destructor is called? Default is no.
~SumOfMatrices()
Destructor: delete matrices as instructed by Should_delete_added_matrix vector and Should_delete_main...
void sparse_indexed_output_helper(std::ostream &outfile) const
Output the matrix in sparse format. Note that this is going to be slow because we have to check every...
DoubleMatrixBase * Main_matrix_pt
Pointer to the matrix which we are adding the others to.
DoubleMatrixBase *& main_matrix_pt()
A slight extension to the standard template vector class so that we can include "graceful" array rang...
Definition: Vector.h:58
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
std::string to_string(T object, unsigned float_precision=8)
Conversion function that should work for anything with operator<< defined (at least all basic types).
void multiply(const CRDoubleMatrix *matrix, const DoubleVector &x, DoubleVector &soln)
Function to perform a matrix-vector multiplication on a oomph-lib matrix and vector using Trilinos fu...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...