26 #ifndef OOMPH_SUM_OF_MATRICES_H
27 #define OOMPH_SUM_OF_MATRICES_H
40 using namespace StringConversion;
58 this->build(mesh_pt, dof_index);
65 this->build(lookup_array, length);
75 int result = unsafe_main_to_added(main);
81 " not found in lookup.";
83 err, OOMPH_EXCEPTION_LOCATION, OOMPH_CURRENT_FUNCTION);
88 std::string err =
"Something crazy went wrong here.";
90 err, OOMPH_EXCEPTION_LOCATION, OOMPH_CURRENT_FUNCTION);
94 return unsigned(result);
102 std::map<unsigned, unsigned>::const_iterator it =
103 Main_to_added_mapping.find(
unsigned(main));
106 if (it == main_to_added_mapping_pt()->end())
120 return Added_to_main_mapping[added];
125 void build(
const Mesh* mesh_pt,
const unsigned& dof_index)
127 construct_added_to_main_mapping(mesh_pt, dof_index);
128 construct_reverse_mapping();
133 void build(
const int* lookup_array,
const unsigned& length)
138 for (
unsigned j = 0; j < length; j++)
140 if (lookup_array[j] < 0)
142 std::string err =
"negative entry in lookup array!";
144 err, OOMPH_EXCEPTION_LOCATION, OOMPH_CURRENT_FUNCTION);
150 Added_to_main_mapping.assign(lookup_array, lookup_array + length);
151 construct_reverse_mapping();
157 const unsigned ni = bem_lookup.size();
158 Added_to_main_mapping.assign(ni, -1);
160 for (
unsigned i = 0;
i < ni;
i++)
162 Added_to_main_mapping[
i] = bem_lookup[
i]->eqn_number(dof_index);
165 construct_reverse_mapping();
171 Added_to_main_mapping.assign(n, 0);
172 for (
unsigned j = 0; j < n; j++)
174 Added_to_main_mapping[j] = j;
176 construct_reverse_mapping();
186 return &Added_to_main_mapping;
192 return &Main_to_added_mapping;
198 const unsigned& dof_index)
201 Added_to_main_mapping.resize(mesh_pt->
nnode());
202 for (
unsigned nd = 0, nnode = mesh_pt->
nnode(); nd < nnode; nd++)
212 if (Added_to_main_mapping.size() == 0)
214 std::ostringstream error_msg;
215 error_msg <<
"Must set up Added_to_main_mapping first.";
217 error_msg.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
222 Main_to_added_mapping.clear();
225 for (
unsigned j = 0; j < Added_to_main_mapping.size(); j++)
227 Main_to_added_mapping.insert(
228 std::make_pair(Added_to_main_mapping[j], j));
261 public Matrix<double, SumOfMatrices>
292 Should_delete_added_matrix(0),
293 Should_delete_main_matrix(0)
299 : Main_matrix_pt(main_matrix_pt),
303 Should_delete_added_matrix(0),
304 Should_delete_main_matrix(0)
318 for (
unsigned i_matrix = 0; i_matrix < Added_matrix_pt.size(); i_matrix++)
320 if (Should_delete_added_matrix[i_matrix] == 1)
322 delete Added_matrix_pt[i_matrix];
326 if (Should_delete_main_matrix)
328 delete Main_matrix_pt;
335 return Main_matrix_pt;
339 return Main_matrix_pt;
346 Should_delete_main_matrix =
true;
355 int last_row = this->nrow() - 1;
356 int last_col = this->ncol() - 1;
358 double last_value = operator()(last_row, last_col);
360 if (last_value == 0.0)
362 outfile << last_row <<
" " << last_col <<
" " << 0.0 << std::endl;
371 for (
unsigned long i = 0;
i < nrow();
i++)
373 for (
unsigned long j = 0; j < ncol(); j++)
375 double entry = operator()(
i, j);
379 outfile <<
i <<
" " << j <<
" " << entry << std::endl;
397 for (
int i = 0;
i < int(nrow());
i++)
399 for (
int j = 0; j < int(ncol()); j++)
401 double entry = operator()(
i, j);
407 values.push_back(entry);
418 bool should_delete_matrix =
false)
423 added_matrix_pt_in->
nrow())
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);
434 added_matrix_pt_in->
ncol())
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);
443 #ifdef RANGE_CHECKING
449 *std::max_element(rowmap_pt->begin(), rowmap_pt->end());
450 if (max_row > main_matrix_pt()->nrow())
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!";
457 err, OOMPH_EXCEPTION_LOCATION, OOMPH_CURRENT_FUNCTION);
465 *std::max_element(colmap_pt->begin(), colmap_pt->end());
466 if (max_col > main_matrix_pt()->ncol())
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!";
473 err, OOMPH_EXCEPTION_LOCATION, OOMPH_CURRENT_FUNCTION);
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));
487 return Added_matrix_pt[
i];
493 return Row_map_pt[
i];
497 return Col_map_pt[
i];
501 inline unsigned long nrow()
const
504 if (Main_matrix_pt == 0)
507 OOMPH_CURRENT_FUNCTION,
508 OOMPH_EXCEPTION_LOCATION);
511 return Main_matrix_pt->
nrow();
515 inline unsigned long ncol()
const
518 if (Main_matrix_pt == 0)
521 OOMPH_CURRENT_FUNCTION,
522 OOMPH_EXCEPTION_LOCATION);
525 return Main_matrix_pt->
ncol();
531 return Added_matrix_pt.size();
540 double&
entry(
const unsigned long&
i,
const unsigned long& j)
const
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);
552 double operator()(
const unsigned long&
i,
const unsigned long& j)
const
555 double sum = main_matrix_pt()->operator()(
i, j);
556 for (
unsigned i_matrix = 0; i_matrix < n_added_matrix(); i_matrix++)
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);
562 if ((li != -1) && (lj != -1))
564 sum += added_matrix_pt(i_matrix)->operator()(li, lj);
576 std::ostringstream error_msg;
577 error_msg <<
"Function not yet implemented.";
579 error_msg.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
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...
~AddedMainNumberingLookup()
Destructor.
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.
Abstract base class for matrices of doubles – adds abstract interfaces for solving,...
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....
Abstract base class for matrices, templated by the type of object that is stored in them and the type...
unsigned long nnode() const
Return number of nodes in the mesh.
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
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...
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...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...