30 #ifndef OOMPH_SUM_OF_MATRICES_H 31 #define OOMPH_SUM_OF_MATRICES_H 45 using namespace StringConversion;
65 this->build(mesh_pt, dof_index);
72 this->build(lookup_array, length);
82 int result = unsafe_main_to_added(main);
88 +
" not found in lookup.";
90 OOMPH_CURRENT_FUNCTION);
95 std::string err =
"Something crazy went wrong here.";
97 OOMPH_CURRENT_FUNCTION);
101 return unsigned(result);
109 std::map<unsigned, unsigned>::const_iterator
110 it = Main_to_added_mapping.find(
unsigned(main));
113 if(it == main_to_added_mapping_pt()->end())
126 {
return Added_to_main_mapping[added];}
130 void build(
const Mesh* mesh_pt,
const unsigned& dof_index)
132 construct_added_to_main_mapping(mesh_pt, dof_index);
133 construct_reverse_mapping();
138 void build(
const int* lookup_array,
const unsigned& length)
143 for(
unsigned j=0; j<length; j++)
145 if(lookup_array[j] < 0)
147 std::string err =
"negative entry in lookup array!";
149 OOMPH_CURRENT_FUNCTION);
155 Added_to_main_mapping.assign(lookup_array, lookup_array+length);
156 construct_reverse_mapping();
161 const unsigned& dof_index)
163 const unsigned ni = bem_lookup.size();
164 Added_to_main_mapping.assign(ni, -1);
166 for(
unsigned i=0;
i<ni;
i++)
168 Added_to_main_mapping[
i] = bem_lookup[
i]->eqn_number(dof_index);
171 construct_reverse_mapping();
177 Added_to_main_mapping.assign(n, 0);
178 for(
unsigned j=0; j<n; j++)
180 Added_to_main_mapping[j] = j;
182 construct_reverse_mapping();
191 {
return &Added_to_main_mapping;}
195 {
return &Main_to_added_mapping;}
201 const unsigned& dof_index)
204 Added_to_main_mapping.resize(mesh_pt->
nnode());
205 for(
unsigned nd=0, nnode=mesh_pt->
nnode(); nd<nnode; nd++)
215 if(Added_to_main_mapping.size() == 0)
217 std::ostringstream error_msg;
218 error_msg <<
"Must set up Added_to_main_mapping first.";
220 OOMPH_CURRENT_FUNCTION,
221 OOMPH_EXCEPTION_LOCATION);
226 Main_to_added_mapping.clear();
229 for(
unsigned j=0; j<Added_to_main_mapping.size(); j++)
231 Main_to_added_mapping.insert(std::make_pair(Added_to_main_mapping[j],
267 public Matrix<double,SumOfMatrices>
297 : Main_matrix_pt(0), Added_matrix_pt(0),
298 Row_map_pt(0), Col_map_pt(0),
299 Should_delete_added_matrix(0), Should_delete_main_matrix(0) {}
303 : Main_matrix_pt(main_matrix_pt), Added_matrix_pt(0),
304 Row_map_pt(0), Col_map_pt(0),
305 Should_delete_added_matrix(0), Should_delete_main_matrix(0) {}
319 for(
unsigned i_matrix=0; i_matrix<Added_matrix_pt.size(); i_matrix++)
321 if(Should_delete_added_matrix[i_matrix] == 1)
323 delete Added_matrix_pt[i_matrix];
327 if(Should_delete_main_matrix) {
delete Main_matrix_pt;}
337 {Should_delete_main_matrix =
true;}
345 int last_row = this->nrow()-1;
346 int last_col = this->ncol()-1;
348 double last_value = operator()(last_row, last_col);
350 if(last_value == 0.0)
352 outfile << last_row <<
" " << last_col <<
" " << 0.0
362 for (
unsigned long i=0;
i<nrow();
i++)
364 for (
unsigned long j=0; j<ncol(); j++)
366 double entry = operator()(
i,j);
370 outfile <<
i <<
" " << j <<
" " << entry
384 row.clear(); col.clear(); values.clear();
386 for (
int i=0;
i<int(nrow());
i++)
388 for (
int j=0; j<int(ncol()); j++)
390 double entry = operator()(
i,j);
396 values.push_back(entry);
407 bool should_delete_matrix=
false)
412 > added_matrix_pt_in->
nrow())
414 throw OomphLibError(
"Row mapping size should be less than or equal to nrow (less than if it is a sparse matrix and there are some empty rows).",
415 OOMPH_CURRENT_FUNCTION,
416 OOMPH_EXCEPTION_LOCATION);
421 > added_matrix_pt_in->
ncol())
423 throw OomphLibError(
"Col mapping size should be less than or equal to ncol (less than if it is a sparse matrix and there are some empty cols).",
424 OOMPH_CURRENT_FUNCTION,
425 OOMPH_EXCEPTION_LOCATION);
428 #ifdef RANGE_CHECKING 432 unsigned max_row = *std::max_element(rowmap_pt->begin(), rowmap_pt->end());
433 if(max_row > main_matrix_pt()->nrow())
435 std::string err =
"Trying to add a matrix with a mapping which specifices";
436 err +=
" a max row of "+
to_string(max_row)+
" but the main matrix ";
437 err +=
"only has "+
to_string(main_matrix_pt()->nrow()) +
" rows!";
439 OOMPH_CURRENT_FUNCTION);
445 unsigned max_col = *std::max_element(colmap_pt->begin(), colmap_pt->end());
446 if(max_col > main_matrix_pt()->ncol())
448 std::string err =
"Trying to add a matrix with a mapping which specifices";
449 err +=
" a max col of "+
to_string(max_col)+
" but the main matrix ";
450 err +=
"only has "+
to_string(main_matrix_pt()->ncol()) +
" cols!";
452 OOMPH_CURRENT_FUNCTION);
456 Added_matrix_pt.push_back(added_matrix_pt_in);
457 Row_map_pt.push_back(main_to_added_rows_pt);
458 Col_map_pt.push_back(main_to_added_cols_pt);
459 Should_delete_added_matrix.push_back(
unsigned(should_delete_matrix));
465 {
return Added_matrix_pt[
i];}
469 {
return Row_map_pt[
i];}
471 {
return Col_map_pt[
i];}
474 inline unsigned long nrow()
const 477 if(Main_matrix_pt==0)
480 OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
483 return Main_matrix_pt->
nrow();
487 inline unsigned long ncol()
const 490 if(Main_matrix_pt==0)
493 OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
496 return Main_matrix_pt->
ncol();
508 double&
entry(
const unsigned long&
i,
const unsigned long& j)
const 510 throw OomphLibError(
"Broken write to entry: it does not make sense to write to a sum, you must write to one of the component matrices.",
511 OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
518 const unsigned long &j)
const 521 double sum = main_matrix_pt()->operator()(
i,j);
522 for(
unsigned i_matrix=0; i_matrix<n_added_matrix(); i_matrix++)
524 int li = Row_map_pt[i_matrix]->unsafe_main_to_added(i);
525 int lj = Col_map_pt[i_matrix]->unsafe_main_to_added(j);
528 if(( li != -1) && (lj != -1))
530 sum += added_matrix_pt(i_matrix)->operator()(li,lj);
542 std::ostringstream error_msg;
543 error_msg <<
"Function not yet implemented.";
545 OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
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 broken_copy(const std::string &class_name)
Issue error message and terminate execution.
AddedMainNumberingLookup()
Default constructor.
unsigned main_to_added(const int &main) const
Given a main matrix row/col number get the equivalent row/col in the added matrix. Throw an error if not found.
unsigned n_added_matrix() const
Return the number of added matrices in the sum.
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...
SumOfMatrices(DoubleMatrixBase *main_matrix_pt)
Constructor taking a pointer to the main matrix as input.
SumOfMatrices(const SumOfMatrices &matrix)
Broken copy constructor.
SumOfMatrices()
Default constructor.
void operator=(const AddedMainNumberingLookup &dummy)
Inaccessible assignment operator.
Vector< DoubleMatrixBase * > Added_matrix_pt
List of pointers to the matrices that are added to the main matrix.
Vector< unsigned > Should_delete_added_matrix
Should we delete the sub matrices when destructor is called?
const AddedMainNumberingLookup * col_map_pt(const unsigned &i) const
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...
Vector< unsigned > Added_to_main_mapping
Mapping from added matrix row/col numbers to main matrix row/col numbers.
long & eqn_number(const unsigned &i)
Return the equation number of the i-th stored variable.
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...
std::map< unsigned, unsigned > Main_to_added_mapping
void set_delete_main_matrix()
Set the main matrix to be deleted by the destructor of the SumOfMatrices (default is to not delete it...
void construct_reverse_mapping()
Set up the main to added mapping using the added to main mapping.
unsigned long nrow() const
Return the number of rows of the main matrix.
AddedMainNumberingLookup(const Mesh *mesh_pt, const unsigned &dof_index)
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 build(const int *lookup_array, const unsigned &length)
void build(const Vector< const Node *> &bem_lookup, const unsigned &dof_index)
Construct lookup using node vector.
const DoubleMatrixBase * main_matrix_pt() const
Access to the main matrix.
const Vector< unsigned > * added_to_main_mapping_pt() const
Const access function for mapping.
void operator=(const SumOfMatrices &)
Broken assignment operator.
const std::map< unsigned, unsigned > * main_to_added_mapping_pt() const
Const access function for mapping.
DoubleMatrixBase * added_matrix_pt(const unsigned &i) const
const AddedMainNumberingLookup * row_map_pt(const unsigned &i) const
Access to the maps.
void build_identity_map(const unsigned &n)
Construct an identity map (mostly for testing).
DoubleMatrixBase *& main_matrix_pt()
Vector< const AddedMainNumberingLookup *> Row_map_pt
List of maps between row numbers of the main matrix and the added matrices.
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 ...
AddedMainNumberingLookup(const AddedMainNumberingLookup &dummy)
Inaccessible copy constructor.
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
unsigned long nnode() const
Return number of nodes in the mesh.
bool Should_delete_main_matrix
Should we delete the main matrix when destructor is called? Default is no.
double operator()(const unsigned long &i, const unsigned long &j) const
DoubleMatrixBase * Main_matrix_pt
Pointer to the matrix which we are adding the others to.
Vector< const AddedMainNumberingLookup *> Col_map_pt
List of maps between col numbers of the main matrix and the added matrices.
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
Abstract base class for matrices, templated by the type of object that is stored in them and the type...
virtual unsigned long nrow() const =0
Return the number of rows of the matrix.
AddedMainNumberingLookup(const int *lookup_array, const unsigned &length)
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
A vector in the mathematical sense, initially developed for linear algebra type applications. If MPI then this vector can be distributed - its distribution is described by the LinearAlgebraDistribution object at Distribution_pt. Data is stored in a C-style pointer vector (double*)
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...
unsigned long ncol() const
Return the number of columns of the main matrix.
Abstract base class for matrices of doubles – adds abstract interfaces for solving, LU decomposition and multiplication by vectors.
virtual unsigned long ncol() const =0
Return the number of columns of the matrix.
void build(const Mesh *mesh_pt, const unsigned &dof_index)
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. Return -1 if not found.
unsigned added_to_main(const unsigned &added) const
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 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.
~AddedMainNumberingLookup()
Destructor.